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.

151 lines
5.8 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.amount_currency, 0.0))
  34. ELSE l.amount_currency + sum(coalesce(pc.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_move m ON (l.move_id = m.id)
  42. LEFT JOIN (SELECT pr.*
  43. FROM account_partial_reconcile pr
  44. INNER JOIN account_move_line l2
  45. ON pr.credit_move_id = l2.id
  46. WHERE l2.date <= %(date_end)s
  47. ) as pd ON pd.debit_move_id = l.id
  48. LEFT JOIN (SELECT pr.*
  49. FROM account_partial_reconcile pr
  50. INNER JOIN account_move_line l2
  51. ON pr.debit_move_id = l2.id
  52. WHERE l2.date <= %(date_end)s
  53. ) as pc ON pc.credit_move_id = l.id
  54. WHERE l.partner_id IN %(partners)s
  55. AND l.account_internal_type = %(account_type)s
  56. AND (
  57. (pd.id IS NOT NULL AND
  58. pd.max_date <= %(date_end)s) OR
  59. (pc.id IS NOT NULL AND
  60. pc.max_date <= %(date_end)s) OR
  61. (pd.id IS NULL AND pc.id IS NULL)
  62. ) AND l.date <= %(date_end)s AND m.state IN ('posted')
  63. GROUP BY l.partner_id, m.name, l.date, l.date_maturity, l.name,
  64. CASE WHEN l.ref IS NOT NULL
  65. THEN l.ref
  66. ELSE m.ref
  67. END,
  68. l.blocked, l.currency_id, l.balance, l.amount_currency, l.company_id
  69. """,
  70. locals(),
  71. ),
  72. "utf-8",
  73. )
  74. def _display_lines_sql_q2(self):
  75. return str(
  76. self._cr.mogrify(
  77. """
  78. SELECT Q1.partner_id, Q1.currency_id, Q1.move_id,
  79. Q1.date, Q1.date_maturity, Q1.debit, Q1.credit,
  80. Q1.name, Q1.ref, Q1.blocked, Q1.company_id,
  81. CASE WHEN Q1.currency_id is not null
  82. THEN Q1.open_amount_currency
  83. ELSE Q1.open_amount
  84. END as open_amount
  85. FROM Q1
  86. """,
  87. locals(),
  88. ),
  89. "utf-8",
  90. )
  91. def _display_lines_sql_q3(self, company_id):
  92. return str(
  93. self._cr.mogrify(
  94. """
  95. SELECT Q2.partner_id, Q2.move_id, Q2.date, Q2.date_maturity,
  96. Q2.name, Q2.ref, Q2.debit, Q2.credit,
  97. Q2.debit-Q2.credit AS amount, blocked,
  98. COALESCE(Q2.currency_id, c.currency_id) AS currency_id,
  99. Q2.open_amount
  100. FROM Q2
  101. JOIN res_company c ON (c.id = Q2.company_id)
  102. WHERE c.id = %(company_id)s AND Q2.open_amount != 0.0
  103. """,
  104. locals(),
  105. ),
  106. "utf-8",
  107. )
  108. def _get_account_display_lines(
  109. self, company_id, partner_ids, date_start, date_end, account_type
  110. ):
  111. res = dict(map(lambda x: (x, []), partner_ids))
  112. partners = tuple(partner_ids)
  113. # pylint: disable=E8103
  114. self.env.cr.execute(
  115. """
  116. WITH Q1 as (%s),
  117. Q2 AS (%s),
  118. Q3 AS (%s)
  119. SELECT partner_id, currency_id, move_id, date, date_maturity, debit,
  120. credit, amount, open_amount, name, ref, blocked
  121. FROM Q3
  122. ORDER BY date, date_maturity, move_id"""
  123. % (
  124. self._display_lines_sql_q1(partners, date_end, account_type),
  125. self._display_lines_sql_q2(),
  126. self._display_lines_sql_q3(company_id),
  127. )
  128. )
  129. for row in self.env.cr.dictfetchall():
  130. res[row.pop("partner_id")].append(row)
  131. return res
  132. @api.model
  133. def _get_report_values(self, docids, data=None):
  134. if not data:
  135. data = {}
  136. if "company_id" not in data:
  137. wiz = self.env["outstanding.statement.wizard"].with_context(
  138. active_ids=docids, model="res.partner"
  139. )
  140. data.update(wiz.create({})._prepare_statement())
  141. data["amount_field"] = "open_amount"
  142. return super()._get_report_values(docids, data)