You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
7.0 KiB

  1. # -*- coding: utf-8 -*-
  2. # © 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  4. from datetime import datetime
  5. from dateutil.relativedelta import relativedelta
  6. from openerp import api, fields, models
  7. class ResPartner(models.Model):
  8. _inherit = 'res.partner'
  9. risk_sale_order_include = fields.Boolean(
  10. string='Include Sales Orders', help='Full risk computation')
  11. risk_sale_order_limit = fields.Monetary(
  12. string='Limit Sales Orders', help='Set 0 if it is not locked')
  13. risk_sale_order = fields.Monetary(
  14. compute='_compute_risk_sale_order', store=True,
  15. string='Total Sales Orders Not Invoiced',
  16. help='Total not invoiced of sales orders in Sale Order state')
  17. risk_invoice_draft_include = fields.Boolean(
  18. string='Include Draft Invoices', help='Full risk computation')
  19. risk_invoice_draft_limit = fields.Monetary(
  20. string='Limit In Draft Invoices', help='Set 0 if it is not locked')
  21. risk_invoice_draft = fields.Monetary(
  22. compute='_compute_risk_invoice', store=True,
  23. string='Total Draft Invoices',
  24. help='Total amount of invoices in Draft or Pro-forma state')
  25. risk_invoice_open_include = fields.Boolean(
  26. string='Include Open Invoices', help='Full risk computation')
  27. risk_invoice_open_limit = fields.Monetary(
  28. string='Limit In Open Invoices', help='Set 0 if it is not locked')
  29. risk_invoice_open = fields.Monetary(
  30. compute='_compute_risk_invoice', store=True,
  31. string='Total Open Invoices',
  32. help='Residual amount of invoices in Open state and the date due is '
  33. 'not exceeded, considering Due Margin set in account '
  34. 'settings')
  35. risk_invoice_unpaid_include = fields.Boolean(
  36. string='Include Due Invoices', help='Full risk computation')
  37. risk_invoice_unpaid_limit = fields.Monetary(
  38. string='Limit In Due Invoices', help='Set 0 if it is not locked')
  39. risk_invoice_unpaid = fields.Monetary(
  40. compute='_compute_risk_invoice', store=True,
  41. string='Total Due Invoices',
  42. help='Residual amount of invoices in Open state and the date due is '
  43. 'exceeded, considering Due Margin set in account settings')
  44. risk_account_amount_include = fields.Boolean(
  45. string='Include Other Account Amount', help='Full risk computation')
  46. risk_account_amount_limit = fields.Monetary(
  47. string='Limit Other Account Amount', help='Set 0 if it is not locked')
  48. risk_account_amount = fields.Monetary(
  49. compute='_compute_risk_account_amount',
  50. string='Other Account Amount',
  51. help='Difference between accounting credit and rest of totals')
  52. risk_total = fields.Monetary(
  53. compute='_compute_risk_exception',
  54. string='Total Risk', help='Sum of total risk included')
  55. risk_exception = fields.Boolean(
  56. compute='_compute_risk_exception',
  57. string='Risk Exception',
  58. help='It Indicate if partner risk exceeded')
  59. @api.multi
  60. @api.depends('sale_order_ids', 'sale_order_ids.invoice_pending_amount')
  61. def _compute_risk_sale_order(self):
  62. for partner in self:
  63. partner.risk_sale_order = sum(
  64. partner.sale_order_ids.mapped('invoice_pending_amount'))
  65. @api.multi
  66. @api.depends('invoice_ids', 'invoice_ids.state',
  67. 'invoice_ids.amount_total', 'invoice_ids.residual',
  68. 'invoice_ids.company_id.invoice_due_margin')
  69. def _compute_risk_invoice(self):
  70. max_date = self._max_risk_date_due()
  71. for partner in self:
  72. invoices = partner.invoice_ids.filtered(
  73. lambda x: x.state in ['draft', 'proforma', 'proforma2'])
  74. partner.risk_invoice_draft = sum(invoices.mapped('amount_total'))
  75. invoices = partner.invoice_ids.filtered(
  76. lambda x: x.state == 'open' and x.date_due >= max_date)
  77. partner.risk_invoice_open = sum(invoices.mapped('residual'))
  78. invoices = partner.invoice_ids.filtered(
  79. lambda x: x.state == 'open' and x.date_due < max_date)
  80. partner.risk_invoice_unpaid = sum(invoices.mapped('residual'))
  81. @api.multi
  82. @api.depends('credit', 'risk_invoice_open', 'risk_invoice_unpaid')
  83. def _compute_risk_account_amount(self):
  84. for partner in self:
  85. partner.risk_account_amount = (
  86. partner.credit - partner.risk_invoice_open -
  87. partner.risk_invoice_unpaid)
  88. @api.multi
  89. @api.depends('risk_sale_order', 'risk_sale_order_include',
  90. 'risk_sale_order_limit',
  91. 'risk_invoice_draft', 'risk_invoice_draft_include',
  92. 'risk_invoice_draft_limit', 'risk_invoice_open',
  93. 'risk_invoice_open_include', 'risk_invoice_open_limit',
  94. 'risk_invoice_unpaid', 'risk_invoice_unpaid_include',
  95. 'risk_invoice_unpaid_limit', 'risk_account_amount',
  96. 'risk_account_amount_include', 'risk_account_amount_limit',
  97. 'credit_limit')
  98. # @api.depends(lambda x: x._depends_list)
  99. def _compute_risk_exception(self):
  100. risk_field_list = self._risk_field_list()
  101. for partner in self:
  102. amount = 0.0
  103. for risk_field in risk_field_list:
  104. field_value = getattr(partner, risk_field[0], 0.0)
  105. max_value = getattr(partner, risk_field[1], 0.0)
  106. if max_value and field_value > max_value:
  107. partner.risk_exception = True
  108. if getattr(partner, risk_field[2], False):
  109. amount += field_value
  110. partner.risk_total = amount
  111. if amount > partner.credit_limit:
  112. partner.risk_exception = True
  113. @api.model
  114. def _max_risk_date_due(self):
  115. return fields.Date.to_string(datetime.today().date() - relativedelta(
  116. days=self.env.user.company_id.invoice_due_margin))
  117. @api.model
  118. def _risk_field_list(self):
  119. return [
  120. ('risk_sale_order', 'risk_sale_order_limit',
  121. 'risk_sale_order_include'),
  122. ('risk_invoice_draft', 'risk_invoice_draft_limit',
  123. 'risk_invoice_draft_include'),
  124. ('risk_invoice_open', 'risk_invoice_open_limit',
  125. 'risk_invoice_open_include'),
  126. ('risk_invoice_unpaid', 'risk_invoice_unpaid_limit',
  127. 'risk_invoice_unpaid_include'),
  128. ('risk_account_amount', 'risk_account_amount_limit',
  129. 'risk_account_amount_include'),
  130. ]
  131. @api.model
  132. def _depends_list(self):
  133. ss = (
  134. 'risk_sale_order', 'risk_sale_order_include', 'risk_sale_order_limit',
  135. 'risk_invoice_draft', 'risk_invoice_draft_include',
  136. 'risk_invoice_draft_limit', 'risk_invoice_open',
  137. 'risk_invoice_open_include', 'risk_invoice_open_limit',
  138. 'risk_invoice_unpaid', 'risk_invoice_unpaid_include',
  139. 'risk_invoice_unpaid_limit', 'risk_account_amount',
  140. 'risk_account_amount_include', 'risk_account_amount_limit',
  141. 'credit_limit')
  142. return ss