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.

822 lines
24 KiB

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