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.

1783 lines
58 KiB

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