[ADD] pos_six: Six payment terminals with TIM
Deprecate MPD integration for Six payment terminals and replace it with TIM because: - MPD broadcasts connection messages to the network so having multiple terminals and MPD servers in the same network results in connection issues - TIM has a JS SDK so it doesn't require an IoT Box. - MPD supports only Yomani and Yoximo terminals while TIM also supports Ingenico. closes odoo/odoo#46789 Taskid: 2188566 Related: odoo/upgrade#903 Related: odoo/enterprise#8994 Signed-off-by: pimodoo <pimodoo@users.noreply.github.com>
This commit is contained in:
@@ -627,6 +627,11 @@ file_filter = addons/pos_sale/i18n/<lang>.po
|
||||
source_file = addons/pos_sale/i18n/pos_sale.pot
|
||||
source_lang = en
|
||||
|
||||
[odoo-master.pos_six]
|
||||
file_filter = addons/pos_six/i18n/<lang>.po
|
||||
source_file = addons/pos_six/i18n/pos_six.pot
|
||||
source_lang = en
|
||||
|
||||
[odoo-master.procurement_jit]
|
||||
file_filter = addons/procurement_jit/i18n/<lang>.po
|
||||
source_file = addons/procurement_jit/i18n/procurement_jit.pot
|
||||
|
||||
@@ -9,6 +9,7 @@ class ResConfigSettings(models.TransientModel):
|
||||
sale_tax_id = fields.Many2one('account.tax', string="Default Sale Tax", related='company_id.account_sale_tax_id', readonly=False)
|
||||
module_pos_mercury = fields.Boolean(string="Vantiv Payment Terminal", help="The transactions are processed by Vantiv. Set your Vantiv credentials on the related payment method.")
|
||||
module_pos_adyen = fields.Boolean(string="Adyen Payment Terminal", help="The transactions are processed by Adyen. Set your Adyen credentials on the related payment method.")
|
||||
module_pos_six = fields.Boolean(string="Six Payment Terminal", help="The transactions are processed by Six. Set the IP address of the terminal on the related payment method.")
|
||||
update_stock_quantities = fields.Selection(related="company_id.point_of_sale_update_stock_quantities", readonly=False)
|
||||
|
||||
def set_values(self):
|
||||
|
||||
@@ -138,6 +138,18 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" title="The transactions are processed by Six. Set the IP address of the terminal on the related payment method.">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_pos_six"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="module_pos_six" string="Six"/>
|
||||
<a href="https://www.odoo.com/documentation/user/13.0/point_of_sale/payment/six.html" title="Documentation" class="o_doc_link" target="_blank"></a>
|
||||
<div class="text-muted">
|
||||
Accept payments with a Six payment terminal
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# coding: utf-8
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import models
|
||||
@@ -0,0 +1,17 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
{
|
||||
'name': 'POS Six',
|
||||
'version': '1.0',
|
||||
'category': 'Sales/Point Of Sale',
|
||||
'sequence': 6,
|
||||
'summary': 'Integrate your POS with a Six payment terminal',
|
||||
'description': '',
|
||||
'data': [
|
||||
'views/pos_payment_method_views.xml',
|
||||
'views/point_of_sale_assets.xml',
|
||||
],
|
||||
'depends': ['point_of_sale'],
|
||||
'installable': True,
|
||||
'license': 'OEEL-1',
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * pos_six
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 13.0+e\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-02-25 08:44+0000\n"
|
||||
"PO-Revision-Date: 2020-02-25 08:44+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: pos_six
|
||||
#: model:ir.model,name:pos_six.model_pos_payment_method
|
||||
msgid "Point of Sale Payment Methods"
|
||||
msgstr ""
|
||||
|
||||
#. module: pos_six
|
||||
#: model:ir.model.fields,field_description:pos_six.field_pos_payment_method__six_terminal_ip
|
||||
msgid "Six Terminal IP"
|
||||
msgstr ""
|
||||
|
||||
#. module: pos_six
|
||||
#. openerp-web
|
||||
#: code:addons/pos_six/static/src/js/payment_six.js:0
|
||||
#, python-format
|
||||
msgid "Terminal Error"
|
||||
msgstr ""
|
||||
|
||||
#. module: pos_six
|
||||
#. openerp-web
|
||||
#: code:addons/pos_six/static/src/js/payment_six.js:0
|
||||
#, python-format
|
||||
msgid "Transaction was not processed correctly"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,4 @@
|
||||
# coding: utf-8
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import pos_payment_method
|
||||
@@ -0,0 +1,13 @@
|
||||
# coding: utf-8
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class PosPaymentMethod(models.Model):
|
||||
_inherit = 'pos.payment.method'
|
||||
|
||||
def _get_payment_terminal_selection(self):
|
||||
return super(PosPaymentMethod, self)._get_payment_terminal_selection() + [('six', 'SIX')]
|
||||
|
||||
six_terminal_ip = fields.Char('Six Terminal IP')
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,9 @@
|
||||
odoo.define('pos_six.models', function (require) {
|
||||
|
||||
var models = require('point_of_sale.models');
|
||||
var PaymentSix = require('pos_six.payment');
|
||||
|
||||
models.register_payment_method('six', PaymentSix);
|
||||
models.load_fields('pos.payment.method', ['six_terminal_ip']);
|
||||
|
||||
});
|
||||
@@ -0,0 +1,134 @@
|
||||
odoo.define('pos_six.payment', function (require) {
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
var PaymentInterface = require('point_of_sale.PaymentInterface');
|
||||
|
||||
var _t = core._t;
|
||||
|
||||
var PaymentSix = PaymentInterface.extend({
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
init: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.enable_reversals();
|
||||
|
||||
var settings = new timapi.TerminalSettings();
|
||||
settings.connectionMode = timapi.constants.ConnectionMode.onFixIp;
|
||||
settings.connectionIPString = this.payment_method.six_terminal_ip;
|
||||
settings.connectionIPPort = "80";
|
||||
|
||||
this.terminal = new timapi.Terminal(settings);
|
||||
this.terminal.posId = this.pos.pos_session.name;
|
||||
this.terminal.userId = this.pos.pos_session.user_id[0];
|
||||
|
||||
this.terminalListener = new timapi.DefaultTerminalListener();
|
||||
this.terminalListener.transactionCompleted = this._onTransactionComplete.bind(this);
|
||||
this.terminal.addListener(this.terminalListener);
|
||||
|
||||
var recipients = [timapi.constants.Recipient.merchant, timapi.constants.Recipient.cardholder];
|
||||
var options = [];
|
||||
_.forEach(recipients, (recipient) => {
|
||||
var option = new timapi.PrintOption(
|
||||
recipient,
|
||||
timapi.constants.PrintFormat.normal,
|
||||
45,
|
||||
[timapi.constants.PrintFlag.suppressHeader, timapi.constants.PrintFlag.suppressEcrInfo]
|
||||
);
|
||||
options.push(option);
|
||||
});
|
||||
this.terminal.printOptions = options;
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
send_payment_cancel: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.terminal.cancel();
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
send_payment_request: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.pos.get_order().selected_paymentline.set_payment_status('waitingCard');
|
||||
return this._sendTransaction(timapi.constants.TransactionType.purchase);
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
send_payment_reversal: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.pos.get_order().selected_paymentline.set_payment_status('reversing');
|
||||
return this._sendTransaction(timapi.constants.TransactionType.reversal);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
_onTransactionComplete: function (event, data) {
|
||||
timapi.DefaultTerminalListener.prototype.transactionCompleted(event, data);
|
||||
|
||||
if (event.exception) {
|
||||
this.pos.gui.show_popup('error', {
|
||||
title: _t('Terminal Error'),
|
||||
body: _t('Transaction was not processed correctly'),
|
||||
});
|
||||
|
||||
this.transactionResolve();
|
||||
} else {
|
||||
if (data.printData){
|
||||
this._printReceipts(data.printData.receipts)
|
||||
}
|
||||
|
||||
// Store Transaction Data
|
||||
var transactionData = new timapi.TransactionData();
|
||||
transactionData.transSeq = data.transactionInformation.transSeq;
|
||||
this.terminal.transactionData = transactionData;
|
||||
|
||||
this.transactionResolve(true);
|
||||
}
|
||||
},
|
||||
|
||||
_printReceipts: function (receipts) {
|
||||
_.forEach(receipts, (receipt) => {
|
||||
var value = receipt.value.replace(/\n/g, "<br />");
|
||||
if (receipt.recipient === timapi.constants.Recipient.merchant && this.pos.proxy.printer) {
|
||||
this.pos.proxy.printer.print_receipt(
|
||||
"<div class='pos-receipt'><div class='pos-payment-terminal-receipt'>" +
|
||||
value +
|
||||
"</div></div>"
|
||||
);
|
||||
} else if (receipt.recipient === timapi.constants.Recipient.cardholder) {
|
||||
this.pos.get_order().selected_paymentline.set_receipt_info(value);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_sendTransaction: function (transactionType) {
|
||||
var amount = new timapi.Amount(
|
||||
this.pos.get_order().selected_paymentline.amount,
|
||||
timapi.constants.Currency[this.pos.currency.name]
|
||||
);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
this.transactionResolve = resolve;
|
||||
this.terminal.transactionAsync(transactionType, amount);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return PaymentSix;
|
||||
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="assets" inherit_id="point_of_sale.assets">
|
||||
<xpath expr="." position="inside">
|
||||
<script type="text/javascript" src="/pos_six/static/lib/six_timapi/timapi.bundle.js"></script>
|
||||
<script type="text/javascript" src="/pos_six/static/src/js/models.js"></script>
|
||||
<script type="text/javascript" src="/pos_six/static/src/js/payment_six.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="pos_payment_method_view_form_inherit_pos_adyen" model="ir.ui.view">
|
||||
<field name="name">pos.payment.method.form.inherit.adyen</field>
|
||||
<field name="model">pos.payment.method</field>
|
||||
<field name="inherit_id" ref="point_of_sale.pos_payment_method_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='use_payment_terminal']" position="after">
|
||||
<field name="six_terminal_ip"
|
||||
attrs="{'invisible': [('use_payment_terminal', '!=', 'six')], 'required': [('use_payment_terminal', '=', 'six')]}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user