diff --git a/apps/wpm/filters.py b/apps/wpm/filters.py index a8dc6aa1..1bb803fd 100644 --- a/apps/wpm/filters.py +++ b/apps/wpm/filters.py @@ -1,5 +1,5 @@ from django_filters import rest_framework as filters -from apps.wpm.models import SfLog, SfLogExp, WMaterial, Mlog +from apps.wpm.models import SfLog, SfLogExp, WMaterial, Mlog, Handover ['mgroup', 'shift', 'team', 'leader', 'team__belong_dept'] @@ -63,3 +63,18 @@ class MlogFilter(filters.FilterSet): "mgroup__belong_dept__name": ["exact", "in"], "submit_time": ["isnull"] } + + +class HandoverFilter(filters.FilterSet): + + class Meta: + model = Handover + fields = { + "send_user": ["exact"], + "send_dept": ["exact"], + "send_dept__name": ["exact"], + "recive_dept": ["exact"], + "recive_dept__name": ["exact"], + "send_date": ["exact"], + "submit_time": ["isnull"] + } diff --git a/apps/wpm/migrations/0025_auto_20231101_1751.py b/apps/wpm/migrations/0025_auto_20231101_1751.py new file mode 100644 index 00000000..af3949f2 --- /dev/null +++ b/apps/wpm/migrations/0025_auto_20231101_1751.py @@ -0,0 +1,26 @@ +# Generated by Django 3.2.12 on 2023-11-01 09:51 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('wpm', '0024_auto_20231101_1325'), + ] + + operations = [ + migrations.AddField( + model_name='handover', + name='submit_time', + field=models.DateTimeField(blank=True, null=True, verbose_name='提交时间'), + ), + migrations.AddField( + model_name='handover', + name='submit_user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='handover_submit_user', to=settings.AUTH_USER_MODEL, verbose_name='提交人'), + ), + ] diff --git a/apps/wpm/models.py b/apps/wpm/models.py index 31882c76..052b877f 100644 --- a/apps/wpm/models.py +++ b/apps/wpm/models.py @@ -165,3 +165,7 @@ class Handover(CommonADModel): on_delete=models.SET_NULL, null=True, blank=True, related_name='handover_mlog') doin_date = models.DateField('加料日期', null=True, blank=True) doout_date = models.DateField('出料日期', null=True, blank=True) + + submit_time = models.DateTimeField('提交时间', null=True, blank=True) + submit_user = models.ForeignKey( + User, verbose_name='提交人', on_delete=models.CASCADE, null=True, blank=True, related_name='handover_submit_user') diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index dbf16eb4..8c3850a5 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -223,3 +223,21 @@ class GenHandoverSerializer(serializers.Serializer): send_user = serializers.PrimaryKeyRelatedField( label='交送人', queryset=User.objects.all()) send_date = serializers.DateField(label='交送日期') + + +class GenHandoverWmSerializer(serializers.Serializer): + wm = serializers.PrimaryKeyRelatedField( + label='车间物料ID', queryset=WMaterial.objects.all()) + recive_dept = serializers.PrimaryKeyRelatedField( + label='交送车间', queryset=Dept.objects.all()) + recive_user = serializers.PrimaryKeyRelatedField( + label='接收人', queryset=User.objects.all()) + send_user = serializers.PrimaryKeyRelatedField( + label='交送人', queryset=User.objects.all()) + send_date = serializers.DateField(label='交送日期') + count = serializers.IntegerField(label='交送数量') + + def validate(self, attrs): + if attrs['count'] <= 1: + raise ValidationError('交送数量必须大于1') + return attrs diff --git a/apps/wpm/services.py b/apps/wpm/services.py index 833f7c92..6491a327 100644 --- a/apps/wpm/services.py +++ b/apps/wpm/services.py @@ -14,7 +14,7 @@ from apps.inm.models import MIO, MIOItem, MIOItemA from apps.pm.models import Mtask from apps.mtm.models import Mgroup, Shift, Material -from .models import SfLog, SfLogExp, WMaterial, Mlog, Mlogb +from .models import SfLog, SfLogExp, WMaterial, Mlog, Mlogb, Handover def make_sflogs(mgroup: Mgroup, start_date: datetime.date, end_date: datetime.date): @@ -187,3 +187,28 @@ def update_mtask(mtask: Mtask): if Mtask.objects.filter(utask=utask).exclude(state=Mtask.MTASK_DONE).count() == 0: utask.state = Mtask.MTASK_DONE utask.save() + + +def handover_submit(handover: Handover, user: User, now: Union[datetime, None]): + """ + 交接提交后需要执行的操作 + """ + if handover.submit_time is not None: + return + now = timezone.now() + if handover.wm: + wm = handover.wm + count_x = wm.count - handover.count + if count_x < 0: + raise ParseError('车间库存不足!') + else: + wm.count = count_x + wm.save() + wm_to, _ = WMaterial.objects.get_or_create(batch=handover.batch, material=handover.material, belong_dept=handover.send_dept, defaults={ + 'batch': handover.batch, 'material': handover.material, 'belong_dept': handover.send_dept + }) + wm_to.count = wm_to.count + handover.count + wm_to.save() + handover.submit_user = user + handover.submit_time = now + handover.save() diff --git a/apps/wpm/views.py b/apps/wpm/views.py index 67438d3d..44d00818 100644 --- a/apps/wpm/views.py +++ b/apps/wpm/views.py @@ -11,10 +11,11 @@ from apps.pm.models import Mtask from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet from apps.utils.mixins import BulkCreateModelMixin -from .filters import SfLogExpFilter, SfLogFilter, WMaterialFilter, MlogFilter +from .filters import SfLogExpFilter, SfLogFilter, WMaterialFilter, MlogFilter, HandoverFilter from .models import SfLog, SfLogExp, StLog, WMaterial, Mlog, Handover -from .serializers import SflogExpSerializer, SfLogSerializer, StLogSerializer, WMaterialSerializer, MlogSerializer, MlogRelatedSerializer, DeptBatchSerializer, HandoverSerializer, GenHandoverSerializer -from .services import mlog_submit, update_mtask +from .serializers import (SflogExpSerializer, SfLogSerializer, StLogSerializer, WMaterialSerializer, + MlogSerializer, MlogRelatedSerializer, DeptBatchSerializer, HandoverSerializer, GenHandoverSerializer, GenHandoverWmSerializer) +from .services import mlog_submit, update_mtask, handover_submit # Create your views here. @@ -127,8 +128,8 @@ class MlogViewSet(CustomModelViewSet): filterset_class = MlogFilter def perform_destroy(self, instance): - if instance.mtask.state == Mtask.MTASK_DONE: - raise ParseError('任务已提交日志不可变动') + if instance.submit_time is not None: + raise ParseError('日志已提交不可变动') return super().perform_destroy(instance) @action(methods=['post'], detail=True, perms_map={'post': 'mlog.submit'}, serializer_class=Serializer) @@ -182,15 +183,58 @@ class HandoverViewSet(CustomModelViewSet): serializer_class = HandoverSerializer select_related_fields = ['send_user', 'send_dept', 'recive_user', 'recive_dept'] - filterset_fields = ['send_user', - 'send_dept', 'recive_user', 'recive_dept', 'recive_dept__name', 'send_date'] + filterset_class = HandoverFilter def perform_destroy(self, instance): user = self.request.user + if instance.submit_time is not None: + raise ParseError('日志已提交不可变动') if instance.send_user != user and instance.recive_user != user and instance.create_by != user: raise ParseError('非交送人和接收人不可删除该记录') return super().perform_destroy(instance) + @action(methods=['post'], detail=True, perms_map={'post': 'handover.submit'}, serializer_class=Serializer) + @transaction.atomic + def submit(self, request): + """交接记录提交(变动车间库存) + + 交接记录提交 + """ + ins: Handover = self.get_object() + user = self.request.user + if user != ins.send_user: + raise ParseError('非接收人不可提交') + if ins.submit_time is None: + handover_submit(ins, user, None) + return Response() + + @action(methods=['post'], detail=False, perms_map={'post': 'handover.create'}, serializer_class=GenHandoverWmSerializer) + @transaction.atomic + def gen_by_wm(self, request): + """从车间库存生成交接记录 + + 从车间库存生成交接记录 + """ + sr = GenHandoverWmSerializer(data=request.data) + sr.is_valid(raise_exception=True) + vdata = sr.validated_data + user = request.user + send_date, send_user, recive_dept, recive_user, wm, count = vdata['send_date'], vdata[ + 'send_user'], vdata['recive_dept'], vdata['recive_user'], vdata['wm'], vdata['count'] + handover = Handover.objects.create( + send_date=send_date, + send_user=send_user, + recive_dept=recive_dept, + recive_user=recive_user, + send_dept=wm.belong_dept, + batch=wm.batch, + material=wm.material, + count=count, + wm=wm, + create_by=user + ) + return Response({'handover': handover.id}) + @action(methods=['post'], detail=False, perms_map={'post': 'handover.create'}, serializer_class=GenHandoverSerializer) @transaction.atomic def gen_by_mlogs(self, request):