diff --git a/apps/inm/serializers.py b/apps/inm/serializers.py index 1ea7604e..9f497659 100644 --- a/apps/inm/serializers.py +++ b/apps/inm/serializers.py @@ -72,7 +72,7 @@ class MIOListSerializer(CustomModelSerializer): source='customer.name', read_only=True) order_number = serializers.CharField(source='order.number', read_only=True) pu_order_number = serializers.CharField( - source='pu_order.name', read_only=True) + source='pu_order.number', read_only=True) class Meta: model = MIO @@ -284,14 +284,17 @@ class MIOItemPurInTestSerializer(CustomModelSerializer): class Meta: model = MIOItem fields = ['id', 'test_date', 'test_user', - 'count_bag', 'weight_kgs', 'is_testok', 'test_note'] + 'count_bag', 'count_sampling', 'weight_kgs', 'is_testok', 'test_note'] extra_kwargs = { 'test_date': {'required': True}, 'test_user': {'required': True} } def validate(self, attrs): - weight_kgs = attrs['weight_kgs'] - attrs['weight_kgs'] = [float(i) for i in weight_kgs] - attrs['count_sampling'] = len(attrs['weight_kgs']) + if 'count_sampling' in attrs and attrs['count_sampling']: + pass + else: + weight_kgs = attrs['weight_kgs'] + attrs['weight_kgs'] = [float(i) for i in weight_kgs] + attrs['count_sampling'] = len(attrs['weight_kgs']) return super().validate(attrs) diff --git a/apps/mtm/serializers.py b/apps/mtm/serializers.py index 608756ab..e63b3bab 100644 --- a/apps/mtm/serializers.py +++ b/apps/mtm/serializers.py @@ -207,7 +207,7 @@ class RouteSerializer(CustomModelSerializer): 'specification': material.specification, 'model': material.model, 'type': Material.MA_TYPE_HALFGOOD, - 'cate': Material.cate, + 'cate': material.cate, 'create_by': self.request.user, 'update_by': self.request.user, }) diff --git a/apps/mtm/services.py b/apps/mtm/services.py index 424f326e..3813a6ad 100644 --- a/apps/mtm/services.py +++ b/apps/mtm/services.py @@ -63,26 +63,29 @@ def daoru_material(path: str): from apps.utils.snowflake import idWorker from openpyxl import load_workbook wb = load_workbook(path) - sheet = wb.get_sheet_by_name('物料') + sheet = wb['物料'] process_l = Process.objects.all() process_d = {p.name: p for p in process_l} i = 3 - while sheet[f'a{i}'].value is not None: - type_str = sheet[f'a{i}'].value.replace(' ', '') + if sheet['a2'].value != '物料编号': + raise ParseError('列错误导入失败') + while sheet[f'b{i}'].value is not None: + type_str = sheet[f'b{i}'].value.replace(' ', '') try: type = type_dict[type_str] - name = sheet[f'b{i}'].value.replace(' ', '') - specification = sheet[f'c{i}'].value.replace( + number = sheet[f'a{i}'].value.replace(' ', '') + name = sheet[f'c{i}'].value.replace(' ', '') + specification = sheet[f'd{i}'].value.replace( '×', '*').replace(' ', '') - model = sheet[f'd{i}'].value.replace(' ', '') - unit = sheet[f'e{i}'].value.replace(' ', '') - count_safe = sheet[f'g{i}'].value - unit_price = sheet[f'h{i}'].value + model = sheet[f'e{i}'].value.replace(' ', '') + unit = sheet[f'f{i}'].value.replace(' ', '') + count_safe = sheet[f'h{i}'].value + unit_price = sheet[f'i{i}'].value except Exception as e: raise ParseError(f'{i}行物料信息错误: {str(e)}') if type in [20, 30]: try: - process = process_d[sheet[f'f{i}'].value.replace(' ', '')] + process = process_d[sheet[f'g{i}'].value.replace(' ', '')] except Exception as e: raise ParseError(f'{i}行物料信息错误: {str(e)}') try: @@ -91,7 +94,7 @@ def daoru_material(path: str): if type in [20, 30]: filters['process'] = process default = {'type': type, 'name': name, 'specification': specification, - 'model': model, 'unit': unit, 'number': f'm{type}_{ranstr(6)}', 'id': idWorker.get_id(), + 'model': model, 'unit': unit, 'number': number if number else f'm{type}_{ranstr(6)}', 'id': idWorker.get_id(), 'count_safe': count_safe, 'unit_price': unit_price} material, is_created = Material.objects.get_or_create( **filters, defaults=default) @@ -101,7 +104,7 @@ def daoru_material(path: str): except Exception as e: raise ParseError(f'{i}行物料有误, 导入失败--{e}') i = i + 1 - print(type, name, specification, model, unit, '导入成功') + print(number, type, name, specification, model, unit, '导入成功') def mgroup_run_change(mgroup: Mgroup, new_run: bool, last_timex: datetime): diff --git a/apps/qm/migrations/0020_auto_20240814_1756.py b/apps/qm/migrations/0020_auto_20240814_1756.py new file mode 100644 index 00000000..d0cfd32b --- /dev/null +++ b/apps/qm/migrations/0020_auto_20240814_1756.py @@ -0,0 +1,31 @@ +# Generated by Django 3.2.12 on 2024-08-14 09:56 + +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), + ('qm', '0019_alter_ftestwork_batch'), + ] + + operations = [ + migrations.AddField( + model_name='ftestwork', + name='test_user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='ftestwork_test_user', to=settings.AUTH_USER_MODEL, verbose_name='操作人'), + ), + migrations.AlterField( + model_name='ftest', + name='type', + field=models.CharField(choices=[('first', '首件检验'), ('process', '过程检验'), ('prod', '成品检验')], max_length=20, verbose_name='检验类型'), + ), + migrations.AlterField( + model_name='ftestwork', + name='type', + field=models.CharField(choices=[('first', '首件检验'), ('process', '过程检验'), ('prod', '成品检验')], default='prod', max_length=20, verbose_name='检验类型'), + ), + ] diff --git a/apps/qm/models.py b/apps/qm/models.py index 7c016672..55437375 100644 --- a/apps/qm/models.py +++ b/apps/qm/models.py @@ -47,15 +47,19 @@ class NotOkOption(models.TextChoices): hqnjyd = "hqnjyd", _("黑圈内径圆度") hqwj = "hqwj", _("黑圈外径") hqwjyd = "hqwjyd", _("黑圈外径圆度") - wj = "wj", _("外径") - yd = "yd", _("圆度") - txd = "txd", _("同心度") - hd = "hd", _("厚度") + wj = "wj", _("外径不良") + yd = "yd", _("圆度不良") + txd = "txd", _("同心度不良") + hd = "hd", _("厚度不良") + z = "z", _("脏") + zhg = "zhg", _("准合格") + yz = "yz", _("圆准") qt = "qt", _("其它") FTEST_TYPE_CHOICES = ( ('first', '首件检验'), + ('process', '过程检验'), ('prod', '成品检验') ) class TestItem(CommonAModel): @@ -113,6 +117,8 @@ class FtestWork(CommonBDModel): count_ok = models.IntegerField('合格数量', default=0) count_notok = models.IntegerField('不合格数量', default=0) count_notok_json = models.JSONField('不合格项数量统计', default=dict, null=False, blank=True) + test_user = models.ForeignKey( + User, verbose_name='操作人', on_delete=models.CASCADE, related_name='ftestwork_test_user', null=True, blank=True) submit_time = models.DateTimeField('提交时间', null=True, blank=True) submit_user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='提交人', null=True, blank=True) diff --git a/apps/qm/serializers.py b/apps/qm/serializers.py index 4dfa3bff..7f0c39a3 100644 --- a/apps/qm/serializers.py +++ b/apps/qm/serializers.py @@ -62,7 +62,8 @@ class QuaStatUpdateSerializer(CustomModelSerializer): class FtestWorkCreateUpdateSerializer(CustomModelSerializer): class Meta: model = FtestWork - fields = ['id', 'wm', 'type', 'type2', 'test_date', 'count', 'count_sampling', 'count_ok', 'count_notok', 'count_notok_json'] + fields = ['id', 'wm', 'type', 'type2', 'test_date', 'count', 'count_sampling', 'count_ok', 'count_notok', 'count_notok_json', 'test_user'] + extra_kwargs = {'test_user': {'required': True}, 'type': {'required': True}} def validate(self, attrs): type2 = attrs.get('type2', 20) @@ -126,7 +127,10 @@ class FtestSerializer(CustomModelSerializer): def validate(self, attrs): ftest_work: FtestWork = attrs.get('ftest_work', None) if ftest_work: + test_user = attrs.get('test_user', None) attrs['type'] = ftest_work.type + if test_user is None: + attrs['test_user'] = ftest_work.test_user return attrs def create(self, validated_data): diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index 089fff16..faee3cfb 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -417,9 +417,20 @@ class MlogbInUpdateSerializer(CustomModelSerializer): class MlogbOutUpdateSerializer(CustomModelSerializer): class Meta: model = Mlogb - fields = ['id', 'batch', 'count_real', 'count_ok', 'count_notok', - 'count_n_hs', 'count_n_qp', 'count_n_swen', 'count_n_bb', - 'count_n_wm', 'count_n_md', 'count_n_xh'] + fields = "__all__" + read_only_fields = EXCLUDE_FIELDS_BASE + ['mlog', 'mtask', 'wm_in', 'material_in', 'material_out', 'count_use', 'count_break'] + + def validate(self, attrs): + count_notok = 0 + for i in attrs: + if 'count_n_' in i: + count_notok = count_notok + attrs[i] + attrs['count_notok'] = count_notok + if attrs['count_real'] >= attrs['count_ok'] + attrs['count_notok']: + pass + else: + raise ValidationError('生产数量不能小于合格数量') + return attrs class MlogRevertSerializer(serializers.Serializer): change_reason = serializers.CharField(label='撤回原因') diff --git a/media/default/template/material.xlsx b/media/default/template/material.xlsx index 19a678a3..db0a83ff 100644 Binary files a/media/default/template/material.xlsx and b/media/default/template/material.xlsx differ