From 947f8088fc1d91902a04143875106708d9d68284 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 23 Feb 2022 14:08:47 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E9=94=80=E5=94=AE=E5=87=BA=E5=BA=93?= =?UTF-8?q?=E5=AE=A1=E6=A0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/inm/serializers.py | 14 ++++++ hb_server/apps/inm/services.py | 65 ++++++++++++++++++++++++-- hb_server/apps/inm/views.py | 14 +++--- hb_server/apps/sam/serializers_sale.py | 3 +- hb_server/apps/sam/views_sale.py | 40 +--------------- 5 files changed, 88 insertions(+), 48 deletions(-) diff --git a/hb_server/apps/inm/serializers.py b/hb_server/apps/inm/serializers.py index a0d1014..1b14ae3 100644 --- a/hb_server/apps/inm/serializers.py +++ b/hb_server/apps/inm/serializers.py @@ -95,6 +95,13 @@ class FIFOItemCreateSerializer(serializers.ModelSerializer): if fifo.pu_order is not None: raise ValidationError('非采购订单') return super().create(validated_data) + + def validate_batch(self, value): + if value == '': + return value + elif len(value) > 6: + return value + raise ValidationError('批次号错误') class FIFOItemUpdateSerializer(serializers.ModelSerializer): class Meta: @@ -122,6 +129,13 @@ class FIFODetailInPurSerializer(serializers.ModelSerializer): class Meta: model = FIFOItem fields = ['material', 'count', 'batch', 'details', 'warehouse'] + + def validate_batch(self, value): + if value == '': + return value + elif len(value) > 6: + return value + raise ValidationError('批次号错误') class MaterialBatchQuerySerializer(serializers.Serializer): diff --git a/hb_server/apps/inm/services.py b/hb_server/apps/inm/services.py index 1c3c743..1bfa718 100644 --- a/hb_server/apps/inm/services.py +++ b/hb_server/apps/inm/services.py @@ -1,6 +1,9 @@ from rest_framework.exceptions import ValidationError -from apps.inm.models import FIFOItemProduct, IProduct, Inventory, MaterialBatch, FIFO, FIFOItem - +from sqlalchemy import true +from apps.inm.models import FIFOItemProduct, IProduct, Inventory, MaterialBatch, FIFO, FIFOItem, WareHouse +from apps.mtm.models import Material +from apps.sam.models import SalePack, SaleProduct +from django.db.models import Count class InmService: @classmethod def update_inm(cls, instance:FIFO, type:int=1): @@ -72,4 +75,60 @@ class InmService: if instance.type == FIFO.FIFO_TYPE_DO_OUT: # 生产领料的情况直接从IProduct中删除 numbers = FIFOItemProduct.objects.filter(fifoitem=i).values_list('number', flat=True) - IProduct.objects.filter(number__in=numbers).delete() \ No newline at end of file + IProduct.objects.filter(number__in=numbers).delete() + # 销售的话已经处理了 + # elif instance.type == FIFO.FIFO_TYPE_SALE_OUT: + # ips = FIFOItemProduct.objects.filter(fifoitem=i).values_list('iproduct', flat=True) + # IProduct.objects.filter(id__in=ips).update(state=IProduct.SALED) + + @classmethod + def sale_out_audit(cls, fifo:FIFO): + sale = fifo.sale + saleps = SaleProduct.objects.filter(sale=sale, packnum__isnull=True, remark__isnull=True) + if saleps.exists(): + raise ValidationError('存在未装箱的产品') + # 创建出库条目 + ips = IProduct.objects.filter(sale_iproduct__sale=sale + ).exclude(sale_iproduct__packnum__isnull=True) + ips.update(state=IProduct.SALED) + 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.need_test = False + fifoitem.warehouse = warehouse + fifoitem.material = material + fifoitem.count = i['total'] + fifoitem.batch = i['batch'] + fifoitem.fifo = fifo + fifoitem.save() + items_p = ips.filter(warehouse=warehouse, batch=i['batch']) + ipxs = [] + for i in items_p: + # 创建出库明细半成品 + ip = {} + ip['fifoitem'] = fifoitem + ip['number'] = i.number + ip['material'] = i.material + ip['iproduct'] = i + ipxs.append(FIFOItemProduct(**ip)) + FIFOItemProduct.objects.bulk_create(ipxs) + # 装箱附件处理 + # SalePack.objects.filter(sale_product__in = saleps) + + + # 更新动态产品表情况 + from apps.wpm.models import WProduct + WProduct.objects.filter(iproduct_wproduct__sale_iproduct__sale=sale).update( + act_state=WProduct.WPR_ACT_STATE_SELLED) + + # 变更销售记录实际发货数 + sale.count_real = ips.count() + sale.save() + # 变更订单状态 + order = sale.order + if order: + order.delivered_count = IProduct.objects.filter(sale_iproduct__sale__order=order + ).exclude(sale_iproduct__packnum__isnull=True).count() + order.save() \ No newline at end of file diff --git a/hb_server/apps/inm/views.py b/hb_server/apps/inm/views.py index fe4b69a..055b3a8 100644 --- a/hb_server/apps/inm/views.py +++ b/hb_server/apps/inm/views.py @@ -184,11 +184,14 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet): return Response() @action(methods=['post'], detail=True, perms_map={'post': 'fifo_audit'}, serializer_class=serializers.Serializer) + @transaction.atomic def audit(self, request, pk=None): """ 审核通过 """ obj = self.get_object() + if obj.type == FIFO.FIFO_TYPE_SALE_OUT: # 如果是销售提货,需额外处理 + pass if not FIFOItem.objects.filter(fifo=obj).exists(): raise ValidationError('出入库条目为空') for i in FIFOItem.objects.filter(fifo=obj, need_test=True): @@ -196,12 +199,11 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet): raise APIException('未检验通过, 不可审核') if obj.is_audited: raise APIException('该入库记录已审核通过') - with transaction.atomic(): - obj.is_audited = True - obj.auditor = request.user - obj.inout_date = timezone.now() # 也是审核日期 - obj.save() - InmService.update_inm(obj) # 更新库存 + obj.is_audited = True + obj.auditor = request.user + obj.inout_date = timezone.now() # 也是审核日期 + obj.save() + InmService.update_inm(obj) # 更新库存 return Response() diff --git a/hb_server/apps/sam/serializers_sale.py b/hb_server/apps/sam/serializers_sale.py index 615deea..4fb7589 100644 --- a/hb_server/apps/sam/serializers_sale.py +++ b/hb_server/apps/sam/serializers_sale.py @@ -89,10 +89,11 @@ class SPackItemCreateSerializer(serializers.Serializer): class SaleProductPackSerializer(serializers.ModelSerializer): detail = SPackItemCreateSerializer(many=True) + packnum = serializers.CharField(min_length=6) class Meta: model = SaleProduct fields = ['packnum', 'detail', 'remark'] class SRemarkItemCreateSerializer(serializers.Serializer): - remark = serializers.CharField() + remark = serializers.CharField(min_length=6) diff --git a/hb_server/apps/sam/views_sale.py b/hb_server/apps/sam/views_sale.py index 7c52345..47f3b07 100644 --- a/hb_server/apps/sam/views_sale.py +++ b/hb_server/apps/sam/views_sale.py @@ -89,46 +89,10 @@ class SaleViewSet(CreateUpdateModelAMixin, ListModelMixin, RetrieveModelMixin, C fifo.create_by = request.user fifo.number = 'CK' + ranstr(7) fifo.save() - # 创建出库条目 - # 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.need_test = False - # fifoitem.warehouse = warehouse - # fifoitem.material = material - # fifoitem.count = i['total'] - # fifoitem.batch = i['batch'] - # fifoitem.fifo = fifo - # fifoitem.save() - # items_p = ips.filter(warehouse=warehouse, batch=i['batch']) - # ipxs = [] - # for i in items_p: - # # 创建出库明细半成品 - # ip = {} - # ip['fifoitem'] = fifoitem - # ip['number'] = i.number - # ip['material'] = i.material - # ip['iproduct'] = i - # ipxs.append(FIFOItemProduct(**ip)) - # FIFOItemProduct.objects.bulk_create(ipxs) - - # 更新动态产品表情况 - # from apps.wpm.models import WProduct - # WProduct.objects.filter(iproduct_wproduct__sale_iproduct__sale=obj).update( - # act_state=WProduct.WPR_ACT_STATE_SELLED) - # 更新库存 - # InmService.update_inm(fifo) - # 变更销售提货审核状态 + obj.is_audited = True obj.save() - # 变更订单状态 - # if obj.order: - # order = obj.order - # order.delivered_count = order.delivered_count + obj.count - # order.save() + return Response() From 9c0fb20743dac9fd8ad4c8d0255ae8bbe38d033d Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 23 Feb 2022 14:12:20 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E5=BC=95=E7=94=A8bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/inm/services.py | 1 - 1 file changed, 1 deletion(-) diff --git a/hb_server/apps/inm/services.py b/hb_server/apps/inm/services.py index 1bfa718..5a760a7 100644 --- a/hb_server/apps/inm/services.py +++ b/hb_server/apps/inm/services.py @@ -1,5 +1,4 @@ from rest_framework.exceptions import ValidationError -from sqlalchemy import true from apps.inm.models import FIFOItemProduct, IProduct, Inventory, MaterialBatch, FIFO, FIFOItem, WareHouse from apps.mtm.models import Material from apps.sam.models import SalePack, SaleProduct From fbebb176aadbec46a805c08772396fdf0699c271 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 23 Feb 2022 14:18:18 +0800 Subject: [PATCH 3/8] inm audit bug --- hb_server/apps/inm/views.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/hb_server/apps/inm/views.py b/hb_server/apps/inm/views.py index 055b3a8..ce7a72d 100644 --- a/hb_server/apps/inm/views.py +++ b/hb_server/apps/inm/views.py @@ -190,15 +190,16 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet): 审核通过 """ obj = self.get_object() - if obj.type == FIFO.FIFO_TYPE_SALE_OUT: # 如果是销售提货,需额外处理 - pass - if not FIFOItem.objects.filter(fifo=obj).exists(): - raise ValidationError('出入库条目为空') - for i in FIFOItem.objects.filter(fifo=obj, need_test=True): - if not i.is_testok: - raise APIException('未检验通过, 不可审核') if obj.is_audited: - raise APIException('该入库记录已审核通过') + raise APIException('该入库记录已审核通过') + if obj.type == FIFO.FIFO_TYPE_SALE_OUT: # 如果是销售提货,需额外处理 + InmService.sale_out_audit(obj) + else: + if not FIFOItem.objects.filter(fifo=obj).exists(): + raise ValidationError('出入库条目为空') + for i in FIFOItem.objects.filter(fifo=obj, need_test=True): + if not i.is_testok: + raise APIException('未检验通过, 不可审核') obj.is_audited = True obj.auditor = request.user obj.inout_date = timezone.now() # 也是审核日期 From 7d715146a2803f7dc91c5547ea82e62f38cc8e65 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 23 Feb 2022 15:30:54 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E9=94=80=E5=94=AE=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E5=88=A0=E9=99=A4bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/inm/services.py | 15 ++++++++------- hb_server/apps/sam/views_sale.py | 3 ++- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/hb_server/apps/inm/services.py b/hb_server/apps/inm/services.py index 5a760a7..847fa76 100644 --- a/hb_server/apps/inm/services.py +++ b/hb_server/apps/inm/services.py @@ -55,18 +55,19 @@ class InmService: o1 = Inventory.objects.get(material=material, warehouse=warehouse) temp_count = o1.count - i.count if temp_count < 0: - raise ValidationError('库存不足,操作失败') + raise ValidationError('仓库库存不足,操作失败') o1.count = temp_count o1.save() + print(i.batch) o2 = MaterialBatch.objects.get(material=material, warehouse=warehouse, batch=i.batch) temp_count = o2.count - i.count if temp_count < 0: - raise ValidationError('库存不足,操作失败') + raise ValidationError('批次库存不足,操作失败') o2.count = temp_count o2.save() temp_count = material.count - i.count if temp_count < 0: - raise ValidationError('库存不足,操作失败') + raise ValidationError('物料库存不足,操作失败') material.count = temp_count material.save() @@ -87,8 +88,8 @@ class InmService: if saleps.exists(): raise ValidationError('存在未装箱的产品') # 创建出库条目 - ips = IProduct.objects.filter(sale_iproduct__sale=sale - ).exclude(sale_iproduct__packnum__isnull=True) + ips = IProduct.objects.filter(sale_iproduct__sale=sale, + sale_iproduct__packnum__isnull=False) ips.update(state=IProduct.SALED) items = ips.values('warehouse', 'material', 'batch').annotate(total=Count('id')) for i in items: @@ -119,7 +120,7 @@ class InmService: # 更新动态产品表情况 from apps.wpm.models import WProduct - WProduct.objects.filter(iproduct_wproduct__sale_iproduct__sale=sale).update( + WProduct.objects.filter(id__in=ips.values_list('wproduct', flat=True)).update( act_state=WProduct.WPR_ACT_STATE_SELLED) # 变更销售记录实际发货数 @@ -129,5 +130,5 @@ class InmService: order = sale.order if order: order.delivered_count = IProduct.objects.filter(sale_iproduct__sale__order=order - ).exclude(sale_iproduct__packnum__isnull=True).count() + , sale_iproduct__packnum__isnull=False).count() order.save() \ No newline at end of file diff --git a/hb_server/apps/sam/views_sale.py b/hb_server/apps/sam/views_sale.py index 47f3b07..a97b37f 100644 --- a/hb_server/apps/sam/views_sale.py +++ b/hb_server/apps/sam/views_sale.py @@ -42,7 +42,8 @@ class SaleViewSet(CreateUpdateModelAMixin, ListModelMixin, RetrieveModelMixin, C if obj.is_audited: raise exceptions.APIException('该销售记录已审核,不可删除') obj.delete() - IProduct.objects.filter(sale_iproduct__sale=obj).update() + IProduct.objects.filter(sale_iproduct__sale=obj).update(state=IProduct.SALE_OK) + return Response() def create(self, request, *args, **kwargs): data = request.data From 378b98f70b3ae134352486299b3006742e8146c0 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 23 Feb 2022 16:49:16 +0800 Subject: [PATCH 5/8] iproduct filter --- hb_server/apps/inm/filters.py | 2 +- hb_server/apps/inm/services.py | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/hb_server/apps/inm/filters.py b/hb_server/apps/inm/filters.py index e4f6409..377cb4d 100644 --- a/hb_server/apps/inm/filters.py +++ b/hb_server/apps/inm/filters.py @@ -29,4 +29,4 @@ class IProductFilterSet(DynamicFieldsFilterMixin, filters.FilterSet): class Meta: model = IProduct fields = ['material', 'warehouse', 'batch', 'order', 'material__type', 'update_time_start', 'update_time_end', - 'to_order', 'need_to_order'] + 'to_order', 'need_to_order', 'state'] diff --git a/hb_server/apps/inm/services.py b/hb_server/apps/inm/services.py index 847fa76..b9df308 100644 --- a/hb_server/apps/inm/services.py +++ b/hb_server/apps/inm/services.py @@ -1,8 +1,11 @@ +from itertools import count from rest_framework.exceptions import ValidationError from apps.inm.models import FIFOItemProduct, IProduct, Inventory, MaterialBatch, FIFO, FIFOItem, WareHouse from apps.mtm.models import Material from apps.sam.models import SalePack, SaleProduct from django.db.models import Count +from django.db.models.aggregates import Sum + class InmService: @classmethod def update_inm(cls, instance:FIFO, type:int=1): @@ -114,8 +117,12 @@ class InmService: ip['iproduct'] = i ipxs.append(FIFOItemProduct(**ip)) FIFOItemProduct.objects.bulk_create(ipxs) + # 装箱附件处理 - # SalePack.objects.filter(sale_product__in = saleps) + # ml = SalePack.objects.filter(sale_product__iproduct = ips + # ).values('packitem__material').annotate(count=Sum('count')) + # for i in ml: + # material = Material.objects.get(id=i['material']) # 更新动态产品表情况 From 4bc4c8bbc1496c2f2e4d1cd8cc17ee0e1b080620 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 23 Feb 2022 17:01:19 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E8=81=94=E7=B3=BB=E6=96=B9=E5=BC=8F?= 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, 1 insertion(+), 1 deletion(-) diff --git a/hb_server/apps/sam/serializers.py b/hb_server/apps/sam/serializers.py index 4aeaeb9..8b3df60 100644 --- a/hb_server/apps/sam/serializers.py +++ b/hb_server/apps/sam/serializers.py @@ -21,7 +21,7 @@ class CustomerCreateUpdateSerializer(serializers.ModelSerializer): class CustomerSimpleSerializer(serializers.ModelSerializer): class Meta: model = Customer - fields = ['id', 'name'] + fields = ['id', 'name', 'address', 'contact', 'contact_phone'] class ContractSerializer(serializers.ModelSerializer): customer_ = CustomerSimpleSerializer(source='customer', read_only=True) From 493845c1f43761755472a4dadafeeeed293a4b70 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 23 Feb 2022 17:15:14 +0800 Subject: [PATCH 7/8] =?UTF-8?q?tolerance=20=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/hrm/services.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hb_server/apps/hrm/services.py b/hb_server/apps/hrm/services.py index bd2f6b4..8bb9ce8 100644 --- a/hb_server/apps/hrm/services.py +++ b/hb_server/apps/hrm/services.py @@ -30,7 +30,7 @@ class HRMService: update_all_user_facedata_cache() try: results = face_recognition.compare_faces(face_datas, - unknown_face_encoding, tolerance=0.5) + unknown_face_encoding, tolerance=0.48) except: return None, '人脸匹配失败' for index, value in enumerate(results): From b97c005b83e8873f2033fc67f51832c84bcb2a62 Mon Sep 17 00:00:00 2001 From: shilixia <2309368887@qq.com> Date: Thu, 24 Feb 2022 08:32:29 +0800 Subject: [PATCH 8/8] xiaoshoufahuo --- hb_client/src/api/sam.js | 32 ++ hb_client/src/views/inm/fifo.vue | 11 + hb_client/src/views/personnel/attendance.vue | 9 +- hb_client/src/views/sam/sales.vue | 576 +++++++++++-------- hb_client/src/views/sam/salesdetail.vue | 353 +++++++++--- 5 files changed, 660 insertions(+), 321 deletions(-) diff --git a/hb_client/src/api/sam.js b/hb_client/src/api/sam.js index 540441f..99940ae 100644 --- a/hb_client/src/api/sam.js +++ b/hb_client/src/api/sam.js @@ -28,6 +28,15 @@ export function deleteCustomer(id, data) { data }) } +export function getCustomer(id) { + return request({ + url: `/sam/customer/${id}/`, + method: 'get', + + }) +} + + //合同 export function getContractList(query) { return request({ @@ -170,4 +179,27 @@ export function saleAudit(id) { }) } +//返回装箱文件 +export function gePack(id) { + return request({ + url: `/sam/sale_product/${id}/pack/`, + method: 'get' + }) +} +//打包装箱文件确认 +export function subPack(id, data) { + return request({ + url: `/sam/sale_product/${id}/pack/`, + method: 'POST', + data + }) +} +///未装箱备注 +export function notPackremark(id, data) { + return request({ + url: `/sam/sale_product/${id}/remark/`, + method: 'POST', + data + }) +} diff --git a/hb_client/src/views/inm/fifo.vue b/hb_client/src/views/inm/fifo.vue index 66b19ea..632288e 100644 --- a/hb_client/src/views/inm/fifo.vue +++ b/hb_client/src/views/inm/fifo.vue @@ -70,6 +70,12 @@ + + +