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
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()
if not bank:
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.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.core.models import BaseModel
from apps.product.models import Product, Broker, QuotaBrokerValue, QuotaDistribution, OrganizationQuotaStats
@@ -70,6 +70,34 @@ class Device(BaseModel):
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):
device = models.ForeignKey(
Device,

View File

@@ -59,7 +59,7 @@ def pos_organizations_sharing_information(
sharing_information_list.append({
"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,
"amount": broker_value_map.get(item.broker_id),
"agency": False,
@@ -115,11 +115,7 @@ def agency_organization_pos_info(
pos_sharing_list.append({
"organization_name": agency.name,
"bank_account": {
"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 {},
"bank_account": get_bank_info(org=agency, device=device),
"amount": agc_share_amount,
"agency": True,
"default_account": True

View File

@@ -81,8 +81,12 @@ class StakeHoldersSerializer(ModelSerializer):
def to_representation(self, 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(
instance.organization.bank_information.all().first()
if not bank_account_device_links.exists() else bank_account_device_links.first().bank_account
).data
representation['device'] = instance.device.device_identity
@@ -127,3 +131,9 @@ class StakeHolderShareAmountSerializer(ModelSerializer):
representation['stakeholders'] = StakeHoldersSerializer(instance.stakeholders).data
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 rest_framework.routers import DefaultRouter
from .viewsets import client as client_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'stake_holders', device_views.StakeHoldersViewSet, basename='stake_holders')
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 = [
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.services.visibility_service import apply_visibility_filter_by_org_type
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.device import BankAccountDeviceLinkSerializer
from apps.pos_device.web.api.v1.viewsets.client import POSClientViewSet
from apps.product.models import Broker, OrganizationQuotaStats
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
serializer = self.get_serializer(page, many=True)
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
)
# get organization bank account that set to a device
bank_account_device_links = organization.bank_account_device_links.filter(device=device)
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),
'sharing': sharing_list,
'base_prices': quota_pricing_items_by_type(instance.quota, sharing=sharing_list)