import - BankAccountDeviceLink for set device to a bank_account/changes in stakeholders & pos

This commit is contained in:
2025-12-30 16:57:15 +03:30
parent 9a02ad4622
commit e3318b7e1e
8 changed files with 104 additions and 11 deletions

View File

@@ -42,7 +42,13 @@ def get_all_org_type_child(org_type: OrganizationType = None) -> typing.Any:
return descendants return descendants
def get_bank_info(org): def get_bank_info(org, device=None):
if device:
# get organization bank account that set to a device
bank_account_device_links = org.bank_account_device_links.filter(device=device)
bank = bank_account_device_links.first().bank_account \
if bank_account_device_links.exists() else org.bank_information.first()
else:
bank = org.bank_information.first() bank = org.bank_information.first()
if not bank: if not bank:
return {} return {}

View File

@@ -0,0 +1,36 @@
# Generated by Django 5.0 on 2025-12-30 12:30
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('authentication', '0057_organization_purchase_policy'),
('pos_device', '0079_stakeholdershareamount_org_quota_stat'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='BankAccountDeviceLink',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_date', models.DateTimeField(auto_now_add=True)),
('modify_date', models.DateTimeField(auto_now=True)),
('creator_info', models.CharField(max_length=100, null=True)),
('modifier_info', models.CharField(max_length=100, null=True)),
('trash', models.BooleanField(default=False)),
('bank_account', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='linked_devices', to='authentication.bankaccountinformation')),
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createddby', to=settings.AUTH_USER_MODEL)),
('device', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='linked_bank_accounts', to='pos_device.device')),
('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL)),
('organization', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='bank_account_device_links', to='authentication.organization')),
],
options={
'abstract': False,
},
),
]

View File

@@ -4,7 +4,7 @@ import string
from django.contrib.postgres.fields import ArrayField from django.contrib.postgres.fields import ArrayField
from django.db import models from django.db import models
from apps.authentication.models import Organization, City, Province from apps.authentication.models import Organization, City, Province, BankAccountInformation
from apps.authorization.models import UserRelations from apps.authorization.models import UserRelations
from apps.core.models import BaseModel from apps.core.models import BaseModel
from apps.product.models import Product, Broker, QuotaBrokerValue, QuotaDistribution, OrganizationQuotaStats from apps.product.models import Product, Broker, QuotaBrokerValue, QuotaDistribution, OrganizationQuotaStats
@@ -70,6 +70,34 @@ class Device(BaseModel):
return super(Device, self).save(*args, **kwargs) return super(Device, self).save(*args, **kwargs)
class BankAccountDeviceLink(BaseModel):
organization = models.ForeignKey(
Organization,
on_delete=models.CASCADE,
related_name='bank_account_device_links',
null=True
)
bank_account = models.ForeignKey(
BankAccountInformation,
on_delete=models.CASCADE,
related_name='linked_devices',
null=True
)
device = models.ForeignKey(
Device,
on_delete=models.CASCADE,
related_name='linked_bank_accounts',
null=True
)
def __str__(self):
return (f'{self.id} --> organization: {self.organization.name}/'
f'{self.organization.id} --> device: {self.device.serial}')
def save(self, *args, **kwargs):
return super(BankAccountDeviceLink, self).save(*args, **kwargs)
class DeviceActivationCode(BaseModel): class DeviceActivationCode(BaseModel):
device = models.ForeignKey( device = models.ForeignKey(
Device, Device,

View File

@@ -59,7 +59,7 @@ def pos_organizations_sharing_information(
sharing_information_list.append({ sharing_information_list.append({
"organization_name": item.organization.name, "organization_name": item.organization.name,
"bank_account": get_bank_info(item.organization), "bank_account": get_bank_info(item.organization, device=device),
"broker": item.broker.name, "broker": item.broker.name,
"amount": broker_value_map.get(item.broker_id), "amount": broker_value_map.get(item.broker_id),
"agency": False, "agency": False,
@@ -115,11 +115,7 @@ def agency_organization_pos_info(
pos_sharing_list.append({ pos_sharing_list.append({
"organization_name": agency.name, "organization_name": agency.name,
"bank_account": { "bank_account": get_bank_info(org=agency, device=device),
"credit_card": agency.bank_information.first().card,
"sheba": "IR" + agency.bank_information.first().sheba,
"account": agency.bank_information.first().account,
} if agency.bank_information.exists() else {},
"amount": agc_share_amount, "amount": agc_share_amount,
"agency": True, "agency": True,
"default_account": True "default_account": True

View File

@@ -81,8 +81,12 @@ class StakeHoldersSerializer(ModelSerializer):
def to_representation(self, instance): def to_representation(self, instance):
representation = super().to_representation(instance) representation = super().to_representation(instance)
# get organization bank account that set to a device
bank_account_device_links = instance.organization.bank_account_device_links.filter(device=instance.device)
representation['bank_account'] = BankAccountSerializer( representation['bank_account'] = BankAccountSerializer(
instance.organization.bank_information.all().first() instance.organization.bank_information.all().first()
if not bank_account_device_links.exists() else bank_account_device_links.first().bank_account
).data ).data
representation['device'] = instance.device.device_identity representation['device'] = instance.device.device_identity
@@ -127,3 +131,9 @@ class StakeHolderShareAmountSerializer(ModelSerializer):
representation['stakeholders'] = StakeHoldersSerializer(instance.stakeholders).data representation['stakeholders'] = StakeHoldersSerializer(instance.stakeholders).data
return representation return representation
class BankAccountDeviceLinkSerializer(ModelSerializer):
class Meta:
model = pos_models.BankAccountDeviceLink
fields = '__all__'

View File

@@ -1,5 +1,6 @@
from django.urls import path, include from django.urls import path, include
from rest_framework.routers import DefaultRouter from rest_framework.routers import DefaultRouter
from .viewsets import client as client_views from .viewsets import client as client_views
from .viewsets import device as device_views from .viewsets import device as device_views
@@ -11,6 +12,11 @@ router.register(r'device', device_views.DeviceViewSet, basename='device')
router.register(r'device_assignment', device_views.DeviceAssignmentViewSet, basename='device_assignment') router.register(r'device_assignment', device_views.DeviceAssignmentViewSet, basename='device_assignment')
router.register(r'stake_holders', device_views.StakeHoldersViewSet, basename='stake_holders') router.register(r'stake_holders', device_views.StakeHoldersViewSet, basename='stake_holders')
router.register(r'holders_share', device_views.StakeHolderShareAmountViewSet, basename='holders_share') router.register(r'holders_share', device_views.StakeHolderShareAmountViewSet, basename='holders_share')
router.register(
r'bank_account_device_link',
device_views.BankAccountDeviceLinkViewSet,
basename='bank_account_device_link'
)
urlpatterns = [ urlpatterns = [
path('v1/pos/', include(router.urls)) path('v1/pos/', include(router.urls))

View File

@@ -24,7 +24,9 @@ from apps.core.mixins.search_mixin import DynamicSearchMixin
from apps.core.mixins.soft_delete_mixin import SoftDeleteMixin from apps.core.mixins.soft_delete_mixin import SoftDeleteMixin
from apps.core.services.visibility_service import apply_visibility_filter_by_org_type from apps.core.services.visibility_service import apply_visibility_filter_by_org_type
from apps.pos_device import models as pos_models from apps.pos_device import models as pos_models
from apps.pos_device.models import BankAccountDeviceLink
from apps.pos_device.web.api.v1.serilaizers import device as device_serializer from apps.pos_device.web.api.v1.serilaizers import device as device_serializer
from apps.pos_device.web.api.v1.serilaizers.device import BankAccountDeviceLinkSerializer
from apps.pos_device.web.api.v1.viewsets.client import POSClientViewSet from apps.pos_device.web.api.v1.viewsets.client import POSClientViewSet
from apps.product.models import Broker, OrganizationQuotaStats from apps.product.models import Broker, OrganizationQuotaStats
from apps.product.web.api.v1.viewsets.quota_distribution_api import QuotaDistributionViewSet from apps.product.web.api.v1.viewsets.quota_distribution_api import QuotaDistributionViewSet
@@ -515,3 +517,8 @@ class StakeHolderShareAmountViewSet(viewsets.ModelViewSet, DynamicSearchMixin, S
if page is not None: # noqa if page is not None: # noqa
serializer = self.get_serializer(page, many=True) serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data) return self.get_paginated_response(serializer.data)
class BankAccountDeviceLinkViewSet(BaseViewSet, viewsets.ModelViewSet, DynamicSearchMixin, SoftDeleteMixin):
queryset = BankAccountDeviceLink.objects.select_related('organization', 'bank_account', 'device')
serializer_class = BankAccountDeviceLinkSerializer

View File

@@ -314,8 +314,12 @@ class OrganizationQuotaStatsSerializer(serializers.ModelSerializer):
owner_org=organization owner_org=organization
) )
# get organization bank account that set to a device
bank_account_device_links = organization.bank_account_device_links.filter(device=device)
representation['pricing'] = { # noqa representation['pricing'] = { # noqa
'main_account_sheba': "IR" + organization.bank_information.first().sheba, 'main_account_sheba': "IR" + organization.bank_information.first().sheba
if not bank_account_device_links.exists() else bank_account_device_links.first().bank_account.sheba,
'pricing_attributes': quota_attribute_value(instance.quota), 'pricing_attributes': quota_attribute_value(instance.quota),
'sharing': sharing_list, 'sharing': sharing_list,
'base_prices': quota_pricing_items_by_type(instance.quota, sharing=sharing_list) 'base_prices': quota_pricing_items_by_type(instance.quota, sharing=sharing_list)