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.

1409 lines
43 KiB

8 years ago
8 years ago
  1. # -*- coding: utf-8 -*-
  2. # © 2016 Julien Coux (Camptocamp)
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. from openerp import models, fields, api, _
  5. class GeneralLedgerReport(models.TransientModel):
  6. """ Here, we just define class fields.
  7. For methods, go more bottom at this file.
  8. The class hierarchy is :
  9. * GeneralLedgerReport
  10. ** GeneralLedgerReportAccount
  11. *** GeneralLedgerReportMoveLine
  12. For non receivable/payable accounts
  13. For receivable/payable centralized accounts
  14. *** GeneralLedgerReportPartner
  15. For receivable/payable and not centralized accounts
  16. **** GeneralLedgerReportMoveLine
  17. For receivable/payable and not centralized accounts
  18. """
  19. _name = 'report_general_ledger_qweb'
  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_balance_at_0 = fields.Boolean()
  26. company_id = fields.Many2one(comodel_name='res.company')
  27. filter_account_ids = fields.Many2many(comodel_name='account.account')
  28. filter_partner_ids = fields.Many2many(comodel_name='res.partner')
  29. filter_cost_center_ids = fields.Many2many(
  30. comodel_name='account.analytic.account'
  31. )
  32. centralize = fields.Boolean()
  33. # Flag fields, used for report display
  34. has_second_currency = fields.Boolean()
  35. show_cost_center = fields.Boolean(
  36. default=lambda self: self.env.user.has_group(
  37. 'analytic.group_analytic_accounting'
  38. )
  39. )
  40. # Data fields, used to browse report data
  41. account_ids = fields.One2many(
  42. comodel_name='report_general_ledger_qweb_account',
  43. inverse_name='report_id'
  44. )
  45. # Compute of unaffected earnings account
  46. @api.depends('company_id')
  47. def _compute_unaffected_earnings_account(self):
  48. account_type = self.env.ref('account.data_unaffected_earnings')
  49. self.unaffected_earnings_account = self.env['account.account'].search(
  50. [
  51. ('user_type_id', '=', account_type.id),
  52. ('company_id', '=', self.company_id.id)
  53. ])
  54. unaffected_earnings_account = fields.Many2one(
  55. comodel_name='account.account',
  56. compute='_compute_unaffected_earnings_account',
  57. store=True
  58. )
  59. class GeneralLedgerReportAccount(models.TransientModel):
  60. _name = 'report_general_ledger_qweb_account'
  61. _order = 'code ASC'
  62. report_id = fields.Many2one(
  63. comodel_name='report_general_ledger_qweb',
  64. ondelete='cascade',
  65. index=True
  66. )
  67. # Data fields, used to keep link with real object
  68. account_id = fields.Many2one(
  69. 'account.account',
  70. index=True
  71. )
  72. # Data fields, used for report display
  73. code = fields.Char()
  74. name = fields.Char()
  75. initial_debit = fields.Float(digits=(16, 2))
  76. initial_credit = fields.Float(digits=(16, 2))
  77. initial_balance = fields.Float(digits=(16, 2))
  78. final_debit = fields.Float(digits=(16, 2))
  79. final_credit = fields.Float(digits=(16, 2))
  80. final_balance = fields.Float(digits=(16, 2))
  81. # Flag fields, used for report display and for data computation
  82. is_partner_account = fields.Boolean()
  83. # Data fields, used to browse report data
  84. move_line_ids = fields.One2many(
  85. comodel_name='report_general_ledger_qweb_move_line',
  86. inverse_name='report_account_id'
  87. )
  88. partner_ids = fields.One2many(
  89. comodel_name='report_general_ledger_qweb_partner',
  90. inverse_name='report_account_id'
  91. )
  92. class GeneralLedgerReportPartner(models.TransientModel):
  93. _name = 'report_general_ledger_qweb_partner'
  94. report_account_id = fields.Many2one(
  95. comodel_name='report_general_ledger_qweb_account',
  96. ondelete='cascade',
  97. index=True
  98. )
  99. # Data fields, used to keep link with real object
  100. partner_id = fields.Many2one(
  101. 'res.partner',
  102. index=True
  103. )
  104. # Data fields, used for report display
  105. name = fields.Char()
  106. initial_debit = fields.Float(digits=(16, 2))
  107. initial_credit = fields.Float(digits=(16, 2))
  108. initial_balance = fields.Float(digits=(16, 2))
  109. final_debit = fields.Float(digits=(16, 2))
  110. final_credit = fields.Float(digits=(16, 2))
  111. final_balance = fields.Float(digits=(16, 2))
  112. # Data fields, used to browse report data
  113. move_line_ids = fields.One2many(
  114. comodel_name='report_general_ledger_qweb_move_line',
  115. inverse_name='report_partner_id'
  116. )
  117. @api.model
  118. def _generate_order_by(self, order_spec, query):
  119. """Custom order to display "No partner allocated" at last position."""
  120. return """
  121. ORDER BY
  122. CASE
  123. WHEN "report_general_ledger_qweb_partner"."partner_id" IS NOT NULL
  124. THEN 0
  125. ELSE 1
  126. END,
  127. "report_general_ledger_qweb_partner"."name"
  128. """
  129. class GeneralLedgerReportMoveLine(models.TransientModel):
  130. _name = 'report_general_ledger_qweb_move_line'
  131. report_account_id = fields.Many2one(
  132. comodel_name='report_general_ledger_qweb_account',
  133. ondelete='cascade',
  134. index=True
  135. )
  136. report_partner_id = fields.Many2one(
  137. comodel_name='report_general_ledger_qweb_partner',
  138. ondelete='cascade',
  139. index=True
  140. )
  141. # Data fields, used to keep link with real object
  142. move_line_id = fields.Many2one('account.move.line')
  143. # Data fields, used for report display
  144. date = fields.Date()
  145. entry = fields.Char()
  146. journal = fields.Char()
  147. account = fields.Char()
  148. partner = fields.Char()
  149. label = fields.Char()
  150. cost_center = fields.Char()
  151. matching_number = fields.Char()
  152. debit = fields.Float(digits=(16, 2))
  153. credit = fields.Float(digits=(16, 2))
  154. cumul_balance = fields.Float(digits=(16, 2))
  155. currency_name = fields.Char()
  156. amount_currency = fields.Float(digits=(16, 2))
  157. class GeneralLedgerReportCompute(models.TransientModel):
  158. """ Here, we just define methods.
  159. For class fields, go more top at this file.
  160. """
  161. _inherit = 'report_general_ledger_qweb'
  162. @api.multi
  163. def print_report(self, xlsx_report=False):
  164. self.ensure_one()
  165. self.compute_data_for_report()
  166. if xlsx_report:
  167. report_name = 'account_financial_report_qweb.' \
  168. 'report_general_ledger_xlsx'
  169. else:
  170. report_name = 'account_financial_report_qweb.' \
  171. 'report_general_ledger_qweb'
  172. return self.env['report'].get_action(records=self,
  173. report_name=report_name)
  174. @api.multi
  175. def compute_data_for_report(self,
  176. with_line_details=True,
  177. with_partners=True
  178. ):
  179. self.ensure_one()
  180. # Compute report data
  181. self._inject_account_values()
  182. if with_partners:
  183. self._inject_partner_values()
  184. if not self.filter_partner_ids:
  185. self._inject_partner_values(only_empty_partner=True)
  186. # Add unaffected earnings account
  187. if (not self.filter_account_ids or
  188. self.unaffected_earnings_account.id in
  189. self.filter_account_ids.ids):
  190. self._inject_unaffected_earnings_account_values()
  191. # Call this function even if we don't want line details because,
  192. # we need to compute
  193. # at least the values for unaffected earnings account
  194. # In this case, only unaffected earnings account values are computed
  195. only_unaffected_earnings_account = not with_line_details
  196. self._inject_line_not_centralized_values(
  197. only_unaffected_earnings_account=only_unaffected_earnings_account
  198. )
  199. if with_line_details:
  200. self._inject_line_not_centralized_values(
  201. is_account_line=False,
  202. is_partner_line=True)
  203. self._inject_line_not_centralized_values(
  204. is_account_line=False,
  205. is_partner_line=True,
  206. only_empty_partner_line=True)
  207. if self.centralize:
  208. self._inject_line_centralized_values()
  209. # Complete unaffected earnings account
  210. if (not self.filter_account_ids or
  211. self.unaffected_earnings_account.id in
  212. self.filter_account_ids.ids):
  213. self._complete_unaffected_earnings_account_values()
  214. if with_line_details:
  215. # Compute display flag
  216. self._compute_has_second_currency()
  217. # Refresh cache because all data are computed with SQL requests
  218. self.refresh()
  219. def _get_account_sub_subquery_sum_amounts(
  220. self, include_initial_balance, date_included
  221. ):
  222. """ Return subquery used to compute sum amounts on accounts """
  223. sub_subquery_sum_amounts = """
  224. SELECT
  225. a.id AS account_id,
  226. SUM(ml.debit) AS debit,
  227. SUM(ml.credit) AS credit,
  228. SUM(ml.balance) AS balance
  229. FROM
  230. accounts a
  231. INNER JOIN
  232. account_account_type at ON a.user_type_id = at.id
  233. INNER JOIN
  234. account_move_line ml
  235. ON a.id = ml.account_id
  236. """
  237. if date_included:
  238. sub_subquery_sum_amounts += """
  239. AND ml.date <= %s
  240. """
  241. else:
  242. sub_subquery_sum_amounts += """
  243. AND ml.date < %s
  244. """
  245. if not include_initial_balance:
  246. sub_subquery_sum_amounts += """
  247. AND at.include_initial_balance != TRUE AND ml.date >= %s
  248. """
  249. else:
  250. sub_subquery_sum_amounts += """
  251. AND at.include_initial_balance = TRUE
  252. """
  253. if self.only_posted_moves:
  254. sub_subquery_sum_amounts += """
  255. INNER JOIN
  256. account_move m ON ml.move_id = m.id AND m.state = 'posted'
  257. """
  258. if self.filter_cost_center_ids:
  259. sub_subquery_sum_amounts += """
  260. INNER JOIN
  261. account_analytic_account aa
  262. ON
  263. ml.analytic_account_id = aa.id
  264. AND aa.id IN %s
  265. """
  266. sub_subquery_sum_amounts += """
  267. GROUP BY
  268. a.id
  269. """
  270. return sub_subquery_sum_amounts
  271. def _get_final_account_sub_subquery_sum_amounts(self, date_included):
  272. """ Return final subquery used to compute sum amounts on accounts """
  273. subquery_sum_amounts = """
  274. SELECT
  275. sub.account_id AS account_id,
  276. SUM(COALESCE(sub.debit, 0.0)) AS debit,
  277. SUM(COALESCE(sub.credit, 0.0)) AS credit,
  278. SUM(COALESCE(sub.balance, 0.0)) AS balance
  279. FROM
  280. (
  281. """
  282. subquery_sum_amounts += self._get_account_sub_subquery_sum_amounts(
  283. include_initial_balance=False, date_included=date_included
  284. )
  285. subquery_sum_amounts += """
  286. UNION
  287. """
  288. subquery_sum_amounts += self._get_account_sub_subquery_sum_amounts(
  289. include_initial_balance=True, date_included=date_included
  290. )
  291. subquery_sum_amounts += """
  292. ) sub
  293. GROUP BY
  294. sub.account_id
  295. """
  296. return subquery_sum_amounts
  297. def _inject_account_values(self):
  298. """Inject report values for report_general_ledger_qweb_account."""
  299. query_inject_account = """
  300. WITH
  301. accounts AS
  302. (
  303. SELECT
  304. a.id,
  305. a.code,
  306. a.name,
  307. a.internal_type IN ('payable', 'receivable')
  308. AS is_partner_account,
  309. a.user_type_id
  310. FROM
  311. account_account a
  312. """
  313. if self.filter_partner_ids or self.filter_cost_center_ids:
  314. query_inject_account += """
  315. INNER JOIN
  316. account_move_line ml ON a.id = ml.account_id
  317. """
  318. if self.filter_partner_ids:
  319. query_inject_account += """
  320. INNER JOIN
  321. res_partner p ON ml.partner_id = p.id
  322. """
  323. if self.filter_cost_center_ids:
  324. query_inject_account += """
  325. INNER JOIN
  326. account_analytic_account aa
  327. ON
  328. ml.analytic_account_id = aa.id
  329. AND aa.id IN %s
  330. """
  331. query_inject_account += """
  332. WHERE
  333. a.company_id = %s
  334. AND a.id != %s
  335. """
  336. if self.filter_account_ids:
  337. query_inject_account += """
  338. AND
  339. a.id IN %s
  340. """
  341. if self.filter_partner_ids:
  342. query_inject_account += """
  343. AND
  344. p.id IN %s
  345. """
  346. if self.filter_partner_ids or self.filter_cost_center_ids:
  347. query_inject_account += """
  348. GROUP BY
  349. a.id
  350. """
  351. init_subquery = self._get_final_account_sub_subquery_sum_amounts(
  352. date_included=False
  353. )
  354. final_subquery = self._get_final_account_sub_subquery_sum_amounts(
  355. date_included=True
  356. )
  357. query_inject_account += """
  358. ),
  359. initial_sum_amounts AS ( """ + init_subquery + """ ),
  360. final_sum_amounts AS ( """ + final_subquery + """ )
  361. INSERT INTO
  362. report_general_ledger_qweb_account
  363. (
  364. report_id,
  365. create_uid,
  366. create_date,
  367. account_id,
  368. code,
  369. name,
  370. initial_debit,
  371. initial_credit,
  372. initial_balance,
  373. final_debit,
  374. final_credit,
  375. final_balance,
  376. is_partner_account
  377. )
  378. SELECT
  379. %s AS report_id,
  380. %s AS create_uid,
  381. NOW() AS create_date,
  382. a.id AS account_id,
  383. a.code,
  384. COALESCE(tr.value, a.name) AS name,
  385. COALESCE(i.debit, 0.0) AS initial_debit,
  386. COALESCE(i.credit, 0.0) AS initial_credit,
  387. COALESCE(i.balance, 0.0) AS initial_balance,
  388. COALESCE(f.debit, 0.0) AS final_debit,
  389. COALESCE(f.credit, 0.0) AS final_credit,
  390. COALESCE(f.balance, 0.0) AS final_balance,
  391. a.is_partner_account
  392. FROM
  393. accounts a
  394. LEFT JOIN
  395. initial_sum_amounts i ON a.id = i.account_id
  396. LEFT JOIN
  397. final_sum_amounts f ON a.id = f.account_id
  398. LEFT JOIN
  399. ir_translation tr ON a.id = tr.res_id
  400. AND tr.lang = %s
  401. AND tr.type = 'model'
  402. AND tr.name = 'account.account,name'
  403. WHERE
  404. (
  405. i.debit IS NOT NULL AND i.debit != 0
  406. OR i.credit IS NOT NULL AND i.credit != 0
  407. OR i.balance IS NOT NULL AND i.balance != 0
  408. OR f.debit IS NOT NULL AND f.debit != 0
  409. OR f.credit IS NOT NULL AND f.credit != 0
  410. OR f.balance IS NOT NULL AND f.balance != 0
  411. )
  412. """
  413. if self.hide_account_balance_at_0:
  414. query_inject_account += """
  415. AND
  416. f.balance IS NOT NULL AND f.balance != 0
  417. """
  418. query_inject_account_params = ()
  419. if self.filter_cost_center_ids:
  420. query_inject_account_params += (
  421. tuple(self.filter_cost_center_ids.ids),
  422. )
  423. query_inject_account_params += (
  424. self.company_id.id,
  425. self.unaffected_earnings_account.id,
  426. )
  427. if self.filter_account_ids:
  428. query_inject_account_params += (
  429. tuple(self.filter_account_ids.ids),
  430. )
  431. if self.filter_partner_ids:
  432. query_inject_account_params += (
  433. tuple(self.filter_partner_ids.ids),
  434. )
  435. query_inject_account_params += (
  436. self.date_from,
  437. self.fy_start_date,
  438. )
  439. if self.filter_cost_center_ids:
  440. query_inject_account_params += (
  441. tuple(self.filter_cost_center_ids.ids),
  442. )
  443. query_inject_account_params += (
  444. self.date_from,
  445. )
  446. if self.filter_cost_center_ids:
  447. query_inject_account_params += (
  448. tuple(self.filter_cost_center_ids.ids),
  449. )
  450. query_inject_account_params += (
  451. self.date_to,
  452. self.fy_start_date,
  453. )
  454. if self.filter_cost_center_ids:
  455. query_inject_account_params += (
  456. tuple(self.filter_cost_center_ids.ids),
  457. )
  458. query_inject_account_params += (
  459. self.date_to,
  460. )
  461. if self.filter_cost_center_ids:
  462. query_inject_account_params += (
  463. tuple(self.filter_cost_center_ids.ids),
  464. )
  465. query_inject_account_params += (
  466. self.id,
  467. self.env.uid,
  468. self.env.lang,
  469. )
  470. self.env.cr.execute(query_inject_account, query_inject_account_params)
  471. def _get_partner_sub_subquery_sum_amounts(
  472. self, only_empty_partner, include_initial_balance, date_included
  473. ):
  474. """ Return subquery used to compute sum amounts on partners """
  475. sub_subquery_sum_amounts = """
  476. SELECT
  477. ap.account_id AS account_id,
  478. ap.partner_id AS partner_id,
  479. SUM(ml.debit) AS debit,
  480. SUM(ml.credit) AS credit,
  481. SUM(ml.balance) AS balance
  482. FROM
  483. accounts_partners ap
  484. INNER JOIN
  485. account_move_line ml
  486. ON ap.account_id = ml.account_id
  487. """
  488. if date_included:
  489. sub_subquery_sum_amounts += """
  490. AND ml.date <= %s
  491. """
  492. else:
  493. sub_subquery_sum_amounts += """
  494. AND ml.date < %s
  495. """
  496. if not only_empty_partner:
  497. sub_subquery_sum_amounts += """
  498. AND ap.partner_id = ml.partner_id
  499. """
  500. else:
  501. sub_subquery_sum_amounts += """
  502. AND ap.partner_id IS NULL AND ml.partner_id IS NULL
  503. """
  504. if not include_initial_balance:
  505. sub_subquery_sum_amounts += """
  506. AND ap.include_initial_balance != TRUE AND ml.date >= %s
  507. """
  508. else:
  509. sub_subquery_sum_amounts += """
  510. AND ap.include_initial_balance = TRUE
  511. """
  512. if self.only_posted_moves:
  513. sub_subquery_sum_amounts += """
  514. INNER JOIN
  515. account_move m ON ml.move_id = m.id AND m.state = 'posted'
  516. """
  517. if self.filter_cost_center_ids:
  518. sub_subquery_sum_amounts += """
  519. INNER JOIN
  520. account_analytic_account aa
  521. ON
  522. ml.analytic_account_id = aa.id
  523. AND aa.id IN %s
  524. """
  525. sub_subquery_sum_amounts += """
  526. GROUP BY
  527. ap.account_id, ap.partner_id
  528. """
  529. return sub_subquery_sum_amounts
  530. def _get_final_partner_sub_subquery_sum_amounts(
  531. self, only_empty_partner, date_included
  532. ):
  533. """ Return final subquery used to compute sum amounts on partners """
  534. subquery_sum_amounts = """
  535. SELECT
  536. sub.account_id AS account_id,
  537. sub.partner_id AS partner_id,
  538. SUM(COALESCE(sub.debit, 0.0)) AS debit,
  539. SUM(COALESCE(sub.credit, 0.0)) AS credit,
  540. SUM(COALESCE(sub.balance, 0.0)) AS balance
  541. FROM
  542. (
  543. """
  544. subquery_sum_amounts += self._get_partner_sub_subquery_sum_amounts(
  545. only_empty_partner,
  546. include_initial_balance=False,
  547. date_included=date_included
  548. )
  549. subquery_sum_amounts += """
  550. UNION
  551. """
  552. subquery_sum_amounts += self._get_partner_sub_subquery_sum_amounts(
  553. only_empty_partner,
  554. include_initial_balance=True,
  555. date_included=date_included
  556. )
  557. subquery_sum_amounts += """
  558. ) sub
  559. GROUP BY
  560. sub.account_id, sub.partner_id
  561. """
  562. return subquery_sum_amounts
  563. def _inject_partner_values(self, only_empty_partner=False):
  564. """ Inject report values for report_general_ledger_qweb_partner.
  565. Only for "partner" accounts (payable and receivable).
  566. """
  567. query_inject_partner = """
  568. WITH
  569. accounts_partners AS
  570. (
  571. SELECT
  572. ra.id AS report_account_id,
  573. a.id AS account_id,
  574. at.include_initial_balance AS include_initial_balance,
  575. p.id AS partner_id,
  576. COALESCE(
  577. CASE
  578. WHEN
  579. NULLIF(p.name, '') IS NOT NULL
  580. AND NULLIF(p.ref, '') IS NOT NULL
  581. THEN p.name || ' (' || p.ref || ')'
  582. ELSE p.name
  583. END,
  584. '""" + _('No partner allocated') + """'
  585. ) AS partner_name
  586. FROM
  587. report_general_ledger_qweb_account ra
  588. INNER JOIN
  589. account_account a ON ra.account_id = a.id
  590. INNER JOIN
  591. account_account_type at ON a.user_type_id = at.id
  592. INNER JOIN
  593. account_move_line ml ON a.id = ml.account_id
  594. LEFT JOIN
  595. res_partner p ON ml.partner_id = p.id
  596. """
  597. if self.filter_cost_center_ids:
  598. query_inject_partner += """
  599. INNER JOIN
  600. account_analytic_account aa
  601. ON
  602. ml.analytic_account_id = aa.id
  603. AND aa.id IN %s
  604. """
  605. query_inject_partner += """
  606. WHERE
  607. ra.report_id = %s
  608. AND
  609. ra.is_partner_account = TRUE
  610. """
  611. if not only_empty_partner:
  612. query_inject_partner += """
  613. AND
  614. p.id IS NOT NULL
  615. """
  616. else:
  617. query_inject_partner += """
  618. AND
  619. p.id IS NULL
  620. """
  621. query_inject_partner += """
  622. """
  623. if self.centralize:
  624. query_inject_partner += """
  625. AND (a.centralized IS NULL OR a.centralized != TRUE)
  626. """
  627. if self.filter_partner_ids:
  628. query_inject_partner += """
  629. AND
  630. p.id IN %s
  631. """
  632. init_subquery = self._get_final_partner_sub_subquery_sum_amounts(
  633. only_empty_partner,
  634. date_included=False
  635. )
  636. final_subquery = self._get_final_partner_sub_subquery_sum_amounts(
  637. only_empty_partner,
  638. date_included=True
  639. )
  640. query_inject_partner += """
  641. GROUP BY
  642. ra.id,
  643. a.id,
  644. p.id,
  645. at.include_initial_balance
  646. ),
  647. initial_sum_amounts AS ( """ + init_subquery + """ ),
  648. final_sum_amounts AS ( """ + final_subquery + """ )
  649. INSERT INTO
  650. report_general_ledger_qweb_partner
  651. (
  652. report_account_id,
  653. create_uid,
  654. create_date,
  655. partner_id,
  656. name,
  657. initial_debit,
  658. initial_credit,
  659. initial_balance,
  660. final_debit,
  661. final_credit,
  662. final_balance
  663. )
  664. SELECT
  665. ap.report_account_id,
  666. %s AS create_uid,
  667. NOW() AS create_date,
  668. ap.partner_id,
  669. ap.partner_name,
  670. COALESCE(i.debit, 0.0) AS initial_debit,
  671. COALESCE(i.credit, 0.0) AS initial_credit,
  672. COALESCE(i.balance, 0.0) AS initial_balance,
  673. COALESCE(f.debit, 0.0) AS final_debit,
  674. COALESCE(f.credit, 0.0) AS final_credit,
  675. COALESCE(f.balance, 0.0) AS final_balance
  676. FROM
  677. accounts_partners ap
  678. LEFT JOIN
  679. initial_sum_amounts i
  680. ON
  681. (
  682. """
  683. if not only_empty_partner:
  684. query_inject_partner += """
  685. ap.partner_id = i.partner_id
  686. """
  687. else:
  688. query_inject_partner += """
  689. ap.partner_id IS NULL AND i.partner_id IS NULL
  690. """
  691. query_inject_partner += """
  692. )
  693. AND ap.account_id = i.account_id
  694. LEFT JOIN
  695. final_sum_amounts f
  696. ON
  697. (
  698. """
  699. if not only_empty_partner:
  700. query_inject_partner += """
  701. ap.partner_id = f.partner_id
  702. """
  703. else:
  704. query_inject_partner += """
  705. ap.partner_id IS NULL AND f.partner_id IS NULL
  706. """
  707. query_inject_partner += """
  708. )
  709. AND ap.account_id = f.account_id
  710. WHERE
  711. (
  712. i.debit IS NOT NULL AND i.debit != 0
  713. OR i.credit IS NOT NULL AND i.credit != 0
  714. OR i.balance IS NOT NULL AND i.balance != 0
  715. OR f.debit IS NOT NULL AND f.debit != 0
  716. OR f.credit IS NOT NULL AND f.credit != 0
  717. OR f.balance IS NOT NULL AND f.balance != 0
  718. )
  719. """
  720. if self.hide_account_balance_at_0:
  721. query_inject_partner += """
  722. AND
  723. f.balance IS NOT NULL AND f.balance != 0
  724. """
  725. query_inject_partner_params = ()
  726. if self.filter_cost_center_ids:
  727. query_inject_partner_params += (
  728. tuple(self.filter_cost_center_ids.ids),
  729. )
  730. query_inject_partner_params += (
  731. self.id,
  732. )
  733. if self.filter_partner_ids:
  734. query_inject_partner_params += (
  735. tuple(self.filter_partner_ids.ids),
  736. )
  737. query_inject_partner_params += (
  738. self.date_from,
  739. self.fy_start_date,
  740. )
  741. if self.filter_cost_center_ids:
  742. query_inject_partner_params += (
  743. tuple(self.filter_cost_center_ids.ids),
  744. )
  745. query_inject_partner_params += (
  746. self.date_from,
  747. )
  748. if self.filter_cost_center_ids:
  749. query_inject_partner_params += (
  750. tuple(self.filter_cost_center_ids.ids),
  751. )
  752. query_inject_partner_params += (
  753. self.date_to,
  754. self.fy_start_date,
  755. )
  756. if self.filter_cost_center_ids:
  757. query_inject_partner_params += (
  758. tuple(self.filter_cost_center_ids.ids),
  759. )
  760. query_inject_partner_params += (
  761. self.date_to,
  762. )
  763. if self.filter_cost_center_ids:
  764. query_inject_partner_params += (
  765. tuple(self.filter_cost_center_ids.ids),
  766. )
  767. query_inject_partner_params += (
  768. self.env.uid,
  769. )
  770. self.env.cr.execute(query_inject_partner, query_inject_partner_params)
  771. def _inject_line_not_centralized_values(
  772. self,
  773. is_account_line=True,
  774. is_partner_line=False,
  775. only_empty_partner_line=False,
  776. only_unaffected_earnings_account=False):
  777. """ Inject report values for report_general_ledger_qweb_move_line.
  778. If centralized option have been chosen,
  779. only non centralized accounts are computed.
  780. In function of `is_account_line` and `is_partner_line` values,
  781. the move_line link is made either with account or either with partner.
  782. The "only_empty_partner_line" value is used
  783. to compute data without partner.
  784. """
  785. query_inject_move_line = """
  786. INSERT INTO
  787. report_general_ledger_qweb_move_line
  788. (
  789. """
  790. if is_account_line:
  791. query_inject_move_line += """
  792. report_account_id,
  793. """
  794. elif is_partner_line:
  795. query_inject_move_line += """
  796. report_partner_id,
  797. """
  798. query_inject_move_line += """
  799. create_uid,
  800. create_date,
  801. move_line_id,
  802. date,
  803. entry,
  804. journal,
  805. account,
  806. partner,
  807. label,
  808. cost_center,
  809. matching_number,
  810. debit,
  811. credit,
  812. cumul_balance,
  813. currency_name,
  814. amount_currency
  815. )
  816. SELECT
  817. """
  818. if is_account_line:
  819. query_inject_move_line += """
  820. ra.id AS report_account_id,
  821. """
  822. elif is_partner_line:
  823. query_inject_move_line += """
  824. rp.id AS report_partner_id,
  825. """
  826. query_inject_move_line += """
  827. %s AS create_uid,
  828. NOW() AS create_date,
  829. ml.id AS move_line_id,
  830. ml.date,
  831. m.name AS entry,
  832. j.code AS journal,
  833. a.code AS account,
  834. """
  835. if not only_empty_partner_line:
  836. query_inject_move_line += """
  837. CASE
  838. WHEN
  839. NULLIF(p.name, '') IS NOT NULL
  840. AND NULLIF(p.ref, '') IS NOT NULL
  841. THEN p.name || ' (' || p.ref || ')'
  842. ELSE p.name
  843. END AS partner,
  844. """
  845. elif only_empty_partner_line:
  846. query_inject_move_line += """
  847. '""" + _('No partner allocated') + """' AS partner,
  848. """
  849. query_inject_move_line += """
  850. CONCAT_WS(' - ', NULLIF(ml.ref, ''), NULLIF(ml.name, '')) AS label,
  851. aa.name AS cost_center,
  852. fr.name AS matching_number,
  853. ml.debit,
  854. ml.credit,
  855. """
  856. if is_account_line:
  857. query_inject_move_line += """
  858. ra.initial_balance + (
  859. SUM(ml.balance)
  860. OVER (PARTITION BY a.code
  861. ORDER BY a.code, ml.date, ml.id)
  862. ) AS cumul_balance,
  863. """
  864. elif is_partner_line and not only_empty_partner_line:
  865. query_inject_move_line += """
  866. rp.initial_balance + (
  867. SUM(ml.balance)
  868. OVER (PARTITION BY a.code, p.name
  869. ORDER BY a.code, p.name, ml.date, ml.id)
  870. ) AS cumul_balance,
  871. """
  872. elif is_partner_line and only_empty_partner_line:
  873. query_inject_move_line += """
  874. rp.initial_balance + (
  875. SUM(ml.balance)
  876. OVER (PARTITION BY a.code
  877. ORDER BY a.code, ml.date, ml.id)
  878. ) AS cumul_balance,
  879. """
  880. query_inject_move_line += """
  881. c.name AS currency_name,
  882. ml.amount_currency
  883. FROM
  884. """
  885. if is_account_line:
  886. query_inject_move_line += """
  887. report_general_ledger_qweb_account ra
  888. """
  889. elif is_partner_line:
  890. query_inject_move_line += """
  891. report_general_ledger_qweb_partner rp
  892. INNER JOIN
  893. report_general_ledger_qweb_account ra ON rp.report_account_id = ra.id
  894. """
  895. query_inject_move_line += """
  896. INNER JOIN
  897. account_move_line ml ON ra.account_id = ml.account_id
  898. INNER JOIN
  899. account_move m ON ml.move_id = m.id
  900. INNER JOIN
  901. account_journal j ON ml.journal_id = j.id
  902. INNER JOIN
  903. account_account a ON ml.account_id = a.id
  904. """
  905. if is_account_line:
  906. query_inject_move_line += """
  907. LEFT JOIN
  908. res_partner p ON ml.partner_id = p.id
  909. """
  910. elif is_partner_line and not only_empty_partner_line:
  911. query_inject_move_line += """
  912. INNER JOIN
  913. res_partner p
  914. ON ml.partner_id = p.id AND rp.partner_id = p.id
  915. """
  916. query_inject_move_line += """
  917. LEFT JOIN
  918. account_full_reconcile fr ON ml.full_reconcile_id = fr.id
  919. LEFT JOIN
  920. res_currency c ON a.currency_id = c.id
  921. """
  922. if self.filter_cost_center_ids:
  923. query_inject_move_line += """
  924. INNER JOIN
  925. account_analytic_account aa
  926. ON
  927. ml.analytic_account_id = aa.id
  928. AND aa.id IN %s
  929. """
  930. else:
  931. query_inject_move_line += """
  932. LEFT JOIN
  933. account_analytic_account aa ON ml.analytic_account_id = aa.id
  934. """
  935. query_inject_move_line += """
  936. WHERE
  937. ra.report_id = %s
  938. AND
  939. """
  940. if only_unaffected_earnings_account:
  941. query_inject_move_line += """
  942. a.id = %s
  943. AND
  944. """
  945. if is_account_line:
  946. query_inject_move_line += """
  947. (ra.is_partner_account IS NULL OR ra.is_partner_account != TRUE)
  948. """
  949. elif is_partner_line:
  950. query_inject_move_line += """
  951. ra.is_partner_account = TRUE
  952. """
  953. if self.centralize:
  954. query_inject_move_line += """
  955. AND
  956. (a.centralized IS NULL OR a.centralized != TRUE)
  957. """
  958. query_inject_move_line += """
  959. AND
  960. ml.date BETWEEN %s AND %s
  961. """
  962. if self.only_posted_moves:
  963. query_inject_move_line += """
  964. AND
  965. m.state = 'posted'
  966. """
  967. if only_empty_partner_line:
  968. query_inject_move_line += """
  969. AND
  970. ml.partner_id IS NULL
  971. AND
  972. rp.partner_id IS NULL
  973. """
  974. if is_account_line:
  975. query_inject_move_line += """
  976. ORDER BY
  977. a.code, ml.date, ml.id
  978. """
  979. elif is_partner_line and not only_empty_partner_line:
  980. query_inject_move_line += """
  981. ORDER BY
  982. a.code, p.name, ml.date, ml.id
  983. """
  984. elif is_partner_line and only_empty_partner_line:
  985. query_inject_move_line += """
  986. ORDER BY
  987. a.code, ml.date, ml.id
  988. """
  989. query_inject_move_line_params = (
  990. self.env.uid,
  991. )
  992. if self.filter_cost_center_ids:
  993. query_inject_move_line_params += (
  994. tuple(self.filter_cost_center_ids.ids),
  995. )
  996. query_inject_move_line_params += (
  997. self.id,
  998. )
  999. if only_unaffected_earnings_account:
  1000. query_inject_move_line_params += (
  1001. self.unaffected_earnings_account.id,
  1002. )
  1003. query_inject_move_line_params += (
  1004. self.date_from,
  1005. self.date_to,
  1006. )
  1007. self.env.cr.execute(
  1008. query_inject_move_line,
  1009. query_inject_move_line_params
  1010. )
  1011. def _inject_line_centralized_values(self):
  1012. """ Inject report values for report_general_ledger_qweb_move_line.
  1013. Only centralized accounts are computed.
  1014. """
  1015. query_inject_move_line_centralized = """
  1016. WITH
  1017. move_lines AS
  1018. (
  1019. SELECT
  1020. ml.account_id,
  1021. (
  1022. DATE_TRUNC('month', ml.date) + interval '1 month'
  1023. - interval '1 day'
  1024. )::date AS date,
  1025. SUM(ml.debit) AS debit,
  1026. SUM(ml.credit) AS credit,
  1027. SUM(ml.balance) AS balance
  1028. FROM
  1029. report_general_ledger_qweb_account ra
  1030. INNER JOIN
  1031. account_move_line ml ON ra.account_id = ml.account_id
  1032. INNER JOIN
  1033. account_move m ON ml.move_id = m.id
  1034. INNER JOIN
  1035. account_account a ON ml.account_id = a.id
  1036. """
  1037. if self.filter_cost_center_ids:
  1038. query_inject_move_line_centralized += """
  1039. INNER JOIN
  1040. account_analytic_account aa
  1041. ON
  1042. ml.analytic_account_id = aa.id
  1043. AND aa.id IN %s
  1044. """
  1045. query_inject_move_line_centralized += """
  1046. WHERE
  1047. ra.report_id = %s
  1048. AND
  1049. a.centralized = TRUE
  1050. AND
  1051. ml.date BETWEEN %s AND %s
  1052. """
  1053. if self.only_posted_moves:
  1054. query_inject_move_line_centralized += """
  1055. AND
  1056. m.state = 'posted'
  1057. """
  1058. query_inject_move_line_centralized += """
  1059. GROUP BY
  1060. ra.id, ml.account_id, a.code, 2
  1061. )
  1062. INSERT INTO
  1063. report_general_ledger_qweb_move_line
  1064. (
  1065. report_account_id,
  1066. create_uid,
  1067. create_date,
  1068. date,
  1069. account,
  1070. label,
  1071. debit,
  1072. credit,
  1073. cumul_balance
  1074. )
  1075. SELECT
  1076. ra.id AS report_account_id,
  1077. %s AS create_uid,
  1078. NOW() AS create_date,
  1079. ml.date,
  1080. a.code AS account,
  1081. '""" + _('Centralized Entries') + """' AS label,
  1082. ml.debit AS debit,
  1083. ml.credit AS credit,
  1084. ra.initial_balance + (
  1085. SUM(ml.balance)
  1086. OVER (PARTITION BY a.code ORDER BY ml.date)
  1087. ) AS cumul_balance
  1088. FROM
  1089. report_general_ledger_qweb_account ra
  1090. INNER JOIN
  1091. move_lines ml ON ra.account_id = ml.account_id
  1092. INNER JOIN
  1093. account_account a ON ml.account_id = a.id
  1094. LEFT JOIN
  1095. res_currency c ON a.currency_id = c.id
  1096. WHERE
  1097. ra.report_id = %s
  1098. AND
  1099. (a.centralized IS NOT NULL AND a.centralized = TRUE)
  1100. ORDER BY
  1101. a.code, ml.date
  1102. """
  1103. query_inject_move_line_centralized_params = ()
  1104. if self.filter_cost_center_ids:
  1105. query_inject_move_line_centralized_params += (
  1106. tuple(self.filter_cost_center_ids.ids),
  1107. )
  1108. query_inject_move_line_centralized_params += (
  1109. self.id,
  1110. self.date_from,
  1111. self.date_to,
  1112. self.env.uid,
  1113. self.id,
  1114. )
  1115. self.env.cr.execute(
  1116. query_inject_move_line_centralized,
  1117. query_inject_move_line_centralized_params
  1118. )
  1119. def _compute_has_second_currency(self):
  1120. """ Compute "has_second_currency" flag which will used for display."""
  1121. query_update_has_second_currency = """
  1122. UPDATE
  1123. report_general_ledger_qweb
  1124. SET
  1125. has_second_currency =
  1126. (
  1127. SELECT
  1128. TRUE
  1129. FROM
  1130. report_general_ledger_qweb_move_line l
  1131. INNER JOIN
  1132. report_general_ledger_qweb_account a
  1133. ON l.report_account_id = a.id
  1134. WHERE
  1135. a.report_id = %s
  1136. AND l.currency_name IS NOT NULL
  1137. LIMIT 1
  1138. )
  1139. OR
  1140. (
  1141. SELECT
  1142. TRUE
  1143. FROM
  1144. report_general_ledger_qweb_move_line l
  1145. INNER JOIN
  1146. report_general_ledger_qweb_partner p
  1147. ON l.report_partner_id = p.id
  1148. INNER JOIN
  1149. report_general_ledger_qweb_account a
  1150. ON p.report_account_id = a.id
  1151. WHERE
  1152. a.report_id = %s
  1153. AND l.currency_name IS NOT NULL
  1154. LIMIT 1
  1155. )
  1156. WHERE id = %s
  1157. """
  1158. params = (self.id,) * 3
  1159. self.env.cr.execute(query_update_has_second_currency, params)
  1160. def _get_unaffected_earnings_account_sub_subquery_sum_amounts(
  1161. self, include_initial_balance
  1162. ):
  1163. """ Return subquery used to compute sum amounts on
  1164. unaffected earnings accounts """
  1165. sub_subquery_sum_amounts = """
  1166. SELECT
  1167. SUM(ml.balance) AS balance
  1168. FROM
  1169. account_account a
  1170. INNER JOIN
  1171. account_account_type at ON a.user_type_id = at.id
  1172. INNER JOIN
  1173. account_move_line ml
  1174. ON a.id = ml.account_id
  1175. AND ml.date < %s
  1176. """
  1177. if not include_initial_balance:
  1178. sub_subquery_sum_amounts += """
  1179. AND NOT(at.include_initial_balance != TRUE AND ml.date >= %s)
  1180. """
  1181. else:
  1182. sub_subquery_sum_amounts += """
  1183. AND at.include_initial_balance = FALSE
  1184. """
  1185. if self.only_posted_moves:
  1186. sub_subquery_sum_amounts += """
  1187. INNER JOIN
  1188. account_move m ON ml.move_id = m.id AND m.state = 'posted'
  1189. """
  1190. if self.filter_cost_center_ids:
  1191. sub_subquery_sum_amounts += """
  1192. INNER JOIN
  1193. account_analytic_account aa
  1194. ON
  1195. ml.analytic_account_id = aa.id
  1196. AND aa.id IN %s
  1197. """
  1198. sub_subquery_sum_amounts += """
  1199. WHERE
  1200. a.company_id =%s
  1201. AND a.id != %s
  1202. """
  1203. return sub_subquery_sum_amounts
  1204. def _inject_unaffected_earnings_account_values(self):
  1205. """Inject the report values of the unaffected earnings account
  1206. for report_general_ledger_qweb_account."""
  1207. subquery_sum_amounts = """
  1208. SELECT
  1209. SUM(COALESCE(sub.balance, 0.0)) AS balance
  1210. FROM
  1211. (
  1212. """
  1213. subquery_sum_amounts += \
  1214. self._get_unaffected_earnings_account_sub_subquery_sum_amounts(
  1215. include_initial_balance=False
  1216. )
  1217. subquery_sum_amounts += """
  1218. UNION
  1219. """
  1220. subquery_sum_amounts += \
  1221. self._get_unaffected_earnings_account_sub_subquery_sum_amounts(
  1222. include_initial_balance=True
  1223. )
  1224. subquery_sum_amounts += """
  1225. ) sub
  1226. """
  1227. query_inject_account = """
  1228. WITH
  1229. initial_sum_amounts AS ( """ + subquery_sum_amounts + """ )
  1230. INSERT INTO
  1231. report_general_ledger_qweb_account
  1232. (
  1233. report_id,
  1234. create_uid,
  1235. create_date,
  1236. account_id,
  1237. code,
  1238. name,
  1239. is_partner_account,
  1240. initial_balance
  1241. )
  1242. SELECT
  1243. %s AS report_id,
  1244. %s AS create_uid,
  1245. NOW() AS create_date,
  1246. a.id AS account_id,
  1247. a.code,
  1248. a.name,
  1249. False AS is_partner_account,
  1250. COALESCE(i.balance, 0.0) AS initial_balance
  1251. FROM
  1252. account_account a,
  1253. initial_sum_amounts i
  1254. WHERE
  1255. a.company_id = %s
  1256. AND a.id = %s
  1257. """
  1258. query_inject_account_params = (
  1259. self.date_from,
  1260. self.fy_start_date,
  1261. )
  1262. if self.filter_cost_center_ids:
  1263. query_inject_account_params += (
  1264. tuple(self.filter_cost_center_ids.ids),
  1265. )
  1266. query_inject_account_params += (
  1267. self.company_id.id,
  1268. self.unaffected_earnings_account.id,
  1269. )
  1270. query_inject_account_params += (
  1271. self.date_from,
  1272. )
  1273. if self.filter_cost_center_ids:
  1274. query_inject_account_params += (
  1275. tuple(self.filter_cost_center_ids.ids),
  1276. )
  1277. query_inject_account_params += (
  1278. self.company_id.id,
  1279. self.unaffected_earnings_account.id,
  1280. )
  1281. query_inject_account_params += (
  1282. self.id,
  1283. self.env.uid,
  1284. self.company_id.id,
  1285. self.unaffected_earnings_account.id,
  1286. )
  1287. self.env.cr.execute(query_inject_account,
  1288. query_inject_account_params)
  1289. def _complete_unaffected_earnings_account_values(self):
  1290. """Complete the report values of the unaffected earnings account
  1291. for report_general_ledger_qweb_account."""
  1292. query_update_unaffected_earnings_account_values = """
  1293. WITH
  1294. sum_amounts AS
  1295. (
  1296. SELECT
  1297. SUM(COALESCE(rml.debit, 0.0)) AS debit,
  1298. SUM(COALESCE(rml.credit, 0.0)) AS credit,
  1299. SUM(
  1300. COALESCE(rml.debit, 0.0) -
  1301. COALESCE(rml.credit, 0.0)
  1302. ) + ra.initial_balance AS balance
  1303. FROM
  1304. report_general_ledger_qweb_account ra
  1305. LEFT JOIN
  1306. report_general_ledger_qweb_move_line rml
  1307. ON ra.id = rml.report_account_id
  1308. WHERE
  1309. ra.report_id = %s
  1310. AND ra.account_id = %s
  1311. GROUP BY
  1312. ra.id
  1313. )
  1314. UPDATE
  1315. report_general_ledger_qweb_account ra
  1316. SET
  1317. initial_debit = 0.0,
  1318. initial_credit = 0.0,
  1319. final_debit = sum_amounts.debit,
  1320. final_credit = sum_amounts.credit,
  1321. final_balance = sum_amounts.balance
  1322. FROM
  1323. sum_amounts
  1324. WHERE
  1325. ra.report_id = %s
  1326. AND ra.account_id = %s
  1327. """
  1328. params = (
  1329. self.id,
  1330. self.unaffected_earnings_account.id,
  1331. self.id,
  1332. self.unaffected_earnings_account.id,
  1333. )
  1334. self.env.cr.execute(
  1335. query_update_unaffected_earnings_account_values,
  1336. params
  1337. )