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.

829 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. coalesce(t.value, 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. ir_translation t
  318. ON
  319. aa.id = t.res_id
  320. AND t.name = 'account.account,name'
  321. AND t.lang = %s
  322. LEFT JOIN
  323. res_partner p
  324. on (p.id = aml.partner_id)
  325. LEFT JOIN
  326. account_tax at
  327. on (at.id = aml.tax_line_id)
  328. LEFT JOIN
  329. res_currency currency
  330. on (currency.id = aml.currency_id)
  331. WHERE
  332. rjqm.report_id = %s
  333. """
  334. params = (
  335. self.env.uid,
  336. self.env.user.lang,
  337. self.id,
  338. )
  339. self.env.cr.execute(sql, params)
  340. @api.multi
  341. def _inject_report_tax_values(self):
  342. self.ensure_one()
  343. sql_distinct_tax_id = """
  344. SELECT
  345. distinct(jrqjtl.tax_id)
  346. FROM
  347. report_journal_qweb_journal_tax_line jrqjtl
  348. WHERE
  349. jrqjtl.report_id = %s
  350. """
  351. self.env.cr.execute(sql_distinct_tax_id, (self.id,))
  352. rows = self.env.cr.fetchall()
  353. tax_ids = set([row[0] for row in rows])
  354. sql = """
  355. INSERT INTO report_journal_qweb_report_tax_line (
  356. create_uid,
  357. create_date,
  358. report_id,
  359. tax_id,
  360. tax_name,
  361. tax_code,
  362. base_debit,
  363. base_credit,
  364. tax_debit,
  365. tax_credit
  366. )
  367. SELECT
  368. %s as create_uid,
  369. NOW() as create_date,
  370. %s as report_id,
  371. %s as tax_id,
  372. at.name as tax_name,
  373. at.description as tax_code,
  374. (
  375. SELECT sum(base_debit)
  376. FROM report_journal_qweb_journal_tax_line jrqjtl2
  377. WHERE jrqjtl2.report_id = %s
  378. AND jrqjtl2.tax_id = %s
  379. ) as base_debit,
  380. (
  381. SELECT sum(base_credit)
  382. FROM report_journal_qweb_journal_tax_line jrqjtl2
  383. WHERE jrqjtl2.report_id = %s
  384. AND jrqjtl2.tax_id = %s
  385. ) as base_credit,
  386. (
  387. SELECT sum(tax_debit)
  388. FROM report_journal_qweb_journal_tax_line jrqjtl2
  389. WHERE jrqjtl2.report_id = %s
  390. AND jrqjtl2.tax_id = %s
  391. ) as tax_debit,
  392. (
  393. SELECT sum(tax_credit)
  394. FROM report_journal_qweb_journal_tax_line jrqjtl2
  395. WHERE jrqjtl2.report_id = %s
  396. AND jrqjtl2.tax_id = %s
  397. ) as tax_credit
  398. FROM
  399. report_journal_qweb_journal_tax_line jrqjtl
  400. LEFT JOIN
  401. account_tax at
  402. on (at.id = jrqjtl.tax_id)
  403. WHERE
  404. jrqjtl.report_id = %s
  405. AND
  406. jrqjtl.tax_id = %s
  407. """
  408. for tax_id in tax_ids:
  409. params = (
  410. self.env.uid,
  411. self.id,
  412. tax_id,
  413. self.id,
  414. tax_id,
  415. self.id,
  416. tax_id,
  417. self.id,
  418. tax_id,
  419. self.id,
  420. tax_id,
  421. self.id,
  422. tax_id,
  423. )
  424. self.env.cr.execute(sql, params)
  425. @api.multi
  426. def _inject_journal_tax_values(self):
  427. self.ensure_one()
  428. sql = """
  429. DELETE
  430. FROM report_journal_qweb_journal_tax_line
  431. WHERE report_id = %s
  432. """
  433. params = (
  434. self.id,
  435. )
  436. self.env.cr.execute(sql, params)
  437. sql_distinct_tax_id = """
  438. SELECT
  439. distinct(jrqml.tax_id)
  440. FROM
  441. report_journal_qweb_move_line jrqml
  442. WHERE
  443. jrqml.report_journal_id = %s
  444. """
  445. tax_ids_by_journal_id = {}
  446. for report_journal in self.report_journal_ids:
  447. if report_journal.id not in tax_ids_by_journal_id:
  448. tax_ids_by_journal_id[report_journal.id] = []
  449. self.env.cr.execute(sql_distinct_tax_id, (report_journal.id,))
  450. rows = self.env.cr.fetchall()
  451. tax_ids_by_journal_id[report_journal.id].extend([
  452. row[0] for row in rows if row[0]
  453. ])
  454. sql = """
  455. INSERT INTO report_journal_qweb_journal_tax_line (
  456. create_uid,
  457. create_date,
  458. report_id,
  459. report_journal_id,
  460. tax_id,
  461. tax_name,
  462. tax_code,
  463. base_debit,
  464. base_credit,
  465. tax_debit,
  466. tax_credit
  467. )
  468. SELECT
  469. %s as create_uid,
  470. NOW() as create_date,
  471. %s as report_id,
  472. %s as report_journal_id,
  473. %s as tax_id,
  474. at.name as tax_name,
  475. at.description as tax_code,
  476. (
  477. SELECT sum(debit)
  478. FROM report_journal_qweb_move_line jrqml2
  479. WHERE jrqml2.report_journal_id = %s
  480. AND (
  481. SELECT
  482. count(*)
  483. FROM
  484. account_move_line_account_tax_rel aml_at_rel
  485. WHERE
  486. aml_at_rel.account_move_line_id =
  487. jrqml2.move_line_id
  488. AND
  489. aml_at_rel.account_tax_id = %s
  490. ) > 0
  491. ) as base_debit,
  492. (
  493. SELECT sum(credit)
  494. FROM report_journal_qweb_move_line jrqml2
  495. WHERE jrqml2.report_journal_id = %s
  496. AND (
  497. SELECT
  498. count(*)
  499. FROM
  500. account_move_line_account_tax_rel aml_at_rel
  501. WHERE
  502. aml_at_rel.account_move_line_id =
  503. jrqml2.move_line_id
  504. AND
  505. aml_at_rel.account_tax_id = %s
  506. ) > 0
  507. ) as base_credit,
  508. (
  509. SELECT sum(debit)
  510. FROM report_journal_qweb_move_line jrqml2
  511. WHERE jrqml2.report_journal_id = %s
  512. AND jrqml2.tax_id = %s
  513. ) as tax_debit,
  514. (
  515. SELECT sum(credit)
  516. FROM report_journal_qweb_move_line jrqml2
  517. WHERE jrqml2.report_journal_id = %s
  518. AND jrqml2.tax_id = %s
  519. ) as tax_credit
  520. FROM
  521. report_journal_qweb_journal rjqj
  522. LEFT JOIN
  523. account_tax at
  524. on (at.id = %s)
  525. WHERE
  526. rjqj.id = %s
  527. """
  528. for report_journal_id in tax_ids_by_journal_id:
  529. tax_ids = tax_ids_by_journal_id[report_journal_id]
  530. for tax_id in tax_ids:
  531. params = (
  532. self.env.uid,
  533. self.id,
  534. report_journal_id,
  535. tax_id,
  536. report_journal_id,
  537. tax_id,
  538. report_journal_id,
  539. tax_id,
  540. report_journal_id,
  541. tax_id,
  542. report_journal_id,
  543. tax_id,
  544. tax_id,
  545. report_journal_id,
  546. )
  547. self.env.cr.execute(sql, params)
  548. @api.multi
  549. def _update_journal_report_total_values(self):
  550. self.ensure_one()
  551. sql = """
  552. UPDATE
  553. report_journal_qweb_journal rjqj
  554. SET
  555. debit = (
  556. SELECT sum(rjqml.debit)
  557. FROM report_journal_qweb_move_line rjqml
  558. WHERE rjqml.report_journal_id = rjqj.id
  559. ),
  560. credit = (
  561. SELECT sum(rjqml.credit)
  562. FROM report_journal_qweb_move_line rjqml
  563. WHERE rjqml.report_journal_id = rjqj.id
  564. )
  565. WHERE
  566. rjqj.report_id = %s
  567. """
  568. self.env.cr.execute(sql, (self.id,))
  569. @api.multi
  570. def print_report(self, report_type):
  571. self.ensure_one()
  572. if report_type == 'xlsx':
  573. report_name = 'account_financial_report_qweb.' \
  574. 'report_journal_xlsx'
  575. else:
  576. report_name = 'account_financial_report_qweb.' \
  577. 'report_journal_qweb'
  578. return self.env['report'].get_action(
  579. docids=self.ids, report_name=report_name)
  580. def _get_html(self):
  581. result = {}
  582. rcontext = {}
  583. context = dict(self.env.context)
  584. report = self.browse(context.get('active_id'))
  585. if report:
  586. rcontext['o'] = report
  587. result['html'] = self.env.ref(
  588. 'account_financial_report_qweb.'
  589. 'report_journal_html').render(rcontext)
  590. return result
  591. @api.model
  592. def get_html(self, given_context=None):
  593. return self._get_html()
  594. class ReportJournalQwebJournal(models.TransientModel):
  595. _name = 'report_journal_qweb_journal'
  596. _inherit = 'report_qweb_abstract'
  597. name = fields.Char(
  598. required=True,
  599. )
  600. code = fields.Char()
  601. report_id = fields.Many2one(
  602. comodel_name='report_journal_qweb',
  603. required=True,
  604. ondelete='cascade'
  605. )
  606. journal_id = fields.Many2one(
  607. comodel_name='account.journal',
  608. required=True,
  609. ondelete='cascade',
  610. )
  611. report_move_ids = fields.One2many(
  612. comodel_name='report_journal_qweb_move',
  613. inverse_name='report_journal_id',
  614. )
  615. report_tax_line_ids = fields.One2many(
  616. comodel_name='report_journal_qweb_journal_tax_line',
  617. inverse_name='report_journal_id',
  618. )
  619. debit = fields.Float(
  620. digits=DIGITS,
  621. )
  622. credit = fields.Float(
  623. digits=DIGITS,
  624. )
  625. company_id = fields.Many2one(
  626. comodel_name='res.company',
  627. required=True,
  628. ondelete='cascade'
  629. )
  630. currency_id = fields.Many2one(
  631. comodel_name='res.currency',
  632. )
  633. class ReportJournalQwebMove(models.TransientModel):
  634. _name = 'report_journal_qweb_move'
  635. _inherit = 'report_qweb_abstract'
  636. report_id = fields.Many2one(
  637. comodel_name='report_journal_qweb',
  638. required=True,
  639. ondelete='cascade'
  640. )
  641. report_journal_id = fields.Many2one(
  642. comodel_name='report_journal_qweb_journal',
  643. required=True,
  644. ondelete='cascade',
  645. )
  646. move_id = fields.Many2one(
  647. comodel_name='account.move',
  648. required=True,
  649. ondelete='cascade',
  650. )
  651. report_move_line_ids = fields.One2many(
  652. comodel_name='report_journal_qweb_move_line',
  653. inverse_name='report_move_id',
  654. )
  655. name = fields.Char()
  656. company_id = fields.Many2one(
  657. comodel_name='res.company',
  658. required=True,
  659. ondelete='cascade'
  660. )
  661. class ReportJournalQwebMoveLine(models.TransientModel):
  662. _name = 'report_journal_qweb_move_line'
  663. _inherit = 'report_qweb_abstract'
  664. _order = 'partner_id desc, account_id desc'
  665. report_id = fields.Many2one(
  666. comodel_name='report_journal_qweb',
  667. required=True,
  668. ondelete='cascade'
  669. )
  670. report_journal_id = fields.Many2one(
  671. comodel_name='report_journal_qweb_journal',
  672. required=True,
  673. ondelete='cascade',
  674. )
  675. report_move_id = fields.Many2one(
  676. comodel_name='report_journal_qweb_move',
  677. required=True,
  678. ondelete='cascade',
  679. )
  680. move_line_id = fields.Many2one(
  681. comodel_name='account.move.line',
  682. required=True,
  683. ondelete='cascade',
  684. )
  685. account_id = fields.Many2one(
  686. comodel_name='account.account'
  687. )
  688. account = fields.Char()
  689. account_code = fields.Char()
  690. account_type = fields.Char()
  691. partner = fields.Char()
  692. partner_id = fields.Many2one(
  693. comodel_name='res.partner',
  694. )
  695. date = fields.Date()
  696. entry = fields.Char()
  697. label = fields.Char()
  698. debit = fields.Float(
  699. digits=DIGITS,
  700. )
  701. credit = fields.Float(
  702. digits=DIGITS,
  703. )
  704. company_currency_id = fields.Many2one(
  705. comodel_name='res.currency',
  706. )
  707. amount_currency = fields.Monetary(
  708. currency_field='currency_id',
  709. )
  710. currency_id = fields.Many2one(
  711. comodel_name='res.currency',
  712. )
  713. currency_name = fields.Char()
  714. taxes_description = fields.Char()
  715. tax_id = fields.Many2one(
  716. comodel_name='account.tax'
  717. )
  718. company_id = fields.Many2one(
  719. comodel_name='res.company',
  720. required=True,
  721. ondelete='cascade'
  722. )
  723. class ReportJournalQwebReportTaxLine(models.TransientModel):
  724. _name = 'report_journal_qweb_report_tax_line'
  725. _inherit = 'report_qweb_abstract'
  726. _order = 'tax_code'
  727. report_id = fields.Many2one(
  728. comodel_name='report_journal_qweb',
  729. required=True,
  730. ondelete='cascade'
  731. )
  732. tax_id = fields.Many2one(
  733. comodel_name='account.tax'
  734. )
  735. tax_name = fields.Char()
  736. tax_code = fields.Char()
  737. base_debit = fields.Float(
  738. digits=DIGITS,
  739. )
  740. base_credit = fields.Float(
  741. digits=DIGITS,
  742. )
  743. base_balance = fields.Float(
  744. digits=DIGITS,
  745. compute='_compute_base_balance',
  746. )
  747. tax_debit = fields.Float(
  748. digits=DIGITS,
  749. )
  750. tax_credit = fields.Float(
  751. digits=DIGITS,
  752. )
  753. tax_balance = fields.Float(
  754. digits=DIGITS,
  755. compute='_compute_tax_balance'
  756. )
  757. @api.multi
  758. def _compute_base_balance(self):
  759. for rec in self:
  760. rec.base_balance = rec.base_debit - rec.base_credit
  761. @api.multi
  762. def _compute_tax_balance(self):
  763. for rec in self:
  764. rec.tax_balance = rec.tax_debit - rec.tax_credit
  765. class ReportJournalQwebJournalTaxLine(models.TransientModel):
  766. _name = 'report_journal_qweb_journal_tax_line'
  767. _inherit = 'report_journal_qweb_report_tax_line'
  768. _order = 'tax_code'
  769. report_journal_id = fields.Many2one(
  770. comodel_name='report_journal_qweb_journal',
  771. required=True,
  772. ondelete='cascade',
  773. )