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.

193 lines
7.2 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 collections import defaultdict
  4. from odoo import api, models
  5. class ActivityStatement(models.AbstractModel):
  6. """Model of Activity Statement"""
  7. _inherit = "statement.common"
  8. _name = "report.partner_statement.activity_statement"
  9. _description = "Partner Activity Statement"
  10. def _initial_balance_sql_q1(self, partners, date_start, account_type):
  11. return str(
  12. self._cr.mogrify(
  13. """
  14. SELECT l.partner_id, l.currency_id, l.company_id,
  15. CASE WHEN l.currency_id is not null AND l.amount_currency > 0.0
  16. THEN sum(l.amount_currency)
  17. ELSE sum(l.debit)
  18. END as debit,
  19. CASE WHEN l.currency_id is not null AND l.amount_currency < 0.0
  20. THEN sum(l.amount_currency * (-1))
  21. ELSE sum(l.credit)
  22. END as credit
  23. FROM account_move_line l
  24. JOIN account_account aa ON (aa.id = l.account_id)
  25. JOIN account_account_type at ON (at.id = aa.user_type_id)
  26. JOIN account_move m ON (l.move_id = m.id)
  27. WHERE l.partner_id IN %(partners)s AND at.type = %(account_type)s
  28. AND l.date < %(date_start)s AND not l.blocked
  29. AND m.state IN ('posted')
  30. GROUP BY l.partner_id, l.currency_id, l.amount_currency,
  31. l.company_id
  32. """,
  33. locals(),
  34. ),
  35. "utf-8",
  36. )
  37. def _initial_balance_sql_q2(self, company_id):
  38. return str(
  39. self._cr.mogrify(
  40. """
  41. SELECT Q1.partner_id, debit-credit AS balance,
  42. COALESCE(Q1.currency_id, c.currency_id) AS currency_id
  43. FROM Q1
  44. JOIN res_company c ON (c.id = Q1.company_id)
  45. WHERE c.id = %(company_id)s
  46. """,
  47. locals(),
  48. ),
  49. "utf-8",
  50. )
  51. def _get_account_initial_balance(
  52. self, company_id, partner_ids, date_start, account_type
  53. ):
  54. balance_start = defaultdict(list)
  55. partners = tuple(partner_ids)
  56. # pylint: disable=E8103
  57. self.env.cr.execute(
  58. """WITH Q1 AS (%s), Q2 AS (%s)
  59. SELECT partner_id, currency_id, balance
  60. FROM Q2"""
  61. % (
  62. self._initial_balance_sql_q1(partners, date_start, account_type),
  63. self._initial_balance_sql_q2(company_id),
  64. )
  65. )
  66. for row in self.env.cr.dictfetchall():
  67. balance_start[row.pop("partner_id")].append(row)
  68. return balance_start
  69. def _display_lines_sql_q1(self, partners, date_start, date_end, account_type):
  70. return str(
  71. self._cr.mogrify(
  72. """
  73. SELECT m.name AS move_id, l.partner_id, l.date,
  74. CASE WHEN (aj.type IN ('sale', 'purchase'))
  75. THEN l.name
  76. ELSE '/'
  77. END as name,
  78. CASE
  79. WHEN (aj.type IN ('sale', 'purchase')) AND l.name IS NOT NULL
  80. THEN l.ref
  81. WHEN aj.type IN ('sale', 'purchase') AND l.name IS NULL
  82. THEN m.ref
  83. WHEN (aj.type in ('bank', 'cash'))
  84. THEN 'Payment'
  85. ELSE ''
  86. END as ref,
  87. l.blocked, l.currency_id, l.company_id,
  88. CASE WHEN (l.currency_id is not null AND l.amount_currency > 0.0)
  89. THEN sum(l.amount_currency)
  90. ELSE sum(l.debit)
  91. END as debit,
  92. CASE WHEN (l.currency_id is not null AND l.amount_currency < 0.0)
  93. THEN sum(l.amount_currency * (-1))
  94. ELSE sum(l.credit)
  95. END as credit,
  96. CASE WHEN l.date_maturity is null
  97. THEN l.date
  98. ELSE l.date_maturity
  99. END as date_maturity
  100. FROM account_move_line l
  101. JOIN account_account aa ON (aa.id = l.account_id)
  102. JOIN account_account_type at ON (at.id = aa.user_type_id)
  103. JOIN account_move m ON (l.move_id = m.id)
  104. JOIN account_journal aj ON (l.journal_id = aj.id)
  105. WHERE l.partner_id IN %(partners)s
  106. AND at.type = %(account_type)s
  107. AND %(date_start)s <= l.date
  108. AND l.date <= %(date_end)s
  109. AND m.state IN ('posted')
  110. GROUP BY l.partner_id, m.name, l.date, l.date_maturity,
  111. CASE WHEN (aj.type IN ('sale', 'purchase'))
  112. THEN l.name
  113. ELSE '/'
  114. END,
  115. CASE
  116. WHEN (aj.type IN ('sale', 'purchase')) AND l.name IS NOT NULL
  117. THEN l.ref
  118. WHEN aj.type IN ('sale', 'purchase') AND l.name IS NULL
  119. THEN m.ref
  120. WHEN (aj.type in ('bank', 'cash'))
  121. THEN 'Payment'
  122. ELSE ''
  123. END,
  124. l.blocked, l.currency_id, l.amount_currency, l.company_id
  125. """,
  126. locals(),
  127. ),
  128. "utf-8",
  129. )
  130. def _display_lines_sql_q2(self, company_id):
  131. return str(
  132. self._cr.mogrify(
  133. """
  134. SELECT Q1.partner_id, Q1.move_id, Q1.date, Q1.date_maturity,
  135. Q1.name, Q1.ref, Q1.debit, Q1.credit,
  136. Q1.debit-Q1.credit as amount, Q1.blocked,
  137. COALESCE(Q1.currency_id, c.currency_id) AS currency_id
  138. FROM Q1
  139. JOIN res_company c ON (c.id = Q1.company_id)
  140. WHERE c.id = %(company_id)s
  141. """,
  142. locals(),
  143. ),
  144. "utf-8",
  145. )
  146. def _get_account_display_lines(
  147. self, company_id, partner_ids, date_start, date_end, account_type
  148. ):
  149. res = dict(map(lambda x: (x, []), partner_ids))
  150. partners = tuple(partner_ids)
  151. # pylint: disable=E8103
  152. self.env.cr.execute(
  153. """
  154. WITH Q1 AS (%s),
  155. Q2 AS (%s)
  156. SELECT partner_id, move_id, date, date_maturity, name, ref, debit,
  157. credit, amount, blocked, currency_id
  158. FROM Q2
  159. ORDER BY date, date_maturity, move_id"""
  160. % (
  161. self._display_lines_sql_q1(
  162. partners, date_start, date_end, account_type
  163. ),
  164. self._display_lines_sql_q2(company_id),
  165. )
  166. )
  167. for row in self.env.cr.dictfetchall():
  168. res[row.pop("partner_id")].append(row)
  169. return res
  170. @api.model
  171. def _get_report_values(self, docids, data=None):
  172. if not data:
  173. data = {}
  174. if "company_id" not in data:
  175. wiz = self.env["activity.statement.wizard"].with_context(
  176. active_ids=docids, model="res.partner"
  177. )
  178. data.update(wiz.create({})._prepare_statement())
  179. data["amount_field"] = "amount"
  180. return super()._get_report_values(docids, data)