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.

152 lines
5.9 KiB

  1. # Copyright 2018 ForgeFlow, S.L. (https://www.forgeflow.com)
  2. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
  3. from odoo import api, models
  4. class OutstandingStatement(models.AbstractModel):
  5. """Model of Outstanding Statement"""
  6. _inherit = "statement.common"
  7. _name = "report.partner_statement.outstanding_statement"
  8. _description = "Partner Outstanding Statement"
  9. def _display_lines_sql_q1(self, partners, date_end, account_type):
  10. partners = tuple(partners)
  11. return str(
  12. self._cr.mogrify(
  13. """
  14. SELECT m.name AS move_id, l.partner_id, l.date, l.name,
  15. l.blocked, l.currency_id, l.company_id,
  16. CASE WHEN l.ref IS NOT NULL
  17. THEN l.ref
  18. ELSE m.ref
  19. END as ref,
  20. CASE WHEN (l.currency_id is not null AND l.amount_currency > 0.0)
  21. THEN avg(l.amount_currency)
  22. ELSE avg(l.debit)
  23. END as debit,
  24. CASE WHEN (l.currency_id is not null AND l.amount_currency < 0.0)
  25. THEN avg(l.amount_currency * (-1))
  26. ELSE avg(l.credit)
  27. END as credit,
  28. CASE WHEN l.balance > 0.0
  29. THEN l.balance - sum(coalesce(pd.amount, 0.0))
  30. ELSE l.balance + sum(coalesce(pc.amount, 0.0))
  31. END AS open_amount,
  32. CASE WHEN l.balance > 0.0
  33. THEN l.amount_currency - sum(coalesce(pd.debit_amount_currency, 0.0))
  34. ELSE l.amount_currency + sum(coalesce(pc.credit_amount_currency, 0.0))
  35. END AS open_amount_currency,
  36. CASE WHEN l.date_maturity is null
  37. THEN l.date
  38. ELSE l.date_maturity
  39. END as date_maturity
  40. FROM account_move_line l
  41. JOIN account_account aa ON (aa.id = l.account_id)
  42. JOIN account_account_type at ON (at.id = aa.user_type_id)
  43. JOIN account_move m ON (l.move_id = m.id)
  44. LEFT JOIN (SELECT pr.*
  45. FROM account_partial_reconcile pr
  46. INNER JOIN account_move_line l2
  47. ON pr.credit_move_id = l2.id
  48. WHERE l2.date <= %(date_end)s
  49. ) as pd ON pd.debit_move_id = l.id
  50. LEFT JOIN (SELECT pr.*
  51. FROM account_partial_reconcile pr
  52. INNER JOIN account_move_line l2
  53. ON pr.debit_move_id = l2.id
  54. WHERE l2.date <= %(date_end)s
  55. ) as pc ON pc.credit_move_id = l.id
  56. WHERE l.partner_id IN %(partners)s AND at.type = %(account_type)s
  57. AND (
  58. (pd.id IS NOT NULL AND
  59. pd.max_date <= %(date_end)s) OR
  60. (pc.id IS NOT NULL AND
  61. pc.max_date <= %(date_end)s) OR
  62. (pd.id IS NULL AND pc.id IS NULL)
  63. ) AND l.date <= %(date_end)s AND m.state IN ('posted')
  64. GROUP BY l.partner_id, m.name, l.date, l.date_maturity, l.name,
  65. CASE WHEN l.ref IS NOT NULL
  66. THEN l.ref
  67. ELSE m.ref
  68. END,
  69. l.blocked, l.currency_id, l.balance, l.amount_currency, l.company_id
  70. """,
  71. locals(),
  72. ),
  73. "utf-8",
  74. )
  75. def _display_lines_sql_q2(self):
  76. return str(
  77. self._cr.mogrify(
  78. """
  79. SELECT Q1.partner_id, Q1.currency_id, Q1.move_id,
  80. Q1.date, Q1.date_maturity, Q1.debit, Q1.credit,
  81. Q1.name, Q1.ref, Q1.blocked, Q1.company_id,
  82. CASE WHEN Q1.currency_id is not null
  83. THEN Q1.open_amount_currency
  84. ELSE Q1.open_amount
  85. END as open_amount
  86. FROM Q1
  87. """,
  88. locals(),
  89. ),
  90. "utf-8",
  91. )
  92. def _display_lines_sql_q3(self, company_id):
  93. return str(
  94. self._cr.mogrify(
  95. """
  96. SELECT Q2.partner_id, Q2.move_id, Q2.date, Q2.date_maturity,
  97. Q2.name, Q2.ref, Q2.debit, Q2.credit,
  98. Q2.debit-Q2.credit AS amount, blocked,
  99. COALESCE(Q2.currency_id, c.currency_id) AS currency_id,
  100. Q2.open_amount
  101. FROM Q2
  102. JOIN res_company c ON (c.id = Q2.company_id)
  103. WHERE c.id = %(company_id)s AND Q2.open_amount != 0.0
  104. """,
  105. locals(),
  106. ),
  107. "utf-8",
  108. )
  109. def _get_account_display_lines(
  110. self, company_id, partner_ids, date_start, date_end, account_type
  111. ):
  112. res = dict(map(lambda x: (x, []), partner_ids))
  113. partners = tuple(partner_ids)
  114. # pylint: disable=E8103
  115. self.env.cr.execute(
  116. """
  117. WITH Q1 as (%s),
  118. Q2 AS (%s),
  119. Q3 AS (%s)
  120. SELECT partner_id, currency_id, move_id, date, date_maturity, debit,
  121. credit, amount, open_amount, name, ref, blocked
  122. FROM Q3
  123. ORDER BY date, date_maturity, move_id"""
  124. % (
  125. self._display_lines_sql_q1(partners, date_end, account_type),
  126. self._display_lines_sql_q2(),
  127. self._display_lines_sql_q3(company_id),
  128. )
  129. )
  130. for row in self.env.cr.dictfetchall():
  131. res[row.pop("partner_id")].append(row)
  132. return res
  133. @api.model
  134. def _get_report_values(self, docids, data=None):
  135. if not data:
  136. data = {}
  137. if "company_id" not in data:
  138. wiz = self.env["outstanding.statement.wizard"].with_context(
  139. active_ids=docids, model="res.partner"
  140. )
  141. data.update(wiz.create({})._prepare_statement())
  142. data["amount_field"] = "open_amount"
  143. return super()._get_report_values(docids, data)