diff --git a/account_payment_order/__manifest__.py b/account_payment_order/__manifest__.py index b66b3d4fd..71d614d98 100644 --- a/account_payment_order/__manifest__.py +++ b/account_payment_order/__manifest__.py @@ -7,37 +7,34 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). { - 'name': 'Account Payment Order', - 'version': '12.0.1.4.0', - 'license': 'AGPL-3', - 'author': "ACSONE SA/NV, " - "Therp BV, " - "Tecnativa, " - "Akretion, " - "Odoo Community Association (OCA)", - 'website': 'https://github.com/OCA/bank-payment', - 'category': 'Banking addons', - 'depends': [ - 'account_payment_partner', - 'base_iban', # for manual_bank_tranfer + "name": "Account Payment Order", + "version": "12.0.1.4.0", + "license": "AGPL-3", + "author": "ACSONE SA/NV, " + "Therp BV, " + "Tecnativa, " + "Akretion, " + "Odoo Community Association (OCA)", + "website": "https://github.com/OCA/bank-payment", + "category": "Banking addons", + "depends": ["account_payment_partner", "base_iban",], # for manual_bank_tranfer + "data": [ + "views/account_payment_method.xml", + "security/payment_security.xml", + "security/ir.model.access.csv", + "wizard/account_payment_line_create_view.xml", + "wizard/account_invoice_payment_line_multi_view.xml", + "views/account_payment_mode.xml", + "views/account_payment_order.xml", + "views/account_payment_line.xml", + "views/bank_payment_line.xml", + "views/account_move_line.xml", + "views/ir_attachment.xml", + "views/account_invoice_view.xml", + "data/payment_seq.xml", + "report/print_account_payment_order.xml", + "report/account_payment_order.xml", ], - 'data': [ - 'views/account_payment_method.xml', - 'security/payment_security.xml', - 'security/ir.model.access.csv', - 'wizard/account_payment_line_create_view.xml', - 'wizard/account_invoice_payment_line_multi_view.xml', - 'views/account_payment_mode.xml', - 'views/account_payment_order.xml', - 'views/account_payment_line.xml', - 'views/bank_payment_line.xml', - 'views/account_move_line.xml', - 'views/ir_attachment.xml', - 'views/account_invoice_view.xml', - 'data/payment_seq.xml', - 'report/print_account_payment_order.xml', - 'report/account_payment_order.xml', - ], - 'demo': ['demo/payment_demo.xml'], - 'installable': True, + "demo": ["demo/payment_demo.xml"], + "installable": True, } diff --git a/account_payment_order/data/payment_seq.xml b/account_payment_order/data/payment_seq.xml index c382f146c..0d80d10ff 100644 --- a/account_payment_order/data/payment_seq.xml +++ b/account_payment_order/data/payment_seq.xml @@ -1,35 +1,30 @@ - + - - - - Bank Payment Line - bank.payment.line - L - 5 - - - - - Payment Line - account.payment.line - P - 5 - - - - - Payment Order - account.payment.order - PAY - 4 - - - + + Bank Payment Line + bank.payment.line + L + 5 + + + + Payment Line + account.payment.line + P + 5 + + + + Payment Order + account.payment.order + PAY + 4 + + diff --git a/account_payment_order/demo/payment_demo.xml b/account_payment_order/demo/payment_demo.xml index 900abe9e9..95b42c3a4 100644 --- a/account_payment_order/demo/payment_demo.xml +++ b/account_payment_order/demo/payment_demo.xml @@ -1,32 +1,47 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/account_payment_order/migrations/12.0.1.2.0/post-migration.py b/account_payment_order/migrations/12.0.1.2.0/post-migration.py index e50551754..575e13c76 100644 --- a/account_payment_order/migrations/12.0.1.2.0/post-migration.py +++ b/account_payment_order/migrations/12.0.1.2.0/post-migration.py @@ -7,9 +7,12 @@ from openupgradelib import openupgrade @openupgrade.migrate() def migrate(env, version): openupgrade.set_xml_ids_noupdate_value( - env, 'account_payment_order', [ - 'bank_payment_line_seq', - 'account_payment_line_seq', - 'account_payment_order_seq', - ], True, + env, + "account_payment_order", + [ + "bank_payment_line_seq", + "account_payment_line_seq", + "account_payment_order_seq", + ], + True, ) diff --git a/account_payment_order/models/account_invoice.py b/account_payment_order/models/account_invoice.py index 6c7345ed4..8f1b2a377 100644 --- a/account_payment_order/models/account_invoice.py +++ b/account_payment_order/models/account_invoice.py @@ -3,40 +3,37 @@ # © 2016 Akretion (Alexis de Lattre ) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from odoo import models, fields, api, _ +from odoo import _, api, fields, models from odoo.exceptions import UserError class AccountInvoice(models.Model): - _inherit = 'account.invoice' + _inherit = "account.invoice" - payment_order_ok = fields.Boolean( - compute="_compute_payment_order_ok", - ) + payment_order_ok = fields.Boolean(compute="_compute_payment_order_ok",) # we restore this field from <=v11 for now for preserving behavior # TODO: Check if we can remove it and base everything in something at # payment mode or company level reference_type = fields.Selection( - selection=[ - ('none', 'Free Reference'), - ('structured', 'Structured Reference'), - ], - string='Payment Reference', + selection=[("none", "Free Reference"), ("structured", "Structured Reference"),], + string="Payment Reference", required=True, readonly=True, - states={'draft': [('readonly', False)]}, - default='none', + states={"draft": [("readonly", False)]}, + default="none", ) - @api.depends('payment_mode_id', 'move_id', 'move_id.line_ids', - 'move_id.line_ids.payment_mode_id') + @api.depends( + "payment_mode_id", + "move_id", + "move_id.line_ids", + "move_id.line_ids.payment_mode_id", + ) def _compute_payment_order_ok(self): for invoice in self: - payment_mode = ( - invoice.move_id.line_ids.filtered( - lambda x: not x.reconciled - ).mapped('payment_mode_id')[:1] - ) + payment_mode = invoice.move_id.line_ids.filtered( + lambda x: not x.reconciled + ).mapped("payment_mode_id")[:1] if not payment_mode: payment_mode = invoice.payment_mode_id invoice.payment_order_ok = payment_mode.payment_order_ok @@ -45,19 +42,19 @@ class AccountInvoice(models.Model): def line_get_convert(self, line, part): """Copy supplier bank account from invoice to account move line""" res = super(AccountInvoice, self).line_get_convert(line, part) - if line.get('type') == 'dest' and line.get('invoice_id'): - invoice = self.browse(line['invoice_id']) - if invoice.type in ('in_invoice', 'in_refund'): - res['partner_bank_id'] = invoice.partner_bank_id.id or False + if line.get("type") == "dest" and line.get("invoice_id"): + invoice = self.browse(line["invoice_id"]) + if invoice.type in ("in_invoice", "in_refund"): + res["partner_bank_id"] = invoice.partner_bank_id.id or False return res @api.multi def _prepare_new_payment_order(self, payment_mode=None): self.ensure_one() if payment_mode is None: - payment_mode = self.env['account.payment.mode'] + payment_mode = self.env["account.payment.mode"] vals = { - 'payment_mode_id': payment_mode.id or self.payment_mode_id.id, + "payment_mode_id": payment_mode.id or self.payment_mode_id.id, } # other important fields are set by the inherit of create # in account_payment_order.py @@ -65,43 +62,48 @@ class AccountInvoice(models.Model): @api.multi def create_account_payment_line(self): - apoo = self.env['account.payment.order'] + apoo = self.env["account.payment.order"] result_payorder_ids = [] - action_payment_type = 'debit' + action_payment_type = "debit" for inv in self: - if inv.state != 'open': - raise UserError(_( - "The invoice %s is not in Open state") % inv.number) + if inv.state != "open": + raise UserError(_("The invoice %s is not in Open state") % inv.number) if not inv.move_id: - raise UserError(_( - "No Journal Entry on invoice %s") % inv.number) + raise UserError(_("No Journal Entry on invoice %s") % inv.number) applicable_lines = inv.move_id.line_ids.filtered( lambda x: ( - not x.reconciled and x.payment_mode_id.payment_order_ok and - x.account_id.internal_type in ('receivable', 'payable') and - not any(p_state in ('draft', 'open', 'generated') - for p_state in x.payment_line_ids.mapped('state')) + not x.reconciled + and x.payment_mode_id.payment_order_ok + and x.account_id.internal_type in ("receivable", "payable") + and not any( + p_state in ("draft", "open", "generated") + for p_state in x.payment_line_ids.mapped("state") + ) ) ) if not applicable_lines: - raise UserError(_( - 'No Payment Line created for invoice %s because ' - 'it already exists or because this invoice is ' - 'already paid.') % inv.number) - payment_modes = applicable_lines.mapped('payment_mode_id') + raise UserError( + _( + "No Payment Line created for invoice %s because " + "it already exists or because this invoice is " + "already paid." + ) + % inv.number + ) + payment_modes = applicable_lines.mapped("payment_mode_id") if not payment_modes: - raise UserError(_( - "No Payment Mode on invoice %s") % inv.number) + raise UserError(_("No Payment Mode on invoice %s") % inv.number) for payment_mode in payment_modes: - payorder = apoo.search([ - ('payment_mode_id', '=', payment_mode.id), - ('state', '=', 'draft') - ], limit=1) + payorder = apoo.search( + [ + ("payment_mode_id", "=", payment_mode.id), + ("state", "=", "draft"), + ], + limit=1, + ) new_payorder = False if not payorder: - payorder = apoo.create(inv._prepare_new_payment_order( - payment_mode - )) + payorder = apoo.create(inv._prepare_new_payment_order(payment_mode)) new_payorder = True result_payorder_ids.append(payorder.id) action_payment_type = payorder.payment_type @@ -112,28 +114,39 @@ class AccountInvoice(models.Model): line.create_payment_line_from_move_line(payorder) count += 1 if new_payorder: - inv.message_post(body=_( - '%d payment lines added to the new draft payment ' - 'order %s which has been automatically created.') - % (count, payorder.name)) + inv.message_post( + body=_( + "%d payment lines added to the new draft payment " + "order %s which has been automatically created." + ) + % (count, payorder.name) + ) else: - inv.message_post(body=_( - '%d payment lines added to the existing draft ' - 'payment order %s.') - % (count, payorder.name)) - action = self.env['ir.actions.act_window'].for_xml_id( - 'account_payment_order', - 'account_payment_order_%s_action' % action_payment_type) + inv.message_post( + body=_( + "%d payment lines added to the existing draft " + "payment order %s." + ) + % (count, payorder.name) + ) + action = self.env["ir.actions.act_window"].for_xml_id( + "account_payment_order", + "account_payment_order_%s_action" % action_payment_type, + ) if len(result_payorder_ids) == 1: - action.update({ - 'view_mode': 'form,tree,pivot,graph', - 'res_id': payorder.id, - 'views': False, - }) + action.update( + { + "view_mode": "form,tree,pivot,graph", + "res_id": payorder.id, + "views": False, + } + ) else: - action.update({ - 'view_mode': 'tree,form,pivot,graph', - 'domain': "[('id', 'in', %s)]" % result_payorder_ids, - 'views': False, - }) + action.update( + { + "view_mode": "tree,form,pivot,graph", + "domain": "[('id', 'in', %s)]" % result_payorder_ids, + "views": False, + } + ) return action diff --git a/account_payment_order/models/account_journal.py b/account_payment_order/models/account_journal.py index dc6b71253..2aa6e2078 100644 --- a/account_payment_order/models/account_journal.py +++ b/account_payment_order/models/account_journal.py @@ -5,29 +5,27 @@ from odoo import api, fields, models class AccountJournal(models.Model): - _inherit = 'account.journal' + _inherit = "account.journal" inbound_payment_order_only = fields.Boolean( - compute='_compute_inbound_payment_order_only', - readonly=True, - store=True, + compute="_compute_inbound_payment_order_only", readonly=True, store=True, ) outbound_payment_order_only = fields.Boolean( - compute='_compute_outbound_payment_order_only', - readonly=True, - store=True, + compute="_compute_outbound_payment_order_only", readonly=True, store=True, ) @api.multi - @api.depends('inbound_payment_method_ids.payment_order_only') + @api.depends("inbound_payment_method_ids.payment_order_only") def _compute_inbound_payment_order_only(self): for rec in self: rec.inbound_payment_order_only = all( - p.payment_order_only for p in rec.inbound_payment_method_ids) + p.payment_order_only for p in rec.inbound_payment_method_ids + ) @api.multi - @api.depends('outbound_payment_method_ids.payment_order_only') + @api.depends("outbound_payment_method_ids.payment_order_only") def _compute_outbound_payment_order_only(self): for rec in self: rec.outbound_payment_order_only = all( - p.payment_order_only for p in rec.outbound_payment_method_ids) + p.payment_order_only for p in rec.outbound_payment_method_ids + ) diff --git a/account_payment_order/models/account_move.py b/account_payment_order/models/account_move.py index f82073e68..5e626d32b 100644 --- a/account_payment_order/models/account_move.py +++ b/account_payment_order/models/account_move.py @@ -1,12 +1,12 @@ # © 2016 Akretion (Alexis de Lattre ) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from odoo import models, fields +from odoo import fields, models class AccountMove(models.Model): - _inherit = 'account.move' + _inherit = "account.move" payment_order_id = fields.Many2one( - 'account.payment.order', string='Payment Order', copy=False, - readonly=True) + "account.payment.order", string="Payment Order", copy=False, readonly=True + ) diff --git a/account_payment_order/models/account_move_line.py b/account_payment_order/models/account_move_line.py index f5c251624..1e57f7859 100644 --- a/account_payment_order/models/account_move_line.py +++ b/account_payment_order/models/account_move_line.py @@ -3,50 +3,50 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from lxml import etree + from odoo import api, fields, models from odoo.fields import first from odoo.osv import orm class AccountMoveLine(models.Model): - _inherit = 'account.move.line' + _inherit = "account.move.line" partner_bank_id = fields.Many2one( - 'res.partner.bank', string='Partner Bank Account', - help='Bank account on which we should pay the supplier') + "res.partner.bank", + string="Partner Bank Account", + help="Bank account on which we should pay the supplier", + ) bank_payment_line_id = fields.Many2one( - 'bank.payment.line', string='Bank Payment Line', - readonly=True, - index=True, + "bank.payment.line", string="Bank Payment Line", readonly=True, index=True, ) payment_line_ids = fields.One2many( - comodel_name='account.payment.line', - inverse_name='move_line_id', + comodel_name="account.payment.line", + inverse_name="move_line_id", string="Payment lines", ) @api.multi def _prepare_payment_line_vals(self, payment_order): self.ensure_one() - assert payment_order, 'Missing payment order' - aplo = self.env['account.payment.line'] + assert payment_order, "Missing payment order" + aplo = self.env["account.payment.line"] # default values for communication_type and communication - communication_type = 'normal' + communication_type = "normal" communication = self.move_id.ref or self.move_id.name # change these default values if move line is linked to an invoice if self.invoice_id: - if self.invoice_id.reference_type != 'none': + if self.invoice_id.reference_type != "none": communication = self.invoice_id.reference - ref2comm_type =\ - aplo.invoice_reference_type2communication_type() - communication_type =\ - ref2comm_type[self.invoice_id.reference_type] + ref2comm_type = aplo.invoice_reference_type2communication_type() + communication_type = ref2comm_type[self.invoice_id.reference_type] else: if ( - self.invoice_id.type in ('in_invoice', 'in_refund') and - self.invoice_id.reference): + self.invoice_id.type in ("in_invoice", "in_refund") + and self.invoice_id.reference + ): communication = self.invoice_id.reference - elif 'out' in self.invoice_id.type: + elif "out" in self.invoice_id.type: # Force to only put invoice number here communication = self.invoice_id.number if self.currency_id: @@ -57,21 +57,20 @@ class AccountMoveLine(models.Model): amount_currency = self.amount_residual # TODO : check that self.amount_residual_currency is 0 # in this case - if payment_order.payment_type == 'outbound': + if payment_order.payment_type == "outbound": amount_currency *= -1 - partner_bank_id = self.partner_bank_id.id or first( - self.partner_id.bank_ids).id + partner_bank_id = self.partner_bank_id.id or first(self.partner_id.bank_ids).id vals = { - 'order_id': payment_order.id, - 'partner_bank_id': partner_bank_id, - 'partner_id': self.partner_id.id, - 'move_line_id': self.id, - 'communication': communication, - 'communication_type': communication_type, - 'currency_id': currency_id, - 'amount_currency': amount_currency, + "order_id": payment_order.id, + "partner_bank_id": partner_bank_id, + "partner_id": self.partner_id.id, + "move_line_id": self.id, + "communication": communication, + "communication_type": communication_type, + "currency_id": currency_id, + "amount_currency": amount_currency, # date is set when the user confirms the payment order - } + } return vals @api.multi @@ -79,52 +78,44 @@ class AccountMoveLine(models.Model): vals_list = [] for mline in self: vals_list.append(mline._prepare_payment_line_vals(payment_order)) - return self.env['account.payment.line'].create(vals_list) + return self.env["account.payment.line"].create(vals_list) @api.model - def fields_view_get(self, view_id=None, view_type='form', toolbar=False, - submenu=False): + def fields_view_get( + self, view_id=None, view_type="form", toolbar=False, submenu=False + ): # When the user looks for open payables or receivables, in the # context of payment orders, she should focus primarily on amount that # is due to be paid, and secondarily on the total amount. In this # method we are forcing to display both the amount due in company and # in the invoice currency. # We then hide the fields debit and credit, because they add no value. - result = super(AccountMoveLine, self).fields_view_get(view_id, - view_type, - toolbar=toolbar, - submenu=submenu) + result = super(AccountMoveLine, self).fields_view_get( + view_id, view_type, toolbar=toolbar, submenu=submenu + ) - doc = etree.XML(result['arch']) - if view_type == 'tree' and self._module == 'account_payment_order': + doc = etree.XML(result["arch"]) + if view_type == "tree" and self._module == "account_payment_order": if not doc.xpath("//field[@name='balance']"): - for placeholder in doc.xpath( - "//field[@name='amount_currency']"): + for placeholder in doc.xpath("//field[@name='amount_currency']"): elem = etree.Element( - 'field', { - 'name': 'balance', - 'readonly': 'True' - }) + "field", {"name": "balance", "readonly": "True"} + ) orm.setup_modifiers(elem) placeholder.addprevious(elem) if not doc.xpath("//field[@name='amount_residual_currency']"): - for placeholder in doc.xpath( - "//field[@name='amount_currency']"): + for placeholder in doc.xpath("//field[@name='amount_currency']"): elem = etree.Element( - 'field', { - 'name': 'amount_residual_currency', - 'readonly': 'True' - }) + "field", + {"name": "amount_residual_currency", "readonly": "True"}, + ) orm.setup_modifiers(elem) placeholder.addnext(elem) if not doc.xpath("//field[@name='amount_residual']"): - for placeholder in doc.xpath( - "//field[@name='amount_currency']"): + for placeholder in doc.xpath("//field[@name='amount_currency']"): elem = etree.Element( - 'field', { - 'name': 'amount_residual', - 'readonly': 'True' - }) + "field", {"name": "amount_residual", "readonly": "True"} + ) orm.setup_modifiers(elem) placeholder.addnext(elem) # Remove credit and debit data - which is irrelevant in this case @@ -132,5 +123,5 @@ class AccountMoveLine(models.Model): doc.remove(elem) for elem in doc.xpath("//field[@name='credit']"): doc.remove(elem) - result['arch'] = etree.tostring(doc) + result["arch"] = etree.tostring(doc) return result diff --git a/account_payment_order/models/account_payment.py b/account_payment_order/models/account_payment.py index 7097b36b1..951470d12 100644 --- a/account_payment_order/models/account_payment.py +++ b/account_payment_order/models/account_payment.py @@ -5,26 +5,25 @@ from odoo import api, models class AccountPayment(models.Model): - _inherit = 'account.payment' + _inherit = "account.payment" def _compute_journal_domain_and_types(self): res = super(AccountPayment, self)._compute_journal_domain_and_types() - journal_domain = res.get('domain', []) - if self.payment_type == 'inbound': - journal_domain.append(('inbound_payment_order_only', '=', False)) + journal_domain = res.get("domain", []) + if self.payment_type == "inbound": + journal_domain.append(("inbound_payment_order_only", "=", False)) else: - journal_domain.append(('outbound_payment_order_only', '=', False)) - res['domain'] = journal_domain + journal_domain.append(("outbound_payment_order_only", "=", False)) + res["domain"] = journal_domain return res @api.multi - @api.onchange('journal_id') + @api.onchange("journal_id") def _onchange_journal(self): res = super(AccountPayment, self)._onchange_journal() - domains = res.get('domain') + domains = res.get("domain") if not domains: return res - if domains.get('payment_method_id'): - domains['payment_method_id'].append( - ('payment_order_only', '!=', True)) + if domains.get("payment_method_id"): + domains["payment_method_id"].append(("payment_order_only", "!=", True)) return res diff --git a/account_payment_order/models/account_payment_line.py b/account_payment_order/models/account_payment_line.py index bf558ae0f..2a2e13f93 100644 --- a/account_payment_order/models/account_payment_line.py +++ b/account_payment_order/models/account_payment_line.py @@ -1,94 +1,112 @@ # © 2015-2016 Akretion - Alexis de Lattre # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from odoo import models, fields, api, _ +from odoo import _, api, fields, models from odoo.exceptions import UserError class AccountPaymentLine(models.Model): - _name = 'account.payment.line' - _description = 'Payment Lines' + _name = "account.payment.line" + _description = "Payment Lines" - name = fields.Char(string='Payment Reference', readonly=True, copy=False) + name = fields.Char(string="Payment Reference", readonly=True, copy=False) order_id = fields.Many2one( - 'account.payment.order', string='Payment Order', - ondelete='cascade', index=True) + "account.payment.order", string="Payment Order", ondelete="cascade", index=True + ) company_id = fields.Many2one( - related='order_id.company_id', store=True, readonly=True) + related="order_id.company_id", store=True, readonly=True + ) company_currency_id = fields.Many2one( - related='order_id.company_currency_id', store=True, readonly=True) + related="order_id.company_currency_id", store=True, readonly=True + ) payment_type = fields.Selection( - related='order_id.payment_type', store=True, readonly=True) + related="order_id.payment_type", store=True, readonly=True + ) bank_account_required = fields.Boolean( - related='order_id.payment_method_id.bank_account_required', - readonly=True) + related="order_id.payment_method_id.bank_account_required", readonly=True + ) state = fields.Selection( - related='order_id.state', string='State', - readonly=True, store=True) + related="order_id.state", string="State", readonly=True, store=True + ) move_line_id = fields.Many2one( - 'account.move.line', string='Journal Item', - ondelete='restrict') - ml_maturity_date = fields.Date( - related='move_line_id.date_maturity', readonly=True) + "account.move.line", string="Journal Item", ondelete="restrict" + ) + ml_maturity_date = fields.Date(related="move_line_id.date_maturity", readonly=True) currency_id = fields.Many2one( - 'res.currency', string='Currency of the Payment Transaction', + "res.currency", + string="Currency of the Payment Transaction", required=True, - default=lambda self: self.env.user.company_id.currency_id) + default=lambda self: self.env.user.company_id.currency_id, + ) # v8 field : currency - amount_currency = fields.Monetary( - string="Amount", currency_field='currency_id') + amount_currency = fields.Monetary(string="Amount", currency_field="currency_id") amount_company_currency = fields.Monetary( - compute='_compute_amount_company_currency', - string='Amount in Company Currency', readonly=True, - currency_field='company_currency_id') # v8 field : amount + compute="_compute_amount_company_currency", + string="Amount in Company Currency", + readonly=True, + currency_field="company_currency_id", + ) # v8 field : amount partner_id = fields.Many2one( - 'res.partner', string='Partner', required=True, - domain=[('parent_id', '=', False)]) + "res.partner", + string="Partner", + required=True, + domain=[("parent_id", "=", False)], + ) partner_bank_id = fields.Many2one( - 'res.partner.bank', string='Partner Bank Account', required=False, - ondelete='restrict') # v8 field : bank_id - date = fields.Date(string='Payment Date') + "res.partner.bank", + string="Partner Bank Account", + required=False, + ondelete="restrict", + ) # v8 field : bank_id + date = fields.Date(string="Payment Date") communication = fields.Char( - string='Communication', required=True, - help="Label of the payment that will be seen by the destinee") - communication_type = fields.Selection([ - ('normal', 'Free'), - ], string='Communication Type', required=True, default='normal') + string="Communication", + required=True, + help="Label of the payment that will be seen by the destinee", + ) + communication_type = fields.Selection( + [("normal", "Free"),], + string="Communication Type", + required=True, + default="normal", + ) # v8 field : state bank_line_id = fields.Many2one( - 'bank.payment.line', string='Bank Payment Line', readonly=True, - index=True, + "bank.payment.line", string="Bank Payment Line", readonly=True, index=True, ) - _sql_constraints = [( - 'name_company_unique', - 'unique(name, company_id)', - 'A payment line already exists with this reference ' - 'in the same company!' - )] + _sql_constraints = [ + ( + "name_company_unique", + "unique(name, company_id)", + "A payment line already exists with this reference " "in the same company!", + ) + ] @api.model def create(self, vals): - if vals.get('name', 'New') == 'New': - vals['name'] = self.env['ir.sequence'].next_by_code( - 'account.payment.line') or 'New' + if vals.get("name", "New") == "New": + vals["name"] = ( + self.env["ir.sequence"].next_by_code("account.payment.line") or "New" + ) return super(AccountPaymentLine, self).create(vals) @api.multi - @api.depends( - 'amount_currency', 'currency_id', 'company_currency_id', 'date') + @api.depends("amount_currency", "currency_id", "company_currency_id", "date") def _compute_amount_company_currency(self): for line in self: if line.currency_id and line.company_currency_id: line.amount_company_currency = line.currency_id._convert( - line.amount_currency, line.company_currency_id, - line.company_id, line.date or fields.Date.today(), + line.amount_currency, + line.company_currency_id, + line.company_id, + line.date or fields.Date.today(), ) @api.multi def payment_line_hashcode(self): self.ensure_one() - bplo = self.env['bank.payment.line'] + bplo = self.env["bank.payment.line"] values = [] for field in bplo.same_fields_payment_line_and_bank_payment_line(): values.append(str(self[field])) @@ -98,23 +116,23 @@ class AccountPaymentLine(models.Model): values.append(str(self.move_line_id.account_id or False)) # Don't group the payment lines that use a structured communication # otherwise it would break the structured communication system ! - if self.communication_type != 'normal': + if self.communication_type != "normal": values.append(str(self.id)) - hashcode = '-'.join(values) + hashcode = "-".join(values) return hashcode - @api.onchange('partner_id') + @api.onchange("partner_id") def partner_id_change(self): partner_bank = False if self.partner_id.bank_ids: partner_bank = self.partner_id.bank_ids[0] self.partner_bank_id = partner_bank - @api.onchange('move_line_id') + @api.onchange("move_line_id") def move_line_id_change(self): if self.move_line_id: vals = self.move_line_id._prepare_payment_line_vals(self.order_id) - vals.pop('order_id') + vals.pop("order_id") for field, value in vals.items(): self[field] = value else: @@ -129,12 +147,13 @@ class AccountPaymentLine(models.Model): localization modules""" # key = value of 'reference_type' field on account_invoice # value = value of 'communication_type' field on account_payment_line - res = {'none': 'normal', 'structured': 'structured'} + res = {"none": "normal", "structured": "structured"} return res @api.multi def draft2open_payment_line_check(self): self.ensure_one() if self.bank_account_required and not self.partner_bank_id: - raise UserError(_( - 'Missing Partner Bank Account on payment line %s') % self.name) + raise UserError( + _("Missing Partner Bank Account on payment line %s") % self.name + ) diff --git a/account_payment_order/models/account_payment_method.py b/account_payment_order/models/account_payment_method.py index 3c0819d57..2e42b544a 100644 --- a/account_payment_order/models/account_payment_method.py +++ b/account_payment_order/models/account_payment_method.py @@ -5,11 +5,11 @@ from odoo import fields, models class AccountPaymentMethod(models.Model): - _inherit = 'account.payment.method' + _inherit = "account.payment.method" payment_order_only = fields.Boolean( string="Only for payment orders", help="This option helps enforcing the use of payment orders for " - "some payment methods.", + "some payment methods.", default=False, ) diff --git a/account_payment_order/models/account_payment_mode.py b/account_payment_order/models/account_payment_mode.py index 47d983a27..f41494d8c 100644 --- a/account_payment_order/models/account_payment_mode.py +++ b/account_payment_order/models/account_payment_mode.py @@ -4,145 +4,178 @@ # © 2016 Akretion (Alexis de Lattre ) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from odoo import models, fields, api, _ +from odoo import _, api, fields, models from odoo.exceptions import ValidationError class AccountPaymentMode(models.Model): """This corresponds to the object payment.mode of v8 with some important changes""" + _inherit = "account.payment.mode" payment_order_ok = fields.Boolean( - string='Selectable in Payment Orders', default=True) + string="Selectable in Payment Orders", default=True + ) no_debit_before_maturity = fields.Boolean( string="Disallow Debit Before Maturity Date", help="If you activate this option on an Inbound payment mode, " "you will have an error message when you confirm a debit order " "that has a payment line with a payment date before the maturity " - "date.") + "date.", + ) # Default options for the "payment.order.create" wizard - default_payment_mode = fields.Selection([ - ('same', 'Same'), - ('same_or_null', 'Same or empty'), - ('any', 'Any'), - ], string='Payment Mode on Invoice', default='same') + default_payment_mode = fields.Selection( + [("same", "Same"), ("same_or_null", "Same or empty"), ("any", "Any"),], + string="Payment Mode on Invoice", + default="same", + ) default_journal_ids = fields.Many2many( - 'account.journal', + "account.journal", string="Journals Filter", - domain="[('company_id', '=', company_id)]" + domain="[('company_id', '=', company_id)]", ) default_invoice = fields.Boolean( - string='Linked to an Invoice or Refund', default=False) - default_target_move = fields.Selection([ - ('posted', 'All Posted Entries'), - ('all', 'All Entries'), - ], string='Target Moves', default='posted') - default_date_type = fields.Selection([ - ('due', 'Due'), - ('move', 'Move'), - ], default='due', string="Type of Date Filter") + string="Linked to an Invoice or Refund", default=False + ) + default_target_move = fields.Selection( + [("posted", "All Posted Entries"), ("all", "All Entries"),], + string="Target Moves", + default="posted", + ) + default_date_type = fields.Selection( + [("due", "Due"), ("move", "Move"),], default="due", string="Type of Date Filter" + ) # default option for account.payment.order - default_date_prefered = fields.Selection([ - ('now', 'Immediately'), - ('due', 'Due Date'), - ('fixed', 'Fixed Date'), - ], string='Default Payment Execution Date') + default_date_prefered = fields.Selection( + [("now", "Immediately"), ("due", "Due Date"), ("fixed", "Fixed Date"),], + string="Default Payment Execution Date", + ) group_lines = fields.Boolean( - string="Group Transactions in Payment Orders", default=True, + string="Group Transactions in Payment Orders", + default=True, help="If this mark is checked, the transaction lines of the " - "payment order will be grouped upon confirmation of the payment " - "order.The grouping will be done only if the following " - "fields matches:\n" - "* Partner\n" - "* Currency\n" - "* Destination Bank Account\n" - "* Payment Date\n" - "and if the 'Communication Type' is 'Free'\n" - "(other modules can set additional fields to restrict the " - "grouping.)") + "payment order will be grouped upon confirmation of the payment " + "order.The grouping will be done only if the following " + "fields matches:\n" + "* Partner\n" + "* Currency\n" + "* Destination Bank Account\n" + "* Payment Date\n" + "and if the 'Communication Type' is 'Free'\n" + "(other modules can set additional fields to restrict the " + "grouping.)", + ) generate_move = fields.Boolean( - string='Generate Accounting Entries On File Upload', default=True) - offsetting_account = fields.Selection([ - ('bank_account', 'Bank Account'), - ('transfer_account', 'Transfer Account'), - ], string='Offsetting Account', default='bank_account') + string="Generate Accounting Entries On File Upload", default=True + ) + offsetting_account = fields.Selection( + [("bank_account", "Bank Account"), ("transfer_account", "Transfer Account"),], + string="Offsetting Account", + default="bank_account", + ) transfer_account_id = fields.Many2one( - 'account.account', string='Transfer Account', - domain=[('reconcile', '=', True)], + "account.account", + string="Transfer Account", + domain=[("reconcile", "=", True)], help="Pay off lines in 'file uploaded' payment orders with a move on " "this account. You can only select accounts " - "that are marked for reconciliation") + "that are marked for reconciliation", + ) transfer_journal_id = fields.Many2one( - 'account.journal', string='Transfer Journal', - help='Journal to write payment entries when confirming ' - 'payment/debit orders of this mode') - move_option = fields.Selection([ - ('date', 'One move per payment date'), - ('line', 'One move per payment line'), - ], string='Move Option', default='date') - post_move = fields.Boolean(string='Post Move', default=True) + "account.journal", + string="Transfer Journal", + help="Journal to write payment entries when confirming " + "payment/debit orders of this mode", + ) + move_option = fields.Selection( + [("date", "One move per payment date"), ("line", "One move per payment line"),], + string="Move Option", + default="date", + ) + post_move = fields.Boolean(string="Post Move", default=True) @api.multi @api.constrains( - 'generate_move', 'offsetting_account', - 'transfer_account_id', 'transfer_journal_id', 'move_option') + "generate_move", + "offsetting_account", + "transfer_account_id", + "transfer_journal_id", + "move_option", + ) def transfer_move_constrains(self): for mode in self: if mode.generate_move: if not mode.offsetting_account: - raise ValidationError(_( - "On the payment mode '%s', you must select an " - "option for the 'Offsetting Account' parameter") - % mode.name) - elif mode.offsetting_account == 'transfer_account': + raise ValidationError( + _( + "On the payment mode '%s', you must select an " + "option for the 'Offsetting Account' parameter" + ) + % mode.name + ) + elif mode.offsetting_account == "transfer_account": if not mode.transfer_account_id: - raise ValidationError(_( - "On the payment mode '%s', you must " - "select a value for the 'Transfer Account'.") - % mode.name) + raise ValidationError( + _( + "On the payment mode '%s', you must " + "select a value for the 'Transfer Account'." + ) + % mode.name + ) if not mode.transfer_journal_id: - raise ValidationError(_( - "On the payment mode '%s', you must " - "select a value for the 'Transfer Journal'.") - % mode.name) + raise ValidationError( + _( + "On the payment mode '%s', you must " + "select a value for the 'Transfer Journal'." + ) + % mode.name + ) if not mode.move_option: - raise ValidationError(_( - "On the payment mode '%s', you must " - "choose an option for the 'Move Option' " - "parameter.") % mode.name) + raise ValidationError( + _( + "On the payment mode '%s', you must " + "choose an option for the 'Move Option' " + "parameter." + ) + % mode.name + ) - @api.onchange('payment_method_id') + @api.onchange("payment_method_id") def payment_method_id_change(self): if self.payment_method_id: - ajo = self.env['account.journal'] + ajo = self.env["account.journal"] aj_ids = [] - if self.payment_method_id.payment_type == 'outbound': - aj_ids = ajo.search([ - ('type', 'in', ('purchase_refund', 'purchase')), - ('company_id', '=', self.company_id.id) - ]).ids - elif self.payment_method_id.payment_type == 'inbound': - aj_ids = ajo.search([ - ('type', 'in', ('sale_refund', 'sale')), - ('company_id', '=', self.company_id.id) - ]).ids + if self.payment_method_id.payment_type == "outbound": + aj_ids = ajo.search( + [ + ("type", "in", ("purchase_refund", "purchase")), + ("company_id", "=", self.company_id.id), + ] + ).ids + elif self.payment_method_id.payment_type == "inbound": + aj_ids = ajo.search( + [ + ("type", "in", ("sale_refund", "sale")), + ("company_id", "=", self.company_id.id), + ] + ).ids self.default_journal_ids = [(6, 0, aj_ids)] - @api.onchange('generate_move') + @api.onchange("generate_move") def generate_move_change(self): if self.generate_move: # default values - self.offsetting_account = 'bank_account' - self.move_option = 'date' + self.offsetting_account = "bank_account" + self.move_option = "date" else: self.offsetting_account = False self.transfer_account_id = False self.transfer_journal_id = False self.move_option = False - @api.onchange('offsetting_account') + @api.onchange("offsetting_account") def offsetting_account_change(self): - if self.offsetting_account == 'bank_account': + if self.offsetting_account == "bank_account": self.transfer_account_id = False self.transfer_journal_id = False diff --git a/account_payment_order/models/account_payment_order.py b/account_payment_order/models/account_payment_order.py index e3f57196b..fcfc025d1 100644 --- a/account_payment_order/models/account_payment_order.py +++ b/account_payment_order/models/account_payment_order.py @@ -5,179 +5,227 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). import base64 -from odoo import models, fields, api, _ + +from odoo import _, api, fields, models from odoo.exceptions import UserError, ValidationError class AccountPaymentOrder(models.Model): - _name = 'account.payment.order' - _description = 'Payment Order' - _inherit = ['mail.thread'] - _order = 'id desc' + _name = "account.payment.order" + _description = "Payment Order" + _inherit = ["mail.thread"] + _order = "id desc" - name = fields.Char( - string='Number', readonly=True, copy=False) # v8 field : name + name = fields.Char(string="Number", readonly=True, copy=False) # v8 field : name payment_mode_id = fields.Many2one( - 'account.payment.mode', 'Payment Mode', required=True, - ondelete='restrict', track_visibility='onchange', - readonly=True, states={'draft': [('readonly', False)]}) - payment_type = fields.Selection([ - ('inbound', 'Inbound'), - ('outbound', 'Outbound'), - ], string='Payment Type', readonly=True, required=True) + "account.payment.mode", + "Payment Mode", + required=True, + ondelete="restrict", + track_visibility="onchange", + readonly=True, + states={"draft": [("readonly", False)]}, + ) + payment_type = fields.Selection( + [("inbound", "Inbound"), ("outbound", "Outbound"),], + string="Payment Type", + readonly=True, + required=True, + ) payment_method_id = fields.Many2one( - 'account.payment.method', related='payment_mode_id.payment_method_id', - readonly=True, store=True) + "account.payment.method", + related="payment_mode_id.payment_method_id", + readonly=True, + store=True, + ) company_id = fields.Many2one( - related='payment_mode_id.company_id', store=True, readonly=True) + related="payment_mode_id.company_id", store=True, readonly=True + ) company_currency_id = fields.Many2one( - related='payment_mode_id.company_id.currency_id', store=True, - readonly=True) + related="payment_mode_id.company_id.currency_id", store=True, readonly=True + ) bank_account_link = fields.Selection( - related='payment_mode_id.bank_account_link', readonly=True) + related="payment_mode_id.bank_account_link", readonly=True + ) allowed_journal_ids = fields.Many2many( - comodel_name='account.journal', + comodel_name="account.journal", compute="_compute_allowed_journal_ids", string="Allowed journals", ) journal_id = fields.Many2one( - 'account.journal', string='Bank Journal', ondelete='restrict', - readonly=True, states={'draft': [('readonly', False)]}, - track_visibility='onchange') + "account.journal", + string="Bank Journal", + ondelete="restrict", + readonly=True, + states={"draft": [("readonly", False)]}, + track_visibility="onchange", + ) # The journal_id field is only required at confirm step, to # allow auto-creation of payment order from invoice company_partner_bank_id = fields.Many2one( - related='journal_id.bank_account_id', string='Company Bank Account', - readonly=True) + related="journal_id.bank_account_id", + string="Company Bank Account", + readonly=True, + ) state = fields.Selection( [ - ('draft', 'Draft'), - ('open', 'Confirmed'), - ('generated', 'File Generated'), - ('uploaded', 'File Uploaded'), - ('done', 'Done'), - ('cancel', 'Cancel'), - ], string='Status', readonly=True, copy=False, default='draft', - track_visibility='onchange') - date_prefered = fields.Selection([ - ('now', 'Immediately'), - ('due', 'Due Date'), - ('fixed', 'Fixed Date'), - ], string='Payment Execution Date Type', required=True, default='due', - track_visibility='onchange', readonly=True, - states={'draft': [('readonly', False)]}) + ("draft", "Draft"), + ("open", "Confirmed"), + ("generated", "File Generated"), + ("uploaded", "File Uploaded"), + ("done", "Done"), + ("cancel", "Cancel"), + ], + string="Status", + readonly=True, + copy=False, + default="draft", + track_visibility="onchange", + ) + date_prefered = fields.Selection( + [("now", "Immediately"), ("due", "Due Date"), ("fixed", "Fixed Date"),], + string="Payment Execution Date Type", + required=True, + default="due", + track_visibility="onchange", + readonly=True, + states={"draft": [("readonly", False)]}, + ) date_scheduled = fields.Date( - string='Payment Execution Date', readonly=True, - states={'draft': [('readonly', False)]}, track_visibility='onchange', + string="Payment Execution Date", + readonly=True, + states={"draft": [("readonly", False)]}, + track_visibility="onchange", help="Select a requested date of execution if you selected 'Due Date' " - "as the Payment Execution Date Type.") - date_generated = fields.Date(string='File Generation Date', readonly=True) - date_uploaded = fields.Date(string='File Upload Date', readonly=True) - date_done = fields.Date(string='Done Date', readonly=True) + "as the Payment Execution Date Type.", + ) + date_generated = fields.Date(string="File Generation Date", readonly=True) + date_uploaded = fields.Date(string="File Upload Date", readonly=True) + date_done = fields.Date(string="Done Date", readonly=True) generated_user_id = fields.Many2one( - 'res.users', string='Generated by', readonly=True, ondelete='restrict', - copy=False) + "res.users", + string="Generated by", + readonly=True, + ondelete="restrict", + copy=False, + ) payment_line_ids = fields.One2many( - 'account.payment.line', 'order_id', string='Transaction Lines', - readonly=True, states={'draft': [('readonly', False)]}) + "account.payment.line", + "order_id", + string="Transaction Lines", + readonly=True, + states={"draft": [("readonly", False)]}, + ) # v8 field : line_ids bank_line_ids = fields.One2many( - 'bank.payment.line', 'order_id', string="Bank Payment Lines", + "bank.payment.line", + "order_id", + string="Bank Payment Lines", readonly=True, help="The bank payment lines are used to generate the payment file. " "They are automatically created from transaction lines upon " "confirmation of the payment order: one bank payment line can " "group several transaction lines if the option " "'Group Transactions in Payment Orders' is active on the payment " - "mode.") + "mode.", + ) total_company_currency = fields.Monetary( - compute='_compute_total', store=True, readonly=True, - currency_field='company_currency_id') + compute="_compute_total", + store=True, + readonly=True, + currency_field="company_currency_id", + ) bank_line_count = fields.Integer( - compute='_compute_bank_line_count', string='Number of Bank Lines', - readonly=True) + compute="_compute_bank_line_count", string="Number of Bank Lines", readonly=True + ) move_ids = fields.One2many( - 'account.move', 'payment_order_id', string='Journal Entries', - readonly=True) + "account.move", "payment_order_id", string="Journal Entries", readonly=True + ) description = fields.Char() - @api.depends('payment_mode_id') + @api.depends("payment_mode_id") def _compute_allowed_journal_ids(self): for record in self: - if record.payment_mode_id.bank_account_link == 'fixed': - record.allowed_journal_ids = ( - record.payment_mode_id.fixed_journal_id) - elif record.payment_mode_id.bank_account_link == 'variable': - record.allowed_journal_ids = ( - record.payment_mode_id.variable_journal_ids) + if record.payment_mode_id.bank_account_link == "fixed": + record.allowed_journal_ids = record.payment_mode_id.fixed_journal_id + elif record.payment_mode_id.bank_account_link == "variable": + record.allowed_journal_ids = record.payment_mode_id.variable_journal_ids @api.multi def unlink(self): for order in self: - if order.state == 'uploaded': - raise UserError(_( - "You cannot delete an uploaded payment order. You can " - "cancel it in order to do so.")) + if order.state == "uploaded": + raise UserError( + _( + "You cannot delete an uploaded payment order. You can " + "cancel it in order to do so." + ) + ) return super(AccountPaymentOrder, self).unlink() @api.multi - @api.constrains('payment_type', 'payment_mode_id') + @api.constrains("payment_type", "payment_mode_id") def payment_order_constraints(self): for order in self: if ( - order.payment_mode_id.payment_type and - order.payment_mode_id.payment_type != order.payment_type): - raise ValidationError(_( - "The payment type (%s) is not the same as the payment " - "type of the payment mode (%s)") % ( - order.payment_type, - order.payment_mode_id.payment_type)) + order.payment_mode_id.payment_type + and order.payment_mode_id.payment_type != order.payment_type + ): + raise ValidationError( + _( + "The payment type (%s) is not the same as the payment " + "type of the payment mode (%s)" + ) + % (order.payment_type, order.payment_mode_id.payment_type) + ) @api.multi - @api.constrains('date_scheduled') + @api.constrains("date_scheduled") def check_date_scheduled(self): today = fields.Date.context_today(self) for order in self: if order.date_scheduled: if order.date_scheduled < today: - raise ValidationError(_( - "On payment order %s, the Payment Execution Date " - "is in the past (%s).") - % (order.name, order.date_scheduled)) + raise ValidationError( + _( + "On payment order %s, the Payment Execution Date " + "is in the past (%s)." + ) + % (order.name, order.date_scheduled) + ) @api.multi - @api.depends( - 'payment_line_ids', 'payment_line_ids.amount_company_currency') + @api.depends("payment_line_ids", "payment_line_ids.amount_company_currency") def _compute_total(self): for rec in self: rec.total_company_currency = sum( - rec.mapped('payment_line_ids.amount_company_currency') or - [0.0]) + rec.mapped("payment_line_ids.amount_company_currency") or [0.0] + ) @api.multi - @api.depends('bank_line_ids') + @api.depends("bank_line_ids") def _compute_bank_line_count(self): for order in self: order.bank_line_count = len(order.bank_line_ids) @api.model def create(self, vals): - if vals.get('name', 'New') == 'New': - vals['name'] = self.env['ir.sequence'].next_by_code( - 'account.payment.order') or 'New' - if vals.get('payment_mode_id'): - payment_mode = self.env['account.payment.mode'].browse( - vals['payment_mode_id']) - vals['payment_type'] = payment_mode.payment_type - if payment_mode.bank_account_link == 'fixed': - vals['journal_id'] = payment_mode.fixed_journal_id.id - if ( - not vals.get('date_prefered') and - payment_mode.default_date_prefered): - vals['date_prefered'] = payment_mode.default_date_prefered + if vals.get("name", "New") == "New": + vals["name"] = ( + self.env["ir.sequence"].next_by_code("account.payment.order") or "New" + ) + if vals.get("payment_mode_id"): + payment_mode = self.env["account.payment.mode"].browse( + vals["payment_mode_id"] + ) + vals["payment_type"] = payment_mode.payment_type + if payment_mode.bank_account_link == "fixed": + vals["journal_id"] = payment_mode.fixed_journal_id.id + if not vals.get("date_prefered") and payment_mode.default_date_prefered: + vals["date_prefered"] = payment_mode.default_date_prefered return super(AccountPaymentOrder, self).create(vals) - @api.onchange('payment_mode_id') + @api.onchange("payment_mode_id") def payment_mode_id_change(self): if len(self.allowed_journal_ids) == 1: self.journal_id = self.allowed_journal_ids @@ -186,10 +234,9 @@ class AccountPaymentOrder(models.Model): @api.multi def action_done(self): - self.write({ - 'date_done': fields.Date.context_today(self), - 'state': 'done', - }) + self.write( + {"date_done": fields.Date.context_today(self), "state": "done",} + ) return True @api.multi @@ -204,24 +251,23 @@ class AccountPaymentOrder(models.Model): @api.multi def cancel2draft(self): - self.write({'state': 'draft'}) + self.write({"state": "draft"}) return True @api.multi def action_cancel(self): for order in self: - order.write({'state': 'cancel'}) + order.write({"state": "cancel"}) order.bank_line_ids.unlink() return True @api.model def _prepare_bank_payment_line(self, paylines): return { - 'order_id': paylines[0].order_id.id, - 'payment_line_ids': [(6, 0, paylines.ids)], - 'communication': '-'.join( - [line.communication for line in paylines]), - } + "order_id": paylines[0].order_id.id, + "payment_line_ids": [(6, 0, paylines.ids)], + "communication": "-".join([line.communication for line in paylines]), + } @api.multi def draft2open(self): @@ -231,22 +277,25 @@ class AccountPaymentOrder(models.Model): setting of the payment.order Re-generate the bank payment lines """ - bplo = self.env['bank.payment.line'] + bplo = self.env["bank.payment.line"] today = fields.Date.context_today(self) for order in self: if not order.journal_id: - raise UserError(_( - 'Missing Bank Journal on payment order %s.') % order.name) + raise UserError( + _("Missing Bank Journal on payment order %s.") % order.name + ) if ( - order.payment_method_id.bank_account_required and - not order.journal_id.bank_account_id): - raise UserError(_( - "Missing bank account on bank journal '%s'.") - % order.journal_id.display_name) + order.payment_method_id.bank_account_required + and not order.journal_id.bank_account_id + ): + raise UserError( + _("Missing bank account on bank journal '%s'.") + % order.journal_id.display_name + ) if not order.payment_line_ids: - raise UserError(_( - 'There are no transactions on payment order %s.') - % order.name) + raise UserError( + _("There are no transactions on payment order %s.") % order.name + ) # Delete existing bank payment lines order.bank_line_ids.unlink() # Create the bank payment lines from the payment lines @@ -254,9 +303,9 @@ class AccountPaymentOrder(models.Model): for payline in order.payment_line_ids: payline.draft2open_payment_line_check() # Compute requested payment date - if order.date_prefered == 'due': + if order.date_prefered == "due": requested_date = payline.ml_maturity_date or today - elif order.date_prefered == 'fixed': + elif order.date_prefered == "fixed": requested_date = order.date_scheduled or today else: requested_date = today @@ -265,19 +314,25 @@ class AccountPaymentOrder(models.Model): requested_date = today # inbound: check option no_debit_before_maturity if ( - order.payment_type == 'inbound' and - order.payment_mode_id.no_debit_before_maturity and - payline.ml_maturity_date and - requested_date < payline.ml_maturity_date): - raise UserError(_( - "The payment mode '%s' has the option " - "'Disallow Debit Before Maturity Date'. The " - "payment line %s has a maturity date %s " - "which is after the computed payment date %s.") % ( + order.payment_type == "inbound" + and order.payment_mode_id.no_debit_before_maturity + and payline.ml_maturity_date + and requested_date < payline.ml_maturity_date + ): + raise UserError( + _( + "The payment mode '%s' has the option " + "'Disallow Debit Before Maturity Date'. The " + "payment line %s has a maturity date %s " + "which is after the computed payment date %s." + ) + % ( order.payment_mode_id.name, payline.name, payline.ml_maturity_date, - requested_date)) + requested_date, + ) + ) # Write requested_date on 'date' field of payment line # norecompute is for avoiding a chained recomputation # payment_line_ids.date @@ -292,39 +347,40 @@ class AccountPaymentOrder(models.Model): # Use line ID as hascode, which actually means no grouping hashcode = payline.id if hashcode in group_paylines: - group_paylines[hashcode]['paylines'] += payline - group_paylines[hashcode]['total'] +=\ - payline.amount_currency + group_paylines[hashcode]["paylines"] += payline + group_paylines[hashcode]["total"] += payline.amount_currency else: group_paylines[hashcode] = { - 'paylines': payline, - 'total': payline.amount_currency, + "paylines": payline, + "total": payline.amount_currency, } order.recompute() # Create bank payment lines for paydict in list(group_paylines.values()): # Block if a bank payment line is <= 0 - if paydict['total'] <= 0: - raise UserError(_( - "The amount for Partner '%s' is negative " - "or null (%.2f) !") - % (paydict['paylines'][0].partner_id.name, - paydict['total'])) - vals = self._prepare_bank_payment_line(paydict['paylines']) + if paydict["total"] <= 0: + raise UserError( + _("The amount for Partner '%s' is negative " "or null (%.2f) !") + % (paydict["paylines"][0].partner_id.name, paydict["total"]) + ) + vals = self._prepare_bank_payment_line(paydict["paylines"]) bplo.create(vals) - self.write({'state': 'open'}) + self.write({"state": "open"}) return True @api.multi def generate_payment_file(self): """Returns (payment file as string, filename)""" self.ensure_one() - if self.payment_method_id.code == 'manual': + if self.payment_method_id.code == "manual": return (False, False) else: - raise UserError(_( - "No handler for this payment method. Maybe you haven't " - "installed the related Odoo module.")) + raise UserError( + _( + "No handler for this payment method. Maybe you haven't " + "installed the related Odoo module." + ) + ) @api.multi def open2generated(self): @@ -332,29 +388,34 @@ class AccountPaymentOrder(models.Model): payment_file_str, filename = self.generate_payment_file() action = {} if payment_file_str and filename: - attachment = self.env['ir.attachment'].create({ - 'res_model': 'account.payment.order', - 'res_id': self.id, - 'name': filename, - 'datas': base64.b64encode(payment_file_str), - 'datas_fname': filename, - }) - simplified_form_view = self.env.ref( - 'account_payment_order.view_attachment_simplified_form') - action = { - 'name': _('Payment File'), - 'view_mode': 'form', - 'view_id': simplified_form_view.id, - 'res_model': 'ir.attachment', - 'type': 'ir.actions.act_window', - 'target': 'current', - 'res_id': attachment.id, + attachment = self.env["ir.attachment"].create( + { + "res_model": "account.payment.order", + "res_id": self.id, + "name": filename, + "datas": base64.b64encode(payment_file_str), + "datas_fname": filename, } - self.write({ - 'date_generated': fields.Date.context_today(self), - 'state': 'generated', - 'generated_user_id': self._uid, - }) + ) + simplified_form_view = self.env.ref( + "account_payment_order.view_attachment_simplified_form" + ) + action = { + "name": _("Payment File"), + "view_mode": "form", + "view_id": simplified_form_view.id, + "res_model": "ir.attachment", + "type": "ir.actions.act_window", + "target": "current", + "res_id": attachment.id, + } + self.write( + { + "date_generated": fields.Date.context_today(self), + "state": "generated", + "generated_user_id": self._uid, + } + ) return action @api.multi @@ -362,58 +423,58 @@ class AccountPaymentOrder(models.Model): for order in self: if order.payment_mode_id.generate_move: order.generate_move() - self.write({ - 'state': 'uploaded', - 'date_uploaded': fields.Date.context_today(self), - }) + self.write( + {"state": "uploaded", "date_uploaded": fields.Date.context_today(self),} + ) return True @api.multi def _prepare_move(self, bank_lines=None): - if self.payment_type == 'outbound': - ref = _('Payment order %s') % self.name + if self.payment_type == "outbound": + ref = _("Payment order %s") % self.name else: - ref = _('Debit order %s') % self.name + ref = _("Debit order %s") % self.name if bank_lines and len(bank_lines) == 1: ref += " - " + bank_lines.name - if self.payment_mode_id.offsetting_account == 'bank_account': + if self.payment_mode_id.offsetting_account == "bank_account": journal_id = self.journal_id.id - elif self.payment_mode_id.offsetting_account == 'transfer_account': + elif self.payment_mode_id.offsetting_account == "transfer_account": journal_id = self.payment_mode_id.transfer_journal_id.id vals = { - 'journal_id': journal_id, - 'ref': ref, - 'payment_order_id': self.id, - 'line_ids': [], - } + "journal_id": journal_id, + "ref": ref, + "payment_order_id": self.id, + "line_ids": [], + } total_company_currency = total_payment_currency = 0 for bline in bank_lines: total_company_currency += bline.amount_company_currency total_payment_currency += bline.amount_currency partner_ml_vals = self._prepare_move_line_partner_account(bline) - vals['line_ids'].append((0, 0, partner_ml_vals)) + vals["line_ids"].append((0, 0, partner_ml_vals)) trf_ml_vals = self._prepare_move_line_offsetting_account( - total_company_currency, total_payment_currency, bank_lines) - vals['line_ids'].append((0, 0, trf_ml_vals)) + total_company_currency, total_payment_currency, bank_lines + ) + vals["line_ids"].append((0, 0, trf_ml_vals)) return vals @api.multi def _prepare_move_line_offsetting_account( - self, amount_company_currency, amount_payment_currency, - bank_lines): + self, amount_company_currency, amount_payment_currency, bank_lines + ): vals = {} - if self.payment_type == 'outbound': - name = _('Payment order %s') % self.name + if self.payment_type == "outbound": + name = _("Payment order %s") % self.name else: - name = _('Debit order %s') % self.name - if self.payment_mode_id.offsetting_account == 'bank_account': - vals.update({'date': bank_lines[0].date}) + name = _("Debit order %s") % self.name + if self.payment_mode_id.offsetting_account == "bank_account": + vals.update({"date": bank_lines[0].date}) else: - vals.update({'date_maturity': bank_lines[0].date}) + vals.update({"date_maturity": bank_lines[0].date}) - if self.payment_mode_id.offsetting_account == 'bank_account': + if self.payment_mode_id.offsetting_account == "bank_account": account_id = self.journal_id.default_debit_account_id.id - elif self.payment_mode_id.offsetting_account == 'transfer_account': + elif self.payment_mode_id.offsetting_account == "transfer_account": account_id = self.payment_mode_id.transfer_account_id.id partner_id = False for index, bank_line in enumerate(bank_lines): @@ -423,63 +484,74 @@ class AccountPaymentOrder(models.Model): # we have different partners in the grouped move partner_id = False break - vals.update({ - 'name': name, - 'partner_id': partner_id, - 'account_id': account_id, - 'credit': (self.payment_type == 'outbound' and - amount_company_currency or 0.0), - 'debit': (self.payment_type == 'inbound' and - amount_company_currency or 0.0), - }) + vals.update( + { + "name": name, + "partner_id": partner_id, + "account_id": account_id, + "credit": ( + self.payment_type == "outbound" and amount_company_currency or 0.0 + ), + "debit": ( + self.payment_type == "inbound" and amount_company_currency or 0.0 + ), + } + ) if bank_lines[0].currency_id != bank_lines[0].company_currency_id: - sign = self.payment_type == 'outbound' and -1 or 1 - vals.update({ - 'currency_id': bank_lines[0].currency_id.id, - 'amount_currency': amount_payment_currency * sign, - }) + sign = self.payment_type == "outbound" and -1 or 1 + vals.update( + { + "currency_id": bank_lines[0].currency_id.id, + "amount_currency": amount_payment_currency * sign, + } + ) return vals @api.multi def _prepare_move_line_partner_account(self, bank_line): if bank_line.payment_line_ids[0].move_line_id: - account_id =\ - bank_line.payment_line_ids[0].move_line_id.account_id.id + account_id = bank_line.payment_line_ids[0].move_line_id.account_id.id else: - if self.payment_type == 'inbound': - account_id =\ - bank_line.partner_id.property_account_receivable_id.id + if self.payment_type == "inbound": + account_id = bank_line.partner_id.property_account_receivable_id.id else: - account_id =\ - bank_line.partner_id.property_account_payable_id.id - if self.payment_type == 'outbound': - name = _('Payment bank line %s') % bank_line.name + account_id = bank_line.partner_id.property_account_payable_id.id + if self.payment_type == "outbound": + name = _("Payment bank line %s") % bank_line.name else: - name = _('Debit bank line %s') % bank_line.name + name = _("Debit bank line %s") % bank_line.name vals = { - 'name': name, - 'bank_payment_line_id': bank_line.id, - 'partner_id': bank_line.partner_id.id, - 'account_id': account_id, - 'credit': (self.payment_type == 'inbound' and - bank_line.amount_company_currency or 0.0), - 'debit': (self.payment_type == 'outbound' and - bank_line.amount_company_currency or 0.0), - } + "name": name, + "bank_payment_line_id": bank_line.id, + "partner_id": bank_line.partner_id.id, + "account_id": account_id, + "credit": ( + self.payment_type == "inbound" + and bank_line.amount_company_currency + or 0.0 + ), + "debit": ( + self.payment_type == "outbound" + and bank_line.amount_company_currency + or 0.0 + ), + } if bank_line.currency_id != bank_line.company_currency_id: - sign = self.payment_type == 'inbound' and -1 or 1 - vals.update({ - 'currency_id': bank_line.currency_id.id, - 'amount_currency': bank_line.amount_currency * sign, - }) + sign = self.payment_type == "inbound" and -1 or 1 + vals.update( + { + "currency_id": bank_line.currency_id.id, + "amount_currency": bank_line.amount_currency * sign, + } + ) return vals @api.multi def _create_reconcile_move(self, hashcode, blines): self.ensure_one() post_move = self.payment_mode_id.post_move - am_obj = self.env['account.move'] + am_obj = self.env["account.move"] mvals = self._prepare_move(blines) move = am_obj.create(mvals) blines.reconcile_payment_lines() diff --git a/account_payment_order/models/bank_payment_line.py b/account_payment_order/models/bank_payment_line.py index 573dcba15..416ba0d61 100644 --- a/account_payment_order/models/bank_payment_line.py +++ b/account_payment_order/models/bank_payment_line.py @@ -2,63 +2,83 @@ # Copyright 2018 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from odoo import models, fields, api, _ +from odoo import _, api, fields, models from odoo.exceptions import UserError class BankPaymentLine(models.Model): - _name = 'bank.payment.line' - _description = 'Bank Payment Lines' + _name = "bank.payment.line" + _description = "Bank Payment Lines" - name = fields.Char( - string='Bank Payment Line Ref', required=True, - readonly=True) + name = fields.Char(string="Bank Payment Line Ref", required=True, readonly=True) order_id = fields.Many2one( - 'account.payment.order', string='Order', ondelete='cascade', - index=True, readonly=True) + "account.payment.order", + string="Order", + ondelete="cascade", + index=True, + readonly=True, + ) payment_type = fields.Selection( - related='order_id.payment_type', string="Payment Type", - readonly=True, store=True) + related="order_id.payment_type", + string="Payment Type", + readonly=True, + store=True, + ) state = fields.Selection( - related='order_id.state', string='State', - readonly=True, store=True) + related="order_id.state", string="State", readonly=True, store=True + ) payment_line_ids = fields.One2many( - 'account.payment.line', 'bank_line_id', string='Payment Lines', - readonly=True) + "account.payment.line", "bank_line_id", string="Payment Lines", readonly=True + ) partner_id = fields.Many2one( - 'res.partner', related='payment_line_ids.partner_id', - readonly=True, store=True) # store=True for groupby + "res.partner", related="payment_line_ids.partner_id", readonly=True, store=True + ) # store=True for groupby # Function Float fields are sometimes badly displayed in tree view, # see bug report https://github.com/odoo/odoo/issues/8632 # But is it still true in v9 ? amount_currency = fields.Monetary( - string='Amount', currency_field='currency_id', - compute='_compute_amount', store=True, readonly=True) + string="Amount", + currency_field="currency_id", + compute="_compute_amount", + store=True, + readonly=True, + ) amount_company_currency = fields.Monetary( - string='Amount in Company Currency', - currency_field='company_currency_id', - compute='_compute_amount', store=True, readonly=True) + string="Amount in Company Currency", + currency_field="company_currency_id", + compute="_compute_amount", + store=True, + readonly=True, + ) currency_id = fields.Many2one( - 'res.currency', required=True, readonly=True, - related='payment_line_ids.currency_id') # v8 field: currency + "res.currency", + required=True, + readonly=True, + related="payment_line_ids.currency_id", + ) # v8 field: currency partner_bank_id = fields.Many2one( - 'res.partner.bank', string='Bank Account', readonly=True, - related='payment_line_ids.partner_bank_id') # v8 field: bank_id - date = fields.Date( - related='payment_line_ids.date', readonly=True) + "res.partner.bank", + string="Bank Account", + readonly=True, + related="payment_line_ids.partner_bank_id", + ) # v8 field: bank_id + date = fields.Date(related="payment_line_ids.date", readonly=True) communication_type = fields.Selection( - related='payment_line_ids.communication_type', readonly=True) - communication = fields.Char( - string='Communication', required=True, - readonly=True) + related="payment_line_ids.communication_type", readonly=True + ) + communication = fields.Char(string="Communication", required=True, readonly=True) company_id = fields.Many2one( - 'res.company', - related='order_id.payment_mode_id.company_id', store=True, - readonly=True) + "res.company", + related="order_id.payment_mode_id.company_id", + store=True, + readonly=True, + ) company_currency_id = fields.Many2one( - 'res.currency', - related='order_id.payment_mode_id.company_id.currency_id', - readonly=True, store=True) + "res.currency", + related="order_id.payment_mode_id.company_id.currency_id", + readonly=True, + store=True, + ) @api.model def same_fields_payment_line_and_bank_payment_line(self): @@ -69,29 +89,35 @@ class BankPaymentLine(models.Model): The fields must have the same name on the 2 objects """ same_fields = [ - 'currency_id', 'partner_id', - 'partner_bank_id', 'date', 'communication_type'] + "currency_id", + "partner_id", + "partner_bank_id", + "date", + "communication_type", + ] return same_fields @api.multi - @api.depends('payment_line_ids', 'payment_line_ids.amount_currency') + @api.depends("payment_line_ids", "payment_line_ids.amount_currency") def _compute_amount(self): for bline in self: - amount_currency = sum( - bline.mapped('payment_line_ids.amount_currency')) + amount_currency = sum(bline.mapped("payment_line_ids.amount_currency")) amount_company_currency = bline.currency_id._convert( - amount_currency, bline.company_currency_id, bline.company_id, + amount_currency, + bline.company_currency_id, + bline.company_id, bline.date or fields.Date.today(), ) bline.amount_currency = amount_currency bline.amount_company_currency = amount_company_currency @api.model - @api.returns('self') + @api.returns("self") def create(self, vals): - if vals.get('name', 'New') == 'New': - vals['name'] = self.env['ir.sequence'].next_by_code( - 'bank.payment.line') or 'New' + if vals.get("name", "New") == "New": + vals["name"] = ( + self.env["ir.sequence"].next_by_code("bank.payment.line") or "New" + ) return super(BankPaymentLine, self).create(vals) @api.multi @@ -101,7 +127,7 @@ class BankPaymentLine(models.Model): account_banking_sepa_direct_debit """ self.ensure_one() - if self.order_id.payment_mode_id.move_option == 'date': + if self.order_id.payment_mode_id.move_option == "date": hashcode = fields.Date.to_string(self.date) else: hashcode = str(self.id) @@ -123,37 +149,40 @@ class BankPaymentLine(models.Model): @api.multi def reconcile(self): self.ensure_one() - amlo = self.env['account.move.line'] - transit_mlines = amlo.search([('bank_payment_line_id', '=', self.id)]) - assert len(transit_mlines) == 1, 'We should have only 1 move' + amlo = self.env["account.move.line"] + transit_mlines = amlo.search([("bank_payment_line_id", "=", self.id)]) + assert len(transit_mlines) == 1, "We should have only 1 move" transit_mline = transit_mlines[0] - assert not transit_mline.reconciled,\ - 'Transit move should not be reconciled' + assert not transit_mline.reconciled, "Transit move should not be reconciled" lines_to_rec = transit_mline for payment_line in self.payment_line_ids: if not payment_line.move_line_id: - raise UserError(_( - "Can not reconcile: no move line for " - "payment line %s of partner '%s'.") % ( - payment_line.name, - payment_line.partner_id.name)) + raise UserError( + _( + "Can not reconcile: no move line for " + "payment line %s of partner '%s'." + ) + % (payment_line.name, payment_line.partner_id.name) + ) if payment_line.move_line_id.reconciled: - raise UserError(_( - "Move line '%s' of partner '%s' has already " - "been reconciled") % ( - payment_line.move_line_id.name, - payment_line.partner_id.name)) - if ( - payment_line.move_line_id.account_id != - transit_mline.account_id): - raise UserError(_( - "For partner '%s', the account of the account " - "move line to pay (%s) is different from the " - "account of of the transit move line (%s).") % ( + raise UserError( + _("Move line '%s' of partner '%s' has already " "been reconciled") + % (payment_line.move_line_id.name, payment_line.partner_id.name) + ) + if payment_line.move_line_id.account_id != transit_mline.account_id: + raise UserError( + _( + "For partner '%s', the account of the account " + "move line to pay (%s) is different from the " + "account of of the transit move line (%s)." + ) + % ( payment_line.move_line_id.partner_id.name, payment_line.move_line_id.account_id.code, - transit_mline.account_id.code)) + transit_mline.account_id.code, + ) + ) lines_to_rec += payment_line.move_line_id @@ -163,9 +192,12 @@ class BankPaymentLine(models.Model): def unlink(self): for line in self: order_state = line.order_id.state - if order_state == 'uploaded': - raise UserError(_( - 'Cannot delete a payment order line whose payment order is' - ' in state \'%s\'. You need to cancel it first.') - % order_state) + if order_state == "uploaded": + raise UserError( + _( + "Cannot delete a payment order line whose payment order is" + " in state '%s'. You need to cancel it first." + ) + % order_state + ) return super(BankPaymentLine, self).unlink() diff --git a/account_payment_order/models/res_bank.py b/account_payment_order/models/res_bank.py index cfef540b1..92ca49d37 100644 --- a/account_payment_order/models/res_bank.py +++ b/account_payment_order/models/res_bank.py @@ -1,21 +1,25 @@ # © 2015-2016 Akretion - Alexis de Lattre # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from odoo import models, api, _ +from odoo import _, api, models from odoo.exceptions import ValidationError class ResBank(models.Model): - _inherit = 'res.bank' + _inherit = "res.bank" @api.multi - @api.constrains('bic') + @api.constrains("bic") def check_bic_length(self): for bank in self: if bank.bic and len(bank.bic) not in (8, 11): - raise ValidationError(_( - "A valid BIC contains 8 or 11 characters. The BIC '%s' " - "contains %d characters, so it is not valid.") - % (bank.bic, len(bank.bic))) + raise ValidationError( + _( + "A valid BIC contains 8 or 11 characters. The BIC '%s' " + "contains %d characters, so it is not valid." + ) + % (bank.bic, len(bank.bic)) + ) + # starting from v9, on res.partner.bank bank_bic is a related of bank_id.bic diff --git a/account_payment_order/report/account_payment_order.py b/account_payment_order/report/account_payment_order.py index 88e0653e8..ca8fefc7b 100644 --- a/account_payment_order/report/account_payment_order.py +++ b/account_payment_order/report/account_payment_order.py @@ -6,22 +6,22 @@ from odoo.tools.misc import formatLang class AccountPaymentOrderReport(models.AbstractModel): - _name = 'report.account_payment_order.print_account_payment_order_main' - _description = 'Technical model for printing payment order' + _name = "report.account_payment_order.print_account_payment_order_main" + _description = "Technical model for printing payment order" @api.model def _get_report_values(self, docids, data=None): - AccountPaymentOrderObj = self.env['account.payment.order'] + AccountPaymentOrderObj = self.env["account.payment.order"] docs = AccountPaymentOrderObj.browse(docids) return { - 'doc_ids': docids, - 'doc_model': 'account.payment.order', - 'docs': docs, - 'data': data, - 'env': self.env, - 'get_bank_account_name': self.get_bank_account_name, - 'formatLang': formatLang, + "doc_ids": docids, + "doc_model": "account.payment.order", + "docs": docs, + "data": data, + "env": self.env, + "get_bank_account_name": self.get_bank_account_name, + "formatLang": formatLang, } @api.model @@ -32,15 +32,15 @@ class AccountPaymentOrderReport(models.AbstractModel): :return: """ if partner_bank: - name = '' + name = "" if partner_bank.bank_name: - name = '%s: ' % partner_bank.bank_id.name + name = "%s: " % partner_bank.bank_id.name if partner_bank.acc_number: - name = '%s %s' % (name, partner_bank.acc_number) + name = "{} {}".format(name, partner_bank.acc_number) if partner_bank.bank_bic: - name = '%s - ' % (name) + name = "%s - " % (name) if partner_bank.bank_bic: - name = '%s BIC %s' % (name, partner_bank.bank_bic) + name = "{} BIC {}".format(name, partner_bank.bank_bic) return name else: return False diff --git a/account_payment_order/report/account_payment_order.xml b/account_payment_order/report/account_payment_order.xml index 9c2f7cde4..b3672d368 100644 --- a/account_payment_order/report/account_payment_order.xml +++ b/account_payment_order/report/account_payment_order.xml @@ -1,58 +1,72 @@ - + - - - diff --git a/account_payment_order/report/print_account_payment_order.xml b/account_payment_order/report/print_account_payment_order.xml index ba0823d3f..546df92fd 100644 --- a/account_payment_order/report/print_account_payment_order.xml +++ b/account_payment_order/report/print_account_payment_order.xml @@ -1,16 +1,14 @@ - + - - - - + + diff --git a/account_payment_order/security/payment_security.xml b/account_payment_order/security/payment_security.xml index 57fc732e0..f9638412e 100644 --- a/account_payment_order/security/payment_security.xml +++ b/account_payment_order/security/payment_security.xml @@ -1,37 +1,36 @@ - + - - - - - Accounting / Payments - - - - - - - - - - - Payment order multi-company rule - - ['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])] - - - - Payment line multi-company rule - - ['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])] - - - - Bank payment line multi-company rule - - ['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])] - - - - + + + Accounting / Payments + + + + + + + Payment order multi-company rule + + ['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])] + + + Payment line multi-company rule + + ['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])] + + + Bank payment line multi-company rule + + ['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])] + + diff --git a/account_payment_order/tests/test_account_payment.py b/account_payment_order/tests/test_account_payment.py index e8f98b52e..2b5b60353 100644 --- a/account_payment_order/tests/test_account_payment.py +++ b/account_payment_order/tests/test_account_payment.py @@ -5,31 +5,34 @@ from odoo.tests.common import SavepointCase class TestAccountPayment(SavepointCase): - @classmethod def setUpClass(cls): super(TestAccountPayment, cls).setUpClass() # MODELS - cls.account_payment_model = cls.env['account.payment'] - cls.account_journal_model = cls.env['account.journal'] - cls.payment_method_model = cls.env['account.payment.method'] + cls.account_payment_model = cls.env["account.payment"] + cls.account_journal_model = cls.env["account.journal"] + cls.payment_method_model = cls.env["account.payment.method"] # INSTANCES # Payment methods - cls.inbound_payment_method_01, cls.inbound_payment_method_02 = \ - cls.payment_method_model.search( - [('payment_type', '=', 'inbound')], limit=2) + ( + cls.inbound_payment_method_01, + cls.inbound_payment_method_02, + ) = cls.payment_method_model.search([("payment_type", "=", "inbound")], limit=2) cls.outbound_payment_method_01 = cls.payment_method_model.search( - [('payment_type', '=', 'outbound')], limit=1) + [("payment_type", "=", "outbound")], limit=1 + ) # Journals cls.bank_journal = cls.account_journal_model.search( - [('type', '=', 'bank')], limit=1) + [("type", "=", "bank")], limit=1 + ) cls.bank_journal.inbound_payment_method_ids = [ - (6, 0, [cls.inbound_payment_method_01.id, - cls.inbound_payment_method_02.id])] + (6, 0, [cls.inbound_payment_method_01.id, cls.inbound_payment_method_02.id]) + ] cls.bank_journal.outbound_payment_method_ids = [ - (6, 0, [cls.outbound_payment_method_01.id])] + (6, 0, [cls.outbound_payment_method_01.id]) + ] def test_account_payment_01(self): self.assertFalse(self.inbound_payment_method_01.payment_order_only) @@ -55,41 +58,43 @@ class TestAccountPayment(SavepointCase): self.assertFalse(self.inbound_payment_method_01.payment_order_only) self.assertFalse(self.inbound_payment_method_02.payment_order_only) self.assertFalse(self.bank_journal.inbound_payment_order_only) - new_account_payment = self.account_payment_model.new({ - 'journal_id': self.bank_journal.id, - 'payment_type': 'inbound', - 'amount': 1, - }) + new_account_payment = self.account_payment_model.new( + { + "journal_id": self.bank_journal.id, + "payment_type": "inbound", + "amount": 1, + } + ) # check journals journal_res = new_account_payment._compute_journal_domain_and_types() - journal_domain = journal_res.get('domain') + journal_domain = journal_res.get("domain") self.assertTrue(journal_domain) journals = self.account_journal_model.search(journal_domain) self.assertIn(self.bank_journal, journals) # check payment methods payment_method_res = new_account_payment._onchange_journal() - payment_method_domain = payment_method_res.get('domain', {}).get( - 'payment_method_id') + payment_method_domain = payment_method_res.get("domain", {}).get( + "payment_method_id" + ) self.assertTrue(payment_method_domain) - payment_methods = self.payment_method_model.search( - payment_method_domain) + payment_methods = self.payment_method_model.search(payment_method_domain) self.assertIn(self.inbound_payment_method_01, payment_methods) self.assertIn(self.inbound_payment_method_02, payment_methods) # Set one payment method of the bank journal 'payment order only' self.inbound_payment_method_01.payment_order_only = True # check journals journal_res = new_account_payment._compute_journal_domain_and_types() - journal_domain = journal_res.get('domain') + journal_domain = journal_res.get("domain") self.assertTrue(journal_domain) journals = self.account_journal_model.search(journal_domain) self.assertIn(self.bank_journal, journals) # check payment methods payment_method_res = new_account_payment._onchange_journal() - payment_method_domain = payment_method_res.get('domain', {}).get( - 'payment_method_id') + payment_method_domain = payment_method_res.get("domain", {}).get( + "payment_method_id" + ) self.assertTrue(payment_method_domain) - payment_methods = self.payment_method_model.search( - payment_method_domain) + payment_methods = self.payment_method_model.search(payment_method_domain) self.assertNotIn(self.inbound_payment_method_01, payment_methods) self.assertIn(self.inbound_payment_method_02, payment_methods) # Set all payment methods of the bank journal 'payment order only' @@ -99,16 +104,16 @@ class TestAccountPayment(SavepointCase): self.assertTrue(self.bank_journal.inbound_payment_order_only) # check journals journal_res = new_account_payment._compute_journal_domain_and_types() - journal_domain = journal_res.get('domain') + journal_domain = journal_res.get("domain") self.assertTrue(journal_domain) journals = self.account_journal_model.search(journal_domain) self.assertNotIn(self.bank_journal, journals) # check payment methods payment_method_res = new_account_payment._onchange_journal() - payment_method_domain = payment_method_res.get('domain', {}).get( - 'payment_method_id') + payment_method_domain = payment_method_res.get("domain", {}).get( + "payment_method_id" + ) self.assertTrue(payment_method_domain) - payment_methods = self.payment_method_model.search( - payment_method_domain) + payment_methods = self.payment_method_model.search(payment_method_domain) self.assertNotIn(self.inbound_payment_method_01, payment_methods) self.assertNotIn(self.inbound_payment_method_02, payment_methods) diff --git a/account_payment_order/tests/test_bank.py b/account_payment_order/tests/test_bank.py index aae7bf81a..d5d78bf81 100644 --- a/account_payment_order/tests/test_bank.py +++ b/account_payment_order/tests/test_bank.py @@ -1,14 +1,13 @@ # © 2017 Creu Blanca # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from odoo.tests.common import TransactionCase from odoo.exceptions import ValidationError +from odoo.tests.common import TransactionCase class TestBank(TransactionCase): - def test_bank(self): - bank = self.env['res.bank'].search([], limit=1) + bank = self.env["res.bank"].search([], limit=1) self.assertTrue(bank) with self.assertRaises(ValidationError): bank.bic = "TEST" diff --git a/account_payment_order/tests/test_payment_mode.py b/account_payment_order/tests/test_payment_mode.py index b56d518e4..474e626c4 100644 --- a/account_payment_order/tests/test_payment_mode.py +++ b/account_payment_order/tests/test_payment_mode.py @@ -1,102 +1,115 @@ # © 2017 Creu Blanca # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from odoo.tests.common import TransactionCase from odoo.exceptions import ValidationError +from odoo.tests.common import TransactionCase class TestPaymentMode(TransactionCase): - def setUp(self): super(TestPaymentMode, self).setUp() # Company - self.company = self.env.ref('base.main_company') + self.company = self.env.ref("base.main_company") - self.journal_c1 = self.env['account.journal'].create({ - 'name': 'Journal 1', - 'code': 'J1', - 'type': 'bank', - 'company_id': self.company.id, - }) + self.journal_c1 = self.env["account.journal"].create( + { + "name": "Journal 1", + "code": "J1", + "type": "bank", + "company_id": self.company.id, + } + ) - self.account = self.env['account.account'].search([ - ('reconcile', '=', True), - ('company_id', '=', self.company.id) - ], limit=1) + self.account = self.env["account.account"].search( + [("reconcile", "=", True), ("company_id", "=", self.company.id)], limit=1 + ) - self.manual_out = self.env.ref( - 'account.account_payment_method_manual_out') + self.manual_out = self.env.ref("account.account_payment_method_manual_out") - self.manual_in = self.env.ref( - 'account.account_payment_method_manual_in') + self.manual_in = self.env.ref("account.account_payment_method_manual_in") - self.electronic_out = self.env['account.payment.method'].create({ - 'name': 'Electronic Out', - 'code': 'electronic_out', - 'payment_type': 'outbound', - }) + self.electronic_out = self.env["account.payment.method"].create( + { + "name": "Electronic Out", + "code": "electronic_out", + "payment_type": "outbound", + } + ) - self.payment_mode_c1 = self.env['account.payment.mode'].create({ - 'name': 'Direct Debit of suppliers from Bank 1', - 'bank_account_link': 'variable', - 'payment_method_id': self.manual_out.id, - 'company_id': self.company.id, - 'fixed_journal_id': self.journal_c1.id, - 'variable_journal_ids': [(6, 0, [self.journal_c1.id])] - }) + self.payment_mode_c1 = self.env["account.payment.mode"].create( + { + "name": "Direct Debit of suppliers from Bank 1", + "bank_account_link": "variable", + "payment_method_id": self.manual_out.id, + "company_id": self.company.id, + "fixed_journal_id": self.journal_c1.id, + "variable_journal_ids": [(6, 0, [self.journal_c1.id])], + } + ) def test_constrains(self): with self.assertRaises(ValidationError): - self.payment_mode_c1.write({ - 'generate_move': True, - 'offsetting_account': False - }) + self.payment_mode_c1.write( + {"generate_move": True, "offsetting_account": False} + ) with self.assertRaises(ValidationError): - self.payment_mode_c1.write({ - 'generate_move': True, - 'offsetting_account': 'bank_account', - 'move_option': False - }) + self.payment_mode_c1.write( + { + "generate_move": True, + "offsetting_account": "bank_account", + "move_option": False, + } + ) with self.assertRaises(ValidationError): - self.payment_mode_c1.write({ - 'generate_move': True, - 'offsetting_account': 'transfer_account', - 'transfer_account_id': False - }) + self.payment_mode_c1.write( + { + "generate_move": True, + "offsetting_account": "transfer_account", + "transfer_account_id": False, + } + ) with self.assertRaises(ValidationError): - self.payment_mode_c1.write({ - 'generate_move': True, - 'offsetting_account': 'transfer_account', - 'transfer_account_id': self.account.id, - 'transfer_journal_id': False - }) + self.payment_mode_c1.write( + { + "generate_move": True, + "offsetting_account": "transfer_account", + "transfer_account_id": self.account.id, + "transfer_journal_id": False, + } + ) def test_onchange_generate_move(self): self.payment_mode_c1.generate_move = True self.payment_mode_c1.generate_move_change() - self.assertEqual(self.payment_mode_c1.move_option, 'date') + self.assertEqual(self.payment_mode_c1.move_option, "date") self.payment_mode_c1.generate_move = False self.payment_mode_c1.generate_move_change() self.assertFalse(self.payment_mode_c1.move_option) def test_onchange_offsetting_account(self): - self.payment_mode_c1.offsetting = 'bank_account' + self.payment_mode_c1.offsetting = "bank_account" self.payment_mode_c1.offsetting_account_change() self.assertFalse(self.payment_mode_c1.transfer_account_id) def test_onchange_payment_type(self): self.payment_mode_c1.payment_method_id = self.manual_in self.payment_mode_c1.payment_method_id_change() - self.assertTrue(all([ - journal.type in [ - 'sale_refund', 'sale' - ] for journal in self.payment_mode_c1.default_journal_ids - ])) + self.assertTrue( + all( + [ + journal.type in ["sale_refund", "sale"] + for journal in self.payment_mode_c1.default_journal_ids + ] + ) + ) self.payment_mode_c1.payment_method_id = self.manual_out self.payment_mode_c1.payment_method_id_change() - self.assertTrue(all([ - journal.type in [ - 'purchase_refund', 'purchase' - ] for journal in self.payment_mode_c1.default_journal_ids - ])) + self.assertTrue( + all( + [ + journal.type in ["purchase_refund", "purchase"] + for journal in self.payment_mode_c1.default_journal_ids + ] + ) + ) diff --git a/account_payment_order/tests/test_payment_order_inbound.py b/account_payment_order/tests/test_payment_order_inbound.py index 45b645a0f..c481edb34 100644 --- a/account_payment_order/tests/test_payment_order_inbound.py +++ b/account_payment_order/tests/test_payment_order_inbound.py @@ -3,10 +3,11 @@ # Copyright 2019 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from odoo.tests.common import SavepointCase -from odoo.exceptions import ValidationError, UserError from datetime import date, timedelta +from odoo.exceptions import UserError, ValidationError +from odoo.tests.common import SavepointCase + class TestPaymentOrderInboundBase(SavepointCase): @classmethod @@ -14,85 +15,112 @@ class TestPaymentOrderInboundBase(SavepointCase): self = cls super().setUpClass() self.inbound_mode = self.env.ref( - 'account_payment_mode.payment_mode_inbound_dd1' + "account_payment_mode.payment_mode_inbound_dd1" ) - self.invoice_line_account = self.env['account.account'].search( - [('user_type_id', '=', self.env.ref( - 'account.data_account_type_revenue').id)], - limit=1).id - self.journal = self.env['account.journal'].search( - [('type', '=', 'bank')], limit=1 + self.invoice_line_account = ( + self.env["account.account"] + .search( + [ + ( + "user_type_id", + "=", + self.env.ref("account.data_account_type_revenue").id, + ) + ], + limit=1, + ) + .id + ) + self.journal = self.env["account.journal"].search( + [("type", "=", "bank")], limit=1 ) self.inbound_mode.variable_journal_ids = self.journal # Make sure no others orders are present self.domain = [ - ('state', '=', 'draft'), - ('payment_type', '=', 'inbound'), + ("state", "=", "draft"), + ("payment_type", "=", "inbound"), ] - self.payment_order_obj = self.env['account.payment.order'] + self.payment_order_obj = self.env["account.payment.order"] self.payment_order_obj.search(self.domain).unlink() # Create payment order - self.inbound_order = self.env['account.payment.order'].create({ - 'payment_type': 'inbound', - 'payment_mode_id': self.inbound_mode.id, - 'journal_id': self.journal.id, - }) + self.inbound_order = self.env["account.payment.order"].create( + { + "payment_type": "inbound", + "payment_mode_id": self.inbound_mode.id, + "journal_id": self.journal.id, + } + ) # Open invoice self.invoice = self._create_customer_invoice(self) self.invoice.action_invoice_open() # Add to payment order using the wizard - self.env['account.invoice.payment.line.multi'].with_context( - active_model='account.invoice', - active_ids=self.invoice.ids + self.env["account.invoice.payment.line.multi"].with_context( + active_model="account.invoice", active_ids=self.invoice.ids ).create({}).run() def _create_customer_invoice(self): - invoice_account = self.env['account.account'].search( - [('user_type_id', '=', self.env.ref( - 'account.data_account_type_receivable').id)], - limit=1).id - invoice = self.env['account.invoice'].create({ - 'partner_id': self.env.ref('base.res_partner_4').id, - 'account_id': invoice_account, - 'type': 'out_invoice', - 'payment_mode_id': self.inbound_mode.id - }) - self.env['account.invoice.line'].create({ - 'product_id': self.env.ref('product.product_product_4').id, - 'quantity': 1.0, - 'price_unit': 100.0, - 'invoice_id': invoice.id, - 'name': 'product that cost 100', - 'account_id': self.invoice_line_account, - }) + invoice_account = ( + self.env["account.account"] + .search( + [ + ( + "user_type_id", + "=", + self.env.ref("account.data_account_type_receivable").id, + ) + ], + limit=1, + ) + .id + ) + invoice = self.env["account.invoice"].create( + { + "partner_id": self.env.ref("base.res_partner_4").id, + "account_id": invoice_account, + "type": "out_invoice", + "payment_mode_id": self.inbound_mode.id, + } + ) + self.env["account.invoice.line"].create( + { + "product_id": self.env.ref("product.product_product_4").id, + "quantity": 1.0, + "price_unit": 100.0, + "invoice_id": invoice.id, + "name": "product that cost 100", + "account_id": self.invoice_line_account, + } + ) return invoice class TestPaymentOrderInbound(TestPaymentOrderInboundBase): def test_constrains_type(self): with self.assertRaises(ValidationError): - order = self.env['account.payment.order'].create({ - 'payment_mode_id': self.inbound_mode.id, - 'journal_id': self.journal.id, - }) - order.payment_type = 'outbound' + order = self.env["account.payment.order"].create( + { + "payment_mode_id": self.inbound_mode.id, + "journal_id": self.journal.id, + } + ) + order.payment_type = "outbound" def test_constrains_date(self): with self.assertRaises(ValidationError): - self.inbound_order.date_scheduled = date.today() - timedelta( - days=1) + self.inbound_order.date_scheduled = date.today() - timedelta(days=1) def test_creation(self): payment_order = self.inbound_order self.assertEqual(len(payment_order.ids), 1) - bank_journal = self.env['account.journal'].search( - [('type', '=', 'bank')], limit=1) + bank_journal = self.env["account.journal"].search( + [("type", "=", "bank")], limit=1 + ) # Set journal to allow cancelling entries bank_journal.update_posted = True - payment_order.write({ - 'journal_id': bank_journal.id, - }) + payment_order.write( + {"journal_id": bank_journal.id,} + ) self.assertEqual(len(payment_order.payment_line_ids), 1) self.assertEqual(len(payment_order.bank_line_ids), 0) @@ -106,7 +134,7 @@ class TestPaymentOrderInbound(TestPaymentOrderInboundBase): payment_order.open2generated() payment_order.generated2uploaded() - self.assertEqual(payment_order.state, 'uploaded') + self.assertEqual(payment_order.state, "uploaded") with self.assertRaises(UserError): payment_order.unlink() @@ -115,7 +143,7 @@ class TestPaymentOrderInbound(TestPaymentOrderInboundBase): with self.assertRaises(UserError): bank_line.unlink() payment_order.action_done_cancel() - self.assertEqual(payment_order.state, 'cancel') + self.assertEqual(payment_order.state, "cancel") payment_order.cancel2draft() payment_order.unlink() self.assertEqual(len(self.payment_order_obj.search(self.domain)), 0) diff --git a/account_payment_order/tests/test_payment_order_outbound.py b/account_payment_order/tests/test_payment_order_outbound.py index 713396c84..3ac463624 100644 --- a/account_payment_order/tests/test_payment_order_outbound.py +++ b/account_payment_order/tests/test_payment_order_outbound.py @@ -3,96 +3,126 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from datetime import date, datetime, timedelta + from odoo.exceptions import UserError, ValidationError from odoo.tests.common import TransactionCase class TestPaymentOrderOutbound(TransactionCase): - def setUp(self): super(TestPaymentOrderOutbound, self).setUp() - self.journal = self.env['account.journal'].search( - [('type', '=', 'bank')], limit=1 + self.journal = self.env["account.journal"].search( + [("type", "=", "bank")], limit=1 + ) + self.invoice_line_account = ( + self.env["account.account"] + .search( + [ + ( + "user_type_id", + "=", + self.env.ref("account.data_account_type_expenses").id, + ) + ], + limit=1, + ) + .id ) - self.invoice_line_account = self.env['account.account'].search( - [('user_type_id', '=', self.env.ref( - 'account.data_account_type_expenses').id)], - limit=1).id self.invoice = self._create_supplier_invoice() self.invoice_02 = self._create_supplier_invoice() - self.mode = self.env.ref( - 'account_payment_mode.payment_mode_outbound_ct1') + self.mode = self.env.ref("account_payment_mode.payment_mode_outbound_ct1") self.creation_mode = self.env.ref( - 'account_payment_mode.payment_mode_outbound_dd1') - self.bank_journal = self.env['account.journal'].search( - [('type', '=', 'bank')], limit=1) + "account_payment_mode.payment_mode_outbound_dd1" + ) + self.bank_journal = self.env["account.journal"].search( + [("type", "=", "bank")], limit=1 + ) # Make sure no other payment orders are in the DB self.domain = [ - ('state', '=', 'draft'), - ('payment_type', '=', 'outbound'), + ("state", "=", "draft"), + ("payment_type", "=", "outbound"), ] - self.env['account.payment.order'].search(self.domain).unlink() + self.env["account.payment.order"].search(self.domain).unlink() def _create_supplier_invoice(self): - invoice_account = self.env['account.account'].search( - [('user_type_id', '=', self.env.ref( - 'account.data_account_type_payable').id)], - limit=1).id - invoice = self.env['account.invoice'].create({ - 'partner_id': self.env.ref('base.res_partner_4').id, - 'account_id': invoice_account, - 'type': 'in_invoice', - 'payment_mode_id': self.env.ref( - 'account_payment_mode.payment_mode_outbound_ct1').id - }) + invoice_account = ( + self.env["account.account"] + .search( + [ + ( + "user_type_id", + "=", + self.env.ref("account.data_account_type_payable").id, + ) + ], + limit=1, + ) + .id + ) + invoice = self.env["account.invoice"].create( + { + "partner_id": self.env.ref("base.res_partner_4").id, + "account_id": invoice_account, + "type": "in_invoice", + "payment_mode_id": self.env.ref( + "account_payment_mode.payment_mode_outbound_ct1" + ).id, + } + ) - self.env['account.invoice.line'].create({ - 'product_id': self.env.ref('product.product_product_4').id, - 'quantity': 1.0, - 'price_unit': 100.0, - 'invoice_id': invoice.id, - 'name': 'product that cost 100', - 'account_id': self.invoice_line_account, - }) + self.env["account.invoice.line"].create( + { + "product_id": self.env.ref("product.product_product_4").id, + "quantity": 1.0, + "price_unit": 100.0, + "invoice_id": invoice.id, + "name": "product that cost 100", + "account_id": self.invoice_line_account, + } + ) return invoice def test_creation_due_date(self): self.mode.variable_journal_ids = self.bank_journal self.mode.group_lines = False - self.order_creation('due') + self.order_creation("due") def test_creation_no_date(self): self.mode.group_lines = True - self.creation_mode.write({ - 'group_lines': False, - 'bank_account_link': 'fixed', - 'default_date_prefered': 'due', - 'fixed_journal_id': self.bank_journal.id, - }) + self.creation_mode.write( + { + "group_lines": False, + "bank_account_link": "fixed", + "default_date_prefered": "due", + "fixed_journal_id": self.bank_journal.id, + } + ) self.mode.variable_journal_ids = self.bank_journal self.order_creation(False) def test_creation_fixed_date(self): - self.mode.write({ - 'bank_account_link': 'fixed', - 'default_date_prefered': 'fixed', - 'fixed_journal_id': self.bank_journal.id, - }) + self.mode.write( + { + "bank_account_link": "fixed", + "default_date_prefered": "fixed", + "fixed_journal_id": self.bank_journal.id, + } + ) self.invoice_02.action_invoice_open() - self.order_creation('fixed') + self.order_creation("fixed") def order_creation(self, date_prefered): # Open invoice self.invoice.action_invoice_open() order_vals = { - 'payment_type': 'outbound', - 'payment_mode_id': self.creation_mode.id, + "payment_type": "outbound", + "payment_mode_id": self.creation_mode.id, } if date_prefered: - order_vals['date_prefered'] = date_prefered - order = self.env['account.payment.order'].create(order_vals) + order_vals["date_prefered"] = date_prefered + order = self.env["account.payment.order"].create(order_vals) with self.assertRaises(UserError): order.draft2open() @@ -105,25 +135,20 @@ class TestPaymentOrderOutbound(TransactionCase): self.assertEqual(order.date_prefered, date_prefered) with self.assertRaises(UserError): order.draft2open() - line_create = self.env['account.payment.line.create'].with_context( - active_model='account.payment.order', - active_id=order.id - ).create({ - 'date_type': 'move', - 'move_date': datetime.now() - }) - line_create.payment_mode = 'any' + line_create = ( + self.env["account.payment.line.create"] + .with_context(active_model="account.payment.order", active_id=order.id) + .create({"date_type": "move", "move_date": datetime.now()}) + ) + line_create.payment_mode = "any" line_create.move_line_filters_change() line_create.populate() line_create.create_payment_lines() - line_created_due = self.env[ - 'account.payment.line.create'].with_context( - active_model='account.payment.order', - active_id=order.id - ).create({ - 'date_type': 'due', - 'due_date': datetime.now() - }) + line_created_due = ( + self.env["account.payment.line.create"] + .with_context(active_model="account.payment.order", active_id=order.id) + .create({"date_type": "due", "due_date": datetime.now()}) + ) line_created_due.populate() line_created_due.create_payment_lines() self.assertGreater(len(order.payment_line_ids), 0) @@ -131,27 +156,27 @@ class TestPaymentOrderOutbound(TransactionCase): order.open2generated() order.generated2uploaded() order.action_done() - self.assertEqual(order.state, 'done') + self.assertEqual(order.state, "done") def test_cancel_payment_order(self): # Open invoice self.invoice.action_invoice_open() # Add to payment order using the wizard - self.env['account.invoice.payment.line.multi'].with_context( - active_model='account.invoice', - active_ids=self.invoice.ids + self.env["account.invoice.payment.line.multi"].with_context( + active_model="account.invoice", active_ids=self.invoice.ids ).create({}).run() - payment_order = self.env['account.payment.order'].search(self.domain) + payment_order = self.env["account.payment.order"].search(self.domain) self.assertEqual(len(payment_order), 1) - bank_journal = self.env['account.journal'].search( - [('type', '=', 'bank')], limit=1) + bank_journal = self.env["account.journal"].search( + [("type", "=", "bank")], limit=1 + ) # Set journal to allow cancelling entries bank_journal.update_posted = True - payment_order.write({ - 'journal_id': bank_journal.id, - }) + payment_order.write( + {"journal_id": bank_journal.id,} + ) self.assertEqual(len(payment_order.payment_line_ids), 1) self.assertEqual(len(payment_order.bank_line_ids), 0) @@ -165,7 +190,7 @@ class TestPaymentOrderOutbound(TransactionCase): payment_order.open2generated() payment_order.generated2uploaded() - self.assertEqual(payment_order.state, 'uploaded') + self.assertEqual(payment_order.state, "uploaded") with self.assertRaises(UserError): payment_order.unlink() @@ -174,19 +199,20 @@ class TestPaymentOrderOutbound(TransactionCase): with self.assertRaises(UserError): bank_line.unlink() payment_order.action_done_cancel() - self.assertEqual(payment_order.state, 'cancel') + self.assertEqual(payment_order.state, "cancel") payment_order.cancel2draft() payment_order.unlink() self.assertEqual( - len(self.env['account.payment.order'].search(self.domain)), 0, + len(self.env["account.payment.order"].search(self.domain)), 0, ) def test_constrains(self): - outbound_order = self.env['account.payment.order'].create({ - 'payment_type': 'outbound', - 'payment_mode_id': self.mode.id, - 'journal_id': self.journal.id, - }) + outbound_order = self.env["account.payment.order"].create( + { + "payment_type": "outbound", + "payment_mode_id": self.mode.id, + "journal_id": self.journal.id, + } + ) with self.assertRaises(ValidationError): - outbound_order.date_scheduled = date.today() - timedelta( - days=1) + outbound_order.date_scheduled = date.today() - timedelta(days=1) diff --git a/account_payment_order/views/account_invoice_view.xml b/account_payment_order/views/account_invoice_view.xml index 74caa7ad3..2dc99bf55 100644 --- a/account_payment_order/views/account_invoice_view.xml +++ b/account_payment_order/views/account_invoice_view.xml @@ -1,63 +1,77 @@ - + - - - - account_payment_order.invoice_form - account.invoice - - - - - + + + + + + + - - + + + account_payment_order.invoice_supplier_form + account.invoice + + + + + + - - - - - - account_payment_order.invoice_supplier_form - account.invoice - - - - - - - - - - - - + + diff --git a/account_payment_order/views/account_move_line.xml b/account_payment_order/views/account_move_line.xml index 60d3d8c49..94b133563 100644 --- a/account_payment_order/views/account_move_line.xml +++ b/account_payment_order/views/account_move_line.xml @@ -1,25 +1,22 @@ - + - - - - - account_payment_order.move_line_form - account.move.line - - - - - - - - - - + + account_payment_order.move_line_form + account.move.line + + + + + + + + diff --git a/account_payment_order/views/account_payment_line.xml b/account_payment_order/views/account_payment_line.xml index 63c7d5e2f..c486859c0 100644 --- a/account_payment_order/views/account_payment_line.xml +++ b/account_payment_order/views/account_payment_line.xml @@ -1,71 +1,83 @@ - + - - - - account.payment.line.form - account.payment.line - -
- - - - - - - - - - - - - - + + account.payment.line.form + account.payment.line + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - -
-
- - - account.payment.line.tree - account.payment.line - - - - - - - - - - - - - - - - - - - - Payment Lines - account.payment.line - tree,form - {'account_payment_line_main_view': True} - - - + + + + + account.payment.line.tree + account.payment.line + + + + + + + + + + + + + + + + + + + Payment Lines + account.payment.line + tree,form + {'account_payment_line_main_view': True} +
diff --git a/account_payment_order/views/account_payment_method.xml b/account_payment_order/views/account_payment_method.xml index 02459a48b..766636aa2 100644 --- a/account_payment_order/views/account_payment_method.xml +++ b/account_payment_order/views/account_payment_method.xml @@ -1,18 +1,20 @@ - + - - - account.payment.method.form (in account_payment_order) + account.payment.method.form (in account_payment_order) account.payment.method - + - + - diff --git a/account_payment_order/views/account_payment_mode.xml b/account_payment_order/views/account_payment_mode.xml index 5be3a6025..136629183 100644 --- a/account_payment_order/views/account_payment_mode.xml +++ b/account_payment_order/views/account_payment_mode.xml @@ -1,75 +1,92 @@ - + - - - - account_payment_order.account.payment.mode.form - account.payment.mode - - - - - - - - - - - - + account_payment_order.account.payment.mode.form + account.payment.mode + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - + attrs="{'invisible': [('payment_order_ok', '=', False)]}" + > + + + + + + + + - - - - - - account_payment_order.account.payment.mode.tree - account.payment.mode - - - - - - - - - account_payment_order.account.payment.mode.search - account.payment.mode - - - - - - - - - + + + account_payment_order.account.payment.mode.tree + account.payment.mode + + + + + + + + + account_payment_order.account.payment.mode.search + account.payment.mode + + + + + + + diff --git a/account_payment_order/views/account_payment_order.xml b/account_payment_order/views/account_payment_order.xml index 155cbb4a8..0e42603ee 100644 --- a/account_payment_order/views/account_payment_order.xml +++ b/account_payment_order/views/account_payment_order.xml @@ -1,170 +1,259 @@ - + - - - - account.payment.order.form - account.payment.order - -
-
-
- -
-