This commit is contained in:
zty 2024-08-20 14:43:55 +08:00
commit bc38196f68
9 changed files with 91 additions and 38 deletions

View File

@ -663,7 +663,8 @@ def get_area_from_point(x: int, y: int, floorNo: str, area_fix_id):
area_temp = None area_temp = None
area_list = cache.get('area_list', None) area_list = cache.get('area_list', None)
if not area_list: if not area_list:
area_list = cache_areas_info() cache_areas_info()
area_list = cache.get('area_list', None)
point = Point(x, y) point = Point(x, y)
for i in area_list: for i in area_list:
if floorNo == i['floor_no']: if floorNo == i['floor_no']:

View File

@ -87,7 +87,10 @@ class InmService:
material = i.material material = i.material
warehouse = i.warehouse warehouse = i.warehouse
mb, is_created = MaterialBatch.objects.get_or_create( mb, is_created = MaterialBatch.objects.get_or_create(
material=material, warehouse=warehouse, batch=i.batch, defaults={"material": material, "warehouse": warehouse, "count": 0, "batch": i.batch} material=material,
warehouse=warehouse,
batch=i.batch,
defaults={"material": material, "warehouse": warehouse, "count": 0, "batch": i.batch}
) )
if in_or_out == 1: if in_or_out == 1:
mb.count = mb.count + getattr(i, field) mb.count = mb.count + getattr(i, field)
@ -107,8 +110,6 @@ class InmService:
mb.count = mb.count - getattr(i, field) mb.count = mb.count - getattr(i, field)
if mb.count < 0: if mb.count < 0:
raise ParseError("批次库存不足,操作失败") raise ParseError("批次库存不足,操作失败")
elif mb.count == 0:
mb.delete()
else: else:
mb.save() mb.save()
else: else:

View File

@ -45,7 +45,7 @@ class MaterialBatchViewSet(ListModelMixin, CustomGenericViewSet):
物料批次 物料批次
""" """
perms_map = {'get': '*'} perms_map = {'get': '*'}
queryset = MaterialBatch.objects.all() queryset = MaterialBatch.objects.filter(count__gt=0)
serializer_class = MaterialBatchSerializer serializer_class = MaterialBatchSerializer
retrieve_serializer_class = MaterialBatchDetailSerializer retrieve_serializer_class = MaterialBatchDetailSerializer
select_related_fields = ['warehouse', 'material'] select_related_fields = ['warehouse', 'material']

View File

@ -73,21 +73,24 @@ def daoru_material(path: str):
type_str = sheet[f'b{i}'].value.replace(' ', '') type_str = sheet[f'b{i}'].value.replace(' ', '')
try: try:
type = type_dict[type_str] type = type_dict[type_str]
number = sheet[f'a{i}'].value.replace(' ', '') number = sheet[f'a{i}'].value.replace(' ', '') if sheet[f'a{i}'].value else None
if sheet[f'c{i}'].value:
name = sheet[f'c{i}'].value.replace(' ', '') name = sheet[f'c{i}'].value.replace(' ', '')
else:
raise ParseError(f'{i}行物料信息错误: 物料名称必填')
specification = sheet[f'd{i}'].value.replace( specification = sheet[f'd{i}'].value.replace(
'×', '*').replace(' ', '') '×', '*').replace(' ', '') if sheet[f'd{i}'].value else None
model = sheet[f'e{i}'].value.replace(' ', '') model = sheet[f'e{i}'].value.replace(' ', '') if sheet[f'e{i}'].value else None
unit = sheet[f'f{i}'].value.replace(' ', '') unit = sheet[f'f{i}'].value.replace(' ', '')
count_safe = sheet[f'h{i}'].value count_safe = sheet[f'h{i}'].value
unit_price = sheet[f'i{i}'].value unit_price = sheet[f'i{i}'].value
except Exception as e: except Exception as e:
raise ParseError(f'{i}行物料信息错误: {str(e)}') raise ParseError(f'{i}行物料信息错误: {e}')
if type in [20, 30]: if type in [20, 30]:
try: try:
process = process_d[sheet[f'g{i}'].value.replace(' ', '')] process = process_d[sheet[f'g{i}'].value.replace(' ', '')]
except Exception as e: except Exception as e:
raise ParseError(f'{i}行物料信息错误: {str(e)}') raise ParseError(f'{i}行物料信息错误: {e}')
try: try:
filters = {'type': type, 'name': name, 'specification': specification, filters = {'type': type, 'name': name, 'specification': specification,
'model': model, 'unit__iexact': unit} 'model': model, 'unit__iexact': unit}
@ -127,9 +130,16 @@ def mgroup_run_change(mgroup: Mgroup, new_run: bool, last_timex: datetime):
last_stlog.save() last_stlog.save()
cal_exp_duration_sec(last_stlog.id) # 触发时间分配 cal_exp_duration_sec(last_stlog.id) # 触发时间分配
elif last_stlog.end_time and new_run is False and last_timex > last_stlog.end_time: # 从开到停 elif last_stlog.end_time and new_run is False and last_timex > last_stlog.end_time: # 从开到停
has_same_stlog =StLog.objects.filter(mgroup=mgroup, is_shutdown=True, start_time=last_timex).exists() StLog.objects.get_or_create(
if not has_same_stlog: mgroup=mgroup,
StLog.objects.create(title="停机", is_shutdown=True, mgroup=mgroup, end_time=None, start_time=last_timex, sflog=get_sflog(mgroup, last_timex)) is_shutdown=True,
start_time=last_timex,
defaults={
'title': '停机',
'end_time': None,
'sflog': get_sflog(mgroup, last_timex)
}
)
elif new_run is False: elif new_run is False:
StLog.objects.create(title="停机", is_shutdown=True, mgroup=mgroup, end_time=None, start_time=last_timex, sflog=get_sflog(mgroup, last_timex)) StLog.objects.create(title="停机", is_shutdown=True, mgroup=mgroup, end_time=None, start_time=last_timex, sflog=get_sflog(mgroup, last_timex))
mgroup.is_running = False mgroup.is_running = False

View File

@ -185,7 +185,17 @@ def check_opl_audit_imgs(ticket: Ticket, transition: Transition, new_ticket_data
audit_imgs = new_ticket_data.get('audit_imgs', []) audit_imgs = new_ticket_data.get('audit_imgs', [])
if audit_imgs: if audit_imgs:
opl = Opl.objects.get(ticket=ticket) opl = Opl.objects.get(ticket=ticket)
opl.audit_imgs = audit_imgs opl.audit_imgs.set(audit_imgs)
opl.save() opl.save()
else: else:
raise Exception('需提交审核照片') raise ParseError('需提交审核照片')
def check_opl_work_imgs(ticket: Ticket, transition: Transition, new_ticket_data: dict):
work_imgs = new_ticket_data.get('work_imgs', [])
if work_imgs:
opl = Opl.objects.get(ticket=ticket)
opl.work_imgs.set(work_imgs)
opl.save()
else:
raise ParseError('需提交作业开始照片')

View File

@ -0,0 +1,20 @@
# Generated by Django 3.2.12 on 2024-08-19 03:25
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('inm', '0001_initial'),
('qm', '0020_auto_20240814_1756'),
]
operations = [
migrations.AddField(
model_name='ftestwork',
name='mb',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='inm.materialbatch', verbose_name='关联仓库'),
),
]

View File

@ -108,6 +108,7 @@ class FtestWork(CommonBDModel):
type = models.CharField('检验类型', max_length=20, choices=FTEST_TYPE_CHOICES, default='prod') type = models.CharField('检验类型', max_length=20, choices=FTEST_TYPE_CHOICES, default='prod')
type2 = models.PositiveSmallIntegerField('检验类型2', choices=((10, '抽检'), (20, '全检')), default=10) type2 = models.PositiveSmallIntegerField('检验类型2', choices=((10, '抽检'), (20, '全检')), default=10)
wm = models.ForeignKey(WMaterial, verbose_name='关联车间库存', on_delete=models.SET_NULL, null=True, blank=True) wm = models.ForeignKey(WMaterial, verbose_name='关联车间库存', on_delete=models.SET_NULL, null=True, blank=True)
mb = models.ForeignKey('inm.materialbatch', verbose_name='关联仓库', on_delete=models.SET_NULL, null=True, blank=True)
test_date = models.DateField('检验日期') test_date = models.DateField('检验日期')
material = models.ForeignKey( material = models.ForeignKey(
Material, verbose_name='产品', on_delete=models.CASCADE) Material, verbose_name='产品', on_delete=models.CASCADE)

View File

@ -6,6 +6,7 @@ from rest_framework.exceptions import ValidationError
from apps.system.models import Dept, Dictionary from apps.system.models import Dept, Dictionary
from apps.wpm.models import SfLog, WMaterial from apps.wpm.models import SfLog, WMaterial
from django.db import transaction from django.db import transaction
from apps.inm.serializers import MaterialBatchDetailSerializer
class TestItemSerializer(CustomModelSerializer): class TestItemSerializer(CustomModelSerializer):
@ -62,15 +63,15 @@ class QuaStatUpdateSerializer(CustomModelSerializer):
class FtestWorkCreateUpdateSerializer(CustomModelSerializer): class FtestWorkCreateUpdateSerializer(CustomModelSerializer):
class Meta: class Meta:
model = FtestWork model = FtestWork
fields = ['id', 'wm', 'type', 'type2', 'test_date', 'count', 'count_sampling', 'count_ok', 'count_notok', 'count_notok_json', 'test_user'] fields = ['id', 'wm', 'mb', '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}} extra_kwargs = {'test_user': {'required': True}, 'type': {'required': True}}
def validate(self, attrs): def validate(self, attrs):
type2 = attrs.get('type2', 20) type2 = attrs.get('type2', 20)
if type2 == 20: # 如果是全检 if type2 == 20: # 如果是全检
attrs['count_sampling'] = attrs['count'] attrs['count_sampling'] = attrs['count']
if 'wm' not in attrs: if 'wm' in attrs and attrs['wm']:
raise ValidationError('请选择车间库存') attrs['mb'] = None
wm:WMaterial = attrs['wm'] wm:WMaterial = attrs['wm']
if wm.state not in [WMaterial.WM_OK, WMaterial.WM_TEST]: if wm.state not in [WMaterial.WM_OK, WMaterial.WM_TEST]:
raise ValidationError('不支持对该物料检验') raise ValidationError('不支持对该物料检验')
@ -89,6 +90,12 @@ class FtestWorkCreateUpdateSerializer(CustomModelSerializer):
else: else:
raise ValidationError(f'不合格项{k_2}必须为非负整数') raise ValidationError(f'不合格项{k_2}必须为非负整数')
attrs['count_notok'] = count_notok attrs['count_notok'] = count_notok
elif 'mb' in attrs and attrs['mb']:
attrs['wm'] = None
attrs['material'] = attrs['mb'].material
attrs['batch'] = attrs['mb'].batch
else:
raise ValidationError('请选择车间/仓库库存')
return attrs return attrs
@ -96,6 +103,7 @@ class FtestWorkSerializer(CustomModelSerializer):
material_name = serializers.StringRelatedField( material_name = serializers.StringRelatedField(
source='material', read_only=True) source='material', read_only=True)
material_cate = serializers.CharField(source='material.cate', read_only=True) material_cate = serializers.CharField(source='material.cate', read_only=True)
mb_ = MaterialBatchDetailSerializer(source='mb', read_only=True)
class Meta: class Meta:
model = FtestWork model = FtestWork

View File

@ -125,7 +125,7 @@ class FtestWorkViewSet(CustomModelViewSet):
serializer_class = FtestWorkSerializer serializer_class = FtestWorkSerializer
create_serializer_class = FtestWorkCreateUpdateSerializer create_serializer_class = FtestWorkCreateUpdateSerializer
update_serializer_class = FtestWorkCreateUpdateSerializer update_serializer_class = FtestWorkCreateUpdateSerializer
select_related_fields = ['material'] select_related_fields = ['material', 'mb', 'mb__material']
filterset_class = FtestWorkFilter filterset_class = FtestWorkFilter
def update(self, request, *args, **kwargs): def update(self, request, *args, **kwargs):
@ -148,6 +148,8 @@ class FtestWorkViewSet(CustomModelViewSet):
提交检验工作 提交检验工作
""" """
ins:FtestWork = self.get_object() ins:FtestWork = self.get_object()
if ins.wm is None:
raise ParseError('该检验工作未关联车间库存')
if ins.submit_time is None: if ins.submit_time is None:
ftestwork_submit(ins, request.user) ftestwork_submit(ins, request.user)
else: else: