From c2b38f3f1e7026793c25d215d956783c3a4d8e1a Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 6 Dec 2021 10:00:04 +0800 Subject: [PATCH 01/17] =?UTF-8?q?=E9=94=80=E5=94=AE=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/inm/filters.py | 12 +++- .../inm/migrations/0020_iproduct_is_saled.py | 18 +++++ hb_server/apps/inm/models.py | 1 + hb_server/apps/inm/serializers.py | 9 +++ hb_server/apps/inm/views.py | 6 +- .../sam/migrations/0005_auto_20211203_1501.py | 28 ++++++++ .../sam/migrations/0006_auto_20211206_0958.py | 65 +++++++++++++++++++ hb_server/apps/sam/models.py | 41 ++++++++++-- hb_server/apps/sam/serializers.py | 39 ++++++++++- hb_server/apps/sam/urls.py | 3 +- hb_server/apps/sam/views.py | 31 +++++++-- .../wf/migrations/0017_auto_20211203_1501.py | 23 +++++++ hb_server/apps/wf/models.py | 26 ++++---- 13 files changed, 273 insertions(+), 29 deletions(-) create mode 100644 hb_server/apps/inm/migrations/0020_iproduct_is_saled.py create mode 100644 hb_server/apps/sam/migrations/0005_auto_20211203_1501.py create mode 100644 hb_server/apps/sam/migrations/0006_auto_20211206_0958.py create mode 100644 hb_server/apps/wf/migrations/0017_auto_20211203_1501.py diff --git a/hb_server/apps/inm/filters.py b/hb_server/apps/inm/filters.py index c71c4fb..3f550a3 100644 --- a/hb_server/apps/inm/filters.py +++ b/hb_server/apps/inm/filters.py @@ -1,9 +1,17 @@ from django_filters import rest_framework as filters from apps.mtm.models import Material -from .models import MaterialBatch +from .models import IProduct, MaterialBatch class MbFilterSet(filters.FilterSet): material = filters.ModelMultipleChoiceFilter(field_name="material", queryset=Material.objects.all()) class Meta: model = MaterialBatch - fields = ['material', 'warehouse'] \ No newline at end of file + fields = ['material', 'warehouse'] + + +class IProductFilterSet(filters.FilterSet): + + order = filters.NumberFilter(field_name="wproduct__subproduction_plan__production_plan__order") + class Meta: + model = IProduct + fields = ['material', 'warehouse', 'batch', 'order'] \ No newline at end of file diff --git a/hb_server/apps/inm/migrations/0020_iproduct_is_saled.py b/hb_server/apps/inm/migrations/0020_iproduct_is_saled.py new file mode 100644 index 0000000..5ca02e7 --- /dev/null +++ b/hb_server/apps/inm/migrations/0020_iproduct_is_saled.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2021-12-06 01:58 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('inm', '0019_auto_20211201_1011'), + ] + + operations = [ + migrations.AddField( + model_name='iproduct', + name='is_saled', + field=models.BooleanField(default=False, verbose_name='是否售出'), + ), + ] diff --git a/hb_server/apps/inm/models.py b/hb_server/apps/inm/models.py index 20d87dd..5c485d0 100644 --- a/hb_server/apps/inm/models.py +++ b/hb_server/apps/inm/models.py @@ -102,5 +102,6 @@ class IProduct(BaseModel): warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库') batch = models.CharField('所属批次号', max_length=100, default='') wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True) + is_saled = models.BooleanField('是否售出', default=False) diff --git a/hb_server/apps/inm/serializers.py b/hb_server/apps/inm/serializers.py index 7f050fc..0a44f79 100644 --- a/hb_server/apps/inm/serializers.py +++ b/hb_server/apps/inm/serializers.py @@ -2,6 +2,7 @@ from rest_framework import serializers from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse,Inventory from apps.qm.models import TestRecord, TestRecordItem +from apps.sam.serializers import OrderSimpleSerializer from apps.system.serializers import UserSimpleSerializer from apps.mtm.serializers import MaterialSimpleSerializer @@ -40,10 +41,18 @@ class MaterialBatchSerializer(serializers. ModelSerializer): class IProductListSerializer(serializers.ModelSerializer): material_= MaterialSimpleSerializer(source='material', read_only=True) warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True) + order_ = serializers.SerializerMethodField() class Meta: model = IProduct fields = '__all__' + def get_order_(self, obj): + if obj.wproduct: + order = obj.wproduct.subproduction_plan.production_plan.order + if order: + return OrderSimpleSerializer(instance=order).data + return None + class FIFOListSerializer(serializers.ModelSerializer): auditor_ = UserSimpleSerializer(source='auditor', read_only=True) diff --git a/hb_server/apps/inm/views.py b/hb_server/apps/inm/views.py index 6454c40..8f455e0 100644 --- a/hb_server/apps/inm/views.py +++ b/hb_server/apps/inm/views.py @@ -3,7 +3,7 @@ from rest_framework import serializers from rest_framework.exceptions import APIException from rest_framework.mixins import DestroyModelMixin, ListModelMixin, RetrieveModelMixin from rest_framework.viewsets import GenericViewSet, ModelViewSet -from apps.inm.filters import MbFilterSet +from apps.inm.filters import IProductFilterSet, MbFilterSet from apps.inm.models import FIFO, FIFOItem, IProduct, MaterialBatch, WareHouse,Inventory from apps.inm.serializers import FIFOItemSerializer, FIFOInPurSerializer, FIFOListSerializer, IProductListSerializer, InmTestRecordCreateSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, WareHouseCreateUpdateSerializer,InventorySerializer @@ -167,9 +167,9 @@ class IProductViewSet(ListModelMixin, GenericViewSet): 半成品库存表 """ perms_map = {'*': '*'} - queryset = IProduct.objects.select_related('material', 'warehouse').all() + queryset = IProduct.objects.select_related('material', 'warehouse', 'wproduct__subproduction_plan__production_plan__order').filter(is_saled=False) serializer_class = IProductListSerializer - filterset_fields = ['material', 'warehouse', 'batch'] + filterset_class = IProductFilterSet search_fields = [] ordering_fields = ['create_time'] ordering = ['-create_time'] \ No newline at end of file diff --git a/hb_server/apps/sam/migrations/0005_auto_20211203_1501.py b/hb_server/apps/sam/migrations/0005_auto_20211203_1501.py new file mode 100644 index 0000000..c819554 --- /dev/null +++ b/hb_server/apps/sam/migrations/0005_auto_20211203_1501.py @@ -0,0 +1,28 @@ +# Generated by Django 3.2.9 on 2021-12-03 07:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sam', '0004_order_planed_count'), + ] + + operations = [ + migrations.AddField( + model_name='order', + name='delivered_count', + field=models.PositiveIntegerField(default=0, verbose_name='交货数量'), + ), + migrations.AlterField( + model_name='order', + name='count', + field=models.PositiveIntegerField(default=0, verbose_name='所需数量'), + ), + migrations.AlterField( + model_name='order', + name='planed_count', + field=models.PositiveIntegerField(default=0, verbose_name='已排数量'), + ), + ] diff --git a/hb_server/apps/sam/migrations/0006_auto_20211206_0958.py b/hb_server/apps/sam/migrations/0006_auto_20211206_0958.py new file mode 100644 index 0000000..9b99454 --- /dev/null +++ b/hb_server/apps/sam/migrations/0006_auto_20211206_0958.py @@ -0,0 +1,65 @@ +# Generated by Django 3.2.9 on 2021-12-06 01:58 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('inm', '0020_iproduct_is_saled'), + ('mtm', '0041_alter_material_type'), + ('sam', '0005_auto_20211203_1501'), + ] + + operations = [ + migrations.AlterField( + model_name='order', + name='delivered_count', + field=models.PositiveIntegerField(default=0, verbose_name='已交货数量'), + ), + migrations.AlterField( + model_name='order', + name='number', + field=models.CharField(max_length=100, unique=True, verbose_name='订单编号'), + ), + migrations.CreateModel( + name='Sale', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')), + ('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')), + ('count', models.PositiveIntegerField(default=0, verbose_name='交货数量')), + ('is_audited', models.BooleanField(default=False, verbose_name='是否审核')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sale_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('customer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sam.customer', verbose_name='客户')), + ('order', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sam.order', verbose_name='关联订单')), + ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='所需产品')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sale_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='SaleProduct', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')), + ('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')), + ('number', models.CharField(max_length=50, unique=True, verbose_name='物品编号')), + ('is_mtested', models.BooleanField(default=False, verbose_name='是否军检')), + ('is_mtestok', models.BooleanField(default=True, verbose_name='是否军检合格')), + ('iproduct', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sale_iproduct', to='inm.iproduct', verbose_name='关联库存产品')), + ('sale', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sam.sale', verbose_name='关联销售记录')), + ], + options={ + 'unique_together': {('sale', 'iproduct')}, + }, + ), + ] diff --git a/hb_server/apps/sam/models.py b/hb_server/apps/sam/models.py index 583fe87..631a472 100644 --- a/hb_server/apps/sam/models.py +++ b/hb_server/apps/sam/models.py @@ -1,4 +1,4 @@ -from apps.system.models import CommonAModel +from apps.system.models import CommonADModel, CommonAModel from django.db import models from django.contrib.auth.models import AbstractUser from django.db.models.base import Model @@ -58,16 +58,47 @@ class Order(CommonAModel): """ 订单信息 """ - number = models.CharField('订单编号', max_length=100) + number = models.CharField('订单编号', max_length=100, unique=True) customer = models.ForeignKey(Customer, verbose_name='客户', on_delete=models.CASCADE) contract = models.ForeignKey(Contract, verbose_name='所属合同', null=True, blank=True, on_delete=models.SET_NULL) product = models.ForeignKey(Material, verbose_name='所需产品', on_delete=models.CASCADE) - count = models.IntegerField('所需数量', default=0) - planed_count = models.IntegerField('已排数量', default=0) + count = models.PositiveIntegerField('所需数量', default=0) + planed_count = models.PositiveIntegerField('已排数量', default=0) + delivered_count = models.PositiveIntegerField('已交货数量', default=0) delivery_date = models.DateField('交货日期') class Meta: verbose_name = '订单信息' verbose_name_plural = verbose_name def __str__(self): - return self.name \ No newline at end of file + return self.name + + +class Sale(CommonADModel): + """ + 销售记录 + """ + customer = models.ForeignKey(Customer, verbose_name='客户', on_delete=models.CASCADE) + order = models.ForeignKey(Order, verbose_name='关联订单', on_delete=models.CASCADE, null=True, blank=True) + product = models.ForeignKey(Material, verbose_name='所需产品', on_delete=models.CASCADE) + count = models.PositiveIntegerField('交货数量', default=0) + is_audited = models.BooleanField('是否审核', default=False) + + +class SaleProduct(BaseModel): + """ + 具体产品 + """ + sale = models.ForeignKey(Sale, verbose_name='关联销售记录', on_delete=models.CASCADE) + number = models.CharField('物品编号', unique=True, max_length=50) + iproduct = models.ForeignKey('inm.iproduct', verbose_name='关联库存产品', on_delete=models.CASCADE, related_name='sale_iproduct') + is_mtested = models.BooleanField('是否军检', default=False) + is_mtestok = models.BooleanField('是否军检合格', default=True) + + class Meta: + unique_together = ( + ('sale','iproduct'), # 联合唯一 + ) + + + diff --git a/hb_server/apps/sam/serializers.py b/hb_server/apps/sam/serializers.py index a4ed099..320ceed 100644 --- a/hb_server/apps/sam/serializers.py +++ b/hb_server/apps/sam/serializers.py @@ -1,6 +1,8 @@ from rest_framework import serializers -from .models import Contract, Customer, Order +from apps.inm.models import IProduct + +from .models import Contract, Customer, Order, Sale, SaleProduct from apps.mtm.serializers import MaterialSimpleSerializer @@ -54,3 +56,38 @@ class OrderSimpleSerializer(serializers.ModelSerializer): class Meta: model = Order fields = '__all__' + +class SaleCreateSerializer(serializers.ModelSerializer): + iproducts = serializers.PrimaryKeyRelatedField(queryset=IProduct.objects.all(), many=True) + class Meta: + model = Sale + fields = ['customer', 'order', 'product', 'iproducts'] + + def validate(self, attrs): + order = attrs.get('order', None) + if order: + if order.customer: + attrs['customer'] = order.customer + attrs['product'] = order.product + return super().validate(attrs) + + def create(self, validated_data): + iproducts = validated_data.pop('iproducts') + sale = Sale.objects.create(**validated_data) + i_l = [] + for i in iproducts: + i_d ={} + i_d['sale'] = sale + i_d['number'] = i.number + i_d['iproduct'] = i + i_l.append(SaleProduct(**i_d)) + SaleProduct.objects.bulk_create(i_l) + return sale + +class SaleListSerializer(serializers.ModelSerializer): + customer_ = CustomerSimpleSerializer(source='customer', read_only=True) + order_ = OrderSimpleSerializer(source='order', read_only=True) + product_ = MaterialSimpleSerializer(source='product', read_only=True) + class Meta: + model = Sale + fields = '__all__' diff --git a/hb_server/apps/sam/urls.py b/hb_server/apps/sam/urls.py index 4aa607f..2418046 100644 --- a/hb_server/apps/sam/urls.py +++ b/hb_server/apps/sam/urls.py @@ -1,6 +1,6 @@ from django.db.models import base from rest_framework import urlpatterns -from apps.sam.views import CustomerViewSet,ContractViewSet,OrderViewSet +from apps.sam.views import CustomerViewSet,ContractViewSet,OrderViewSet, SaleViewSet from django.urls import path, include from rest_framework.routers import DefaultRouter @@ -8,6 +8,7 @@ router = DefaultRouter() router.register('customer', CustomerViewSet, basename='customer') router.register('contract', ContractViewSet, basename='contract') router.register('order', OrderViewSet, basename='order') +router.register('sale', SaleViewSet, basename='sale') urlpatterns = [ path('', include(router.urls)), diff --git a/hb_server/apps/sam/views.py b/hb_server/apps/sam/views.py index 441e7fa..98bced6 100644 --- a/hb_server/apps/sam/views.py +++ b/hb_server/apps/sam/views.py @@ -1,6 +1,7 @@ -from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer -from apps.sam.models import Contract, Customer, Order -from rest_framework.viewsets import ModelViewSet +from rest_framework.mixins import CreateModelMixin, ListModelMixin, RetrieveModelMixin +from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer, SaleCreateSerializer, SaleListSerializer +from apps.sam.models import Contract, Customer, Order, Sale +from rest_framework.viewsets import GenericViewSet, ModelViewSet from apps.system.mixins import CreateUpdateCustomMixin from django.shortcuts import render from rest_framework.decorators import action @@ -57,7 +58,7 @@ class OrderViewSet(CreateUpdateCustomMixin, ModelViewSet): def get_serializer_class(self): if self.action in ['create', 'update']: return OrderCreateUpdateSerializer - return OrderSerializer + return super().get_serializer_class() @action(methods=['get'], detail=False, perms_map={'get':'*'}) def toplan(self, request, pk=None): @@ -67,4 +68,24 @@ class OrderViewSet(CreateUpdateCustomMixin, ModelViewSet): serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) - return Response(serializer.data) \ No newline at end of file + return Response(serializer.data) + + +class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, CreateModelMixin, GenericViewSet): + """ + 销售记录 + """ + perms_map = {'*': '*'} + queryset = Sale.objects.select_related('customer', 'order', 'product').all() + serializer_class = SaleListSerializer + search_fields = ['customer__name', 'order__number'] + filterset_fields = ['product', 'order', 'customer'] + ordering_fields = ['create_time'] + ordering = ['-create_time'] + + def get_serializer_class(self): + if self.action == 'create': + return SaleCreateSerializer + elif self.action == 'retrieve': + return SaleListSerializer + return super().get_serializer_class() \ No newline at end of file diff --git a/hb_server/apps/wf/migrations/0017_auto_20211203_1501.py b/hb_server/apps/wf/migrations/0017_auto_20211203_1501.py new file mode 100644 index 0000000..f5b3766 --- /dev/null +++ b/hb_server/apps/wf/migrations/0017_auto_20211203_1501.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.9 on 2021-12-03 07:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('wf', '0016_auto_20211024_2349'), + ] + + operations = [ + migrations.AlterField( + model_name='customfield', + name='field_type', + field=models.CharField(choices=[('string', '字符串'), ('int', '整型'), ('float', '浮点'), ('boolean', '布尔'), ('date', '日期'), ('datetime', '日期时间'), ('radio', '单选'), ('checkbox', '多选'), ('select', '单选下拉'), ('selects', '多选下拉'), ('textarea', '文本域'), ('selectuser', '单选用户'), ('selectusers', '多选用户'), ('file', '附件'), ('draw', '绘图')], help_text='5.字符串,10.整形,15.浮点型,20.布尔,25.日期,30.日期时间,35.单选框,40.多选框,45.下拉列表,50.多选下拉列表,55.文本域,60.用户名, 70.多选的用户名, 80.附件(只保存路径,多个使用逗号隔开)', max_length=50, verbose_name='类型'), + ), + migrations.AlterField( + model_name='ticket', + name='ticket_data', + field=models.JSONField(default=dict, help_text='工单自定义字段内容', verbose_name='工单数据'), + ), + ] diff --git a/hb_server/apps/wf/models.py b/hb_server/apps/wf/models.py index a9ae071..bc1597c 100644 --- a/hb_server/apps/wf/models.py +++ b/hb_server/apps/wf/models.py @@ -152,7 +152,8 @@ class CustomField(CommonAModel): ('textarea', '文本域'), ('selectuser', '单选用户'), ('selectusers', '多选用户'), - ('file', '附件') + ('file', '附件'), + ('draw', '绘图') ) workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE, verbose_name='所属工作流') field_type = models.CharField('类型', max_length=50, choices=field_type_choices, help_text='5.字符串,10.整形,15.浮点型,20.布尔,25.日期,30.日期时间,35.单选框,40.多选框,45.下拉列表,50.多选下拉列表,55.文本域,60.用户名, 70.多选的用户名, 80.附件(只保存路径,多个使用逗号隔开)') @@ -201,7 +202,7 @@ class Ticket(CommonBModel): state = models.ForeignKey(State, on_delete=models.CASCADE, verbose_name='当前状态', related_name='ticket_state') parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE, verbose_name='父工单') parent_state = models.ForeignKey(State, null=True, blank=True, on_delete=models.CASCADE, verbose_name='父工单状态', related_name='ticket_parent_state') - ticket_data = models.JSONField('工单数据', default=dict, help_text='工单所有字段内容') + ticket_data = models.JSONField('工单数据', default=dict, help_text='工单自定义字段内容') in_add_node = models.BooleanField('加签状态中', default=False, help_text='是否处于加签状态下') add_node_man = models.ForeignKey(User, verbose_name='加签人', on_delete=models.SET_NULL, null=True, blank=True, help_text='加签操作的人,工单当前处理人处理完成后会回到该处理人,当处于加签状态下才有效') @@ -211,16 +212,17 @@ class Ticket(CommonBModel): multi_all_person = models.JSONField('全部处理的结果', default=dict, blank=True, help_text='需要当前状态处理人全部处理时实际的处理结果,json格式') -class TicketData(): - """ - 工单数据,自定义字段值 - """ - form_field = models.ForeignKey(CustomField, verbose_name='关联字段', on_delete=models.SET_NULL, db_constraint=False, null=True, blank=True) - field_name = models.CharField('字段名', max_length=50) - field_key = models.CharField('字段标识', max_length=50) - field_type = models.CharField('字段类型', choices=CustomField.field_type_choices, max_length=50) - field_value = models.JSONField('录入值', default=dict, blank=True) - sort = models.IntegerField('排序号', default=1) +# class TicketCustomField(BaseModel): +# """ +# 工单数据,自定义字段值 +# """ +# ticket = models.ForeignKey(Ticket, verbose_name='关联工单', on_delete=models.CASCADE) +# form_field = models.ForeignKey(CustomField, verbose_name='关联字段', on_delete=models.SET_NULL, db_constraint=False, null=True, blank=True) +# field_name = models.CharField('字段名', max_length=50) +# field_key = models.CharField('字段标识', max_length=50) +# field_type = models.CharField('字段类型', choices=CustomField.field_type_choices, max_length=50) +# field_value = models.JSONField('录入值', default=dict, blank=True) +# sort = models.IntegerField('排序号', default=1) class TicketFlow(BaseModel): """ From 4fe19e3a6af437f01aa78f773f3f3d351887d2fe Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 6 Dec 2021 10:20:33 +0800 Subject: [PATCH 02/17] =?UTF-8?q?sale=20=E4=BA=8B=E5=8A=A1=E6=80=A7?= =?UTF-8?q?=E5=88=9B=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/sam/serializers.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hb_server/apps/sam/serializers.py b/hb_server/apps/sam/serializers.py index 320ceed..b28a913 100644 --- a/hb_server/apps/sam/serializers.py +++ b/hb_server/apps/sam/serializers.py @@ -1,3 +1,4 @@ +from django.db import transaction from rest_framework import serializers from apps.inm.models import IProduct @@ -71,6 +72,7 @@ class SaleCreateSerializer(serializers.ModelSerializer): attrs['product'] = order.product return super().validate(attrs) + @transaction.atomic def create(self, validated_data): iproducts = validated_data.pop('iproducts') sale = Sale.objects.create(**validated_data) From e83c5ff59f18294a2511334fa0591db4e7432540 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 6 Dec 2021 10:21:18 +0800 Subject: [PATCH 03/17] =?UTF-8?q?sale=20=E5=88=9B=E5=BB=BAbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/sam/serializers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/hb_server/apps/sam/serializers.py b/hb_server/apps/sam/serializers.py index b28a913..e4ce902 100644 --- a/hb_server/apps/sam/serializers.py +++ b/hb_server/apps/sam/serializers.py @@ -75,6 +75,7 @@ class SaleCreateSerializer(serializers.ModelSerializer): @transaction.atomic def create(self, validated_data): iproducts = validated_data.pop('iproducts') + validated_data['count'] = len(iproducts) sale = Sale.objects.create(**validated_data) i_l = [] for i in iproducts: From 7555ef9dba69f025476be0062ce8d55b61fd821d Mon Sep 17 00:00:00 2001 From: shijing Date: Mon, 6 Dec 2021 13:18:20 +0800 Subject: [PATCH 04/17] needCheckForm --- hb_client/src/components/customForm/index.vue | 181 +++- hb_client/src/views/wpm/need.vue | 866 ++++++++---------- 2 files changed, 530 insertions(+), 517 deletions(-) diff --git a/hb_client/src/components/customForm/index.vue b/hb_client/src/components/customForm/index.vue index 7fcfd50..416696f 100644 --- a/hb_client/src/components/customForm/index.vue +++ b/hb_client/src/components/customForm/index.vue @@ -19,7 +19,7 @@ @@ -68,7 +68,7 @@ placeholder="选择日期" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" - @change="keyChange(item.field_key)" + @change="keyChange($index,item.field_key)" /> @@ -80,7 +80,7 @@ v-model="checkForm[item.field_key]" style="width: 100%" placeholder="请选择" - @change="keyChange(item.field_key)" + @change="keyChange($index,item.field_key)" > @@ -135,11 +137,22 @@ -
- - 合格验证 - -
+ + + + + 检查合格 + 检查不合格 + + + + @@ -159,6 +172,10 @@ type:Number, default:0 }, + wproduct: { + type:Number, + default:0 + }, hasPicture:{ type:Boolean, default:false @@ -167,24 +184,28 @@ mounted() { let that = this; this.form = this.formID; - // debugger; - // console.log(this.results); - this.formData=this.results; - this.formData=[...this.formData]; + let formData=this.results; + that.wproductId=this.wproduct; + formData.forEach(item => { + let obj = new Object(); + obj = item; + obj.is_testok = true;//是否合格 + that.formData.push(obj) + }); + that.formData=[...that.formData]; + for(let i=0;i { return item.need_judge === true; }); listJudge.forEach(item => { let obj = new Object(); obj = item; - obj.judge = false; that.judgeList.push(obj) }); setTimeout(function(){ @@ -193,8 +214,16 @@ }, data(){ return{ + field:[], checkForm:{}, + testrecord:{ + form:this.formID, + record_data:[], + is_testok:true, + wproduct:null, + }, canvas:null, + wproductId:null, ctx:null, myCanvas_rect:null, Txt:null, @@ -207,6 +236,9 @@ canvasImg:'', formData:[],//表单数组 judgeList:[],//判定数组 + is_testok:true, + testokTrue:true, + testokFalse:false, } }, methods:{ @@ -276,15 +308,63 @@ return true; } }, - keyChange(key){ - key; - this.$forceUpdate(); - /* debugger; - let y = this.checkForm[key]; - this.$set(this.checkForm,key,y);*/ - // this.filterBlock(); + keyChange(index,key){ + let that = this; + let reg = /\{(.+?)\}/g; + that.$forceUpdate(); + that.$nextTick(()=>{ + if(that.formData[index].need_judge===true){ + let arr = [],str = ''; + let item = that.formData[index].rule_expression.replace(/`/g,''); + if(item.indexOf('||')>-1){ + arr = item.split('||'); + }else if(item.indexOf('&&')>-1){ + arr = item.split('&&'); + }else{ + arr.push(item); + } + //对每个条件进行判定,如果符合, + for (let i = 0;i-1){ + if(str.indexOf('false')>-1){ + that.formData[index].is_testok = true; + }else{ + that.formData[index].is_testok = false; + } + }else{ + if(str.indexOf('true')>-1){ + that.formData[index].is_testok = false; + }else{ + that.formData[index].is_testok = true; + } + } + }else{ + that.formData[index].is_testok = true; + } + that.judgeList = that.formData.filter(item => { + return item.need_judge === true; + }); + that.judgeForm(); + }) }, - /* base64ToFile */ + /* 图片保存 */ + //初始化canvas canvasInit(){ let that = this; preDrawAry = []; @@ -299,6 +379,7 @@ that.draw(); },500); }, + //画布添加背景模板图 draw(){ let canvasImg = document.getElementById("canvasImg"); canvasImg.style.width = '500px'; @@ -360,7 +441,6 @@ } } }, - // 文字 word1(){ let canvas3 = document.getElementById('canvas'); @@ -462,6 +542,7 @@ // console.log(res); }) }, + //base64ToFile base64ToFile(baseUrl) { let arr = baseUrl.split(','); // let type = arr[0].match(/:(.*?);/)[1]; // 解锁图片类型 @@ -474,7 +555,8 @@ // let fileOfBlob = new File([bufferArray], new Date()+'.jpg'); return new File([bufferArray ],'draw.jpg'); }, - /* base64ToFile */ + /* 图片保存 */ + //最终表格判定 judgeForm(){ let that = this , reg = /\{(.+?)\}/g, @@ -508,21 +590,56 @@ } } } - if(str.indexOf('true')>-1){ - that.judgeList[i].judge = true; + if(item.indexOf('&&')>-1){ + if(str.indexOf('false')>-1){ + that.judgeList[i].is_testok = true; + }else{ + that.judgeList[i].is_testok = false; + } }else{ - that.judgeList[i].judge = false; + if(str.indexOf('true')>-1){ + that.judgeList[i].is_testok = false; + }else{ + that.judgeList[i].is_testok = true; + } } } let real = that.judgeList.filter(item=>{ - return item.judge==true; + return item.is_testok===false; }); if(real.length>0){ + that.is_testok = false; alert("检验不合格!") }else{ + that.is_testok = true; alert("检验合格!") } }, + //提交检查项目 + submitfield() { + let that = this; + debugger; + console.log(that.checkForm); + debugger; + that.field = []; //检查项目 + that.formData.forEach((item) => { + debugger; + console.log(that.checkForm[item.field_key]); + debugger; + that.field.push({ + form_field: item.id, + field_value: that.checkForm[item.field_key], + is_testok: item.is_testok//单项检查结果 + }); + }); + console.log(that.field); + debugger; + that.testrecord.form = that.formID;//检查表 + that.testrecord.record_data = that.field;//检查项列表 + that.testrecord.is_testok = that.is_testok;//检查表检查结果 + that.testrecord.wproduct = that.wproductId;//半成品ID + this.$emit('formFunc',that.testrecord); + }, } } diff --git a/hb_client/src/views/wpm/need.vue b/hb_client/src/views/wpm/need.vue index 37be5ee..c0764b2 100644 --- a/hb_client/src/views/wpm/need.vue +++ b/hb_client/src/views/wpm/need.vue @@ -1,152 +1,155 @@ From 332c4b7729208ccd8e26159778837c8ee0963f9d Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 6 Dec 2021 13:26:41 +0800 Subject: [PATCH 05/17] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=86=9B=E6=A3=80?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/inm/serializers.py | 9 ---- .../sam/migrations/0007_saleproduct_remark.py | 18 ++++++++ hb_server/apps/sam/models.py | 1 + hb_server/apps/sam/serializers.py | 21 ++++++++++ hb_server/apps/sam/views.py | 41 ++++++++++++++++--- 5 files changed, 76 insertions(+), 14 deletions(-) create mode 100644 hb_server/apps/sam/migrations/0007_saleproduct_remark.py diff --git a/hb_server/apps/inm/serializers.py b/hb_server/apps/inm/serializers.py index 0a44f79..7f050fc 100644 --- a/hb_server/apps/inm/serializers.py +++ b/hb_server/apps/inm/serializers.py @@ -2,7 +2,6 @@ from rest_framework import serializers from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse,Inventory from apps.qm.models import TestRecord, TestRecordItem -from apps.sam.serializers import OrderSimpleSerializer from apps.system.serializers import UserSimpleSerializer from apps.mtm.serializers import MaterialSimpleSerializer @@ -41,18 +40,10 @@ class MaterialBatchSerializer(serializers. ModelSerializer): class IProductListSerializer(serializers.ModelSerializer): material_= MaterialSimpleSerializer(source='material', read_only=True) warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True) - order_ = serializers.SerializerMethodField() class Meta: model = IProduct fields = '__all__' - def get_order_(self, obj): - if obj.wproduct: - order = obj.wproduct.subproduction_plan.production_plan.order - if order: - return OrderSimpleSerializer(instance=order).data - return None - class FIFOListSerializer(serializers.ModelSerializer): auditor_ = UserSimpleSerializer(source='auditor', read_only=True) diff --git a/hb_server/apps/sam/migrations/0007_saleproduct_remark.py b/hb_server/apps/sam/migrations/0007_saleproduct_remark.py new file mode 100644 index 0000000..846c3bc --- /dev/null +++ b/hb_server/apps/sam/migrations/0007_saleproduct_remark.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2021-12-06 05:26 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sam', '0006_auto_20211206_0958'), + ] + + operations = [ + migrations.AddField( + model_name='saleproduct', + name='remark', + field=models.TextField(blank=True, null=True, verbose_name='备注'), + ), + ] diff --git a/hb_server/apps/sam/models.py b/hb_server/apps/sam/models.py index 631a472..774b3ef 100644 --- a/hb_server/apps/sam/models.py +++ b/hb_server/apps/sam/models.py @@ -94,6 +94,7 @@ class SaleProduct(BaseModel): iproduct = models.ForeignKey('inm.iproduct', verbose_name='关联库存产品', on_delete=models.CASCADE, related_name='sale_iproduct') is_mtested = models.BooleanField('是否军检', default=False) is_mtestok = models.BooleanField('是否军检合格', default=True) + remark = models.TextField('备注', null=True, blank=True) class Meta: unique_together = ( diff --git a/hb_server/apps/sam/serializers.py b/hb_server/apps/sam/serializers.py index e4ce902..1087e23 100644 --- a/hb_server/apps/sam/serializers.py +++ b/hb_server/apps/sam/serializers.py @@ -2,6 +2,7 @@ from django.db import transaction from rest_framework import serializers from apps.inm.models import IProduct +from apps.inm.serializers import IProductListSerializer from .models import Contract, Customer, Order, Sale, SaleProduct @@ -94,3 +95,23 @@ class SaleListSerializer(serializers.ModelSerializer): class Meta: model = Sale fields = '__all__' + +class SaleProductListSerializer(serializers.ModelSerializer): + iproduct_ = IProductListSerializer(source='iproduct', read_only=True) + class Meta: + model = SaleProduct + fields = '__all__' + +class SaleProductCreateSerializer(serializers.ModelSerializer): + class Meta: + model = SaleProduct + fields = ['sale', 'iproduct'] + + def create(self, validated_data): + validated_data['number'] = validated_data['iproduct'].number + return super().create(validated_data) + +class SaleProductMtestSerializer(serializers.ModelSerializer): + class Meta: + model = SaleProduct + fields = ['remark', 'is_mtestok'] \ No newline at end of file diff --git a/hb_server/apps/sam/views.py b/hb_server/apps/sam/views.py index 98bced6..4ac3eff 100644 --- a/hb_server/apps/sam/views.py +++ b/hb_server/apps/sam/views.py @@ -1,6 +1,7 @@ -from rest_framework.mixins import CreateModelMixin, ListModelMixin, RetrieveModelMixin -from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer, SaleCreateSerializer, SaleListSerializer -from apps.sam.models import Contract, Customer, Order, Sale +from rest_framework import exceptions +from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin +from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer, SaleCreateSerializer, SaleListSerializer, SaleProductCreateSerializer, SaleProductListSerializer +from apps.sam.models import Contract, Customer, Order, Sale, SaleProduct from rest_framework.viewsets import GenericViewSet, ModelViewSet from apps.system.mixins import CreateUpdateCustomMixin from django.shortcuts import render @@ -76,7 +77,7 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C 销售记录 """ perms_map = {'*': '*'} - queryset = Sale.objects.select_related('customer', 'order', 'product').all() + queryset = Sale.objects.select_related('customer', 'order', 'product', 'order__contract').all() serializer_class = SaleListSerializer search_fields = ['customer__name', 'order__number'] filterset_fields = ['product', 'order', 'customer'] @@ -88,4 +89,34 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C return SaleCreateSerializer elif self.action == 'retrieve': return SaleListSerializer - return super().get_serializer_class() \ No newline at end of file + return super().get_serializer_class() + +class SaleProductViewSet(ListModelMixin, DestroyModelMixin, CreateModelMixin, GenericViewSet): + """ + 销售记录关联产品 + """ + perms_map = {'*': '*'} + queryset = SaleProduct.objects.select_related('iproduct', 'iproduct__material', 'iproduct__warehouse').all() + serializer_class = SaleProductListSerializer + search_fields = [] + filterset_fields = ['sale', 'iproduct'] + ordering_fields = ['create_time'] + ordering = ['id'] + + def get_serializer_class(self): + if self.action == 'create': + return SaleProductCreateSerializer + return super().get_serializer_class() + + @action(methods=['post'], detail=True, perms_map={'post':'*'}) + def mtest(self, request, pk=None): + """ + 军检 + """ + obj = self.get_object() + if obj.is_mtested: + raise exceptions.APIException('已进行军检') + obj.remark = request.data.get('remark', None) + obj.is_mtestok = request.data.get('is_mtestok') + obj.save() + return Response() \ No newline at end of file From 0f65b1ff8a0e3d07c03b098964bffe0db26e3d81 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 6 Dec 2021 13:39:40 +0800 Subject: [PATCH 06/17] =?UTF-8?q?safeproduct=20=E5=88=9B=E5=BB=BA=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E6=8E=A5=E5=8F=A3=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/sam/serializers.py | 5 ++++- hb_server/apps/sam/views.py | 25 ++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/hb_server/apps/sam/serializers.py b/hb_server/apps/sam/serializers.py index 1087e23..6f4bb6a 100644 --- a/hb_server/apps/sam/serializers.py +++ b/hb_server/apps/sam/serializers.py @@ -109,7 +109,10 @@ class SaleProductCreateSerializer(serializers.ModelSerializer): def create(self, validated_data): validated_data['number'] = validated_data['iproduct'].number - return super().create(validated_data) + instance = SaleProduct.objects.create(**validated_data) + instance.sale.count = SaleProduct.objects.filter(sale=instance.sale).count() + instance.sale.save() + return instance class SaleProductMtestSerializer(serializers.ModelSerializer): class Meta: diff --git a/hb_server/apps/sam/views.py b/hb_server/apps/sam/views.py index 4ac3eff..e613147 100644 --- a/hb_server/apps/sam/views.py +++ b/hb_server/apps/sam/views.py @@ -1,6 +1,6 @@ -from rest_framework import exceptions +from rest_framework import exceptions, serializers from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin -from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer, SaleCreateSerializer, SaleListSerializer, SaleProductCreateSerializer, SaleProductListSerializer +from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer, SaleCreateSerializer, SaleListSerializer, SaleProductCreateSerializer, SaleProductListSerializer, SaleProductMtestSerializer from apps.sam.models import Contract, Customer, Order, Sale, SaleProduct from rest_framework.viewsets import GenericViewSet, ModelViewSet from apps.system.mixins import CreateUpdateCustomMixin @@ -90,6 +90,18 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C elif self.action == 'retrieve': return SaleListSerializer return super().get_serializer_class() + + @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=serializers.Serializer) + def audit(self, request, pk=None): + """ + 审核 + """ + obj = self.get_object() + if obj.is_audited: + raise exceptions.APIException('已审核通过') + # 创建出库记录 + # 更新库存 + return Response() class SaleProductViewSet(ListModelMixin, DestroyModelMixin, CreateModelMixin, GenericViewSet): """ @@ -107,8 +119,15 @@ class SaleProductViewSet(ListModelMixin, DestroyModelMixin, CreateModelMixin, Ge if self.action == 'create': return SaleProductCreateSerializer return super().get_serializer_class() + + def destroy(self, request, *args, **kwargs): + obj = self.get_object() + obj.sale.count = SaleProduct.objects.filter(sale=obj.sale).count() + obj.sale.save() + obj.delete() + return Response() - @action(methods=['post'], detail=True, perms_map={'post':'*'}) + @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=SaleProductMtestSerializer) def mtest(self, request, pk=None): """ 军检 From c451a5350094a20fcec71a3a34c819c4e3c52182 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 6 Dec 2021 14:39:03 +0800 Subject: [PATCH 07/17] =?UTF-8?q?sale=20=E5=88=9B=E5=BB=BA=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0008_alter_saleproduct_number.py | 18 +++++++++ hb_server/apps/sam/models.py | 5 +-- hb_server/apps/sam/serializers.py | 14 ------- hb_server/apps/sam/views.py | 38 ++++++++++++++++++- 4 files changed, 56 insertions(+), 19 deletions(-) create mode 100644 hb_server/apps/sam/migrations/0008_alter_saleproduct_number.py diff --git a/hb_server/apps/sam/migrations/0008_alter_saleproduct_number.py b/hb_server/apps/sam/migrations/0008_alter_saleproduct_number.py new file mode 100644 index 0000000..72e87f2 --- /dev/null +++ b/hb_server/apps/sam/migrations/0008_alter_saleproduct_number.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2021-12-06 06:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sam', '0007_saleproduct_remark'), + ] + + operations = [ + migrations.AlterField( + model_name='saleproduct', + name='number', + field=models.CharField(max_length=50, verbose_name='物品编号'), + ), + ] diff --git a/hb_server/apps/sam/models.py b/hb_server/apps/sam/models.py index 774b3ef..bb0fb8e 100644 --- a/hb_server/apps/sam/models.py +++ b/hb_server/apps/sam/models.py @@ -69,9 +69,6 @@ class Order(CommonAModel): class Meta: verbose_name = '订单信息' verbose_name_plural = verbose_name - - def __str__(self): - return self.name class Sale(CommonADModel): @@ -90,7 +87,7 @@ class SaleProduct(BaseModel): 具体产品 """ sale = models.ForeignKey(Sale, verbose_name='关联销售记录', on_delete=models.CASCADE) - number = models.CharField('物品编号', unique=True, max_length=50) + number = models.CharField('物品编号', max_length=50) iproduct = models.ForeignKey('inm.iproduct', verbose_name='关联库存产品', on_delete=models.CASCADE, related_name='sale_iproduct') is_mtested = models.BooleanField('是否军检', default=False) is_mtestok = models.BooleanField('是否军检合格', default=True) diff --git a/hb_server/apps/sam/serializers.py b/hb_server/apps/sam/serializers.py index 6f4bb6a..d321616 100644 --- a/hb_server/apps/sam/serializers.py +++ b/hb_server/apps/sam/serializers.py @@ -73,20 +73,6 @@ class SaleCreateSerializer(serializers.ModelSerializer): attrs['product'] = order.product return super().validate(attrs) - @transaction.atomic - def create(self, validated_data): - iproducts = validated_data.pop('iproducts') - validated_data['count'] = len(iproducts) - sale = Sale.objects.create(**validated_data) - i_l = [] - for i in iproducts: - i_d ={} - i_d['sale'] = sale - i_d['number'] = i.number - i_d['iproduct'] = i - i_l.append(SaleProduct(**i_d)) - SaleProduct.objects.bulk_create(i_l) - return sale class SaleListSerializer(serializers.ModelSerializer): customer_ = CustomerSimpleSerializer(source='customer', read_only=True) diff --git a/hb_server/apps/sam/views.py b/hb_server/apps/sam/views.py index e613147..624aa2d 100644 --- a/hb_server/apps/sam/views.py +++ b/hb_server/apps/sam/views.py @@ -1,5 +1,7 @@ +from django.db import transaction from rest_framework import exceptions, serializers from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin +from apps.inm.models import FIFO from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer, SaleCreateSerializer, SaleListSerializer, SaleProductCreateSerializer, SaleProductListSerializer, SaleProductMtestSerializer from apps.sam.models import Contract, Customer, Order, Sale, SaleProduct from rest_framework.viewsets import GenericViewSet, ModelViewSet @@ -8,6 +10,7 @@ from django.shortcuts import render from rest_framework.decorators import action from django.db.models import F from rest_framework.response import Response +from django.utils import timezone # Create your views here. class CustomerViewSet(CreateUpdateCustomMixin, ModelViewSet): """ @@ -90,8 +93,28 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C elif self.action == 'retrieve': return SaleListSerializer return super().get_serializer_class() - + + def create(self, request, *args, **kwargs): + data = request.data + serializer = SaleCreateSerializer(data=data) + serializer.is_valid(raise_exception=True) + vdata = serializer.validated_data + with transaction.atomic(): + iproducts = vdata.pop('iproducts') + vdata['count'] = len(iproducts) + sale = Sale.objects.create(**vdata) + i_l = [] + for i in iproducts: + i_d ={} + i_d['sale'] = sale + i_d['number'] = i.number + i_d['iproduct'] = i + i_l.append(SaleProduct(**i_d)) + SaleProduct.objects.bulk_create(i_l) + return Response() + @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=serializers.Serializer) + @transaction.atomic def audit(self, request, pk=None): """ 审核 @@ -100,6 +123,19 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C if obj.is_audited: raise exceptions.APIException('已审核通过') # 创建出库记录 + fifo = FIFO() + fifo.type = FIFO.FIFO_TYPE_SALE_OUT + fifo.is_audited = True + fifo.auditor = request.user + fifo.inout_date = timezone.now() + fifo.save() + # 出库条目 + spds = SaleProduct.objects.filter(sale=obj) + for i in spds: + if i.is_mtested and i.is_mtestok: + pass + else: + raise exceptions.APIException('存在未军检产品') # 更新库存 return Response() From 87369611bb28a262ae5b4c6cba60fe3680e218e0 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 6 Dec 2021 14:48:00 +0800 Subject: [PATCH 08/17] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=9C=AA=E4=BD=BF=E7=94=A8serializer.vdata=E7=9A=84=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/mtm/serializers.py | 6 +++--- hb_server/apps/wpm/views.py | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/hb_server/apps/mtm/serializers.py b/hb_server/apps/mtm/serializers.py index 153971f..f00b95d 100644 --- a/hb_server/apps/mtm/serializers.py +++ b/hb_server/apps/mtm/serializers.py @@ -209,13 +209,13 @@ class RecordFormDetailSerializer(serializers.ModelSerializer): def get_form_fields(self, obj): serializer = RecordFormFieldSerializer(instance=RecordFormField.objects.filter(form=obj, is_deleted=False), many=True) - vdata = serializer.data + data = serializer.data if obj.type == RecordForm.RF_TYPE_TEST: - for i in vdata: + for i in data: if i['need_judge']: i['is_testok'] = False i['is_teskok_robot'] = False - return serializer.data + return data class RecordFormFieldCreateSerializer(serializers.ModelSerializer): diff --git a/hb_server/apps/wpm/views.py b/hb_server/apps/wpm/views.py index 9d3b427..40b4b93 100644 --- a/hb_server/apps/wpm/views.py +++ b/hb_server/apps/wpm/views.py @@ -58,7 +58,7 @@ class WPlanViewSet(ListModelMixin, GenericViewSet): elif request.method=='POST': serializer= PickHalfsSerializer(data=request.data) serializer.is_valid(raise_exception=True) - vdata = serializer.data + vdata = serializer.validated_data first_step = Step.objects.get(pk=sp.steps[0]['id']) # 创建领料记录 pick = Pick() @@ -68,12 +68,12 @@ class WPlanViewSet(ListModelMixin, GenericViewSet): pick.save() for i in vdata: if 'wproducts' in i and len(i['wproducts'])>0: - spp = SubProductionProgress.objects.get(pk=i['id']) + spp = i['id'] spp.count_pick = spp.count_pick + len(i['wproducts']) # if spp.count_pick > spp.count: # raise exceptions.APIException('超过计划数') spp.save() - wps = WProduct.objects.filter(pk__in=[x for x in i['wproducts']], act_state=WProduct.WPR_ACT_STATE_OK) + wps = WProduct.objects.filter(pk__in=[x.id for x in i['wproducts']], act_state=WProduct.WPR_ACT_STATE_OK) wps.update(step=first_step, act_state=WProduct.WPR_ACT_STATE_TORETEST, is_hidden=False, warehouse=None, subproduction_plan=sp, update_by=request.user, update_time=timezone.now()) @@ -99,11 +99,11 @@ class WPlanViewSet(ListModelMixin, GenericViewSet): """ serializer= WplanPutInSerializer(data=request.data) serializer.is_valid(raise_exception=True) - vdata = serializer.data + vdata = serializer.validated_data subplan = self.get_object() material = subplan.main_product batch = subplan.number - warehouse = WareHouse.objects.get(id=vdata['warehouse']) + warehouse = vdata['warehouse'] wproducts = WProduct.objects.filter(subproduction_plan=subplan, act_state=WProduct.WPR_ACT_STATE_OK, material=material, is_deleted=False) if wproducts.exists(): @@ -253,9 +253,9 @@ class WProductViewSet(ListModelMixin, GenericViewSet): """ serializer= WproductPutInsSerializer(data=request.data) serializer.is_valid(raise_exception=True) - vdata = serializer.data - wproducts = WProduct.objects.filter(pk__in=[x for x in vdata['wproducts']]) - warehouse = WareHouse.objects.get(id=vdata['warehouse']) + vdata = serializer.validated_data + wproducts = WProduct.objects.filter(pk__in=[x.id for x in vdata['wproducts']]) + warehouse = vdata['warehouse'] for i in wproducts: if i.act_state is not WProduct.WPR_ACT_STATE_OK: raise exceptions.APIException('存在不可入库半成品') @@ -267,12 +267,12 @@ class WProductViewSet(ListModelMixin, GenericViewSet): is_audited=True, auditor=request.user, inout_date=timezone.now(), create_by=request.user, remark=remark) # 创建入库明细 for i in wproducts_a: - spi = SubProductionPlan.objects.get(pk=i['subproduction_plan']) + spi = i['subproduction_plan'] fifoitem = FIFOItem() fifoitem.is_tested = True fifoitem.is_testok = True fifoitem.warehouse = warehouse - fifoitem.material = Material.objects.get(pk=i['material']) + fifoitem.material = i['material'] fifoitem.count = i['total'] fifoitem.batch = spi.number fifoitem.fifo = fifo @@ -303,9 +303,9 @@ class WProductViewSet(ListModelMixin, GenericViewSet): """ serializer= WproductPutInSerializer(data=request.data) serializer.is_valid(raise_exception=True) - vdata = serializer.data + vdata = serializer.validated_data wproduct = self.get_object() - warehouse = WareHouse.objects.get(id=vdata['warehouse']) + warehouse = vdata['warehouse'] if wproduct.act_state != WProduct.WPR_ACT_STATE_OK: raise exceptions.APIException('半成品不可入库') material = wproduct.material @@ -598,11 +598,11 @@ class OperationRecordViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet): def submit(self, request, pk=None): serializer = OperationRecordSubmitSerializer(data=request.data, context={'request':self.request}) serializer.is_valid(raise_exception=True) - vdata = serializer.data + vdata = serializer.validated_data opr = self.get_object() wrds = [] for m in vdata['record_data']: # 保存记录详情 - form_field = RecordFormField.objects.get(pk=m['form_field']) + form_field = m['form_field'] m['form_field'] = form_field m['field_name'] = form_field.field_name m['field_key'] = form_field.field_key From ac4063d97e24ca2ef050861d832b5c79412da256 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 6 Dec 2021 14:59:34 +0800 Subject: [PATCH 09/17] =?UTF-8?q?sale=5Fproduct=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/sam/serializers.py | 5 ++++- hb_server/apps/sam/urls.py | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/hb_server/apps/sam/serializers.py b/hb_server/apps/sam/serializers.py index d321616..eb3a840 100644 --- a/hb_server/apps/sam/serializers.py +++ b/hb_server/apps/sam/serializers.py @@ -1,5 +1,5 @@ from django.db import transaction -from rest_framework import serializers +from rest_framework import exceptions, serializers from apps.inm.models import IProduct from apps.inm.serializers import IProductListSerializer @@ -71,6 +71,9 @@ class SaleCreateSerializer(serializers.ModelSerializer): if order.customer: attrs['customer'] = order.customer attrs['product'] = order.product + for i in attrs['iproducts']: + if i.material is not attrs['product']: + raise exceptions.APIException('产品选取错误') return super().validate(attrs) diff --git a/hb_server/apps/sam/urls.py b/hb_server/apps/sam/urls.py index 2418046..7a66e01 100644 --- a/hb_server/apps/sam/urls.py +++ b/hb_server/apps/sam/urls.py @@ -1,6 +1,6 @@ from django.db.models import base from rest_framework import urlpatterns -from apps.sam.views import CustomerViewSet,ContractViewSet,OrderViewSet, SaleViewSet +from apps.sam.views import CustomerViewSet,ContractViewSet,OrderViewSet, SaleProductViewSet, SaleViewSet from django.urls import path, include from rest_framework.routers import DefaultRouter @@ -9,6 +9,7 @@ router.register('customer', CustomerViewSet, basename='customer') router.register('contract', ContractViewSet, basename='contract') router.register('order', OrderViewSet, basename='order') router.register('sale', SaleViewSet, basename='sale') +router.register('sale_product', SaleProductViewSet, basename='sale_product') urlpatterns = [ path('', include(router.urls)), From 68162baacce1be16922cdc3beeb2ba6049bd7d98 Mon Sep 17 00:00:00 2001 From: shijing Date: Mon, 6 Dec 2021 15:31:20 +0800 Subject: [PATCH 10/17] need.vue --- hb_client/src/views/wpm/need.vue | 676 ++++++++++++++++--------------- 1 file changed, 345 insertions(+), 331 deletions(-) diff --git a/hb_client/src/views/wpm/need.vue b/hb_client/src/views/wpm/need.vue index b5f6bf7..4ed28d8 100644 --- a/hb_client/src/views/wpm/need.vue +++ b/hb_client/src/views/wpm/need.vue @@ -78,49 +78,51 @@ - - - - - - - - - - 批量入库 - + + + + + + + + + 批量入库 + + - - - - - - + > + + + + + + @@ -158,15 +160,13 @@ - + + > @@ -190,308 +190,322 @@ - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + + From cf1759c7444b16e24ba7672c8642d0ff30ee9ce0 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 7 Dec 2021 08:43:28 +0800 Subject: [PATCH 11/17] =?UTF-8?q?is=5Fmtestok=20=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E4=B8=BA=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0021_fifoitemproduct_iproduct.py | 19 +++++++++++ hb_server/apps/inm/models.py | 21 +++++++----- .../0009_alter_saleproduct_is_mtestok.py | 18 ++++++++++ hb_server/apps/sam/models.py | 2 +- hb_server/apps/sam/views.py | 33 +++++++++++++++++-- 5 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 hb_server/apps/inm/migrations/0021_fifoitemproduct_iproduct.py create mode 100644 hb_server/apps/sam/migrations/0009_alter_saleproduct_is_mtestok.py diff --git a/hb_server/apps/inm/migrations/0021_fifoitemproduct_iproduct.py b/hb_server/apps/inm/migrations/0021_fifoitemproduct_iproduct.py new file mode 100644 index 0000000..9d9ea22 --- /dev/null +++ b/hb_server/apps/inm/migrations/0021_fifoitemproduct_iproduct.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.9 on 2021-12-07 00:42 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('inm', '0020_iproduct_is_saled'), + ] + + operations = [ + migrations.AddField( + model_name='fifoitemproduct', + name='iproduct', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='inm.iproduct', verbose_name='关联库存产品'), + ), + ] diff --git a/hb_server/apps/inm/models.py b/hb_server/apps/inm/models.py index 5c485d0..9059a91 100644 --- a/hb_server/apps/inm/models.py +++ b/hb_server/apps/inm/models.py @@ -84,15 +84,6 @@ class FIFOItem(BaseModel): fifo = models.ForeignKey(FIFO, verbose_name='关联出入库', on_delete=models.CASCADE) subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, null=True, blank=True) -class FIFOItemProduct(BaseModel): - """ - 出入库产品 - """ - fifoitem = models.ForeignKey(FIFOItem, verbose_name='关联出入库具体产品', on_delete=models.CASCADE) - wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True) - number = models.CharField('物品编号', max_length=50) - material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE) - class IProduct(BaseModel): """ 具体产品条目 @@ -104,4 +95,16 @@ class IProduct(BaseModel): wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True) is_saled = models.BooleanField('是否售出', default=False) +class FIFOItemProduct(BaseModel): + """ + 出入库产品 + """ + fifoitem = models.ForeignKey(FIFOItem, verbose_name='关联出入库具体产品', on_delete=models.CASCADE) + wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True) + number = models.CharField('物品编号', max_length=50) + material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE) + iproduct = models.ForeignKey(IProduct, verbose_name='关联库存产品', null=True, blank=True, on_delete=models.SET_NULL) + + + diff --git a/hb_server/apps/sam/migrations/0009_alter_saleproduct_is_mtestok.py b/hb_server/apps/sam/migrations/0009_alter_saleproduct_is_mtestok.py new file mode 100644 index 0000000..d034dfa --- /dev/null +++ b/hb_server/apps/sam/migrations/0009_alter_saleproduct_is_mtestok.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2021-12-07 00:42 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sam', '0008_alter_saleproduct_number'), + ] + + operations = [ + migrations.AlterField( + model_name='saleproduct', + name='is_mtestok', + field=models.BooleanField(blank=True, null=True, verbose_name='是否军检合格'), + ), + ] diff --git a/hb_server/apps/sam/models.py b/hb_server/apps/sam/models.py index bb0fb8e..e82137a 100644 --- a/hb_server/apps/sam/models.py +++ b/hb_server/apps/sam/models.py @@ -90,7 +90,7 @@ class SaleProduct(BaseModel): number = models.CharField('物品编号', max_length=50) iproduct = models.ForeignKey('inm.iproduct', verbose_name='关联库存产品', on_delete=models.CASCADE, related_name='sale_iproduct') is_mtested = models.BooleanField('是否军检', default=False) - is_mtestok = models.BooleanField('是否军检合格', default=True) + is_mtestok = models.BooleanField('是否军检合格', null=True, blank=True) remark = models.TextField('备注', null=True, blank=True) class Meta: diff --git a/hb_server/apps/sam/views.py b/hb_server/apps/sam/views.py index 624aa2d..f6e51c1 100644 --- a/hb_server/apps/sam/views.py +++ b/hb_server/apps/sam/views.py @@ -1,7 +1,9 @@ from django.db import transaction +from django.db.models.aggregates import Count from rest_framework import exceptions, serializers from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin -from apps.inm.models import FIFO +from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct +from apps.inm.signals import update_inm from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer, SaleCreateSerializer, SaleListSerializer, SaleProductCreateSerializer, SaleProductListSerializer, SaleProductMtestSerializer from apps.sam.models import Contract, Customer, Order, Sale, SaleProduct from rest_framework.viewsets import GenericViewSet, ModelViewSet @@ -75,7 +77,7 @@ class OrderViewSet(CreateUpdateCustomMixin, ModelViewSet): return Response(serializer.data) -class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, CreateModelMixin, GenericViewSet): +class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, CreateModelMixin, DestroyModelMixin, GenericViewSet): """ 销售记录 """ @@ -136,7 +138,34 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C pass else: raise exceptions.APIException('存在未军检产品') + # 创建出库条目 + ips = IProduct.objects.filter(sale_iproduct__sale=obj) + items = ips.values('warehouse', 'material', 'batch').annotate(total=Count('id')) + for i in items: + fifoitem = FIFOItem() + fifoitem.is_tested = True + fifoitem.is_testok = True + fifoitem.warehouse = i['warehouse'] + fifoitem.material = i['material'] + fifoitem.count = i['total'] + fifoitem.batch = i['batch'] + fifoitem.fifo = fifo + fifoitem.save() + items_p = ips.filter(warehouse=i['warehouse'], batch=i['batch']) + ips = [] + for i in items_p: + # 创建入库明细半成品 + ip = {} + ip['fifoitem'] = fifoitem + ip['number'] = i.number + ip['material'] = i.material + ip['iproduct'] = i + ips.append(FIFOItemProduct(**ip)) + FIFOItemProduct.objects.bulk_create(ips) # 更新库存 + update_inm(fifo) + # 更新成品库情况 + ips.update(is_saled=True) return Response() class SaleProductViewSet(ListModelMixin, DestroyModelMixin, CreateModelMixin, GenericViewSet): From 03437e1e4d0e981f9f9aa5b1115ed4ad327209f3 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 7 Dec 2021 08:47:09 +0800 Subject: [PATCH 12/17] =?UTF-8?q?=E5=86=9B=E6=A3=80mtest=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/sam/views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/hb_server/apps/sam/views.py b/hb_server/apps/sam/views.py index f6e51c1..e4902a8 100644 --- a/hb_server/apps/sam/views.py +++ b/hb_server/apps/sam/views.py @@ -201,6 +201,7 @@ class SaleProductViewSet(ListModelMixin, DestroyModelMixin, CreateModelMixin, Ge if obj.is_mtested: raise exceptions.APIException('已进行军检') obj.remark = request.data.get('remark', None) + obj.is_mtested = True obj.is_mtestok = request.data.get('is_mtestok') obj.save() return Response() \ No newline at end of file From 439566b4e5b0015dd3d1a57c15a295681c99018d Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 7 Dec 2021 10:24:37 +0800 Subject: [PATCH 13/17] =?UTF-8?q?=E9=94=80=E5=94=AE=E5=AE=A1=E6=A0=B8bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/inm/signals.py | 11 ++++++----- hb_server/apps/sam/views.py | 11 +++++++---- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/hb_server/apps/inm/signals.py b/hb_server/apps/inm/signals.py index 79d5a19..e659c0c 100644 --- a/hb_server/apps/inm/signals.py +++ b/hb_server/apps/inm/signals.py @@ -36,7 +36,7 @@ def update_inm(instance:FIFO, type:int=1): ips2.append(IProduct(**ip)) IProduct.objects.bulk_create(ips2) - elif instance.type in [FIFO.FIFO_TYPE_DO_OUT]: # 生产领料 + elif instance.type in [FIFO.FIFO_TYPE_DO_OUT, FIFO.FIFO_TYPE_SALE_OUT]: # 生产领料 销售出库 # 更新相关表 for i in FIFOItem.objects.filter(fifo=instance): material = i.material @@ -49,8 +49,9 @@ def update_inm(instance:FIFO, type:int=1): o2.save() material.count = material.count - i.count material.save() - - # 删除IProduct - numbers = FIFOItemProduct.objects.filter(fifoitem=i).values_list('number', flat=True) - IProduct.objects.filter(number__in=numbers).delete() + + # 删除IProduct + if instance.type == FIFO.FIFO_TYPE_DO_OUT: + numbers = FIFOItemProduct.objects.filter(fifoitem=i).values_list('number', flat=True) + IProduct.objects.filter(number__in=numbers).delete() diff --git a/hb_server/apps/sam/views.py b/hb_server/apps/sam/views.py index e4902a8..1f7b0b3 100644 --- a/hb_server/apps/sam/views.py +++ b/hb_server/apps/sam/views.py @@ -2,7 +2,8 @@ from django.db import transaction from django.db.models.aggregates import Count from rest_framework import exceptions, serializers from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin -from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct +from apps.mtm.models import Material +from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, WareHouse from apps.inm.signals import update_inm from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer, SaleCreateSerializer, SaleListSerializer, SaleProductCreateSerializer, SaleProductListSerializer, SaleProductMtestSerializer from apps.sam.models import Contract, Customer, Order, Sale, SaleProduct @@ -142,16 +143,18 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C ips = IProduct.objects.filter(sale_iproduct__sale=obj) items = ips.values('warehouse', 'material', 'batch').annotate(total=Count('id')) for i in items: + warehouse = WareHouse.objects.get(id=i['warehouse']) + material = Material.objects.get(id=i['material']) fifoitem = FIFOItem() fifoitem.is_tested = True fifoitem.is_testok = True - fifoitem.warehouse = i['warehouse'] - fifoitem.material = i['material'] + fifoitem.warehouse = warehouse + fifoitem.material = material fifoitem.count = i['total'] fifoitem.batch = i['batch'] fifoitem.fifo = fifo fifoitem.save() - items_p = ips.filter(warehouse=i['warehouse'], batch=i['batch']) + items_p = ips.filter(warehouse=warehouse, batch=i['batch']) ips = [] for i in items_p: # 创建入库明细半成品 From 8e3ab103dd324baf2bb42a12e93e1fa29827df2e Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 7 Dec 2021 10:29:34 +0800 Subject: [PATCH 14/17] =?UTF-8?q?sale=20commit=20=E6=8F=90=E4=BA=A4bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/sam/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hb_server/apps/sam/views.py b/hb_server/apps/sam/views.py index 1f7b0b3..8269505 100644 --- a/hb_server/apps/sam/views.py +++ b/hb_server/apps/sam/views.py @@ -165,10 +165,10 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C ip['iproduct'] = i ips.append(FIFOItemProduct(**ip)) FIFOItemProduct.objects.bulk_create(ips) + # 更新成品库情况 + IProduct.objects.filter(sale_iproduct__sale=obj).update(is_saled=True) # 更新库存 update_inm(fifo) - # 更新成品库情况 - ips.update(is_saled=True) return Response() class SaleProductViewSet(ListModelMixin, DestroyModelMixin, CreateModelMixin, GenericViewSet): From 6ee7c46d7d9b52177c7755d6bd8da7890c8a455d Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 7 Dec 2021 10:32:48 +0800 Subject: [PATCH 15/17] sale audit bug --- hb_server/apps/sam/views.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hb_server/apps/sam/views.py b/hb_server/apps/sam/views.py index 8269505..55d3c21 100644 --- a/hb_server/apps/sam/views.py +++ b/hb_server/apps/sam/views.py @@ -155,7 +155,7 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C fifoitem.fifo = fifo fifoitem.save() items_p = ips.filter(warehouse=warehouse, batch=i['batch']) - ips = [] + ipxs = [] for i in items_p: # 创建入库明细半成品 ip = {} @@ -163,10 +163,10 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C ip['number'] = i.number ip['material'] = i.material ip['iproduct'] = i - ips.append(FIFOItemProduct(**ip)) - FIFOItemProduct.objects.bulk_create(ips) + ipxs.append(FIFOItemProduct(**ip)) + FIFOItemProduct.objects.bulk_create(ipxs) # 更新成品库情况 - IProduct.objects.filter(sale_iproduct__sale=obj).update(is_saled=True) + ips.update(is_saled=True) # 更新库存 update_inm(fifo) return Response() From b743675190520c04b8c600d12ac7caa6fa597faf Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 7 Dec 2021 10:36:14 +0800 Subject: [PATCH 16/17] sale submit bug --- hb_server/apps/sam/views.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hb_server/apps/sam/views.py b/hb_server/apps/sam/views.py index 55d3c21..2fe48f5 100644 --- a/hb_server/apps/sam/views.py +++ b/hb_server/apps/sam/views.py @@ -157,7 +157,7 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C items_p = ips.filter(warehouse=warehouse, batch=i['batch']) ipxs = [] for i in items_p: - # 创建入库明细半成品 + # 创建出库明细半成品 ip = {} ip['fifoitem'] = fifoitem ip['number'] = i.number @@ -169,6 +169,9 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C ips.update(is_saled=True) # 更新库存 update_inm(fifo) + # 变更审核状态 + obj.is_audited = True + obj.save() return Response() class SaleProductViewSet(ListModelMixin, DestroyModelMixin, CreateModelMixin, GenericViewSet): From 7a97e5e99bdb58999fe7cd806142fd23924edc7a Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 7 Dec 2021 10:42:17 +0800 Subject: [PATCH 17/17] =?UTF-8?q?sale=20audit=20=E5=8F=98=E6=9B=B4?= =?UTF-8?q?=E5=AE=A1=E6=A0=B8=E5=92=8C=E8=AE=A2=E5=8D=95=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/sam/views.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hb_server/apps/sam/views.py b/hb_server/apps/sam/views.py index 2fe48f5..e3098ef 100644 --- a/hb_server/apps/sam/views.py +++ b/hb_server/apps/sam/views.py @@ -131,6 +131,7 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C fifo.is_audited = True fifo.auditor = request.user fifo.inout_date = timezone.now() + fifo.create_by = request.user fifo.save() # 出库条目 spds = SaleProduct.objects.filter(sale=obj) @@ -172,6 +173,11 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C # 变更审核状态 obj.is_audited = True obj.save() + # 变更订单状态 + if obj.order: + order = obj.order + order.delivered_count = order.delivered_count + obj.count + order.save() return Response() class SaleProductViewSet(ListModelMixin, DestroyModelMixin, CreateModelMixin, GenericViewSet):