Browse Source

Merge PR #682 into 13.0

Signed-off-by sbidoul
pull/715/head
OCA-git-bot 4 years ago
parent
commit
74f37117aa
  1. 958
      account_financial_report/i18n/es.po
  2. 17
      account_financial_report/report/abstract_report_xlsx.py
  3. 65
      account_financial_report/report/aged_partner_balance.py
  4. 2
      account_financial_report/report/aged_partner_balance_xlsx.py
  5. 219
      account_financial_report/report/general_ledger.py
  6. 101
      account_financial_report/report/general_ledger_xlsx.py
  7. 383
      account_financial_report/report/open_items.py
  8. 74
      account_financial_report/report/open_items_xlsx.py
  9. 2
      account_financial_report/report/templates/aged_partner_balance.xml
  10. 57
      account_financial_report/report/templates/general_ledger.xml
  11. 315
      account_financial_report/report/templates/open_items.xml
  12. 263
      account_financial_report/report/trial_balance.py
  13. 148
      account_financial_report/report/vat_report.py
  14. 40
      account_financial_report/tests/test_vat_report.py
  15. 55
      account_financial_report/wizard/aged_partner_balance_wizard.py
  16. 19
      account_financial_report/wizard/aged_partner_balance_wizard_view.xml
  17. 34
      account_financial_report/wizard/general_ledger_wizard.py
  18. 40
      account_financial_report/wizard/general_ledger_wizard_view.xml
  19. 50
      account_financial_report/wizard/open_items_wizard.py
  20. 19
      account_financial_report/wizard/open_items_wizard_view.xml
  21. 28
      account_financial_report/wizard/trial_balance_wizard.py
  22. 16
      account_financial_report/wizard/trial_balance_wizard_view.xml
  23. 7
      account_financial_report/wizard/vat_report_wizard.py
  24. 9
      account_financial_report/wizard/vat_report_wizard_view.xml

958
account_financial_report/i18n/es.po
File diff suppressed because it is too large
View File

17
account_financial_report/report/abstract_report_xlsx.py

@ -440,25 +440,29 @@ class AbstractReportXslx(models.AbstractModel):
self.sheet.write_string( self.sheet.write_string(
self.row_pos, col_pos, value or "", self.format_header_right self.row_pos, col_pos, value or "", self.format_header_right
) )
elif cell_type == "currency_name":
self.sheet.write_string(
self.row_pos, col_pos, value or "", self.format_header_right
)
self.row_pos += 1 self.row_pos += 1
def _get_currency_amt_format(self, line_object): def _get_currency_amt_format(self, line_object):
""" Return amount format specific for each currency. """ """ Return amount format specific for each currency. """
if hasattr(line_object, "account_group_id") and line_object.account_group_id:
if "account_group_id" in line_object and line_object["account_group_id"]:
format_amt = self.format_amount_bold format_amt = self.format_amount_bold
field_prefix = "format_amount_bold" field_prefix = "format_amount_bold"
else: else:
format_amt = self.format_amount format_amt = self.format_amount
field_prefix = "format_amount" field_prefix = "format_amount"
if line_object.currency_id:
field_name = "{}_{}".format(field_prefix, line_object.currency_id.name)
if "currency_id" in line_object and line_object.get("currency_id", False):
field_name = "{}_{}".format(field_prefix, line_object["currency_id"].name)
if hasattr(self, field_name): if hasattr(self, field_name):
format_amt = getattr(self, field_name) format_amt = getattr(self, field_name)
else: else:
format_amt = self.workbook.add_format() format_amt = self.workbook.add_format()
self.field_name = format_amt self.field_name = format_amt
format_amount = "#,##0." + ( format_amount = "#,##0." + (
"0" * line_object.currency_id.decimal_places
"0" * line_object["currency_id"].decimal_places
) )
format_amt.set_num_format(format_amount) format_amt.set_num_format(format_amount)
return format_amt return format_amt
@ -472,7 +476,10 @@ class AbstractReportXslx(models.AbstractModel):
format_amt = self.format_amount format_amt = self.format_amount
field_prefix = "format_amount" field_prefix = "format_amount"
if line_dict.get("currency_id", False) and line_dict["currency_id"]: if line_dict.get("currency_id", False) and line_dict["currency_id"]:
currency = self.env["res.currency"].browse([line_dict["currency_id"]])
if isinstance(line_dict["currency_id"], int):
currency = self.env["res.currency"].browse(line_dict["currency_id"])
else:
currency = line_dict["currency_id"]
field_name = "{}_{}".format(field_prefix, currency.name) field_name = "{}_{}".format(field_prefix, currency.name)
if hasattr(self, field_name): if hasattr(self, field_name):
format_amt = getattr(self, field_name) format_amt = getattr(self, field_name)

65
account_financial_report/report/aged_partner_balance.py

@ -2,6 +2,7 @@
# Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com) # Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import operator
from datetime import date, datetime, timedelta from datetime import date, datetime, timedelta
from odoo import api, models from odoo import api, models
@ -63,7 +64,7 @@ class AgedPartnerBalanceReport(models.AbstractModel):
@api.model @api.model
def _get_move_lines_domain( def _get_move_lines_domain(
self, company_id, account_ids, partner_ids, only_posted_moves
self, company_id, account_ids, partner_ids, only_posted_moves, date_from
): ):
domain = [ domain = [
("account_id", "in", account_ids), ("account_id", "in", account_ids),
@ -74,6 +75,8 @@ class AgedPartnerBalanceReport(models.AbstractModel):
domain += [("partner_id", "in", partner_ids)] domain += [("partner_id", "in", partner_ids)]
if only_posted_moves: if only_posted_moves:
domain += [("move_id.state", "=", "posted")] domain += [("move_id.state", "=", "posted")]
if date_from:
domain += [("date", ">", date_from)]
return domain return domain
@api.model @api.model
@ -104,7 +107,7 @@ class AgedPartnerBalanceReport(models.AbstractModel):
return ag_pb_data return ag_pb_data
def _get_account_partial_reconciled(self, company_id, date_at_object): def _get_account_partial_reconciled(self, company_id, date_at_object):
domain = [("max_date", ">=", date_at_object), ("company_id", "=", company_id)]
domain = [("max_date", ">", date_at_object), ("company_id", "=", company_id)]
fields = ["debit_move_id", "credit_move_id", "amount"] fields = ["debit_move_id", "credit_move_id", "amount"]
accounts_partial_reconcile = self.env["account.partial.reconcile"].search_read( accounts_partial_reconcile = self.env["account.partial.reconcile"].search_read(
domain=domain, fields=fields domain=domain, fields=fields
@ -153,11 +156,14 @@ class AgedPartnerBalanceReport(models.AbstractModel):
partner_ids, partner_ids,
only_posted_moves, only_posted_moves,
): ):
reconciled_ids = list(debit_ids) + list(credit_ids)
new_ml_ids = []
for reconciled_id in reconciled_ids:
if reconciled_id not in ml_ids and reconciled_id not in new_ml_ids:
new_ml_ids += [reconciled_id]
debit_ids = set(debit_ids)
credit_ids = set(credit_ids)
in_credit_but_not_in_debit = credit_ids - debit_ids
reconciled_ids = list(debit_ids) + list(in_credit_but_not_in_debit)
reconciled_ids = set(reconciled_ids)
ml_ids = set(ml_ids)
new_ml_ids = reconciled_ids - ml_ids
new_ml_ids = list(new_ml_ids)
new_domain = self._get_new_move_lines_domain( new_domain = self._get_new_move_lines_domain(
new_ml_ids, account_ids, company_id, partner_ids, only_posted_moves new_ml_ids, account_ids, company_id, partner_ids, only_posted_moves
) )
@ -192,11 +198,12 @@ class AgedPartnerBalanceReport(models.AbstractModel):
account_ids, account_ids,
partner_ids, partner_ids,
date_at_object, date_at_object,
date_from,
only_posted_moves, only_posted_moves,
show_move_line_details, show_move_line_details,
): ):
domain = self._get_move_lines_domain( domain = self._get_move_lines_domain(
company_id, account_ids, partner_ids, only_posted_moves
company_id, account_ids, partner_ids, only_posted_moves, date_from
) )
ml_fields = [ ml_fields = [
"id", "id",
@ -225,9 +232,13 @@ class AgedPartnerBalanceReport(models.AbstractModel):
credit_amount, credit_amount,
) = self._get_account_partial_reconciled(company_id, date_at_object) ) = self._get_account_partial_reconciled(company_id, date_at_object)
if acc_partial_rec: if acc_partial_rec:
ml_ids = map(lambda r: r["id"], move_lines)
debit_ids = map(lambda r: r["debit_move_id"], acc_partial_rec)
credit_ids = map(lambda r: r["credit_move_id"], acc_partial_rec)
ml_ids = list(map(operator.itemgetter("id"), move_lines))
debit_ids = list(
map(operator.itemgetter("debit_move_id"), acc_partial_rec)
)
credit_ids = list(
map(operator.itemgetter("credit_move_id"), acc_partial_rec)
)
move_lines = self._recalculate_move_lines( move_lines = self._recalculate_move_lines(
move_lines, move_lines,
debit_ids, debit_ids,
@ -240,15 +251,12 @@ class AgedPartnerBalanceReport(models.AbstractModel):
partner_ids, partner_ids,
only_posted_moves, only_posted_moves,
) )
moves_lines_to_remove = []
for move_line in move_lines:
if move_line["date"] > date_at_object or float_is_zero(
move_line["amount_residual"], precision_digits=2
):
moves_lines_to_remove.append(move_line)
if len(moves_lines_to_remove) > 0:
for move_line_to_remove in moves_lines_to_remove:
move_lines.remove(move_line_to_remove)
move_lines = [
move_line
for move_line in move_lines
if move_line["date"] <= date_at_object
and not float_is_zero(move_line["amount_residual"], precision_digits=2)
]
for move_line in move_lines: for move_line in move_lines:
journals_ids.add(move_line["journal_id"][0]) journals_ids.add(move_line["journal_id"][0])
acc_id = move_line["account_id"][0] acc_id = move_line["account_id"][0]
@ -267,6 +275,17 @@ class AgedPartnerBalanceReport(models.AbstractModel):
ag_pb_data = self._initialize_partner(ag_pb_data, acc_id, prt_id) ag_pb_data = self._initialize_partner(ag_pb_data, acc_id, prt_id)
move_line_data = {} move_line_data = {}
if show_move_line_details: if show_move_line_details:
if move_line["ref"] == move_line["name"]:
if move_line["ref"]:
ref_label = move_line["ref"]
else:
ref_label = ""
elif not move_line["ref"]:
ref_label = move_line["name"]
elif not move_line["name"]:
ref_label = move_line["ref"]
else:
ref_label = move_line["ref"] + str(" - ") + move_line["name"]
move_line_data.update( move_line_data.update(
{ {
"date": move_line["date"], "date": move_line["date"],
@ -274,7 +293,7 @@ class AgedPartnerBalanceReport(models.AbstractModel):
"jnl_id": move_line["journal_id"][0], "jnl_id": move_line["journal_id"][0],
"acc_id": acc_id, "acc_id": acc_id,
"partner": prt_name, "partner": prt_name,
"ref": move_line["ref"],
"ref_label": ref_label,
"due_date": move_line["date_maturity"], "due_date": move_line["date_maturity"],
"residual": move_line["amount_residual"], "residual": move_line["amount_residual"],
} }
@ -367,6 +386,7 @@ class AgedPartnerBalanceReport(models.AbstractModel):
) )
self._compute_maturity_date(ml, date_at_oject) self._compute_maturity_date(ml, date_at_oject)
move_lines.append(ml) move_lines.append(ml)
move_lines = sorted(move_lines, key=lambda k: (k["date"]))
partner.update({"move_lines": move_lines}) partner.update({"move_lines": move_lines})
account["partners"].append(partner) account["partners"].append(partner)
aged_partner_data.append(account) aged_partner_data.append(account)
@ -420,7 +440,7 @@ class AgedPartnerBalanceReport(models.AbstractModel):
partner_ids = data["partner_ids"] partner_ids = data["partner_ids"]
date_at = data["date_at"] date_at = data["date_at"]
date_at_object = datetime.strptime(date_at, "%Y-%m-%d").date() date_at_object = datetime.strptime(date_at, "%Y-%m-%d").date()
date_from = data["date_from"]
only_posted_moves = data["only_posted_moves"] only_posted_moves = data["only_posted_moves"]
show_move_line_details = data["show_move_line_details"] show_move_line_details = data["show_move_line_details"]
( (
@ -433,6 +453,7 @@ class AgedPartnerBalanceReport(models.AbstractModel):
account_ids, account_ids,
partner_ids, partner_ids,
date_at_object, date_at_object,
date_from,
only_posted_moves, only_posted_moves,
show_move_line_details, show_move_line_details,
) )

2
account_financial_report/report/aged_partner_balance_xlsx.py

@ -85,7 +85,7 @@ class AgedPartnerBalanceXslx(models.AbstractModel):
2: {"header": _("Journal"), "field": "journal", "width": 8}, 2: {"header": _("Journal"), "field": "journal", "width": 8},
3: {"header": _("Account"), "field": "account", "width": 9}, 3: {"header": _("Account"), "field": "account", "width": 9},
4: {"header": _("Partner"), "field": "partner", "width": 25}, 4: {"header": _("Partner"), "field": "partner", "width": 25},
5: {"header": _("Ref - Label"), "field": "ref", "width": 40},
5: {"header": _("Ref - Label"), "field": "ref_label", "width": 40},
6: {"header": _("Due date"), "field": "due_date", "width": 11}, 6: {"header": _("Due date"), "field": "due_date", "width": 11},
7: { 7: {
"header": _("Residual"), "header": _("Residual"),

219
account_financial_report/report/general_ledger.py

@ -4,8 +4,10 @@
import calendar import calendar
import datetime import datetime
import operator
from odoo import api, models
from odoo import _, api, models
from odoo.tools import float_is_zero
class GeneralLedgerReport(models.AbstractModel): class GeneralLedgerReport(models.AbstractModel):
@ -55,6 +57,7 @@ class GeneralLedgerReport(models.AbstractModel):
"id": tax.id, "id": tax.id,
"amount": tax.amount, "amount": tax.amount,
"amount_type": tax.amount_type, "amount_type": tax.amount_type,
"display_name": tax.display_name,
} }
} }
) )
@ -62,6 +65,13 @@ class GeneralLedgerReport(models.AbstractModel):
taxes_data[tax.id]["string"] = "%" taxes_data[tax.id]["string"] = "%"
else: else:
taxes_data[tax.id]["string"] = "" taxes_data[tax.id]["string"] = ""
taxes_data[tax.id]["tax_name"] = (
tax.display_name
+ " ("
+ str(tax.amount)
+ taxes_data[tax.id]["string"]
+ ")"
)
return taxes_data return taxes_data
def _get_acc_prt_accounts_ids(self, company_id): def _get_acc_prt_accounts_ids(self, company_id):
@ -168,7 +178,6 @@ class GeneralLedgerReport(models.AbstractModel):
date_from, date_from,
foreign_currency, foreign_currency,
only_posted_moves, only_posted_moves,
hide_account_at_0,
unaffected_earnings_account, unaffected_earnings_account,
fy_start_date, fy_start_date,
analytic_tag_ids, analytic_tag_ids,
@ -301,6 +310,7 @@ class GeneralLedgerReport(models.AbstractModel):
if move_line["partner_id"] if move_line["partner_id"]
else "", else "",
"ref": "" if not move_line["ref"] else move_line["ref"], "ref": "" if not move_line["ref"] else move_line["ref"],
"name": "" if not move_line["name"] else move_line["name"],
"tax_ids": move_line["tax_ids"], "tax_ids": move_line["tax_ids"],
"debit": move_line["debit"], "debit": move_line["debit"],
"credit": move_line["credit"], "credit": move_line["credit"],
@ -314,7 +324,23 @@ class GeneralLedgerReport(models.AbstractModel):
else "", else "",
"tag_ids": move_line["analytic_tag_ids"], "tag_ids": move_line["analytic_tag_ids"],
"currency_id": move_line["currency_id"], "currency_id": move_line["currency_id"],
"analytic_account": move_line["analytic_account_id"][1]
if move_line["analytic_account_id"]
else "",
"analytic_account_id": move_line["analytic_account_id"][0]
if move_line["analytic_account_id"]
else False,
} }
if (
move_line_data["ref"] == move_line_data["name"]
or move_line_data["ref"] == ""
):
ref_label = move_line_data["name"]
elif move_line_data["name"] == "":
ref_label = move_line_data["ref"]
else:
ref_label = move_line_data["ref"] + str(" - ") + move_line_data["name"]
move_line_data.update({"ref_label": ref_label})
return move_line_data return move_line_data
@api.model @api.model
@ -383,6 +409,22 @@ class GeneralLedgerReport(models.AbstractModel):
gen_ld_data[acc_id]["fin_bal"]["bal_curr"] = 0.0 gen_ld_data[acc_id]["fin_bal"]["bal_curr"] = 0.0
return gen_ld_data return gen_ld_data
def _get_reconciled_after_date_to_ids(self, full_reconcile_ids, date_to):
full_reconcile_ids = list(full_reconcile_ids)
domain = [
("max_date", ">", date_to),
("full_reconcile_id", "in", full_reconcile_ids),
]
fields = ["full_reconcile_id"]
reconciled_after_date_to = self.env["account.partial.reconcile"].search_read(
domain=domain, fields=fields
)
rec_after_date_to_ids = list(
map(operator.itemgetter("full_reconcile_id"), reconciled_after_date_to)
)
rec_after_date_to_ids = [i[0] for i in rec_after_date_to_ids]
return rec_after_date_to_ids
def _get_period_ml_data( def _get_period_ml_data(
self, self,
account_ids, account_ids,
@ -390,13 +432,11 @@ class GeneralLedgerReport(models.AbstractModel):
company_id, company_id,
foreign_currency, foreign_currency,
only_posted_moves, only_posted_moves,
hide_account_at_0,
date_from, date_from,
date_to, date_to,
partners_data, partners_data,
gen_ld_data, gen_ld_data,
partners_ids, partners_ids,
centralize,
analytic_tag_ids, analytic_tag_ids,
cost_center_ids, cost_center_ids,
): ):
@ -427,6 +467,8 @@ class GeneralLedgerReport(models.AbstractModel):
"analytic_tag_ids", "analytic_tag_ids",
"amount_currency", "amount_currency",
"ref", "ref",
"name",
"analytic_account_id",
] ]
move_lines = self.env["account.move.line"].search_read( move_lines = self.env["account.move.line"].search_read(
domain=domain, fields=ml_fields domain=domain, fields=ml_fields
@ -497,6 +539,9 @@ class GeneralLedgerReport(models.AbstractModel):
accounts_data = self._get_accounts_data(gen_ld_data.keys()) accounts_data = self._get_accounts_data(gen_ld_data.keys())
taxes_data = self._get_taxes_data(list(taxes_ids)) taxes_data = self._get_taxes_data(list(taxes_ids))
tags_data = self._get_tags_data(list(tags_ids)) tags_data = self._get_tags_data(list(tags_ids))
rec_after_date_to_ids = self._get_reconciled_after_date_to_ids(
full_reconcile_data.keys(), date_to
)
return ( return (
gen_ld_data, gen_ld_data,
accounts_data, accounts_data,
@ -505,18 +550,66 @@ class GeneralLedgerReport(models.AbstractModel):
full_reconcile_data, full_reconcile_data,
taxes_data, taxes_data,
tags_data, tags_data,
rec_after_date_to_ids,
) )
@api.model @api.model
def _recalculate_cumul_balance(self, move_lines, last_cumul_balance):
def _recalculate_cumul_balance(
self, move_lines, last_cumul_balance, rec_after_date_to_ids
):
for move_line in move_lines: for move_line in move_lines:
move_line["balance"] += last_cumul_balance move_line["balance"] += last_cumul_balance
last_cumul_balance = move_line["balance"] last_cumul_balance = move_line["balance"]
if move_line["rec_id"] in rec_after_date_to_ids:
move_line["rec_name"] = "(" + _("future") + ") " + move_line["rec_name"]
return move_lines return move_lines
@api.model
def _create_general_ledger(self, gen_led_data, accounts_data):
def _create_account(self, account, acc_id, gen_led_data, rec_after_date_to_ids):
move_lines = []
for ml_id in gen_led_data[acc_id].keys():
if not isinstance(ml_id, int):
account.update({ml_id: gen_led_data[acc_id][ml_id]})
else:
move_lines += [gen_led_data[acc_id][ml_id]]
move_lines = sorted(move_lines, key=lambda k: (k["date"]))
move_lines = self._recalculate_cumul_balance(
move_lines,
gen_led_data[acc_id]["init_bal"]["balance"],
rec_after_date_to_ids,
)
account.update({"move_lines": move_lines})
return account
def _create_account_not_show_partner(
self, account, acc_id, gen_led_data, rec_after_date_to_ids
):
move_lines = []
for prt_id in gen_led_data[acc_id].keys():
if not isinstance(prt_id, int):
account.update({prt_id: gen_led_data[acc_id][prt_id]})
else:
for ml_id in gen_led_data[acc_id][prt_id].keys():
if isinstance(ml_id, int):
move_lines += [gen_led_data[acc_id][prt_id][ml_id]]
move_lines = sorted(move_lines, key=lambda k: (k["date"]))
move_lines = self._recalculate_cumul_balance(
move_lines,
gen_led_data[acc_id]["init_bal"]["balance"],
rec_after_date_to_ids,
)
account.update({"move_lines": move_lines, "partners": False})
return account
def _create_general_ledger(
self,
gen_led_data,
accounts_data,
show_partner_details,
rec_after_date_to_ids,
hide_account_at_0,
):
general_ledger = [] general_ledger = []
rounding = self.env.user.company_id.currency_id.rounding
for acc_id in gen_led_data.keys(): for acc_id in gen_led_data.keys():
account = {} account = {}
account.update( account.update(
@ -529,40 +622,74 @@ class GeneralLedgerReport(models.AbstractModel):
} }
) )
if not gen_led_data[acc_id]["partners"]: if not gen_led_data[acc_id]["partners"]:
move_lines = []
for ml_id in gen_led_data[acc_id].keys():
if not isinstance(ml_id, int):
account.update({ml_id: gen_led_data[acc_id][ml_id]})
else:
move_lines += [gen_led_data[acc_id][ml_id]]
move_lines = sorted(move_lines, key=lambda k: (k["date"]))
move_lines = self._recalculate_cumul_balance(
move_lines, gen_led_data[acc_id]["init_bal"]["balance"]
account = self._create_account(
account, acc_id, gen_led_data, rec_after_date_to_ids
) )
account.update({"move_lines": move_lines})
if (
hide_account_at_0
and float_is_zero(
gen_led_data[acc_id]["init_bal"]["balance"],
precision_rounding=rounding,
)
and account["move_lines"] == []
):
continue
else: else:
list_partner = []
for prt_id in gen_led_data[acc_id].keys():
partner = {}
move_lines = []
if not isinstance(prt_id, int):
account.update({prt_id: gen_led_data[acc_id][prt_id]})
else:
for ml_id in gen_led_data[acc_id][prt_id].keys():
if not isinstance(ml_id, int):
partner.update(
{ml_id: gen_led_data[acc_id][prt_id][ml_id]}
if show_partner_details:
list_partner = []
for prt_id in gen_led_data[acc_id].keys():
partner = {}
move_lines = []
if not isinstance(prt_id, int):
account.update({prt_id: gen_led_data[acc_id][prt_id]})
else:
for ml_id in gen_led_data[acc_id][prt_id].keys():
if not isinstance(ml_id, int):
partner.update(
{ml_id: gen_led_data[acc_id][prt_id][ml_id]}
)
else:
move_lines += [gen_led_data[acc_id][prt_id][ml_id]]
move_lines = sorted(move_lines, key=lambda k: (k["date"]))
move_lines = self._recalculate_cumul_balance(
move_lines,
gen_led_data[acc_id][prt_id]["init_bal"]["balance"],
rec_after_date_to_ids,
)
partner.update({"move_lines": move_lines})
if (
hide_account_at_0
and float_is_zero(
gen_led_data[acc_id][prt_id]["init_bal"]["balance"],
precision_rounding=rounding,
) )
else:
move_lines += [gen_led_data[acc_id][prt_id][ml_id]]
move_lines = sorted(move_lines, key=lambda k: (k["date"]))
move_lines = self._recalculate_cumul_balance(
move_lines,
gen_led_data[acc_id][prt_id]["init_bal"]["balance"],
and partner["move_lines"] == []
):
continue
list_partner += [partner]
account.update({"list_partner": list_partner})
if (
hide_account_at_0
and float_is_zero(
gen_led_data[acc_id]["init_bal"]["balance"],
precision_rounding=rounding,
) )
partner.update({"move_lines": move_lines})
list_partner += [partner]
account.update({"list_partner": list_partner})
and account["list_partner"] == []
):
continue
else:
account = self._create_account_not_show_partner(
account, acc_id, gen_led_data, rec_after_date_to_ids
)
if (
hide_account_at_0
and float_is_zero(
gen_led_data[acc_id]["init_bal"]["balance"],
precision_rounding=rounding,
)
and account["move_lines"] == []
):
continue
general_ledger += [account] general_ledger += [account]
return general_ledger return general_ledger
@ -581,7 +708,7 @@ class GeneralLedgerReport(models.AbstractModel):
centralized_ml[jnl_id][month].update( centralized_ml[jnl_id][month].update(
{ {
"journal_id": jnl_id, "journal_id": jnl_id,
"ref": "Centralized entries",
"ref_label": "Centralized entries",
"date": date, "date": date,
"debit": 0.0, "debit": 0.0,
"credit": 0.0, "credit": 0.0,
@ -595,6 +722,7 @@ class GeneralLedgerReport(models.AbstractModel):
"id": False, "id": False,
"tag_ids": False, "tag_ids": False,
"currency_id": False, "currency_id": False,
"analytic_account_id": False,
} }
) )
centralized_ml[jnl_id][month]["debit"] += move_line["debit"] centralized_ml[jnl_id][month]["debit"] += move_line["debit"]
@ -640,6 +768,7 @@ class GeneralLedgerReport(models.AbstractModel):
account_ids = data["account_ids"] account_ids = data["account_ids"]
analytic_tag_ids = data["analytic_tag_ids"] analytic_tag_ids = data["analytic_tag_ids"]
cost_center_ids = data["cost_center_ids"] cost_center_ids = data["cost_center_ids"]
show_partner_details = data["show_partner_details"]
hide_account_at_0 = data["hide_account_at_0"] hide_account_at_0 = data["hide_account_at_0"]
foreign_currency = data["foreign_currency"] foreign_currency = data["foreign_currency"]
only_posted_moves = data["only_posted_moves"] only_posted_moves = data["only_posted_moves"]
@ -652,7 +781,6 @@ class GeneralLedgerReport(models.AbstractModel):
date_from, date_from,
foreign_currency, foreign_currency,
only_posted_moves, only_posted_moves,
hide_account_at_0,
unaffected_earnings_account, unaffected_earnings_account,
fy_start_date, fy_start_date,
analytic_tag_ids, analytic_tag_ids,
@ -667,23 +795,28 @@ class GeneralLedgerReport(models.AbstractModel):
full_reconcile_data, full_reconcile_data,
taxes_data, taxes_data,
tags_data, tags_data,
rec_after_date_to_ids,
) = self._get_period_ml_data( ) = self._get_period_ml_data(
account_ids, account_ids,
partner_ids, partner_ids,
company_id, company_id,
foreign_currency, foreign_currency,
only_posted_moves, only_posted_moves,
hide_account_at_0,
date_from, date_from,
date_to, date_to,
partners_data, partners_data,
gen_ld_data, gen_ld_data,
partners_ids, partners_ids,
centralize,
analytic_tag_ids, analytic_tag_ids,
cost_center_ids, cost_center_ids,
) )
general_ledger = self._create_general_ledger(gen_ld_data, accounts_data)
general_ledger = self._create_general_ledger(
gen_ld_data,
accounts_data,
show_partner_details,
rec_after_date_to_ids,
hide_account_at_0,
)
if centralize: if centralize:
for account in general_ledger: for account in general_ledger:
if account["centralized"]: if account["centralized"]:
@ -692,6 +825,7 @@ class GeneralLedgerReport(models.AbstractModel):
account["move_lines"] = self._recalculate_cumul_balance( account["move_lines"] = self._recalculate_cumul_balance(
account["move_lines"], account["move_lines"],
gen_ld_data[account["id"]]["init_bal"]["balance"], gen_ld_data[account["id"]]["init_bal"]["balance"],
rec_after_date_to_ids,
) )
if account["partners"]: if account["partners"]:
account["partners"] = False account["partners"] = False
@ -710,6 +844,7 @@ class GeneralLedgerReport(models.AbstractModel):
"only_posted_moves": data["only_posted_moves"], "only_posted_moves": data["only_posted_moves"],
"hide_account_at_0": data["hide_account_at_0"], "hide_account_at_0": data["hide_account_at_0"],
"show_analytic_tags": data["show_analytic_tags"], "show_analytic_tags": data["show_analytic_tags"],
"show_cost_center": data["show_cost_center"],
"general_ledger": general_ledger, "general_ledger": general_ledger,
"accounts_data": accounts_data, "accounts_data": accounts_data,
"partners_data": partners_data, "partners_data": partners_data,

101
account_financial_report/report/general_ledger_xlsx.py

@ -21,18 +21,30 @@ class GeneralLedgerXslx(models.AbstractModel):
return report_name return report_name
def _get_report_columns(self, report): def _get_report_columns(self, report):
res = {
0: {"header": _("Date"), "field": "date", "width": 11},
1: {"header": _("Entry"), "field": "entry", "width": 18},
2: {"header": _("Journal"), "field": "journal", "width": 8},
3: {"header": _("Account"), "field": "account", "width": 9},
4: {"header": _("Taxes"), "field": "taxes_description", "width": 15},
5: {"header": _("Partner"), "field": "partner_name", "width": 25},
6: {"header": _("Ref - Label"), "field": "ref", "width": 40},
7: {"header": _("Cost center"), "field": "cost_center", "width": 15},
8: {"header": _("Tags"), "field": "tags", "width": 10},
9: {"header": _("Rec."), "field": "rec_name", "width": 5},
10: {
res = [
{"header": _("Date"), "field": "date", "width": 11},
{"header": _("Entry"), "field": "entry", "width": 18},
{"header": _("Journal"), "field": "journal", "width": 8},
{"header": _("Account"), "field": "account", "width": 9},
{"header": _("Taxes"), "field": "taxes_description", "width": 15},
{"header": _("Partner"), "field": "partner_name", "width": 25},
{"header": _("Ref - Label"), "field": "ref_label", "width": 40},
]
if report.show_cost_center:
res += [
{
"header": _("Analytic Account"),
"field": "analytic_account",
"width": 20,
},
]
if report.show_analytic_tags:
res += [
{"header": _("Tags"), "field": "tags", "width": 10},
]
res += [
{"header": _("Rec."), "field": "rec_name", "width": 15},
{
"header": _("Debit"), "header": _("Debit"),
"field": "debit", "field": "debit",
"field_initial_balance": "initial_debit", "field_initial_balance": "initial_debit",
@ -40,7 +52,7 @@ class GeneralLedgerXslx(models.AbstractModel):
"type": "amount", "type": "amount",
"width": 14, "width": 14,
}, },
11: {
{
"header": _("Credit"), "header": _("Credit"),
"field": "credit", "field": "credit",
"field_initial_balance": "initial_credit", "field_initial_balance": "initial_credit",
@ -48,7 +60,7 @@ class GeneralLedgerXslx(models.AbstractModel):
"type": "amount", "type": "amount",
"width": 14, "width": 14,
}, },
12: {
{
"header": _("Cumul. Bal."), "header": _("Cumul. Bal."),
"field": "balance", "field": "balance",
"field_initial_balance": "initial_balance", "field_initial_balance": "initial_balance",
@ -56,17 +68,17 @@ class GeneralLedgerXslx(models.AbstractModel):
"type": "amount", "type": "amount",
"width": 14, "width": 14,
}, },
}
]
if report.foreign_currency: if report.foreign_currency:
foreign_currency = {
13: {
res += [
{
"header": _("Cur."), "header": _("Cur."),
"field": "currency_name", "field": "currency_name",
"field_currency_balance": "currency_name", "field_currency_balance": "currency_name",
"type": "currency_name", "type": "currency_name",
"width": 7, "width": 7,
}, },
14: {
{
"header": _("Amount cur."), "header": _("Amount cur."),
"field": "bal_curr", "field": "bal_curr",
"field_initial_balance": "initial_bal_curr", "field_initial_balance": "initial_bal_curr",
@ -74,9 +86,11 @@ class GeneralLedgerXslx(models.AbstractModel):
"type": "amount_currency", "type": "amount_currency",
"width": 14, "width": 14,
}, },
}
res = {**res, **foreign_currency}
return res
]
res_as_dict = {}
for i, column in enumerate(res):
res_as_dict[i] = column
return res_as_dict
def _get_report_filters(self, report): def _get_report_filters(self, report):
return [ return [
@ -173,20 +187,15 @@ class GeneralLedgerXslx(models.AbstractModel):
"currency_id": line["currency_id"][0], "currency_id": line["currency_id"][0],
} }
) )
if line["ref"] != "Centralized entries":
if line["ref_label"] != "Centralized entries":
taxes_description = "" taxes_description = ""
tags = "" tags = ""
for tax_id in line["tax_ids"]: for tax_id in line["tax_ids"]:
taxes_description += (
str(taxes_data[tax_id]["amount"])
+ " "
+ taxes_data[tax_id]["string"]
+ " "
)
taxes_description += taxes_data[tax_id]["tax_name"] + " "
for tag_id in line["tag_ids"]: for tag_id in line["tag_ids"]:
tags += tags_data[tag_id]["name"] + " " tags += tags_data[tag_id]["name"] + " "
line.update( line.update(
{"taxes_description": taxes_description, "tags": tags}
{"taxes_description": taxes_description, "tags": tags,}
) )
self.write_line_from_dict(line) self.write_line_from_dict(line)
# Display ending balance line for account # Display ending balance line for account
@ -225,7 +234,7 @@ class GeneralLedgerXslx(models.AbstractModel):
) )
if foreign_currency: if foreign_currency:
partner.update( partner.update(
{"initial_bal_culrr": partner["init_bal"]["bal_curr"]}
{"initial_bal_curr": partner["init_bal"]["bal_curr"],}
) )
self.write_initial_balance_from_dict(partner) self.write_initial_balance_from_dict(partner)
@ -237,20 +246,24 @@ class GeneralLedgerXslx(models.AbstractModel):
"journal": journals_data[line["journal_id"]]["code"], "journal": journals_data[line["journal_id"]]["code"],
} }
) )
if line["ref"] != "Centralized entries":
if line["currency_id"]:
line.update(
{
"currency_name": line["currency_id"][1],
"currency_id": line["currency_id"][0],
}
)
if line["ref_label"] != "Centralized entries":
taxes_description = "" taxes_description = ""
tags = "" tags = ""
for tax_id in line["tax_ids"]: for tax_id in line["tax_ids"]:
taxes_description += ( taxes_description += (
str(taxes_data[tax_id]["amount"])
+ " "
+ taxes_data[tax_id]["string"]
+ " "
taxes_data[tax_id]["tax_name"] + " "
) )
for tag_id in line["tag_ids"]: for tag_id in line["tag_ids"]:
tags += tags_data[tag_id]["name"] + " " tags += tags_data[tag_id]["name"] + " "
line.update( line.update(
{"taxes_description": taxes_description, "tags": tags}
{"taxes_description": taxes_description, "tags": tags,}
) )
self.write_line_from_dict(line) self.write_line_from_dict(line)
@ -262,9 +275,13 @@ class GeneralLedgerXslx(models.AbstractModel):
"final_balance": partner["fin_bal"]["balance"], "final_balance": partner["fin_bal"]["balance"],
} }
) )
if foreign_currency:
if foreign_currency and partner["currency_id"]:
partner.update( partner.update(
{"final_bal_curr": partner["fin_bal"]["bal_curr"]}
{
"final_bal_curr": partner["fin_bal"]["bal_curr"],
"currency_name": partner["currency_id"].name,
"currency_id": partner["currency_id"].id,
}
) )
self.write_ending_balance_from_dict(partner) self.write_ending_balance_from_dict(partner)
@ -279,9 +296,13 @@ class GeneralLedgerXslx(models.AbstractModel):
"final_balance": account["fin_bal"]["balance"], "final_balance": account["fin_bal"]["balance"],
} }
) )
if foreign_currency:
if foreign_currency and account["currency_id"]:
account.update( account.update(
{"final_bal_curr": account["fin_bal"]["bal_curr"],}
{
"final_bal_curr": account["fin_bal"]["bal_curr"],
"currency_name": account["currency_id"].name,
"currency_id": account["currency_id"].id,
}
) )
self.write_ending_balance_from_dict(account) self.write_ending_balance_from_dict(account)

383
account_financial_report/report/open_items.py

@ -6,7 +6,6 @@ import operator
from datetime import date, datetime from datetime import date, datetime
from odoo import api, models from odoo import api, models
from odoo.osv import expression
from odoo.tools import float_is_zero from odoo.tools import float_is_zero
@ -31,137 +30,113 @@ class OpenItemsReport(models.AbstractModel):
).render(rcontext) ).render(rcontext)
return result return result
def _get_account_partial_reconciled(self, move_lines_data, date_at_object):
reconciled_ids = []
for move_line in move_lines_data:
if move_line["reconciled"]:
reconciled_ids += [move_line["id"]]
domain = [("max_date", ">=", date_at_object)]
domain += expression.OR(
[
[("debit_move_id", "in", reconciled_ids)],
[("credit_move_id", "in", reconciled_ids)],
]
)
def _get_account_partial_reconciled(self, company_id, date_at_object):
domain = [("max_date", ">", date_at_object), ("company_id", "=", company_id)]
fields = ["debit_move_id", "credit_move_id", "amount"] fields = ["debit_move_id", "credit_move_id", "amount"]
accounts_partial_reconcile = self.env["account.partial.reconcile"].search_read( accounts_partial_reconcile = self.env["account.partial.reconcile"].search_read(
domain=domain, fields=fields domain=domain, fields=fields
) )
debit_accounts_partial_amount = {}
credit_accounts_partial_amount = {}
debit_amount = {}
credit_amount = {}
for account_partial_reconcile_data in accounts_partial_reconcile: for account_partial_reconcile_data in accounts_partial_reconcile:
debit_move_id = account_partial_reconcile_data["debit_move_id"][0] debit_move_id = account_partial_reconcile_data["debit_move_id"][0]
credit_move_id = account_partial_reconcile_data["credit_move_id"][0] credit_move_id = account_partial_reconcile_data["credit_move_id"][0]
if debit_move_id not in debit_accounts_partial_amount.keys():
debit_accounts_partial_amount[debit_move_id] = 0.0
debit_accounts_partial_amount[
debit_move_id
] += account_partial_reconcile_data["amount"]
if credit_move_id not in credit_accounts_partial_amount.keys():
credit_accounts_partial_amount[credit_move_id] = 0.0
credit_accounts_partial_amount[
credit_move_id
] += account_partial_reconcile_data["amount"]
if debit_move_id not in debit_amount.keys():
debit_amount[debit_move_id] = 0.0
debit_amount[debit_move_id] += account_partial_reconcile_data["amount"]
if credit_move_id not in credit_amount.keys():
credit_amount[credit_move_id] = 0.0
credit_amount[credit_move_id] += account_partial_reconcile_data["amount"]
account_partial_reconcile_data.update( account_partial_reconcile_data.update(
{"debit_move_id": debit_move_id, "credit_move_id": credit_move_id} {"debit_move_id": debit_move_id, "credit_move_id": credit_move_id}
) )
return (
accounts_partial_reconcile,
debit_accounts_partial_amount,
credit_accounts_partial_amount,
)
return accounts_partial_reconcile, debit_amount, credit_amount
@api.model @api.model
def _get_query_domain(
self,
account_ids,
partner_ids,
date_at_object,
target_move,
company_id,
date_from,
def _get_new_move_lines_domain(
self, new_ml_ids, account_ids, company_id, partner_ids, target_moves
): ):
query = """
WHERE aml.account_id in %s and aml.company_id = %s
""" % (
tuple(account_ids) if len(account_ids) > 1 else "(%s)" % account_ids[0],
company_id,
)
if date_from:
query += " and aml.date >= '%s'" % date_from
domain = [
("account_id", "in", account_ids),
("company_id", "=", company_id),
("id", "in", new_ml_ids),
]
if partner_ids: if partner_ids:
query += " and aml.partner_id in {}".format(tuple(partner_ids))
if target_move == "posted":
query += " and am.state = 'posted'"
if date_at_object >= date.today():
query += " and aml.reconciled IS FALSE"
else:
query += (
""" and ((aml.reconciled IS FALSE OR aml.date >= '%s')
OR aml.full_reconcile_id IS NOT NULL)"""
% date_at_object
)
return query
domain += [("partner_id", "in", partner_ids)]
if target_moves == "posted":
domain += [("move_id.state", "=", "posted")]
return domain
@api.model
def _get_query(
def _recalculate_move_lines(
self, self,
move_lines,
debit_ids,
credit_ids,
debit_amount,
credit_amount,
ml_ids,
account_ids, account_ids,
partner_ids,
date_at_object,
target_move,
company_id, company_id,
date_from,
partner_ids,
target_moves,
): ):
aml_fields = [
debit_ids = set(debit_ids)
credit_ids = set(credit_ids)
in_credit_but_not_in_debit = credit_ids - debit_ids
reconciled_ids = list(debit_ids) + list(in_credit_but_not_in_debit)
reconciled_ids = set(reconciled_ids)
ml_ids = set(ml_ids)
new_ml_ids = reconciled_ids - ml_ids
new_ml_ids = list(new_ml_ids)
new_domain = self._get_new_move_lines_domain(
new_ml_ids, account_ids, company_id, partner_ids, target_moves
)
ml_fields = [
"id", "id",
"name",
"date", "date",
"move_id", "move_id",
"journal_id", "journal_id",
"account_id", "account_id",
"partner_id", "partner_id",
"ref",
"date_maturity",
"amount_residual", "amount_residual",
"amount_currency",
"amount_residual_currency",
"date_maturity",
"ref",
"debit", "debit",
"credit", "credit",
"currency_id",
"reconciled", "reconciled",
"full_reconcile_id",
"currency_id",
"amount_currency",
"amount_residual_currency",
] ]
query = ""
# SELECT
for field in aml_fields:
if not query:
query = "SELECT aml.%s" % field
else:
query += ", aml.%s" % field
# name from res_partner
query += ", rp.name as partner_name"
# name from res_currency
query += ", rc.name as currency_name"
# state and name from account_move
query += ", am.state, am.name as move_name"
# FROM
query += """
FROM account_move_line as aml
LEFT JOIN res_partner as rp
ON aml.partner_id = rp.id
LEFT JOIN res_currency as rc
ON aml.currency_id = rc.id
LEFT JOIN account_move as am
ON am.id = aml.move_id
"""
# WHERE
query += self._get_query_domain(
account_ids, partner_ids, date_at_object, target_move, company_id, date_from
new_move_lines = self.env["account.move.line"].search_read(
domain=new_domain, fields=ml_fields
) )
return query
move_lines = move_lines + new_move_lines
for move_line in move_lines:
ml_id = move_line["id"]
if ml_id in debit_ids:
move_line["amount_residual"] += debit_amount[ml_id]
if ml_id in credit_ids:
move_line["amount_residual"] -= credit_amount[ml_id]
return move_lines
@api.model
def _get_move_lines_domain(
self, company_id, account_ids, partner_ids, target_move, date_from
):
domain = [
("account_id", "in", account_ids),
("company_id", "=", company_id),
("reconciled", "=", False),
]
if partner_ids:
domain += [("partner_id", "in", partner_ids)]
if target_move == "posted":
domain += [("move_id.state", "=", "posted")]
if date_from:
domain += [("date", ">", date_from)]
return domain
def _get_accounts_data(self, accounts_ids): def _get_accounts_data(self, accounts_ids):
accounts = self.env["account.account"].browse(accounts_ids) accounts = self.env["account.account"].browse(accounts_ids)
@ -188,7 +163,6 @@ class OpenItemsReport(models.AbstractModel):
journals_data.update({journal.id: {"id": journal.id, "code": journal.code}}) journals_data.update({journal.id: {"id": journal.id, "code": journal.code}})
return journals_data return journals_data
# flake8: noqa: C901
def _get_data( def _get_data(
self, self,
account_ids, account_ids,
@ -198,69 +172,80 @@ class OpenItemsReport(models.AbstractModel):
company_id, company_id,
date_from, date_from,
): ):
query = self._get_query(
account_ids, partner_ids, date_at_object, target_move, company_id, date_from
domain = self._get_move_lines_domain(
company_id, account_ids, partner_ids, target_move, date_from
) )
self._cr.execute(query)
move_lines_data = self._cr.dictfetchall()
account_ids = map(lambda r: r["account_id"], move_lines_data)
accounts_data = self._get_accounts_data(list(account_ids))
journal_ids = map(lambda r: r["journal_id"], move_lines_data)
journals_data = self._get_journals_data(list(journal_ids))
ml_fields = [
"id",
"name",
"date",
"move_id",
"journal_id",
"account_id",
"partner_id",
"amount_residual",
"date_maturity",
"ref",
"debit",
"credit",
"reconciled",
"currency_id",
"amount_currency",
"amount_residual_currency",
]
move_lines = self.env["account.move.line"].search_read(
domain=domain, fields=ml_fields
)
journals_ids = set()
partners_ids = set()
partners_data = {}
if date_at_object < date.today(): if date_at_object < date.today():
( (
accounts_partial_reconcile,
debit_accounts_partial_amount,
credit_accounts_partial_amount,
) = self._get_account_partial_reconciled(move_lines_data, date_at_object)
if accounts_partial_reconcile:
debit_ids = map(
operator.itemgetter("debit_move_id"), accounts_partial_reconcile
acc_partial_rec,
debit_amount,
credit_amount,
) = self._get_account_partial_reconciled(company_id, date_at_object)
if acc_partial_rec:
ml_ids = list(map(operator.itemgetter("id"), move_lines))
debit_ids = list(
map(operator.itemgetter("debit_move_id"), acc_partial_rec)
)
credit_ids = list(
map(operator.itemgetter("credit_move_id"), acc_partial_rec)
) )
credit_ids = map(
operator.itemgetter("credit_move_id"), accounts_partial_reconcile
move_lines = self._recalculate_move_lines(
move_lines,
debit_ids,
credit_ids,
debit_amount,
credit_amount,
ml_ids,
account_ids,
company_id,
partner_ids,
target_move,
) )
for move_line in move_lines_data:
if move_line["id"] in debit_ids:
move_line["amount_residual"] += debit_accounts_partial_amount[
move_line["id"]
]
if move_line["id"] in credit_ids:
move_line["amount_residual"] -= credit_accounts_partial_amount[
move_line["id"]
]
moves_lines_to_remove = []
for move_line in move_lines_data:
if move_line["date"] > date_at_object or float_is_zero(
move_line["amount_residual"], precision_digits=2
):
moves_lines_to_remove.append(move_line)
if len(moves_lines_to_remove) > 0:
for move_line_to_remove in moves_lines_to_remove:
move_lines_data.remove(move_line_to_remove)
partners_data = {0: {"id": 0, "name": "Missing Partner"}}
move_lines = [
move_line
for move_line in move_lines
if move_line["date"] <= date_at_object
and not float_is_zero(move_line["amount_residual"], precision_digits=2)
]
open_items_move_lines_data = {} open_items_move_lines_data = {}
for move_line in move_lines_data:
no_partner = True
for move_line in move_lines:
journals_ids.add(move_line["journal_id"][0])
acc_id = move_line["account_id"][0]
# Partners data # Partners data
if move_line["partner_id"]: if move_line["partner_id"]:
no_partner = False
partners_data.update(
{
move_line["partner_id"]: {
"id": move_line["partner_id"],
"name": move_line["partner_name"],
"currency_id": accounts_data[move_line["account_id"]][
"currency_id"
],
}
}
)
prt_id = move_line["partner_id"][0]
prt_name = move_line["partner_id"][1]
else: else:
partners_data[0]["currency_id"] = accounts_data[
move_line["account_id"]
]["currency_id"]
prt_id = 0
prt_name = "Missing Partner"
if prt_id not in partners_ids:
partners_data.update({prt_id: {"id": prt_id, "name": prt_name}})
partners_ids.add(prt_id)
# Move line update # Move line update
original = 0 original = 0
@ -269,39 +254,51 @@ class OpenItemsReport(models.AbstractModel):
original = move_line["credit"] * (-1) original = move_line["credit"] * (-1)
if not float_is_zero(move_line["debit"], precision_digits=2): if not float_is_zero(move_line["debit"], precision_digits=2):
original = move_line["debit"] original = move_line["debit"]
if move_line["ref"] == move_line["name"]:
if move_line["ref"]:
ref_label = move_line["ref"]
else:
ref_label = ""
elif not move_line["ref"]:
ref_label = move_line["name"]
elif not move_line["name"]:
ref_label = move_line["ref"]
else:
ref_label = move_line["ref"] + str(" - ") + move_line["name"]
move_line.update( move_line.update(
{ {
"date": move_line["date"].strftime("%d/%m/%Y"),
"date": move_line["date"],
"date_maturity": move_line["date_maturity"] "date_maturity": move_line["date_maturity"]
and move_line["date_maturity"].strftime("%d/%m/%Y"), and move_line["date_maturity"].strftime("%d/%m/%Y"),
"original": original, "original": original,
"partner_id": 0 if no_partner else move_line["partner_id"],
"partner_name": "" if no_partner else move_line["partner_name"],
"ref": "" if not move_line["ref"] else move_line["ref"],
"account": accounts_data[move_line["account_id"]]["code"],
"journal": journals_data[move_line["journal_id"]]["code"],
"partner_id": prt_id,
"partner_name": prt_name,
"ref_label": ref_label,
"journal_id": move_line["journal_id"][0],
"move_name": move_line["move_id"][1],
"currency_id": move_line["currency_id"][0]
if move_line["currency_id"]
else False,
"currency_name": move_line["currency_id"][1]
if move_line["currency_id"]
else False,
} }
) )
# Open Items Move Lines Data # Open Items Move Lines Data
if move_line["account_id"] not in open_items_move_lines_data.keys():
open_items_move_lines_data[move_line["account_id"]] = {
move_line["partner_id"]: [move_line]
}
if acc_id not in open_items_move_lines_data.keys():
open_items_move_lines_data[acc_id] = {prt_id: [move_line]}
else: else:
if (
move_line["partner_id"]
not in open_items_move_lines_data[move_line["account_id"]].keys()
):
open_items_move_lines_data[move_line["account_id"]][
move_line["partner_id"]
] = [move_line]
if prt_id not in open_items_move_lines_data[acc_id].keys():
open_items_move_lines_data[acc_id][prt_id] = [move_line]
else: else:
open_items_move_lines_data[move_line["account_id"]][
move_line["partner_id"]
].append(move_line)
open_items_move_lines_data[acc_id][prt_id].append(move_line)
journals_data = self._get_journals_data(list(journals_ids))
accounts_data = self._get_accounts_data(open_items_move_lines_data.keys())
return ( return (
move_lines_data,
move_lines,
partners_data, partners_data,
journals_data, journals_data,
accounts_data, accounts_data,
@ -324,6 +321,32 @@ class OpenItemsReport(models.AbstractModel):
total_amount[account_id]["residual"] += move_line["amount_residual"] total_amount[account_id]["residual"] += move_line["amount_residual"]
return total_amount return total_amount
@api.model
def _order_open_items_by_date(
self, open_items_move_lines_data, show_partner_details
):
new_open_items = {}
if not show_partner_details:
for acc_id in open_items_move_lines_data.keys():
new_open_items[acc_id] = {}
move_lines = []
for prt_id in open_items_move_lines_data[acc_id]:
for move_line in open_items_move_lines_data[acc_id][prt_id]:
move_lines += [move_line]
move_lines = sorted(move_lines, key=lambda k: (k["date"]))
new_open_items[acc_id] = move_lines
else:
for acc_id in open_items_move_lines_data.keys():
new_open_items[acc_id] = {}
for prt_id in open_items_move_lines_data[acc_id]:
new_open_items[acc_id][prt_id] = {}
move_lines = []
for move_line in open_items_move_lines_data[acc_id][prt_id]:
move_lines += [move_line]
move_lines = sorted(move_lines, key=lambda k: (k["date"]))
new_open_items[acc_id][prt_id] = move_lines
return new_open_items
def _get_report_values(self, docids, data): def _get_report_values(self, docids, data):
wizard_id = data["wizard_id"] wizard_id = data["wizard_id"]
company = self.env["res.company"].browse(data["company_id"]) company = self.env["res.company"].browse(data["company_id"])
@ -334,6 +357,7 @@ class OpenItemsReport(models.AbstractModel):
date_at_object = datetime.strptime(date_at, "%Y-%m-%d").date() date_at_object = datetime.strptime(date_at, "%Y-%m-%d").date()
date_from = data["date_from"] date_from = data["date_from"]
target_move = data["target_move"] target_move = data["target_move"]
show_partner_details = data["show_partner_details"]
( (
move_lines_data, move_lines_data,
@ -346,16 +370,21 @@ class OpenItemsReport(models.AbstractModel):
) )
total_amount = self._calculate_amounts(open_items_move_lines_data) total_amount = self._calculate_amounts(open_items_move_lines_data)
open_items_move_lines_data = self._order_open_items_by_date(
open_items_move_lines_data, show_partner_details
)
return { return {
"doc_ids": [wizard_id], "doc_ids": [wizard_id],
"doc_model": "open.items.report.wizard", "doc_model": "open.items.report.wizard",
"docs": self.env["open.items.report.wizard"].browse(wizard_id), "docs": self.env["open.items.report.wizard"].browse(wizard_id),
"foreign_currency": data["foreign_currency"], "foreign_currency": data["foreign_currency"],
"show_partner_details": data["show_partner_details"],
"company_name": company.display_name, "company_name": company.display_name,
"currency_name": company.currency_id.name, "currency_name": company.currency_id.name,
"date_at": date_at_object.strftime("%d/%m/%Y"), "date_at": date_at_object.strftime("%d/%m/%Y"),
"hide_account_at_0": data["hide_account_at_0"], "hide_account_at_0": data["hide_account_at_0"],
"target_move": data["target_move"], "target_move": data["target_move"],
"journals_data": journals_data,
"partners_data": partners_data, "partners_data": partners_data,
"accounts_data": accounts_data, "accounts_data": accounts_data,
"total_amount": total_amount, "total_amount": total_amount,

74
account_financial_report/report/open_items_xlsx.py

@ -22,11 +22,11 @@ class OpenItemsXslx(models.AbstractModel):
def _get_report_columns(self, report): def _get_report_columns(self, report):
res = { res = {
0: {"header": _("Date"), "field": "date", "width": 11}, 0: {"header": _("Date"), "field": "date", "width": 11},
1: {"header": _("Entry"), "field": "move_id_name", "width": 18},
1: {"header": _("Entry"), "field": "move_name", "width": 18},
2: {"header": _("Journal"), "field": "journal", "width": 8}, 2: {"header": _("Journal"), "field": "journal", "width": 8},
3: {"header": _("Account"), "field": "account", "width": 9}, 3: {"header": _("Account"), "field": "account", "width": 9},
4: {"header": _("Partner"), "field": "partner", "width": 25},
5: {"header": _("Ref - Label"), "field": "ref", "width": 40},
4: {"header": _("Partner"), "field": "partner_name", "width": 25},
5: {"header": _("Ref - Label"), "field": "ref_label", "width": 40},
6: {"header": _("Due date"), "field": "date_maturity", "width": 11}, 6: {"header": _("Due date"), "field": "date_maturity", "width": 11},
7: { 7: {
"header": _("Original"), "header": _("Original"),
@ -108,7 +108,9 @@ class OpenItemsXslx(models.AbstractModel):
Open_items = res_data["Open_Items"] Open_items = res_data["Open_Items"]
accounts_data = res_data["accounts_data"] accounts_data = res_data["accounts_data"]
partners_data = res_data["partners_data"] partners_data = res_data["partners_data"]
journals_data = res_data["journals_data"]
total_amount = res_data["total_amount"] total_amount = res_data["total_amount"]
show_partner_details = res_data["show_partner_details"]
for account_id in Open_items.keys(): for account_id in Open_items.keys():
# Write account title # Write account title
self.write_array_title( self.write_array_title(
@ -119,30 +121,60 @@ class OpenItemsXslx(models.AbstractModel):
# For each partner # For each partner
if Open_items[account_id]: if Open_items[account_id]:
for partner_id in Open_items[account_id]:
type_object = "partner"
# Write partner title
self.write_array_title(partners_data[partner_id]["name"])
if show_partner_details:
for partner_id in Open_items[account_id]:
type_object = "partner"
# Write partner title
self.write_array_title(partners_data[partner_id]["name"])
# Display array header for move lines
self.write_array_header()
# Display account move lines
for line in Open_items[account_id][partner_id]:
line.update(
{
"account": accounts_data[account_id]["code"],
"journal": journals_data[line["journal_id"]][
"code"
],
}
)
self.write_line_from_dict(line)
# Display ending balance line for partner
partners_data[partner_id].update(
{
"currency_id": accounts_data[account_id]["currency_id"],
"currency_name": accounts_data[account_id][
"currency_name"
],
}
)
self.write_ending_balance_from_dict(
partners_data[partner_id],
type_object,
total_amount,
account_id,
partner_id,
)
# Line break
self.row_pos += 1
else:
# Display array header for move lines # Display array header for move lines
self.write_array_header() self.write_array_header()
# Display account move lines # Display account move lines
for line in Open_items[account_id][partner_id]:
for line in Open_items[account_id]:
line.update(
{
"account": accounts_data[account_id]["code"],
"journal": journals_data[line["journal_id"]]["code"],
}
)
self.write_line_from_dict(line) self.write_line_from_dict(line)
# Display ending balance line for partner
self.write_ending_balance_from_dict(
partners_data[partner_id],
type_object,
total_amount,
account_id,
partner_id,
)
# Line break
self.row_pos += 1
# Display ending balance line for account # Display ending balance line for account
type_object = "account" type_object = "account"
self.write_ending_balance_from_dict( self.write_ending_balance_from_dict(

2
account_financial_report/report/templates/aged_partner_balance.xml

@ -295,7 +295,7 @@
<!-- t-att-data-res-model="'account.move.line'"--> <!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action"--> <!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">--> <!-- style="color: black;">-->
<t t-raw="line['ref']" />
<t t-raw="line['ref_label']" />
<!-- </a>--> <!-- </a>-->
<!-- </span>--> <!-- </span>-->
</div> </div>

57
account_financial_report/report/templates/general_ledger.xml

@ -85,20 +85,20 @@
/> />
<t t-set="type" t-value='"partner_type"' /> <t t-set="type" t-value='"partner_type"' />
</t> </t>
<!-- Display account footer -->
<t t-if="not filter_partner_ids">
<t
t-call="account_financial_report.report_general_ledger_ending_cumul"
>
<t
t-set="account_or_partner_object"
t-value="account"
/>
<t t-set="type" t-value='"account_type"' />
</t>
</t>
</div> </div>
</t> </t>
<!-- Display account footer -->
<t t-if="not filter_partner_ids">
<t
t-call="account_financial_report.report_general_ledger_ending_cumul"
>
<t
t-set="account_or_partner_object"
t-value="account"
/>
<t t-set="type" t-value='"account_type"' />
</t>
</t>
</t> </t>
</div> </div>
</t> </t>
@ -160,8 +160,10 @@
Label</div> Label</div>
<t t-if="show_cost_center"> <t t-if="show_cost_center">
<!--## cost_center--> <!--## cost_center-->
<div class="act_as_cell" style="width: 8.03%;">Cost
center</div>
<div
class="act_as_cell"
style="width: 8.03%;"
>Analytic Account</div>
</t> </t>
<t t-if="show_analytic_tags"> <t t-if="show_analytic_tags">
<!--## analytic tags--> <!--## analytic tags-->
@ -357,7 +359,7 @@
> >
<div class="act_as_cell amount" style="width: 2.08%;"> <div class="act_as_cell amount" style="width: 2.08%;">
<span <span
t-field="o._get_atr_from_dict(account['id'], accounts_data, 'currency_name')"
t-esc="o._get_atr_from_dict(account['id'], accounts_data, 'currency_name')"
/> />
</div> </div>
<div class="act_as_cell amount" style="width: 5.19%;"> <div class="act_as_cell amount" style="width: 5.19%;">
@ -376,7 +378,7 @@
> >
<t <t
t-raw="account_or_partner_object['init_bal']['bal_curr']" t-raw="account_or_partner_object['init_bal']['bal_curr']"
t-options="{'widget': 'monetary', 'display_currency': account.account_id.currency_id}"
t-options="{'widget': 'monetary', 'display_currency': o._get_atr_from_dict(account['id'], accounts_data, 'currency_id')}"
/> />
</a> </a>
</span> </span>
@ -397,7 +399,7 @@
> >
<t <t
t-raw="account_or_partner_object['init_bal']['bal_curr']" t-raw="account_or_partner_object['init_bal']['bal_curr']"
t-options="{'widget': 'monetary', 'display_currency': account.account_id.currency_id}"
t-options="{'widget': 'monetary', 'display_currency': o._get_atr_from_dict(account['id'], accounts_data, 'currency_id')}"
/> />
</a> </a>
</span> </span>
@ -501,10 +503,7 @@
<t t-if="taxes_data and line['tax_ids']"> <t t-if="taxes_data and line['tax_ids']">
<t t-foreach="line['tax_ids']" t-as="tax_id"> <t t-foreach="line['tax_ids']" t-as="tax_id">
<span <span
t-esc="o._get_atr_from_dict(tax_id, taxes_data, 'amount')"
/>
<span
t-esc="o._get_atr_from_dict(tax_id, taxes_data, 'string')"
t-esc="o._get_atr_from_dict(tax_id, taxes_data, 'tax_name')"
/> />
</t> </t>
</t> </t>
@ -534,7 +533,7 @@
class="o_account_financial_reports_web_action" class="o_account_financial_reports_web_action"
style="color: black;" style="color: black;"
> >
<t t-raw="line['ref']" />
<t t-raw="line['ref_label']" />
</a> </a>
</span> </span>
</t> </t>
@ -544,7 +543,7 @@
class="o_account_financial_reports_web_action" class="o_account_financial_reports_web_action"
style="color: black;" style="color: black;"
> >
<t t-raw="line['ref']" />
<t t-raw="line['ref_label']" />
</a> </a>
</span> </span>
</t> </t>
@ -553,14 +552,14 @@
<t t-if="show_cost_center"> <t t-if="show_cost_center">
<div class="act_as_cell left"> <div class="act_as_cell left">
<t t-set="res_model" t-value="'account.analytic.account'" /> <t t-set="res_model" t-value="'account.analytic.account'" />
<span t-if="line.cost_center">
<span t-if="line['analytic_account_id']">
<a <a
t-att-data-active-id="line.move_line_id.analytic_account_id.id"
t-att-data-active-id="line['analytic_account_id']"
t-att-data-res-model="res_model" t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action" class="o_account_financial_reports_web_action"
style="color: black;" style="color: black;"
> >
<t t-raw="line.cost_center" />
<t t-raw="line['analytic_account']" />
</a> </a>
</span> </span>
</div> </div>
@ -780,7 +779,7 @@
> >
<div class="act_as_cell amount" style="width: 2.08%;"> <div class="act_as_cell amount" style="width: 2.08%;">
<span <span
t-field="o._get_atr_from_dict(account['id'], accounts_data, 'currency_name')"
t-esc="o._get_atr_from_dict(account['id'], accounts_data, 'currency_name')"
/> />
</div> </div>
<div class="act_as_cell amount" style="width: 5.19%;"> <div class="act_as_cell amount" style="width: 5.19%;">
@ -799,7 +798,7 @@
> >
<t <t
t-raw="account_or_partner_object['fin_bal']['bal_curr']" t-raw="account_or_partner_object['fin_bal']['bal_curr']"
t-options="{'widget': 'monetary', 'display_currency': account_or_partner_object.account_id.currency_id}"
t-options="{'widget': 'monetary', 'display_currency': o._get_atr_from_dict(account['id'], accounts_data, 'currency_id')}"
/> />
</a> </a>
</span> </span>
@ -820,7 +819,7 @@
> >
<t <t
t-raw="account_or_partner_object['fin_bal']['bal_curr']" t-raw="account_or_partner_object['fin_bal']['bal_curr']"
t-options="{'widget': 'monetary', 'display_currency': account_or_partner_object.report_account_id.currency_id}"
t-options="{'widget': 'monetary', 'display_currency': o._get_atr_from_dict(account['id'], accounts_data, 'currency_id')}"
/> />
</a> </a>
</span> </span>

315
account_financial_report/report/templates/open_items.xml

@ -28,26 +28,48 @@
<!-- Display filters --> <!-- Display filters -->
<t t-call="account_financial_report.report_open_items_filters" /> <t t-call="account_financial_report.report_open_items_filters" />
<t t-foreach="Open_Items.keys()" t-as="account_id"> <t t-foreach="Open_Items.keys()" t-as="account_id">
<div class="page_break">
<!-- Display account header -->
<div class="act_as_table list_table" style="margin-top: 10px;" />
<div class="account_title" style="width: 100%;">
<!-- Display account header -->
<div class="act_as_table list_table" style="margin-top: 10px;" />
<div class="account_title" style="width: 100%;">
<span t-esc="accounts_data[account_id]['code']" /> <span t-esc="accounts_data[account_id]['code']" />
- -
<span t-esc="accounts_data[account_id]['name']" /> <span t-esc="accounts_data[account_id]['name']" />
</div> </div>
<!-- Display account partners -->
<t t-foreach="Open_Items[account_id]" t-as="partner_id">
<div class="page_break">
<!-- Display partner header -->
<div class="act_as_caption account_title">
<span t-esc="partners_data[partner_id]['name']" />
</div>
<!-- Display partner move lines -->
<t t-if="not show_partner_details">
<div class="act_as_table data_table" style="width: 100%;">
<t
t-call="account_financial_report.report_open_items_lines_header"
/>
<!-- Display account move lines -->
<t t-foreach="Open_Items[account_id]" t-as="line">
<t <t
t-call="account_financial_report.report_open_items_lines" t-call="account_financial_report.report_open_items_lines"
/> />
<!-- Display partner footer -->
</t>
</div>
</t>
<t t-if="show_partner_details">
<div class="page_break">
<!-- Display account partners -->
<t t-foreach="Open_Items[account_id]" t-as="partner_id">
<div class="act_as_caption account_title">
<span t-esc="partners_data[partner_id]['name']" />
</div>
<div class="act_as_table data_table" style="width: 100%;">
<!-- Display partner header -->
<t
t-call="account_financial_report.report_open_items_lines_header"
/>
<!-- Display partner move lines -->
<t
t-foreach="Open_Items[account_id][partner_id]"
t-as="line"
>
<t
t-call="account_financial_report.report_open_items_lines"
/>
</t>
</div>
<t <t
t-call="account_financial_report.report_open_items_ending_cumul" t-call="account_financial_report.report_open_items_ending_cumul"
> >
@ -61,21 +83,21 @@
/> />
<t t-set="type" t-value='"partner_type"' /> <t t-set="type" t-value='"partner_type"' />
</t> </t>
</div>
</t>
<!-- Display account footer -->
<t t-call="account_financial_report.report_open_items_ending_cumul">
<t
t-set="account_or_partner_id"
t-value="accounts_data[account_id]"
/>
<t
t-set="currency_id"
t-value="accounts_data[account_id]['currency_name']"
/>
<t t-set="type" t-value='"account_type"' />
</t>
</div>
</t>
</div>
</t>
<!-- Display account footer -->
<t t-call="account_financial_report.report_open_items_ending_cumul">
<t
t-set="account_or_partner_id"
t-value="accounts_data[account_id]"
/>
<t
t-set="currency_id"
t-value="accounts_data[account_id]['currency_name']"
/>
<t t-set="type" t-value='"account_type"' />
</t>
</t> </t>
</div> </div>
</template> </template>
@ -101,133 +123,130 @@
</div> </div>
</div> </div>
</template> </template>
<template id="account_financial_report.report_open_items_lines">
<div class="act_as_table data_table" style="width: 100%;">
<!-- Display table headers for lines -->
<div class="act_as_thead">
<div class="act_as_row labels">
<!--## date-->
<div class="act_as_cell first_column" style="width: 5.51%;">
Date</div>
<!--## move-->
<div class="act_as_cell" style="width: 9.76%;">Entry</div>
<!--## journal-->
<div class="act_as_cell" style="width: 4.78%;">Journal</div>
<!--## account code-->
<div class="act_as_cell" style="width: 5.38%;">Account</div>
<!--## partner-->
<div class="act_as_cell" style="width: 15.07%;">Partner
</div>
<!--## ref - label-->
<div class="act_as_cell" style="width: 24.5%;">Ref -
Label</div>
<!--## date_due-->
<div class="act_as_cell" style="width: 6.47%;">Due
date</div>
<!--## amount_total_due-->
<div class="act_as_cell" style="width: 6.57%;">Original
</div>
<!--## amount_residual-->
<div class="act_as_cell" style="width: 6.57%;">Residual</div>
<t t-if="foreign_currency">
<!--## currency_name-->
<div class="act_as_cell" style="width: 2.25%;">Cur.</div>
<!--## amount_total_due_currency-->
<div
class="act_as_cell amount"
style="width: 6.57%;"
>Cur. Original</div>
<!--## amount_residual_currency-->
<div
class="act_as_cell amount"
style="width: 6.57%;"
>Cur. Residual</div>
</t>
<template id="account_financial_report.report_open_items_lines_header">
<!-- Display table headers for lines -->
<div class="act_as_thead">
<div class="act_as_row labels">
<!--## date-->
<div class="act_as_cell first_column" style="width: 5.51%;">
Date</div>
<!--## move-->
<div class="act_as_cell" style="width: 9.76%;">Entry</div>
<!--## journal-->
<div class="act_as_cell" style="width: 4.78%;">Journal</div>
<!--## account code-->
<div class="act_as_cell" style="width: 5.38%;">Account</div>
<!--## partner-->
<div class="act_as_cell" style="width: 15.07%;">Partner
</div>
<!--## ref - label-->
<div class="act_as_cell" style="width: 24.5%;">Ref -
Label</div>
<!--## date_due-->
<div class="act_as_cell" style="width: 6.47%;">Due
date</div>
<!--## amount_total_due-->
<div class="act_as_cell" style="width: 6.57%;">Original
</div> </div>
<!--## amount_residual-->
<div class="act_as_cell" style="width: 6.57%;">Residual</div>
<t t-if="foreign_currency">
<!--## currency_name-->
<div class="act_as_cell" style="width: 2.25%;">Cur.</div>
<!--## amount_total_due_currency-->
<div
class="act_as_cell amount"
style="width: 6.57%;"
>Cur. Original</div>
<!--## amount_residual_currency-->
<div
class="act_as_cell amount"
style="width: 6.57%;"
>Cur. Residual</div>
</t>
</div> </div>
<!-- Display each lines -->
<t t-foreach="Open_Items[account_id][partner_id]" t-as="line">
<!-- # lines or centralized lines -->
<div class="act_as_row lines">
<!--## date-->
<div class="act_as_cell left">
<span t-raw="line['date']" />
</div>
<!--## move-->
<div class="act_as_cell left">
<t t-set="res_model" t-value="'account.move'" />
<span>
<a
t-att-data-active-id="line['move_id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;"
>
<t t-esc="line['move_name']" />
</a>
</span>
</div>
<!--## journal-->
<div class="act_as_cell left">
<span t-esc="line['journal']" />
</div>
<!--## account code-->
<div class="act_as_cell left">
<span t-esc="line['account']" />
</div>
<!--## partner-->
<div class="act_as_cell left">
<!-- <span t-if="line.get('partner_id', False)" t-esc="line['partner_id']"/>-->
<span t-esc="line['partner_name']" />
</div>
<!--## ref - label-->
<div class="act_as_cell left">
<span t-esc="line['ref']" />
</div>
<!--## date_due-->
<div class="act_as_cell left">
<span t-esc="line['date_maturity']" />
</div>
</template>
<template id="account_financial_report.report_open_items_lines">
<!-- # lines or centralized lines -->
<div class="act_as_row lines">
<!--## date-->
<div class="act_as_cell left">
<span t-raw="line['date'].strftime('%d/%m/%Y')" />
</div>
<!--## move-->
<div class="act_as_cell left">
<t t-set="res_model" t-value="'account.move'" />
<span>
<a
t-att-data-active-id="line['move_id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;"
>
<t t-esc="line['move_name']" />
</a>
</span>
</div>
<!--## journal-->
<div class="act_as_cell left">
<span t-esc="journals_data[line['journal_id']]['code']" />
</div>
<!--## account code-->
<div class="act_as_cell left">
<span t-esc="accounts_data[account_id]['code']" />
</div>
<!--## partner-->
<div class="act_as_cell left">
<!-- <span t-if="line.get('partner_id', False)" t-esc="line['partner_id']"/>-->
<span t-esc="line['partner_name']" />
</div>
<!--## ref - label-->
<div class="act_as_cell left">
<span t-esc="line['ref_label']" />
</div>
<!--## date_due-->
<div class="act_as_cell left">
<span t-esc="line['date_maturity']" />
</div>
<!--## amount_total_due-->
<div class="act_as_cell amount">
<span
t-if="line.get('original', False)"
t-esc="line['original']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## amount_residual-->
<div class="act_as_cell amount">
<span
t-esc="line['amount_residual']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<t t-if="foreign_currency">
<t t-if="line['currency_id']">
<!--## currency_name-->
<div class="act_as_cell amount">
<span t-esc="line['currency_name']" />
</div> </div>
<!--## amount_total_due-->
<!--## amount_total_due_currency-->
<div class="act_as_cell amount"> <div class="act_as_cell amount">
<span
t-if="line.get('original', False)"
t-esc="line['original']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
<span t-esc="line['amount_currency']" />
</div> </div>
<!--## amount_residual-->
<!--## amount_residual_currency-->
<div class="act_as_cell amount"> <div class="act_as_cell amount">
<span
t-esc="line['amount_residual']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
<span t-esc="line['amount_residual_currency']" />
</div> </div>
<t t-if="foreign_currency">
<t t-if="line['currency_id']">
<!--## currency_name-->
<div class="act_as_cell amount">
<span t-esc="line['currency_name']" />
</div>
<!--## amount_total_due_currency-->
<div class="act_as_cell amount">
<span t-esc="line['amount_currency']" />
</div>
<!--## amount_residual_currency-->
<div class="act_as_cell amount">
<span t-esc="line['amount_residual_currency']" />
</div>
</t>
<t t-if="not line['currency_id']">
<!--## currency_name-->
<div class="act_as_cell" />
<!--## amount_total_due_currency-->
<div class="act_as_cell" />
<!--## amount_residual_currency-->
<div class="act_as_cell" />
</t>
</t>
</div>
</t>
<t t-if="not line['currency_id']">
<!--## currency_name-->
<div class="act_as_cell" />
<!--## amount_total_due_currency-->
<div class="act_as_cell" />
<!--## amount_residual_currency-->
<div class="act_as_cell" />
</t>
</t> </t>
</div> </div>
</template> </template>

263
account_financial_report/report/trial_balance.py

@ -3,7 +3,6 @@
# Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com) # Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from operator import itemgetter
from odoo import api, models from odoo import api, models
@ -203,10 +202,133 @@ class TrialBalanceReport(models.AbstractModel):
for initial_balance in initial_balances: for initial_balance in initial_balances:
pl_initial_balance += initial_balance["balance"] pl_initial_balance += initial_balance["balance"]
if foreign_currency: if foreign_currency:
pl_initial_currency_balance += initial_balance["amount_currency"]
pl_initial_currency_balance += round(
initial_balance["amount_currency"], 2
)
return pl_initial_balance, pl_initial_currency_balance return pl_initial_balance, pl_initial_currency_balance
# flake8: noqa: C901
@api.model
def _compute_account_amount(
self, total_amount, tb_initial_acc, tb_period_acc, foreign_currency
):
for tb in tb_period_acc:
acc_id = tb["account_id"][0]
total_amount[acc_id] = {}
total_amount[acc_id]["credit"] = tb["credit"]
total_amount[acc_id]["debit"] = tb["debit"]
total_amount[acc_id]["balance"] = tb["balance"]
total_amount[acc_id]["initial_balance"] = 0.0
total_amount[acc_id]["ending_balance"] = tb["balance"]
if foreign_currency:
total_amount[acc_id]["initial_currency_balance"] = 0.0
total_amount[acc_id]["ending_currency_balance"] = round(
tb["amount_currency"], 2
)
for tb in tb_initial_acc:
acc_id = tb["account_id"]
if acc_id not in total_amount.keys():
total_amount[acc_id] = {}
total_amount[acc_id]["credit"] = 0.0
total_amount[acc_id]["debit"] = 0.0
total_amount[acc_id]["balance"] = 0.0
total_amount[acc_id]["initial_balance"] = tb["balance"]
total_amount[acc_id]["ending_balance"] = tb["balance"]
if foreign_currency:
total_amount[acc_id]["initial_currency_balance"] = round(
tb["amount_currency"], 2
)
total_amount[acc_id]["ending_currency_balance"] = round(
tb["amount_currency"], 2
)
else:
total_amount[acc_id]["initial_balance"] = tb["balance"]
total_amount[acc_id]["ending_balance"] += tb["balance"]
if foreign_currency:
total_amount[acc_id]["initial_currency_balance"] = round(
tb["amount_currency"], 2
)
total_amount[acc_id]["ending_currency_balance"] += round(
tb["amount_currency"], 2
)
return total_amount
@api.model
def _compute_partner_amount(
self, total_amount, tb_initial_prt, tb_period_prt, foreign_currency
):
partners_ids = set()
partners_data = {}
for tb in tb_period_prt:
acc_id = tb["account_id"][0]
if tb["partner_id"]:
prt_id = tb["partner_id"][0]
if tb["partner_id"] not in partners_ids:
partners_data.update(
{prt_id: {"id": prt_id, "name": tb["partner_id"][1]}}
)
total_amount[acc_id][prt_id] = {}
total_amount[acc_id][prt_id]["credit"] = tb["credit"]
total_amount[acc_id][prt_id]["debit"] = tb["debit"]
total_amount[acc_id][prt_id]["balance"] = tb["balance"]
total_amount[acc_id][prt_id]["initial_balance"] = 0.0
total_amount[acc_id][prt_id]["ending_balance"] = tb["balance"]
if foreign_currency:
total_amount[acc_id][prt_id]["initial_currency_balance"] = 0.0
total_amount[acc_id][prt_id]["ending_currency_balance"] = round(
tb["amount_currency"], 2
)
partners_ids.add(tb["partner_id"])
for tb in tb_initial_prt:
acc_id = tb["account_id"][0]
if tb["partner_id"]:
prt_id = tb["partner_id"][0]
if tb["partner_id"] not in partners_ids:
partners_data.update(
{prt_id: {"id": prt_id, "name": tb["partner_id"][1]}}
)
if acc_id not in total_amount.keys():
total_amount[acc_id][prt_id] = {}
total_amount[acc_id][prt_id]["credit"] = 0.0
total_amount[acc_id][prt_id]["debit"] = 0.0
total_amount[acc_id][prt_id]["balance"] = 0.0
total_amount[acc_id][prt_id]["initial_balance"] = tb["balance"]
total_amount[acc_id][prt_id]["ending_balance"] = tb["balance"]
if foreign_currency:
total_amount[acc_id][prt_id][
"initial_currency_balance"
] = round(tb["amount_currency"], 2)
total_amount[acc_id][prt_id]["ending_currency_balance"] = round(
tb["amount_currency"], 2
)
partners_ids.add(tb["partner_id"])
elif prt_id not in total_amount[acc_id].keys():
total_amount[acc_id][prt_id] = {}
total_amount[acc_id][prt_id]["credit"] = 0.0
total_amount[acc_id][prt_id]["debit"] = 0.0
total_amount[acc_id][prt_id]["balance"] = 0.0
total_amount[acc_id][prt_id]["initial_balance"] = tb["balance"]
total_amount[acc_id][prt_id]["ending_balance"] = tb["balance"]
if foreign_currency:
total_amount[acc_id][prt_id][
"initial_currency_balance"
] = round(tb["amount_currency"], 2)
total_amount[acc_id][prt_id]["ending_currency_balance"] = round(
tb["amount_currency"], 2
)
partners_ids.add(tb["partner_id"])
else:
total_amount[acc_id][prt_id]["initial_balance"] += tb["balance"]
total_amount[acc_id][prt_id]["ending_balance"] += tb["balance"]
if foreign_currency:
total_amount[acc_id][prt_id][
"initial_currency_balance"
] += round(tb["amount_currency"], 2)
total_amount[acc_id][prt_id][
"ending_currency_balance"
] += round(tb["amount_currency"], 2)
return total_amount, partners_data
@api.model
def _get_data( def _get_data(
self, self,
account_ids, account_ids,
@ -222,6 +344,15 @@ class TrialBalanceReport(models.AbstractModel):
unaffected_earnings_account, unaffected_earnings_account,
fy_start_date, fy_start_date,
): ):
accounts_domain = [("company_id", "=", company_id)]
if account_ids:
accounts_domain += [("id", "in", account_ids)]
accounts = self.env["account.account"].search(accounts_domain)
tb_initial_acc = []
for account in accounts:
tb_initial_acc.append(
{"account_id": account.id, "balance": 0.0, "amount_currency": 0.0}
)
initial_domain_bs = self._get_initial_balances_bs_ml_domain( initial_domain_bs = self._get_initial_balances_bs_ml_domain(
account_ids, account_ids,
journal_ids, journal_ids,
@ -251,7 +382,18 @@ class TrialBalanceReport(models.AbstractModel):
fields=["account_id", "balance", "amount_currency"], fields=["account_id", "balance", "amount_currency"],
groupby=["account_id"], groupby=["account_id"],
) )
tb_initial_acc = tb_initial_acc_bs + tb_initial_acc_pl
tb_initial_acc_rg = tb_initial_acc_bs + tb_initial_acc_pl
for account_rg in tb_initial_acc_rg:
element = list(
filter(
lambda acc_dict: acc_dict["account_id"]
== account_rg["account_id"][0],
tb_initial_acc,
)
)
if element:
element[0]["balance"] += account_rg["balance"]
element[0]["amount_currency"] += account_rg["amount_currency"]
if hide_account_at_0: if hide_account_at_0:
tb_initial_acc = [p for p in tb_initial_acc if p["balance"] != 0] tb_initial_acc = [p for p in tb_initial_acc if p["balance"] != 0]
@ -301,114 +443,13 @@ class TrialBalanceReport(models.AbstractModel):
) )
total_amount = {} total_amount = {}
partners_data = [] partners_data = []
for tb in tb_period_acc:
acc_id = tb["account_id"][0]
total_amount[acc_id] = {}
total_amount[acc_id]["credit"] = tb["credit"]
total_amount[acc_id]["debit"] = tb["debit"]
total_amount[acc_id]["balance"] = tb["balance"]
total_amount[acc_id]["initial_balance"] = 0.0
total_amount[acc_id]["ending_balance"] = tb["balance"]
if foreign_currency:
total_amount[acc_id]["initial_currency_balance"] = 0.0
total_amount[acc_id]["ending_currency_balance"] = tb["amount_currency"]
for tb in tb_initial_acc:
acc_id = tb["account_id"][0]
if acc_id not in total_amount.keys():
total_amount[acc_id] = {}
total_amount[acc_id]["credit"] = 0.0
total_amount[acc_id]["debit"] = 0.0
total_amount[acc_id]["balance"] = 0.0
total_amount[acc_id]["initial_balance"] = tb["balance"]
total_amount[acc_id]["ending_balance"] = tb["balance"]
if foreign_currency:
total_amount[acc_id]["initial_currency_balance"] = tb[
"amount_currency"
]
total_amount[acc_id]["ending_currency_balance"] = tb[
"amount_currency"
]
else:
total_amount[acc_id]["initial_balance"] = tb["balance"]
total_amount[acc_id]["ending_balance"] += tb["balance"]
if foreign_currency:
total_amount[acc_id]["initial_currency_balance"] = tb[
"amount_currency"
]
total_amount[acc_id]["ending_currency_balance"] += tb[
"amount_currency"
]
total_amount = self._compute_account_amount(
total_amount, tb_initial_acc, tb_period_acc, foreign_currency
)
if show_partner_details: if show_partner_details:
partners_ids = set()
partners_data = {}
for tb in tb_period_prt:
acc_id = tb["account_id"][0]
if tb["partner_id"]:
prt_id = tb["partner_id"][0]
if tb["partner_id"] not in partners_ids:
partners_data.update(
{prt_id: {"id": prt_id, "name": tb["partner_id"][1]}}
)
total_amount[acc_id][prt_id] = {}
total_amount[acc_id][prt_id]["credit"] = tb["credit"]
total_amount[acc_id][prt_id]["debit"] = tb["debit"]
total_amount[acc_id][prt_id]["balance"] = tb["balance"]
total_amount[acc_id][prt_id]["initial_balance"] = 0.0
total_amount[acc_id][prt_id]["ending_balance"] = tb["balance"]
if foreign_currency:
total_amount[acc_id][prt_id]["initial_currency_balance"] = 0.0
total_amount[acc_id][prt_id]["ending_currency_balance"] = tb[
"amount_currency"
]
partners_ids.add(tb["partner_id"])
for tb in tb_initial_prt:
acc_id = tb["account_id"][0]
if tb["partner_id"]:
prt_id = tb["partner_id"][0]
if tb["partner_id"] not in partners_ids:
partners_data.update(
{prt_id: {"id": prt_id, "name": tb["partner_id"][1]}}
)
if acc_id not in total_amount.keys():
total_amount[acc_id][prt_id] = {}
total_amount[acc_id][prt_id]["credit"] = 0.0
total_amount[acc_id][prt_id]["debit"] = 0.0
total_amount[acc_id][prt_id]["balance"] = 0.0
total_amount[acc_id][prt_id]["initial_balance"] = tb["balance"]
total_amount[acc_id][prt_id]["ending_balance"] = tb["balance"]
if foreign_currency:
total_amount[acc_id][prt_id][
"initial_currency_balance"
] = tb["amount_currency"]
total_amount[acc_id][prt_id][
"ending_currency_balance"
] = tb["amount_currency"]
partners_ids.add(tb["partner_id"])
elif prt_id not in total_amount[acc_id].keys():
total_amount[acc_id][prt_id] = {}
total_amount[acc_id][prt_id]["credit"] = 0.0
total_amount[acc_id][prt_id]["debit"] = 0.0
total_amount[acc_id][prt_id]["balance"] = 0.0
total_amount[acc_id][prt_id]["initial_balance"] = tb["balance"]
total_amount[acc_id][prt_id]["ending_balance"] = tb["balance"]
if foreign_currency:
total_amount[acc_id][prt_id][
"initial_currency_balance"
] = tb["amount_currency"]
total_amount[acc_id][prt_id][
"ending_currency_balance"
] = tb["amount_currency"]
partners_ids.add(tb["partner_id"])
else:
total_amount[acc_id][prt_id]["initial_balance"] += tb["balance"]
total_amount[acc_id][prt_id]["ending_balance"] += tb["balance"]
if foreign_currency:
total_amount[acc_id][prt_id][
"initial_currency_balance"
] += tb["amount_currency"]
total_amount[acc_id][prt_id][
"ending_currency_balance"
] += tb["amount_currency"]
total_amount, partners_data = self._compute_partner_amount(
total_amount, tb_initial_prt, tb_period_prt, foreign_currency
)
accounts_ids = list(total_amount.keys()) accounts_ids = list(total_amount.keys())
unaffected_id = unaffected_earnings_account unaffected_id = unaffected_earnings_account
if unaffected_id not in accounts_ids: if unaffected_id not in accounts_ids:

148
account_financial_report/report/vat_report.py

@ -2,6 +2,8 @@
# Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com) # Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import operator
from odoo import api, models from odoo import api, models
@ -19,55 +21,82 @@ class VATReport(models.AbstractModel):
"id": tax.id, "id": tax.id,
"name": tax.name, "name": tax.name,
"tax_group_id": tax.tax_group_id.id, "tax_group_id": tax.tax_group_id.id,
"type_tax_use": tax.type_tax_use,
"amount_type": tax.amount_type,
"tags_ids": tax.invoice_repartition_line_ids.tag_ids.ids,
} }
} }
) )
return tax_data return tax_data
@api.model @api.model
def _get_vat_report_domain(self, company_id, date_from, date_to):
def _get_tax_report_domain(self, company_id, date_from, date_to, only_posted_moves):
domain = [ domain = [
("company_id", "=", company_id), ("company_id", "=", company_id),
("date", ">=", date_from), ("date", ">=", date_from),
("date", "<", date_to),
("date", "<=", date_to),
("tax_line_id", "!=", False), ("tax_line_id", "!=", False),
("tax_exigible", "=", True), ("tax_exigible", "=", True),
] ]
if only_posted_moves:
domain += [("move_id.state", "=", "posted")]
return domain
@api.model
def _get_net_report_domain(self, company_id, date_from, date_to, only_posted_moves):
domain = [
("company_id", "=", company_id),
("date", ">=", date_from),
("date", "<=", date_to),
("tax_exigible", "=", True),
]
if only_posted_moves:
domain += [("move_id.state", "=", "posted")]
return domain return domain
def _get_vat_report_data(self, company_id, date_from, date_to):
domain = self._get_vat_report_domain(company_id, date_from, date_to)
def _get_vat_report_data(self, company_id, date_from, date_to, only_posted_moves):
tax_domain = self._get_tax_report_domain(
company_id, date_from, date_to, only_posted_moves
)
ml_fields = [ ml_fields = [
"id", "id",
"tax_base_amount", "tax_base_amount",
"balance", "balance",
"tax_line_id", "tax_line_id",
"tax_repartition_line_id",
"tax_ids",
"analytic_tag_ids", "analytic_tag_ids",
"tag_ids",
] ]
tax_move_lines = self.env["account.move.line"].search_read( tax_move_lines = self.env["account.move.line"].search_read(
domain=domain, fields=ml_fields
domain=tax_domain, fields=ml_fields,
)
net_domain = self._get_net_report_domain(
company_id, date_from, date_to, only_posted_moves
)
taxed_move_lines = self.env["account.move.line"].search_read(
domain=net_domain, fields=ml_fields,
) )
vat_data = {}
tax_ids = set()
taxed_move_lines = list(filter(lambda d: d["tax_ids"], taxed_move_lines))
vat_data = []
for tax_move_line in tax_move_lines: for tax_move_line in tax_move_lines:
tax_ml_id = tax_move_line["id"]
repartition = self.env["account.tax.repartition.line"].browse(
tax_move_line["tax_repartition_line_id"][0]
)
vat_data[tax_ml_id] = {}
vat_data[tax_ml_id].update(
vat_data.append(
{ {
"id": tax_ml_id,
"net": tax_move_line["tax_base_amount"],
"tax": tax_move_line["balance"]
if tax_move_line["balance"] > 0
else (-1) * tax_move_line["balance"],
"tax_line_id": tax_move_line["tax_line_id"],
"tags_ids": repartition.tag_ids.ids,
"net": 0.0,
"tax": tax_move_line["balance"],
"tax_line_id": tax_move_line["tax_line_id"][0],
} }
) )
tax_ids.add(tax_move_line["tax_line_id"][0])
for taxed_move_line in taxed_move_lines:
for tax_id in taxed_move_line["tax_ids"]:
vat_data.append(
{
"net": taxed_move_line["balance"],
"tax": 0.0,
"tax_line_id": tax_id,
}
)
tax_ids = list(map(operator.itemgetter("tax_line_id"), vat_data))
tax_ids = list(set(tax_ids))
tax_data = self._get_tax_data(tax_ids) tax_data = self._get_tax_data(tax_ids)
return vat_data, tax_data return vat_data, tax_data
@ -88,23 +117,28 @@ class VATReport(models.AbstractModel):
def _get_vat_report_group_data(self, vat_report_data, tax_data, tax_detail): def _get_vat_report_group_data(self, vat_report_data, tax_data, tax_detail):
vat_report = {} vat_report = {}
for tax_move_line in vat_report_data.values():
tax_id = tax_move_line["tax_line_id"][0]
tax_group_id = tax_data[tax_id]["tax_group_id"]
if tax_group_id not in vat_report.keys():
vat_report[tax_group_id] = {}
vat_report[tax_group_id]["net"] = 0.0
vat_report[tax_group_id]["tax"] = 0.0
vat_report[tax_group_id][tax_id] = dict(tax_data[tax_id])
vat_report[tax_group_id][tax_id].update({"net": 0.0, "tax": 0.0})
for tax_move_line in vat_report_data:
tax_id = tax_move_line["tax_line_id"]
if tax_data[tax_id]["amount_type"] == "group":
pass
else: else:
if tax_id not in vat_report[tax_group_id].keys():
tax_group_id = tax_data[tax_id]["tax_group_id"]
if tax_group_id not in vat_report.keys():
vat_report[tax_group_id] = {}
vat_report[tax_group_id]["net"] = 0.0
vat_report[tax_group_id]["tax"] = 0.0
vat_report[tax_group_id][tax_id] = dict(tax_data[tax_id]) vat_report[tax_group_id][tax_id] = dict(tax_data[tax_id])
vat_report[tax_group_id][tax_id].update({"net": 0.0, "tax": 0.0}) vat_report[tax_group_id][tax_id].update({"net": 0.0, "tax": 0.0})
vat_report[tax_group_id]["net"] += tax_move_line["net"]
vat_report[tax_group_id]["tax"] += tax_move_line["tax"]
vat_report[tax_group_id][tax_id]["net"] += tax_move_line["net"]
vat_report[tax_group_id][tax_id]["tax"] += tax_move_line["tax"]
else:
if tax_id not in vat_report[tax_group_id].keys():
vat_report[tax_group_id][tax_id] = dict(tax_data[tax_id])
vat_report[tax_group_id][tax_id].update(
{"net": 0.0, "tax": 0.0}
)
vat_report[tax_group_id]["net"] += tax_move_line["net"]
vat_report[tax_group_id]["tax"] += tax_move_line["tax"]
vat_report[tax_group_id][tax_id]["net"] += tax_move_line["net"]
vat_report[tax_group_id][tax_id]["tax"] += tax_move_line["tax"]
tax_group_data = self._get_tax_group_data(vat_report.keys()) tax_group_data = self._get_tax_group_data(vat_report.keys())
vat_report_list = [] vat_report_list = []
for tax_group_id in vat_report.keys(): for tax_group_id in vat_report.keys():
@ -129,25 +163,30 @@ class VATReport(models.AbstractModel):
def _get_vat_report_tag_data(self, vat_report_data, tax_data, tax_detail): def _get_vat_report_tag_data(self, vat_report_data, tax_data, tax_detail):
vat_report = {} vat_report = {}
for tax_move_line in vat_report_data.values():
tax_id = tax_move_line["tax_line_id"][0]
tags_ids = tax_move_line["tags_ids"]
if tags_ids:
for tag_id in tags_ids:
if tag_id not in vat_report.keys():
vat_report[tag_id] = {}
vat_report[tag_id]["net"] = 0.0
vat_report[tag_id]["tax"] = 0.0
vat_report[tag_id][tax_id] = dict(tax_data[tax_id])
vat_report[tag_id][tax_id].update({"net": 0.0, "tax": 0.0})
else:
if tax_id not in vat_report[tag_id].keys():
for tax_move_line in vat_report_data:
tax_id = tax_move_line["tax_line_id"]
tags_ids = tax_data[tax_id]["tags_ids"]
if tax_data[tax_id]["amount_type"] == "group":
continue
else:
if tags_ids:
for tag_id in tags_ids:
if tag_id not in vat_report.keys():
vat_report[tag_id] = {}
vat_report[tag_id]["net"] = 0.0
vat_report[tag_id]["tax"] = 0.0
vat_report[tag_id][tax_id] = dict(tax_data[tax_id]) vat_report[tag_id][tax_id] = dict(tax_data[tax_id])
vat_report[tag_id][tax_id].update({"net": 0.0, "tax": 0.0}) vat_report[tag_id][tax_id].update({"net": 0.0, "tax": 0.0})
vat_report[tag_id][tax_id]["net"] += tax_move_line["net"]
vat_report[tag_id][tax_id]["tax"] += tax_move_line["tax"]
vat_report[tag_id]["net"] += tax_move_line["net"]
vat_report[tag_id]["tax"] += tax_move_line["tax"]
else:
if tax_id not in vat_report[tag_id].keys():
vat_report[tag_id][tax_id] = dict(tax_data[tax_id])
vat_report[tag_id][tax_id].update(
{"net": 0.0, "tax": 0.0}
)
vat_report[tag_id][tax_id]["net"] += tax_move_line["net"]
vat_report[tag_id][tax_id]["tax"] += tax_move_line["tax"]
vat_report[tag_id]["net"] += tax_move_line["net"]
vat_report[tag_id]["tax"] += tax_move_line["tax"]
tags_data = self._get_tags_data(vat_report.keys()) tags_data = self._get_tags_data(vat_report.keys())
vat_report_list = [] vat_report_list = []
for tag_id in vat_report.keys(): for tag_id in vat_report.keys():
@ -169,8 +208,9 @@ class VATReport(models.AbstractModel):
date_to = data["date_to"] date_to = data["date_to"]
based_on = data["based_on"] based_on = data["based_on"]
tax_detail = data["tax_detail"] tax_detail = data["tax_detail"]
only_posted_moves = data["only_posted_moves"]
vat_report_data, tax_data = self._get_vat_report_data( vat_report_data, tax_data = self._get_vat_report_data(
company_id, date_from, date_to
company_id, date_from, date_to, only_posted_moves
) )
if based_on == "taxgroups": if based_on == "taxgroups":
vat_report = self._get_vat_report_group_data( vat_report = self._get_vat_report_group_data(

40
account_financial_report/tests/test_vat_report.py

@ -173,8 +173,8 @@ class TestVATReport(common.TransactionCase):
line_form.price_unit = 250.0 line_form.price_unit = 250.0
line_form.account_id = self.income_account line_form.account_id = self.income_account
line_form.tax_ids.add(self.tax_20) line_form.tax_ids.add(self.tax_20)
self.cbinvoice = move_form.save()
self.cbinvoice.post()
invoice = move_form.save()
invoice.post()
def _get_report_lines(self, taxgroups=False): def _get_report_lines(self, taxgroups=False):
based_on = "taxtags" based_on = "taxtags"
@ -267,16 +267,16 @@ class TestVATReport(common.TransactionCase):
tax_10_net, tax_10_tax = self._get_tax_line(self.tax_10.name, vat_report) tax_10_net, tax_10_tax = self._get_tax_line(self.tax_10.name, vat_report)
tax_20_net, tax_20_tax = self._get_tax_line(self.tax_20.name, vat_report) tax_20_net, tax_20_tax = self._get_tax_line(self.tax_20.name, vat_report)
self.assertEqual(tag_01_net, 100)
self.assertEqual(tag_01_tax, 10)
self.assertEqual(tag_02_net, 350)
self.assertEqual(tag_02_tax, 60)
self.assertEqual(tag_03_net, 250)
self.assertEqual(tag_03_tax, 50)
self.assertEqual(tax_10_net, 100)
self.assertEqual(tax_10_tax, 10)
self.assertEqual(tax_20_net, 250)
self.assertEqual(tax_20_tax, 50)
self.assertEqual(tag_01_net, -100)
self.assertEqual(tag_01_tax, -10)
self.assertEqual(tag_02_net, -350)
self.assertEqual(tag_02_tax, -60)
self.assertEqual(tag_03_net, -250)
self.assertEqual(tag_03_tax, -50)
self.assertEqual(tax_10_net, -100)
self.assertEqual(tax_10_tax, -10)
self.assertEqual(tax_20_net, -250)
self.assertEqual(tax_20_tax, -50)
# Check report based on taxgroups # Check report based on taxgroups
res_data = self._get_report_lines(taxgroups=True) res_data = self._get_report_lines(taxgroups=True)
@ -304,14 +304,14 @@ class TestVATReport(common.TransactionCase):
tax_10_net, tax_10_tax = self._get_tax_line(self.tax_10.name, vat_report) tax_10_net, tax_10_tax = self._get_tax_line(self.tax_10.name, vat_report)
tax_20_net, tax_20_tax = self._get_tax_line(self.tax_20.name, vat_report) tax_20_net, tax_20_tax = self._get_tax_line(self.tax_20.name, vat_report)
self.assertEqual(group_10_net, 100)
self.assertEqual(group_10_tax, 10)
self.assertEqual(group_20_net, 250)
self.assertEqual(group_20_tax, 50)
self.assertEqual(tax_10_net, 100)
self.assertEqual(tax_10_tax, 10)
self.assertEqual(tax_20_net, 250)
self.assertEqual(tax_20_tax, 50)
self.assertEqual(group_10_net, -100)
self.assertEqual(group_10_tax, -10)
self.assertEqual(group_20_net, -250)
self.assertEqual(group_20_tax, -50)
self.assertEqual(tax_10_net, -100)
self.assertEqual(tax_10_tax, -10)
self.assertEqual(tax_20_net, -250)
self.assertEqual(tax_20_tax, -50)
def test_wizard_date_range(self): def test_wizard_date_range(self):
vat_wizard = self.env["vat.report.wizard"] vat_wizard = self.env["vat.report.wizard"]

55
account_financial_report/wizard/aged_partner_balance_wizard.py

@ -20,6 +20,7 @@ class AgedPartnerBalanceWizard(models.TransientModel):
string="Company", string="Company",
) )
date_at = fields.Date(required=True, default=fields.Date.context_today) date_at = fields.Date(required=True, default=fields.Date.context_today)
date_from = fields.Date(string="Date From")
target_move = fields.Selection( target_move = fields.Selection(
[("posted", "All Posted Entries"), ("all", "All Entries")], [("posted", "All Posted Entries"), ("all", "All Entries")],
string="Target Moves", string="Target Moves",
@ -27,13 +28,54 @@ class AgedPartnerBalanceWizard(models.TransientModel):
default="posted", default="posted",
) )
account_ids = fields.Many2many( account_ids = fields.Many2many(
comodel_name="account.account", string="Filter accounts"
comodel_name="account.account",
string="Filter accounts",
domain=[("reconcile", "=", True)],
required=True,
) )
receivable_accounts_only = fields.Boolean() receivable_accounts_only = fields.Boolean()
payable_accounts_only = fields.Boolean() payable_accounts_only = fields.Boolean()
partner_ids = fields.Many2many(comodel_name="res.partner", string="Filter partners") partner_ids = fields.Many2many(comodel_name="res.partner", string="Filter partners")
show_move_line_details = fields.Boolean() show_move_line_details = fields.Boolean()
account_code_from = fields.Many2one(
comodel_name="account.account",
string="Account Code From",
help="Starting account in a range",
)
account_code_to = fields.Many2one(
comodel_name="account.account",
string="Account Code To",
help="Ending account in a range",
)
@api.onchange("account_code_from", "account_code_to")
def on_change_account_range(self):
if (
self.account_code_from
and self.account_code_from.code.isdigit()
and self.account_code_to
and self.account_code_to.code.isdigit()
):
start_range = int(self.account_code_from.code)
end_range = int(self.account_code_to.code)
self.account_ids = self.env["account.account"].search(
[
("code", "in", [x for x in range(start_range, end_range + 1)]),
("reconcile", "=", True),
]
)
if self.company_id:
self.account_ids = self.account_ids.filtered(
lambda a: a.company_id == self.company_id
)
return {
"domain": {
"account_code_from": [("reconcile", "=", True)],
"account_code_to": [("reconcile", "=", True)],
}
}
@api.onchange("company_id") @api.onchange("company_id")
def onchange_company_id(self): def onchange_company_id(self):
"""Handle company change.""" """Handle company change."""
@ -56,6 +98,10 @@ class AgedPartnerBalanceWizard(models.TransientModel):
res["domain"]["partner_ids"] += self._get_partner_ids_domain() res["domain"]["partner_ids"] += self._get_partner_ids_domain()
return res return res
@api.onchange("account_ids")
def onchange_account_ids(self):
return {"domain": {"account_ids": [("reconcile", "=", True)]}}
@api.onchange("receivable_accounts_only", "payable_accounts_only") @api.onchange("receivable_accounts_only", "payable_accounts_only")
def onchange_type_accounts_only(self): def onchange_type_accounts_only(self):
"""Handle receivable/payable accounts only change.""" """Handle receivable/payable accounts only change."""
@ -67,9 +113,9 @@ class AgedPartnerBalanceWizard(models.TransientModel):
domain += [("internal_type", "=", "receivable")] domain += [("internal_type", "=", "receivable")]
elif self.payable_accounts_only: elif self.payable_accounts_only:
domain += [("internal_type", "=", "payable")] domain += [("internal_type", "=", "payable")]
elif not self.receivable_accounts_only and not self.payable_accounts_only:
domain += [("reconcile", "=", True)]
self.account_ids = self.env["account.account"].search(domain)
self.account_ids = self.env["account.account"].search(domain)
else:
self.account_ids = None
def _print_report(self, report_type): def _print_report(self, report_type):
self.ensure_one() self.ensure_one()
@ -107,6 +153,7 @@ class AgedPartnerBalanceWizard(models.TransientModel):
return { return {
"wizard_id": self.id, "wizard_id": self.id,
"date_at": self.date_at, "date_at": self.date_at,
"date_from": self.date_from or False,
"only_posted_moves": self.target_move == "posted", "only_posted_moves": self.target_move == "posted",
"company_id": self.company_id.id, "company_id": self.company_id.id,
"account_ids": self.account_ids.ids, "account_ids": self.account_ids.ids,

19
account_financial_report/wizard/aged_partner_balance_wizard_view.xml

@ -16,6 +16,7 @@
<group name="filters"> <group name="filters">
<group name="date_range"> <group name="date_range">
<field name="date_at" /> <field name="date_at" />
<field name="date_from" />
</group> </group>
<group name="other_filters"> <group name="other_filters">
<field name="target_move" widget="radio" /> <field name="target_move" widget="radio" />
@ -35,6 +36,24 @@
<label for="account_ids" colspan="4" /> <label for="account_ids" colspan="4" />
<field name="receivable_accounts_only" /> <field name="receivable_accounts_only" />
<field name="payable_accounts_only" /> <field name="payable_accounts_only" />
<label for="account_code_from" string="From Code" />
<div>
<div class="o_row">
<field
name="account_code_from"
class="oe_inline"
options="{'no_create': True}"
/>
<span class="oe_inline">
To
</span>
<field
name="account_code_to"
class="oe_inline"
options="{'no_create': True}"
/>
</div>
</div>
<field <field
name="account_ids" name="account_ids"
nolabel="1" nolabel="1"

34
account_financial_report/wizard/general_ledger_wizard.py

@ -47,7 +47,7 @@ class GeneralLedgerReportWizard(models.TransientModel):
"If partners are filtered, " "If partners are filtered, "
"debits and credits totals will not match the trial balance.", "debits and credits totals will not match the trial balance.",
) )
show_analytic_tags = fields.Boolean(string="Show analytic tags")
show_analytic_tags = fields.Boolean(string="Show analytic tags",)
receivable_accounts_only = fields.Boolean() receivable_accounts_only = fields.Boolean()
payable_accounts_only = fields.Boolean() payable_accounts_only = fields.Boolean()
partner_ids = fields.Many2many( partner_ids = fields.Many2many(
@ -75,6 +75,36 @@ class GeneralLedgerReportWizard(models.TransientModel):
"will display initial and final balance in that currency.", "will display initial and final balance in that currency.",
default=lambda self: self._default_foreign_currency(), default=lambda self: self._default_foreign_currency(),
) )
account_code_from = fields.Many2one(
comodel_name="account.account",
string="Account Code From",
help="Starting account in a range",
)
account_code_to = fields.Many2one(
comodel_name="account.account",
string="Account Code To",
help="Ending account in a range",
)
show_partner_details = fields.Boolean(string="Show Partner Details", default=True,)
show_cost_center = fields.Boolean(string="Show Analytic Account", default=True,)
@api.onchange("account_code_from", "account_code_to")
def on_change_account_range(self):
if (
self.account_code_from
and self.account_code_from.code.isdigit()
and self.account_code_to
and self.account_code_to.code.isdigit()
):
start_range = int(self.account_code_from.code)
end_range = int(self.account_code_to.code)
self.account_ids = self.env["account.account"].search(
[("code", "in", [x for x in range(start_range, end_range + 1)])]
)
if self.company_id:
self.account_ids = self.account_ids.filtered(
lambda a: a.company_id == self.company_id
)
def _init_date_from(self): def _init_date_from(self):
"""set start date to begin of current year if fiscal year running""" """set start date to begin of current year if fiscal year running"""
@ -272,7 +302,9 @@ class GeneralLedgerReportWizard(models.TransientModel):
"company_id": self.company_id.id, "company_id": self.company_id.id,
"account_ids": self.account_ids.ids, "account_ids": self.account_ids.ids,
"partner_ids": self.partner_ids.ids, "partner_ids": self.partner_ids.ids,
"show_partner_details": self.show_partner_details,
"cost_center_ids": self.cost_center_ids.ids, "cost_center_ids": self.cost_center_ids.ids,
"show_cost_center": self.show_cost_center,
"analytic_tag_ids": self.analytic_tag_ids.ids, "analytic_tag_ids": self.analytic_tag_ids.ids,
"journal_ids": self.account_journal_ids.ids, "journal_ids": self.account_journal_ids.ids,
"centralize": self.centralize, "centralize": self.centralize,

40
account_financial_report/wizard/general_ledger_wizard_view.xml

@ -26,23 +26,45 @@
<group name="other_filters"> <group name="other_filters">
<field name="target_move" widget="radio" /> <field name="target_move" widget="radio" />
<field name="centralize" /> <field name="centralize" />
<field name="show_partner_details" />
<field name="hide_account_at_0" /> <field name="hide_account_at_0" />
<field name="foreign_currency" /> <field name="foreign_currency" />
<field name="show_analytic_tags" /> <field name="show_analytic_tags" />
<field name="show_cost_center" />
</group> </group>
</group> </group>
<notebook> <notebook>
<page string="Filter accounts"> <page string="Filter accounts">
<group col="4">
<group name="account_filter" col="4">
<label for="account_ids" colspan="4" />
<field name="receivable_accounts_only" /> <field name="receivable_accounts_only" />
<field name="payable_accounts_only" /> <field name="payable_accounts_only" />
<label for="account_code_from" string="From Code" />
<div>
<div class="o_row">
<field
name="account_code_from"
class="oe_inline"
options="{'no_create': True}"
/>
<span class="oe_inline">
To
</span>
<field
name="account_code_to"
class="oe_inline"
options="{'no_create': True}"
/>
</div>
</div>
<field
name="account_ids"
nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"
colspan="4"
/>
</group> </group>
<field
name="account_ids"
nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"
/>
</page> </page>
<page string="Filter partners"> <page string="Filter partners">
<field <field
@ -53,14 +75,14 @@
/> />
</page> </page>
<page <page
string="Filter cost centers"
string="Filter analytic accounts"
groups="analytic.group_analytic_accounting" groups="analytic.group_analytic_accounting"
> >
<field <field
name="cost_center_ids" name="cost_center_ids"
nolabel="1" nolabel="1"
widget="many2many_tags"
options="{'no_create': True}" options="{'no_create': True}"
groups="analytic.group_analytic_accounting"
/> />
</page> </page>
<page string="Filter analytic tags"> <page string="Filter analytic tags">

50
account_financial_report/wizard/open_items_wizard.py

@ -31,6 +31,7 @@ class OpenItemsReportWizard(models.TransientModel):
comodel_name="account.account", comodel_name="account.account",
string="Filter accounts", string="Filter accounts",
domain=[("reconcile", "=", True)], domain=[("reconcile", "=", True)],
required=True,
) )
hide_account_at_0 = fields.Boolean( hide_account_at_0 = fields.Boolean(
string="Hide account ending balance at 0", string="Hide account ending balance at 0",
@ -54,6 +55,44 @@ class OpenItemsReportWizard(models.TransientModel):
"will display initial and final balance in that currency.", "will display initial and final balance in that currency.",
default=lambda self: self._default_foreign_currency(), default=lambda self: self._default_foreign_currency(),
) )
show_partner_details = fields.Boolean(string="Show Partner Details", default=True,)
account_code_from = fields.Many2one(
comodel_name="account.account",
string="Account Code From",
help="Starting account in a range",
)
account_code_to = fields.Many2one(
comodel_name="account.account",
string="Account Code To",
help="Ending account in a range",
)
@api.onchange("account_code_from", "account_code_to")
def on_change_account_range(self):
if (
self.account_code_from
and self.account_code_from.code.isdigit()
and self.account_code_to
and self.account_code_to.code.isdigit()
):
start_range = int(self.account_code_from.code)
end_range = int(self.account_code_to.code)
self.account_ids = self.env["account.account"].search(
[
("code", "in", [x for x in range(start_range, end_range + 1)]),
("reconcile", "=", True),
]
)
if self.company_id:
self.account_ids = self.account_ids.filtered(
lambda a: a.company_id == self.company_id
)
return {
"domain": {
"account_code_from": [("reconcile", "=", True)],
"account_code_to": [("reconcile", "=", True)],
}
}
def _default_foreign_currency(self): def _default_foreign_currency(self):
return self.env.user.has_group("base.group_multi_currency") return self.env.user.has_group("base.group_multi_currency")
@ -80,6 +119,10 @@ class OpenItemsReportWizard(models.TransientModel):
res["domain"]["partner_ids"] += self._get_partner_ids_domain() res["domain"]["partner_ids"] += self._get_partner_ids_domain()
return res return res
@api.onchange("account_ids")
def onchange_account_ids(self):
return {"domain": {"account_ids": [("reconcile", "=", True)]}}
@api.onchange("receivable_accounts_only", "payable_accounts_only") @api.onchange("receivable_accounts_only", "payable_accounts_only")
def onchange_type_accounts_only(self): def onchange_type_accounts_only(self):
"""Handle receivable/payable accounts only change.""" """Handle receivable/payable accounts only change."""
@ -91,9 +134,9 @@ class OpenItemsReportWizard(models.TransientModel):
domain += [("internal_type", "=", "receivable")] domain += [("internal_type", "=", "receivable")]
elif self.payable_accounts_only: elif self.payable_accounts_only:
domain += [("internal_type", "=", "payable")] domain += [("internal_type", "=", "payable")]
elif not self.receivable_accounts_only and not self.payable_accounts_only:
domain += [("reconcile", "=", True)]
self.account_ids = self.env["account.account"].search(domain)
self.account_ids = self.env["account.account"].search(domain)
else:
self.account_ids = None
def _print_report(self, report_type): def _print_report(self, report_type):
self.ensure_one() self.ensure_one()
@ -135,6 +178,7 @@ class OpenItemsReportWizard(models.TransientModel):
"only_posted_moves": self.target_move == "posted", "only_posted_moves": self.target_move == "posted",
"hide_account_at_0": self.hide_account_at_0, "hide_account_at_0": self.hide_account_at_0,
"foreign_currency": self.foreign_currency, "foreign_currency": self.foreign_currency,
"show_partner_details": self.show_partner_details,
"company_id": self.company_id.id, "company_id": self.company_id.id,
"target_move": self.target_move, "target_move": self.target_move,
"account_ids": self.account_ids.ids, "account_ids": self.account_ids.ids,

19
account_financial_report/wizard/open_items_wizard_view.xml

@ -20,6 +20,7 @@
</group> </group>
<group name="other_filters"> <group name="other_filters">
<field name="target_move" widget="radio" /> <field name="target_move" widget="radio" />
<field name="show_partner_details" />
<field name="hide_account_at_0" /> <field name="hide_account_at_0" />
<field name="foreign_currency" /> <field name="foreign_currency" />
</group> </group>
@ -36,6 +37,24 @@
<group name="account_filter" col="4"> <group name="account_filter" col="4">
<field name="receivable_accounts_only" /> <field name="receivable_accounts_only" />
<field name="payable_accounts_only" /> <field name="payable_accounts_only" />
<label for="account_code_from" string="From Code" />
<div>
<div class="o_row">
<field
name="account_code_from"
class="oe_inline"
options="{'no_create': True}"
/>
<span class="oe_inline">
To
</span>
<field
name="account_code_to"
class="oe_inline"
options="{'no_create': True}"
/>
</div>
</div>
<field <field
name="account_ids" name="account_ids"
nolabel="1" nolabel="1"

28
account_financial_report/wizard/trial_balance_wizard.py

@ -77,6 +77,34 @@ class TrialBalanceReportWizard(models.TransientModel):
"account currency is not setup through chart of accounts " "account currency is not setup through chart of accounts "
"will display initial and final balance in that currency.", "will display initial and final balance in that currency.",
) )
account_code_from = fields.Many2one(
comodel_name="account.account",
string="Account Code From",
help="Starting account in a range",
)
account_code_to = fields.Many2one(
comodel_name="account.account",
string="Account Code To",
help="Ending account in a range",
)
@api.onchange("account_code_from", "account_code_to")
def on_change_account_range(self):
if (
self.account_code_from
and self.account_code_from.code.isdigit()
and self.account_code_to
and self.account_code_to.code.isdigit()
):
start_range = int(self.account_code_from.code)
end_range = int(self.account_code_to.code)
self.account_ids = self.env["account.account"].search(
[("code", "in", [x for x in range(start_range, end_range + 1)])]
)
if self.company_id:
self.account_ids = self.account_ids.filtered(
lambda a: a.company_id == self.company_id
)
@api.constrains("hierarchy_on", "show_hierarchy_level") @api.constrains("hierarchy_on", "show_hierarchy_level")
def _check_show_hierarchy_level(self): def _check_show_hierarchy_level(self):

16
account_financial_report/wizard/trial_balance_wizard_view.xml

@ -73,6 +73,22 @@
<label for="account_ids" colspan="4" /> <label for="account_ids" colspan="4" />
<field name="receivable_accounts_only" /> <field name="receivable_accounts_only" />
<field name="payable_accounts_only" /> <field name="payable_accounts_only" />
<label for="account_code_from" string="From Code" />
<div>
<div class="o_row">
<field
name="account_code_from"
class="oe_inline"
options="{'no_create': True}"
/>
<span class="oe_inline">To</span>
<field
name="account_code_to"
class="oe_inline"
options="{'no_create': True}"
/>
</div>
</div>
<field <field
name="account_ids" name="account_ids"
nolabel="1" nolabel="1"

7
account_financial_report/wizard/vat_report_wizard.py

@ -25,6 +25,12 @@ class VATReportWizard(models.TransientModel):
default="taxtags", default="taxtags",
) )
tax_detail = fields.Boolean("Detail Taxes") tax_detail = fields.Boolean("Detail Taxes")
target_move = fields.Selection(
[("posted", "All Posted Entries"), ("all", "All Entries")],
string="Target Moves",
required=True,
default="posted",
)
@api.onchange("company_id") @api.onchange("company_id")
def onchange_company_id(self): def onchange_company_id(self):
@ -105,6 +111,7 @@ class VATReportWizard(models.TransientModel):
"date_from": self.date_from, "date_from": self.date_from,
"date_to": self.date_to, "date_to": self.date_to,
"based_on": self.based_on, "based_on": self.based_on,
"only_posted_moves": self.target_move == "posted",
"tax_detail": self.tax_detail, "tax_detail": self.tax_detail,
} }

9
account_financial_report/wizard/vat_report_wizard_view.xml

@ -18,10 +18,11 @@
<field name="date_from" /> <field name="date_from" />
<field name="date_to" /> <field name="date_to" />
</group> </group>
<group name="other_filters">
<field name="based_on" widget="radio" />
<field name="tax_detail" />
</group>
</group>
<group name="other_filters">
<field name="target_move" widget="radio" />
<field name="based_on" widget="radio" />
<field name="tax_detail" />
</group> </group>
<footer> <footer>
<button <button

Loading…
Cancel
Save