models.py 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  1. # coding=utf-8
  2. from django.utils import timezone
  3. from apps.foundation.models import Option
  4. from apps.exceptions import CustomError
  5. from django.db import models
  6. from django.conf import settings
  7. from django.db.models import Sum, Q, Count
  8. from apps.account.models import User, Department
  9. from apps.supplier.models import Supplier
  10. from apps.product.models import ProductBase
  11. from apps.warehouse.models import Warehouse, WarehouseStock, WarehouseStockRecord, WarehouseRecord
  12. from libs.filefield import PathAndRename
  13. class PurchasePlan(models.Model):
  14. no = models.CharField(max_length=20, verbose_name=u"单号", editable=False)
  15. name = models.CharField(max_length=100, verbose_name=u"名称")
  16. status = models.PositiveSmallIntegerField(choices=settings.CHECK_STATUS_CHOICES, verbose_name=u"审核状态", default=settings.DEFAULT)
  17. create_user = models.ForeignKey(User, verbose_name=u"创建人", related_name='purchase_plan_ref_create_user',
  18. on_delete=models.PROTECT, blank=True, editable=False)
  19. department = models.ForeignKey(Department, verbose_name=u"创建部门", related_name='purchase_plan_ref_department', blank=True, editable=False, on_delete=models.PROTECT)
  20. demend_user = models.ForeignKey(User, verbose_name=u"需求人", related_name='purchase_plan_ref_demend_user', on_delete=models.PROTECT, blank=True, null=True)
  21. demend_department = models.ForeignKey(Department, verbose_name=u"需求车间", related_name='purchase_plan_ref_demend_department', on_delete=models.PROTECT, null=True, blank=True)
  22. create_time = models.DateTimeField(verbose_name=u"下单时间", default=timezone.now)
  23. check_user = models.ForeignKey(User, verbose_name=u"审核人",related_name='purchase_plan_ref_check_user', on_delete=models.PROTECT, null=True)
  24. check_time = models.DateTimeField(verbose_name=u"审核时间", null=True)
  25. total_count = models.BigIntegerField(verbose_name=u"合计数量", default=0)
  26. notes = models.CharField(max_length=100, verbose_name=u"备注", null=True, blank=True)
  27. # check_user2 = models.ForeignKey(User, verbose_name=u"复核人", related_name='purchase_plan_ref_check_user2',
  28. # on_delete=models.PROTECT, null=True, blank=True)
  29. # check_time2 = models.DateTimeField(verbose_name=u"复核时间", null=True)
  30. #
  31. # check_user3 = models.ForeignKey(User, verbose_name=u"批准人", related_name='purchase_plan_ref_check_user3',
  32. # on_delete=models.PROTECT, null=True, blank=True)
  33. # check_time3 = models.DateTimeField(verbose_name=u"批准时间", null=True)
  34. class Meta:
  35. db_table = "purchase_plan"
  36. verbose_name = u"计划管理"
  37. ordering = ('-id',)
  38. index_together = (
  39. 'name',
  40. 'create_time','status','check_time'
  41. )
  42. unique_together = (
  43. 'no',
  44. )
  45. default_permissions = ()
  46. permissions = (# 采购计划管理
  47. ("view_purchase_plan", u"浏览"),
  48. ("add_purchase_plan", u"添加"),
  49. ("check_purchase_plan", u"审核"),
  50. ("delete_purchase_plan", u"删除"),
  51. ("export_purchase_plan", u"导出"),
  52. ("print_purchase_plan", u"打印"),
  53. ("export_purchase_plan_price", u"导出询价汇总"),
  54. ("add_purchase_user_plan", u"添加采购员"),
  55. ("check2_purchase_plan", u"复核"),
  56. ("check3_purchase_plan", u"批准"),
  57. )
  58. def isReport(self):
  59. purchaseprcies = PurchasePrice.objects.filter(purchase_detail__purchase=self, report=True).count()
  60. if purchaseprcies:
  61. return True
  62. return False
  63. def isCompart(self):
  64. purchaseprcies = PurchasePlanDetail.objects.filter(purchase=self, is_compact=True).count()
  65. if purchaseprcies:
  66. return True
  67. return False
  68. def updateTotalCount(self):
  69. total_count = 0
  70. sum_row = PurchasePlanDetail.objects.filter(purchase=self).aggregate(Sum('purchase_count'))
  71. if sum_row:
  72. total_count = sum_row['purchase_count__sum'] or 0
  73. self.total_count = total_count
  74. self.save()
  75. def getPurchaseDetails(self):
  76. return PurchasePlanDetail.objects.filter(purchase=self)
  77. @staticmethod
  78. def getById(id):
  79. instance = PurchasePlan.objects.filter(pk=id).first()
  80. if not instance:
  81. raise CustomError(u'未找到相应的采购计划')
  82. return instance
  83. def save(self, *args, **kwargs):
  84. if self.no == None or self.no == '':
  85. now = timezone.now()
  86. rows = PurchasePlan.objects.filter(create_time__gte=now.strftime('%Y-%m-%d')).order_by('-no')
  87. count = rows.count()
  88. if count == 0:
  89. self.no = 'CG%s%03d' % (now.strftime('%Y%m%d'), count + 1)
  90. else:
  91. self.no = rows[0].no[:2] + str(int(rows[0].no[2:]) + 1)
  92. super(PurchasePlan, self).save(*args, **kwargs)
  93. def removeCompact(self):
  94. PurchasePlanDetail.objects.filter(purchase=self).update(is_compact=False)
  95. def updateCompact(self):
  96. self.removeCompact()
  97. product_ids = PurchaseOrderDetail.objects.filter(main__plan=self).values_list('product_id',flat=True)
  98. PurchasePlanDetail.objects.filter(purchase=self,product_id__in=product_ids).update(is_compact=True)
  99. class PurchasePlanDetail(models.Model):
  100. purchase = models.ForeignKey(PurchasePlan, verbose_name=u"采购计划", on_delete=models.PROTECT)
  101. product = models.ForeignKey(ProductBase, verbose_name=u"产品", on_delete=models.PROTECT)
  102. #quality_request = models.ForeignKey(Option, verbose_name=u"质量要求", null=True, blank=True, on_delete=models.PROTECT)
  103. quality_request_text = models.CharField(max_length=100, verbose_name=u"质量要求", null=True, blank=True)
  104. purchase_count = models.BigIntegerField(u"采购数量", default=0)
  105. product_time = models.DateTimeField(verbose_name=u"需求时间", null=True, blank=True)
  106. notes = models.CharField(max_length=100, verbose_name=u"备注", null=True, blank=True)
  107. is_compact = models.BooleanField(verbose_name=u"生成采购合同", default=False)
  108. class Meta:
  109. db_table = "purchase_plan_detail"
  110. verbose_name = u"退料查询"
  111. default_permissions = ()
  112. permissions = (# 采购计划明细
  113. ("view_consumable_deliver_return_query", u"浏览"),
  114. ("export_consumable_deliver_return_query", u"导出"),
  115. ("print_consumable_deliver_return_query", u"打印"),
  116. )
  117. @staticmethod
  118. def getById(id):
  119. instance = PurchasePlanDetail.objects.filter(id=id).first()
  120. if not instance:
  121. raise CustomError(u'未找到相应的采购计划明细')
  122. return instance
  123. class PurchaseUser(models.Model):
  124. purchase = models.ForeignKey(PurchasePlan, verbose_name=u"采购计划", on_delete=models.PROTECT)
  125. purchase_user = models.ForeignKey(User, verbose_name=u"采购员", on_delete=models.PROTECT, blank=True)
  126. class Meta:
  127. db_table = "purchase_user"
  128. verbose_name = u"询价管理"
  129. default_permissions = ()
  130. permissions = (
  131. ("view_purchase_user_plan", u"浏览"),
  132. ("add_purchase_price_plan", u"上报价格"),
  133. ("edit_purchase_price", u"修改询价"),
  134. )
  135. class PurchasePrice(models.Model):
  136. purchase_detail = models.ForeignKey(PurchasePlanDetail, verbose_name=u"采购计划明细", on_delete=models.PROTECT, blank=True)
  137. purchase_user = models.ForeignKey(User, verbose_name=u"采购员", on_delete=models.PROTECT, blank=True)
  138. report = models.BooleanField(verbose_name=u"上报", default=False)
  139. supplier = models.ForeignKey(Supplier, verbose_name=u"供应商", on_delete=models.PROTECT, null=True)
  140. price = models.BigIntegerField(u"价格", default=0)
  141. tax_rate = models.FloatField(verbose_name=u"税率", null=True, blank=True)
  142. notes = models.CharField(max_length=100, verbose_name=u"备注", null=True, blank=True)
  143. class Meta:
  144. db_table = "purchase_plan_price"
  145. verbose_name = u"入库查询"
  146. ordering = ('-id',)
  147. default_permissions = ()
  148. permissions = (# 询价记录
  149. ("view_material_godownentry_query", u"浏览"),
  150. ("export_material_godownentry_query", u"导出"),
  151. ("print_material_godownentry_query", u"打印"),
  152. )
  153. @staticmethod
  154. def getById(id):
  155. instances = PurchasePrice.objects.filter(pk=id).first()
  156. if not instances:
  157. raise CustomError(u'未找到相应的询价记录')
  158. return instances
  159. class PurchaseOrder(models.Model):
  160. DEFAULT = 0
  161. PASS = 1
  162. STATUS_CHOICES = (
  163. (DEFAULT, u'未审核'),
  164. (PASS, u'已审核')
  165. )
  166. NO_ARRVAL = 0
  167. PART_ARRVAL = 1
  168. ALL_ARRVAL = 2
  169. ARRVAL_CHOICES = (
  170. (NO_ARRVAL, u'未到货'),
  171. (PART_ARRVAL, u'部分到货'),
  172. (ALL_ARRVAL, u'全部到货'),
  173. )
  174. no = models.CharField(max_length=50, verbose_name=u"合同号", null=True)
  175. order_no = models.CharField(max_length=50, verbose_name=u"单号", editable=False)
  176. supplier = models.ForeignKey(Supplier, verbose_name=u"供应商", on_delete=models.PROTECT)
  177. count = models.BigIntegerField(u'数量', default=0)
  178. amount = models.BigIntegerField(u'金额', default=0)
  179. apply_amount = models.BigIntegerField(verbose_name=u'申请金额', default=0)
  180. plan = models.ForeignKey(PurchasePlan, verbose_name=u"采购计划", on_delete=models.PROTECT, blank=True,null=True)
  181. status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, verbose_name=u"状态", default=DEFAULT)
  182. arrval = models.PositiveSmallIntegerField(choices=ARRVAL_CHOICES, verbose_name=u"到货", default=NO_ARRVAL)
  183. notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True)
  184. create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now)
  185. create_user = models.ForeignKey(User, related_name='purchase_order_ref_create_user', verbose_name=u"创建人", on_delete=models.PROTECT, editable=False)
  186. department = models.ForeignKey(Department, verbose_name=u"创建部门", editable=False, on_delete=models.PROTECT)
  187. check_time = models.DateTimeField(verbose_name=u"审核时间", null=True)
  188. check_user = models.ForeignKey(User, related_name='purchase_order_ref_check_user', verbose_name=u"审核人", on_delete=models.PROTECT, null=True)
  189. payment_type = models.CharField(max_length=50, verbose_name=u"付款方式", null=True, blank=True)
  190. deliver_time = models.CharField(max_length=200, verbose_name=u"交货时间", blank=True, null=True)
  191. # check_user2 = models.ForeignKey(User, verbose_name=u"复核人", related_name='purchase_order_ref_check_user2',
  192. # on_delete=models.PROTECT, null=True, blank=True)
  193. # check_time2 = models.DateTimeField(verbose_name=u"复核时间", null=True)
  194. #
  195. # check_user3 = models.ForeignKey(User, verbose_name=u"批准人", related_name='purchase_order_ref_check_user3',
  196. # on_delete=models.PROTECT, null=True, blank=True)
  197. # check_time3 = models.DateTimeField(verbose_name=u"批准时间", null=True)
  198. consignee_name = models.CharField(max_length=100, verbose_name=u"收货人姓名", null=True)
  199. consignee_tel = models.CharField(max_length=100, verbose_name=u"收货人电话", null=True)
  200. class Meta:
  201. db_table = "purchase_order"
  202. verbose_name = u"合同管理"
  203. ordering = ('-id',)
  204. index_together = (
  205. 'create_time', 'check_time', 'status', 'no'
  206. )
  207. unique_together = (
  208. 'order_no',
  209. )
  210. default_permissions = ()
  211. permissions = (# 采购合同管理
  212. ("view_purchase_order", u"浏览"),
  213. ("add_purchase_order", u"添加"),
  214. ("edit_purchase_order", u"修改"),
  215. ("senior_purchase_order", u"高级修改"),
  216. ("check_purchase_order", u"审核"),
  217. ("delete_purchase_order", u"删除"),
  218. ("export_purchase_order", u"导出"),
  219. ("print_purchase_order", u"打印"),
  220. # ("check2_purchase_order", u"复核"),
  221. # ("check3_purchase_order", u"批准"),
  222. )
  223. def updateApplyAmount(self):
  224. sum_amount = 0
  225. sum_rows = PurchasePayment.objects.filter(order=self).aggregate(sum_amount=Sum('apply_amount'))
  226. if sum_rows:
  227. sum_amount = sum_rows['sum_amount'] or 0
  228. self.apply_amount = sum_amount
  229. self.save()
  230. def save(self, *args, **kwargs):
  231. if self.order_no == None or self.order_no == '':
  232. now = timezone.now()
  233. rows = PurchaseOrder.objects.filter(create_time__gte=now.strftime('%Y-%m-%d')).order_by('-order_no')
  234. count = rows.count()
  235. if count == 0:
  236. self.order_no = 'CN%s%03d' % (now.strftime('%Y%m%d'), count + 1)
  237. else:
  238. self.order_no = rows[0].order_no[:2] + str(int(rows[0].order_no[2:]) + 1)
  239. super(PurchaseOrder, self).save(*args, **kwargs)
  240. @staticmethod
  241. def getById(id):
  242. instance = PurchaseOrder.objects.filter(pk=id).first()
  243. if not instance:
  244. raise CustomError(u'未找到相应的采购合同')
  245. return instance
  246. def updateAmount(self):
  247. sum_count = 0
  248. sum_amount = 0
  249. sum_row = PurchaseOrderDetail.objects.filter(main=self).aggregate(sum_count=Sum('count'), sum_amount=Sum('amount'))
  250. if sum_row:
  251. sum_count = sum_row['sum_count'] or 0
  252. sum_amount = sum_row['sum_amount'] or 0
  253. self.count = sum_count
  254. self.amount = sum_amount
  255. self.save()
  256. def updateArrval(self):
  257. rows = PurchaseOrderDetail.objects.filter(main=self)
  258. for row in rows:
  259. arrval_count = 0
  260. g_rows = GodownEntryDetail.objects.filter(product_base_id=row.product_id, main__purchase_order=self, main__status=settings.PASS).aggregate(sum_count=Sum('count'))
  261. if g_rows:
  262. arrval_count = g_rows['sum_count'] or 0
  263. row.arrval_count = arrval_count
  264. if row.arrval_count >= row.count:
  265. row.is_arrval = True
  266. else:
  267. row.is_arrval = False
  268. row.save()
  269. sum_arrval_count = 0
  270. d_rows = PurchaseOrderDetail.objects.filter(main=self).aggregate(sum_count=Sum('arrval_count'))
  271. if d_rows:
  272. sum_arrval_count = d_rows['sum_count'] or 0
  273. if sum_arrval_count == 0:
  274. self.arrval = PurchaseOrder.NO_ARRVAL
  275. self.save()
  276. else:
  277. all_arrval = True
  278. for row in rows:
  279. if not row.is_arrval:
  280. all_arrval = False
  281. break
  282. if all_arrval:
  283. self.arrval = PurchaseOrder.ALL_ARRVAL
  284. else:
  285. self.arrval = PurchaseOrder.PART_ARRVAL
  286. self.save()
  287. path_and_rename = PathAndRename("purchase_order/invoice/")
  288. class PurchaseOrderDetail(models.Model):
  289. main = models.ForeignKey(PurchaseOrder, verbose_name=u'采购合同', on_delete=models.PROTECT)
  290. product = models.ForeignKey(ProductBase, verbose_name=u'产品', on_delete=models.PROTECT)
  291. #quality_request = models.ForeignKey(Option, verbose_name=u"质量标准", null=True, on_delete=models.PROTECT)
  292. quality_request_text = models.CharField(max_length=100, verbose_name=u"质量要求", null=True, blank=True)
  293. count = models.BigIntegerField(u'数量', default=0)
  294. price = models.BigIntegerField(u'单价', default=0)
  295. amount = models.BigIntegerField(u'金额', default=0)
  296. arrval_count = models.BigIntegerField(u'到货数量', default=0)
  297. is_arrval = models.BooleanField(verbose_name=u"全部到货", default=0)
  298. invoice_no = models.CharField(max_length=50, verbose_name=u"发票号", null=True)
  299. invoice_amount = models.BigIntegerField(u'发票金额', null=True)
  300. invoice_date = models.DateField(verbose_name=u"开票日期", null=True)
  301. create_time = models.DateTimeField(verbose_name=u"录入时间", null=True)
  302. create_user = models.ForeignKey(User, related_name='purchase_order_detail_ref_create_user', verbose_name=u"录入人",
  303. on_delete=models.PROTECT, null=True)
  304. department = models.ForeignKey(Department, verbose_name=u"录入部门", null=True, on_delete=models.PROTECT)
  305. check_time = models.DateTimeField(verbose_name=u"审核时间", null=True)
  306. check_user = models.ForeignKey(User, related_name='purchase_order_detail_ref_check_user', verbose_name=u"审核人",
  307. on_delete=models.PROTECT, null=True)
  308. check_status = models.PositiveSmallIntegerField(choices=settings.CHECK_STATUS_CHOICES,
  309. verbose_name=u"审核状态", default=settings.DEFAULT)
  310. class Meta:
  311. db_table = "purchase_order_detail"
  312. verbose_name = u"发票管理"
  313. ordering = ('-id',)
  314. default_permissions = ()
  315. permissions = (# 采购合同明细
  316. ("view_purchase_invoice", u"浏览"),
  317. ("add_purchase_invoice", u"录入"),
  318. ("check_purchase_invoice", u"审核"),
  319. ("export_purchase_invoice", u"导出"),
  320. )
  321. @staticmethod
  322. def getById(id):
  323. instances = PurchaseOrderDetail.objects.filter(id=id).first()
  324. if not instances:
  325. raise CustomError(u'未找到相应的合同明细')
  326. return instances
  327. class PurchaseInvoiceImage(models.Model):
  328. order_detail = models.ForeignKey(PurchaseOrderDetail, related_name='invoice_image_ref_purchase_order_detail', verbose_name=u"合同明细",
  329. editable=False)
  330. invoice_image = models.ImageField(verbose_name=u"发票图片", default='', null=True, upload_to=path_and_rename,
  331. blank=True)
  332. class Meta:
  333. db_table = "purchase_invoice_image"
  334. verbose_name = u"采购合同发票图片"
  335. class PurchasePayment(models.Model):
  336. no = models.CharField(max_length=20, verbose_name=u"单号", editable=False)
  337. order = models.ForeignKey(PurchaseOrder, verbose_name=u"合同", on_delete=models.PROTECT)
  338. status = models.PositiveSmallIntegerField(choices=settings.CHECK_STATUS_CHOICES, default=settings.DEFAULT, verbose_name=u"状态")
  339. amount = models.BigIntegerField(verbose_name=u'合同金额', default=0)
  340. actual_amount = models.BigIntegerField(verbose_name=u'实付金额', default=0)
  341. apply_amount = models.BigIntegerField(verbose_name=u'申请金额', default=0)
  342. is_pay = models.BooleanField(verbose_name=u"是否付款", default=0)
  343. notes = models.CharField(max_length=200, verbose_name=u"申请备注", blank=True, null=True)
  344. create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now)
  345. create_user = models.ForeignKey(User, related_name='purchase_payment_ref_create_user', verbose_name=u"创建人", on_delete=models.PROTECT, editable=False)
  346. department = models.ForeignKey(Department, verbose_name=u"创建部门", editable=False, on_delete=models.PROTECT)
  347. check_time = models.DateTimeField(verbose_name=u"审核时间", null=True)
  348. check_user = models.ForeignKey(User, related_name='purchase_payment_ref_check_user', verbose_name=u"审核人", on_delete=models.PROTECT, null=True)
  349. # review_user = models.ForeignKey(User, verbose_name=u"复核人", related_name='purchase_payment_ref_review_user',
  350. # on_delete=models.PROTECT, null=True, blank=True)
  351. # review_time = models.DateTimeField(verbose_name=u"复核时间", null=True)
  352. #
  353. # ratify_user = models.ForeignKey(User, verbose_name=u"批准人", related_name='purchase_payment_ref_ratify_user',
  354. # on_delete=models.PROTECT, null=True, blank=True)
  355. # ratify_time = models.DateTimeField(verbose_name=u"批准时间", null=True)
  356. class Meta:
  357. db_table = "purchase_payment"
  358. verbose_name = u"付款管理"
  359. ordering = ('-id',)
  360. index_together = (
  361. 'create_time', 'check_time', 'status'
  362. )
  363. unique_together = (
  364. 'no',
  365. )
  366. default_permissions = ()
  367. permissions = (
  368. ("view_purchase_payment", u"浏览"),
  369. ("add_purchase_payment", u"添加"),
  370. ("check_purchase_payment", u"审核"),
  371. # ("review_purchase_payment", u"复核"),
  372. # ("ratify_purchase_payment", u"批准"),
  373. ("pay_purchase_payment", u"付款"),
  374. ("delete_purchase_payment", u"删除"),
  375. ("export_purchase_payment", u"导出"),
  376. ("print_purchase_payment", u"打印"),
  377. )
  378. @staticmethod
  379. def getById(id):
  380. instance = PurchasePayment.objects.filter(pk=id).first()
  381. if not instance:
  382. raise CustomError(u'未找到相应的付款单')
  383. return instance
  384. def updateAmount(self):
  385. sum_amount = 0
  386. sum_row = PurchasePaymentDetail.objects.filter(main=self).aggregate(sum_amount=Sum('purchase_detail__amount'))
  387. if sum_row:
  388. sum_amount = sum_row['sum_amount'] or 0
  389. self.amount = sum_amount
  390. self.save()
  391. def updateActualAmount(self):
  392. sum_actual_amount = 0
  393. sum_row = PurchasePay.objects.filter(main=self).aggregate(sum_actual_amount=Sum('actual_amount'))
  394. if sum_row:
  395. sum_actual_amount = sum_row['sum_actual_amount'] or 0
  396. self.actual_amount = sum_actual_amount
  397. self.save()
  398. def save(self, *args, **kwargs):
  399. if self.no == None or self.no == '':
  400. now = timezone.now()
  401. rows = PurchasePayment.objects.filter(create_time__gte=now.strftime('%Y-%m-%d')).order_by('-no')
  402. count = rows.count()
  403. if count == 0:
  404. self.no = 'CY%s%03d' % (now.strftime('%Y%m%d'), count + 1)
  405. else:
  406. self.no = rows[0].no[:2] + str(int(rows[0].no[2:]) + 1)
  407. super(PurchasePayment, self).save(*args, **kwargs)
  408. class PurchasePaymentDetail(models.Model):
  409. main = models.ForeignKey(PurchasePayment, verbose_name=u"付款单", on_delete=models.PROTECT)
  410. purchase_detail = models.ForeignKey(PurchaseOrderDetail, verbose_name=u"合同明细", on_delete=models.PROTECT)
  411. class Meta:
  412. db_table = "purchase_payment_detail"
  413. verbose_name = u"入库查询"
  414. ordering = ('-id',)
  415. default_permissions = ()
  416. permissions = ( # 付款明细
  417. ("view_consumable_godownentry_query", u"浏览"),
  418. ("export_consumable_godownentry_query", u"导出"),
  419. ("print_consumable_godownentry_query", u"打印"),
  420. )
  421. class PurchasePay(models.Model):
  422. main = models.ForeignKey(PurchasePayment, verbose_name=u"付款单", on_delete=models.PROTECT)
  423. payment_type = models.ForeignKey(Option, verbose_name=u"付款方式", on_delete=models.PROTECT)
  424. payment_time = models.DateTimeField(verbose_name=u"付款时间", default=timezone.now)
  425. actual_amount = models.BigIntegerField(verbose_name=u'实付金额', default=0)
  426. payment_user = models.ForeignKey(User, verbose_name=u"付款人", editable=False,on_delete=models.PROTECT)
  427. payment_department = models.ForeignKey(Department, verbose_name=u"付款部门", editable=False, on_delete=models.PROTECT)
  428. notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True)
  429. class Meta:
  430. db_table = "purchase_pay"
  431. verbose_name = u"付款明细"
  432. ordering = ('-id',)
  433. default_permissions = ()
  434. @staticmethod
  435. def getByMainId(id):
  436. instances = PurchasePay.objects.filter(main_id=id)
  437. if not instances:
  438. raise CustomError(u'未找到相应的付款单')
  439. return instances
  440. @staticmethod
  441. def getById(id):
  442. instance = PurchasePay.objects.filter(id=id).first()
  443. if not instance:
  444. raise CustomError(u'未找到相应的付款单')
  445. return instance
  446. class GodownEntry(models.Model):
  447. MATERIAL = 0
  448. CONSUMABLE = 1
  449. PRODUCT_CHOICES = (
  450. (MATERIAL, u'原料'),
  451. (CONSUMABLE, u'耗材'),
  452. )
  453. PREFIX_CHOICES = (
  454. (MATERIAL, 'MR'),
  455. (CONSUMABLE, 'CR'),
  456. )
  457. no = models.CharField(max_length=20, verbose_name=u"入库单号", editable=False)
  458. supplier = models.ForeignKey(Supplier, verbose_name=u'供应商', on_delete=models.PROTECT)
  459. purchase_order = models.ForeignKey(PurchaseOrder, verbose_name=u'采购合同', blank=True, null=True, on_delete=models.PROTECT)
  460. total_count = models.BigIntegerField(verbose_name=u'数量合计', default=0)
  461. total_amount = models.BigIntegerField(verbose_name=u'金额合计', default=0)
  462. total_invoice_amount = models.BigIntegerField(verbose_name=u'发票金额合计', default=0) #等于明细里面的发票金额合计
  463. create_user = models.ForeignKey(User, related_name='godown_entry_ref_create_user', verbose_name=u"创建人", on_delete=models.PROTECT, editable=False)
  464. department = models.ForeignKey(Department, verbose_name=u"创建部门", on_delete=models.PROTECT, editable=False)
  465. create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now)
  466. status = models.PositiveSmallIntegerField(choices=settings.CHECK_STATUS_CHOICES, default=settings.DEFAULT, verbose_name=u"审核状态")
  467. check_user = models.ForeignKey(User, related_name='godown_entry_ref_check_user', verbose_name=u"审核人", on_delete=models.PROTECT, blank=True, null=True)
  468. check_time = models.DateTimeField(verbose_name=u"审核时间", blank=True, null=True)
  469. notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True)
  470. warehouse = models.ForeignKey(Warehouse, verbose_name=u'仓别', on_delete=models.PROTECT)
  471. product_type = models.PositiveSmallIntegerField(choices=PRODUCT_CHOICES, verbose_name=u"产品类型")
  472. total_return_count = models.BigIntegerField(verbose_name=u"退货数量合计", default=0)
  473. total_return_amount = models.BigIntegerField(verbose_name=u"退货金额合计", default=0)
  474. total_deliver_count = models.BigIntegerField(verbose_name=u"出库数量合计", default=0)
  475. total_deliver_amount = models.BigIntegerField(verbose_name=u"出库金额合计", default=0)
  476. class Meta:
  477. db_table = "godown_entry"
  478. verbose_name = u"入库管理"
  479. ordering = ('-id',)
  480. index_together = (
  481. 'create_time', 'check_time', 'status'
  482. )
  483. unique_together = (
  484. 'no',
  485. )
  486. default_permissions = ()
  487. permissions = (
  488. ("view_material_godown_entry", u"浏览"),
  489. ("add_material_godown_entry", u"添加"),
  490. ("check_material_godown_entry", u"审核"),
  491. ("delete_material_godown_entry", u"删除"),
  492. ("export_material_godown_entry", u"导出"),
  493. ("import_material_godown_entry", u"导入"),
  494. ("print_material_godown_entry", u"打印"),
  495. ("edit_material_godown_entry", u"高级修改"),
  496. )
  497. @staticmethod
  498. def getById(id):
  499. instances = GodownEntry.objects.filter(id=id).first()
  500. if not instances:
  501. raise CustomError(u'未找到相应的入库单')
  502. return instances
  503. @staticmethod
  504. def getPermissionByType(type, action):
  505. permissions = GodownEntry.getPermissionMap()
  506. type = GodownEntry.getValidType(type)
  507. return permissions[type][action]
  508. @staticmethod
  509. def getPermissionMap():
  510. permissions = {
  511. GodownEntry.MATERIAL: {'view': 'purchase.view_material_godown_entry',
  512. 'add': 'purchase.add_material_godown_entry',
  513. 'check': 'purchase.check_material_godown_entry',
  514. 'delete': 'purchase.delete_material_godown_entry',
  515. 'export': 'purchase.export_material_godown_entry',
  516. 'import': 'purchase.import_material_godown_entry',
  517. 'print': 'purchase.print_material_godown_entry',
  518. 'edit': "purchase.edit_consumable_godown_entry",
  519. },
  520. GodownEntry.CONSUMABLE: {'view': 'purchase.view_consumable_godown_entry',
  521. 'add': 'purchase.add_consumable_godown_entry',
  522. 'check': 'purchase.check_consumable_godown_entry',
  523. 'delete': 'purchase.delete_consumable_godown_entry',
  524. 'export': 'purchase.export_consumable_godown_entry',
  525. 'import': 'purchase.import_consumable_godown_entry',
  526. 'print': 'purchase.print_consumable_godown_entry',
  527. 'edit': "purchase.edit_consumable_godown_entry",
  528. },
  529. }
  530. return permissions
  531. @staticmethod
  532. def getValidType(type):
  533. try:
  534. type = int(type)
  535. except:
  536. raise CustomError(u'错误的入库类型')
  537. types = (r[0] for r in GodownEntry.PRODUCT_CHOICES)
  538. if type not in types:
  539. raise CustomError(u'无效的入库类型')
  540. return type
  541. def getPermission(self, action):
  542. permissions = GodownEntry.getPermissionMap()
  543. return permissions[self.product_type][action]
  544. def save(self, *args, **kwargs):
  545. if self.no == None or self.no == '':
  546. now = timezone.now()
  547. rows = GodownEntry.objects.filter(create_time__gte=now.strftime('%Y-%m-%d'), product_type=self.product_type).order_by('-no')
  548. count = rows.count()
  549. prefix = GodownEntry.PREFIX_CHOICES[self.product_type][1]
  550. if count == 0:
  551. self.no = '%s%s%03d' % (prefix, now.strftime('%Y%m%d'), count + 1)
  552. else:
  553. self.no = rows[0].no[:2] + str(int(rows[0].no[2:]) + 1)
  554. super(GodownEntry, self).save(*args, **kwargs)
  555. def update_total(self):
  556. total_count = 0
  557. total_amount = 0
  558. total_invoice_amount = 0
  559. sum_row = GodownEntryDetail.objects.filter(main=self).aggregate(total_count=Sum('count'),\
  560. total_amount=Sum('amount'), total_invoice_amount=Sum('invoice_amount'))
  561. if sum_row:
  562. total_count = sum_row['total_count'] or 0
  563. total_amount = sum_row['total_amount'] or 0
  564. total_invoice_amount = sum_row['total_invoice_amount'] or 0
  565. self.total_count = total_count
  566. self.total_amount = total_amount
  567. self.total_invoice_amount = total_invoice_amount
  568. self.save()
  569. def update_redundant(self):
  570. total_return_count = 0
  571. total_return_amount = 0
  572. total_deliver_count = 0
  573. total_deliver_amount = 0
  574. sum_row = GodownEntryDetail.objects.filter(main=self).aggregate(sum_return_count=Sum('return_count'), sum_return_amount=Sum('return_amount'),
  575. sum_deliver_count=Sum('deliver_count'), sum_deliver_amount=Sum('deliver_amount'))
  576. if sum_row:
  577. total_return_count = sum_row['sum_return_count'] or 0
  578. total_return_amount = sum_row['sum_return_amount'] or 0
  579. total_deliver_count = sum_row['sum_deliver_count'] or 0
  580. total_deliver_amount = sum_row['sum_deliver_amount'] or 0
  581. self.total_return_count = total_return_count
  582. self.total_return_amount = total_return_amount
  583. self.total_deliver_count = total_deliver_count
  584. self.total_deliver_amount = total_deliver_amount
  585. self.save()
  586. class GodownEntryDetail(models.Model):
  587. main = models.ForeignKey(GodownEntry, verbose_name=u'入库单',related_name='godown_entry_detail_ref_main', on_delete=models.PROTECT)
  588. product_base = models.ForeignKey(ProductBase, verbose_name=u'产品', on_delete=models.PROTECT)
  589. count = models.BigIntegerField(verbose_name=u'数量', default=0)
  590. price = models.BigIntegerField(verbose_name=u'单价', default=0)
  591. warehouse_stock = models.ForeignKey(WarehouseStock, verbose_name=u'仓别库存', on_delete=models.PROTECT, editable=False)
  592. stock_record = models.ForeignKey(WarehouseStockRecord, verbose_name=u'库存记录', on_delete=models.PROTECT, null=True,blank=True, related_name='godown_entry_detail_ref_stock_record',)
  593. amount = models.BigIntegerField(verbose_name=u'金额', default=0)#数量*单价
  594. invoice_amount = models.BigIntegerField(verbose_name=u'发票金额', default=0) #手工录入
  595. return_count = models.BigIntegerField(verbose_name=u"退货数量", default=0)
  596. return_amount = models.BigIntegerField(verbose_name=u"退货金额", default=0)
  597. deliver_count = models.BigIntegerField(verbose_name=u"出库数量", default=0)
  598. deliver_amount = models.BigIntegerField(verbose_name=u"出库金额", default=0)
  599. notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True)
  600. class Meta:
  601. db_table = "godown_entry_detail"
  602. verbose_name = u"入库管理"
  603. ordering = ('-id',)
  604. default_permissions = ()
  605. permissions = (# 原料/耗材入库明细
  606. ("view_consumable_godown_entry", u"浏览"),
  607. ("add_consumable_godown_entry", u"添加"),
  608. ("check_consumable_godown_entry", u"审核"),
  609. ("delete_consumable_godown_entry", u"删除"),
  610. ("export_consumable_godown_entry", u"导出"),
  611. ("import_consumable_godown_entry", u"导入"),
  612. ("print_consumable_godown_entry", u"打印"),
  613. ("edit_consumable_godown_entry", u"高级修改"),
  614. )
  615. @staticmethod
  616. def getById(id):
  617. instances = GodownEntryDetail.objects.filter(id=id).first()
  618. if not instances:
  619. raise CustomError(u'未找到相应的入库明细')
  620. return instances
  621. class GodownEntryReturn(models.Model):
  622. MATERIAL = 0
  623. CONSUMABLE = 1
  624. PRODUCT_CHOICES = (
  625. (MATERIAL, u'原料'),
  626. (CONSUMABLE, u'耗材'),
  627. )
  628. PREFIX_CHOICES = (
  629. (MATERIAL, 'MT'),
  630. (CONSUMABLE, 'CT'),
  631. )
  632. no = models.CharField(max_length=20, verbose_name=u"单号", editable=False)
  633. type = models.PositiveSmallIntegerField(choices=PRODUCT_CHOICES, verbose_name=u"产品类型")
  634. supplier = models.ForeignKey(Supplier, verbose_name=u"供应商", null=True, blank=True, on_delete=models.PROTECT)
  635. warehouse = models.ForeignKey(Warehouse, verbose_name=u"仓别", on_delete=models.PROTECT)
  636. create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now)
  637. create_user = models.ForeignKey(User, related_name='godown_entry_return_ref_create_user', verbose_name=u"创建人", on_delete=models.PROTECT, editable=False)
  638. department = models.ForeignKey(Department, verbose_name=u"创建部门", editable=False, on_delete=models.PROTECT)
  639. status = models.PositiveSmallIntegerField(choices=settings.CHECK_STATUS_CHOICES, default=settings.DEFAULT, verbose_name=u"审核状态")
  640. check_user = models.ForeignKey(User, related_name='godown_entry_return_ref_check_user', verbose_name=u"审核人", on_delete=models.PROTECT, blank=True, null=True)
  641. check_time = models.DateTimeField(verbose_name=u"审核时间", blank=True, null=True)
  642. notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True)
  643. total_count = models.BigIntegerField(verbose_name=u"合计数量", default=0)
  644. total_amount = models.BigIntegerField(verbose_name=u"合计金额", default=0)
  645. class Meta:
  646. db_table = "godown_entry_return"
  647. verbose_name = u"退货管理"
  648. ordering = ('-id',)
  649. index_together = (
  650. 'create_time', 'check_time', 'status'
  651. )
  652. unique_together = (
  653. 'no',
  654. )
  655. default_permissions = ()
  656. permissions = (
  657. ("view_material_godown_entry_return", u"浏览"),
  658. ("add_material_godown_entry_return", u"添加"),
  659. ("check_material_godown_entry_return", u"审核"),
  660. ("delete_material_godown_entry_return", u"删除"),
  661. ("export_material_godown_entry_return", u"导出"),
  662. ("print_material_godown_entry_return", u"打印"),
  663. )
  664. @staticmethod
  665. def getById(id):
  666. instances = GodownEntryReturn.objects.filter(id=id).first()
  667. if not instances:
  668. raise CustomError(u'未找到相应的退货单')
  669. return instances
  670. @staticmethod
  671. def getPermissionByType(type, action):
  672. permissions = GodownEntryReturn.getPermissionMap()
  673. type = GodownEntryReturn.getValidType(type)
  674. return permissions[type][action]
  675. @staticmethod
  676. def getPermissionMap():
  677. permissions = {
  678. GodownEntryReturn.MATERIAL: {'view': 'purchase.view_material_godown_entry_return',
  679. 'add': 'purchase.add_material_godown_entry_return',
  680. 'check': 'purchase.check_material_godown_entry_return',
  681. 'delete': 'purchase.delete_material_godown_entry_return',
  682. 'export': 'purchase.export_material_godown_entry_return',
  683. 'print': 'purchase.print_material_godown_entry_return'
  684. },
  685. GodownEntryReturn.CONSUMABLE: {'view': 'purchase.view_consumable_godown_entry_return',
  686. 'add': 'purchase.add_consumable_godown_entry_return',
  687. 'check': 'purchase.check_consumable_godown_entry_return',
  688. 'delete': 'purchase.delete_consumable_godown_entry_return',
  689. 'export': 'purchase.export_consumable_godown_entry_return',
  690. 'print': 'purchase.print_consumable_godown_entry_return'
  691. },
  692. }
  693. return permissions
  694. @staticmethod
  695. def getValidType(type):
  696. try:
  697. type = int(type)
  698. except:
  699. raise CustomError(u'错误的退货类型')
  700. types = (r[0] for r in GodownEntryReturn.PRODUCT_CHOICES)
  701. if type not in types:
  702. raise CustomError(u'无效的退货类型')
  703. return type
  704. def getPermission(self, action):
  705. permissions = GodownEntryReturn.getPermissionMap()
  706. return permissions[self.type][action]
  707. def save(self, *args, **kwargs):
  708. if self.no == None or self.no == '':
  709. now = timezone.now()
  710. rows = GodownEntryReturn.objects.filter(create_time__gte=now.strftime('%Y-%m-%d'), type=self.type).order_by('-no')
  711. count = rows.count()
  712. prefix = GodownEntryReturn.PREFIX_CHOICES[self.type][1]
  713. if count == 0:
  714. self.no = '%s%s%03d' % (prefix, now.strftime('%Y%m%d'), count + 1)
  715. else:
  716. self.no = rows[0].no[:2] + str(int(rows[0].no[2:]) + 1)
  717. super(GodownEntryReturn, self).save(*args, **kwargs)
  718. def update_total(self):
  719. total_count = 0
  720. total_amount = 0
  721. sum_row = GodownEntryReturnDetail.objects.filter(main=self).aggregate(total_count=Sum('count'), total_amount=Sum('amount'))
  722. if sum_row:
  723. total_count = sum_row['total_count'] or 0
  724. total_amount = sum_row['total_amount'] or 0
  725. self.total_count = total_count
  726. self.total_amount = total_amount
  727. self.save()
  728. class GodownEntryReturnDetail(models.Model):
  729. main = models.ForeignKey(GodownEntryReturn, verbose_name=u"退货单", related_name='godown_entry_return_detail_ref_main', on_delete=models.PROTECT)
  730. product_base = models.ForeignKey(ProductBase, verbose_name=u'产品')
  731. count = models.BigIntegerField(verbose_name=u"数量", default=0)
  732. price = models.BigIntegerField(verbose_name=u"单价", default=0)
  733. amount = models.BigIntegerField(verbose_name=u"金额", default=0)
  734. warehouse_stock = models.ForeignKey(WarehouseStock, verbose_name=u'仓别库存', on_delete=models.PROTECT, editable=False)
  735. warehouse_record = models.ForeignKey(WarehouseRecord, verbose_name=u'出入库记录', on_delete=models.PROTECT, null=True,
  736. blank=True, related_name='godown_entry_return_detail_ref_warehouse_record', )
  737. godownentry_detail = models.ForeignKey(GodownEntryDetail, verbose_name=u"入库明细", on_delete=models.PROTECT, null=True, blank=True)
  738. notes = models.CharField(max_length=200, verbose_name=u"备注", blank=True, null=True)
  739. class Meta:
  740. db_table = "godown_entry_detail_return"
  741. verbose_name = u"退货管理"
  742. ordering = ('-id',)
  743. default_permissions = ()
  744. permissions = (# 退货明细
  745. ("view_consumable_godown_entry_return", u"浏览"),
  746. ("add_consumable_godown_entry_return", u"添加"),
  747. ("check_consumable_godown_entry_return", u"审核"),
  748. ("delete_consumable_godown_entry_return", u"删除"),
  749. ("export_consumable_godown_entry_return", u"导出"),
  750. ("print_consumable_godown_entry_return", u"打印"),
  751. )
  752. @staticmethod
  753. def getById(id):
  754. instances = GodownEntryReturnDetail.objects.filter(id=id).first()
  755. if not instances:
  756. raise CustomError(u'未找到相应的退货明细')
  757. return instances
  758. @staticmethod
  759. def getById2(id):
  760. instances = GodownEntryReturnDetail.objects.filter(id=id).first()
  761. if not instances:
  762. return None
  763. return instances