add some new fields to quota sale transaction model - add rancher information about live stocks & quota aalocations information
This commit is contained in:
18
apps/pos_device/migrations/0062_stakeholders_default.py
Normal file
18
apps/pos_device/migrations/0062_stakeholders_default.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.0 on 2025-08-25 11:32
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('pos_device', '0061_posfreeproducts'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='stakeholders',
|
||||||
|
name='default',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -474,7 +474,7 @@ class QuotaBrokerValue(BaseModel):
|
|||||||
value = models.PositiveBigIntegerField(default=0)
|
value = models.PositiveBigIntegerField(default=0)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"Quota ({self.quota.id}) for Broker({self.broker.organization.name})"
|
return f"Quota ({self.quota.id}) for Broker({self.broker.organization_type.name})"
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
return super(QuotaBrokerValue, self).save(*args, **kwargs)
|
return super(QuotaBrokerValue, self).save(*args, **kwargs)
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
from apps.product.models import Quota, QuotaLivestockAllocation
|
||||||
from apps.warehouse.models import InventoryEntry
|
from apps.warehouse.models import InventoryEntry
|
||||||
|
import typing
|
||||||
|
|
||||||
|
|
||||||
def get_products_in_warehouse(organization_id):
|
def get_products_in_warehouse(organization_id):
|
||||||
@@ -14,3 +16,16 @@ def get_products_in_warehouse(organization_id):
|
|||||||
|
|
||||||
return list(set(product_objects))
|
return list(set(product_objects))
|
||||||
|
|
||||||
|
|
||||||
|
def quota_live_stock_allocation_info(quota: Quota) -> typing.Any:
|
||||||
|
""" information of quota live stock allocations """
|
||||||
|
|
||||||
|
allocations = quota.livestock_allocations.filter(quota=quota)
|
||||||
|
|
||||||
|
allocations_list = [{
|
||||||
|
"name": alloc.livestock_type.name,
|
||||||
|
"quantity": alloc.quantity_kg
|
||||||
|
} for alloc in allocations]
|
||||||
|
|
||||||
|
return allocations_list
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.0 on 2025-08-25 11:32
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('warehouse', '0014_remove_inventoryquotasaletransaction_buyer_user_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='inventoryentry',
|
||||||
|
name='entry_identity',
|
||||||
|
field=models.CharField(max_length=50, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
# Generated by Django 5.0 on 2025-08-25 13:01
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('warehouse', '0015_inventoryentry_entry_identity'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='inventoryquotasaletransaction',
|
||||||
|
name='additional',
|
||||||
|
field=models.JSONField(default=dict),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='inventoryquotasaletransaction',
|
||||||
|
name='payer_cart',
|
||||||
|
field=models.CharField(max_length=50, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='inventoryquotasaletransaction',
|
||||||
|
name='price_paid',
|
||||||
|
field=models.PositiveBigIntegerField(default=0),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='inventoryquotasaletransaction',
|
||||||
|
name='price_type',
|
||||||
|
field=models.CharField(choices=[('card', 'CARD'), ('cash', 'CASH'), ('credit', 'CREDIT'), ('check', 'CHECK')], max_length=50, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='inventoryquotasaletransaction',
|
||||||
|
name='ref_num',
|
||||||
|
field=models.CharField(max_length=50, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='inventoryquotasaletransaction',
|
||||||
|
name='result_text',
|
||||||
|
field=models.TextField(null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='inventoryquotasaletransaction',
|
||||||
|
name='terminal',
|
||||||
|
field=models.CharField(max_length=50, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='inventoryquotasaletransaction',
|
||||||
|
name='transaction_status_code',
|
||||||
|
field=models.IntegerField(default=0),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import string
|
||||||
|
import random
|
||||||
from apps.product import models as product_models
|
from apps.product import models as product_models
|
||||||
from apps.authentication.models import User
|
from apps.authentication.models import User
|
||||||
from apps.pos_device.models import Device
|
from apps.pos_device.models import Device
|
||||||
@@ -7,6 +9,7 @@ from django.db import models
|
|||||||
|
|
||||||
|
|
||||||
class InventoryEntry(BaseModel):
|
class InventoryEntry(BaseModel):
|
||||||
|
entry_identity = models.CharField(max_length=50, null=True)
|
||||||
distribution = models.ForeignKey(
|
distribution = models.ForeignKey(
|
||||||
product_models.QuotaDistribution,
|
product_models.QuotaDistribution,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
@@ -27,6 +30,15 @@ class InventoryEntry(BaseModel):
|
|||||||
is_confirmed = models.BooleanField(default=False)
|
is_confirmed = models.BooleanField(default=False)
|
||||||
notes = models.TextField(blank=True, null=True)
|
notes = models.TextField(blank=True, null=True)
|
||||||
|
|
||||||
|
def generate_entry_identity(self): # noqa
|
||||||
|
""" generate identity for every device """
|
||||||
|
# prefix = "POS"
|
||||||
|
while True:
|
||||||
|
number_part = ''.join(random.choices(string.digits, k=6))
|
||||||
|
code = f"{self.distribution.quota.quota_id}{number_part}"
|
||||||
|
if not InventoryEntry.objects.filter(entry_identity=code).exists():
|
||||||
|
return code
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def total_sold(self):
|
def total_sold(self):
|
||||||
return self.inventory_sales.aggregate(total=models.Sum('weight'))['total'] or 0
|
return self.inventory_sales.aggregate(total=models.Sum('weight'))['total'] or 0
|
||||||
@@ -39,6 +51,8 @@ class InventoryEntry(BaseModel):
|
|||||||
return f"distribution: {self.distribution.distribution_id}-{self.organization.name}"
|
return f"distribution: {self.distribution.distribution_id}-{self.organization.name}"
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
|
if not self.entry_identity:
|
||||||
|
self.entry_identity = self.generate_entry_identity()
|
||||||
super(InventoryEntry, self).save(*args, **kwargs)
|
super(InventoryEntry, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@@ -83,6 +97,14 @@ class InventoryQuotaSaleTransaction(BaseModel):
|
|||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
transaction_price = models.PositiveBigIntegerField(default=0)
|
transaction_price = models.PositiveBigIntegerField(default=0)
|
||||||
|
price_paid = models.PositiveBigIntegerField(default=0)
|
||||||
|
type_of_price = (
|
||||||
|
('card', 'CARD'),
|
||||||
|
('cash', 'CASH'),
|
||||||
|
('credit', 'CREDIT'),
|
||||||
|
('check', 'CHECK'),
|
||||||
|
)
|
||||||
|
price_type = models.CharField(choices=type_of_price, max_length=50, null=True)
|
||||||
description = models.TextField(blank=True, null=True)
|
description = models.TextField(blank=True, null=True)
|
||||||
herd_owners_number = models.PositiveBigIntegerField(default=0)
|
herd_owners_number = models.PositiveBigIntegerField(default=0)
|
||||||
transactions_number = models.PositiveBigIntegerField(default=0)
|
transactions_number = models.PositiveBigIntegerField(default=0)
|
||||||
@@ -92,6 +114,12 @@ class InventoryQuotaSaleTransaction(BaseModel):
|
|||||||
('failed', 'Failed'),
|
('failed', 'Failed'),
|
||||||
)
|
)
|
||||||
transaction_status = models.CharField(choices=status_type, max_length=25, null=True)
|
transaction_status = models.CharField(choices=status_type, max_length=25, null=True)
|
||||||
|
transaction_status_code = models.IntegerField(default=0)
|
||||||
|
result_text = models.TextField(null=True)
|
||||||
|
ref_num = models.CharField(max_length=50, null=True)
|
||||||
|
terminal = models.CharField(max_length=50, null=True)
|
||||||
|
payer_cart = models.CharField(max_length=50, null=True)
|
||||||
|
additional = models.JSONField(default=dict)
|
||||||
|
|
||||||
def buyers_count(self):
|
def buyers_count(self):
|
||||||
""" number of buyers from specific inventory """
|
""" number of buyers from specific inventory """
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from apps.herd.services.services import get_rancher_statistics, rancher_quota_weight
|
from apps.herd.services.services import get_rancher_statistics, rancher_quota_weight
|
||||||
|
from apps.product.services.services import quota_live_stock_allocation_info
|
||||||
from apps.pos_device.pos.api.v1.serializers.device import DeviceSerializer
|
from apps.pos_device.pos.api.v1.serializers.device import DeviceSerializer
|
||||||
from apps.herd.pos.api.v1.serializers import RancherSerializer
|
from apps.herd.pos.api.v1.serializers import RancherSerializer
|
||||||
from apps.warehouse.exceptions import (
|
from apps.warehouse.exceptions import (
|
||||||
@@ -14,6 +15,7 @@ class InventoryEntrySerializer(serializers.ModelSerializer):
|
|||||||
model = warehouse_models.InventoryEntry
|
model = warehouse_models.InventoryEntry
|
||||||
fields = [
|
fields = [
|
||||||
"id",
|
"id",
|
||||||
|
"entry_identity",
|
||||||
"create_date",
|
"create_date",
|
||||||
"modify_date",
|
"modify_date",
|
||||||
"organization",
|
"organization",
|
||||||
@@ -42,6 +44,9 @@ class InventoryEntrySerializer(serializers.ModelSerializer):
|
|||||||
representation['quota'] = {
|
representation['quota'] = {
|
||||||
'quota_identity': instance.distribution.quota.quota_id,
|
'quota_identity': instance.distribution.quota.quota_id,
|
||||||
'quota_weight': instance.distribution.quota.quota_weight,
|
'quota_weight': instance.distribution.quota.quota_weight,
|
||||||
|
'quota_livestock_allocations': quota_live_stock_allocation_info(
|
||||||
|
instance.distribution.quota
|
||||||
|
)
|
||||||
}
|
}
|
||||||
representation['product'] = {
|
representation['product'] = {
|
||||||
'name': instance.distribution.quota.product.name,
|
'name': instance.distribution.quota.product.name,
|
||||||
|
|||||||
Reference in New Issue
Block a user