-
-
Notifications
You must be signed in to change notification settings - Fork 534
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
686 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
TO BE FILLED AUTOMATICALLY |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
from . import models | ||
from .hooks import pre_init_hook | ||
from . import reports | ||
from . import wizards |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Copyright 2024 Dixmit | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). | ||
|
||
{ | ||
"name": "L10n Es Payment Ratio", | ||
"summary": """ | ||
Create a report to see your payment ratio""", | ||
"version": "14.0.1.0.0", | ||
"license": "AGPL-3", | ||
"author": "Dixmit,Odoo Community Association (OCA)", | ||
"website": "https://github.com/OCA/l10n-spain", | ||
"depends": ["account", "report_xlsx"], | ||
"data": [ | ||
"security/ir.model.access.csv", | ||
"wizards/company_payment_ratio_wizard.xml", | ||
"views/account_move.xml", | ||
"reports/reports.xml", | ||
], | ||
"demo": [], | ||
"pre_init_hook": "pre_init_hook", | ||
"maintainers": ["pedrobaeza"], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# Copyright 2024 Dixmit | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
|
||
def pre_init_hook(cr): | ||
"""Precreate Information, as it could take a long time and recompute work if done by ORM""" | ||
cr.execute("ALTER TABLE account_move ADD COLUMN IF NOT EXISTS payment_date DATE") | ||
cr.execute( | ||
"ALTER TABLE account_move ADD COLUMN IF NOT EXISTS payment_ratio_create FLOAT" | ||
) | ||
cr.execute( | ||
"ALTER TABLE account_move ADD COLUMN IF NOT EXISTS payment_ratio_bill_date FLOAT" | ||
) | ||
cr.execute( | ||
"ALTER TABLE account_move ADD COLUMN IF NOT EXISTS payment_ratio_validation FLOAT" | ||
) | ||
cr.execute( | ||
""" | ||
UPDATE account_move am | ||
SET payment_date = T.payment_date, | ||
payment_ratio_create = - T.payment_ratio_create * am.amount_total_signed, | ||
payment_ratio_bill_date = - T.payment_ratio_bill_date * am.amount_total_signed, | ||
payment_ratio_validation = - T.payment_ratio_validation * am.amount_total_signed | ||
FROM ( | ||
SELECT am.id, MAX(am2.date) as payment_date, | ||
EXTRACT(DAY FROM MAX(am2.date)::timestamp-am.create_date::timestamp) | ||
as payment_ratio_create, | ||
EXTRACT(DAY FROM MAX(am2.date)::timestamp-am.invoice_date::timestamp) | ||
as payment_ratio_bill_date, | ||
EXTRACT(DAY FROM MAX(am2.date)::timestamp-am.date::timestamp) | ||
as payment_ratio_validation | ||
FROM account_move am | ||
INNER JOIN res_company rc ON rc.id = am.company_id | ||
INNER JOIN res_currency cur ON cur.id = rc.currency_id | ||
INNER JOIN account_move_line aml ON aml.move_id = am.id | ||
INNER JOIN account_partial_reconcile apr | ||
ON apr.credit_move_id = aml.id OR apr.debit_move_id = aml.id | ||
INNER JOIN account_move_line aml2 | ||
ON aml2.id!= aml.id | ||
AND (apr.credit_move_id = aml2.id OR apr.debit_move_id = aml2.id) | ||
INNER JOIN account_move am2 ON am2.id = aml2.move_id | ||
WHERE am.move_type in ('in_refund', 'in_invoice') | ||
AND abs(am.amount_residual) < cur.rounding | ||
AND am.state = 'posted' | ||
GROUP BY am.id | ||
) T | ||
WHERE T.id = am.id | ||
""" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import account_move |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# Copyright 2024 Dixmit | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). | ||
|
||
from odoo import api, fields, models, tools | ||
|
||
|
||
class AccountMove(models.Model): | ||
|
||
_inherit = "account.move" | ||
|
||
payment_date = fields.Date(compute="_compute_amount", store=True) | ||
payment_ratio_create = fields.Float(compute="_compute_amount", store=True) | ||
payment_ratio_bill_date = fields.Float(compute="_compute_amount", store=True) | ||
payment_ratio_validation = fields.Float(compute="_compute_amount", store=True) | ||
|
||
@api.depends() | ||
def _compute_amount(self): | ||
super(AccountMove, self)._compute_amount() | ||
for record in self: | ||
if ( | ||
record.state == "posted" | ||
and record.is_purchase_document() | ||
and tools.float_is_zero( | ||
record.amount_residual, | ||
precision_rounding=record.currency_id.rounding, | ||
) | ||
): | ||
payments = ( | ||
record.line_ids.matched_debit_ids.debit_move_id | ||
| record.line_ids.matched_credit_ids.credit_move_id | ||
) | ||
date = ( | ||
payments and max(payments.move_id.mapped("date")) | ||
) or record.date | ||
record.payment_date = date | ||
record.payment_ratio_create = ( | ||
-record.amount_total_signed | ||
* (date - record.create_date.date()).days | ||
) | ||
record.payment_ratio_bill_date = ( | ||
-record.amount_total_signed | ||
* (date - (record.invoice_date or record.date)).days | ||
) | ||
record.payment_ratio_validation = ( | ||
-record.amount_total_signed * (date - record.date).days | ||
) | ||
else: | ||
record.payment_date = False | ||
record.payment_ratio_create = 0.0 | ||
record.payment_ratio_bill_date = 0.0 | ||
record.payment_ratio_validation = 0.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
* Dixmit <https://www.dixmit.com> | ||
|
||
* Enric Tobella |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
This addon generates a report to see and export the payment ratio according to BOE <https://www.boe.es/buscar/doc.php?id=BOE-A-2017-15364> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import report_l10n_es_payment_ratio_xlsx |
185 changes: 185 additions & 0 deletions
185
l10n_es_payment_ratio/reports/report_l10n_es_payment_ratio_xlsx.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
# Author: Julien Coux | ||
# Copyright 2016 Camptocamp SA | ||
# Copyright 2021 Tecnativa - João Marques | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
from odoo import _, models | ||
|
||
|
||
class AbstractReportXslx(models.AbstractModel): | ||
_name = "report.l10n_es_payment_ratio.report_l10n_es_payment_ratio_xlsx" | ||
_description = "Payment Ratio report XLSX" | ||
_inherit = "report.report_xlsx.abstract" | ||
|
||
def get_workbook_options(self): | ||
vals = super().get_workbook_options() | ||
vals.update({"constant_memory": True}) | ||
return vals | ||
|
||
def _define_formats(self, workbook): | ||
currency_id = self.env["res.company"]._default_currency_id() | ||
formats = { | ||
"format_bold": workbook.add_format({"bold": True}), | ||
"format_right": workbook.add_format({"align": "right"}), | ||
"format_left": workbook.add_format({"align": "left"}), | ||
"format_right_bold_italic": workbook.add_format( | ||
{"align": "right", "bold": True, "italic": True} | ||
), | ||
"format_header_left": workbook.add_format( | ||
{"bold": True, "border": True, "bg_color": "#FFFFCC"} | ||
), | ||
"format_header_center": workbook.add_format( | ||
{"bold": True, "align": "center", "border": True, "bg_color": "#FFFFCC"} | ||
), | ||
"format_header_right": workbook.add_format( | ||
{"bold": True, "align": "right", "border": True, "bg_color": "#FFFFCC"} | ||
), | ||
"format_header_amount": workbook.add_format( | ||
{"bold": True, "border": True, "bg_color": "#FFFFCC"} | ||
), | ||
"format_amount": workbook.add_format(), | ||
"format_amount_bold": workbook.add_format({"bold": True}), | ||
"format_percent_bold_italic": workbook.add_format( | ||
{"bold": True, "italic": True} | ||
), | ||
} | ||
formats["format_amount"].set_num_format( | ||
"#,##0." + "0" * currency_id.decimal_places | ||
) | ||
formats["format_header_amount"].set_num_format( | ||
"#,##0." + "0" * currency_id.decimal_places | ||
) | ||
formats["format_percent_bold_italic"].set_num_format("#,##0.00%") | ||
formats["format_amount_bold"].set_num_format( | ||
"#,##0." + "0" * currency_id.decimal_places | ||
) | ||
return formats | ||
|
||
def _generate_xlsx_filters(self, sheet, data, objects, formats): | ||
row = 0 | ||
sheet.write(row, 0, _("Company"), formats["format_header_right"]) | ||
sheet.write(row, 1, data["company_name"], formats["format_left"]) | ||
row += 1 | ||
sheet.write(row, 0, _("Start"), formats["format_header_right"]) | ||
sheet.write(row, 1, data["start_date"], formats["format_left"]) | ||
row += 1 | ||
sheet.write(row, 0, _("End"), formats["format_header_right"]) | ||
sheet.write(row, 1, data["end_date"], formats["format_left"]) | ||
row += 1 | ||
sheet.write(row, 0, _("Total payed amount"), formats["format_header_right"]) | ||
sheet.write( | ||
row, 1, data["aggregated_data"]["amount_total"], formats["format_amount"] | ||
) | ||
row += 1 | ||
sheet.write(row, 0, _("Ratio of payed amount"), formats["format_header_right"]) | ||
if data["aggregated_data"]["amount_total"]: | ||
sheet.write( | ||
row, | ||
1, | ||
data["aggregated_data"][data["field"]] | ||
/ data["aggregated_data"]["amount_total"], | ||
formats["format_amount"], | ||
) | ||
row += 1 | ||
sheet.write(row, 0, _("Pending amount"), formats["format_header_right"]) | ||
sheet.write( | ||
row, | ||
1, | ||
data["aggregated_data"]["pending_amount_total"], | ||
formats["format_amount"], | ||
) | ||
row += 1 | ||
sheet.write( | ||
row, 0, _("Ratio of pending payment"), formats["format_header_right"] | ||
) | ||
if data["aggregated_data"]["pending_amount_total"]: | ||
sheet.write( | ||
row, | ||
1, | ||
data["aggregated_data"]["pending_" + data["field"]] | ||
/ data["aggregated_data"]["pending_amount_total"], | ||
formats["format_amount"], | ||
) | ||
row += 1 | ||
sheet.write(row, 0, _("Ratio of payment"), formats["format_header_right"]) | ||
if ( | ||
data["aggregated_data"]["amount_total"] | ||
+ data["aggregated_data"]["pending_amount_total"] | ||
): | ||
sheet.write( | ||
row, | ||
1, | ||
( | ||
data["aggregated_data"][data["field"]] | ||
+ data["aggregated_data"]["pending_" + data["field"]] | ||
) | ||
/ ( | ||
data["aggregated_data"]["amount_total"] | ||
+ data["aggregated_data"]["pending_amount_total"] | ||
), | ||
formats["format_amount"], | ||
) | ||
return row | ||
|
||
def _generate_xlsx_report_headers(self, sheet, data, objects, formats, row): | ||
sheet.write(row, 0, _("Partner"), formats["format_header_left"]) | ||
sheet.write(row, 1, _("Payed amount"), formats["format_header_left"]) | ||
sheet.write(row, 2, _("Ratio of payed amount"), formats["format_header_left"]) | ||
sheet.write(row, 3, _("Pending amount"), formats["format_header_left"]) | ||
sheet.write(row, 4, _("Ratio of pending amount"), formats["format_header_left"]) | ||
sheet.write(row, 5, _("Ratio of payment"), formats["format_header_left"]) | ||
row += 1 | ||
return row | ||
|
||
def _generate_xlsx_report_data(self, sheet, data, objects, formats, row): | ||
for partner_data in data["data"]: | ||
if not ( | ||
partner_data["amount_total"] | ||
+ partner_data.get("pending_amount_total", 0) | ||
): | ||
continue | ||
sheet.write(row, 0, partner_data["partner_id"][1], formats["format_left"]) | ||
sheet.write(row, 1, partner_data["amount_total"], formats["format_amount"]) | ||
if partner_data["amount_total"]: | ||
sheet.write( | ||
row, | ||
2, | ||
partner_data[data["field"]] / partner_data["amount_total"], | ||
formats["format_amount"], | ||
) | ||
sheet.write( | ||
row, | ||
3, | ||
partner_data.get("pending_amount_total", 0), | ||
formats["format_amount"], | ||
) | ||
if partner_data.get("pending_amount_total", 0): | ||
sheet.write( | ||
row, | ||
4, | ||
partner_data.get("pending_" + data["field"], 0) | ||
/ partner_data.get("pending_amount_total", 0), | ||
formats["format_amount"], | ||
) | ||
sheet.write( | ||
row, | ||
5, | ||
( | ||
partner_data[data["field"]] | ||
+ partner_data.get("pending_" + data["field"], 0) | ||
) | ||
/ ( | ||
partner_data["amount_total"] | ||
+ partner_data.get("pending_amount_total", 0) | ||
), | ||
formats["format_amount"], | ||
) | ||
row += 1 | ||
return row | ||
|
||
def generate_xlsx_report(self, workbook, data, objects): | ||
formats = self._define_formats(workbook) | ||
sheet = workbook.add_worksheet("Payment Ratio") | ||
row = self._generate_xlsx_filters(sheet, data, objects, formats) | ||
row += 2 | ||
row = self._generate_xlsx_report_headers(sheet, data, objects, formats, row) | ||
row = self._generate_xlsx_report_data(sheet, data, objects, formats, row) | ||
Oops, something went wrong.