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.

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