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.

282 lines
11 KiB

  1. # Copyright 2018 Forest and Biomass Romania
  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 operator
  5. from odoo import api, models
  6. class VATReport(models.AbstractModel):
  7. _name = "report.account_financial_report.vat_report"
  8. _description = "Vat Report Report"
  9. def _get_tax_data(self, tax_ids, hide_tax_at_zero):
  10. domain = []
  11. if hide_tax_at_zero:
  12. domain += [("id", "in", tax_ids)]
  13. taxes = self.env["account.tax"].search(domain)
  14. tax_data = {}
  15. for tax in taxes:
  16. tax_data.update(
  17. {
  18. tax.id: {
  19. "id": tax.id,
  20. "name": tax.name,
  21. "tax_group_id": tax.tax_group_id.id,
  22. "type_tax_use": tax.type_tax_use,
  23. "amount_type": tax.amount_type,
  24. "tags_ids": tax.invoice_repartition_line_ids.tag_ids.ids,
  25. }
  26. }
  27. )
  28. return tax_data
  29. @api.model
  30. def _get_tax_report_domain(self, company_id, date_from, date_to, only_posted_moves):
  31. domain = [
  32. ("company_id", "=", company_id),
  33. ("date", ">=", date_from),
  34. ("date", "<=", date_to),
  35. ("tax_line_id", "!=", False),
  36. ("tax_exigible", "=", True),
  37. ]
  38. if only_posted_moves:
  39. domain += [("move_id.state", "=", "posted")]
  40. else:
  41. domain += [("move_id.state", "in", ["posted", "draft"])]
  42. return domain
  43. @api.model
  44. def _get_net_report_domain(self, company_id, date_from, date_to, only_posted_moves):
  45. domain = [
  46. ("company_id", "=", company_id),
  47. ("date", ">=", date_from),
  48. ("date", "<=", date_to),
  49. ("tax_exigible", "=", True),
  50. ]
  51. if only_posted_moves:
  52. domain += [("move_id.state", "=", "posted")]
  53. else:
  54. domain += [("move_id.state", "in", ["posted", "draft"])]
  55. return domain
  56. def _get_vat_report_data(
  57. self, company_id, date_from, date_to, only_posted_moves, hide_tax_at_zero
  58. ):
  59. tax_domain = self._get_tax_report_domain(
  60. company_id, date_from, date_to, only_posted_moves
  61. )
  62. ml_fields = [
  63. "id",
  64. "tax_base_amount",
  65. "balance",
  66. "tax_line_id",
  67. "tax_ids",
  68. "analytic_tag_ids",
  69. "tag_ids",
  70. ]
  71. tax_move_lines = self.env["account.move.line"].search_read(
  72. domain=tax_domain, fields=ml_fields,
  73. )
  74. net_domain = self._get_net_report_domain(
  75. company_id, date_from, date_to, only_posted_moves
  76. )
  77. taxed_move_lines = self.env["account.move.line"].search_read(
  78. domain=net_domain, fields=ml_fields,
  79. )
  80. taxed_move_lines = list(filter(lambda d: d["tax_ids"], taxed_move_lines))
  81. vat_data = []
  82. for tax_move_line in tax_move_lines:
  83. vat_data.append(
  84. {
  85. "net": 0.0,
  86. "tax": tax_move_line["balance"],
  87. "tax_line_id": tax_move_line["tax_line_id"][0],
  88. }
  89. )
  90. for taxed_move_line in taxed_move_lines:
  91. for tax_id in taxed_move_line["tax_ids"]:
  92. vat_data.append(
  93. {
  94. "net": taxed_move_line["balance"],
  95. "tax": 0.0,
  96. "tax_line_id": tax_id,
  97. }
  98. )
  99. tax_ids = list(map(operator.itemgetter("tax_line_id"), vat_data))
  100. tax_ids = list(set(tax_ids))
  101. tax_data = self._get_tax_data(tax_ids, hide_tax_at_zero)
  102. return vat_data, tax_data
  103. def _get_tax_group_data(self, tax_group_ids):
  104. tax_groups = self.env["account.tax.group"].browse(tax_group_ids)
  105. tax_group_data = {}
  106. for tax_group in tax_groups:
  107. tax_group_data.update(
  108. {
  109. tax_group.id: {
  110. "id": tax_group.id,
  111. "name": tax_group.name,
  112. "code": str(tax_group.sequence),
  113. }
  114. }
  115. )
  116. return tax_group_data
  117. @api.model
  118. def _initialize_vat_report(self, tax_id, tag_or_group_id, vat_report, tax_data):
  119. if tag_or_group_id not in vat_report.keys():
  120. vat_report[tag_or_group_id] = {}
  121. vat_report[tag_or_group_id]["net"] = 0.0
  122. vat_report[tag_or_group_id]["tax"] = 0.0
  123. vat_report[tag_or_group_id][tax_id] = dict(tax_data[tax_id])
  124. vat_report[tag_or_group_id][tax_id].update({"net": 0.0, "tax": 0.0})
  125. else:
  126. if tax_id not in vat_report[tag_or_group_id].keys():
  127. vat_report[tag_or_group_id][tax_id] = dict(tax_data[tax_id])
  128. vat_report[tag_or_group_id][tax_id].update({"net": 0.0, "tax": 0.0})
  129. return vat_report
  130. def _get_vat_report_group_data(
  131. self, vat_report_data, tax_data, tax_detail, hide_tax_at_zero
  132. ):
  133. vat_report = {}
  134. if not hide_tax_at_zero:
  135. for tax_id in tax_data.keys():
  136. if tax_data[tax_id]["amount_type"] == "group":
  137. continue
  138. tax_group_id = tax_data[tax_id]["tax_group_id"]
  139. vat_report = self._initialize_vat_report(
  140. tax_id, tax_group_id, vat_report, tax_data
  141. )
  142. for tax_move_line in vat_report_data:
  143. tax_id = tax_move_line["tax_line_id"]
  144. if tax_data[tax_id]["amount_type"] == "group":
  145. continue
  146. tax_group_id = tax_data[tax_id]["tax_group_id"]
  147. vat_report = self._initialize_vat_report(
  148. tax_id, tax_group_id, vat_report, tax_data
  149. )
  150. vat_report[tax_group_id]["net"] += tax_move_line["net"]
  151. vat_report[tax_group_id]["tax"] += tax_move_line["tax"]
  152. vat_report[tax_group_id][tax_id]["net"] += tax_move_line["net"]
  153. vat_report[tax_group_id][tax_id]["tax"] += tax_move_line["tax"]
  154. tax_group_data = self._get_tax_group_data(vat_report.keys())
  155. vat_report_list = []
  156. for tax_group_id in vat_report.keys():
  157. vat_report_group = {}
  158. vat_report_group.update(
  159. {
  160. tax_group_id: {
  161. "name": tax_group_data[tax_group_id]["name"],
  162. "code": tax_group_data[tax_group_id]["code"],
  163. "net": vat_report[tax_group_id]["net"],
  164. "tax": vat_report[tax_group_id]["tax"],
  165. }
  166. }
  167. )
  168. if tax_detail:
  169. vat_report_group[tax_group_id]["taxes"] = []
  170. for tax_id in vat_report[tax_group_id]:
  171. if isinstance(tax_id, int):
  172. vat_report_group[tax_group_id]["taxes"].append(
  173. vat_report[tax_group_id][tax_id]
  174. )
  175. vat_report_list.append(vat_report_group[tax_group_id])
  176. return vat_report_list
  177. def _get_tags_data(self, tags_ids):
  178. tags = self.env["account.account.tag"].browse(tags_ids)
  179. tags_data = {}
  180. for tag in tags:
  181. tags_data.update({tag.id: {"code": "", "name": tag.name}})
  182. return tags_data
  183. def _get_vat_report_tag_data(
  184. self, vat_report_data, tax_data, tax_detail, hide_tax_at_zero
  185. ):
  186. vat_report = {}
  187. if not hide_tax_at_zero:
  188. for tax_id in tax_data.keys():
  189. if tax_data[tax_id]["amount_type"] == "group":
  190. continue
  191. tags_ids = tax_data[tax_id]["tags_ids"]
  192. if tags_ids:
  193. for tag_id in tags_ids:
  194. vat_report = self._initialize_vat_report(
  195. tax_id, tag_id, vat_report, tax_data
  196. )
  197. for tax_move_line in vat_report_data:
  198. tax_id = tax_move_line["tax_line_id"]
  199. tags_ids = tax_data[tax_id]["tags_ids"]
  200. if tax_data[tax_id]["amount_type"] == "group":
  201. continue
  202. else:
  203. if tags_ids:
  204. for tag_id in tags_ids:
  205. vat_report = self._initialize_vat_report(
  206. tax_id, tag_id, vat_report, tax_data
  207. )
  208. vat_report[tag_id][tax_id]["net"] += tax_move_line["net"]
  209. vat_report[tag_id][tax_id]["tax"] += tax_move_line["tax"]
  210. vat_report[tag_id]["net"] += tax_move_line["net"]
  211. vat_report[tag_id]["tax"] += tax_move_line["tax"]
  212. tags_data = self._get_tags_data(vat_report.keys())
  213. vat_report_list = []
  214. for tag_id in vat_report.keys():
  215. vat_report_tag = {}
  216. vat_report_tag.update(
  217. {
  218. tag_id: {
  219. "name": tags_data[tag_id]["name"],
  220. "code": tags_data[tag_id]["code"],
  221. "net": vat_report[tag_id]["net"],
  222. "tax": vat_report[tag_id]["tax"],
  223. }
  224. }
  225. )
  226. if tax_detail:
  227. vat_report_tag[tag_id]["taxes"] = []
  228. for tax_id in vat_report[tag_id]:
  229. if isinstance(tax_id, int):
  230. vat_report_tag[tag_id]["taxes"].append(
  231. vat_report[tag_id][tax_id]
  232. )
  233. vat_report_list.append(vat_report_tag[tag_id])
  234. return vat_report_list
  235. def _get_report_values(self, docids, data):
  236. wizard_id = data["wizard_id"]
  237. company = self.env["res.company"].browse(data["company_id"])
  238. company_id = data["company_id"]
  239. date_from = data["date_from"]
  240. date_to = data["date_to"]
  241. based_on = data["based_on"]
  242. tax_detail = data["tax_detail"]
  243. only_posted_moves = data["only_posted_moves"]
  244. hide_tax_at_zero = data["hide_tax_at_zero"]
  245. vat_report_data, tax_data = self._get_vat_report_data(
  246. company_id, date_from, date_to, only_posted_moves, hide_tax_at_zero
  247. )
  248. if based_on == "taxgroups":
  249. vat_report = self._get_vat_report_group_data(
  250. vat_report_data, tax_data, tax_detail, hide_tax_at_zero
  251. )
  252. else:
  253. vat_report = self._get_vat_report_tag_data(
  254. vat_report_data, tax_data, tax_detail, hide_tax_at_zero
  255. )
  256. return {
  257. "doc_ids": [wizard_id],
  258. "doc_model": "open.items.report.wizard",
  259. "docs": self.env["open.items.report.wizard"].browse(wizard_id),
  260. "company_name": company.display_name,
  261. "company_currency": company.currency_id,
  262. "currency_name": company.currency_id.name,
  263. "date_to": data["date_to"],
  264. "date_from": data["date_from"],
  265. "based_on": data["based_on"],
  266. "tax_detail": data["tax_detail"],
  267. "vat_report": vat_report,
  268. }