Skip to content
Snippets Groups Projects
Commit 12fd8c37 authored by Antoine Prieels's avatar Antoine Prieels
Browse files

[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: default avatarpimodoo <pimodoo@users.noreply.github.com>
parent 6413ef69
No related branches found
No related tags found
No related merge requests found
Showing with 37175 additions and 0 deletions
......@@ -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>
......
# coding: utf-8
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import models
# -*- 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',
}
# 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 ""
# coding: utf-8
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import pos_payment_method
# 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')
This diff is collapsed.
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']);
});
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;
});
<?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>
<?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>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment