# coding=utf-8 from django.db import models from django.db.models import Sum from django.utils import timezone from django.conf import settings from apps.account.models import User, Department from apps.exceptions import CustomError from apps.goods.models import Goods from apps.product.models import ProductBase from apps.warehouse.models import Warehouse, WarehouseStock, WarehouseRecord, WarehouseStockRecord class Material(models.Model): NONE = 0 LOWER = 1 UPPER = 2 SUGGEST_CHOICES = ( (NONE, u'不开启'), (LOWER, u'按库存下限预警'), (UPPER, u'按库存上限预警'), ) product_base = models.ForeignKey(ProductBase, verbose_name=u"产品", on_delete=models.PROTECT, blank=True) htc_identification = models.CharField(max_length=100, verbose_name=u"产品标识", null=True, blank=True) stock_upper_limit = models.BigIntegerField(verbose_name=u"库存上限", null=True, blank=True) stock_lower_limit = models.BigIntegerField(verbose_name=u"库存下限", null=True, blank=True) purchase_suggest = models.PositiveSmallIntegerField(choices=SUGGEST_CHOICES, verbose_name=u"库存预警", default=NONE) class Meta: db_table = "material" verbose_name = u"原料产品管理" ordering = ('-id',) default_permissions = () permissions = ( ("view_material", u"浏览"), ("add_material", u"添加"), ("delete_material", u"删除"), ("export_material", u"导出"), ("import_material", u"导入"), ("view_material_cost", u"查看成本"), ) @staticmethod def getById(id): instance = Material.objects.filter(pk=id).first() if not instance: raise CustomError(u'未找到相应的原料') return instance @staticmethod def getPurchaseSuggest(): purchasesuggest = { u'不开启' : 0, u'按库存下限预警': 1, u'按库存上限预警': 2 } return purchasesuggest @staticmethod def getPurchaseSuggestValue(value): purchasesuggest = Material.getPurchaseSuggest() try: purchase_suggest = purchasesuggest[value] except: raise CustomError(u'库存预警填写不正确') return purchase_suggest class Consumable(models.Model): product_base = models.ForeignKey(ProductBase, verbose_name=u"产品", on_delete=models.PROTECT, blank=True) stock_upper_limit = models.BigIntegerField(verbose_name=u"库存上限", null=True, blank=True) stock_lower_limit = models.BigIntegerField(verbose_name=u"库存下限", null=True, blank=True) purchase_suggest = models.PositiveSmallIntegerField(choices=Material.SUGGEST_CHOICES, verbose_name=u"库存预警", default=Material.NONE) class Meta: db_table = "consumable" verbose_name = u"耗材产品管理" ordering = ('-id',) default_permissions = () permissions = ( ("view_consumable", u"浏览"), ("add_consumable", u"添加"), ("delete_consumable", u"删除"), ("export_consumable", u"导出"), ("import_consumable", u"导入"), ("view_consumable_cost", u"查看成本"), ) @staticmethod def getById(id): instance = Consumable.objects.filter(pk=id).first() if not instance: raise CustomError(u'未找到相应的耗材') return instance class Deliver(models.Model): MATERIAL = 0 CONSUMABLE = 1 PRODUCT_CHOICES = ( (MATERIAL, u'原料'), (CONSUMABLE, u'耗材'), ) PREFIX_CHOICES = ( (MATERIAL, 'CM'), (CONSUMABLE, 'CC') ) no = models.CharField(max_length=20, verbose_name=u"出库单号", editable=False) product_type = models.PositiveSmallIntegerField(choices=PRODUCT_CHOICES, verbose_name=u"产品类型") create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now) create_user = models.ForeignKey(User, verbose_name=u"创建人", related_name='deliver_ref_create_user', on_delete=models.PROTECT, blank=True, editable=False) department = models.ForeignKey(Department, verbose_name=u"创建部门", related_name='deliver_ref_department', on_delete=models.PROTECT, blank=True, editable=False) receiver = models.ForeignKey(User, verbose_name=u"领用人", related_name='deliver_ref_receiver',on_delete=models.PROTECT) receiver_department = models.ForeignKey(Department, verbose_name=u"领用车间", related_name='deliver_ref_receiver_department', on_delete=models.PROTECT, blank=True, editable=False) status = models.PositiveSmallIntegerField(choices=settings.CHECK_STATUS_CHOICES, verbose_name=u"审核状态", default=settings.DEFAULT) check_user = models.ForeignKey(User, related_name='deliver_ref_check_user', verbose_name=u"审核人", on_delete=models.PROTECT, blank=True, null=True) check_time = models.DateTimeField(verbose_name=u"审核时间", blank=True, null=True) warehouse = models.ForeignKey(Warehouse, verbose_name=u'仓别', on_delete=models.PROTECT) notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True) goods = models.ForeignKey(Goods, verbose_name=u'成品', on_delete=models.PROTECT, blank=True, null=True) total_count = models.BigIntegerField(verbose_name=u'合计数量', default=0) total_cost = models.BigIntegerField(verbose_name=u'合计成本', default=0) return_count = models.BigIntegerField(verbose_name=u"合计退料数量", default=0) return_cost = models.BigIntegerField(verbose_name=u"合计退料成本", default=0) class Meta: db_table = "deliver" verbose_name = u"出库管理" ordering = ('-id',) index_together = ( 'create_time', 'check_time', 'status' ) unique_together = ( 'no', ) default_permissions = () permissions = ( ("view_material_deliver", u"浏览"), ("add_material_deliver", u"添加"), ("check_material_deliver", u"审核"), ("delete_material_deliver", u"删除"), ("export_material_deliver", u"导出"), ("print_material_deliver", u"打印"), ) def getPermission(self, action): permissions = Deliver.getPermissionMap() return permissions[self.product_type][action] @staticmethod def getById(id): instances = Deliver.objects.filter(id=id).first() if not instances: raise CustomError(u'未找到相应的出库单') return instances @staticmethod def getPermissionByType(type, action): permissions = Deliver.getPermissionMap() type = Deliver.getValidType(type) return permissions[type][action] @staticmethod def getPermissionMap(): permissions = { Deliver.MATERIAL: {'view': 'material.view_material_deliver', 'add': 'material.add_material_deliver', 'check': 'material.check_material_deliver', 'delete': 'material.delete_material_deliver', 'export': 'material.export_material_deliver', 'import': 'material.import_material_deliver', 'print': 'material.print_material_deliver' }, Deliver.CONSUMABLE: {'view': 'material.view_consumable_deliver', 'add': 'material.add_consumable_deliver', 'check': 'material.check_consumable_deliver', 'delete': 'material.delete_consumable_deliver', 'export': 'material.export_consumable_deliver', 'import': 'material.import_consumable_deliver', 'print': 'material.print_consumable_deliver' }, } return permissions @staticmethod def getValidType(type): try: type = int(type) except: raise CustomError(u'错误的出库类型') types = (r[0] for r in Deliver.PRODUCT_CHOICES) if type not in types: raise CustomError(u'无效的出库类型') return type def save(self, *args, **kwargs): if self.no == None or self.no == '': now = timezone.now() rows = Deliver.objects.filter(create_time__gte=now.strftime('%Y-%m-%d')).order_by('-no') count = rows.count() prefix = self.PREFIX_CHOICES[self.product_type][1] if count == 0: self.no = '%s%s%03d' % (prefix, now.strftime('%Y%m%d'), count + 1) else: self.no = rows[0].no[:2] + str(int(rows[0].no[2:]) + 1) super(Deliver, self).save(*args, **kwargs) def update_total(self): total_count = 0 total_cost = 0 sum_row = DeliverDetail.objects.filter(main=self).aggregate(total_count=Sum('count'), total_cost=Sum('total_cost')) if sum_row: total_count = sum_row['total_count'] or 0 total_cost = sum_row['total_cost'] or 0 self.total_count = total_count self.total_cost = total_cost self.save() def update_return(self): return_count = 0 return_cost = 0 sum_row = DeliverDetail.objects.filter(main=self).aggregate(return_count=Sum('return_count'), return_cost=Sum('return_cost')) if sum_row: return_count = sum_row['return_count'] or 0 return_cost = sum_row['return_cost'] or 0 self.return_count = return_count self.return_cost = return_cost self.save() class DeliverDetail(models.Model): main = models.ForeignKey(Deliver, verbose_name=u'出库单', on_delete=models.PROTECT, related_name='deliver_details') product_base = models.ForeignKey(ProductBase, verbose_name=u'产品', on_delete=models.PROTECT) count = models.BigIntegerField(verbose_name=u'数量', default=0) warehouse_stock = models.ForeignKey(WarehouseStock, verbose_name=u'仓别库存', on_delete=models.PROTECT, editable=False) warehouse_record = models.ForeignKey(WarehouseRecord, verbose_name=u'库存记录', on_delete=models.PROTECT, null=True,blank=True, related_name='deliver_detail_ref_warehouse_record') warehouse_stockrecord = models.ForeignKey(WarehouseStockRecord, verbose_name=u'入库库存记录', on_delete=models.PROTECT, null=True,blank=True, related_name='deliver_detail_ref_warehouse_stock_record') total_cost = models.BigIntegerField(verbose_name=u'成本合计', default=0) return_count = models.BigIntegerField(verbose_name=u'退料数量',default=0) return_cost = models.BigIntegerField(verbose_name=u'退料成本合计', default=0) notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True) class Meta: db_table = "deliver_detail" verbose_name = u"出库管理" ordering = ('-id',) default_permissions = () permissions = ( ("view_consumable_deliver", u"浏览"), ("add_consumable_deliver", u"添加"), ("check_consumable_deliver", u"审核"), ("delete_consumable_deliver", u"删除"), ("export_consumable_deliver", u"导出"), ("print_consumable_deliver", u"打印"), ) def updateReturn(self): return_count = 0 return_cost = 0 sum_row = DeliverReturnDetail.objects.filter(deliver_detail=self).aggregate(return_count=Sum('return_count'), return_cost=Sum('return_cost')) if sum_row: return_count = sum_row['return_count'] or 0 return_cost = sum_row['return_cost'] or 0 self.return_count = return_count self.return_cost = return_cost self.save() class DeliverReturn(models.Model): PREFIX_CHOICES = ( (Deliver.MATERIAL, 'TM'), (Deliver.CONSUMABLE, 'TC') ) no = models.CharField(max_length=20, verbose_name=u"退料单号", editable=False) product_type = models.PositiveSmallIntegerField(choices=Deliver.PRODUCT_CHOICES, verbose_name=u"产品类型") reason = models.CharField(max_length=500, verbose_name=u"原因", editable=False) create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now) create_user = models.ForeignKey(User, verbose_name=u"创建人", on_delete=models.PROTECT, blank=True, editable=False) department = models.ForeignKey(Department, verbose_name=u"创建部门", on_delete=models.PROTECT, blank=True, editable=False) return_count = models.BigIntegerField(verbose_name=u'退料合计数量', default=0) return_cost = models.BigIntegerField(verbose_name=u'退料合计成本', default=0) class Meta: db_table = "deliver_return" verbose_name = u"退料管理" ordering = ('-id',) index_together = ( 'create_time', ) unique_together = ( 'no', ) default_permissions = () permissions = ( ("view_material_deliver_return", u"浏览"), ("add_material_deliver_return", u"添加"), ("print_material_deliver_return", u"打印"), ) @staticmethod def getByIds(ids): return DeliverReturn.objects.filter(id__in=ids) def getPermission(self, action): permissions = DeliverReturn.getPermissionMap() return permissions[self.product_type][action] @staticmethod def getById(id): instances = DeliverReturn.objects.filter(id=id).first() if not instances: raise CustomError(u'未找到相应的退料单') return instances @staticmethod def getPermissionByType(type, action): permissions = DeliverReturn.getPermissionMap() type = DeliverReturn.getValidType(type) return permissions[type][action] @staticmethod def getPermissionMap(): permissions = { Deliver.MATERIAL: {'view': 'material.view_material_deliver_return', 'add': 'material.add_material_deliver_return', 'print': 'material.print_material_deliver_return' }, Deliver.CONSUMABLE: {'view': 'material.view_consumable_deliver_return', 'add': 'material.add_consumable_deliver_return', 'print': 'material.print_consumable_deliver_return' }, } return permissions @staticmethod def getValidType(type): try: type = int(type) except: raise CustomError(u'错误的退料类型') types = (r[0] for r in Deliver.PRODUCT_CHOICES) if type not in types: raise CustomError(u'无效的退料类型') return type def save(self, *args, **kwargs): if self.no == None or self.no == '': now = timezone.now() rows = DeliverReturn.objects.filter(create_time__gte=now.strftime('%Y-%m-%d')).order_by('-no') count = rows.count() prefix = self.PREFIX_CHOICES[self.product_type][1] if count == 0: self.no = '%s%s%03d' % (prefix, now.strftime('%Y%m%d'), count + 1) else: self.no = rows[0].no[:2] + str(int(rows[0].no[2:]) + 1) super(DeliverReturn, self).save(*args, **kwargs) def update_total(self): return_count = 0 return_cost = 0 sum_row = DeliverReturnDetail.objects.filter(main=self).aggregate(return_count=Sum('return_count'), return_cost=Sum('return_cost')) if sum_row: return_count = sum_row['return_count'] or 0 return_cost = sum_row['return_cost'] or 0 self.return_count = return_count self.return_cost = return_cost self.save() class DeliverReturnDetail(models.Model): main = models.ForeignKey(DeliverReturn, verbose_name=u'退料单', on_delete=models.PROTECT, related_name='deliver_return_details') deliver_detail = models.ForeignKey(DeliverDetail, verbose_name=u'出库明细', on_delete=models.PROTECT) product_base = models.ForeignKey(ProductBase, verbose_name=u'产品', on_delete=models.PROTECT) return_count = models.BigIntegerField(verbose_name=u'退料数量', default=0) return_cost = models.BigIntegerField(verbose_name=u'退料成本合计', default=0) warehouse_stock = models.ForeignKey(WarehouseStock, verbose_name=u'仓别库存', on_delete=models.PROTECT, editable=False) warehouse_record = models.ForeignKey(WarehouseRecord, verbose_name=u'库存记录', on_delete=models.PROTECT, null=True, blank=True, related_name='deliver_return_detail_ref_warehouse_record') notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True) class Meta: db_table = "deliver_detail_return" verbose_name = u"退料管理" ordering = ('-id',) default_permissions = () permissions = (# 退料管理明细 ("view_consumable_deliver_return", u"浏览"), ("add_consumable_deliver_return", u"添加"), ("print_consumable_deliver_return", u"打印"), )