# coding=utf-8 from django.utils import timezone from apps.foundation.models import Option from apps.exceptions import CustomError from django.db import models from django.conf import settings from django.db.models import Sum, Q, Count from apps.account.models import User, Department from apps.supplier.models import Supplier from apps.product.models import ProductBase from apps.warehouse.models import Warehouse, WarehouseStock, WarehouseStockRecord, WarehouseRecord from libs.filefield import PathAndRename class PurchasePlan(models.Model): no = models.CharField(max_length=20, verbose_name=u"单号", editable=False) name = models.CharField(max_length=100, verbose_name=u"名称") status = models.PositiveSmallIntegerField(choices=settings.CHECK_STATUS_CHOICES, verbose_name=u"审核状态", default=settings.DEFAULT) create_user = models.ForeignKey(User, verbose_name=u"创建人", related_name='purchase_plan_ref_create_user', on_delete=models.PROTECT, blank=True, editable=False) department = models.ForeignKey(Department, verbose_name=u"创建部门", related_name='purchase_plan_ref_department', blank=True, editable=False, on_delete=models.PROTECT) demend_user = models.ForeignKey(User, verbose_name=u"需求人", related_name='purchase_plan_ref_demend_user', on_delete=models.PROTECT, blank=True, null=True) demend_department = models.ForeignKey(Department, verbose_name=u"需求车间", related_name='purchase_plan_ref_demend_department', on_delete=models.PROTECT, null=True, blank=True) create_time = models.DateTimeField(verbose_name=u"下单时间", default=timezone.now) check_user = models.ForeignKey(User, verbose_name=u"审核人",related_name='purchase_plan_ref_check_user', on_delete=models.PROTECT, null=True) check_time = models.DateTimeField(verbose_name=u"审核时间", null=True) total_count = models.BigIntegerField(verbose_name=u"合计数量", default=0) notes = models.CharField(max_length=100, verbose_name=u"备注", null=True, blank=True) # check_user2 = models.ForeignKey(User, verbose_name=u"复核人", related_name='purchase_plan_ref_check_user2', # on_delete=models.PROTECT, null=True, blank=True) # check_time2 = models.DateTimeField(verbose_name=u"复核时间", null=True) # # check_user3 = models.ForeignKey(User, verbose_name=u"批准人", related_name='purchase_plan_ref_check_user3', # on_delete=models.PROTECT, null=True, blank=True) # check_time3 = models.DateTimeField(verbose_name=u"批准时间", null=True) class Meta: db_table = "purchase_plan" verbose_name = u"计划管理" ordering = ('-id',) index_together = ( 'name', 'create_time','status','check_time' ) unique_together = ( 'no', ) default_permissions = () permissions = (# 采购计划管理 ("view_purchase_plan", u"浏览"), ("add_purchase_plan", u"添加"), ("check_purchase_plan", u"审核"), ("delete_purchase_plan", u"删除"), ("export_purchase_plan", u"导出"), ("print_purchase_plan", u"打印"), ("export_purchase_plan_price", u"导出询价汇总"), ("add_purchase_user_plan", u"添加采购员"), ("check2_purchase_plan", u"复核"), ("check3_purchase_plan", u"批准"), ) def isReport(self): purchaseprcies = PurchasePrice.objects.filter(purchase_detail__purchase=self, report=True).count() if purchaseprcies: return True return False def isCompart(self): purchaseprcies = PurchasePlanDetail.objects.filter(purchase=self, is_compact=True).count() if purchaseprcies: return True return False def updateTotalCount(self): total_count = 0 sum_row = PurchasePlanDetail.objects.filter(purchase=self).aggregate(Sum('purchase_count')) if sum_row: total_count = sum_row['purchase_count__sum'] or 0 self.total_count = total_count self.save() def getPurchaseDetails(self): return PurchasePlanDetail.objects.filter(purchase=self) @staticmethod def getById(id): instance = PurchasePlan.objects.filter(pk=id).first() if not instance: raise CustomError(u'未找到相应的采购计划') return instance def save(self, *args, **kwargs): if self.no == None or self.no == '': now = timezone.now() rows = PurchasePlan.objects.filter(create_time__gte=now.strftime('%Y-%m-%d')).order_by('-no') count = rows.count() if count == 0: self.no = 'CG%s%03d' % (now.strftime('%Y%m%d'), count + 1) else: self.no = rows[0].no[:2] + str(int(rows[0].no[2:]) + 1) super(PurchasePlan, self).save(*args, **kwargs) def removeCompact(self): PurchasePlanDetail.objects.filter(purchase=self).update(is_compact=False) def updateCompact(self): self.removeCompact() product_ids = PurchaseOrderDetail.objects.filter(main__plan=self).values_list('product_id',flat=True) PurchasePlanDetail.objects.filter(purchase=self,product_id__in=product_ids).update(is_compact=True) class PurchasePlanDetail(models.Model): purchase = models.ForeignKey(PurchasePlan, verbose_name=u"采购计划", on_delete=models.PROTECT) product = models.ForeignKey(ProductBase, verbose_name=u"产品", on_delete=models.PROTECT) #quality_request = models.ForeignKey(Option, verbose_name=u"质量要求", null=True, blank=True, on_delete=models.PROTECT) quality_request_text = models.CharField(max_length=100, verbose_name=u"质量要求", null=True, blank=True) purchase_count = models.BigIntegerField(u"采购数量", default=0) product_time = models.DateTimeField(verbose_name=u"需求时间", null=True, blank=True) notes = models.CharField(max_length=100, verbose_name=u"备注", null=True, blank=True) is_compact = models.BooleanField(verbose_name=u"生成采购合同", default=False) class Meta: db_table = "purchase_plan_detail" verbose_name = u"退料查询" default_permissions = () permissions = (# 采购计划明细 ("view_consumable_deliver_return_query", u"浏览"), ("export_consumable_deliver_return_query", u"导出"), ("print_consumable_deliver_return_query", u"打印"), ) @staticmethod def getById(id): instance = PurchasePlanDetail.objects.filter(id=id).first() if not instance: raise CustomError(u'未找到相应的采购计划明细') return instance class PurchaseUser(models.Model): purchase = models.ForeignKey(PurchasePlan, verbose_name=u"采购计划", on_delete=models.PROTECT) purchase_user = models.ForeignKey(User, verbose_name=u"采购员", on_delete=models.PROTECT, blank=True) class Meta: db_table = "purchase_user" verbose_name = u"询价管理" default_permissions = () permissions = ( ("view_purchase_user_plan", u"浏览"), ("add_purchase_price_plan", u"上报价格"), ("edit_purchase_price", u"修改询价"), ) class PurchasePrice(models.Model): purchase_detail = models.ForeignKey(PurchasePlanDetail, verbose_name=u"采购计划明细", on_delete=models.PROTECT, blank=True) purchase_user = models.ForeignKey(User, verbose_name=u"采购员", on_delete=models.PROTECT, blank=True) report = models.BooleanField(verbose_name=u"上报", default=False) supplier = models.ForeignKey(Supplier, verbose_name=u"供应商", on_delete=models.PROTECT, null=True) price = models.BigIntegerField(u"价格", default=0) tax_rate = models.FloatField(verbose_name=u"税率", null=True, blank=True) notes = models.CharField(max_length=100, verbose_name=u"备注", null=True, blank=True) class Meta: db_table = "purchase_plan_price" verbose_name = u"入库查询" ordering = ('-id',) default_permissions = () permissions = (# 询价记录 ("view_material_godownentry_query", u"浏览"), ("export_material_godownentry_query", u"导出"), ("print_material_godownentry_query", u"打印"), ) @staticmethod def getById(id): instances = PurchasePrice.objects.filter(pk=id).first() if not instances: raise CustomError(u'未找到相应的询价记录') return instances class PurchaseOrder(models.Model): DRAFT = 0 TAKE_EFFECT = 1 CHECKING = 2 STATUS_CHOICES = ( (DRAFT, u'草拟'), (TAKE_EFFECT, u'生效'), (CHECKING, u'审核中'), ) NO_ARRVAL = 0 PART_ARRVAL = 1 ALL_ARRVAL = 2 ARRVAL_CHOICES = ( (NO_ARRVAL, u'未到货'), (PART_ARRVAL, u'部分到货'), (ALL_ARRVAL, u'全部到货'), ) no = models.CharField(max_length=50, verbose_name=u"合同号", null=True) order_no = models.CharField(max_length=50, verbose_name=u"单号", editable=False) supplier = models.ForeignKey(Supplier, verbose_name=u"供应商", on_delete=models.PROTECT) count = models.BigIntegerField(u'数量', default=0) amount = models.BigIntegerField(u'金额', default=0) apply_amount = models.BigIntegerField(verbose_name=u'申请金额', default=0) plan = models.ForeignKey(PurchasePlan, verbose_name=u"采购计划", on_delete=models.PROTECT, blank=True,null=True) status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, verbose_name=u"状态", default=DRAFT) arrval = models.PositiveSmallIntegerField(choices=ARRVAL_CHOICES, verbose_name=u"到货", default=NO_ARRVAL) notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True) create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now) create_user = models.ForeignKey(User, related_name='purchase_order_ref_create_user', verbose_name=u"创建人", on_delete=models.PROTECT, editable=False) department = models.ForeignKey(Department, verbose_name=u"创建部门", editable=False, on_delete=models.PROTECT) check_time = models.DateTimeField(verbose_name=u"审核时间", null=True) check_user = models.ForeignKey(User, related_name='purchase_order_ref_check_user', verbose_name=u"审核人", on_delete=models.PROTECT, null=True) payment_type = models.CharField(max_length=50, verbose_name=u"付款方式", null=True, blank=True) deliver_time = models.CharField(max_length=200, verbose_name=u"交货时间", blank=True, null=True) check_user2 = models.ForeignKey(User, verbose_name=u"复核人", related_name='purchase_order_ref_check_user2', on_delete=models.PROTECT, null=True, blank=True) check_time2 = models.DateTimeField(verbose_name=u"复核时间", null=True) check_user3 = models.ForeignKey(User, verbose_name=u"批准人", related_name='purchase_order_ref_check_user3', on_delete=models.PROTECT, null=True, blank=True) check_time3 = models.DateTimeField(verbose_name=u"批准时间", null=True) consignee_name = models.CharField(max_length=100, verbose_name=u"收货人姓名", null=True) consignee_tel = models.CharField(max_length=100, verbose_name=u"收货人电话", null=True) class Meta: db_table = "purchase_order" verbose_name = u"合同管理" ordering = ('-id',) index_together = ( 'create_time', 'check_time', 'status', 'no' ) unique_together = ( 'order_no', ) default_permissions = () permissions = (# 采购合同管理 ("view_purchase_order", u"浏览"), ("add_purchase_order", u"添加"), ("edit_purchase_order", u"修改"), ("senior_purchase_order", u"高级修改"), ("check_purchase_order", u"审核"), ("delete_purchase_order", u"删除"), ("export_purchase_order", u"导出"), ("print_purchase_order", u"打印"), ("check2_purchase_order", u"复核"), ("check3_purchase_order", u"批准"), ) def updateApplyAmount(self): sum_amount = 0 sum_rows = PurchasePayment.objects.filter(order=self).aggregate(sum_amount=Sum('apply_amount')) if sum_rows: sum_amount = sum_rows['sum_amount'] or 0 self.apply_amount = sum_amount self.save() def save(self, *args, **kwargs): if self.order_no == None or self.order_no == '': now = timezone.now() rows = PurchaseOrder.objects.filter(create_time__gte=now.strftime('%Y-%m-%d')).order_by('-order_no') count = rows.count() if count == 0: self.order_no = 'CN%s%03d' % (now.strftime('%Y%m%d'), count + 1) else: self.order_no = rows[0].order_no[:2] + str(int(rows[0].order_no[2:]) + 1) super(PurchaseOrder, self).save(*args, **kwargs) @staticmethod def getById(id): instance = PurchaseOrder.objects.filter(pk=id).first() if not instance: raise CustomError(u'未找到相应的采购合同') return instance def updateAmount(self): sum_count = 0 sum_amount = 0 sum_row = PurchaseOrderDetail.objects.filter(main=self).aggregate(sum_count=Sum('count'), sum_amount=Sum('amount')) if sum_row: sum_count = sum_row['sum_count'] or 0 sum_amount = sum_row['sum_amount'] or 0 self.count = sum_count self.amount = sum_amount self.save() def updateArrval(self): rows = PurchaseOrderDetail.objects.filter(main=self) for row in rows: arrval_count = 0 g_rows = GodownEntryDetail.objects.filter(product_base_id=row.product_id, main__purchase_order=self, main__status=settings.PASS).aggregate(sum_count=Sum('count')) if g_rows: arrval_count = g_rows['sum_count'] or 0 row.arrval_count = arrval_count if row.arrval_count >= row.count: row.is_arrval = True else: row.is_arrval = False row.save() sum_arrval_count = 0 d_rows = PurchaseOrderDetail.objects.filter(main=self).aggregate(sum_count=Sum('arrval_count')) if d_rows: sum_arrval_count = d_rows['sum_count'] or 0 if sum_arrval_count == 0: self.arrval = PurchaseOrder.NO_ARRVAL self.save() else: all_arrval = True for row in rows: if not row.is_arrval: all_arrval = False break if all_arrval: self.arrval = PurchaseOrder.ALL_ARRVAL else: self.arrval = PurchaseOrder.PART_ARRVAL self.save() path_and_rename = PathAndRename("purchase_order/invoice/") class PurchaseOrderDetail(models.Model): main = models.ForeignKey(PurchaseOrder, verbose_name=u'采购合同', on_delete=models.PROTECT) product = models.ForeignKey(ProductBase, verbose_name=u'产品', on_delete=models.PROTECT) #quality_request = models.ForeignKey(Option, verbose_name=u"质量标准", null=True, on_delete=models.PROTECT) quality_request_text = models.CharField(max_length=100, verbose_name=u"质量要求", null=True, blank=True) count = models.BigIntegerField(u'数量', default=0) price = models.BigIntegerField(u'单价', default=0) amount = models.BigIntegerField(u'金额', default=0) arrval_count = models.BigIntegerField(u'到货数量', default=0) is_arrval = models.BooleanField(verbose_name=u"全部到货", default=0) invoice_no = models.CharField(max_length=50, verbose_name=u"发票号", null=True) invoice_amount = models.BigIntegerField(u'发票金额', null=True) invoice_date = models.DateField(verbose_name=u"开票日期", null=True) create_time = models.DateTimeField(verbose_name=u"录入时间", null=True) create_user = models.ForeignKey(User, related_name='purchase_order_detail_ref_create_user', verbose_name=u"录入人", on_delete=models.PROTECT, null=True) department = models.ForeignKey(Department, verbose_name=u"录入部门", null=True, on_delete=models.PROTECT) check_time = models.DateTimeField(verbose_name=u"审核时间", null=True) check_user = models.ForeignKey(User, related_name='purchase_order_detail_ref_check_user', verbose_name=u"审核人", on_delete=models.PROTECT, null=True) check_status = models.PositiveSmallIntegerField(choices=settings.CHECK_STATUS_CHOICES, verbose_name=u"审核状态", default=settings.DEFAULT) class Meta: db_table = "purchase_order_detail" verbose_name = u"发票管理" ordering = ('-id',) default_permissions = () permissions = (# 采购合同明细 ("view_purchase_invoice", u"浏览"), ("add_purchase_invoice", u"录入"), ("check_purchase_invoice", u"审核"), ("export_purchase_invoice", u"导出"), ) @staticmethod def getById(id): instances = PurchaseOrderDetail.objects.filter(id=id).first() if not instances: raise CustomError(u'未找到相应的合同明细') return instances class PurchaseInvoiceImage(models.Model): order_detail = models.ForeignKey(PurchaseOrderDetail, related_name='invoice_image_ref_purchase_order_detail', verbose_name=u"合同明细", editable=False) invoice_image = models.ImageField(verbose_name=u"发票图片", default='', null=True, upload_to=path_and_rename, blank=True) class Meta: db_table = "purchase_invoice_image" verbose_name = u"采购合同发票图片" class PurchasePayment(models.Model): no = models.CharField(max_length=20, verbose_name=u"单号", editable=False) order = models.ForeignKey(PurchaseOrder, verbose_name=u"合同", on_delete=models.PROTECT) status = models.PositiveSmallIntegerField(choices=settings.CHECK_STATUS_CHOICES, default=settings.DEFAULT, verbose_name=u"状态") amount = models.BigIntegerField(verbose_name=u'合同金额', default=0) actual_amount = models.BigIntegerField(verbose_name=u'实付金额', default=0) apply_amount = models.BigIntegerField(verbose_name=u'申请金额', default=0) is_pay = models.BooleanField(verbose_name=u"是否付款", default=0) notes = models.CharField(max_length=200, verbose_name=u"申请备注", blank=True, null=True) create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now) create_user = models.ForeignKey(User, related_name='purchase_payment_ref_create_user', verbose_name=u"创建人", on_delete=models.PROTECT, editable=False) department = models.ForeignKey(Department, verbose_name=u"创建部门", editable=False, on_delete=models.PROTECT) check_time = models.DateTimeField(verbose_name=u"审核时间", null=True) check_user = models.ForeignKey(User, related_name='purchase_payment_ref_check_user', verbose_name=u"审核人", on_delete=models.PROTECT, null=True) review_user = models.ForeignKey(User, verbose_name=u"复核人", related_name='purchase_payment_ref_review_user', on_delete=models.PROTECT, null=True, blank=True) review_time = models.DateTimeField(verbose_name=u"复核时间", null=True) ratify_user = models.ForeignKey(User, verbose_name=u"批准人", related_name='purchase_payment_ref_ratify_user', on_delete=models.PROTECT, null=True, blank=True) ratify_time = models.DateTimeField(verbose_name=u"批准时间", null=True) class Meta: db_table = "purchase_payment" verbose_name = u"付款管理" ordering = ('-id',) index_together = ( 'create_time', 'check_time', 'status' ) unique_together = ( 'no', ) default_permissions = () permissions = ( ("view_purchase_payment", u"浏览"), ("add_purchase_payment", u"添加"), ("check_purchase_payment", u"审核"), ("review_purchase_payment", u"复核"), ("ratify_purchase_payment", u"批准"), ("pay_purchase_payment", u"付款"), ("delete_purchase_payment", u"删除"), ("export_purchase_payment", u"导出"), ("print_purchase_payment", u"打印"), ) @staticmethod def getById(id): instance = PurchasePayment.objects.filter(pk=id).first() if not instance: raise CustomError(u'未找到相应的付款单') return instance def updateAmount(self): sum_amount = 0 sum_row = PurchasePaymentDetail.objects.filter(main=self).aggregate(sum_amount=Sum('purchase_detail__amount')) if sum_row: sum_amount = sum_row['sum_amount'] or 0 self.amount = sum_amount self.save() def updateActualAmount(self): sum_actual_amount = 0 sum_row = PurchasePay.objects.filter(main=self).aggregate(sum_actual_amount=Sum('actual_amount')) if sum_row: sum_actual_amount = sum_row['sum_actual_amount'] or 0 self.actual_amount = sum_actual_amount self.save() def save(self, *args, **kwargs): if self.no == None or self.no == '': now = timezone.now() rows = PurchasePayment.objects.filter(create_time__gte=now.strftime('%Y-%m-%d')).order_by('-no') count = rows.count() if count == 0: self.no = 'CY%s%03d' % (now.strftime('%Y%m%d'), count + 1) else: self.no = rows[0].no[:2] + str(int(rows[0].no[2:]) + 1) super(PurchasePayment, self).save(*args, **kwargs) class PurchasePaymentDetail(models.Model): main = models.ForeignKey(PurchasePayment, verbose_name=u"付款单", on_delete=models.PROTECT) purchase_detail = models.ForeignKey(PurchaseOrderDetail, verbose_name=u"合同明细", on_delete=models.PROTECT) class Meta: db_table = "purchase_payment_detail" verbose_name = u"入库查询" ordering = ('-id',) default_permissions = () permissions = ( # 付款明细 ("view_consumable_godownentry_query", u"浏览"), ("export_consumable_godownentry_query", u"导出"), ("print_consumable_godownentry_query", u"打印"), ) class PurchasePay(models.Model): main = models.ForeignKey(PurchasePayment, verbose_name=u"付款单", on_delete=models.PROTECT) payment_type = models.ForeignKey(Option, verbose_name=u"付款方式", on_delete=models.PROTECT) payment_time = models.DateTimeField(verbose_name=u"付款时间", default=timezone.now) actual_amount = models.BigIntegerField(verbose_name=u'实付金额', default=0) payment_user = models.ForeignKey(User, verbose_name=u"付款人", editable=False,on_delete=models.PROTECT) payment_department = models.ForeignKey(Department, verbose_name=u"付款部门", editable=False, on_delete=models.PROTECT) notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True) class Meta: db_table = "purchase_pay" verbose_name = u"付款明细" ordering = ('-id',) default_permissions = () @staticmethod def getByMainId(id): instances = PurchasePay.objects.filter(main_id=id) if not instances: raise CustomError(u'未找到相应的付款单') return instances @staticmethod def getById(id): instance = PurchasePay.objects.filter(id=id).first() if not instance: raise CustomError(u'未找到相应的付款单') return instance class GodownEntry(models.Model): MATERIAL = 0 CONSUMABLE = 1 PRODUCT_CHOICES = ( (MATERIAL, u'原料'), (CONSUMABLE, u'耗材'), ) PREFIX_CHOICES = ( (MATERIAL, 'MR'), (CONSUMABLE, 'CR'), ) no = models.CharField(max_length=20, verbose_name=u"入库单号", editable=False) supplier = models.ForeignKey(Supplier, verbose_name=u'供应商', on_delete=models.PROTECT) purchase_order = models.ForeignKey(PurchaseOrder, verbose_name=u'采购合同', blank=True, null=True, on_delete=models.PROTECT) total_count = models.BigIntegerField(verbose_name=u'数量合计', default=0) total_amount = models.BigIntegerField(verbose_name=u'金额合计', default=0) total_invoice_amount = models.BigIntegerField(verbose_name=u'发票金额合计', default=0) #等于明细里面的发票金额合计 create_user = models.ForeignKey(User, related_name='godown_entry_ref_create_user', verbose_name=u"创建人", on_delete=models.PROTECT, editable=False) department = models.ForeignKey(Department, verbose_name=u"创建部门", on_delete=models.PROTECT, editable=False) create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now) status = models.PositiveSmallIntegerField(choices=settings.CHECK_STATUS_CHOICES, default=settings.DEFAULT, verbose_name=u"审核状态") check_user = models.ForeignKey(User, related_name='godown_entry_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) notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True) warehouse = models.ForeignKey(Warehouse, verbose_name=u'仓别', on_delete=models.PROTECT) product_type = models.PositiveSmallIntegerField(choices=PRODUCT_CHOICES, verbose_name=u"产品类型") total_return_count = models.BigIntegerField(verbose_name=u"退货数量合计", default=0) total_return_amount = models.BigIntegerField(verbose_name=u"退货金额合计", default=0) total_deliver_count = models.BigIntegerField(verbose_name=u"出库数量合计", default=0) total_deliver_amount = models.BigIntegerField(verbose_name=u"出库金额合计", default=0) class Meta: db_table = "godown_entry" verbose_name = u"入库管理" ordering = ('-id',) index_together = ( 'create_time', 'check_time', 'status' ) unique_together = ( 'no', ) default_permissions = () permissions = ( ("view_material_godown_entry", u"浏览"), ("add_material_godown_entry", u"添加"), ("check_material_godown_entry", u"审核"), ("delete_material_godown_entry", u"删除"), ("export_material_godown_entry", u"导出"), ("import_material_godown_entry", u"导入"), ("print_material_godown_entry", u"打印"), ("edit_material_godown_entry", u"高级修改"), ) @staticmethod def getById(id): instances = GodownEntry.objects.filter(id=id).first() if not instances: raise CustomError(u'未找到相应的入库单') return instances @staticmethod def getPermissionByType(type, action): permissions = GodownEntry.getPermissionMap() type = GodownEntry.getValidType(type) return permissions[type][action] @staticmethod def getPermissionMap(): permissions = { GodownEntry.MATERIAL: {'view': 'purchase.view_material_godown_entry', 'add': 'purchase.add_material_godown_entry', 'check': 'purchase.check_material_godown_entry', 'delete': 'purchase.delete_material_godown_entry', 'export': 'purchase.export_material_godown_entry', 'import': 'purchase.import_material_godown_entry', 'print': 'purchase.print_material_godown_entry', 'edit': "purchase.edit_consumable_godown_entry", }, GodownEntry.CONSUMABLE: {'view': 'purchase.view_consumable_godown_entry', 'add': 'purchase.add_consumable_godown_entry', 'check': 'purchase.check_consumable_godown_entry', 'delete': 'purchase.delete_consumable_godown_entry', 'export': 'purchase.export_consumable_godown_entry', 'import': 'purchase.import_consumable_godown_entry', 'print': 'purchase.print_consumable_godown_entry', 'edit': "purchase.edit_consumable_godown_entry", }, } return permissions @staticmethod def getValidType(type): try: type = int(type) except: raise CustomError(u'错误的入库类型') types = (r[0] for r in GodownEntry.PRODUCT_CHOICES) if type not in types: raise CustomError(u'无效的入库类型') return type def getPermission(self, action): permissions = GodownEntry.getPermissionMap() return permissions[self.product_type][action] def save(self, *args, **kwargs): if self.no == None or self.no == '': now = timezone.now() rows = GodownEntry.objects.filter(create_time__gte=now.strftime('%Y-%m-%d'), product_type=self.product_type).order_by('-no') count = rows.count() prefix = GodownEntry.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(GodownEntry, self).save(*args, **kwargs) def update_total(self): total_count = 0 total_amount = 0 total_invoice_amount = 0 sum_row = GodownEntryDetail.objects.filter(main=self).aggregate(total_count=Sum('count'),\ total_amount=Sum('amount'), total_invoice_amount=Sum('invoice_amount')) if sum_row: total_count = sum_row['total_count'] or 0 total_amount = sum_row['total_amount'] or 0 total_invoice_amount = sum_row['total_invoice_amount'] or 0 self.total_count = total_count self.total_amount = total_amount self.total_invoice_amount = total_invoice_amount self.save() def update_redundant(self): total_return_count = 0 total_return_amount = 0 total_deliver_count = 0 total_deliver_amount = 0 sum_row = GodownEntryDetail.objects.filter(main=self).aggregate(sum_return_count=Sum('return_count'), sum_return_amount=Sum('return_amount'), sum_deliver_count=Sum('deliver_count'), sum_deliver_amount=Sum('deliver_amount')) if sum_row: total_return_count = sum_row['sum_return_count'] or 0 total_return_amount = sum_row['sum_return_amount'] or 0 total_deliver_count = sum_row['sum_deliver_count'] or 0 total_deliver_amount = sum_row['sum_deliver_amount'] or 0 self.total_return_count = total_return_count self.total_return_amount = total_return_amount self.total_deliver_count = total_deliver_count self.total_deliver_amount = total_deliver_amount self.save() class GodownEntryDetail(models.Model): main = models.ForeignKey(GodownEntry, verbose_name=u'入库单',related_name='godown_entry_detail_ref_main', on_delete=models.PROTECT) product_base = models.ForeignKey(ProductBase, verbose_name=u'产品', on_delete=models.PROTECT) count = models.BigIntegerField(verbose_name=u'数量', default=0) price = models.BigIntegerField(verbose_name=u'单价', default=0) warehouse_stock = models.ForeignKey(WarehouseStock, verbose_name=u'仓别库存', on_delete=models.PROTECT, editable=False) stock_record = models.ForeignKey(WarehouseStockRecord, verbose_name=u'库存记录', on_delete=models.PROTECT, null=True,blank=True, related_name='godown_entry_detail_ref_stock_record',) amount = models.BigIntegerField(verbose_name=u'金额', default=0)#数量*单价 invoice_amount = models.BigIntegerField(verbose_name=u'发票金额', default=0) #手工录入 return_count = models.BigIntegerField(verbose_name=u"退货数量", default=0) return_amount = models.BigIntegerField(verbose_name=u"退货金额", default=0) deliver_count = models.BigIntegerField(verbose_name=u"出库数量", default=0) deliver_amount = models.BigIntegerField(verbose_name=u"出库金额", default=0) notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True) class Meta: db_table = "godown_entry_detail" verbose_name = u"入库管理" ordering = ('-id',) default_permissions = () permissions = (# 原料/耗材入库明细 ("view_consumable_godown_entry", u"浏览"), ("add_consumable_godown_entry", u"添加"), ("check_consumable_godown_entry", u"审核"), ("delete_consumable_godown_entry", u"删除"), ("export_consumable_godown_entry", u"导出"), ("import_consumable_godown_entry", u"导入"), ("print_consumable_godown_entry", u"打印"), ("edit_consumable_godown_entry", u"高级修改"), ) @staticmethod def getById(id): instances = GodownEntryDetail.objects.filter(id=id).first() if not instances: raise CustomError(u'未找到相应的入库明细') return instances class GodownEntryReturn(models.Model): MATERIAL = 0 CONSUMABLE = 1 PRODUCT_CHOICES = ( (MATERIAL, u'原料'), (CONSUMABLE, u'耗材'), ) PREFIX_CHOICES = ( (MATERIAL, 'MT'), (CONSUMABLE, 'CT'), ) no = models.CharField(max_length=20, verbose_name=u"单号", editable=False) type = models.PositiveSmallIntegerField(choices=PRODUCT_CHOICES, verbose_name=u"产品类型") supplier = models.ForeignKey(Supplier, verbose_name=u"供应商", null=True, blank=True, on_delete=models.PROTECT) warehouse = models.ForeignKey(Warehouse, verbose_name=u"仓别", on_delete=models.PROTECT) create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now) create_user = models.ForeignKey(User, related_name='godown_entry_return_ref_create_user', verbose_name=u"创建人", on_delete=models.PROTECT, editable=False) department = models.ForeignKey(Department, verbose_name=u"创建部门", editable=False, on_delete=models.PROTECT) status = models.PositiveSmallIntegerField(choices=settings.CHECK_STATUS_CHOICES, default=settings.DEFAULT, verbose_name=u"审核状态") check_user = models.ForeignKey(User, related_name='godown_entry_return_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) notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True) total_count = models.BigIntegerField(verbose_name=u"合计数量", default=0) total_amount = models.BigIntegerField(verbose_name=u"合计金额", default=0) class Meta: db_table = "godown_entry_return" verbose_name = u"退货管理" ordering = ('-id',) index_together = ( 'create_time', 'check_time', 'status' ) unique_together = ( 'no', ) default_permissions = () permissions = ( ("view_material_godown_entry_return", u"浏览"), ("add_material_godown_entry_return", u"添加"), ("check_material_godown_entry_return", u"审核"), ("delete_material_godown_entry_return", u"删除"), ("export_material_godown_entry_return", u"导出"), ("print_material_godown_entry_return", u"打印"), ) @staticmethod def getById(id): instances = GodownEntryReturn.objects.filter(id=id).first() if not instances: raise CustomError(u'未找到相应的退货单') return instances @staticmethod def getPermissionByType(type, action): permissions = GodownEntryReturn.getPermissionMap() type = GodownEntryReturn.getValidType(type) return permissions[type][action] @staticmethod def getPermissionMap(): permissions = { GodownEntryReturn.MATERIAL: {'view': 'purchase.view_material_godown_entry_return', 'add': 'purchase.add_material_godown_entry_return', 'check': 'purchase.check_material_godown_entry_return', 'delete': 'purchase.delete_material_godown_entry_return', 'export': 'purchase.export_material_godown_entry_return', 'print': 'purchase.print_material_godown_entry_return' }, GodownEntryReturn.CONSUMABLE: {'view': 'purchase.view_consumable_godown_entry_return', 'add': 'purchase.add_consumable_godown_entry_return', 'check': 'purchase.check_consumable_godown_entry_return', 'delete': 'purchase.delete_consumable_godown_entry_return', 'export': 'purchase.export_consumable_godown_entry_return', 'print': 'purchase.print_consumable_godown_entry_return' }, } return permissions @staticmethod def getValidType(type): try: type = int(type) except: raise CustomError(u'错误的退货类型') types = (r[0] for r in GodownEntryReturn.PRODUCT_CHOICES) if type not in types: raise CustomError(u'无效的退货类型') return type def getPermission(self, action): permissions = GodownEntryReturn.getPermissionMap() return permissions[self.type][action] def save(self, *args, **kwargs): if self.no == None or self.no == '': now = timezone.now() rows = GodownEntryReturn.objects.filter(create_time__gte=now.strftime('%Y-%m-%d'), type=self.type).order_by('-no') count = rows.count() prefix = GodownEntryReturn.PREFIX_CHOICES[self.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(GodownEntryReturn, self).save(*args, **kwargs) def update_total(self): total_count = 0 total_amount = 0 sum_row = GodownEntryReturnDetail.objects.filter(main=self).aggregate(total_count=Sum('count'), total_amount=Sum('amount')) if sum_row: total_count = sum_row['total_count'] or 0 total_amount = sum_row['total_amount'] or 0 self.total_count = total_count self.total_amount = total_amount self.save() class GodownEntryReturnDetail(models.Model): main = models.ForeignKey(GodownEntryReturn, verbose_name=u"退货单", related_name='godown_entry_return_detail_ref_main', on_delete=models.PROTECT) product_base = models.ForeignKey(ProductBase, verbose_name=u'产品') count = models.BigIntegerField(verbose_name=u"数量", default=0) price = models.BigIntegerField(verbose_name=u"单价", default=0) amount = 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='godown_entry_return_detail_ref_warehouse_record', ) godownentry_detail = models.ForeignKey(GodownEntryDetail, verbose_name=u"入库明细", on_delete=models.PROTECT, null=True, blank=True) notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True) class Meta: db_table = "godown_entry_detail_return" verbose_name = u"退货管理" ordering = ('-id',) default_permissions = () permissions = (# 退货明细 ("view_consumable_godown_entry_return", u"浏览"), ("add_consumable_godown_entry_return", u"添加"), ("check_consumable_godown_entry_return", u"审核"), ("delete_consumable_godown_entry_return", u"删除"), ("export_consumable_godown_entry_return", u"导出"), ("print_consumable_godown_entry_return", u"打印"), ) @staticmethod def getById(id): instances = GodownEntryReturnDetail.objects.filter(id=id).first() if not instances: raise CustomError(u'未找到相应的退货明细') return instances @staticmethod def getById2(id): instances = GodownEntryReturnDetail.objects.filter(id=id).first() if not instances: return None return instances