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.

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