diff --git a/__manifest__.py b/__manifest__.py index 9954c36c114867b0313335e0dd3d1554e15e7f0e..709413b177ea4cff20bd34bf9d2f2592218222b2 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -10,6 +10,7 @@ "installable": True, "depends": [ "account", + "account_banking_mandate", "account_banking_sepa_direct_debit", "account_payment_order", "cgscop_account", @@ -19,6 +20,7 @@ ], "data": [ "security/ir.model.access.csv", + "views/account_banking_mandate.xml", "views/account_move.xml", "views/account_payment_order.xml", "views/account_payment_line.xml", @@ -26,6 +28,7 @@ "views/res_partner.xml", "report/scop_contribution_report.xml", "wizard/account_payment_line_create_view.xml", + "wizard/account_banking_mandate_change_wizard.xml", ], "qweb": [ "static/src/xml/*.xml", diff --git a/models/__init__.py b/models/__init__.py index 5c324d7446baca0c0531001a4a2c5fa3ed029e42..573ece4f59fd9308a3612c7c125f8c76a8d74d81 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -1,6 +1,7 @@ # © 2019 Le Filament (<http://www.le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from . import account_banking_mandate from . import account_move from . import account_payment_order from . import chart_template diff --git a/models/account_banking_mandate.py b/models/account_banking_mandate.py new file mode 100644 index 0000000000000000000000000000000000000000..1f4d9ac622963c0f0900b28e648615ec6a853d93 --- /dev/null +++ b/models/account_banking_mandate.py @@ -0,0 +1,51 @@ +# © 2020 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models + + +class AccountBankingMandate(models.Model): + _inherit = "account.banking.mandate" + + # ------------------------------------------------------ + # Button functions + # ------------------------------------------------------ + def set_invoice_mandate(self): + return { + "name": "Affectation du nouveau mandat", + "type": "ir.actions.act_window", + "res_model": "account.banking.mandate.change.wizard", + "views": [[False, "form"]], + "target": "new", + } + + # ------------------------------------------------------ + # Business functions + # ------------------------------------------------------ + def _select_open_invoices(self): + self.ensure_one() + invoice_ids = self.env["account.move"].search( + [ + ("partner_id", "=", self.partner_id.id), + ("move_type", "in", ("out_invoice", "out_refund")), + ("state", "in", ("draft", "posted")), + ("payment_state", "in", ("draft", "not_paid", "partial")), + ] + ) + return invoice_ids + + def _change_invoice_mandate(self, invoice): + """ + Affecte le mandat courant pur la facture passée en paramètre + :param invoice : objet account.move + """ + payment_mode = self.env["account.payment.mode"].search( + [("payment_method_id.code", "=", "sepa_direct_debit")] + ) + invoice.update( + { + "payment_mode_id": payment_mode.id, + "partner_bank_id": self.partner_bank_id.id, + "mandate_id": self.id, + } + ) diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index a6a75a0cff7931caca51cb84c17fe256ef518c6e..5e95b369ad3f013361a3de132791e88734af2f5d 100644 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -1,2 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_scop_contribution_report_user,access_scop_contribution_report_user,model_scop_contribution_report,base.group_user,1,0,0,0 +access_account_banking_mandate_change_wizard,access_account_banking_mandate_change_wizard,model_account_banking_mandate_change_wizard,account.group_account_manager,1,1,1,1 diff --git a/views/account_banking_mandate.xml b/views/account_banking_mandate.xml new file mode 100644 index 0000000000000000000000000000000000000000..70d2c1b0ebfed13ceda7dc83554a7dfcff702b13 --- /dev/null +++ b/views/account_banking_mandate.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" ?> +<odoo> + <!-- Copyright 2020 Le Filament + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> + <data> + + <record id="view_mandate_form_inherit" model="ir.ui.view"> + <field name="name">scop.view.mandate.form</field> + <field name="model">account.banking.mandate</field> + <field name="inherit_id" ref="account_banking_mandate.view_mandate_form" /> + <field name="priority" eval="90" /> + <field name="arch" type="xml"> + <xpath expr="//group[@name='main']" position="before"> + <div class="col-12 mt16 mb16" name="change_mandate_button"> + <button + name="set_invoice_mandate" + type="object" + class="btn-outline-info" + string="Affecter ce mandat aux factures ouvertes" + attrs="{'invisible': [('state', '!=', 'valid')]}" + /> + </div> + </xpath> + </field> + </record> + </data> +</odoo> diff --git a/wizard/__init__.py b/wizard/__init__.py index 95b3bde4f8f1e35bc95b4dbba7109abc3fc947ec..e0feed5416fab7eb083ee6cee672ffb42d5c700f 100644 --- a/wizard/__init__.py +++ b/wizard/__init__.py @@ -1,5 +1,6 @@ # © 2020 Le Filament (<http://www.le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from . import account_banking_mandate_change_wizard from . import account_move_reversal from . import account_payment_line_create diff --git a/wizard/account_banking_mandate_change_wizard.py b/wizard/account_banking_mandate_change_wizard.py new file mode 100644 index 0000000000000000000000000000000000000000..45fafcbc6e3339ef4fb1bbe9d8e870d98505771e --- /dev/null +++ b/wizard/account_banking_mandate_change_wizard.py @@ -0,0 +1,39 @@ +# © 2020 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + + +class AccountBankingMandateChange(models.TransientModel): + _name = "account.banking.mandate.change.wizard" + _description = "Wizard changement mandat" + + @api.model + def _default_mandate_id(self): + return self.env.context.get("active_id") + + @api.model + def _default_invoice_ids(self): + invoice_ids = ( + self.env["account.banking.mandate"] + .browse(self.env.context.get("active_id")) + ._select_open_invoices() + ) + return invoice_ids + + mandate_id = fields.Many2one( + comodel_name="account.banking.mandate", + string="Mandat", + default=_default_mandate_id, + required=True, + ) + partner_id = fields.Many2one(related="mandate_id.partner_id") + invoice_ids = fields.Many2many( + comodel_name="account.move", + string="Factures", + default=_default_invoice_ids, + ) + + def change_mandate(self): + for invoice in self.invoice_ids: + self.mandate_id._change_invoice_mandate(invoice) diff --git a/wizard/account_banking_mandate_change_wizard.xml b/wizard/account_banking_mandate_change_wizard.xml new file mode 100644 index 0000000000000000000000000000000000000000..b3ebc0909444e62e59b999648d14d3aac332c463 --- /dev/null +++ b/wizard/account_banking_mandate_change_wizard.xml @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="utf-8" ?> +<odoo> + <data> + <record id="account_banking_mandate_change_wizard_form" model="ir.ui.view"> + <field name="name">account.banking.mandate.change.wizard.form</field> + <field name="model">account.banking.mandate.change.wizard</field> + <field name="arch" type="xml"> + <form string="Changement de mandat"> + <group> + <field name="partner_id" invisible="1" /> + <field name="mandate_id" readonly="1" /> + </group> + <label for="invoice_ids" /> + <field + name="invoice_ids" + mode="tree" + domain="[('partner_id', '=', partner_id), ('state', 'in', ('draft', 'posted')), ('payment_state', 'in', ('draft', 'not_paid', 'partial')), ('move_type', 'in', ('out_invoice', 'out_refund'))]" + > + <tree + editable="bottom" + create="0" + edit="0" + delete="1" + decoration-info="state == 'draft'" + > + <field name="partner_id" invisible="1" /> + <field name="name" decoration-bf="1" /> + <field name="partner_member_number" /> + <field name="invoice_date" /> + <field + name="invoice_partner_display_name" + string="Partenaire" + /> + <field name="invoice_date_due" /> + <field name="amount_untaxed_signed" string="Total HT" /> + <field + name="amount_total_signed" + decoration-bf="1" + string="Total TTC" + /> + <field + name="state" + widget="badge" + decoration-success="state == 'posted'" + decoration-info="state == 'draft'" + /> + <field + name="payment_state" + widget="badge" + decoration-danger="payment_state == 'not_paid'" + decoration-warning="payment_state in ('partial', 'in_payment')" + decoration-success="payment_state in ('paid', 'reversed')" + /> + <field name="currency_id" invisible="1" /> + <field name="company_currency_id" invisible="1" /> + <field name="company_id" invisible="1" /> + </tree> + </field> + <footer> + <button + name="change_mandate" + type="object" + string="Affecter le mandat" + class="btn-primary" + confirm="Valider le changement de mandat ?" + /> + <button special="cancel" string="Cancel" /> + </footer> + </form> + </field> + </record> + </data> +</odoo>