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.

1743 lines
57 KiB

  1. # © 2016 Julien Coux (Camptocamp)
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  3. from odoo import _, api, fields, models
  4. class GeneralLedgerReport(models.TransientModel):
  5. """ Here, we just define class fields.
  6. For methods, go more bottom at this file.
  7. The class hierarchy is :
  8. * GeneralLedgerReport
  9. ** GeneralLedgerReportAccount
  10. *** GeneralLedgerReportMoveLine
  11. For non receivable/payable accounts
  12. For receivable/payable centralized accounts
  13. *** GeneralLedgerReportPartner
  14. For receivable/payable and not centralized accounts
  15. **** GeneralLedgerReportMoveLine
  16. For receivable/payable and not centralized accounts
  17. """
  18. _name = "report_general_ledger"
  19. _description = "General Ledger Report"
  20. _inherit = "account_financial_report_abstract"
  21. # Filters fields, used for data computation
  22. date_from = fields.Date()
  23. date_to = fields.Date()
  24. fy_start_date = fields.Date()
  25. only_posted_moves = fields.Boolean()
  26. hide_account_at_0 = fields.Boolean()
  27. foreign_currency = fields.Boolean()
  28. show_analytic_tags = fields.Boolean()
  29. company_id = fields.Many2one(comodel_name="res.company")
  30. filter_account_ids = fields.Many2many(comodel_name="account.account")
  31. filter_partner_ids = fields.Many2many(comodel_name="res.partner")
  32. filter_cost_center_ids = fields.Many2many(comodel_name="account.analytic.account")
  33. filter_analytic_tag_ids = fields.Many2many(comodel_name="account.analytic.tag",)
  34. filter_journal_ids = fields.Many2many(comodel_name="account.journal",)
  35. centralize = fields.Boolean()
  36. # Flag fields, used for report display
  37. show_cost_center = fields.Boolean(
  38. default=lambda self: self.env.user.has_group(
  39. "analytic.group_analytic_accounting"
  40. )
  41. )
  42. partner_ungrouped = fields.Boolean(
  43. string="Partner ungrouped",
  44. help="If set moves are not grouped by partner in any case",
  45. )
  46. # Data fields, used to browse report data
  47. account_ids = fields.One2many(
  48. comodel_name="report_general_ledger_account", inverse_name="report_id"
  49. )
  50. # Compute of unaffected earnings account
  51. @api.depends("company_id")
  52. def _compute_unaffected_earnings_account(self):
  53. account_type = self.env.ref("account.data_unaffected_earnings")
  54. self.unaffected_earnings_account = self.env["account.account"].search(
  55. [
  56. ("user_type_id", "=", account_type.id),
  57. ("company_id", "=", self.company_id.id),
  58. ]
  59. )
  60. unaffected_earnings_account = fields.Many2one(
  61. comodel_name="account.account",
  62. compute="_compute_unaffected_earnings_account",
  63. store=True,
  64. )
  65. class GeneralLedgerReportAccount(models.TransientModel):
  66. _name = "report_general_ledger_account"
  67. _inherit = "account_financial_report_abstract"
  68. _order = "code ASC"
  69. report_id = fields.Many2one(
  70. comodel_name="report_general_ledger", ondelete="cascade", index=True
  71. )
  72. # Data fields, used to keep link with real object
  73. account_id = fields.Many2one("account.account", index=True)
  74. # Data fields, used for report display
  75. code = fields.Char()
  76. name = fields.Char()
  77. initial_debit = fields.Float(digits=(16, 2))
  78. initial_credit = fields.Float(digits=(16, 2))
  79. initial_balance = fields.Float(digits=(16, 2))
  80. currency_id = fields.Many2one("res.currency")
  81. initial_balance_foreign_currency = fields.Float(digits=(16, 2))
  82. final_debit = fields.Float(digits=(16, 2))
  83. final_credit = fields.Float(digits=(16, 2))
  84. final_balance = fields.Float(digits=(16, 2))
  85. final_balance_foreign_currency = fields.Float(digits=(16, 2))
  86. # Flag fields, used for report display and for data computation
  87. is_partner_account = fields.Boolean()
  88. # Data fields, used to browse report data
  89. move_line_ids = fields.One2many(
  90. comodel_name="report_general_ledger_move_line", inverse_name="report_account_id"
  91. )
  92. partner_ids = fields.One2many(
  93. comodel_name="report_general_ledger_partner", inverse_name="report_account_id"
  94. )
  95. class GeneralLedgerReportPartner(models.TransientModel):
  96. _name = "report_general_ledger_partner"
  97. _inherit = "account_financial_report_abstract"
  98. report_account_id = fields.Many2one(
  99. comodel_name="report_general_ledger_account", ondelete="cascade", index=True
  100. )
  101. # Data fields, used to keep link with real object
  102. partner_id = fields.Many2one("res.partner", index=True)
  103. # Data fields, used for report display
  104. name = fields.Char()
  105. initial_debit = fields.Float(digits=(16, 2))
  106. initial_credit = fields.Float(digits=(16, 2))
  107. initial_balance = fields.Float(digits=(16, 2))
  108. currency_id = fields.Many2one("res.currency")
  109. initial_balance_foreign_currency = fields.Float(digits=(16, 2))
  110. final_debit = fields.Float(digits=(16, 2))
  111. final_credit = fields.Float(digits=(16, 2))
  112. final_balance = fields.Float(digits=(16, 2))
  113. final_balance_foreign_currency = fields.Float(digits=(16, 2))
  114. # Data fields, used to browse report data
  115. move_line_ids = fields.One2many(
  116. comodel_name="report_general_ledger_move_line", inverse_name="report_partner_id"
  117. )
  118. @api.model
  119. def _generate_order_by(self, order_spec, query):
  120. """Custom order to display "No partner allocated" at last position."""
  121. return """
  122. ORDER BY
  123. CASE
  124. WHEN "report_general_ledger_partner"."partner_id" IS NOT NULL
  125. THEN 0
  126. ELSE 1
  127. END,
  128. "report_general_ledger_partner"."name"
  129. """
  130. class GeneralLedgerReportMoveLine(models.TransientModel):
  131. _name = "report_general_ledger_move_line"
  132. _inherit = "account_financial_report_abstract"
  133. report_account_id = fields.Many2one(
  134. comodel_name="report_general_ledger_account", ondelete="cascade", index=True
  135. )
  136. report_partner_id = fields.Many2one(
  137. comodel_name="report_general_ledger_partner", ondelete="cascade", index=True
  138. )
  139. # Data fields, used to keep link with real object
  140. move_line_id = fields.Many2one("account.move.line")
  141. # Data fields, used for report display
  142. date = fields.Date()
  143. entry = fields.Char()
  144. journal = fields.Char()
  145. account = fields.Char()
  146. taxes_description = fields.Char()
  147. partner = fields.Char()
  148. label = fields.Char()
  149. cost_center = fields.Char()
  150. tags = fields.Char()
  151. matching_number = fields.Char()
  152. debit = fields.Float(digits=(16, 2))
  153. credit = fields.Float(digits=(16, 2))
  154. cumul_balance = fields.Float(digits=(16, 2))
  155. currency_id = fields.Many2one("res.currency")
  156. amount_currency = fields.Float(digits=(16, 2))
  157. class GeneralLedgerReportCompute(models.TransientModel):
  158. """ Here, we just define methods.
  159. For class fields, go more top at this file.
  160. """
  161. _inherit = "report_general_ledger"
  162. def print_report(self, report_type):
  163. self.ensure_one()
  164. if report_type == "xlsx":
  165. report_name = "a_f_r.report_general_ledger_xlsx"
  166. else:
  167. report_name = "account_financial_report." "report_general_ledger_qweb"
  168. return (
  169. self.env["ir.actions.report"]
  170. .search(
  171. [("report_name", "=", report_name), ("report_type", "=", report_type)],
  172. limit=1,
  173. )
  174. .report_action(self, config=False)
  175. )
  176. def _get_html(self):
  177. result = {}
  178. rcontext = {}
  179. context = dict(self.env.context)
  180. report = self.browse(context.get("active_id"))
  181. if report:
  182. rcontext["o"] = report
  183. result["html"] = self.env.ref(
  184. "account_financial_report.report_general_ledger"
  185. ).render(rcontext)
  186. return result
  187. @api.model
  188. def get_html(self, given_context=None):
  189. return self._get_html()
  190. def compute_data_for_report(self, with_line_details=True, with_partners=True):
  191. self.ensure_one()
  192. # Compute report data
  193. self._inject_account_values()
  194. if with_partners:
  195. self._inject_partner_values()
  196. if not self.filter_partner_ids:
  197. self._inject_partner_values(only_empty_partner=True)
  198. # Add unaffected earnings account
  199. if (
  200. not self.filter_account_ids
  201. or self.unaffected_earnings_account.id in self.filter_account_ids.ids
  202. ):
  203. self._inject_unaffected_earnings_account_values()
  204. # Call this function even if we don't want line details because,
  205. # we need to compute
  206. # at least the values for unaffected earnings account
  207. # In this case, only unaffected earnings account values are computed
  208. only_unaffected_earnings_account = not with_line_details
  209. self._inject_line_not_centralized_values(
  210. only_unaffected_earnings_account=only_unaffected_earnings_account
  211. )
  212. if with_line_details:
  213. self._inject_line_not_centralized_values(
  214. is_account_line=False, is_partner_line=True
  215. )
  216. self._inject_line_not_centralized_values(
  217. is_account_line=False,
  218. is_partner_line=True,
  219. only_empty_partner_line=True,
  220. )
  221. if self.centralize:
  222. self._inject_line_centralized_values()
  223. if self.show_analytic_tags:
  224. # Compute analytic tags
  225. self._compute_analytic_tags()
  226. # Refresh cache because all data are computed with SQL requests
  227. self.invalidate_cache()
  228. def _get_account_sub_subquery_sum_amounts(
  229. self, include_initial_balance, date_included
  230. ):
  231. """ Return subquery used to compute sum amounts on accounts """
  232. sub_subquery_sum_amounts = """
  233. SELECT
  234. a.id AS account_id,
  235. SUM(ml.debit) AS debit,
  236. SUM(ml.credit) AS credit,
  237. SUM(ml.balance) AS balance,
  238. c.id AS currency_id,
  239. CASE
  240. WHEN c.id IS NOT NULL
  241. THEN SUM(ml.amount_currency)
  242. ELSE NULL
  243. END AS balance_currency
  244. FROM
  245. accounts a
  246. INNER JOIN
  247. account_account_type at ON a.user_type_id = at.id
  248. INNER JOIN
  249. account_move_line ml
  250. ON a.id = ml.account_id
  251. """
  252. if date_included:
  253. sub_subquery_sum_amounts += """
  254. AND ml.date <= %s
  255. """
  256. else:
  257. sub_subquery_sum_amounts += """
  258. AND ml.date < %s
  259. """
  260. if not include_initial_balance:
  261. sub_subquery_sum_amounts += """
  262. AND at.include_initial_balance != TRUE AND ml.date >= %s
  263. """
  264. else:
  265. sub_subquery_sum_amounts += """
  266. AND at.include_initial_balance = TRUE
  267. """
  268. if self.filter_journal_ids:
  269. sub_subquery_sum_amounts += """
  270. AND
  271. ml.journal_id IN %s
  272. """ % (
  273. tuple(self.filter_journal_ids.ids,),
  274. )
  275. if self.only_posted_moves:
  276. sub_subquery_sum_amounts += """
  277. INNER JOIN
  278. account_move m ON ml.move_id = m.id AND m.state = 'posted'
  279. """
  280. if self.filter_cost_center_ids:
  281. sub_subquery_sum_amounts += """
  282. INNER JOIN
  283. account_analytic_account aa
  284. ON
  285. ml.analytic_account_id = aa.id
  286. AND aa.id IN %s
  287. """
  288. if self.filter_analytic_tag_ids:
  289. sub_subquery_sum_amounts += """
  290. INNER JOIN
  291. move_lines_on_tags ON ml.id = move_lines_on_tags.ml_id
  292. """
  293. sub_subquery_sum_amounts += """
  294. LEFT JOIN
  295. res_currency c ON a.currency_id = c.id
  296. """
  297. sub_subquery_sum_amounts += """
  298. GROUP BY
  299. a.id, c.id
  300. """
  301. return sub_subquery_sum_amounts
  302. def _get_final_account_sub_subquery_sum_amounts(self, date_included):
  303. """ Return final subquery used to compute sum amounts on accounts """
  304. subquery_sum_amounts = """
  305. SELECT
  306. sub.account_id AS account_id,
  307. SUM(COALESCE(sub.debit, 0.0)) AS debit,
  308. SUM(COALESCE(sub.credit, 0.0)) AS credit,
  309. SUM(COALESCE(sub.balance, 0.0)) AS balance,
  310. MAX(sub.currency_id) AS currency_id,
  311. SUM(COALESCE(sub.balance_currency, 0.0)) AS balance_currency
  312. FROM
  313. (
  314. """
  315. subquery_sum_amounts += self._get_account_sub_subquery_sum_amounts(
  316. include_initial_balance=False, date_included=date_included
  317. )
  318. subquery_sum_amounts += """
  319. UNION
  320. """
  321. subquery_sum_amounts += self._get_account_sub_subquery_sum_amounts(
  322. include_initial_balance=True, date_included=date_included
  323. )
  324. subquery_sum_amounts += """
  325. ) sub
  326. GROUP BY
  327. sub.account_id
  328. """
  329. return subquery_sum_amounts
  330. def _inject_account_values(self):
  331. """Inject report values for report_general_ledger_account."""
  332. query_inject_account = """
  333. WITH
  334. accounts AS
  335. (
  336. SELECT
  337. a.id,
  338. a.code,
  339. a.name,
  340. """
  341. if self.partner_ungrouped:
  342. query_inject_account += """
  343. FALSE AS is_partner_account,
  344. """
  345. else:
  346. query_inject_account += """
  347. a.internal_type IN ('payable', 'receivable')
  348. AS is_partner_account,
  349. """
  350. query_inject_account += """
  351. a.user_type_id,
  352. a.currency_id
  353. FROM
  354. account_account a
  355. """
  356. if (
  357. self.filter_partner_ids
  358. or self.filter_cost_center_ids
  359. or self.filter_analytic_tag_ids
  360. ):
  361. query_inject_account += """
  362. INNER JOIN
  363. account_move_line ml ON a.id = ml.account_id
  364. """
  365. if self.filter_partner_ids:
  366. query_inject_account += """
  367. INNER JOIN
  368. res_partner p ON ml.partner_id = p.id
  369. """
  370. if self.filter_cost_center_ids:
  371. query_inject_account += """
  372. INNER JOIN
  373. account_analytic_account aa
  374. ON
  375. ml.analytic_account_id = aa.id
  376. AND aa.id IN %s
  377. """
  378. if self.filter_analytic_tag_ids:
  379. query_inject_account += """
  380. INNER JOIN
  381. account_analytic_tag_account_move_line_rel atml
  382. ON atml.account_move_line_id = ml.id
  383. INNER JOIN
  384. account_analytic_tag aat
  385. ON
  386. atml.account_analytic_tag_id = aat.id
  387. AND aat.id IN %s
  388. """
  389. query_inject_account += """
  390. WHERE
  391. a.company_id = %s
  392. AND a.id != %s
  393. """
  394. if self.filter_account_ids:
  395. query_inject_account += """
  396. AND
  397. a.id IN %s
  398. """
  399. if self.filter_partner_ids:
  400. query_inject_account += """
  401. AND
  402. p.id IN %s
  403. """
  404. if (
  405. self.filter_partner_ids
  406. or self.filter_cost_center_ids
  407. or self.filter_analytic_tag_ids
  408. ):
  409. query_inject_account += """
  410. GROUP BY
  411. a.id
  412. """
  413. query_inject_account += """
  414. ),
  415. """
  416. if self.filter_analytic_tag_ids:
  417. query_inject_account += """
  418. move_lines_on_tags AS
  419. (
  420. SELECT
  421. DISTINCT ml.id AS ml_id
  422. FROM
  423. accounts a
  424. INNER JOIN
  425. account_move_line ml
  426. ON a.id = ml.account_id
  427. INNER JOIN
  428. account_analytic_tag_account_move_line_rel atml
  429. ON atml.account_move_line_id = ml.id
  430. INNER JOIN
  431. account_analytic_tag aat
  432. ON
  433. atml.account_analytic_tag_id = aat.id
  434. WHERE
  435. aat.id IN %s
  436. ),
  437. """
  438. init_subquery = self._get_final_account_sub_subquery_sum_amounts(
  439. date_included=False
  440. )
  441. final_subquery = self._get_final_account_sub_subquery_sum_amounts(
  442. date_included=True
  443. )
  444. query_inject_account += (
  445. """
  446. initial_sum_amounts AS ( """
  447. + init_subquery
  448. + """ ),
  449. final_sum_amounts AS ( """
  450. + final_subquery
  451. + """ )
  452. INSERT INTO
  453. report_general_ledger_account
  454. (
  455. report_id,
  456. create_uid,
  457. create_date,
  458. account_id,
  459. code,
  460. name,
  461. initial_debit,
  462. initial_credit,
  463. initial_balance,
  464. currency_id,
  465. initial_balance_foreign_currency,
  466. final_debit,
  467. final_credit,
  468. final_balance,
  469. final_balance_foreign_currency,
  470. is_partner_account
  471. )
  472. SELECT
  473. %s AS report_id,
  474. %s AS create_uid,
  475. NOW() AS create_date,
  476. a.id AS account_id,
  477. a.code,
  478. a.name,
  479. COALESCE(i.debit, 0.0) AS initial_debit,
  480. COALESCE(i.credit, 0.0) AS initial_credit,
  481. COALESCE(i.balance, 0.0) AS initial_balance,
  482. c.id AS currency_id,
  483. COALESCE(i.balance_currency, 0.0) AS initial_balance_foreign_currency,
  484. COALESCE(f.debit, 0.0) AS final_debit,
  485. COALESCE(f.credit, 0.0) AS final_credit,
  486. COALESCE(f.balance, 0.0) AS final_balance,
  487. COALESCE(f.balance_currency, 0.0) AS final_balance_foreign_currency,
  488. a.is_partner_account
  489. FROM
  490. accounts a
  491. LEFT JOIN
  492. initial_sum_amounts i ON a.id = i.account_id
  493. LEFT JOIN
  494. final_sum_amounts f ON a.id = f.account_id
  495. LEFT JOIN
  496. res_currency c ON c.id = a.currency_id
  497. WHERE
  498. (
  499. i.debit IS NOT NULL AND i.debit != 0
  500. OR i.credit IS NOT NULL AND i.credit != 0
  501. OR i.balance IS NOT NULL AND i.balance != 0
  502. OR f.debit IS NOT NULL AND f.debit != 0
  503. OR f.credit IS NOT NULL AND f.credit != 0
  504. OR f.balance IS NOT NULL AND f.balance != 0
  505. )
  506. """
  507. )
  508. if self.hide_account_at_0:
  509. query_inject_account += """
  510. AND
  511. f.balance IS NOT NULL AND f.balance != 0
  512. """
  513. query_inject_account_params = ()
  514. if self.filter_cost_center_ids:
  515. query_inject_account_params += (tuple(self.filter_cost_center_ids.ids),)
  516. if self.filter_analytic_tag_ids:
  517. query_inject_account_params += (tuple(self.filter_analytic_tag_ids.ids),)
  518. query_inject_account_params += (
  519. self.company_id.id,
  520. self.unaffected_earnings_account.id,
  521. )
  522. if self.filter_account_ids:
  523. query_inject_account_params += (tuple(self.filter_account_ids.ids),)
  524. if self.filter_partner_ids:
  525. query_inject_account_params += (tuple(self.filter_partner_ids.ids),)
  526. if self.filter_analytic_tag_ids:
  527. query_inject_account_params += (tuple(self.filter_analytic_tag_ids.ids),)
  528. query_inject_account_params += (
  529. self.date_from,
  530. self.fy_start_date,
  531. )
  532. if self.filter_cost_center_ids:
  533. query_inject_account_params += (tuple(self.filter_cost_center_ids.ids),)
  534. query_inject_account_params += (self.date_from,)
  535. if self.filter_cost_center_ids:
  536. query_inject_account_params += (tuple(self.filter_cost_center_ids.ids),)
  537. query_inject_account_params += (
  538. self.date_to,
  539. self.fy_start_date,
  540. )
  541. if self.filter_cost_center_ids:
  542. query_inject_account_params += (tuple(self.filter_cost_center_ids.ids),)
  543. query_inject_account_params += (self.date_to,)
  544. if self.filter_cost_center_ids:
  545. query_inject_account_params += (tuple(self.filter_cost_center_ids.ids),)
  546. query_inject_account_params += (
  547. self.id,
  548. self.env.uid,
  549. )
  550. self.env.cr.execute(query_inject_account, query_inject_account_params)
  551. def _get_partner_sub_subquery_sum_amounts(
  552. self, only_empty_partner, include_initial_balance, date_included
  553. ):
  554. """ Return subquery used to compute sum amounts on partners """
  555. sub_subquery_sum_amounts = """
  556. SELECT
  557. ap.account_id AS account_id,
  558. ap.partner_id AS partner_id,
  559. SUM(ml.debit) AS debit,
  560. SUM(ml.credit) AS credit,
  561. SUM(ml.balance) AS balance,
  562. c.id as currency_id,
  563. CASE
  564. WHEN c.id IS NOT NULL
  565. THEN SUM(ml.amount_currency)
  566. ELSE NULL
  567. END AS balance_currency
  568. FROM
  569. accounts_partners ap
  570. INNER JOIN account_account ac
  571. ON ac.id = ap.account_id
  572. LEFT JOIN
  573. res_currency c ON ac.currency_id = c.id
  574. INNER JOIN
  575. account_move_line ml
  576. ON ap.account_id = ml.account_id
  577. """
  578. if date_included:
  579. sub_subquery_sum_amounts += """
  580. AND ml.date <= %s
  581. """
  582. else:
  583. sub_subquery_sum_amounts += """
  584. AND ml.date < %s
  585. """
  586. if not only_empty_partner:
  587. sub_subquery_sum_amounts += """
  588. AND ap.partner_id = ml.partner_id
  589. """
  590. else:
  591. sub_subquery_sum_amounts += """
  592. AND ap.partner_id IS NULL AND ml.partner_id IS NULL
  593. """
  594. if not include_initial_balance:
  595. sub_subquery_sum_amounts += """
  596. AND ap.include_initial_balance != TRUE AND ml.date >= %s
  597. """
  598. else:
  599. sub_subquery_sum_amounts += """
  600. AND ap.include_initial_balance = TRUE
  601. """
  602. if self.only_posted_moves:
  603. sub_subquery_sum_amounts += """
  604. INNER JOIN
  605. account_move m ON ml.move_id = m.id AND m.state = 'posted'
  606. """
  607. if self.filter_cost_center_ids:
  608. sub_subquery_sum_amounts += """
  609. INNER JOIN
  610. account_analytic_account aa
  611. ON
  612. ml.analytic_account_id = aa.id
  613. AND aa.id IN %s
  614. """
  615. if self.filter_analytic_tag_ids:
  616. sub_subquery_sum_amounts += """
  617. INNER JOIN
  618. move_lines_on_tags ON ml.id = move_lines_on_tags.ml_id
  619. """
  620. sub_subquery_sum_amounts += """
  621. GROUP BY
  622. ap.account_id, ap.partner_id, c.id
  623. """
  624. return sub_subquery_sum_amounts
  625. def _get_final_partner_sub_subquery_sum_amounts(
  626. self, only_empty_partner, date_included
  627. ):
  628. """Return final subquery used to compute sum amounts on partners"""
  629. subquery_sum_amounts = """
  630. SELECT
  631. sub.account_id AS account_id,
  632. sub.partner_id AS partner_id,
  633. SUM(COALESCE(sub.debit, 0.0)) AS debit,
  634. SUM(COALESCE(sub.credit, 0.0)) AS credit,
  635. SUM(COALESCE(sub.balance, 0.0)) AS balance,
  636. MAX(sub.currency_id) AS currency_id,
  637. SUM(COALESCE(sub.balance_currency, 0.0)) AS balance_currency
  638. FROM
  639. (
  640. """
  641. subquery_sum_amounts += self._get_partner_sub_subquery_sum_amounts(
  642. only_empty_partner,
  643. include_initial_balance=False,
  644. date_included=date_included,
  645. )
  646. subquery_sum_amounts += """
  647. UNION
  648. """
  649. subquery_sum_amounts += self._get_partner_sub_subquery_sum_amounts(
  650. only_empty_partner,
  651. include_initial_balance=True,
  652. date_included=date_included,
  653. )
  654. subquery_sum_amounts += """
  655. ) sub
  656. GROUP BY
  657. sub.account_id, sub.partner_id
  658. """
  659. return subquery_sum_amounts
  660. def _inject_partner_values(self, only_empty_partner=False):
  661. """ Inject report values for report_general_ledger_partner.
  662. Only for "partner" accounts (payable and receivable).
  663. """
  664. # pylint: disable=sql-injection
  665. query_inject_partner = (
  666. """
  667. WITH
  668. accounts_partners AS
  669. (
  670. SELECT
  671. ra.id AS report_account_id,
  672. a.id AS account_id,
  673. at.include_initial_balance AS include_initial_balance,
  674. p.id AS partner_id,
  675. COALESCE(
  676. CASE
  677. WHEN
  678. NULLIF(p.name, '') IS NOT NULL
  679. AND NULLIF(p.ref, '') IS NOT NULL
  680. THEN p.name || ' (' || p.ref || ')'
  681. ELSE p.name
  682. END,
  683. '"""
  684. + _("No partner allocated")
  685. + """'
  686. ) AS partner_name
  687. FROM
  688. report_general_ledger_account ra
  689. INNER JOIN
  690. account_account a ON ra.account_id = a.id
  691. INNER JOIN
  692. account_account_type at ON a.user_type_id = at.id
  693. INNER JOIN
  694. account_move_line ml ON a.id = ml.account_id
  695. LEFT JOIN
  696. res_partner p ON ml.partner_id = p.id
  697. """
  698. )
  699. if self.filter_cost_center_ids:
  700. query_inject_partner += """
  701. INNER JOIN
  702. account_analytic_account aa
  703. ON
  704. ml.analytic_account_id = aa.id
  705. AND aa.id IN %s
  706. """
  707. if self.filter_analytic_tag_ids:
  708. query_inject_partner += """
  709. INNER JOIN
  710. account_analytic_tag_account_move_line_rel atml
  711. ON atml.account_move_line_id = ml.id
  712. INNER JOIN
  713. account_analytic_tag aat
  714. ON
  715. atml.account_analytic_tag_id = aat.id
  716. AND aat.id IN %s
  717. """
  718. query_inject_partner += """
  719. WHERE
  720. ra.report_id = %s
  721. AND
  722. ra.is_partner_account = TRUE
  723. """
  724. if not only_empty_partner:
  725. query_inject_partner += """
  726. AND
  727. p.id IS NOT NULL
  728. """
  729. else:
  730. query_inject_partner += """
  731. AND
  732. p.id IS NULL
  733. """
  734. query_inject_partner += """
  735. """
  736. if self.centralize:
  737. query_inject_partner += """
  738. AND (a.centralized IS NULL OR a.centralized != TRUE)
  739. """
  740. if self.filter_partner_ids:
  741. query_inject_partner += """
  742. AND
  743. p.id IN %s
  744. """
  745. init_subquery = self._get_final_partner_sub_subquery_sum_amounts(
  746. only_empty_partner, date_included=False
  747. )
  748. final_subquery = self._get_final_partner_sub_subquery_sum_amounts(
  749. only_empty_partner, date_included=True
  750. )
  751. query_inject_partner += """
  752. GROUP BY
  753. ra.id,
  754. a.id,
  755. p.id,
  756. at.include_initial_balance
  757. ),
  758. """
  759. if self.filter_analytic_tag_ids:
  760. query_inject_partner += """
  761. move_lines_on_tags AS
  762. (
  763. SELECT
  764. DISTINCT ml.id AS ml_id
  765. FROM
  766. accounts_partners ap
  767. INNER JOIN
  768. account_move_line ml
  769. ON ap.account_id = ml.account_id
  770. INNER JOIN
  771. account_analytic_tag_account_move_line_rel atml
  772. ON atml.account_move_line_id = ml.id
  773. INNER JOIN
  774. account_analytic_tag aat
  775. ON
  776. atml.account_analytic_tag_id = aat.id
  777. WHERE
  778. aat.id IN %s
  779. ),
  780. """
  781. query_inject_partner += (
  782. """
  783. initial_sum_amounts AS ( """
  784. + init_subquery
  785. + """ ),
  786. final_sum_amounts AS ( """
  787. + final_subquery
  788. + """ )
  789. INSERT INTO
  790. report_general_ledger_partner
  791. (
  792. report_account_id,
  793. create_uid,
  794. create_date,
  795. partner_id,
  796. name,
  797. initial_debit,
  798. initial_credit,
  799. initial_balance,
  800. currency_id,
  801. initial_balance_foreign_currency,
  802. final_debit,
  803. final_credit,
  804. final_balance,
  805. final_balance_foreign_currency
  806. )
  807. SELECT
  808. ap.report_account_id,
  809. %s AS create_uid,
  810. NOW() AS create_date,
  811. ap.partner_id,
  812. ap.partner_name,
  813. COALESCE(i.debit, 0.0) AS initial_debit,
  814. COALESCE(i.credit, 0.0) AS initial_credit,
  815. COALESCE(i.balance, 0.0) AS initial_balance,
  816. i.currency_id AS currency_id,
  817. COALESCE(i.balance_currency, 0.0) AS initial_balance_foreign_currency,
  818. COALESCE(f.debit, 0.0) AS final_debit,
  819. COALESCE(f.credit, 0.0) AS final_credit,
  820. COALESCE(f.balance, 0.0) AS final_balance,
  821. COALESCE(f.balance_currency, 0.0) AS final_balance_foreign_currency
  822. FROM
  823. accounts_partners ap
  824. LEFT JOIN
  825. initial_sum_amounts i
  826. ON
  827. (
  828. """
  829. )
  830. if not only_empty_partner:
  831. query_inject_partner += """
  832. ap.partner_id = i.partner_id
  833. """
  834. else:
  835. query_inject_partner += """
  836. ap.partner_id IS NULL AND i.partner_id IS NULL
  837. """
  838. query_inject_partner += """
  839. )
  840. AND ap.account_id = i.account_id
  841. LEFT JOIN
  842. final_sum_amounts f
  843. ON
  844. (
  845. """
  846. if not only_empty_partner:
  847. query_inject_partner += """
  848. ap.partner_id = f.partner_id
  849. """
  850. else:
  851. query_inject_partner += """
  852. ap.partner_id IS NULL AND f.partner_id IS NULL
  853. """
  854. query_inject_partner += """
  855. )
  856. AND ap.account_id = f.account_id
  857. WHERE
  858. (
  859. i.debit IS NOT NULL AND i.debit != 0
  860. OR i.credit IS NOT NULL AND i.credit != 0
  861. OR i.balance IS NOT NULL AND i.balance != 0
  862. OR f.debit IS NOT NULL AND f.debit != 0
  863. OR f.credit IS NOT NULL AND f.credit != 0
  864. OR f.balance IS NOT NULL AND f.balance != 0
  865. )
  866. """
  867. if self.hide_account_at_0:
  868. query_inject_partner += """
  869. AND
  870. f.balance IS NOT NULL AND f.balance != 0
  871. """
  872. query_inject_partner_params = ()
  873. if self.filter_cost_center_ids:
  874. query_inject_partner_params += (tuple(self.filter_cost_center_ids.ids),)
  875. if self.filter_analytic_tag_ids:
  876. query_inject_partner_params += (tuple(self.filter_analytic_tag_ids.ids),)
  877. query_inject_partner_params += (self.id,)
  878. if self.filter_partner_ids:
  879. query_inject_partner_params += (tuple(self.filter_partner_ids.ids),)
  880. if self.filter_analytic_tag_ids:
  881. query_inject_partner_params += (tuple(self.filter_analytic_tag_ids.ids),)
  882. query_inject_partner_params += (
  883. self.date_from,
  884. self.fy_start_date,
  885. )
  886. if self.filter_cost_center_ids:
  887. query_inject_partner_params += (tuple(self.filter_cost_center_ids.ids),)
  888. query_inject_partner_params += (self.date_from,)
  889. if self.filter_cost_center_ids:
  890. query_inject_partner_params += (tuple(self.filter_cost_center_ids.ids),)
  891. query_inject_partner_params += (
  892. self.date_to,
  893. self.fy_start_date,
  894. )
  895. if self.filter_cost_center_ids:
  896. query_inject_partner_params += (tuple(self.filter_cost_center_ids.ids),)
  897. query_inject_partner_params += (self.date_to,)
  898. if self.filter_cost_center_ids:
  899. query_inject_partner_params += (tuple(self.filter_cost_center_ids.ids),)
  900. query_inject_partner_params += (self.env.uid,)
  901. self.env.cr.execute(query_inject_partner, query_inject_partner_params)
  902. def _inject_line_not_centralized_values(
  903. self,
  904. is_account_line=True,
  905. is_partner_line=False,
  906. only_empty_partner_line=False,
  907. only_unaffected_earnings_account=False,
  908. ):
  909. """ Inject report values for report_general_ledger_move_line.
  910. If centralized option have been chosen,
  911. only non centralized accounts are computed.
  912. In function of `is_account_line` and `is_partner_line` values,
  913. the move_line link is made either with account or either with partner.
  914. The "only_empty_partner_line" value is used
  915. to compute data without partner.
  916. """
  917. query_inject_move_line = ""
  918. if self.filter_analytic_tag_ids:
  919. query_inject_move_line += """
  920. WITH
  921. move_lines_on_tags AS
  922. (
  923. SELECT
  924. DISTINCT ml.id AS ml_id
  925. FROM
  926. """
  927. if is_account_line:
  928. query_inject_move_line += """
  929. report_general_ledger_account ra
  930. """
  931. elif is_partner_line:
  932. query_inject_move_line += """
  933. report_general_ledger_partner rp
  934. INNER JOIN
  935. report_general_ledger_account ra
  936. ON rp.report_account_id = ra.id
  937. """
  938. query_inject_move_line += """
  939. INNER JOIN
  940. account_move_line ml
  941. ON ra.account_id = ml.account_id
  942. INNER JOIN
  943. account_analytic_tag_account_move_line_rel atml
  944. ON atml.account_move_line_id = ml.id
  945. INNER JOIN
  946. account_analytic_tag aat
  947. ON
  948. atml.account_analytic_tag_id = aat.id
  949. WHERE
  950. ra.report_id = %s
  951. AND
  952. aat.id IN %s
  953. )
  954. """
  955. query_inject_move_line += """
  956. INSERT INTO
  957. report_general_ledger_move_line
  958. (
  959. """
  960. if is_account_line:
  961. query_inject_move_line += """
  962. report_account_id,
  963. """
  964. elif is_partner_line:
  965. query_inject_move_line += """
  966. report_partner_id,
  967. """
  968. query_inject_move_line += """
  969. create_uid,
  970. create_date,
  971. move_line_id,
  972. date,
  973. entry,
  974. journal,
  975. account,
  976. taxes_description,
  977. partner,
  978. label,
  979. cost_center,
  980. matching_number,
  981. debit,
  982. credit,
  983. cumul_balance,
  984. currency_id,
  985. amount_currency
  986. )
  987. SELECT
  988. """
  989. if is_account_line:
  990. query_inject_move_line += """
  991. ra.id AS report_account_id,
  992. """
  993. elif is_partner_line:
  994. query_inject_move_line += """
  995. rp.id AS report_partner_id,
  996. """
  997. query_inject_move_line += """
  998. %s AS create_uid,
  999. NOW() AS create_date,
  1000. ml.id AS move_line_id,
  1001. ml.date,
  1002. m.name AS entry,
  1003. j.code AS journal,
  1004. a.code AS account,
  1005. CASE
  1006. WHEN
  1007. ml.tax_line_id is not null
  1008. THEN
  1009. COALESCE(at.description, at.name)
  1010. WHEN
  1011. ml.tax_line_id is null
  1012. THEN
  1013. (SELECT
  1014. array_to_string(
  1015. array_agg(COALESCE(at.description, at.name)
  1016. ), ', ')
  1017. FROM
  1018. account_move_line_account_tax_rel aml_at_rel
  1019. LEFT JOIN
  1020. account_tax at on (at.id = aml_at_rel.account_tax_id)
  1021. WHERE
  1022. aml_at_rel.account_move_line_id = ml.id)
  1023. ELSE
  1024. ''
  1025. END as taxes_description,
  1026. """
  1027. if not only_empty_partner_line:
  1028. query_inject_move_line += """
  1029. CASE
  1030. WHEN
  1031. NULLIF(p.name, '') IS NOT NULL
  1032. AND NULLIF(p.ref, '') IS NOT NULL
  1033. THEN p.name || ' (' || p.ref || ')'
  1034. ELSE p.name
  1035. END AS partner,
  1036. """
  1037. elif only_empty_partner_line:
  1038. query_inject_move_line += (
  1039. """
  1040. '"""
  1041. + _("No partner allocated")
  1042. + """' AS partner,
  1043. """
  1044. )
  1045. query_inject_move_line += """
  1046. CONCAT_WS(' - ', NULLIF(ml.ref, ''), NULLIF(ml.name, '')) AS label,
  1047. aa.name AS cost_center,
  1048. fr.name AS matching_number,
  1049. ml.debit,
  1050. ml.credit,
  1051. """
  1052. if is_account_line:
  1053. query_inject_move_line += """
  1054. ra.initial_balance + (
  1055. SUM(ml.balance)
  1056. OVER (PARTITION BY a.code
  1057. ORDER BY a.code, ml.date, ml.id)
  1058. ) AS cumul_balance,
  1059. """
  1060. elif is_partner_line and not only_empty_partner_line:
  1061. query_inject_move_line += """
  1062. rp.initial_balance + (
  1063. SUM(ml.balance)
  1064. OVER (PARTITION BY a.code, p.name
  1065. ORDER BY a.code, p.name, ml.date, ml.id)
  1066. ) AS cumul_balance,
  1067. """
  1068. elif is_partner_line and only_empty_partner_line:
  1069. query_inject_move_line += """
  1070. rp.initial_balance + (
  1071. SUM(ml.balance)
  1072. OVER (PARTITION BY a.code
  1073. ORDER BY a.code, ml.date, ml.id)
  1074. ) AS cumul_balance,
  1075. """
  1076. query_inject_move_line += """
  1077. c.id AS currency_id,
  1078. ml.amount_currency
  1079. FROM
  1080. """
  1081. if is_account_line:
  1082. query_inject_move_line += """
  1083. report_general_ledger_account ra
  1084. """
  1085. elif is_partner_line:
  1086. query_inject_move_line += """
  1087. report_general_ledger_partner rp
  1088. INNER JOIN
  1089. report_general_ledger_account ra ON rp.report_account_id = ra.id
  1090. """
  1091. query_inject_move_line += """
  1092. INNER JOIN
  1093. account_move_line ml ON ra.account_id = ml.account_id
  1094. INNER JOIN
  1095. account_move m ON ml.move_id = m.id
  1096. INNER JOIN
  1097. account_journal j ON ml.journal_id = j.id
  1098. INNER JOIN
  1099. account_account a ON ml.account_id = a.id
  1100. LEFT JOIN
  1101. account_tax at ON ml.tax_line_id = at.id
  1102. """
  1103. if is_account_line:
  1104. query_inject_move_line += """
  1105. LEFT JOIN
  1106. res_partner p ON ml.partner_id = p.id
  1107. """
  1108. elif is_partner_line and not only_empty_partner_line:
  1109. query_inject_move_line += """
  1110. INNER JOIN
  1111. res_partner p
  1112. ON ml.partner_id = p.id AND rp.partner_id = p.id
  1113. """
  1114. query_inject_move_line += """
  1115. LEFT JOIN
  1116. account_full_reconcile fr ON ml.full_reconcile_id = fr.id
  1117. LEFT JOIN
  1118. res_currency c ON ml.currency_id = c.id
  1119. """
  1120. if self.filter_cost_center_ids:
  1121. query_inject_move_line += """
  1122. INNER JOIN
  1123. account_analytic_account aa
  1124. ON
  1125. ml.analytic_account_id = aa.id
  1126. AND aa.id IN %s
  1127. """
  1128. else:
  1129. query_inject_move_line += """
  1130. LEFT JOIN
  1131. account_analytic_account aa ON ml.analytic_account_id = aa.id
  1132. """
  1133. if self.filter_analytic_tag_ids:
  1134. query_inject_move_line += """
  1135. INNER JOIN
  1136. move_lines_on_tags ON ml.id = move_lines_on_tags.ml_id
  1137. """
  1138. query_inject_move_line += """
  1139. WHERE
  1140. ra.report_id = %s
  1141. AND
  1142. """
  1143. if only_unaffected_earnings_account:
  1144. query_inject_move_line += """
  1145. a.id = %s
  1146. AND
  1147. """
  1148. if is_account_line:
  1149. query_inject_move_line += """
  1150. (ra.is_partner_account IS NULL OR ra.is_partner_account != TRUE)
  1151. """
  1152. elif is_partner_line:
  1153. query_inject_move_line += """
  1154. ra.is_partner_account = TRUE
  1155. """
  1156. if self.centralize:
  1157. query_inject_move_line += """
  1158. AND
  1159. (a.centralized IS NULL OR a.centralized != TRUE)
  1160. """
  1161. query_inject_move_line += """
  1162. AND
  1163. ml.date BETWEEN %s AND %s
  1164. """
  1165. if self.only_posted_moves:
  1166. query_inject_move_line += """
  1167. AND
  1168. m.state = 'posted'
  1169. """
  1170. if only_empty_partner_line:
  1171. query_inject_move_line += """
  1172. AND
  1173. ml.partner_id IS NULL
  1174. AND
  1175. rp.partner_id IS NULL
  1176. """
  1177. if self.filter_journal_ids:
  1178. query_inject_move_line += """
  1179. AND
  1180. j.id IN %s
  1181. """
  1182. if is_account_line:
  1183. query_inject_move_line += """
  1184. ORDER BY
  1185. a.code, ml.date, ml.id
  1186. """
  1187. elif is_partner_line and not only_empty_partner_line:
  1188. query_inject_move_line += """
  1189. ORDER BY
  1190. a.code, p.name, ml.date, ml.id
  1191. """
  1192. elif is_partner_line and only_empty_partner_line:
  1193. query_inject_move_line += """
  1194. ORDER BY
  1195. a.code, ml.date, ml.id
  1196. """
  1197. query_inject_move_line_params = ()
  1198. if self.filter_analytic_tag_ids:
  1199. query_inject_move_line_params += (
  1200. self.id,
  1201. tuple(self.filter_analytic_tag_ids.ids),
  1202. )
  1203. query_inject_move_line_params += (self.env.uid,)
  1204. if self.filter_cost_center_ids:
  1205. query_inject_move_line_params += (tuple(self.filter_cost_center_ids.ids),)
  1206. query_inject_move_line_params += (self.id,)
  1207. if only_unaffected_earnings_account:
  1208. query_inject_move_line_params += (self.unaffected_earnings_account.id,)
  1209. query_inject_move_line_params += (
  1210. self.date_from,
  1211. self.date_to,
  1212. )
  1213. if self.filter_journal_ids:
  1214. query_inject_move_line_params += (tuple(self.filter_journal_ids.ids,),)
  1215. self.env.cr.execute(query_inject_move_line, query_inject_move_line_params)
  1216. def _inject_line_centralized_values(self):
  1217. """ Inject report values for report_general_ledger_move_line.
  1218. Only centralized accounts are computed.
  1219. """
  1220. if self.filter_analytic_tag_ids:
  1221. query_inject_move_line_centralized = """
  1222. WITH
  1223. move_lines_on_tags AS
  1224. (
  1225. SELECT
  1226. DISTINCT ml.id AS ml_id
  1227. FROM
  1228. report_general_ledger_account ra
  1229. INNER JOIN
  1230. account_move_line ml
  1231. ON ra.account_id = ml.account_id
  1232. INNER JOIN
  1233. account_analytic_tag_account_move_line_rel atml
  1234. ON atml.account_move_line_id = ml.id
  1235. INNER JOIN
  1236. account_analytic_tag aat
  1237. ON
  1238. atml.account_analytic_tag_id = aat.id
  1239. WHERE
  1240. ra.report_id = %s
  1241. AND
  1242. aat.id IN %s
  1243. ),
  1244. """
  1245. else:
  1246. query_inject_move_line_centralized = """
  1247. WITH
  1248. """
  1249. query_inject_move_line_centralized += """
  1250. move_lines AS
  1251. (
  1252. SELECT
  1253. ml.account_id,
  1254. (
  1255. DATE_TRUNC('month', ml.date) + interval '1 month'
  1256. - interval '1 day'
  1257. )::date AS date,
  1258. SUM(ml.debit) AS debit,
  1259. SUM(ml.credit) AS credit,
  1260. SUM(ml.balance) AS balance,
  1261. ml.currency_id AS currency_id,
  1262. ml.journal_id as journal_id
  1263. FROM
  1264. report_general_ledger_account ra
  1265. INNER JOIN
  1266. account_move_line ml ON ra.account_id = ml.account_id
  1267. INNER JOIN
  1268. account_move m ON ml.move_id = m.id
  1269. INNER JOIN
  1270. account_account a ON ml.account_id = a.id
  1271. """
  1272. if self.filter_cost_center_ids:
  1273. query_inject_move_line_centralized += """
  1274. INNER JOIN
  1275. account_analytic_account aa
  1276. ON
  1277. ml.analytic_account_id = aa.id
  1278. AND aa.id IN %s
  1279. """
  1280. if self.filter_analytic_tag_ids:
  1281. query_inject_move_line_centralized += """
  1282. INNER JOIN
  1283. move_lines_on_tags ON ml.id = move_lines_on_tags.ml_id
  1284. """
  1285. query_inject_move_line_centralized += """
  1286. WHERE
  1287. ra.report_id = %s
  1288. AND
  1289. a.centralized = TRUE
  1290. AND
  1291. ml.date BETWEEN %s AND %s
  1292. """
  1293. if self.only_posted_moves:
  1294. query_inject_move_line_centralized += """
  1295. AND
  1296. m.state = 'posted'
  1297. """
  1298. query_inject_move_line_centralized += (
  1299. """
  1300. GROUP BY
  1301. ra.id, ml.account_id, a.code, 2, ml.currency_id, ml.journal_id
  1302. )
  1303. INSERT INTO
  1304. report_general_ledger_move_line
  1305. (
  1306. report_account_id,
  1307. create_uid,
  1308. create_date,
  1309. date,
  1310. account,
  1311. journal,
  1312. label,
  1313. debit,
  1314. credit,
  1315. cumul_balance
  1316. )
  1317. SELECT
  1318. ra.id AS report_account_id,
  1319. %s AS create_uid,
  1320. NOW() AS create_date,
  1321. ml.date,
  1322. a.code AS account,
  1323. j.code AS journal,
  1324. '"""
  1325. + _("Centralized Entries")
  1326. + """' AS label,
  1327. ml.debit AS debit,
  1328. ml.credit AS credit,
  1329. ra.initial_balance + (
  1330. SUM(ml.balance)
  1331. OVER (PARTITION BY a.code ORDER BY ml.date)
  1332. ) AS cumul_balance
  1333. FROM
  1334. report_general_ledger_account ra
  1335. INNER JOIN
  1336. move_lines ml ON ra.account_id = ml.account_id
  1337. INNER JOIN
  1338. account_account a ON ml.account_id = a.id
  1339. INNER JOIN
  1340. account_journal j ON ml.journal_id = j.id
  1341. LEFT JOIN
  1342. res_currency c ON ml.currency_id = c.id
  1343. WHERE
  1344. ra.report_id = %s
  1345. AND
  1346. (a.centralized IS NOT NULL AND a.centralized = TRUE)
  1347. """
  1348. )
  1349. if self.filter_journal_ids:
  1350. query_inject_move_line_centralized += """
  1351. AND
  1352. j.id in %s
  1353. """
  1354. query_inject_move_line_centralized += """
  1355. ORDER BY
  1356. a.code, ml.date
  1357. """
  1358. query_inject_move_line_centralized_params = ()
  1359. if self.filter_analytic_tag_ids:
  1360. query_inject_move_line_centralized_params += (
  1361. self.id,
  1362. tuple(self.filter_analytic_tag_ids.ids),
  1363. )
  1364. if self.filter_cost_center_ids:
  1365. query_inject_move_line_centralized_params += (
  1366. tuple(self.filter_cost_center_ids.ids),
  1367. )
  1368. query_inject_move_line_centralized_params += (
  1369. self.id,
  1370. self.date_from,
  1371. self.date_to,
  1372. self.env.uid,
  1373. self.id,
  1374. )
  1375. if self.filter_journal_ids:
  1376. query_inject_move_line_centralized_params += (
  1377. tuple(self.filter_journal_ids.ids,),
  1378. )
  1379. self.env.cr.execute(
  1380. query_inject_move_line_centralized,
  1381. query_inject_move_line_centralized_params,
  1382. )
  1383. def _compute_analytic_tags(self):
  1384. """ Compute "tags" column"""
  1385. query_update_analytic_tags = """
  1386. UPDATE
  1387. report_general_ledger_move_line
  1388. SET
  1389. tags = tags_values.tags
  1390. FROM
  1391. (
  1392. (
  1393. SELECT
  1394. rml.id AS report_id,
  1395. array_to_string(array_agg(t.name ORDER BY t.name), ',') AS tags
  1396. FROM
  1397. account_move_line ml
  1398. INNER JOIN
  1399. report_general_ledger_move_line rml
  1400. ON ml.id = rml.move_line_id
  1401. INNER JOIN
  1402. report_general_ledger_account ra
  1403. ON rml.report_account_id = ra.id
  1404. INNER JOIN
  1405. account_analytic_tag_account_move_line_rel tml
  1406. ON ml.id = tml.account_move_line_id
  1407. INNER JOIN
  1408. account_analytic_tag t
  1409. ON tml.account_analytic_tag_id = t.id
  1410. WHERE
  1411. ra.report_id = %(report_id)s
  1412. GROUP BY
  1413. rml.id,
  1414. ml.id
  1415. )
  1416. UNION
  1417. (
  1418. SELECT
  1419. rml.id AS report_id,
  1420. array_to_string(array_agg(t.name ORDER BY t.name), ',') AS tags
  1421. FROM
  1422. account_move_line ml
  1423. INNER JOIN
  1424. report_general_ledger_move_line rml
  1425. ON ml.id = rml.move_line_id
  1426. INNER JOIN
  1427. report_general_ledger_partner rp
  1428. ON rml.report_partner_id = rp.id
  1429. INNER JOIN
  1430. report_general_ledger_account ra
  1431. ON rp.report_account_id = ra.id
  1432. INNER JOIN
  1433. account_analytic_tag_account_move_line_rel tml
  1434. ON ml.id = tml.account_move_line_id
  1435. INNER JOIN
  1436. account_analytic_tag t
  1437. ON tml.account_analytic_tag_id = t.id
  1438. WHERE
  1439. ra.report_id = %(report_id)s
  1440. GROUP BY
  1441. rml.id,
  1442. ml.id
  1443. )
  1444. ) AS tags_values
  1445. WHERE
  1446. report_general_ledger_move_line.id = tags_values.report_id
  1447. """
  1448. params = {
  1449. "report_id": self.id,
  1450. }
  1451. self.env.cr.execute(query_update_analytic_tags, params)
  1452. def _inject_unaffected_earnings_account_values(self):
  1453. """Inject the report values of the unaffected earnings account
  1454. for report_general_ledger_account."""
  1455. # Fetch the profit and loss accounts
  1456. query_unaffected_earnings_account_ids = """
  1457. SELECT a.id
  1458. FROM account_account as a
  1459. INNER JOIN account_account_type as at
  1460. ON at.id = a.user_type_id
  1461. WHERE at.include_initial_balance = FALSE
  1462. """
  1463. self.env.cr.execute(query_unaffected_earnings_account_ids)
  1464. pl_account_ids = [r[0] for r in self.env.cr.fetchall()]
  1465. unaffected_earnings_account_ids = pl_account_ids + [
  1466. self.unaffected_earnings_account.id
  1467. ]
  1468. # Fetch the current fiscal year start date
  1469. date = fields.Datetime.from_string(self.date_from)
  1470. res = self.company_id.compute_fiscalyear_dates(date)
  1471. fy_start_date = res["date_from"]
  1472. query_select_previous_fy_unaffected_earnings_params = {
  1473. "date_to": fy_start_date,
  1474. "company_id": self.company_id.id,
  1475. "account_ids": tuple(unaffected_earnings_account_ids),
  1476. "analytic_tag_ids": tuple(self.filter_analytic_tag_ids.ids),
  1477. }
  1478. query_select_previous_fy_unaffected_earnings = ""
  1479. q_analytic_tags = ""
  1480. if self.filter_analytic_tag_ids:
  1481. q_analytic_tags = """
  1482. WITH move_lines_on_tags AS
  1483. (
  1484. SELECT
  1485. DISTINCT ml.id AS ml_id
  1486. FROM
  1487. account_account a
  1488. INNER JOIN
  1489. account_move_line ml
  1490. ON a.id = ml.account_id
  1491. INNER JOIN
  1492. account_analytic_tag_account_move_line_rel atml
  1493. ON atml.account_move_line_id = ml.id
  1494. INNER JOIN
  1495. account_analytic_tag aat
  1496. ON
  1497. atml.account_analytic_tag_id = aat.id
  1498. WHERE
  1499. aat.id IN %(analytic_tag_ids)s
  1500. )
  1501. """
  1502. query_select_previous_fy_unaffected_earnings += q_analytic_tags
  1503. query_select_previous_fy_unaffected_earnings += """
  1504. SELECT sum(ml.balance) as balance
  1505. FROM account_move_line as ml
  1506. INNER JOIN account_move as am
  1507. ON am.id = ml.move_id
  1508. INNER JOIN account_journal j
  1509. ON am.journal_id = j.id
  1510. """
  1511. if self.filter_cost_center_ids:
  1512. query_select_previous_fy_unaffected_earnings += """
  1513. INNER JOIN account_analytic_account aa
  1514. ON ml.analytic_account_id = aa.id
  1515. AND aa.id IN %(cost_center_ids)s
  1516. """
  1517. query_select_previous_fy_unaffected_earnings_params[
  1518. "cost_center_ids"
  1519. ] = tuple(self.filter_cost_center_ids.ids)
  1520. if self.filter_analytic_tag_ids:
  1521. query_select_previous_fy_unaffected_earnings += """
  1522. INNER JOIN move_lines_on_tags ON ml.id =
  1523. move_lines_on_tags.ml_id
  1524. """
  1525. query_select_previous_fy_unaffected_earnings += """
  1526. WHERE ml.date < %(date_to)s
  1527. AND ml.company_id = %(company_id)s
  1528. AND ml.account_id IN %(account_ids)s
  1529. """
  1530. if self.filter_journal_ids:
  1531. query_select_previous_fy_unaffected_earnings += """
  1532. AND j.id IN %(journal_ids)s
  1533. """
  1534. query_select_previous_fy_unaffected_earnings_params["journal_ids"] = tuple(
  1535. self.filter_journal_ids.ids
  1536. )
  1537. if self.only_posted_moves:
  1538. query_select_previous_fy_unaffected_earnings += """
  1539. AND am.state = 'posted'
  1540. """
  1541. self.env.cr.execute(
  1542. query_select_previous_fy_unaffected_earnings,
  1543. query_select_previous_fy_unaffected_earnings_params,
  1544. )
  1545. res = self.env.cr.fetchone()
  1546. unaffected_earnings_initial_balance = res[0] or 0.0
  1547. # Now select the current period unaffected earnings,
  1548. # excluding the current period P&L.
  1549. query_select_period_unaffected_earnings_params = {
  1550. "date_from": self.date_from,
  1551. "date_to": self.date_to,
  1552. "company_id": self.company_id.id,
  1553. "unaffected_earnings_id": self.unaffected_earnings_account.id,
  1554. "analytic_tag_ids": tuple(self.filter_analytic_tag_ids.ids),
  1555. }
  1556. query_select_period_unaffected_earnings = ""
  1557. if self.filter_analytic_tag_ids:
  1558. query_select_period_unaffected_earnings += q_analytic_tags
  1559. query_select_period_unaffected_earnings += """
  1560. SELECT
  1561. sum(ml.debit) as sum_debit,
  1562. sum(ml.credit) as sum_credit,
  1563. sum(ml.balance) as balance
  1564. FROM account_move_line as ml
  1565. INNER JOIN account_move as am
  1566. ON am.id = ml.move_id
  1567. INNER JOIN account_journal j
  1568. ON am.journal_id = j.id
  1569. """
  1570. if self.filter_cost_center_ids:
  1571. query_select_period_unaffected_earnings += """
  1572. INNER JOIN account_analytic_account aa
  1573. ON ml.analytic_account_id = aa.id
  1574. AND aa.id IN %(cost_center_ids)s
  1575. """
  1576. query_select_period_unaffected_earnings_params["cost_center_ids"] = tuple(
  1577. self.filter_cost_center_ids.ids
  1578. )
  1579. if self.filter_analytic_tag_ids:
  1580. query_select_period_unaffected_earnings += """
  1581. INNER JOIN move_lines_on_tags
  1582. ON ml.id = move_lines_on_tags.ml_id
  1583. """
  1584. query_select_period_unaffected_earnings += """
  1585. WHERE am.date >= %(date_from)s
  1586. AND ml.date <= %(date_to)s
  1587. AND ml.company_id = %(company_id)s
  1588. AND ml.account_id = %(unaffected_earnings_id)s
  1589. """
  1590. if self.filter_journal_ids:
  1591. query_select_period_unaffected_earnings += """
  1592. AND j.id IN %(journal_ids)s
  1593. """
  1594. query_select_period_unaffected_earnings_params["journal_ids"] = tuple(
  1595. self.filter_journal_ids.ids
  1596. )
  1597. if self.only_posted_moves:
  1598. query_select_period_unaffected_earnings += """
  1599. AND am.state = 'posted'
  1600. """
  1601. self.env.cr.execute(
  1602. query_select_period_unaffected_earnings,
  1603. query_select_period_unaffected_earnings_params,
  1604. )
  1605. res = self.env.cr.fetchone()
  1606. unaffected_earnings_period_debit = res[0] or 0.0
  1607. unaffected_earnings_period_credit = res[1] or 0.0
  1608. unaffected_earnings_period_balance = res[2] or 0.0
  1609. # pylint: disable=sql-injection
  1610. query_inject_account = """
  1611. INSERT INTO
  1612. report_general_ledger_account (
  1613. report_id,
  1614. create_uid,
  1615. create_date,
  1616. account_id,
  1617. code,
  1618. name,
  1619. is_partner_account,
  1620. initial_debit,
  1621. initial_credit,
  1622. initial_balance,
  1623. final_debit,
  1624. final_credit,
  1625. final_balance
  1626. )
  1627. VALUES (
  1628. %(report_id)s,
  1629. %(user_id)s,
  1630. NOW(),
  1631. %(account_id)s,
  1632. %(code)s,
  1633. %(name)s,
  1634. False,
  1635. %(initial_debit)s,
  1636. %(initial_credit)s,
  1637. %(initial_balance)s,
  1638. %(final_debit)s,
  1639. %(final_credit)s,
  1640. %(final_balance)s
  1641. )
  1642. """
  1643. initial_debit = (
  1644. unaffected_earnings_initial_balance >= 0
  1645. and unaffected_earnings_initial_balance
  1646. or 0
  1647. )
  1648. initial_credit = (
  1649. unaffected_earnings_initial_balance < 0
  1650. and -1 * unaffected_earnings_initial_balance
  1651. or 0
  1652. )
  1653. final_balance = (
  1654. unaffected_earnings_initial_balance + unaffected_earnings_period_balance
  1655. )
  1656. query_inject_account_params = {
  1657. "report_id": self.id,
  1658. "user_id": self.env.uid,
  1659. "account_id": self.unaffected_earnings_account.id,
  1660. "code": self.unaffected_earnings_account.code,
  1661. "name": self.unaffected_earnings_account.name,
  1662. "initial_debit": initial_debit,
  1663. "initial_credit": initial_credit,
  1664. "initial_balance": unaffected_earnings_initial_balance,
  1665. "final_debit": initial_debit + unaffected_earnings_period_debit,
  1666. "final_credit": initial_credit + unaffected_earnings_period_credit,
  1667. "final_balance": final_balance,
  1668. }
  1669. self.env.cr.execute(query_inject_account, query_inject_account_params)