213 lines
7.1 KiB
Python
213 lines
7.1 KiB
Python
import json
|
|
|
|
from apps.core.custom_middlewares.request_middleware import get_current_request_body
|
|
from apps.product.models import QuotaDistribution, OrganizationQuotaStats, AttributeValue, Attribute, QuotaBrokerValue, \
|
|
Broker
|
|
from apps.product.validators.quota_stats_validator import QuotaStatsValidator
|
|
from apps.warehouse.models import InventoryEntry
|
|
|
|
|
|
def import_price_features(data, assigned_stat, quota):
|
|
"""
|
|
create price attributes data & broker pricing value for every distribution
|
|
"""
|
|
assigned_stat.attribute_values.all().delete()
|
|
assigned_stat.broker_values.all().delete()
|
|
|
|
if 'price_attributes_data' and 'broker_data' in data.keys():
|
|
attr_price_values = [AttributeValue(
|
|
attribute=Attribute.objects.get(id=attr['attribute']),
|
|
value=attr['value'],
|
|
quota=quota,
|
|
org_quota_stat=assigned_stat
|
|
) for attr in data['price_attributes_data']]
|
|
AttributeValue.objects.bulk_create(attr_price_values) # bulk create
|
|
|
|
broker_price_values = [
|
|
QuotaBrokerValue(
|
|
quota=quota,
|
|
broker=Broker.objects.get(id=broker['broker']),
|
|
value=broker['value'],
|
|
org_quota_stat=assigned_stat
|
|
) for broker in data['broker_data']
|
|
]
|
|
QuotaBrokerValue.objects.bulk_create(broker_price_values) # bulk create
|
|
|
|
quota.edited_pricing_features = True
|
|
quota.save(update_fields=['edited_pricing_features'])
|
|
|
|
|
|
class QuotaStatsService:
|
|
@staticmethod
|
|
def apply_distribution(distribution: QuotaDistribution):
|
|
quota = distribution.quota
|
|
# origin org
|
|
assigner = distribution.assigner_organization
|
|
if assigner.type.key == 'ADM':
|
|
assigner = quota.registerer_organization
|
|
|
|
# destination org
|
|
assigned = distribution.assigned_organization
|
|
|
|
QuotaStatsValidator.validate_assigner_has_enough(
|
|
assigner_org=assigner,
|
|
quota=quota,
|
|
amount=distribution.weight
|
|
)
|
|
|
|
# ================ origin ================
|
|
assigner_stat, created = OrganizationQuotaStats.objects.get_or_create(
|
|
organization=assigner,
|
|
quota=quota,
|
|
stat_type='distribution'
|
|
)
|
|
assigner_stat.remaining_amount -= distribution.weight
|
|
assigner_stat.total_distributed += distribution.weight
|
|
assigner_stat.save()
|
|
|
|
# ============== destination ================
|
|
assigned_stat, _ = OrganizationQuotaStats.objects.get_or_create(
|
|
organization=assigned,
|
|
quota=quota,
|
|
stat_type='distribution'
|
|
)
|
|
assigned_stat.total_amount += distribution.weight
|
|
assigned_stat.remaining_amount += distribution.weight
|
|
assigned_stat.distributions.add(distribution)
|
|
assigned_stat.save()
|
|
|
|
# create pricing attributes and broker pricing data
|
|
data = json.loads(get_current_request_body().decode())
|
|
import_price_features(data, assigned_stat, quota)
|
|
|
|
@staticmethod
|
|
def update_distribution(distribution: QuotaDistribution, old_weight: int):
|
|
diff = distribution.weight - old_weight
|
|
|
|
quota = distribution.quota
|
|
|
|
assigner = distribution.assigner_organization
|
|
assigned = distribution.assigned_organization
|
|
|
|
QuotaStatsValidator.validate_distribution_update(
|
|
assigner_org=assigner,
|
|
assigned_org=assigned,
|
|
quota=quota,
|
|
old_amount=old_weight,
|
|
new_amount=distribution.weight
|
|
)
|
|
|
|
assigner_stat = OrganizationQuotaStats.objects.get(
|
|
organization=assigner,
|
|
quota=quota
|
|
)
|
|
assigned_stat = OrganizationQuotaStats.objects.get(
|
|
organization=assigned,
|
|
quota=quota
|
|
)
|
|
|
|
# create pricing attributes and broker pricing data
|
|
data = json.loads(get_current_request_body().decode())
|
|
import_price_features(data, assigned_stat, quota)
|
|
|
|
if diff == 0:
|
|
return
|
|
|
|
if assigner_stat.stat_type == 'distribution':
|
|
# if diff > 0 it is added to destination
|
|
assigner_stat.remaining_amount -= diff
|
|
assigner_stat.total_distributed += diff
|
|
assigner_stat.save()
|
|
assigned_stat.total_amount += diff
|
|
assigned_stat.remaining_amount += diff
|
|
assigned_stat.save()
|
|
|
|
@staticmethod
|
|
def delete_distribution(distribution: QuotaDistribution):
|
|
quota = distribution.quota
|
|
|
|
# origin
|
|
assigner_stat = OrganizationQuotaStats.objects.get(
|
|
organization=distribution.assigner_organization,
|
|
quota=quota
|
|
)
|
|
if assigner_stat.stat_type == 'distribution':
|
|
assigner_stat.remaining_amount += distribution.weight
|
|
assigner_stat.total_distributed -= distribution.weight
|
|
assigner_stat.save()
|
|
|
|
# destination
|
|
assigned_stat = OrganizationQuotaStats.objects.get(
|
|
organization=distribution.assigned_organization,
|
|
quota=quota
|
|
)
|
|
assigned_stat.total_amount -= distribution.weight
|
|
assigned_stat.remaining_amount -= distribution.weight
|
|
assigned_stat.distributions.remove(distribution)
|
|
assigned_stat.save()
|
|
|
|
@staticmethod
|
|
def apply_inventory_entry(entry: InventoryEntry, created):
|
|
quota = entry.quota
|
|
weight = entry.weight
|
|
|
|
if not created:
|
|
old_weight = entry._old_weight # noqa
|
|
diff = weight - old_weight
|
|
else:
|
|
diff = weight
|
|
print("0000", diff)
|
|
QuotaStatsService._propagate_inventory(
|
|
organization=entry.organization,
|
|
quota=quota,
|
|
diff=diff
|
|
)
|
|
|
|
@staticmethod
|
|
def remove_inventory_entry(entry: InventoryEntry):
|
|
quota = entry.quota
|
|
weight = entry.weight
|
|
|
|
QuotaStatsService._propagate_inventory(
|
|
organization=entry.organization,
|
|
quota=quota,
|
|
diff=-weight
|
|
)
|
|
|
|
@staticmethod
|
|
def _propagate_inventory(organization, quota, diff):
|
|
org = organization
|
|
stat_queryset = OrganizationQuotaStats.objects.select_related('quota', 'organization')
|
|
update_my_remaining_stat = True
|
|
|
|
parent_orgs = []
|
|
|
|
while org:
|
|
parent_orgs.append(org)
|
|
org = org.parent_organization
|
|
|
|
parent_orgs_ids = [org.id for org in parent_orgs]
|
|
|
|
target_org_ids = set(parent_orgs_ids)
|
|
|
|
if quota.registerer_organization.id not in target_org_ids:
|
|
target_org_ids.add(quota.registerer_organization.id)
|
|
|
|
stats = (stat_queryset.filter(
|
|
quota=quota,
|
|
organization__in=target_org_ids
|
|
))
|
|
|
|
for stat in stats:
|
|
stat.inventory_received = (stat.inventory_received or 0) + diff
|
|
|
|
# just update my own stat remaining quota weight
|
|
if update_my_remaining_stat:
|
|
stat.remaining_amount -= diff
|
|
update_my_remaining_stat = False
|
|
|
|
if stat.inventory_received < 0:
|
|
stat.inventory_received = 0
|
|
|
|
OrganizationQuotaStats.objects.bulk_update(stats, ['inventory_received', 'remaining_amount'])
|