mrp_workorder.py 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. # -*- coding: utf-8 -*-
  2. # Part of Odoo. See LICENSE file for full copyright and licensing details.
  3. from odoo import fields, models, _
  4. from odoo.tools import float_is_zero
  5. class MrpWorkorder(models.Model):
  6. _inherit = 'mrp.workorder'
  7. mo_analytic_account_line_id = fields.Many2one('account.analytic.line', copy=False)
  8. wc_analytic_account_line_id = fields.Many2one('account.analytic.line', copy=False)
  9. def _compute_duration(self):
  10. res = super()._compute_duration()
  11. self._create_or_update_analytic_entry()
  12. return res
  13. def _set_duration(self):
  14. res = super()._set_duration()
  15. self._create_or_update_analytic_entry()
  16. return res
  17. def action_cancel(self):
  18. (self.mo_analytic_account_line_id | self.wc_analytic_account_line_id).unlink()
  19. return super().action_cancel()
  20. def _prepare_analytic_line_values(self, account, unit_amount, amount):
  21. self.ensure_one()
  22. return {
  23. 'name': _("[WC] %s", self.display_name),
  24. 'amount': amount,
  25. 'account_id': account.id,
  26. 'unit_amount': unit_amount,
  27. 'product_id': self.product_id.id,
  28. 'product_uom_id': self.env.ref('uom.product_uom_hour').id,
  29. 'company_id': self.company_id.id,
  30. 'ref': self.production_id.name,
  31. 'category': 'manufacturing_order',
  32. }
  33. def _create_or_update_analytic_entry(self):
  34. wo_to_link_mo_analytic_line = self.env['mrp.workorder']
  35. wo_to_link_wc_analytic_line = self.env['mrp.workorder']
  36. mo_analytic_line_vals_list = []
  37. wc_analytic_line_vals_list = []
  38. for wo in self.filtered(lambda wo: wo.production_id.analytic_account_id or wo.workcenter_id.costs_hour_account_id):
  39. hours = wo.duration / 60.0
  40. value = -hours * wo.workcenter_id.costs_hour
  41. mo_account = wo.production_id.analytic_account_id
  42. wc_account = wo.workcenter_id.costs_hour_account_id
  43. if mo_account:
  44. mo_currency = mo_account.currency_id or wo.company_id.currency_id
  45. is_zero = float_is_zero(value, precision_rounding=mo_currency.rounding)
  46. if wo.mo_analytic_account_line_id:
  47. wo.mo_analytic_account_line_id.write({
  48. 'unit_amount': hours,
  49. 'amount': value if not is_zero else 0,
  50. })
  51. elif not is_zero:
  52. wo_to_link_mo_analytic_line += wo
  53. mo_analytic_line_vals_list.append(wo._prepare_analytic_line_values(mo_account, hours, value))
  54. if wc_account and wc_account != mo_account:
  55. is_zero = float_is_zero(value, precision_rounding=wc_account.currency_id.rounding)
  56. if wo.wc_analytic_account_line_id:
  57. wo.wc_analytic_account_line_id.write({
  58. 'unit_amount': hours,
  59. 'amount': value if not is_zero else 0,
  60. })
  61. elif not is_zero:
  62. wo_to_link_wc_analytic_line += wo
  63. wc_analytic_line_vals_list.append(wo._prepare_analytic_line_values(wc_account, hours, value))
  64. analytic_lines = self.env['account.analytic.line'].sudo().create(mo_analytic_line_vals_list + wc_analytic_line_vals_list)
  65. mo_analytic_lines, wc_analytic_lines = analytic_lines[:len(wo_to_link_mo_analytic_line)], analytic_lines[len(wo_to_link_mo_analytic_line):]
  66. for wo, analytic_line in zip(wo_to_link_mo_analytic_line, mo_analytic_lines):
  67. wo.mo_analytic_account_line_id = analytic_line
  68. for wo, analytic_line in zip(wo_to_link_wc_analytic_line, wc_analytic_lines):
  69. wo.wc_analytic_account_line_id = analytic_line
  70. def unlink(self):
  71. (self.mo_analytic_account_line_id | self.wc_analytic_account_line_id).unlink()
  72. return super().unlink()