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.

325 lines
12 KiB

  1. # Author: Julien Coux
  2. # Copyright 2016 Camptocamp SA
  3. # Copyright 2021 Tecnativa - João Marques
  4. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  5. from odoo import _, models
  6. class AgedPartnerBalanceXslx(models.AbstractModel):
  7. _name = "report.a_f_r.report_aged_partner_balance_xlsx"
  8. _description = "Aged Partner Balance XLSL Report"
  9. _inherit = "report.account_financial_report.abstract_report_xlsx"
  10. def _get_report_name(self, report, data=False):
  11. company_id = data.get("company_id", False)
  12. report_name = _("Aged Partner Balance")
  13. if company_id:
  14. company = self.env["res.company"].browse(company_id)
  15. suffix = " - {} - {}".format(company.name, company.currency_id.name)
  16. report_name = report_name + suffix
  17. return report_name
  18. def _get_report_columns(self, report):
  19. if not report.show_move_line_details:
  20. return {
  21. 0: {"header": _("Partner"), "field": "name", "width": 70},
  22. 1: {
  23. "header": _("Residual"),
  24. "field": "residual",
  25. "field_footer_total": "residual",
  26. "type": "amount",
  27. "width": 14,
  28. },
  29. 2: {
  30. "header": _("Current"),
  31. "field": "current",
  32. "field_footer_total": "current",
  33. "field_footer_percent": "percent_current",
  34. "type": "amount",
  35. "width": 14,
  36. },
  37. 3: {
  38. "header": _(u"Age ≤ 30 d."),
  39. "field": "30_days",
  40. "field_footer_total": "30_days",
  41. "field_footer_percent": "percent_30_days",
  42. "type": "amount",
  43. "width": 14,
  44. },
  45. 4: {
  46. "header": _(u"Age ≤ 60 d."),
  47. "field": "60_days",
  48. "field_footer_total": "60_days",
  49. "field_footer_percent": "percent_60_days",
  50. "type": "amount",
  51. "width": 14,
  52. },
  53. 5: {
  54. "header": _(u"Age ≤ 90 d."),
  55. "field": "90_days",
  56. "field_footer_total": "90_days",
  57. "field_footer_percent": "percent_90_days",
  58. "type": "amount",
  59. "width": 14,
  60. },
  61. 6: {
  62. "header": _(u"Age ≤ 120 d."),
  63. "field": "120_days",
  64. "field_footer_total": "120_days",
  65. "field_footer_percent": "percent_120_days",
  66. "type": "amount",
  67. "width": 14,
  68. },
  69. 7: {
  70. "header": _("Older"),
  71. "field": "older",
  72. "field_footer_total": "older",
  73. "field_footer_percent": "percent_older",
  74. "type": "amount",
  75. "width": 14,
  76. },
  77. }
  78. return {
  79. 0: {"header": _("Date"), "field": "date", "width": 11},
  80. 1: {"header": _("Entry"), "field": "entry", "width": 18},
  81. 2: {"header": _("Journal"), "field": "journal", "width": 8},
  82. 3: {"header": _("Account"), "field": "account", "width": 9},
  83. 4: {"header": _("Partner"), "field": "partner", "width": 25},
  84. 5: {"header": _("Ref - Label"), "field": "ref_label", "width": 40},
  85. 6: {"header": _("Due date"), "field": "due_date", "width": 11},
  86. 7: {
  87. "header": _("Residual"),
  88. "field": "residual",
  89. "field_footer_total": "residual",
  90. "field_final_balance": "residual",
  91. "type": "amount",
  92. "width": 14,
  93. },
  94. 8: {
  95. "header": _("Current"),
  96. "field": "current",
  97. "field_footer_total": "current",
  98. "field_footer_percent": "percent_current",
  99. "field_final_balance": "current",
  100. "type": "amount",
  101. "width": 14,
  102. },
  103. 9: {
  104. "header": _(u"Age ≤ 30 d."),
  105. "field": "30_days",
  106. "field_footer_total": "30_days",
  107. "field_footer_percent": "percent_30_days",
  108. "field_final_balance": "30_days",
  109. "type": "amount",
  110. "width": 14,
  111. },
  112. 10: {
  113. "header": _(u"Age ≤ 60 d."),
  114. "field": "60_days",
  115. "field_footer_total": "60_days",
  116. "field_footer_percent": "percent_60_days",
  117. "field_final_balance": "60_days",
  118. "type": "amount",
  119. "width": 14,
  120. },
  121. 11: {
  122. "header": _(u"Age ≤ 90 d."),
  123. "field": "90_days",
  124. "field_footer_total": "90_days",
  125. "field_footer_percent": "percent_90_days",
  126. "field_final_balance": "90_days",
  127. "type": "amount",
  128. "width": 14,
  129. },
  130. 12: {
  131. "header": _(u"Age ≤ 120 d."),
  132. "field": "120_days",
  133. "field_footer_total": "120_days",
  134. "field_footer_percent": "percent_120_days",
  135. "field_final_balance": "120_days",
  136. "type": "amount",
  137. "width": 14,
  138. },
  139. 13: {
  140. "header": _("Older"),
  141. "field": "older",
  142. "field_footer_total": "older",
  143. "field_footer_percent": "percent_older",
  144. "field_final_balance": "older",
  145. "type": "amount",
  146. "width": 14,
  147. },
  148. }
  149. def _get_report_filters(self, report):
  150. return [
  151. [_("Date at filter"), report.date_at.strftime("%d/%m/%Y")],
  152. [
  153. _("Target moves filter"),
  154. _("All posted entries")
  155. if report.target_move == "posted"
  156. else _("All entries"),
  157. ],
  158. ]
  159. def _get_col_count_filter_name(self):
  160. return 2
  161. def _get_col_count_filter_value(self):
  162. return 3
  163. def _get_col_pos_footer_label(self, report):
  164. return 0 if not report.show_move_line_details else 5
  165. def _get_col_count_final_balance_name(self):
  166. return 5
  167. def _get_col_pos_final_balance_label(self):
  168. return 5
  169. def _generate_report_content(self, workbook, report, data, report_data):
  170. res_data = self.env[
  171. "report.account_financial_report.aged_partner_balance"
  172. ]._get_report_values(report, data)
  173. show_move_line_details = res_data["show_move_lines_details"]
  174. aged_partner_balance = res_data["aged_partner_balance"]
  175. if not show_move_line_details:
  176. # For each account
  177. for account in aged_partner_balance:
  178. # Write account title
  179. self.write_array_title(
  180. account["code"] + " - " + account["name"], report_data
  181. )
  182. # Display array header for partners lines
  183. self.write_array_header(report_data)
  184. # Display partner lines
  185. for partner in account["partners"]:
  186. self.write_line_from_dict(partner, report_data)
  187. # Display account lines
  188. self.write_account_footer_from_dict(
  189. report,
  190. account,
  191. ("Total"),
  192. "field_footer_total",
  193. report_data["formats"]["format_header_right"],
  194. report_data["formats"]["format_header_amount"],
  195. False,
  196. report_data,
  197. )
  198. self.write_account_footer_from_dict(
  199. report,
  200. account,
  201. ("Percents"),
  202. "field_footer_percent",
  203. report_data["formats"]["format_right_bold_italic"],
  204. report_data["formats"]["format_percent_bold_italic"],
  205. True,
  206. report_data,
  207. )
  208. # 2 lines break
  209. report_data["row_pos"] += 2
  210. else:
  211. # For each account
  212. for account in aged_partner_balance:
  213. # Write account title
  214. self.write_array_title(
  215. account["code"] + " - " + account["name"], report_data
  216. )
  217. # For each partner
  218. for partner in account["partners"]:
  219. # Write partner title
  220. self.write_array_title(partner["name"], report_data)
  221. # Display array header for move lines
  222. self.write_array_header(report_data)
  223. # Display account move lines
  224. for line in partner["move_lines"]:
  225. self.write_line_from_dict(line, report_data)
  226. # Display ending balance line for partner
  227. self.write_ending_balance_from_dict(partner, report_data)
  228. # Line break
  229. report_data["row_pos"] += 1
  230. # Display account lines
  231. self.write_account_footer_from_dict(
  232. report,
  233. account,
  234. ("Total"),
  235. "field_footer_total",
  236. report_data["formats"]["format_header_right"],
  237. report_data["formats"]["format_header_amount"],
  238. False,
  239. report_data,
  240. )
  241. self.write_account_footer_from_dict(
  242. report,
  243. account,
  244. ("Percents"),
  245. "field_footer_percent",
  246. report_data["formats"]["format_right_bold_italic"],
  247. report_data["formats"]["format_percent_bold_italic"],
  248. True,
  249. report_data,
  250. )
  251. # 2 lines break
  252. report_data["row_pos"] += 2
  253. def write_ending_balance_from_dict(self, my_object, report_data):
  254. """
  255. Specific function to write ending partner balance
  256. for Aged Partner Balance
  257. """
  258. name = None
  259. label = _("Partner cumul aged balance")
  260. super().write_ending_balance_from_dict(my_object, name, label, report_data)
  261. def write_account_footer_from_dict(
  262. self,
  263. report,
  264. account,
  265. label,
  266. field_name,
  267. string_format,
  268. amount_format,
  269. amount_is_percent,
  270. report_data,
  271. ):
  272. """
  273. Specific function to write account footer for Aged Partner Balance
  274. """
  275. col_pos_footer_label = self._get_col_pos_footer_label(report)
  276. for col_pos, column in report_data["columns"].items():
  277. if col_pos == col_pos_footer_label or column.get(field_name):
  278. if col_pos == col_pos_footer_label:
  279. value = label
  280. else:
  281. value = account.get(column[field_name], False)
  282. cell_type = column.get("type", "string")
  283. if cell_type == "string" or col_pos == col_pos_footer_label:
  284. report_data["sheet"].write_string(
  285. report_data["row_pos"], col_pos, value or "", string_format
  286. )
  287. elif cell_type == "amount":
  288. number = float(value)
  289. if amount_is_percent:
  290. number /= 100
  291. report_data["sheet"].write_number(
  292. report_data["row_pos"], col_pos, number, amount_format
  293. )
  294. else:
  295. report_data["sheet"].write_string(
  296. report_data["row_pos"], col_pos, "", string_format
  297. )
  298. report_data["row_pos"] += 1