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.

550 lines
16 KiB

  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 AgedPartnerBalanceReport(models.TransientModel):
  6. """ Here, we just define class fields.
  7. For methods, go more bottom at this file.
  8. """
  9. _name = 'report_aged_partner_balance_qweb'
  10. date_at = fields.Date()
  11. only_posted_moves = fields.Boolean()
  12. company_id = fields.Many2one(comodel_name='res.company')
  13. filter_account_ids = fields.Many2many(comodel_name='account.account')
  14. filter_partner_ids = fields.Many2many(comodel_name='res.partner')
  15. show_move_line_details = fields.Boolean()
  16. open_invoice_id = fields.Many2one(comodel_name='report_open_invoice_qweb')
  17. account_ids = fields.One2many(
  18. comodel_name='report_aged_partner_balance_qweb_account',
  19. inverse_name='report_id'
  20. )
  21. class AgedPartnerBalanceAccount(models.TransientModel):
  22. _name = 'report_aged_partner_balance_qweb_account'
  23. _order = 'code ASC'
  24. report_id = fields.Many2one(
  25. comodel_name='report_aged_partner_balance_qweb',
  26. ondelete='cascade',
  27. index=True
  28. )
  29. account_id = fields.Many2one(
  30. 'account.account',
  31. index=True
  32. )
  33. code = fields.Char()
  34. name = fields.Char()
  35. cumul_amount_residual = fields.Float(digits=(16, 2))
  36. cumul_current = fields.Float(digits=(16, 2))
  37. cumul_age_30_days = fields.Float(digits=(16, 2))
  38. cumul_age_60_days = fields.Float(digits=(16, 2))
  39. cumul_age_90_days = fields.Float(digits=(16, 2))
  40. cumul_age_120_days = fields.Float(digits=(16, 2))
  41. cumul_older = fields.Float(digits=(16, 2))
  42. percent_current = fields.Float(digits=(16, 2))
  43. percent_age_30_days = fields.Float(digits=(16, 2))
  44. percent_age_60_days = fields.Float(digits=(16, 2))
  45. percent_age_90_days = fields.Float(digits=(16, 2))
  46. percent_age_120_days = fields.Float(digits=(16, 2))
  47. percent_older = fields.Float(digits=(16, 2))
  48. partner_ids = fields.One2many(
  49. comodel_name='report_aged_partner_balance_qweb_partner',
  50. inverse_name='report_account_id'
  51. )
  52. class AgedPartnerBalancePartner(models.TransientModel):
  53. _name = 'report_aged_partner_balance_qweb_partner'
  54. report_account_id = fields.Many2one(
  55. comodel_name='report_aged_partner_balance_qweb_account',
  56. ondelete='cascade',
  57. index=True
  58. )
  59. partner_id = fields.Many2one(
  60. 'res.partner',
  61. index=True
  62. )
  63. name = fields.Char()
  64. move_line_ids = fields.One2many(
  65. comodel_name='report_aged_partner_balance_qweb_move_line',
  66. inverse_name='report_partner_id'
  67. )
  68. line_ids = fields.One2many(
  69. comodel_name='report_aged_partner_balance_qweb_line',
  70. inverse_name='report_partner_id'
  71. )
  72. @api.model
  73. def _generate_order_by(self, order_spec, query):
  74. return """
  75. ORDER BY
  76. CASE
  77. WHEN "report_aged_partner_balance_qweb_partner"."partner_id" IS NOT NULL
  78. THEN 0
  79. ELSE 1
  80. END,
  81. "report_aged_partner_balance_qweb_partner"."name"
  82. """
  83. class AgedPartnerBalanceLine(models.TransientModel):
  84. _name = 'report_aged_partner_balance_qweb_line'
  85. report_partner_id = fields.Many2one(
  86. comodel_name='report_aged_partner_balance_qweb_partner',
  87. ondelete='cascade',
  88. index=True
  89. )
  90. partner = fields.Char()
  91. amount_residual = fields.Float(digits=(16, 2))
  92. current = fields.Float(digits=(16, 2))
  93. age_30_days = fields.Float(digits=(16, 2))
  94. age_60_days = fields.Float(digits=(16, 2))
  95. age_90_days = fields.Float(digits=(16, 2))
  96. age_120_days = fields.Float(digits=(16, 2))
  97. older = fields.Float(digits=(16, 2))
  98. class AgedPartnerBalanceMoveLine(models.TransientModel):
  99. _name = 'report_aged_partner_balance_qweb_move_line'
  100. report_partner_id = fields.Many2one(
  101. comodel_name='report_aged_partner_balance_qweb_partner',
  102. ondelete='cascade',
  103. index=True
  104. )
  105. move_line_id = fields.Many2one('account.move.line')
  106. date = fields.Date()
  107. date_due = fields.Date()
  108. entry = fields.Char()
  109. journal = fields.Char()
  110. account = fields.Char()
  111. partner = fields.Char()
  112. label = fields.Char()
  113. amount_residual = fields.Float(digits=(16, 2))
  114. current = fields.Float(digits=(16, 2))
  115. age_30_days = fields.Float(digits=(16, 2))
  116. age_60_days = fields.Float(digits=(16, 2))
  117. age_90_days = fields.Float(digits=(16, 2))
  118. age_120_days = fields.Float(digits=(16, 2))
  119. older = fields.Float(digits=(16, 2))
  120. class AgedPartnerBalanceReportCompute(models.TransientModel):
  121. _inherit = 'report_aged_partner_balance_qweb'
  122. @api.model
  123. def print_report(self):
  124. self.ensure_one()
  125. self.compute_data_for_report()
  126. return {
  127. 'type': 'ir.actions.report.xml',
  128. 'report_name':
  129. 'account_financial_report_qweb.'
  130. 'report_aged_partner_balance_qweb',
  131. 'datas': {'ids': [self.id]},
  132. }
  133. @api.model
  134. def compute_data_for_report(self):
  135. self.ensure_one()
  136. model = self.env['report_open_invoice_qweb']
  137. self.open_invoice_id = model.create({
  138. 'date_at': self.date_at,
  139. 'only_posted_moves': self.only_posted_moves,
  140. 'company_id': self.company_id.id,
  141. 'filter_account_ids': [(6, 0, self.filter_account_ids.ids)],
  142. 'filter_partner_ids': [(6, 0, self.filter_partner_ids.ids)],
  143. })
  144. self.open_invoice_id.compute_data_for_report()
  145. self.inject_account_values()
  146. self.inject_partner_values()
  147. self.inject_line_values()
  148. self.inject_line_values(only_empty_partner_line=True)
  149. if self.show_move_line_details:
  150. self.inject_move_line_values()
  151. self.inject_move_line_values(only_empty_partner_line=True)
  152. self.compute_accounts_cumul()
  153. def inject_account_values(self):
  154. query_inject_account = """
  155. INSERT INTO
  156. report_aged_partner_balance_qweb_account
  157. (
  158. report_id,
  159. create_uid,
  160. create_date,
  161. account_id,
  162. code,
  163. name
  164. )
  165. SELECT
  166. %s AS report_id,
  167. %s AS create_uid,
  168. NOW() AS create_date,
  169. rao.account_id,
  170. rao.code,
  171. rao.name
  172. FROM
  173. report_open_invoice_qweb_account rao
  174. WHERE
  175. rao.report_id = %s
  176. """
  177. query_inject_account_params = (
  178. self.id,
  179. self.env.uid,
  180. self.open_invoice_id.id,
  181. )
  182. self.env.cr.execute(query_inject_account, query_inject_account_params)
  183. def inject_partner_values(self):
  184. query_inject_partner = """
  185. INSERT INTO
  186. report_aged_partner_balance_qweb_partner
  187. (
  188. report_account_id,
  189. create_uid,
  190. create_date,
  191. partner_id,
  192. name
  193. )
  194. SELECT
  195. ra.id AS report_account_id,
  196. %s AS create_uid,
  197. NOW() AS create_date,
  198. rpo.partner_id,
  199. rpo.name
  200. FROM
  201. report_open_invoice_qweb_partner rpo
  202. INNER JOIN
  203. report_open_invoice_qweb_account rao ON rpo.report_account_id = rao.id
  204. INNER JOIN
  205. report_aged_partner_balance_qweb_account ra ON rao.code = ra.code
  206. WHERE
  207. rao.report_id = %s
  208. AND ra.report_id = %s
  209. """
  210. query_inject_partner_params = (
  211. self.env.uid,
  212. self.open_invoice_id.id,
  213. self.id,
  214. )
  215. self.env.cr.execute(query_inject_partner, query_inject_partner_params)
  216. def inject_line_values(self, only_empty_partner_line=False):
  217. query_inject_line = """
  218. WITH
  219. date_range AS
  220. (
  221. SELECT
  222. %s AS date_current,
  223. DATE %s - INTEGER '30' AS date_less_30_days,
  224. DATE %s - INTEGER '60' AS date_less_60_days,
  225. DATE %s - INTEGER '90' AS date_less_90_days,
  226. DATE %s - INTEGER '120' AS date_less_120_days,
  227. DATE %s - INTEGER '150' AS date_older
  228. )
  229. INSERT INTO
  230. report_aged_partner_balance_qweb_line
  231. (
  232. report_partner_id,
  233. partner,
  234. amount_residual,
  235. current,
  236. age_30_days,
  237. age_60_days,
  238. age_90_days,
  239. age_120_days,
  240. older
  241. )
  242. SELECT
  243. rp.id AS report_partner_id,
  244. rp.name,
  245. SUM(rlo.amount_residual) AS amount_residual,
  246. SUM(
  247. CASE
  248. WHEN rlo.date_due > date_range.date_less_30_days
  249. THEN rlo.amount_residual
  250. END
  251. ) AS current,
  252. SUM(
  253. CASE
  254. WHEN
  255. rlo.date_due > date_range.date_less_60_days
  256. AND rlo.date_due <= date_range.date_less_30_days
  257. THEN rlo.amount_residual
  258. END
  259. ) AS age_30_days,
  260. SUM(
  261. CASE
  262. WHEN
  263. rlo.date_due > date_range.date_less_90_days
  264. AND rlo.date_due <= date_range.date_less_60_days
  265. THEN rlo.amount_residual
  266. END
  267. ) AS age_60_days,
  268. SUM(
  269. CASE
  270. WHEN
  271. rlo.date_due > date_range.date_less_120_days
  272. AND rlo.date_due <= date_range.date_less_90_days
  273. THEN rlo.amount_residual
  274. END
  275. ) AS age_90_days,
  276. SUM(
  277. CASE
  278. WHEN
  279. rlo.date_due > date_range.date_older
  280. AND rlo.date_due <= date_range.date_less_120_days
  281. THEN rlo.amount_residual
  282. END
  283. ) AS age_120_days,
  284. SUM(
  285. CASE
  286. WHEN rlo.date_due <= date_range.date_older
  287. THEN rlo.amount_residual
  288. END
  289. ) AS older
  290. FROM
  291. date_range,
  292. report_open_invoice_qweb_move_line rlo
  293. INNER JOIN
  294. report_open_invoice_qweb_partner rpo ON rlo.report_partner_id = rpo.id
  295. INNER JOIN
  296. report_open_invoice_qweb_account rao ON rpo.report_account_id = rao.id
  297. INNER JOIN
  298. report_aged_partner_balance_qweb_account ra ON rao.code = ra.code
  299. INNER JOIN
  300. report_aged_partner_balance_qweb_partner rp
  301. ON
  302. ra.id = rp.report_account_id
  303. """
  304. if not only_empty_partner_line:
  305. query_inject_line += """
  306. AND rpo.partner_id = rp.partner_id
  307. """
  308. elif only_empty_partner_line:
  309. query_inject_line += """
  310. AND rpo.partner_id IS NULL
  311. AND rp.partner_id IS NULL
  312. """
  313. query_inject_line += """
  314. WHERE
  315. rao.report_id = %s
  316. AND ra.report_id = %s
  317. GROUP BY
  318. rp.id
  319. """
  320. query_inject_line_params = (self.date_at,) * 6
  321. query_inject_line_params += (
  322. self.open_invoice_id.id,
  323. self.id,
  324. )
  325. self.env.cr.execute(query_inject_line, query_inject_line_params)
  326. def inject_move_line_values(self, only_empty_partner_line=False):
  327. query_inject_move_line = """
  328. WITH
  329. date_range AS
  330. (
  331. SELECT
  332. %s AS date_current,
  333. DATE %s - INTEGER '30' AS date_less_30_days,
  334. DATE %s - INTEGER '60' AS date_less_60_days,
  335. DATE %s - INTEGER '90' AS date_less_90_days,
  336. DATE %s - INTEGER '120' AS date_less_120_days,
  337. DATE %s - INTEGER '150' AS date_older
  338. )
  339. INSERT INTO
  340. report_aged_partner_balance_qweb_move_line
  341. (
  342. report_partner_id,
  343. date,
  344. date_due,
  345. entry,
  346. journal,
  347. account,
  348. partner,
  349. label,
  350. amount_residual,
  351. current,
  352. age_30_days,
  353. age_60_days,
  354. age_90_days,
  355. age_120_days,
  356. older
  357. )
  358. SELECT
  359. rp.id AS report_partner_id,
  360. rlo.date,
  361. rlo.date_due,
  362. rlo.entry,
  363. rlo.journal,
  364. rlo.account,
  365. rlo.partner,
  366. rlo.label,
  367. rlo.amount_residual AS amount_residual,
  368. CASE
  369. WHEN rlo.date_due > date_range.date_less_30_days
  370. THEN rlo.amount_residual
  371. END AS current,
  372. CASE
  373. WHEN
  374. rlo.date_due > date_range.date_less_60_days
  375. AND rlo.date_due <= date_range.date_less_30_days
  376. THEN rlo.amount_residual
  377. END AS age_30_days,
  378. CASE
  379. WHEN
  380. rlo.date_due > date_range.date_less_90_days
  381. AND rlo.date_due <= date_range.date_less_60_days
  382. THEN rlo.amount_residual
  383. END AS age_60_days,
  384. CASE
  385. WHEN
  386. rlo.date_due > date_range.date_less_120_days
  387. AND rlo.date_due <= date_range.date_less_90_days
  388. THEN rlo.amount_residual
  389. END AS age_90_days,
  390. CASE
  391. WHEN
  392. rlo.date_due > date_range.date_older
  393. AND rlo.date_due <= date_range.date_less_120_days
  394. THEN rlo.amount_residual
  395. END AS age_120_days,
  396. CASE
  397. WHEN rlo.date_due <= date_range.date_older
  398. THEN rlo.amount_residual
  399. END AS older
  400. FROM
  401. date_range,
  402. report_open_invoice_qweb_move_line rlo
  403. INNER JOIN
  404. report_open_invoice_qweb_partner rpo ON rlo.report_partner_id = rpo.id
  405. INNER JOIN
  406. report_open_invoice_qweb_account rao ON rpo.report_account_id = rao.id
  407. INNER JOIN
  408. report_aged_partner_balance_qweb_account ra ON rao.code = ra.code
  409. INNER JOIN
  410. report_aged_partner_balance_qweb_partner rp
  411. ON
  412. ra.id = rp.report_account_id
  413. """
  414. if not only_empty_partner_line:
  415. query_inject_move_line += """
  416. AND rpo.partner_id = rp.partner_id
  417. """
  418. elif only_empty_partner_line:
  419. query_inject_move_line += """
  420. AND rpo.partner_id IS NULL
  421. AND rp.partner_id IS NULL
  422. """
  423. query_inject_move_line += """
  424. WHERE
  425. rao.report_id = %s
  426. AND ra.report_id = %s
  427. """
  428. query_inject_move_line_params = (self.date_at,) * 6
  429. query_inject_move_line_params += (
  430. self.open_invoice_id.id,
  431. self.id,
  432. )
  433. self.env.cr.execute(query_inject_move_line,
  434. query_inject_move_line_params)
  435. def compute_accounts_cumul(self):
  436. query_compute_accounts_cumul = """
  437. WITH
  438. cumuls AS
  439. (
  440. SELECT
  441. ra.id AS report_account_id,
  442. SUM(rl.amount_residual) AS cumul_amount_residual,
  443. SUM(rl.current) AS cumul_current,
  444. SUM(rl.age_30_days) AS cumul_age_30_days,
  445. SUM(rl.age_60_days) AS cumul_age_60_days,
  446. SUM(rl.age_90_days) AS cumul_age_90_days,
  447. SUM(rl.age_120_days) AS cumul_age_120_days,
  448. SUM(rl.older) AS cumul_older
  449. FROM
  450. report_aged_partner_balance_qweb_line rl
  451. INNER JOIN
  452. report_aged_partner_balance_qweb_partner rp
  453. ON rl.report_partner_id = rp.id
  454. INNER JOIN
  455. report_aged_partner_balance_qweb_account ra
  456. ON rp.report_account_id = ra.id
  457. WHERE
  458. ra.report_id = %s
  459. GROUP BY
  460. ra.id
  461. )
  462. UPDATE
  463. report_aged_partner_balance_qweb_account
  464. SET
  465. cumul_amount_residual = c.cumul_amount_residual,
  466. cumul_current = c.cumul_current,
  467. cumul_age_30_days = c.cumul_age_30_days,
  468. cumul_age_60_days = c.cumul_age_60_days,
  469. cumul_age_90_days = c.cumul_age_90_days,
  470. cumul_age_120_days = c.cumul_age_120_days,
  471. cumul_older = c.cumul_older,
  472. percent_current =
  473. CASE
  474. WHEN c.cumul_amount_residual != 0
  475. THEN 100 * c.cumul_current / c.cumul_amount_residual
  476. END,
  477. percent_age_30_days =
  478. CASE
  479. WHEN c.cumul_amount_residual != 0
  480. THEN 100 * c.cumul_age_30_days / c.cumul_amount_residual
  481. END,
  482. percent_age_60_days =
  483. CASE
  484. WHEN c.cumul_amount_residual != 0
  485. THEN 100 * c.cumul_age_60_days / c.cumul_amount_residual
  486. END,
  487. percent_age_90_days =
  488. CASE
  489. WHEN c.cumul_amount_residual != 0
  490. THEN 100 * c.cumul_age_90_days / c.cumul_amount_residual
  491. END,
  492. percent_age_120_days =
  493. CASE
  494. WHEN c.cumul_amount_residual != 0
  495. THEN 100 * c.cumul_age_120_days / c.cumul_amount_residual
  496. END,
  497. percent_older =
  498. CASE
  499. WHEN c.cumul_amount_residual != 0
  500. THEN 100 * c.cumul_older / c.cumul_amount_residual
  501. END
  502. FROM
  503. cumuls c
  504. WHERE
  505. id = c.report_account_id
  506. """
  507. params_compute_accounts_cumul = (self.id,)
  508. self.env.cr.execute(query_compute_accounts_cumul,
  509. params_compute_accounts_cumul)