210 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			210 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			Python
		
	
	
	
| from django.db import models
 | |
| from apps.utils.models import BaseModel, CommonBModel, CommonBDModel, CommonADModel
 | |
| from apps.pum.models import Supplier, PuOrder
 | |
| from apps.sam.models import Customer, Order
 | |
| from apps.mtm.models import Material, Mgroup
 | |
| from apps.system.models import User
 | |
| from datetime import datetime
 | |
| from django.db.models import Max
 | |
| # Create your models here.
 | |
| 
 | |
| 
 | |
| class WareHouse(CommonBModel):
 | |
|     """
 | |
|     TN:仓库信息
 | |
|     """
 | |
|     number = models.CharField('仓库编号', max_length=20)
 | |
|     name = models.CharField('仓库名称', max_length=20)
 | |
|     place = models.CharField('具体地点', max_length=50)
 | |
| 
 | |
| 
 | |
| class MaterialBatch(BaseModel):
 | |
|     """
 | |
|     TN:物料批次
 | |
|     """
 | |
|     batch = models.TextField('批次号')
 | |
|     state = models.PositiveSmallIntegerField('状态', default=10, choices=((10, '合格'), (20, '不合格'), (30, '返修'), (40, '检验'), (50, '报废')))
 | |
|     material = models.ForeignKey(
 | |
|         Material, on_delete=models.CASCADE, verbose_name='物料')
 | |
|     warehouse = models.ForeignKey(
 | |
|         WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
 | |
|     count = models.DecimalField('存量', max_digits=12, decimal_places=3, default=0)
 | |
|     production_dept = models.ForeignKey('system.dept', verbose_name='生产车间', on_delete=models.CASCADE, null=True, blank=True)
 | |
|     expiration_date = models.DateField('有效期', null=True, blank=True)
 | |
|     supplier = models.ForeignKey(
 | |
|         Supplier, verbose_name='供应商', on_delete=models.SET_NULL, null=True, blank=True)
 | |
| 
 | |
|     batch_ofrom = models.TextField('原料批次号', null=True, blank=True)
 | |
|     material_ofrom = models.ForeignKey(Material, verbose_name='原料物料', on_delete=models.SET_NULL, null=True, blank=True, related_name='mb_mofrom')
 | |
|     defect = models.ForeignKey('qm.defect', verbose_name='缺陷', on_delete=models.PROTECT, null=True, blank=True)
 | |
| 
 | |
| 
 | |
| class MaterialBatchA(BaseModel):
 | |
|     """
 | |
|     TN:组合件物料批次
 | |
|     """
 | |
|     batch = models.CharField('批次号', max_length=100)
 | |
|     material = models.ForeignKey(
 | |
|         Material, on_delete=models.CASCADE, verbose_name='物料')
 | |
|     rate = models.PositiveIntegerField('比例', default=1)
 | |
|     mb = models.ForeignKey(
 | |
|         MaterialBatch, verbose_name='关联物料批次', on_delete=models.CASCADE, related_name='a_mb')
 | |
| 
 | |
| 
 | |
| MIO_TYPE_PREFIX = {
 | |
|     'do_out': 'SCLL',     # 生产领料 (Shēngchǎn Lǐngliào)
 | |
|     'sale_out': 'XSFH',   # 销售发货 (Xiāoshòu Fāhuò)
 | |
|     'pur_in': 'CGRK',     # 采购入库 (Cǎigòu Rùkù)
 | |
|     'do_in': 'SCRK',      # 生产入库 (Shēngchǎn Rùkù)
 | |
|     'other_in': 'QTRK',   # 其他入库 (Qítā Rùkù)
 | |
|     'other_out': 'QTCK'   # 其他出库 (Qítā Chūkù)
 | |
| }
 | |
| 
 | |
| class MIO(CommonBDModel):
 | |
|     """
 | |
|     TN:出入库记录
 | |
|     """
 | |
|     MIO_TYPE_DO_OUT = 'do_out'
 | |
|     MIO_TYPE_SALE_OUT = 'sale_out'
 | |
|     MIO_TYPE_PUR_IN = 'pur_in'
 | |
|     MIO_TYPE_DO_IN = 'do_in'
 | |
|     MIO_TYPE_OTHER_IN = 'other_in'
 | |
|     MIO_TYPE_OTHER_OUT = 'other_out'
 | |
| 
 | |
|     MIO_TYPES = (
 | |
|         (MIO_TYPE_DO_OUT, '生产领料'),
 | |
|         (MIO_TYPE_SALE_OUT, '销售发货'),
 | |
|         (MIO_TYPE_PUR_IN, '采购入库'),
 | |
|         (MIO_TYPE_DO_IN, '生产入库'),
 | |
|         (MIO_TYPE_OTHER_IN, '其他入库'),
 | |
|         (MIO_TYPE_OTHER_OUT, '其他出库')
 | |
|     )
 | |
|     MIO_CREATE = 10
 | |
|     MIO_SUBMITED = 20
 | |
|     MIO_STATES = (
 | |
|         (MIO_CREATE, '创建中'),
 | |
|         (MIO_SUBMITED, '已提交')
 | |
|     )
 | |
|     number = models.CharField('编号', max_length=20, unique=True)
 | |
|     state = models.PositiveSmallIntegerField(
 | |
|         '状态', choices=MIO_STATES, default=10, help_text=str(MIO_CREATE))
 | |
|     type = models.CharField('出入库类型', max_length=10, default=MIO_TYPE_DO_OUT,
 | |
|                             choices=MIO_TYPES, help_text=str(MIO_TYPES))
 | |
|     mgroup = models.ForeignKey(Mgroup, verbose_name='出入库工段', on_delete=models.CASCADE, null=True, blank=True)
 | |
|     inout_date = models.DateField('出入库日期', null=True, blank=True)
 | |
|     supplier = models.ForeignKey(
 | |
|         Supplier, verbose_name='供应商', on_delete=models.CASCADE, null=True, blank=True)
 | |
|     customer = models.ForeignKey(
 | |
|         Customer, verbose_name='客户', on_delete=models.CASCADE, null=True, blank=True)
 | |
|     pu_order = models.ForeignKey(
 | |
|         PuOrder, verbose_name='关联采购订单', on_delete=models.CASCADE, null=True, blank=True)
 | |
|     order = models.ForeignKey(
 | |
|         Order, verbose_name='关联订单', on_delete=models.CASCADE, null=True, blank=True)
 | |
|     note = models.CharField('备注', max_length=1000, default='')
 | |
|     expiration_date = models.DateField('有效期', null=True, blank=True)
 | |
|     submit_time = models.DateTimeField('提交时间', null=True, blank=True)
 | |
|     submit_user = models.ForeignKey(
 | |
|         User, verbose_name='提交人', related_name='submit_user_mio', on_delete=models.CASCADE, null=True, blank=True)
 | |
|     mio_user = models.ForeignKey(
 | |
|         User, verbose_name='仓库执行人', related_name='mio_user_mio', on_delete=models.CASCADE, null=True, blank=True)
 | |
|     do_user = models.ForeignKey(
 | |
|         User, verbose_name='车间执行人', related_name='do_user_mio', on_delete=models.CASCADE, null=True, blank=True)
 | |
|     materials = models.ManyToManyField(
 | |
|         Material, verbose_name='物料明细', through='inm.mioitem', blank=True)
 | |
| 
 | |
|     @classmethod
 | |
|     def get_a_number(cls, mio_type:str):
 | |
|         today_str = datetime.now().strftime('%Y%m%d')
 | |
|         prefix = MIO_TYPE_PREFIX[mio_type]
 | |
|         last_record = MIO.objects.filter(number__startswith=f"{prefix}-{today_str}") \
 | |
|                                        .aggregate(Max('number'))['number__max']
 | |
|         if last_record:
 | |
|             last_number = int(last_record.split('-')[-1]) + 1
 | |
|         else:
 | |
|             last_number = 1
 | |
|         return f"{prefix}-{today_str}-{last_number:04d}"
 | |
| 
 | |
| class MIOItem(BaseModel):
 | |
|     """
 | |
|     TN:出入库明细
 | |
|     """
 | |
|     mio = models.ForeignKey(MIO, verbose_name='关联出入库',
 | |
|                             on_delete=models.CASCADE, related_name='item_mio')
 | |
|     mb = models.ForeignKey(MaterialBatch, verbose_name='关联仓库库存',
 | |
|                            on_delete=models.SET_NULL, related_name='mb_mioitem', null=True, blank=True)
 | |
|     wm = models.ForeignKey("wpm.wmaterial", verbose_name='关联车间库存',
 | |
|                            on_delete=models.SET_NULL, related_name='wm_mioitem', null=True, blank=True)
 | |
|     warehouse = models.ForeignKey(
 | |
|         WareHouse, on_delete=models.CASCADE, verbose_name='仓库')
 | |
|     material = models.ForeignKey(
 | |
|         Material, verbose_name='物料', on_delete=models.CASCADE)
 | |
|     batch = models.TextField('批次号')
 | |
|     count = models.DecimalField('出入数量', max_digits=12, decimal_places=3)
 | |
|     count_tested = models.PositiveIntegerField('已检数', null=True, blank=True)
 | |
|     test_date = models.DateField('检验日期', null=True, blank=True)
 | |
|     test_user = models.ForeignKey(
 | |
|         User, verbose_name='检验人', on_delete=models.CASCADE, null=True, blank=True)
 | |
|     test_note = models.TextField('检验备注', default='', blank=True)
 | |
|     count_bag = models.PositiveIntegerField('总袋数', default=0)
 | |
|     count_sampling = models.PositiveIntegerField('抽样数', default=0)
 | |
|     weight_kgs = models.JSONField('称重记录', default=list)
 | |
| 
 | |
|     count_notok = models.PositiveIntegerField('不合格数', default=0)
 | |
|     count_n_zw = models.PositiveIntegerField('炸纹', default=0)
 | |
|     count_n_tw = models.PositiveIntegerField('条纹', default=0)
 | |
|     count_n_qp = models.PositiveIntegerField('气泡', default=0)
 | |
|     count_n_wq = models.PositiveIntegerField('弯曲', default=0)
 | |
|     count_n_dl = models.PositiveIntegerField('断裂', default=0)
 | |
|     count_n_pb = models.PositiveIntegerField('偏壁', default=0)
 | |
|     count_n_dxt = models.PositiveIntegerField('大小头', default=0)
 | |
|     count_n_js = models.PositiveIntegerField('结石', default=0)
 | |
|     count_n_qx = models.PositiveIntegerField('气线', default=0)
 | |
|     count_n_zz = models.PositiveIntegerField('杂质', default=0)
 | |
|     count_n_ysq = models.PositiveIntegerField('颜色青', default=0)
 | |
|     count_n_hs = models.PositiveIntegerField('划伤', default=0)
 | |
|     count_n_b = models.PositiveIntegerField('扁', default=0)
 | |
|     count_n_jsqx = models.PositiveIntegerField('结石气线', default=0)  # 废弃字段
 | |
|     count_n_qt = models.PositiveIntegerField('其他', default=0)
 | |
| 
 | |
|     is_testok = models.BooleanField('检验是否合格', null=True, blank=True)
 | |
| 
 | |
|     @classmethod
 | |
|     def count_fields(cls):
 | |
|         mioitem_count_fields = []
 | |
|         for f in MIOItem._meta.fields:
 | |
|             if f.name.startswith("count"):
 | |
|                 mioitem_count_fields.append(f.name)
 | |
|         return mioitem_count_fields
 | |
| 
 | |
|     @property
 | |
|     def mioitemw(self):
 | |
|         return MIOItemw.objects.filter(mioitem=self)
 | |
| 
 | |
| class MIOItemA(BaseModel):
 | |
|     """
 | |
|     TN:组合件出入库明细
 | |
|     """
 | |
|     material = models.ForeignKey(
 | |
|         Material, verbose_name='物料', on_delete=models.CASCADE)
 | |
|     batch = models.CharField('批次号', max_length=50)
 | |
|     rate = models.PositiveIntegerField('比例', default=1)
 | |
|     mioitem = models.ForeignKey(
 | |
|         MIOItem, verbose_name='关联出入库明细', on_delete=models.CASCADE, related_name='a_mioitem')
 | |
| 
 | |
|     zhuidu = models.FloatField('锥度', null=True, blank=True)
 | |
|     b_zuidawaijing = models.FloatField('最大外径', null=True, blank=True)
 | |
|     g_zuidaneijing = models.FloatField('最大内径', null=True, blank=True)
 | |
| 
 | |
| 
 | |
| class MIOItemw(BaseModel):
 | |
|     """
 | |
|     TN:单件记录
 | |
|     """
 | |
|     number = models.TextField('编号')
 | |
|     wpr = models.ForeignKey("wpmw.wpr", verbose_name='关联产品', on_delete=models.SET_NULL, related_name='wpr_mioitemw'
 | |
|                             , null=True, blank=True)
 | |
|     mioitem = models.ForeignKey(MIOItem, verbose_name='关联出入库明细', on_delete=models.CASCADE, related_name='w_mioitem')
 | |
|     ftest = models.ForeignKey("qm.ftest", verbose_name='关联检验记录', on_delete=models.PROTECT,
 | |
|                               related_name='mioitemw_ftest', null=True, blank=True)
 | |
|     note = models.TextField('备注', null=True, blank=True)
 | |
|      |