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.

810 lines
24 KiB

  1. # Copyright 2017 ACSONE SA/NV
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  3. from odoo import models, fields, api
  4. DIGITS = (16, 2)
  5. class ReportJournalLedger(models.TransientModel):
  6. _name = 'report_journal_ledger'
  7. date_from = fields.Date(
  8. required=True
  9. )
  10. date_to = fields.Date(
  11. required=True
  12. )
  13. company_id = fields.Many2one(
  14. comodel_name='res.company',
  15. required=True,
  16. ondelete='cascade'
  17. )
  18. move_target = fields.Selection(
  19. selection='_get_move_targets',
  20. default='all',
  21. required=True,
  22. )
  23. sort_option = fields.Selection(
  24. selection='_get_sort_options',
  25. default='move_name',
  26. required=True,
  27. )
  28. group_option = fields.Selection(
  29. selection='_get_group_options',
  30. default='journal',
  31. required=True,
  32. )
  33. journal_ids = fields.Many2many(
  34. comodel_name='account.journal',
  35. required=True,
  36. )
  37. report_journal_ledger_ids = fields.One2many(
  38. comodel_name='report_journal_ledger_journal',
  39. inverse_name='report_id',
  40. )
  41. report_move_ids = fields.One2many(
  42. comodel_name='report_journal_ledger_move',
  43. inverse_name='report_id',
  44. )
  45. report_move_line_ids = fields.One2many(
  46. comodel_name='report_journal_ledger_move_line',
  47. inverse_name='report_id',
  48. )
  49. report_journal_ledger_tax_line_ids = fields.One2many(
  50. comodel_name='report_journal_ledger_journal_tax_line',
  51. inverse_name='report_id',
  52. )
  53. report_tax_line_ids = fields.One2many(
  54. comodel_name='report_journal_ledger_report_tax_line',
  55. inverse_name='report_id',
  56. )
  57. foreign_currency = fields.Boolean()
  58. with_account_name = fields.Boolean()
  59. @api.model
  60. def _get_move_targets(self):
  61. return self.env['journal.ledger.report.wizard']._get_move_targets()
  62. @api.model
  63. def _get_sort_options(self):
  64. return self.env['journal.ledger.report.wizard']._get_sort_options()
  65. @api.model
  66. def _get_group_options(self):
  67. return self.env['journal.ledger.report.wizard']._get_group_options()
  68. @api.multi
  69. def compute_data_for_report(self):
  70. self.ensure_one()
  71. self._inject_journal_values()
  72. self._inject_move_values()
  73. self._inject_move_line_values()
  74. self._inject_journal_tax_values()
  75. self._update_journal_report_total_values()
  76. if self.group_option == 'none':
  77. self._inject_report_tax_values()
  78. # Refresh cache because all data are computed with SQL requests
  79. self.invalidate_cache()
  80. @api.multi
  81. def _inject_journal_values(self):
  82. self.ensure_one()
  83. sql = """
  84. DELETE
  85. FROM report_journal_ledger_journal
  86. WHERE report_id = %s
  87. """
  88. params = (
  89. self.id,
  90. )
  91. self.env.cr.execute(sql, params)
  92. sql = """
  93. INSERT INTO report_journal_ledger_journal (
  94. create_uid,
  95. create_date,
  96. report_id,
  97. journal_id,
  98. name,
  99. code,
  100. company_id,
  101. currency_id
  102. )
  103. SELECT
  104. %s as create_uid,
  105. NOW() as create_date,
  106. %s as report_id,
  107. aj.id as journal_id,
  108. aj.name as name,
  109. aj.code as code,
  110. aj.company_id as company_id,
  111. COALESCE(aj.currency_id, company.currency_id) as currency_id
  112. FROM
  113. account_journal aj
  114. LEFT JOIN
  115. res_company company on (company.id = aj.company_id)
  116. WHERE
  117. aj.id in %s
  118. AND
  119. aj.company_id = %s
  120. ORDER BY
  121. aj.name
  122. """
  123. params = (
  124. self.env.uid,
  125. self.id,
  126. tuple(self.journal_ids.ids),
  127. self.company_id.id,
  128. )
  129. self.env.cr.execute(sql, params)
  130. @api.multi
  131. def _inject_move_values(self):
  132. self.ensure_one()
  133. sql = """
  134. DELETE
  135. FROM report_journal_ledger_move
  136. WHERE report_id = %s
  137. """
  138. params = (
  139. self.id,
  140. )
  141. self.env.cr.execute(sql, params)
  142. sql = self._get_inject_move_insert()
  143. sql += self._get_inject_move_select()
  144. sql += self._get_inject_move_where_clause()
  145. sql += self._get_inject_move_order_by()
  146. params = self._get_inject_move_params()
  147. self.env.cr.execute(sql, params)
  148. @api.multi
  149. def _get_inject_move_insert(self):
  150. return """
  151. INSERT INTO report_journal_ledger_move (
  152. create_uid,
  153. create_date,
  154. report_id,
  155. report_journal_ledger_id,
  156. move_id,
  157. name,
  158. company_id
  159. )
  160. """
  161. @api.multi
  162. def _get_inject_move_select(self):
  163. return """
  164. SELECT
  165. %s as create_uid,
  166. NOW() as create_date,
  167. rjqj.report_id as report_id,
  168. rjqj.id as report_journal_ledger_id,
  169. am.id as move_id,
  170. am.name as name,
  171. am.company_id as company_id
  172. FROM
  173. account_move am
  174. INNER JOIN
  175. report_journal_ledger_journal rjqj
  176. on (rjqj.journal_id = am.journal_id)
  177. """
  178. @api.multi
  179. def _get_inject_move_where_clause(self):
  180. self.ensure_one()
  181. where_clause = """
  182. WHERE
  183. rjqj.report_id = %s
  184. AND
  185. am.date >= %s
  186. AND
  187. am.date <= %s
  188. """
  189. if self.move_target != 'all':
  190. where_clause += """
  191. AND
  192. am.state = %s
  193. """
  194. return where_clause
  195. @api.multi
  196. def _get_inject_move_order_by(self):
  197. self.ensure_one()
  198. order_by = """
  199. ORDER BY
  200. """
  201. if self.sort_option == 'move_name':
  202. order_by += " am.name"
  203. elif self.sort_option == 'date':
  204. order_by += " am.date, am.name"
  205. return order_by
  206. @api.multi
  207. def _get_inject_move_params(self):
  208. params = [
  209. self.env.uid,
  210. self.id,
  211. self.date_from,
  212. self.date_to
  213. ]
  214. if self.move_target != 'all':
  215. params.append(self.move_target)
  216. return tuple(params)
  217. @api.multi
  218. def _inject_move_line_values(self):
  219. self.ensure_one()
  220. sql = """
  221. DELETE
  222. FROM report_journal_ledger_move_line
  223. WHERE report_id = %s
  224. """
  225. params = (
  226. self.id,
  227. )
  228. self.env.cr.execute(sql, params)
  229. sql = """
  230. INSERT INTO report_journal_ledger_move_line (
  231. create_uid,
  232. create_date,
  233. report_id,
  234. report_journal_ledger_id,
  235. report_move_id,
  236. move_line_id,
  237. account_id,
  238. account,
  239. account_code,
  240. account_type,
  241. partner_id,
  242. partner,
  243. date,
  244. entry,
  245. label,
  246. debit,
  247. credit,
  248. company_currency_id,
  249. amount_currency,
  250. currency_id,
  251. currency_name,
  252. tax_id,
  253. taxes_description,
  254. company_id
  255. )
  256. SELECT
  257. %s as create_uid,
  258. NOW() as create_date,
  259. rjqm.report_id as report_id,
  260. rjqm.report_journal_ledger_id as report_journal_ledger_id,
  261. rjqm.id as report_move_id,
  262. aml.id as move_line_id,
  263. aml.account_id as account_id,
  264. aa.name as account,
  265. aa.code as account_code,
  266. aa.internal_type as account_type,
  267. aml.partner_id as partner_id,
  268. p.name as partner,
  269. aml.date as date,
  270. rjqm.name as entry,
  271. aml.name as label,
  272. aml.debit as debit,
  273. aml.credit as credit,
  274. aml.company_currency_id as currency_id,
  275. aml.amount_currency as amount_currency,
  276. aml.currency_id as currency_id,
  277. currency.name as currency_name,
  278. aml.tax_line_id as tax_id,
  279. CASE
  280. WHEN
  281. aml.tax_line_id is not null
  282. THEN
  283. COALESCE(at.description, at.name)
  284. WHEN
  285. aml.tax_line_id is null
  286. THEN
  287. (SELECT
  288. array_to_string(
  289. array_agg(COALESCE(at.description, at.name)
  290. ), ', ')
  291. FROM
  292. account_move_line_account_tax_rel aml_at_rel
  293. LEFT JOIN
  294. account_tax at on (at.id = aml_at_rel.account_tax_id)
  295. WHERE
  296. aml_at_rel.account_move_line_id = aml.id)
  297. ELSE
  298. ''
  299. END as taxes_description,
  300. aml.company_id as company_id
  301. FROM
  302. account_move_line aml
  303. INNER JOIN
  304. report_journal_ledger_move rjqm
  305. on (rjqm.move_id = aml.move_id)
  306. LEFT JOIN
  307. account_account aa
  308. on (aa.id = aml.account_id)
  309. LEFT JOIN
  310. res_partner p
  311. on (p.id = aml.partner_id)
  312. LEFT JOIN
  313. account_tax at
  314. on (at.id = aml.tax_line_id)
  315. LEFT JOIN
  316. res_currency currency
  317. on (currency.id = aml.currency_id)
  318. WHERE
  319. rjqm.report_id = %s
  320. """
  321. params = (
  322. self.env.uid,
  323. self.id,
  324. )
  325. self.env.cr.execute(sql, params)
  326. @api.multi
  327. def _inject_report_tax_values(self):
  328. self.ensure_one()
  329. sql_distinct_tax_id = """
  330. SELECT
  331. distinct(jrqjtl.tax_id)
  332. FROM
  333. report_journal_ledger_journal_tax_line jrqjtl
  334. WHERE
  335. jrqjtl.report_id = %s
  336. """
  337. self.env.cr.execute(sql_distinct_tax_id, (self.id,))
  338. rows = self.env.cr.fetchall()
  339. tax_ids = set([row[0] for row in rows])
  340. sql = """
  341. INSERT INTO report_journal_ledger_report_tax_line (
  342. create_uid,
  343. create_date,
  344. report_id,
  345. tax_id,
  346. tax_name,
  347. tax_code,
  348. base_debit,
  349. base_credit,
  350. tax_debit,
  351. tax_credit
  352. )
  353. SELECT
  354. %s as create_uid,
  355. NOW() as create_date,
  356. %s as report_id,
  357. %s as tax_id,
  358. at.name as tax_name,
  359. at.description as tax_code,
  360. (
  361. SELECT sum(base_debit)
  362. FROM report_journal_ledger_journal_tax_line jrqjtl2
  363. WHERE jrqjtl2.report_id = %s
  364. AND jrqjtl2.tax_id = %s
  365. ) as base_debit,
  366. (
  367. SELECT sum(base_credit)
  368. FROM report_journal_ledger_journal_tax_line jrqjtl2
  369. WHERE jrqjtl2.report_id = %s
  370. AND jrqjtl2.tax_id = %s
  371. ) as base_credit,
  372. (
  373. SELECT sum(tax_debit)
  374. FROM report_journal_ledger_journal_tax_line jrqjtl2
  375. WHERE jrqjtl2.report_id = %s
  376. AND jrqjtl2.tax_id = %s
  377. ) as tax_debit,
  378. (
  379. SELECT sum(tax_credit)
  380. FROM report_journal_ledger_journal_tax_line jrqjtl2
  381. WHERE jrqjtl2.report_id = %s
  382. AND jrqjtl2.tax_id = %s
  383. ) as tax_credit
  384. FROM
  385. report_journal_ledger_journal_tax_line jrqjtl
  386. LEFT JOIN
  387. account_tax at
  388. on (at.id = jrqjtl.tax_id)
  389. WHERE
  390. jrqjtl.report_id = %s
  391. AND
  392. jrqjtl.tax_id = %s
  393. """
  394. for tax_id in tax_ids:
  395. params = (
  396. self.env.uid,
  397. self.id,
  398. tax_id,
  399. self.id,
  400. tax_id,
  401. self.id,
  402. tax_id,
  403. self.id,
  404. tax_id,
  405. self.id,
  406. tax_id,
  407. self.id,
  408. tax_id,
  409. )
  410. self.env.cr.execute(sql, params)
  411. @api.multi
  412. def _inject_journal_tax_values(self):
  413. self.ensure_one()
  414. sql = """
  415. DELETE
  416. FROM report_journal_ledger_journal_tax_line
  417. WHERE report_id = %s
  418. """
  419. params = (
  420. self.id,
  421. )
  422. self.env.cr.execute(sql, params)
  423. sql_distinct_tax_id = """
  424. SELECT
  425. distinct(jrqml.tax_id)
  426. FROM
  427. report_journal_ledger_move_line jrqml
  428. WHERE
  429. jrqml.report_journal_ledger_id = %s
  430. """
  431. tax_ids_by_journal_id = {}
  432. for report_journal in self.report_journal_ledger_ids:
  433. if report_journal.id not in tax_ids_by_journal_id:
  434. tax_ids_by_journal_id[report_journal.id] = []
  435. self.env.cr.execute(sql_distinct_tax_id, (report_journal.id,))
  436. rows = self.env.cr.fetchall()
  437. tax_ids_by_journal_id[report_journal.id].extend([
  438. row[0] for row in rows if row[0]
  439. ])
  440. sql = """
  441. INSERT INTO report_journal_ledger_journal_tax_line (
  442. create_uid,
  443. create_date,
  444. report_id,
  445. report_journal_ledger_id,
  446. tax_id,
  447. tax_name,
  448. tax_code,
  449. base_debit,
  450. base_credit,
  451. tax_debit,
  452. tax_credit
  453. )
  454. SELECT
  455. %s as create_uid,
  456. NOW() as create_date,
  457. %s as report_id,
  458. %s as report_journal_ledger_id,
  459. %s as tax_id,
  460. at.name as tax_name,
  461. at.description as tax_code,
  462. (
  463. SELECT sum(debit)
  464. FROM report_journal_ledger_move_line jrqml2
  465. WHERE jrqml2.report_journal_ledger_id = %s
  466. AND (
  467. SELECT
  468. count(*)
  469. FROM
  470. account_move_line_account_tax_rel aml_at_rel
  471. WHERE
  472. aml_at_rel.account_move_line_id =
  473. jrqml2.move_line_id
  474. AND
  475. aml_at_rel.account_tax_id = %s
  476. ) > 0
  477. ) as base_debit,
  478. (
  479. SELECT sum(credit)
  480. FROM report_journal_ledger_move_line jrqml2
  481. WHERE jrqml2.report_journal_ledger_id = %s
  482. AND (
  483. SELECT
  484. count(*)
  485. FROM
  486. account_move_line_account_tax_rel aml_at_rel
  487. WHERE
  488. aml_at_rel.account_move_line_id =
  489. jrqml2.move_line_id
  490. AND
  491. aml_at_rel.account_tax_id = %s
  492. ) > 0
  493. ) as base_credit,
  494. (
  495. SELECT sum(debit)
  496. FROM report_journal_ledger_move_line jrqml2
  497. WHERE jrqml2.report_journal_ledger_id = %s
  498. AND jrqml2.tax_id = %s
  499. ) as tax_debit,
  500. (
  501. SELECT sum(credit)
  502. FROM report_journal_ledger_move_line jrqml2
  503. WHERE jrqml2.report_journal_ledger_id = %s
  504. AND jrqml2.tax_id = %s
  505. ) as tax_credit
  506. FROM
  507. report_journal_ledger_journal rjqj
  508. LEFT JOIN
  509. account_tax at
  510. on (at.id = %s)
  511. WHERE
  512. rjqj.id = %s
  513. """
  514. for report_journal_ledger_id in tax_ids_by_journal_id:
  515. tax_ids = tax_ids_by_journal_id[report_journal_ledger_id]
  516. for tax_id in tax_ids:
  517. params = (
  518. self.env.uid,
  519. self.id,
  520. report_journal_ledger_id,
  521. tax_id,
  522. report_journal_ledger_id,
  523. tax_id,
  524. report_journal_ledger_id,
  525. tax_id,
  526. report_journal_ledger_id,
  527. tax_id,
  528. report_journal_ledger_id,
  529. tax_id,
  530. tax_id,
  531. report_journal_ledger_id,
  532. )
  533. self.env.cr.execute(sql, params)
  534. @api.multi
  535. def _update_journal_report_total_values(self):
  536. self.ensure_one()
  537. sql = """
  538. UPDATE
  539. report_journal_ledger_journal rjqj
  540. SET
  541. debit = (
  542. SELECT sum(rjqml.debit)
  543. FROM report_journal_ledger_move_line rjqml
  544. WHERE rjqml.report_journal_ledger_id = rjqj.id
  545. ),
  546. credit = (
  547. SELECT sum(rjqml.credit)
  548. FROM report_journal_ledger_move_line rjqml
  549. WHERE rjqml.report_journal_ledger_id = rjqj.id
  550. )
  551. WHERE
  552. rjqj.report_id = %s
  553. """
  554. self.env.cr.execute(sql, (self.id,))
  555. @api.multi
  556. def print_report(self, report_type):
  557. self.ensure_one()
  558. if report_type == 'xlsx':
  559. report_name = 'a_f_r.report_journal_ledger_xlsx'
  560. else:
  561. report_name = 'account_financial_report.' \
  562. 'report_journal_ledger_qweb'
  563. return self.env['ir.actions.report'].search(
  564. [('report_name', '=', report_name),
  565. ('report_type', '=', report_type)], limit=1).report_action(self)
  566. def _get_html(self):
  567. result = {}
  568. rcontext = {}
  569. context = dict(self.env.context)
  570. report = self.browse(context.get('active_id'))
  571. if report:
  572. rcontext['o'] = report
  573. result['html'] = self.env.ref(
  574. 'account_financial_report.report_journal_ledger').render(
  575. rcontext)
  576. return result
  577. @api.model
  578. def get_html(self, given_context=None):
  579. return self._get_html()
  580. class ReportJournalLedgerJournal(models.TransientModel):
  581. _name = 'report_journal_ledger_journal'
  582. name = fields.Char(
  583. required=True,
  584. )
  585. code = fields.Char()
  586. report_id = fields.Many2one(
  587. comodel_name='report_journal_ledger',
  588. required=True,
  589. ondelete='cascade'
  590. )
  591. journal_id = fields.Many2one(
  592. comodel_name='account.journal',
  593. required=True,
  594. ondelete='cascade',
  595. )
  596. report_move_ids = fields.One2many(
  597. comodel_name='report_journal_ledger_move',
  598. inverse_name='report_journal_ledger_id',
  599. )
  600. report_tax_line_ids = fields.One2many(
  601. comodel_name='report_journal_ledger_journal_tax_line',
  602. inverse_name='report_journal_ledger_id',
  603. )
  604. debit = fields.Float(
  605. digits=DIGITS,
  606. )
  607. credit = fields.Float(
  608. digits=DIGITS,
  609. )
  610. company_id = fields.Many2one(
  611. comodel_name='res.company',
  612. required=True,
  613. ondelete='cascade'
  614. )
  615. currency_id = fields.Many2one(
  616. comodel_name='res.currency',
  617. )
  618. class ReportJournalLedgerMove(models.TransientModel):
  619. _name = 'report_journal_ledger_move'
  620. report_id = fields.Many2one(
  621. comodel_name='report_journal_ledger',
  622. required=True,
  623. ondelete='cascade'
  624. )
  625. report_journal_ledger_id = fields.Many2one(
  626. comodel_name='report_journal_ledger_journal',
  627. required=True,
  628. ondelete='cascade',
  629. )
  630. move_id = fields.Many2one(
  631. comodel_name='account.move',
  632. required=True,
  633. ondelete='cascade',
  634. )
  635. report_move_line_ids = fields.One2many(
  636. comodel_name='report_journal_ledger_move_line',
  637. inverse_name='report_move_id',
  638. )
  639. name = fields.Char()
  640. company_id = fields.Many2one(
  641. comodel_name='res.company',
  642. required=True,
  643. ondelete='cascade'
  644. )
  645. class ReportJournalLedgerMoveLine(models.TransientModel):
  646. _name = 'report_journal_ledger_move_line'
  647. _order = 'partner_id desc, account_id desc'
  648. report_id = fields.Many2one(
  649. comodel_name='report_journal_ledger',
  650. required=True,
  651. ondelete='cascade'
  652. )
  653. report_journal_ledger_id = fields.Many2one(
  654. comodel_name='report_journal_ledger_journal',
  655. required=True,
  656. ondelete='cascade',
  657. )
  658. report_move_id = fields.Many2one(
  659. comodel_name='report_journal_ledger_move',
  660. required=True,
  661. ondelete='cascade',
  662. )
  663. move_line_id = fields.Many2one(
  664. comodel_name='account.move.line',
  665. required=True,
  666. ondelete='cascade',
  667. )
  668. account_id = fields.Many2one(
  669. comodel_name='account.account'
  670. )
  671. account = fields.Char()
  672. account_code = fields.Char()
  673. account_type = fields.Char()
  674. partner = fields.Char()
  675. partner_id = fields.Many2one(
  676. comodel_name='res.partner',
  677. )
  678. date = fields.Date()
  679. entry = fields.Char()
  680. label = fields.Char()
  681. debit = fields.Float(
  682. digits=DIGITS,
  683. )
  684. credit = fields.Float(
  685. digits=DIGITS,
  686. )
  687. company_currency_id = fields.Many2one(
  688. comodel_name='res.currency',
  689. )
  690. amount_currency = fields.Monetary(
  691. currency_field='currency_id',
  692. )
  693. currency_id = fields.Many2one(
  694. comodel_name='res.currency',
  695. )
  696. currency_name = fields.Char()
  697. taxes_description = fields.Char()
  698. tax_id = fields.Many2one(
  699. comodel_name='account.tax'
  700. )
  701. company_id = fields.Many2one(
  702. comodel_name='res.company',
  703. required=True,
  704. ondelete='cascade'
  705. )
  706. class ReportJournalLedgerReportTaxLine(models.TransientModel):
  707. _name = 'report_journal_ledger_report_tax_line'
  708. _order = 'tax_code'
  709. report_id = fields.Many2one(
  710. comodel_name='report_journal_ledger',
  711. required=True,
  712. ondelete='cascade'
  713. )
  714. tax_id = fields.Many2one(
  715. comodel_name='account.tax'
  716. )
  717. tax_name = fields.Char()
  718. tax_code = fields.Char()
  719. base_debit = fields.Float(
  720. digits=DIGITS,
  721. )
  722. base_credit = fields.Float(
  723. digits=DIGITS,
  724. )
  725. base_balance = fields.Float(
  726. digits=DIGITS,
  727. compute='_compute_base_balance',
  728. )
  729. tax_debit = fields.Float(
  730. digits=DIGITS,
  731. )
  732. tax_credit = fields.Float(
  733. digits=DIGITS,
  734. )
  735. tax_balance = fields.Float(
  736. digits=DIGITS,
  737. compute='_compute_tax_balance'
  738. )
  739. @api.multi
  740. def _compute_base_balance(self):
  741. for rec in self:
  742. rec.base_balance = rec.base_debit - rec.base_credit
  743. @api.multi
  744. def _compute_tax_balance(self):
  745. for rec in self:
  746. rec.tax_balance = rec.tax_debit - rec.tax_credit
  747. class ReportJournalLedgerJournalTaxLine(models.TransientModel):
  748. _name = 'report_journal_ledger_journal_tax_line'
  749. _inherit = 'report_journal_ledger_report_tax_line'
  750. _order = 'tax_code'
  751. report_journal_ledger_id = fields.Many2one(
  752. comodel_name='report_journal_ledger_journal',
  753. required=True,
  754. ondelete='cascade',
  755. )