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.

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