diff --git a/pos_check_deposit/__init__.py b/pos_check_deposit/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/pos_check_deposit/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/pos_check_deposit/__manifest__.py b/pos_check_deposit/__manifest__.py new file mode 100644 index 0000000..cdac7b5 --- /dev/null +++ b/pos_check_deposit/__manifest__.py @@ -0,0 +1,41 @@ +# Copyright 2022 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "POS Check Deposit", + "version": "16.0.1.0.0", + "category": "Point of sale", + "license": "AGPL-3", + "summary": "Make POS and Check Deposit module work together", + "description": """ +POS Check Deposit +================= + +On POS payment method, there is a boolean field named 'split_transactions' which has a string "Identify Customer". When this option is enabled, the payment move lines are split (which is required for the account_check_deposit module) and you must select a Customer on the POS order (which is not really needed for a payment by check). + +The goal of this module is to have 2 different options on POS payment method: + +* split_transactions (the current field), to split the payment move lines +* identify_customer (a new field), to require the selection of a customer on the POS order + +That way, you can configure the **Check** payment method with split_transactions enabled and identify_customer disabled. + +WARNING: this module requires a patch on the point_of_sale module. The patch is available in the root directory of the module under the name **odoo-pos_check_deposit.diff**. + +Authors +------- + +Akretion: + +* Alexis de Lattre + + """, + "author": "Akretion", + "website": "https://github.com/akretion/odoo-usability", + "depends": ["point_of_sale"], + "data": [ + "views/pos_payment_method.xml", + ], + "installable": True, +} diff --git a/pos_check_deposit/models/__init__.py b/pos_check_deposit/models/__init__.py new file mode 100644 index 0000000..604d90c --- /dev/null +++ b/pos_check_deposit/models/__init__.py @@ -0,0 +1,2 @@ +from . import pos_payment_method +from . import pos_session diff --git a/pos_check_deposit/models/pos_payment_method.py b/pos_check_deposit/models/pos_payment_method.py new file mode 100644 index 0000000..17e4c6e --- /dev/null +++ b/pos_check_deposit/models/pos_payment_method.py @@ -0,0 +1,27 @@ +# Copyright 2022 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + + +class PosPaymentMethod(models.Model): + _inherit = "pos.payment.method" + + split_transactions = fields.Boolean(string="Split Transactions") + identify_customer = fields.Boolean(string='Identify Customer') + + @api.constrains('split_transactions', 'identify_customer') + def _check_split_transactions_identify_customer(self): + for method in self: + if method.identify_customer and not method.split_transactions: + raise ValidationError(_( + "On payment method '%s' the option 'Identify Customer' " + "is enabled, so the option 'Split Transactions' must " + "be enabled too.") % method.display_name) + + @api.onchange('split_transactions') + def split_transactions_change(self): + if not self.split_transactions and self.identify_customer: + self.identify_customer = False diff --git a/pos_check_deposit/models/pos_session.py b/pos_check_deposit/models/pos_session.py new file mode 100644 index 0000000..1316f93 --- /dev/null +++ b/pos_check_deposit/models/pos_session.py @@ -0,0 +1,14 @@ +# Copyright 2022 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models + + +class PosSession(models.Model): + _inherit = "pos.session" + + def _loader_params_pos_payment_method(self): + res = super()._loader_params_pos_payment_method() + res['search_params']['fields'].append('identify_customer') + return res diff --git a/pos_check_deposit/odoo-pos_check_deposit.diff b/pos_check_deposit/odoo-pos_check_deposit.diff new file mode 100644 index 0000000..190822c --- /dev/null +++ b/pos_check_deposit/odoo-pos_check_deposit.diff @@ -0,0 +1,79 @@ +diff --git a/addons/point_of_sale/models/pos_session.py b/addons/point_of_sale/models/pos_session.py +index 31e39105612..fe74620369a 100644 +--- a/addons/point_of_sale/models/pos_session.py ++++ b/addons/point_of_sale/models/pos_session.py +@@ -928,8 +928,13 @@ class PosSession(models.Model): + if not payment_method.journal_id: + return self.env['account.move.line'] + outstanding_account = payment_method.outstanding_account_id or self.company_id.account_journal_payment_debit_account_id +- accounting_partner = self.env["res.partner"]._find_accounting_partner(payment.partner_id) +- destination_account = accounting_partner.property_account_receivable_id ++ # HACK for pos_check_deposit ++ if payment.partner_id: ++ accounting_partner = self.env["res.partner"]._find_accounting_partner(payment.partner_id) ++ destination_account = accounting_partner.property_account_receivable_id ++ else: ++ accounting_partner = False ++ destination_account = self._get_receivable_account(payment.payment_method_id) + + if float_compare(amounts['amount'], 0, precision_rounding=self.currency_id.rounding) < 0: + # revert the accounts because account.payment doesn't accept negative amount. +@@ -937,7 +942,7 @@ class PosSession(models.Model): + + account_payment = self.env['account.payment'].create({ + 'amount': abs(amounts['amount']), +- 'partner_id': payment.partner_id.id, ++ 'partner_id': accounting_partner and accounting_partner.id or False, + 'journal_id': payment_method.journal_id.id, + 'force_outstanding_account_id': outstanding_account.id, + 'destination_account_id': destination_account.id, +@@ -1097,8 +1102,8 @@ class PosSession(models.Model): + lines.filtered(lambda line: not line.reconciled).reconcile() + + for payment, lines in payment_to_receivable_lines.items(): +- if payment.partner_id.property_account_receivable_id.reconcile: +- lines.filtered(lambda line: not line.reconciled).reconcile() ++ # HACK for pos_check_deposit ++ lines.filtered(lambda line: line.account_id.reconcile and not line.reconciled).reconcile() + + # Reconcile invoice payments' receivable lines. But we only do when the account is reconcilable. + # Though `account_default_pos_receivable_account_id` should be of type receivable, there is currently +@@ -1176,15 +1181,17 @@ class PosSession(models.Model): + return self._credit_amounts(partial_args, amount, amount_converted) + + def _get_split_receivable_vals(self, payment, amount, amount_converted): +- accounting_partner = self.env["res.partner"]._find_accounting_partner(payment.partner_id) +- if not accounting_partner: +- raise UserError(_("You have enabled the \"Identify Customer\" option for %s payment method," +- "but the order %s does not contain a customer.") % (payment.payment_method_id.name, +- payment.pos_order_id.name)) ++ # HACK for pos_check_deposit ++ if payment.partner_id: ++ accounting_partner = self.env["res.partner"]._find_accounting_partner(payment.partner_id) ++ account_id = accounting_partner.property_account_receivable_id.id ++ else: ++ accounting_partner = False ++ account_id = self._get_receivable_account(payment.payment_method_id).id + partial_vals = { +- 'account_id': accounting_partner.property_account_receivable_id.id, ++ 'account_id': account_id, + 'move_id': self.move_id.id, +- 'partner_id': accounting_partner.id, ++ 'partner_id': accounting_partner and accounting_partner.id or False, + 'name': '%s - %s' % (self.name, payment.payment_method_id.name), + } + return self._debit_amounts(partial_vals, amount, amount_converted) +diff --git a/addons/point_of_sale/static/src/js/Screens/PaymentScreen/PaymentScreen.js b/addons/point_of_sale/static/src/js/Screens/PaymentScreen/PaymentScreen.js +index b9a237eb34c..62ad67e9517 100644 +--- a/addons/point_of_sale/static/src/js/Screens/PaymentScreen/PaymentScreen.js ++++ b/addons/point_of_sale/static/src/js/Screens/PaymentScreen/PaymentScreen.js +@@ -288,7 +288,8 @@ odoo.define('point_of_sale.PaymentScreen', function (require) { + return false; + } + +- const splitPayments = this.paymentLines.filter(payment => payment.payment_method.split_transactions) ++ // HACK for pos_check_deposit ++ const splitPayments = this.paymentLines.filter(payment => payment.payment_method.identify_customer) + if (splitPayments.length && !this.currentOrder.get_partner()) { + const paymentMethod = splitPayments[0].payment_method + const { confirmed } = await this.showPopup('ConfirmPopup', { diff --git a/pos_check_deposit/views/pos_payment_method.xml b/pos_check_deposit/views/pos_payment_method.xml new file mode 100644 index 0000000..1a00b64 --- /dev/null +++ b/pos_check_deposit/views/pos_payment_method.xml @@ -0,0 +1,30 @@ + + + + + + + pos.payment.method + + + + + + + + + + pos.payment.method + + + + + + + + +