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.

304 lines
12 KiB

  1. # Author: Julien Coux
  2. # Copyright 2016 Camptocamp SA
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. from odoo import _, models
  5. class TrialBalanceXslx(models.AbstractModel):
  6. _name = "report.a_f_r.report_trial_balance_xlsx"
  7. _inherit = "report.account_financial_report.abstract_report_xlsx"
  8. def _get_report_name(self, report, data=False):
  9. company_id = data.get("company_id", False)
  10. report_name = _("Trial Balance")
  11. if company_id:
  12. company = self.env["res.company"].browse(company_id)
  13. suffix = " - {} - {}".format(company.name, company.currency_id.name)
  14. report_name = report_name + suffix
  15. return report_name
  16. def _get_report_columns(self, report):
  17. if not report.show_partner_details:
  18. res = {
  19. 0: {"header": _("Code"), "field": "code", "width": 10},
  20. 1: {"header": _("Account"), "field": "name", "width": 60},
  21. 2: {
  22. "header": _("Initial balance"),
  23. "field": "initial_balance",
  24. "type": "amount",
  25. "width": 14,
  26. },
  27. 3: {
  28. "header": _("Debit"),
  29. "field": "debit",
  30. "type": "amount",
  31. "width": 14,
  32. },
  33. 4: {
  34. "header": _("Credit"),
  35. "field": "credit",
  36. "type": "amount",
  37. "width": 14,
  38. },
  39. 5: {
  40. "header": _("Period balance"),
  41. "field": "period_balance",
  42. "type": "amount",
  43. "width": 14,
  44. },
  45. 6: {
  46. "header": _("Ending balance"),
  47. "field": "final_balance",
  48. "type": "amount",
  49. "width": 14,
  50. },
  51. }
  52. if report.foreign_currency:
  53. foreign_currency = {
  54. 7: {
  55. "header": _("Cur."),
  56. "field": "currency_id",
  57. "field_currency_balance": "currency_id",
  58. "type": "many2one",
  59. "width": 7,
  60. },
  61. 8: {
  62. "header": _("Initial balance"),
  63. "field": "initial_balance_foreign_currency",
  64. "type": "amount_currency",
  65. "width": 14,
  66. },
  67. 9: {
  68. "header": _("Ending balance"),
  69. "field": "final_balance_foreign_currency",
  70. "type": "amount_currency",
  71. "width": 14,
  72. },
  73. }
  74. res = {**res, **foreign_currency}
  75. return res
  76. else:
  77. res = {
  78. 0: {"header": _("Partner"), "field": "name", "width": 70},
  79. 1: {
  80. "header": _("Initial balance"),
  81. "field": "initial_balance",
  82. "type": "amount",
  83. "width": 14,
  84. },
  85. 2: {
  86. "header": _("Debit"),
  87. "field": "debit",
  88. "type": "amount",
  89. "width": 14,
  90. },
  91. 3: {
  92. "header": _("Credit"),
  93. "field": "credit",
  94. "type": "amount",
  95. "width": 14,
  96. },
  97. 4: {
  98. "header": _("Period balance"),
  99. "field": "balance",
  100. "type": "amount",
  101. "width": 14,
  102. },
  103. 5: {
  104. "header": _("Ending balance"),
  105. "field": "ending_balance",
  106. "type": "amount",
  107. "width": 14,
  108. },
  109. }
  110. if report.foreign_currency:
  111. foreign_currency = {
  112. 6: {
  113. "header": _("Cur."),
  114. "field": "currency_id",
  115. "field_currency_balance": "currency_id",
  116. "type": "many2one",
  117. "width": 7,
  118. },
  119. 7: {
  120. "header": _("Initial balance"),
  121. "field": "initial_currency_balance",
  122. "type": "amount_currency",
  123. "width": 14,
  124. },
  125. 8: {
  126. "header": _("Ending balance"),
  127. "field": "ending_currency_balance",
  128. "type": "amount_currency",
  129. "width": 14,
  130. },
  131. }
  132. res = {**res, **foreign_currency}
  133. return res
  134. def _get_report_filters(self, report):
  135. return [
  136. [
  137. _("Date range filter"),
  138. _("From: %s To: %s") % (report.date_from, report.date_to),
  139. ],
  140. [
  141. _("Target moves filter"),
  142. _("All posted entries")
  143. if report.target_move == "all"
  144. else _("All entries"),
  145. ],
  146. [
  147. _("Account at 0 filter"),
  148. _("Hide") if report.hide_account_at_0 else _("Show"),
  149. ],
  150. [
  151. _("Show foreign currency"),
  152. _("Yes") if report.foreign_currency else _("No"),
  153. ],
  154. [
  155. _("Limit hierarchy levels"),
  156. _("Level %s" % report.show_hierarchy_level)
  157. if report.limit_hierarchy_level
  158. else _("No limit"),
  159. ],
  160. ]
  161. def _get_col_count_filter_name(self):
  162. return 2
  163. def _get_col_count_filter_value(self):
  164. return 3
  165. def _generate_report_content(self, workbook, report, data):
  166. res_data = self.env[
  167. "report.account_financial_report.trial_balance"
  168. ]._get_report_values(report, data)
  169. trial_balance = res_data["trial_balance"]
  170. total_amount = res_data["total_amount"]
  171. partners_data = res_data["partners_data"]
  172. accounts_data = res_data["accounts_data"]
  173. hierarchy_on = res_data["hierarchy_on"]
  174. show_partner_details = res_data["show_partner_details"]
  175. show_hierarchy_level = res_data["show_hierarchy_level"]
  176. foreign_currency = res_data["foreign_currency"]
  177. limit_hierarchy_level = res_data["limit_hierarchy_level"]
  178. if not show_partner_details:
  179. # Display array header for account lines
  180. self.write_array_header()
  181. # For each account
  182. if not show_partner_details:
  183. for balance in trial_balance:
  184. if hierarchy_on == "relation":
  185. if limit_hierarchy_level:
  186. if show_hierarchy_level > balance["level"]:
  187. # Display account lines
  188. self.write_line_from_dict(balance)
  189. else:
  190. self.write_line_from_dict(balance)
  191. elif hierarchy_on == "computed":
  192. if balance["type"] == "account_type":
  193. if limit_hierarchy_level:
  194. if show_hierarchy_level > balance["level"]:
  195. # Display account lines
  196. self.write_line_from_dict(balance)
  197. else:
  198. self.write_line_from_dict(balance)
  199. else:
  200. self.write_line_from_dict(balance)
  201. else:
  202. for account_id in total_amount:
  203. # Write account title
  204. self.write_array_title(
  205. accounts_data[account_id]["code"]
  206. + "- "
  207. + accounts_data[account_id]["name"]
  208. )
  209. # Display array header for partner lines
  210. self.write_array_header()
  211. # For each partner
  212. for partner_id in total_amount[account_id]:
  213. if isinstance(partner_id, int):
  214. # Display partner lines
  215. self.write_line_from_dict_order(
  216. total_amount[account_id][partner_id],
  217. partners_data[partner_id],
  218. )
  219. # Display account footer line
  220. accounts_data[account_id].update(
  221. {
  222. "initial_balance": total_amount[account_id]["initial_balance"],
  223. "credit": total_amount[account_id]["credit"],
  224. "debit": total_amount[account_id]["debit"],
  225. "balance": total_amount[account_id]["balance"],
  226. "ending_balance": total_amount[account_id]["ending_balance"],
  227. }
  228. )
  229. if foreign_currency:
  230. accounts_data[account_id].update(
  231. {
  232. "initial_currency_balance": total_amount[account_id][
  233. "initial_currency_balance"
  234. ],
  235. "ending_currency_balance": total_amount[account_id][
  236. "ending_currency_balance"
  237. ],
  238. }
  239. )
  240. self.write_account_footer(
  241. accounts_data[account_id],
  242. accounts_data[account_id]["code"]
  243. + "- "
  244. + accounts_data[account_id]["name"],
  245. )
  246. # Line break
  247. self.row_pos += 2
  248. def write_line_from_dict_order(self, total_amount, partner_data):
  249. total_amount.update({"name": str(partner_data["name"])})
  250. self.write_line_from_dict(total_amount)
  251. def write_line(self, line_object, type_object):
  252. """Write a line on current line using all defined columns field name.
  253. Columns are defined with `_get_report_columns` method.
  254. """
  255. if type_object == "partner":
  256. line_object.currency_id = line_object.report_account_id.currency_id
  257. elif type_object == "account":
  258. line_object.currency_id = line_object.currency_id
  259. super(TrialBalanceXslx, self).write_line(line_object)
  260. def write_account_footer(self, account, name_value):
  261. """Specific function to write account footer for Trial Balance"""
  262. format_amt = self._get_currency_amt_header_format_dict(account)
  263. for col_pos, column in self.columns.items():
  264. if column["field"] == "name":
  265. value = name_value
  266. else:
  267. value = account[column["field"]]
  268. cell_type = column.get("type", "string")
  269. if cell_type == "string":
  270. self.sheet.write_string(
  271. self.row_pos, col_pos, value or "", self.format_header_left
  272. )
  273. elif cell_type == "amount":
  274. self.sheet.write_number(
  275. self.row_pos, col_pos, float(value), self.format_header_amount
  276. )
  277. elif cell_type == "many2one" and account["currency_id"]:
  278. self.sheet.write_string(
  279. self.row_pos, col_pos, value.name or "", self.format_header_right
  280. )
  281. elif cell_type == "amount_currency" and account["currency_id"]:
  282. self.sheet.write_number(self.row_pos, col_pos, float(value), format_amt)
  283. else:
  284. self.sheet.write_string(
  285. self.row_pos, col_pos, "", self.format_header_right
  286. )
  287. self.row_pos += 1