GoodERP
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

178 lignes
6.2KB

  1. # -*- coding: utf-8 -*-
  2. from odoo import _
  3. from .utils import safe_division
  4. from odoo import models, fields, api
  5. from odoo.exceptions import UserError
  6. class WhMoveMatching(models.Model):
  7. _name = 'wh.move.matching'
  8. _description = '匹配记录'
  9. line_in_id = fields.Many2one(
  10. 'wh.move.line', '入库',
  11. ondelete='set null', index=True,
  12. help='入库单行')
  13. line_out_id = fields.Many2one(
  14. 'wh.move.line', '出库',
  15. ondelete='set null', index=True,
  16. help='出库单行')
  17. goods_id = fields.Many2one('goods',string='商品', related='line_in_id.goods_id', store=True)
  18. attribute_id = fields.Many2one('attribute',string='属性', related='line_in_id.attribute_id', store=True)
  19. lot = fields.Char(string='批号', related='line_in_id.lot', store=True)
  20. qty = fields.Float(
  21. '出库数量',
  22. digits='Quantity', required=True,
  23. help='出库单行商品的数量')
  24. uos_qty = fields.Float(
  25. '辅助数量',
  26. digits='Quantity', required=True,
  27. help='出库单行商品的辅助数量')
  28. cost_unit = fields.Float(
  29. '单位成本',
  30. digits='price',
  31. related='line_in_id.cost_unit',
  32. store=True)
  33. expiration_date = fields.Date(
  34. '过保日',
  35. related='line_in_id.expiration_date',
  36. store=True,
  37. help='商品保质期截止日期')
  38. in_name = fields.Char(
  39. '入库单号',
  40. related='line_in_id.move_id.name',
  41. help='入库单号')
  42. in_date = fields.Date(
  43. '入库日期',
  44. related='line_in_id.date',
  45. help='入库日期')
  46. out_name = fields.Char(
  47. '出库单号',
  48. related='line_out_id.move_id.name',
  49. help='出库单号')
  50. out_date = fields.Date(
  51. '出库日期',
  52. related='line_out_id.date',
  53. help='出库日期')
  54. in_partner_id = fields.Many2one(
  55. 'partner',
  56. string='供应商',
  57. related='line_in_id.move_id.partner_id'
  58. )
  59. out_partner_id = fields.Many2one(
  60. 'partner',
  61. string='客户',
  62. related='line_out_id.move_id.partner_id'
  63. )
  64. warehouse_id = fields.Many2one(
  65. 'warehouse',
  66. string='仓库',
  67. related='line_out_id.warehouse_id'
  68. )
  69. warehouse_id = fields.Many2one(
  70. 'warehouse',
  71. string='仓库',
  72. related='line_out_id.warehouse_id'
  73. )
  74. company_id = fields.Many2one(
  75. 'res.company',
  76. string='公司',
  77. change_default=True,
  78. default=lambda self: self.env.company)
  79. def create_matching(self, line_in_id, line_out_id, qty, uos_qty, expiration_date):
  80. res = {
  81. 'line_out_id': line_out_id,
  82. 'line_in_id': line_in_id,
  83. 'qty': qty,
  84. 'uos_qty': uos_qty,
  85. 'expiration_date': expiration_date,
  86. }
  87. return self.create(res)
  88. class WhMoveLine(models.Model):
  89. _inherit = 'wh.move.line'
  90. qty_remaining = fields.Float(
  91. compute='_get_qty_remaining',
  92. string='剩余数量',
  93. digits='Quantity',
  94. index=True, store=True, readonly=True,
  95. help='商品的剩余数量')
  96. uos_qty_remaining = fields.Float(
  97. compute='_get_qty_remaining', string='剩余辅助数量',
  98. digits='Quantity',
  99. index=True, store=True, readonly=True,
  100. help='商品的剩余辅助数量')
  101. matching_in_ids = fields.One2many(
  102. 'wh.move.matching', 'line_in_id', string='关联的出库',
  103. help='关联的入库单行')
  104. matching_out_ids = fields.One2many(
  105. 'wh.move.matching', 'line_out_id', string='关联的入库',
  106. help='关联的出库单行')
  107. @api.depends('goods_qty', 'matching_in_ids.qty', 'matching_in_ids.uos_qty')
  108. def _get_qty_remaining(self):
  109. for wml in self:
  110. wml.qty_remaining = wml.goods_qty - \
  111. sum(match.qty for match in wml.matching_in_ids)
  112. wml.uos_qty_remaining = wml.goods_uos_qty - \
  113. sum(match.uos_qty for match in wml.matching_in_ids)
  114. def create_matching_obj(self, line, matching):
  115. matching_obj = self.env['wh.move.matching']
  116. matching_obj.create_matching(
  117. matching.get('line_in_id'),
  118. line.id, matching.get('qty'),
  119. matching.get('uos_qty'),
  120. matching.get('expiration_date'),
  121. )
  122. def prev_action_done(self):
  123. """
  124. 发货 matching
  125. """
  126. for line in self:
  127. if line.warehouse_id.type == 'stock' and \
  128. line.goods_id.is_using_matching():
  129. if line.goods_id.is_using_batch() and line.lot_id:
  130. matching_records, cost = \
  131. line.goods_id.get_matching_records_by_lot(
  132. line.lot_id, line.goods_qty, line.goods_uos_qty)
  133. for matching in matching_records:
  134. self.create_matching_obj(line, matching)
  135. else:
  136. matching_records, cost = line.goods_id \
  137. .get_matching_records(
  138. line.warehouse_id, line.goods_qty,
  139. uos_qty = line.goods_uos_qty,
  140. attribute = line.attribute_id,
  141. move_line = line)
  142. for matching in matching_records:
  143. self.create_matching_obj(line, matching)
  144. line.cost_unit = safe_division(cost, line.goods_qty)
  145. line.cost = cost
  146. # 将过保日填充到出库明细行
  147. line.expiration_date = matching_records and matching_records[0].get(
  148. 'expiration_date')
  149. return super(WhMoveLine, self).prev_action_done()
  150. def prev_action_draft(self):
  151. for line in self:
  152. if line.qty_remaining != line.goods_qty:
  153. raise UserError(
  154. _('当前的入库已经被其他出库匹配,请先取消相关的出库\n %s') %
  155. '\n'.join([m.out_name for m in line.matching_in_ids])
  156. )
  157. line.matching_in_ids.unlink()
  158. line.matching_out_ids.unlink()
  159. line.expiration_date = False
  160. return super(WhMoveLine, self).prev_action_draft()
上海开阖软件有限公司 沪ICP备12045867号-1