diff --git a/apps/product/migrations/0037_remove_attribute_type_and_more.py b/apps/product/migrations/0037_remove_attribute_type_and_more.py new file mode 100644 index 0000000..53a976a --- /dev/null +++ b/apps/product/migrations/0037_remove_attribute_type_and_more.py @@ -0,0 +1,26 @@ +# Generated by Django 5.0 on 2025-07-08 10:32 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('product', '0036_historicalquotadistribution'), + ] + + operations = [ + migrations.RemoveField( + model_name='attribute', + name='type', + ), + migrations.RemoveField( + model_name='broker', + name='calculation_strategy', + ), + migrations.AlterField( + model_name='saleunit', + name='unit', + field=models.CharField(max_length=250, null=True), + ), + ] diff --git a/apps/product/migrations/0038_attribute_type_broker_calculation_strategy.py b/apps/product/migrations/0038_attribute_type_broker_calculation_strategy.py new file mode 100644 index 0000000..1b1196a --- /dev/null +++ b/apps/product/migrations/0038_attribute_type_broker_calculation_strategy.py @@ -0,0 +1,24 @@ +# Generated by Django 5.0 on 2025-07-08 10:37 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('product', '0037_remove_attribute_type_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='attribute', + name='type', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='attributes', to='product.saleunit'), + ), + migrations.AddField( + model_name='broker', + name='calculation_strategy', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='brokers', to='product.saleunit'), + ), + ] diff --git a/apps/product/models.py b/apps/product/models.py index 630804c..404d8ef 100644 --- a/apps/product/models.py +++ b/apps/product/models.py @@ -144,15 +144,11 @@ class Attribute(BaseModel): null=True ) name = models.CharField(max_length=100, default='empty') - type_choices = ( - ('K', 'Per Kilo'), - ('', ''), - ) - type = models.CharField( - max_length=10, - choices=type_choices, - default='empty', - help_text='type of attribute like: calculate product by kilogram' + type = models.ForeignKey( + 'SaleUnit', + on_delete=models.CASCADE, + related_name="attributes", + null=True ) is_global = models.BooleanField(default=False) @@ -194,10 +190,6 @@ class AttributeValue(BaseModel): class Broker(BaseModel): """ Broker for product """ - CALCULATION_CHOICES = ( - ('K', 'Per Kilo'), - ('', ''), - ) BROKER_TYPES = ( ('public', 'PUBLIC'), ('exclusive', 'EXCLUSIVE') @@ -215,10 +207,11 @@ class Broker(BaseModel): related_name='product_organization', null=True ) - calculation_strategy = models.CharField( - max_length=3, - choices=CALCULATION_CHOICES, - default='empty' + calculation_strategy = models.ForeignKey( + 'SaleUnit', + on_delete=models.CASCADE, + related_name='brokers', + null=True ) broker_type = models.CharField(choices=BROKER_TYPES, max_length=20, null=True) required = models.BooleanField(default=False) @@ -239,12 +232,7 @@ class SaleUnit(BaseModel): related_name='sale_unit', null=True ) - unit_choices = ( - ('10P', '10KG Package'), - ('50P', '50KG Package'), - ('', ''), - ) - unit = models.CharField(max_length=10, choices=unit_choices, null=True) + unit = models.CharField(max_length=250, null=True) variation_coefficient = models.IntegerField(default=0) required = models.BooleanField(default=False) diff --git a/apps/product/services.py b/apps/product/services.py index 0aabb24..82ac14f 100644 --- a/apps/product/services.py +++ b/apps/product/services.py @@ -2,7 +2,7 @@ from apps.warehouse.models import InventoryEntry def get_products_in_warehouse(organization_id): - """ get lis of products from organization warehouse """ + """ get list of products from organization warehouse """ entries = InventoryEntry.objects.select_related( 'distribution__quota__product' diff --git a/apps/product/web/api/v1/product_api.py b/apps/product/web/api/v1/product_api.py index 0e8afc6..d0ac79f 100644 --- a/apps/product/web/api/v1/product_api.py +++ b/apps/product/web/api/v1/product_api.py @@ -103,6 +103,27 @@ class ProductViewSet(viewsets.ModelViewSet): return Response(product_data, status=status.HTTP_200_OK) + @action( + methods=['get'], + detail=True, + url_path='quotas_information', + url_name='quotas_information', + name='quotas_information' + ) + @transaction.atomic + def quotas_information_by_product(self, request, pk=None): + """ get quotas information of a product """ + + quotas = product_models.Quota.objects.select_related('product').filter( + product_id=pk, is_closed=False + ) + + try: + quota_serializer = product_serializers.QuotaSerializer(quotas, many=True).data + return Response(quota_serializer, status=status.HTTP_200_OK) + except APIException as e: + raise APIException(detail="data error", code=400) + @action( methods=['put'], detail=True, @@ -136,7 +157,7 @@ class ProductViewSet(viewsets.ModelViewSet): class AttributeViewSet(viewsets.ModelViewSet): - """ attributes of reference product """ + """ attributes of reference product """ # queryset = product_models.Attribute.objects.all() serializer_class = product_serializers.AttributeSerializer diff --git a/apps/product/web/api/v1/product_serializers.py b/apps/product/web/api/v1/product_serializers.py index 2505e6f..038fbff 100644 --- a/apps/product/web/api/v1/product_serializers.py +++ b/apps/product/web/api/v1/product_serializers.py @@ -44,6 +44,12 @@ class AttributeSerializer(serializers.ModelSerializer): 'id': instance.product.id, 'name': instance.product.name } + + if instance.type: + representation['type'] = { + 'id': instance.type.id, + 'unit': instance.type.unit + } return representation @@ -70,6 +76,7 @@ class BrokerSerializer(serializers.ModelSerializer): class Meta: model = product_models.Broker fields = '__all__' + depth = 0 def to_representation(self, instance): representation = super().to_representation(instance) @@ -83,6 +90,12 @@ class BrokerSerializer(serializers.ModelSerializer): instance.product ).data + if instance.calculation_strategy: + representation['calculation_strategy'] = { + 'id': instance.calculation_strategy.id, + 'unit': instance.calculation_strategy.unit + } + return representation