diff options
| author | Antoine Prieels <anp@odoo.com> | 2020-08-27 09:50:57 +0000 |
|---|---|---|
| committer | Antoine Prieels <anp@odoo.com> | 2020-08-28 06:18:48 +0000 |
| commit | eaae65941177dcf89d03251343de3cb4e7866003 (patch) | |
| tree | b2e8f16a5e74882b00b68f2d670ca42d5809b7c8 | |
| parent | 9b67f6ee0783e8b02edb260b3ba5a0322187a416 (diff) | |
[IMP] pos_restaurant(_adyen): Keep tab open
As long as the payment is not validated, the cashier can add products
to the order, even if the payment has been completed. The amount
authorized can be adjusted if the payment interface implements the
canBeAdjusted method.
closes odoo/odoo#56639
Taskid: 2117032
Signed-off-by: pimodoo <pimodoo@users.noreply.github.com>
24 files changed, 185 insertions, 56 deletions
diff --git a/addons/point_of_sale/models/pos_order.py b/addons/point_of_sale/models/pos_order.py index 500890cf0fe..23d0f845feb 100644 --- a/addons/point_of_sale/models/pos_order.py +++ b/addons/point_of_sale/models/pos_order.py @@ -60,6 +60,7 @@ class PosOrder(models.Model): 'payment_date': ui_paymentline['name'], 'payment_method_id': ui_paymentline['payment_method_id'], 'card_type': ui_paymentline.get('card_type'), + 'cardholder_name': ui_paymentline.get('cardholder_name'), 'transaction_id': ui_paymentline.get('transaction_id'), 'payment_status': ui_paymentline.get('payment_status'), 'pos_order_id': order.id, diff --git a/addons/point_of_sale/models/pos_payment.py b/addons/point_of_sale/models/pos_payment.py index f5f21f1c12b..389a7fdde05 100644 --- a/addons/point_of_sale/models/pos_payment.py +++ b/addons/point_of_sale/models/pos_payment.py @@ -25,6 +25,7 @@ class PosPayment(models.Model): session_id = fields.Many2one('pos.session', string='Session', related='pos_order_id.session_id', store=True) company_id = fields.Many2one('res.company', string='Company', related='pos_order_id.company_id') card_type = fields.Char('Type of card used') + cardholder_name = fields.Char('Cardholder Name') transaction_id = fields.Char('Payment Transaction ID') payment_status = fields.Char('Payment Status') ticket = fields.Char('Payment Receipt Info') @@ -46,6 +47,7 @@ class PosPayment(models.Model): 'amount': payment.amount, 'payment_status': payment.payment_status, 'card_type': payment.card_type, + 'cardholder_name': payment.cardholder_name, 'transaction_id': payment.transaction_id, 'ticket': payment.ticket, 'is_change': payment.is_change, diff --git a/addons/point_of_sale/static/src/js/Screens/TicketScreen/TicketScreen.js b/addons/point_of_sale/static/src/js/Screens/TicketScreen/TicketScreen.js index 3b125ba6b75..7ab35fcf08e 100644 --- a/addons/point_of_sale/static/src/js/Screens/TicketScreen/TicketScreen.js +++ b/addons/point_of_sale/static/src/js/Screens/TicketScreen/TicketScreen.js @@ -103,6 +103,9 @@ odoo.define('point_of_sale.TicketScreen', function (require) { getCustomer(order) { return order.get_client_name(); } + getCardholderName(order) { + return order.get_cardholder_name(); + } getEmployee(order) { return order.employee.name; } @@ -118,6 +121,9 @@ odoo.define('point_of_sale.TicketScreen', function (require) { .get_paymentlines() .some((payment) => payment.is_electronic() && payment.get_payment_status() === 'done'); } + showCardholderName() { + return this.env.pos.payment_methods.some(method => method.use_payment_terminal); + } get searchBarConfig() { return { searchFields: this.constants.searchFieldNames, @@ -152,11 +158,17 @@ odoo.define('point_of_sale.TicketScreen', function (require) { * @returns Record<string, (models.Order) => string> */ get _searchFields() { - return { + var fields = { 'Receipt Number': (order) => order.name, Date: (order) => moment(order.creation_date).format('YYYY-MM-DD hh:mm A'), Customer: (order) => order.get_client_name(), }; + + if (this.showCardholderName()) { + fields['Cardholder Name'] = (order) => order.get_cardholder_name(); + } + + return fields; } /** * Maps the order screen params to order status. diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 15a534d6d4f..efbbf802db2 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -2389,6 +2389,7 @@ exports.Paymentline = Backbone.Model.extend({ this.ticket = ''; this.payment_status = ''; this.card_type = ''; + this.cardholder_name = ''; this.transaction_id = ''; if (options.json) { @@ -2408,6 +2409,7 @@ exports.Paymentline = Backbone.Model.extend({ this.payment_status = json.payment_status; this.ticket = json.ticket; this.card_type = json.card_type; + this.cardholder_name = json.cardholder_name; this.transaction_id = json.transaction_id; this.is_change = json.is_change; }, @@ -2488,6 +2490,7 @@ exports.Paymentline = Backbone.Model.extend({ payment_status: this.payment_status, ticket: this.ticket, card_type: this.card_type, + cardholder_name: this.cardholder_name, transaction_id: this.transaction_id, }; }, @@ -3328,6 +3331,10 @@ exports.Order = Backbone.Model.extend({ var client = this.get('client'); return client ? client.name : ""; }, + get_cardholder_name: function(){ + var card_payment_line = this.paymentlines.find(pl => pl.cardholder_name); + return card_payment_line ? card_payment_line.cardholder_name : ""; + }, /* ---- Screen Status --- */ // the order also stores the screen status, as the PoS supports // different active screens per order. This method is used to diff --git a/addons/point_of_sale/static/src/xml/Screens/TicketScreen/TicketScreen.xml b/addons/point_of_sale/static/src/xml/Screens/TicketScreen/TicketScreen.xml index 2aa890e029d..abdba9bb63e 100644 --- a/addons/point_of_sale/static/src/xml/Screens/TicketScreen/TicketScreen.xml +++ b/addons/point_of_sale/static/src/xml/Screens/TicketScreen/TicketScreen.xml @@ -16,6 +16,7 @@ <div class="col start wide">Date</div> <div class="col start wide">Receipt Number</div> <div class="col start">Customer</div> + <div class="col start wide" t-if="showCardholderName()">Cardholder Name</div> <div class="col start">Employee</div> <div class="col end">Total</div> <div class="col start narrow">Status</div> @@ -32,6 +33,9 @@ <div class="col start"> <t t-esc="getCustomer(order)"></t> </div> + <div t-if="showCardholderName()" class="col start"> + <t t-esc="getCardholderName(order)"></t> + </div> <div class="col start"> <t t-esc="getEmployee(order)"></t> </div> diff --git a/addons/point_of_sale/static/tests/unit/test_PaymentScreen.js b/addons/point_of_sale/static/tests/unit/test_PaymentScreen.js index 8f44e82cc84..48d3b55dbc6 100644 --- a/addons/point_of_sale/static/tests/unit/test_PaymentScreen.js +++ b/addons/point_of_sale/static/tests/unit/test_PaymentScreen.js @@ -220,6 +220,9 @@ odoo.define('point_of_sale.tests.PaymentScreen', function (require) { this.payment_status = 'pending'; this.can_be_reversed = false; } + canBeAdjusted() { + return false; + } setPaymentStatus(status) { this.payment_status = status; this.trigger('change'); diff --git a/addons/point_of_sale/views/pos_payment_views.xml b/addons/point_of_sale/views/pos_payment_views.xml index 4093605f5c3..af855fb187a 100644 --- a/addons/point_of_sale/views/pos_payment_views.xml +++ b/addons/point_of_sale/views/pos_payment_views.xml @@ -13,6 +13,7 @@ <field name="pos_order_id" /> <field name="payment_method_id" /> <field name="card_type" attrs="{'invisible': [('card_type', '=', False)]}"/> + <field name="cardholder_name" attrs="{'invisible': [('cardholder_name', '=', False)]}"/> <field name="transaction_id" attrs="{'invisible': [('transaction_id', '=', False)]}"/> <field name="session_id" /> </group> diff --git a/addons/pos_adyen/models/pos_payment_method.py b/addons/pos_adyen/models/pos_payment_method.py index 4baa83afdd3..327fc9af52d 100644 --- a/addons/pos_adyen/models/pos_payment_method.py +++ b/addons/pos_adyen/models/pos_payment_method.py @@ -84,7 +84,7 @@ class PosPaymentMethod(models.Model): } @api.model - def proxy_adyen_request(self, data, test_mode, api_key): + def proxy_adyen_request(self, data, test_mode, api_key, test_endpoint=False, live_endpoint=False): '''Necessary because Adyen's endpoints don't have CORS enabled. This is an @api.model function to avoid concurrent update errors. Adyen's async endpoint can still take well over a second to complete a @@ -95,9 +95,15 @@ class PosPaymentMethod(models.Model): pos.payment.method. ''' TIMEOUT = 10 - endpoint = 'https://terminal-api-live.adyen.com/async' + + if not test_endpoint: + test_endpoint = 'https://terminal-api-test.adyen.com/async' + if not live_endpoint: + live_endpoint = 'https://terminal-api-live.adyen.com/async' + + endpoint = live_endpoint if test_mode: - endpoint = 'https://terminal-api-test.adyen.com/async' + endpoint = test_endpoint _logger.info('request to adyen\n%s', pprint.pformat(data)) headers = { diff --git a/addons/pos_adyen/static/src/js/payment_adyen.js b/addons/pos_adyen/static/src/js/payment_adyen.js index f8eb63fb515..df63ec49bdd 100644 --- a/addons/pos_adyen/static/src/js/payment_adyen.js +++ b/addons/pos_adyen/static/src/js/payment_adyen.js @@ -43,12 +43,12 @@ var PaymentAdyen = PaymentInterface.extend({ return Promise.reject(data); // prevent subsequent onFullFilled's from being called }, - _call_adyen: function (data) { + _call_adyen: function (data, test_endpoint, live_endpoint) { var self = this; return rpc.query({ model: 'pos.payment.method', method: 'proxy_adyen_request', - args: [data, this.payment_method.adyen_test_mode, this.payment_method.adyen_api_key], + args: [data, this.payment_method.adyen_test_mode, this.payment_method.adyen_api_key, test_endpoint, live_endpoint], }, { // When a payment terminal is disconnected it takes Adyen // a while to return an error (~6s). So wait 10 seconds @@ -232,6 +232,7 @@ var PaymentAdyen = PaymentInterface.extend({ line.transaction_id = additional_response.get('pspReference'); line.card_type = additional_response.get('cardType'); + line.cardholder_name = additional_response.get('cardHolderName') || ''; resolve(true); } else { var message = additional_response.get('message'); diff --git a/addons/pos_restaurant/__manifest__.py b/addons/pos_restaurant/__manifest__.py index dc1a6149235..d4b234ee9d5 100644 --- a/addons/pos_restaurant/__manifest__.py +++ b/addons/pos_restaurant/__manifest__.py @@ -42,6 +42,7 @@ This module adds several features to the Point of Sale that are specific to rest 'static/src/xml/Screens/SplitBillScreen/SplitOrderline.xml', 'static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml', 'static/src/xml/Screens/ProductScreen/Orderline.xml', + 'static/src/xml/Screens/PaymentScreen/PaymentScreenElectronicPayment.xml', 'static/src/xml/Screens/FloorScreen/FloorScreen.xml', 'static/src/xml/Screens/FloorScreen/EditBar.xml', 'static/src/xml/Screens/FloorScreen/TableWidget.xml', diff --git a/addons/pos_restaurant/models/pos_order.py b/addons/pos_restaurant/models/pos_order.py index 10a8fe23885..6880b038153 100644 --- a/addons/pos_restaurant/models/pos_order.py +++ b/addons/pos_restaurant/models/pos_order.py @@ -95,6 +95,7 @@ class PosOrder(models.Model): 'pos_order_id', 'payment_method_id', 'card_type', + 'cardholder_name', 'transaction_id', 'payment_status' ] diff --git a/addons/pos_restaurant/static/src/js/Screens/PaymentScreen.js b/addons/pos_restaurant/static/src/js/Screens/PaymentScreen.js index 257f028f291..472f7cad6a8 100644 --- a/addons/pos_restaurant/static/src/js/Screens/PaymentScreen.js +++ b/addons/pos_restaurant/static/src/js/Screens/PaymentScreen.js @@ -2,10 +2,32 @@ odoo.define('pos_restaurant.PosResPaymentScreen', function (require) { 'use strict'; const PaymentScreen = require('point_of_sale.PaymentScreen'); + const { useListener } = require('web.custom_hooks'); const Registries = require('point_of_sale.Registries'); const PosResPaymentScreen = (PaymentScreen) => class extends PaymentScreen { + constructor() { + super(...arguments); + useListener('send-payment-adjust', this._sendPaymentAdjust); + } + + async _sendPaymentAdjust({ detail: line }) { + const previous_amount = line.get_amount(); + const amount_diff = line.order.get_total_with_tax() - line.order.get_total_paid(); + line.set_amount(previous_amount + amount_diff); + line.set_payment_status('waiting'); + + const payment_terminal = line.payment_method.payment_terminal; + const isAdjustSuccessful = await payment_terminal.send_payment_adjust(line.cid); + if (isAdjustSuccessful) { + line.set_payment_status('done'); + } else { + line.set_amount(previous_amount); + line.set_payment_status('done'); + } + } + get nextScreen() { const order = this.currentOrder; if (!this.env.pos.config.set_tip_after_payment || order.is_tipped) { @@ -13,7 +35,7 @@ odoo.define('pos_restaurant.PosResPaymentScreen', function (require) { } // Take the first payment method as the main payment. const mainPayment = order.get_paymentlines()[0]; - if (mainPayment.canBeTipped()) { + if (mainPayment.canBeAdjusted()) { return 'TipScreen'; } return super.nextScreen; diff --git a/addons/pos_restaurant/static/src/js/Screens/TicketScreen.js b/addons/pos_restaurant/static/src/js/Screens/TicketScreen.js index b3f7e128a81..83ca91882bf 100644 --- a/addons/pos_restaurant/static/src/js/Screens/TicketScreen.js +++ b/addons/pos_restaurant/static/src/js/Screens/TicketScreen.js @@ -73,6 +73,13 @@ odoo.define('pos_restaurant.TicketScreen', function (require) { } async setTip(order, serverId, amount) { try { + const paymentline = order.get_paymentlines()[0]; + if (paymentline.payment_method.payment_terminal) { + paymentline.amount += amount; + this.env.pos.set_order(order, {silent: true}); + await paymentline.payment_method.payment_terminal.send_payment_adjust(paymentline.cid); + } + if (!amount) { await this.setNoTip(); } else { diff --git a/addons/pos_restaurant/static/src/js/Screens/TipScreen.js b/addons/pos_restaurant/static/src/js/Screens/TipScreen.js index 84091103542..ae3561e233a 100644 --- a/addons/pos_restaurant/static/src/js/Screens/TipScreen.js +++ b/addons/pos_restaurant/static/src/js/Screens/TipScreen.js @@ -75,6 +75,12 @@ odoo.define('pos_restaurant.TipScreen', function (require) { order.set_tip(amount); order.finalized = true; + const paymentline = this.env.pos.get_order().get_paymentlines()[0]; + if (paymentline.payment_method.payment_terminal) { + paymentline.amount += amount; + await paymentline.payment_method.payment_terminal.send_payment_adjust(paymentline.cid); + } + // set_tip calls add_product which sets the new line as the selected_orderline const tip_line = order.selected_orderline; await this.rpc({ diff --git a/addons/pos_restaurant/static/src/js/floors.js b/addons/pos_restaurant/static/src/js/floors.js index 7e4d73271b0..d271f88fe39 100644 --- a/addons/pos_restaurant/static/src/js/floors.js +++ b/addons/pos_restaurant/static/src/js/floors.js @@ -381,11 +381,15 @@ models.PosModel = models.PosModel.extend({ var _super_paymentline = models.Paymentline.prototype; models.Paymentline = models.Paymentline.extend({ /** - * Override this method to be able to show the tip screen which allow + * Override this method to be able to show the 'Adjust Authorisation' button + * on a validated payment_line and to show the tip screen which allow * tipping even after payment. By default, this returns true for all * non-cash payment. */ - canBeTipped: function() { + canBeAdjusted: function() { + if (this.payment_method.payment_terminal) { + return this.payment_method.payment_terminal.canBeAdjusted(this.cid); + } return !this.payment_method.is_cash_count; }, }); diff --git a/addons/pos_restaurant/static/src/js/payment.js b/addons/pos_restaurant/static/src/js/payment.js new file mode 100644 index 00000000000..355d67425d2 --- /dev/null +++ b/addons/pos_restaurant/static/src/js/payment.js @@ -0,0 +1,24 @@ +odoo.define('pos_restaurant.PaymentInterface', function (require) { + "use strict"; + + var PaymentInterface = require('point_of_sale.PaymentInterface'); + + PaymentInterface.include({ + /** + * Return true if the amount that was authorized can be modified, + * false otherwise + * @param {string} cid - The id of the paymentline + */ + canBeAdjusted(cid) { + return false; + }, + + /** + * Called when the amount authorized by a payment request should + * be adjusted to account for a new order line, it can only be called if + * canBeAdjusted returns True + * @param {string} cid - The id of the paymentline + */ + send_payment_adjust: function (cid) {}, + }); +}); diff --git a/addons/pos_restaurant/static/src/xml/Screens/PaymentScreen/PaymentScreenElectronicPayment.xml b/addons/pos_restaurant/static/src/xml/Screens/PaymentScreen/PaymentScreenElectronicPayment.xml new file mode 100644 index 00000000000..11683ddbd12 --- /dev/null +++ b/addons/pos_restaurant/static/src/xml/Screens/PaymentScreen/PaymentScreenElectronicPayment.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="PaymentScreenElectronicPayment" t-inherit="point_of_sale.PaymentScreenElectronicPayment" t-inherit-mode="extension" owl="1"> + <xpath expr="//div[hasclass('send_payment_reversal')]/.." position="replace"> + <t t-if="props.line.canBeAdjusted() && props.line.order.get_total_paid() < props.line.order.get_total_with_tax()"> + <div class="button send_adjust_amount" title="Adjust Amount" t-on-click="trigger('send-payment-adjust', props.line)"> + Adjust Amount + </div> + </t> + <t t-elif="props.line.can_be_reversed"> + <div class="button send_payment_reversal" title="Reverse Payment" t-on-click="trigger('send-payment-reverse', props.line)"> + Reverse + </div> + </t> + </xpath> + </t> + +</templates> diff --git a/addons/pos_restaurant/views/pos_restaurant_templates.xml b/addons/pos_restaurant/views/pos_restaurant_templates.xml index e10b3b3cc6d..8f5727a9447 100644 --- a/addons/pos_restaurant/views/pos_restaurant_templates.xml +++ b/addons/pos_restaurant/views/pos_restaurant_templates.xml @@ -7,6 +7,7 @@ <script type="text/javascript" src="/pos_restaurant/static/src/js/multiprint.js"></script> <script type="text/javascript" src="/pos_restaurant/static/src/js/floors.js"></script> <script type="text/javascript" src="/pos_restaurant/static/src/js/notes.js"></script> + <script type="text/javascript" src="/pos_restaurant/static/src/js/payment.js"></script> <script type="text/javascript" src="/pos_restaurant/static/src/js/Resizeable.js"></script> <script type="text/javascript" src="/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/OrderlineNoteButton.js"></script> <script type="text/javascript" src="/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/TableGuestsButton.js"></script> diff --git a/addons/pos_restaurant_adyen/controllers/main.py b/addons/pos_restaurant_adyen/controllers/main.py index 5eef4aa18a0..32329293807 100644 --- a/addons/pos_restaurant_adyen/controllers/main.py +++ b/addons/pos_restaurant_adyen/controllers/main.py @@ -14,11 +14,6 @@ class PosRestaurantAdyenController(AdyenController): @http.route() def adyen_notification(self, **post): - if post.get('eventCode') == 'AUTHORISATION_ADJUSTMENT': - ref = post.get('originalReference') - payment = request.env['pos.payment'].sudo().search([('transaction_id', '=', ref)], limit=1) - if payment and post.get('success') == 'true': - payment._adyen_capture_tip() - else: - _logger.warning('Authorisation adjustment for transaction_id %s failed', ref) + if post.get('eventCode') in ['CAPTURE', 'AUTHORISATION_ADJUSTMENT'] and post.get('success') != 'true': + _logger.warning('%s for transaction_id %s failed', post.get('eventCode'), post.get('originalReference')) return super(PosRestaurantAdyenController, self).adyen_notification(**post) diff --git a/addons/pos_restaurant_adyen/models/pos_order.py b/addons/pos_restaurant_adyen/models/pos_order.py index f32a1af7418..f3b8553c8c8 100644 --- a/addons/pos_restaurant_adyen/models/pos_order.py +++ b/addons/pos_restaurant_adyen/models/pos_order.py @@ -7,10 +7,10 @@ from odoo import models class PosOrder(models.Model): _inherit = 'pos.order' - def set_no_tip(self): - """Capture the Adyen payment when no tip is set.""" - self.ensure_one() - payment_line = self.payment_ids.filtered(lambda line: not line.is_change)[0] - if payment_line.payment_method_id.use_payment_terminal == 'adyen': - payment_line._adyen_capture_tip() - return super(PosOrder, self).set_no_tip() + def action_pos_order_paid(self): + res = super(PosOrder, self).action_pos_order_paid() + if not self.config_id.set_tip_after_payment: + payment_lines = self.payment_ids.filtered(lambda line: line.payment_method_id.use_payment_terminal == 'adyen') + for payment_line in payment_lines: + payment_line._adyen_capture() + return res diff --git a/addons/pos_restaurant_adyen/models/pos_payment.py b/addons/pos_restaurant_adyen/models/pos_payment.py index 8a067022b3e..5f38d0159f3 100644 --- a/addons/pos_restaurant_adyen/models/pos_payment.py +++ b/addons/pos_restaurant_adyen/models/pos_payment.py @@ -13,22 +13,13 @@ class PosPayment(models.Model): _inherit = 'pos.payment' def _update_payment_line_for_tip(self, tip_amount): - """Capture the correct amount when a tip is set.""" + """Capture the payment when a tip is set.""" res = super(PosPayment, self)._update_payment_line_for_tip(tip_amount) if self.payment_method_id.use_payment_terminal == 'adyen': - self._adyen_capture_tip(True) + self._adyen_capture() return res - def _adyen_capture_tip(self, adjust_authorisation=False): - endpoint = 'https://pal-live.adyen.com/pal/servlet/Payment/v52/' - if self.payment_method_id.adyen_test_mode: - endpoint = 'https://pal-test.adyen.com/pal/servlet/Payment/v52/' - - headers = { - 'x-api-key': self.payment_method_id.adyen_api_key, - 'Content-Type': 'application/json' - } - + def _adyen_capture(self): data = { 'originalReference': self.transaction_id, 'modificationAmount': { @@ -38,15 +29,10 @@ class PosPayment(models.Model): 'merchantAccount': self.payment_method_id.adyen_merchant_account, } - if adjust_authorisation: - endpoint += 'adjustAuthorisation' - data['additionalData'] = { - 'industryUsage':'DelayedCharge' - } - else: - endpoint += 'capture' - - req = requests.post(endpoint, data=json.dumps(data), headers=headers, timeout=TIMEOUT) - - if not req.ok: - raise Exception('An error occured while capturing the payment') + return self.payment_method_id.proxy_adyen_request( + data, + self.payment_method_id.adyen_test_mode, + self.payment_method_id.adyen_api_key, + 'https://pal-test.adyen.com/pal/servlet/Payment/v52/capture', + 'https://pal-live.adyen.com/pal/servlet/Payment/v52/capture', + ) diff --git a/addons/pos_restaurant_adyen/static/src/js/models.js b/addons/pos_restaurant_adyen/static/src/js/models.js new file mode 100644 index 00000000000..0c6e9fb7cdd --- /dev/null +++ b/addons/pos_restaurant_adyen/static/src/js/models.js @@ -0,0 +1,5 @@ +odoo.define('pos_restaurant_adyen.models', function (require) { + var models = require('point_of_sale.models'); + + models.load_fields('pos.payment.method', ['adyen_merchant_account']); +}); diff --git a/addons/pos_restaurant_adyen/static/src/js/payment_adyen.js b/addons/pos_restaurant_adyen/static/src/js/payment_adyen.js index 531311b09cb..d94e990fdf3 100644 --- a/addons/pos_restaurant_adyen/static/src/js/payment_adyen.js +++ b/addons/pos_restaurant_adyen/static/src/js/payment_adyen.js @@ -8,21 +8,41 @@ odoo.define('pos_restaurant_adyen.payment', function (require) { _adyen_pay_data: function () { var data = this._super(); - if (this.pos.config.set_tip_after_payment) { + if (data.SaleToPOIRequest.PaymentRequest.SaleData.SaleToAcquirerData) { + data.SaleToPOIRequest.PaymentRequest.SaleData.SaleToAcquirerData += "&authorisationType=PreAuth"; + } else { data.SaleToPOIRequest.PaymentRequest.SaleData.SaleToAcquirerData = "authorisationType=PreAuth"; } return data; }, - }); - var paymentline_super = models.Paymentline.prototype; - models.Paymentline = models.Paymentline.extend({ - canBeTipped: function () { - if (this.payment_method.use_payment_terminal === 'adyen') { - return ['mc', 'visa', 'amex', 'discover'].includes(this.card_type); - } - return paymentline_super.canBeTipped.apply(this); + send_payment_adjust: function (cid) { + var order = this.pos.get_order(); + var line = order.get_paymentline(cid); + var data = { + originalReference: line.transaction_id, + modificationAmount: { + value: parseInt(line.amount * Math.pow(10, this.pos.currency.decimals)), + currency: this.pos.currency.name, + }, + merchantAccount: this.payment_method.adyen_merchant_account, + additionalData: { + industryUsage: 'DelayedCharge', + }, + }; + + return this._call_adyen( + data, + 'https://pal-test.adyen.com/pal/servlet/Payment/v52/adjustAuthorisation', + 'https://pal-live.adyen.com/pal/servlet/Payment/v52/adjustAuthorisation', + ); }, + + canBeAdjusted: function (cid) { + var order = this.pos.get_order(); + var line = order.get_paymentline(cid); + return ['mc', 'visa', 'amex', 'discover'].includes(line.card_type); + } }); }); diff --git a/addons/pos_restaurant_adyen/views/point_of_sale_assets.xml b/addons/pos_restaurant_adyen/views/point_of_sale_assets.xml index 69462495b5b..03533b1d4dc 100644 --- a/addons/pos_restaurant_adyen/views/point_of_sale_assets.xml +++ b/addons/pos_restaurant_adyen/views/point_of_sale_assets.xml @@ -2,6 +2,7 @@ <odoo> <template id="assets" inherit_id="point_of_sale.assets"> <xpath expr="." position="inside"> + <script type="text/javascript" src="/pos_restaurant_adyen/static/src/js/models.js"></script> <script type="text/javascript" src="/pos_restaurant_adyen/static/src/js/payment_adyen.js"></script> </xpath> </template> |
