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.

722 lines
29 KiB

  1. # © 2016 Julien Coux (Camptocamp)
  2. # Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com)
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. import calendar
  5. import datetime
  6. from odoo import api, models
  7. class GeneralLedgerReport(models.AbstractModel):
  8. _name = "report.account_financial_report.general_ledger"
  9. _description = "General Ledger Report"
  10. def _get_accounts_data(self, account_ids):
  11. accounts = self.env["account.account"].browse(account_ids)
  12. accounts_data = {}
  13. for account in accounts:
  14. accounts_data.update(
  15. {
  16. account.id: {
  17. "id": account.id,
  18. "code": account.code,
  19. "name": account.name,
  20. "group_id": account.group_id.id,
  21. "currency_id": account.currency_id or False,
  22. "currency_name": account.currency_id.name,
  23. "centralized": account.centralized,
  24. }
  25. }
  26. )
  27. return accounts_data
  28. def _get_journals_data(self, journals_ids):
  29. journals = self.env["account.journal"].browse(journals_ids)
  30. journals_data = {}
  31. for journal in journals:
  32. journals_data.update({journal.id: {"id": journal.id, "code": journal.code}})
  33. return journals_data
  34. def _get_tags_data(self, tags_ids):
  35. tags = self.env["account.analytic.tag"].browse(tags_ids)
  36. tags_data = {}
  37. for tag in tags:
  38. tags_data.update({tag.id: {"name": tag.name}})
  39. return tags_data
  40. def _get_taxes_data(self, taxes_ids):
  41. taxes = self.env["account.tax"].browse(taxes_ids)
  42. taxes_data = {}
  43. for tax in taxes:
  44. taxes_data.update(
  45. {
  46. tax.id: {
  47. "id": tax.id,
  48. "amount": tax.amount,
  49. "amount_type": tax.amount_type,
  50. }
  51. }
  52. )
  53. if tax.amount_type == "percent" or tax.amount_type == "division":
  54. taxes_data[tax.id]["string"] = "%"
  55. else:
  56. taxes_data[tax.id]["string"] = ""
  57. return taxes_data
  58. def _get_acc_prt_accounts_ids(self, company_id):
  59. accounts_domain = [
  60. ("company_id", "=", company_id),
  61. ("internal_type", "in", ["receivable", "payable"]),
  62. ]
  63. acc_prt_accounts = self.env["account.account"].search(accounts_domain)
  64. return acc_prt_accounts.ids
  65. def _get_initial_balances_bs_ml_domain(
  66. self, account_ids, company_id, date_from, base_domain, acc_prt=False
  67. ):
  68. accounts_domain = [
  69. ("company_id", "=", company_id),
  70. ("user_type_id.include_initial_balance", "=", True),
  71. ]
  72. if account_ids:
  73. accounts_domain += [("id", "in", account_ids)]
  74. domain = []
  75. domain += base_domain
  76. domain += [("date", "<", date_from)]
  77. accounts = self.env["account.account"].search(accounts_domain)
  78. domain += [("account_id", "in", accounts.ids)]
  79. if acc_prt:
  80. domain += [("account_id.internal_type", "in", ["receivable", "payable"])]
  81. return domain
  82. def _get_initial_balances_pl_ml_domain(
  83. self, account_ids, company_id, date_from, fy_start_date, base_domain
  84. ):
  85. accounts_domain = [
  86. ("company_id", "=", company_id),
  87. ("user_type_id.include_initial_balance", "=", False),
  88. ]
  89. if account_ids:
  90. accounts_domain += [("id", "in", account_ids)]
  91. domain = []
  92. domain += base_domain
  93. domain += [("date", "<", date_from), ("date", ">=", fy_start_date)]
  94. accounts = self.env["account.account"].search(accounts_domain)
  95. domain += [("account_id", "in", accounts.ids)]
  96. return domain
  97. def _get_accounts_initial_balance(self, initial_domain_bs, initial_domain_pl):
  98. gl_initial_acc_bs = self.env["account.move.line"].read_group(
  99. domain=initial_domain_bs,
  100. fields=["account_id", "debit", "credit", "balance", "amount_currency"],
  101. groupby=["account_id"],
  102. )
  103. gl_initial_acc_pl = self.env["account.move.line"].read_group(
  104. domain=initial_domain_pl,
  105. fields=["account_id", "debit", "credit", "balance", "amount_currency"],
  106. groupby=["account_id"],
  107. )
  108. gl_initial_acc = gl_initial_acc_bs + gl_initial_acc_pl
  109. return gl_initial_acc
  110. def _get_initial_balance_fy_pl_ml_domain(
  111. self, account_ids, company_id, fy_start_date, base_domain
  112. ):
  113. accounts_domain = [
  114. ("company_id", "=", company_id),
  115. ("user_type_id.include_initial_balance", "=", False),
  116. ]
  117. if account_ids:
  118. accounts_domain += [("id", "in", account_ids)]
  119. domain = []
  120. domain += base_domain
  121. domain += [("date", "<", fy_start_date)]
  122. accounts = self.env["account.account"].search(accounts_domain)
  123. domain += [("account_id", "in", accounts.ids)]
  124. return domain
  125. def _get_pl_initial_balance(
  126. self, account_ids, company_id, fy_start_date, foreign_currency, base_domain
  127. ):
  128. domain = self._get_initial_balance_fy_pl_ml_domain(
  129. account_ids, company_id, fy_start_date, base_domain
  130. )
  131. initial_balances = self.env["account.move.line"].read_group(
  132. domain=domain,
  133. fields=["account_id", "debit", "credit", "balance", "amount_currency"],
  134. groupby=["account_id"],
  135. )
  136. pl_initial_balance = {
  137. "debit": 0.0,
  138. "credit": 0.0,
  139. "balance": 0.0,
  140. "bal_curr": 0.0,
  141. }
  142. for initial_balance in initial_balances:
  143. pl_initial_balance["debit"] += initial_balance["debit"]
  144. pl_initial_balance["credit"] += initial_balance["credit"]
  145. pl_initial_balance["balance"] += initial_balance["balance"]
  146. pl_initial_balance["bal_curr"] += initial_balance["amount_currency"]
  147. return pl_initial_balance
  148. def _get_initial_balance_data(
  149. self,
  150. account_ids,
  151. partner_ids,
  152. company_id,
  153. date_from,
  154. foreign_currency,
  155. only_posted_moves,
  156. hide_account_at_0,
  157. unaffected_earnings_account,
  158. fy_start_date,
  159. analytic_tag_ids,
  160. cost_center_ids,
  161. ):
  162. base_domain = []
  163. if company_id:
  164. base_domain += [("company_id", "=", company_id)]
  165. if partner_ids:
  166. base_domain += [("partner_id", "in", partner_ids)]
  167. if only_posted_moves:
  168. base_domain += [("move_id.state", "=", "posted")]
  169. if analytic_tag_ids:
  170. base_domain += [("analytic_tag_ids", "in", analytic_tag_ids)]
  171. if cost_center_ids:
  172. base_domain += [("analytic_account_id", "in", cost_center_ids)]
  173. initial_domain_bs = self._get_initial_balances_bs_ml_domain(
  174. account_ids, company_id, date_from, base_domain
  175. )
  176. initial_domain_pl = self._get_initial_balances_pl_ml_domain(
  177. account_ids, company_id, date_from, fy_start_date, base_domain
  178. )
  179. gl_initial_acc = self._get_accounts_initial_balance(
  180. initial_domain_bs, initial_domain_pl
  181. )
  182. initial_domain_acc_prt = self._get_initial_balances_bs_ml_domain(
  183. account_ids, company_id, date_from, base_domain, acc_prt=True
  184. )
  185. gl_initial_acc_prt = self.env["account.move.line"].read_group(
  186. domain=initial_domain_acc_prt,
  187. fields=[
  188. "account_id",
  189. "partner_id",
  190. "debit",
  191. "credit",
  192. "balance",
  193. "amount_currency",
  194. ],
  195. groupby=["account_id", "partner_id"],
  196. lazy=False,
  197. )
  198. gen_ld_data = {}
  199. for gl in gl_initial_acc:
  200. acc_id = gl["account_id"][0]
  201. gen_ld_data[acc_id] = {}
  202. gen_ld_data[acc_id]["id"] = acc_id
  203. gen_ld_data[acc_id]["partners"] = False
  204. gen_ld_data[acc_id]["init_bal"] = {}
  205. gen_ld_data[acc_id]["init_bal"]["credit"] = gl["credit"]
  206. gen_ld_data[acc_id]["init_bal"]["debit"] = gl["debit"]
  207. gen_ld_data[acc_id]["init_bal"]["balance"] = gl["balance"]
  208. gen_ld_data[acc_id]["fin_bal"] = {}
  209. gen_ld_data[acc_id]["fin_bal"]["credit"] = gl["credit"]
  210. gen_ld_data[acc_id]["fin_bal"]["debit"] = gl["debit"]
  211. gen_ld_data[acc_id]["fin_bal"]["balance"] = gl["balance"]
  212. gen_ld_data[acc_id]["init_bal"]["bal_curr"] = gl["amount_currency"]
  213. gen_ld_data[acc_id]["fin_bal"]["bal_curr"] = gl["amount_currency"]
  214. partners_data = {}
  215. partners_ids = set()
  216. if gl_initial_acc_prt:
  217. for gl in gl_initial_acc_prt:
  218. if not gl["partner_id"]:
  219. prt_id = 0
  220. prt_name = "Missing Partner"
  221. else:
  222. prt_id = gl["partner_id"][0]
  223. prt_name = gl["partner_id"][1]
  224. prt_name = prt_name._value
  225. if prt_id not in partners_ids:
  226. partners_ids.add(prt_id)
  227. partners_data.update({prt_id: {"id": prt_id, "name": prt_name}})
  228. acc_id = gl["account_id"][0]
  229. gen_ld_data[acc_id][prt_id] = {}
  230. gen_ld_data[acc_id][prt_id]["id"] = prt_id
  231. gen_ld_data[acc_id]["partners"] = True
  232. gen_ld_data[acc_id][prt_id]["init_bal"] = {}
  233. gen_ld_data[acc_id][prt_id]["init_bal"]["credit"] = gl["credit"]
  234. gen_ld_data[acc_id][prt_id]["init_bal"]["debit"] = gl["debit"]
  235. gen_ld_data[acc_id][prt_id]["init_bal"]["balance"] = gl["balance"]
  236. gen_ld_data[acc_id][prt_id]["fin_bal"] = {}
  237. gen_ld_data[acc_id][prt_id]["fin_bal"]["credit"] = gl["credit"]
  238. gen_ld_data[acc_id][prt_id]["fin_bal"]["debit"] = gl["debit"]
  239. gen_ld_data[acc_id][prt_id]["fin_bal"]["balance"] = gl["balance"]
  240. gen_ld_data[acc_id][prt_id]["init_bal"]["bal_curr"] = gl[
  241. "amount_currency"
  242. ]
  243. gen_ld_data[acc_id][prt_id]["fin_bal"]["bal_curr"] = gl[
  244. "amount_currency"
  245. ]
  246. accounts_ids = list(gen_ld_data.keys())
  247. unaffected_id = unaffected_earnings_account
  248. if unaffected_id not in accounts_ids:
  249. accounts_ids.append(unaffected_id)
  250. self._initialize_account(gen_ld_data, unaffected_id, foreign_currency)
  251. pl_initial_balance = self._get_pl_initial_balance(
  252. account_ids, company_id, fy_start_date, foreign_currency, base_domain
  253. )
  254. gen_ld_data[unaffected_id]["init_bal"]["debit"] += pl_initial_balance["debit"]
  255. gen_ld_data[unaffected_id]["init_bal"]["credit"] += pl_initial_balance["credit"]
  256. gen_ld_data[unaffected_id]["init_bal"]["balance"] += pl_initial_balance[
  257. "balance"
  258. ]
  259. gen_ld_data[unaffected_id]["fin_bal"]["debit"] += pl_initial_balance["debit"]
  260. gen_ld_data[unaffected_id]["fin_bal"]["credit"] += pl_initial_balance["credit"]
  261. gen_ld_data[unaffected_id]["fin_bal"]["balance"] += pl_initial_balance[
  262. "balance"
  263. ]
  264. if foreign_currency:
  265. gen_ld_data[unaffected_id]["init_bal"]["bal_curr"] += pl_initial_balance[
  266. "bal_curr"
  267. ]
  268. gen_ld_data[unaffected_id]["fin_bal"]["bal_curr"] += pl_initial_balance[
  269. "bal_curr"
  270. ]
  271. return gen_ld_data, partners_data, partner_ids
  272. @api.model
  273. def _get_move_line_data(self, move_line):
  274. move_line_data = {
  275. "id": move_line["id"],
  276. "date": move_line["date"],
  277. "entry": move_line["move_id"][1],
  278. "entry_id": move_line["move_id"][0],
  279. "journal_id": move_line["journal_id"][0],
  280. "account_id": move_line["account_id"][0],
  281. "partner_id": move_line["partner_id"][0]
  282. if move_line["partner_id"]
  283. else False,
  284. "partner_name": move_line["partner_id"][1]
  285. if move_line["partner_id"]
  286. else "",
  287. "ref": "" if not move_line["ref"] else move_line["ref"],
  288. "tax_ids": move_line["tax_ids"],
  289. "debit": move_line["debit"],
  290. "credit": move_line["credit"],
  291. "balance": move_line["balance"],
  292. "bal_curr": move_line["amount_currency"],
  293. "rec_id": move_line["full_reconcile_id"][0]
  294. if move_line["full_reconcile_id"]
  295. else False,
  296. "rec_name": move_line["full_reconcile_id"][1]
  297. if move_line["full_reconcile_id"]
  298. else "",
  299. "tag_ids": move_line["analytic_tag_ids"],
  300. "currency_id": move_line["currency_id"],
  301. }
  302. return move_line_data
  303. @api.model
  304. def _get_period_domain(
  305. self,
  306. account_ids,
  307. partner_ids,
  308. company_id,
  309. only_posted_moves,
  310. date_to,
  311. date_from,
  312. analytic_tag_ids,
  313. cost_center_ids,
  314. ):
  315. domain = [
  316. ("display_type", "=", False),
  317. ("date", ">=", date_from),
  318. ("date", "<=", date_to),
  319. ]
  320. if account_ids:
  321. domain += [("account_id", "in", account_ids)]
  322. if company_id:
  323. domain += [("company_id", "=", company_id)]
  324. if partner_ids:
  325. domain += [("partner_id", "in", partner_ids)]
  326. if only_posted_moves:
  327. domain += [("move_id.state", "=", "posted")]
  328. if analytic_tag_ids:
  329. domain += [("analytic_tag_ids", "in", analytic_tag_ids)]
  330. if cost_center_ids:
  331. domain += [("analytic_account_id", "in", cost_center_ids)]
  332. return domain
  333. @api.model
  334. def _initialize_partner(self, gen_ld_data, acc_id, prt_id, foreign_currency):
  335. gen_ld_data[acc_id]["partners"] = True
  336. gen_ld_data[acc_id][prt_id] = {}
  337. gen_ld_data[acc_id][prt_id]["id"] = prt_id
  338. gen_ld_data[acc_id][prt_id]["init_bal"] = {}
  339. gen_ld_data[acc_id][prt_id]["init_bal"]["balance"] = 0.0
  340. gen_ld_data[acc_id][prt_id]["init_bal"]["credit"] = 0.0
  341. gen_ld_data[acc_id][prt_id]["init_bal"]["debit"] = 0.0
  342. gen_ld_data[acc_id][prt_id]["fin_bal"] = {}
  343. gen_ld_data[acc_id][prt_id]["fin_bal"]["credit"] = 0.0
  344. gen_ld_data[acc_id][prt_id]["fin_bal"]["debit"] = 0.0
  345. gen_ld_data[acc_id][prt_id]["fin_bal"]["balance"] = 0.0
  346. if foreign_currency:
  347. gen_ld_data[acc_id][prt_id]["init_bal"]["bal_curr"] = 0.0
  348. gen_ld_data[acc_id][prt_id]["fin_bal"]["bal_curr"] = 0.0
  349. return gen_ld_data
  350. def _initialize_account(self, gen_ld_data, acc_id, foreign_currency):
  351. gen_ld_data[acc_id] = {}
  352. gen_ld_data[acc_id]["id"] = acc_id
  353. gen_ld_data[acc_id]["partners"] = False
  354. gen_ld_data[acc_id]["init_bal"] = {}
  355. gen_ld_data[acc_id]["init_bal"]["balance"] = 0.0
  356. gen_ld_data[acc_id]["init_bal"]["credit"] = 0.0
  357. gen_ld_data[acc_id]["init_bal"]["debit"] = 0.0
  358. gen_ld_data[acc_id]["fin_bal"] = {}
  359. gen_ld_data[acc_id]["fin_bal"]["credit"] = 0.0
  360. gen_ld_data[acc_id]["fin_bal"]["debit"] = 0.0
  361. gen_ld_data[acc_id]["fin_bal"]["balance"] = 0.0
  362. if foreign_currency:
  363. gen_ld_data[acc_id]["init_bal"]["bal_curr"] = 0.0
  364. gen_ld_data[acc_id]["fin_bal"]["bal_curr"] = 0.0
  365. return gen_ld_data
  366. def _get_period_ml_data(
  367. self,
  368. account_ids,
  369. partner_ids,
  370. company_id,
  371. foreign_currency,
  372. only_posted_moves,
  373. hide_account_at_0,
  374. date_from,
  375. date_to,
  376. partners_data,
  377. gen_ld_data,
  378. partners_ids,
  379. centralize,
  380. analytic_tag_ids,
  381. cost_center_ids,
  382. ):
  383. domain = self._get_period_domain(
  384. account_ids,
  385. partner_ids,
  386. company_id,
  387. only_posted_moves,
  388. date_to,
  389. date_from,
  390. analytic_tag_ids,
  391. cost_center_ids,
  392. )
  393. ml_fields = [
  394. "id",
  395. "name",
  396. "date",
  397. "move_id",
  398. "journal_id",
  399. "account_id",
  400. "partner_id",
  401. "debit",
  402. "credit",
  403. "balance",
  404. "currency_id",
  405. "full_reconcile_id",
  406. "tax_ids",
  407. "analytic_tag_ids",
  408. "amount_currency",
  409. "ref",
  410. ]
  411. move_lines = self.env["account.move.line"].search_read(
  412. domain=domain, fields=ml_fields
  413. )
  414. journal_ids = set()
  415. full_reconcile_ids = set()
  416. taxes_ids = set()
  417. tags_ids = set()
  418. full_reconcile_data = {}
  419. acc_prt_account_ids = self._get_acc_prt_accounts_ids(company_id)
  420. for move_line in move_lines:
  421. journal_ids.add(move_line["journal_id"][0])
  422. for tax_id in move_line["tax_ids"]:
  423. taxes_ids.add(tax_id)
  424. for analytic_tag_id in move_line["analytic_tag_ids"]:
  425. tags_ids.add(analytic_tag_id)
  426. if move_line["full_reconcile_id"]:
  427. rec_id = move_line["full_reconcile_id"][0]
  428. if rec_id not in full_reconcile_ids:
  429. full_reconcile_data.update(
  430. {
  431. rec_id: {
  432. "id": rec_id,
  433. "name": move_line["full_reconcile_id"][1],
  434. }
  435. }
  436. )
  437. full_reconcile_ids.add(rec_id)
  438. acc_id = move_line["account_id"][0]
  439. ml_id = move_line["id"]
  440. if move_line["partner_id"]:
  441. prt_id = move_line["partner_id"][0]
  442. partner_name = move_line["partner_id"][1]
  443. if acc_id not in gen_ld_data.keys():
  444. gen_ld_data = self._initialize_account(
  445. gen_ld_data, acc_id, foreign_currency
  446. )
  447. if acc_id in acc_prt_account_ids:
  448. if not move_line["partner_id"]:
  449. prt_id = 0
  450. partner_name = "Missing Partner"
  451. partners_ids.append(prt_id)
  452. partners_data.update({prt_id: {"id": prt_id, "name": partner_name}})
  453. if prt_id not in gen_ld_data[acc_id]:
  454. gen_ld_data = self._initialize_partner(
  455. gen_ld_data, acc_id, prt_id, foreign_currency
  456. )
  457. gen_ld_data[acc_id][prt_id][ml_id] = self._get_move_line_data(move_line)
  458. gen_ld_data[acc_id][prt_id]["fin_bal"]["credit"] += move_line["credit"]
  459. gen_ld_data[acc_id][prt_id]["fin_bal"]["debit"] += move_line["debit"]
  460. gen_ld_data[acc_id][prt_id]["fin_bal"]["balance"] += move_line[
  461. "balance"
  462. ]
  463. if foreign_currency:
  464. gen_ld_data[acc_id][prt_id]["fin_bal"]["bal_curr"] += move_line[
  465. "amount_currency"
  466. ]
  467. else:
  468. gen_ld_data[acc_id][ml_id] = self._get_move_line_data(move_line)
  469. gen_ld_data[acc_id]["fin_bal"]["credit"] += move_line["credit"]
  470. gen_ld_data[acc_id]["fin_bal"]["debit"] += move_line["debit"]
  471. gen_ld_data[acc_id]["fin_bal"]["balance"] += move_line["balance"]
  472. if foreign_currency:
  473. gen_ld_data[acc_id]["fin_bal"]["bal_curr"] += move_line[
  474. "amount_currency"
  475. ]
  476. journals_data = self._get_journals_data(list(journal_ids))
  477. accounts_data = self._get_accounts_data(gen_ld_data.keys())
  478. taxes_data = self._get_taxes_data(list(taxes_ids))
  479. tags_data = self._get_tags_data(list(tags_ids))
  480. return (
  481. gen_ld_data,
  482. accounts_data,
  483. partners_data,
  484. journals_data,
  485. full_reconcile_data,
  486. taxes_data,
  487. tags_data,
  488. )
  489. @api.model
  490. def _recalculate_cumul_balance(self, move_lines, last_cumul_balance):
  491. for move_line in move_lines:
  492. move_line["balance"] += last_cumul_balance
  493. last_cumul_balance = move_line["balance"]
  494. return move_lines
  495. @api.model
  496. def _create_general_ledger(self, gen_led_data, accounts_data):
  497. general_ledger = []
  498. for acc_id in gen_led_data.keys():
  499. account = {}
  500. account.update(
  501. {
  502. "code": accounts_data[acc_id]["code"],
  503. "name": accounts_data[acc_id]["name"],
  504. "type": "account",
  505. "currency_id": accounts_data[acc_id]["currency_id"],
  506. "centralized": accounts_data[acc_id]["centralized"],
  507. }
  508. )
  509. if not gen_led_data[acc_id]["partners"]:
  510. move_lines = []
  511. for ml_id in gen_led_data[acc_id].keys():
  512. if not isinstance(ml_id, int):
  513. account.update({ml_id: gen_led_data[acc_id][ml_id]})
  514. else:
  515. move_lines += [gen_led_data[acc_id][ml_id]]
  516. move_lines = sorted(move_lines, key=lambda k: (k["date"]))
  517. move_lines = self._recalculate_cumul_balance(
  518. move_lines, gen_led_data[acc_id]["init_bal"]["balance"]
  519. )
  520. account.update({"move_lines": move_lines})
  521. else:
  522. list_partner = []
  523. for prt_id in gen_led_data[acc_id].keys():
  524. partner = {}
  525. move_lines = []
  526. if not isinstance(prt_id, int):
  527. account.update({prt_id: gen_led_data[acc_id][prt_id]})
  528. else:
  529. for ml_id in gen_led_data[acc_id][prt_id].keys():
  530. if not isinstance(ml_id, int):
  531. partner.update(
  532. {ml_id: gen_led_data[acc_id][prt_id][ml_id]}
  533. )
  534. else:
  535. move_lines += [gen_led_data[acc_id][prt_id][ml_id]]
  536. move_lines = sorted(move_lines, key=lambda k: (k["date"]))
  537. move_lines = self._recalculate_cumul_balance(
  538. move_lines,
  539. gen_led_data[acc_id][prt_id]["init_bal"]["balance"],
  540. )
  541. partner.update({"move_lines": move_lines})
  542. list_partner += [partner]
  543. account.update({"list_partner": list_partner})
  544. general_ledger += [account]
  545. return general_ledger
  546. @api.model
  547. def _calculate_centralization(self, centralized_ml, move_line, date_to):
  548. jnl_id = move_line["journal_id"]
  549. month = move_line["date"].month
  550. if jnl_id not in centralized_ml.keys():
  551. centralized_ml[jnl_id] = {}
  552. if month not in centralized_ml[jnl_id].keys():
  553. centralized_ml[jnl_id][month] = {}
  554. last_day_month = calendar.monthrange(move_line["date"].year, month)
  555. date = datetime.date(move_line["date"].year, month, last_day_month[1])
  556. if date > date_to:
  557. date = date_to
  558. centralized_ml[jnl_id][month].update(
  559. {
  560. "journal_id": jnl_id,
  561. "ref": "Centralized entries",
  562. "date": date,
  563. "debit": 0.0,
  564. "credit": 0.0,
  565. "balance": 0.0,
  566. "bal_curr": 0.0,
  567. "partner_id": False,
  568. "rec_id": 0,
  569. "entry_id": False,
  570. "tax_ids": [],
  571. "full_reconcile_id": False,
  572. "id": False,
  573. "tag_ids": False,
  574. "currency_id": False,
  575. }
  576. )
  577. centralized_ml[jnl_id][month]["debit"] += move_line["debit"]
  578. centralized_ml[jnl_id][month]["credit"] += move_line["credit"]
  579. centralized_ml[jnl_id][month]["balance"] += (
  580. move_line["debit"] - move_line["credit"]
  581. )
  582. centralized_ml[jnl_id][month]["bal_curr"] += move_line["bal_curr"]
  583. return centralized_ml
  584. @api.model
  585. def _get_centralized_ml(self, account, date_to):
  586. centralized_ml = {}
  587. if isinstance(date_to, str):
  588. date_to = datetime.datetime.strptime(date_to, "%Y-%m-%d").date()
  589. if account["partners"]:
  590. for partner in account["list_partner"]:
  591. for move_line in partner["move_lines"]:
  592. centralized_ml = self._calculate_centralization(
  593. centralized_ml, move_line, date_to,
  594. )
  595. else:
  596. for move_line in account["move_lines"]:
  597. centralized_ml = self._calculate_centralization(
  598. centralized_ml, move_line, date_to,
  599. )
  600. list_centralized_ml = []
  601. for jnl_id in centralized_ml.keys():
  602. list_centralized_ml += list(centralized_ml[jnl_id].values())
  603. return list_centralized_ml
  604. def _get_report_values(self, docids, data):
  605. wizard_id = data["wizard_id"]
  606. company = self.env["res.company"].browse(data["company_id"])
  607. company_id = data["company_id"]
  608. date_to = data["date_to"]
  609. date_from = data["date_from"]
  610. partner_ids = data["partner_ids"]
  611. if not partner_ids:
  612. filter_partner_ids = False
  613. else:
  614. filter_partner_ids = True
  615. account_ids = data["account_ids"]
  616. analytic_tag_ids = data["analytic_tag_ids"]
  617. cost_center_ids = data["cost_center_ids"]
  618. hide_account_at_0 = data["hide_account_at_0"]
  619. foreign_currency = data["foreign_currency"]
  620. only_posted_moves = data["only_posted_moves"]
  621. unaffected_earnings_account = data["unaffected_earnings_account"]
  622. fy_start_date = data["fy_start_date"]
  623. gen_ld_data, partners_data, partners_ids = self._get_initial_balance_data(
  624. account_ids,
  625. partner_ids,
  626. company_id,
  627. date_from,
  628. foreign_currency,
  629. only_posted_moves,
  630. hide_account_at_0,
  631. unaffected_earnings_account,
  632. fy_start_date,
  633. analytic_tag_ids,
  634. cost_center_ids,
  635. )
  636. centralize = data["centralize"]
  637. (
  638. gen_ld_data,
  639. accounts_data,
  640. partners_data,
  641. journals_data,
  642. full_reconcile_data,
  643. taxes_data,
  644. tags_data,
  645. ) = self._get_period_ml_data(
  646. account_ids,
  647. partner_ids,
  648. company_id,
  649. foreign_currency,
  650. only_posted_moves,
  651. hide_account_at_0,
  652. date_from,
  653. date_to,
  654. partners_data,
  655. gen_ld_data,
  656. partners_ids,
  657. centralize,
  658. analytic_tag_ids,
  659. cost_center_ids,
  660. )
  661. general_ledger = self._create_general_ledger(gen_ld_data, accounts_data)
  662. if centralize:
  663. for account in general_ledger:
  664. if account["centralized"]:
  665. centralized_ml = self._get_centralized_ml(account, date_to)
  666. account["move_lines"] = centralized_ml
  667. account["move_lines"] = self._recalculate_cumul_balance(
  668. account["move_lines"],
  669. gen_ld_data[account["id"]]["init_bal"]["balance"],
  670. )
  671. if account["partners"]:
  672. account["partners"] = False
  673. del account["list_partner"]
  674. general_ledger = sorted(general_ledger, key=lambda k: k["code"])
  675. return {
  676. "doc_ids": [wizard_id],
  677. "doc_model": "general.ledger.report.wizard",
  678. "docs": self.env["general.ledger.report.wizard"].browse(wizard_id),
  679. "foreign_currency": data["foreign_currency"],
  680. "company_name": company.display_name,
  681. "company_currency": company.currency_id,
  682. "currency_name": company.currency_id.name,
  683. "date_from": data["date_from"],
  684. "date_to": data["date_to"],
  685. "only_posted_moves": data["only_posted_moves"],
  686. "hide_account_at_0": data["hide_account_at_0"],
  687. "show_analytic_tags": data["show_analytic_tags"],
  688. "general_ledger": general_ledger,
  689. "accounts_data": accounts_data,
  690. "partners_data": partners_data,
  691. "journals_data": journals_data,
  692. "full_reconcile_data": full_reconcile_data,
  693. "taxes_data": taxes_data,
  694. "centralize": centralize,
  695. "tags_data": tags_data,
  696. "filter_partner_ids": filter_partner_ids,
  697. }