diff options
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> |
