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.

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