Browse Source

Merge pull request #30 from akretion/8.0-pos_payment_terminal-code-simplify

pos_payment_terminal + pos_customer_display: simplify JS code
pull/37/head
Alexis de Lattre 9 years ago
parent
commit
fe0842e942
  1. 4
      hw_customer_display/controllers/main.py
  2. 24
      hw_telium_payment_terminal/controllers/main.py
  3. 19
      hw_telium_payment_terminal/test-scripts/telium-test.py
  4. 8
      pos_customer_display/customer_display_view.xml
  5. 81
      pos_customer_display/i18n/fr.po
  6. 71
      pos_customer_display/i18n/pos_customer_display.pot
  7. 47
      pos_customer_display/pos_customer_display.py
  8. 239
      pos_customer_display/static/src/js/customer_display.js
  9. 55
      pos_payment_terminal/README.rst
  10. 24
      pos_payment_terminal/__openerp__.py
  11. 5
      pos_payment_terminal/pos_payment_terminal.py
  12. 4
      pos_payment_terminal/pos_payment_terminal_demo.xml
  13. 54
      pos_payment_terminal/static/src/js/pos_payment_terminal.js

4
hw_customer_display/controllers/main.py

@ -174,5 +174,7 @@ class CustomerDisplayProxy(hw_proxy.Proxy):
'/hw_proxy/send_text_customer_display', type='json', auth='none',
cors='*')
def send_text_customer_display(self, text_to_display):
logger.debug('LCD: Call send_text_customer_display')
logger.debug(
'LCD: Call send_text_customer_display with text=%s',
text_to_display)
driver.push_task('display', text_to_display)

24
hw_telium_payment_terminal/controllers/main.py

@ -156,16 +156,15 @@ class TeliumPaymentTerminalDriver(Thread):
'''We use protocol E+'''
ascii_names = curses.ascii.controlnames
real_msg = (
data['pos_number']
+ data['amount_msg']
+ data['answer_flag']
+ data['payment_mode']
+ data['transaction_type']
+ data['currency_numeric']
+ data['private']
+ data['delay']
+ data['auto']
)
data['pos_number'] +
data['amount_msg'] +
data['answer_flag'] +
data['payment_mode'] +
data['transaction_type'] +
data['currency_numeric'] +
data['private'] +
data['delay'] +
data['auto'])
logger.debug('Real message to send = %s' % real_msg)
assert len(real_msg) == 34, 'Wrong length for protocol E+'
real_msg_with_etx = real_msg + chr(ascii_names.index('ETX'))
@ -224,7 +223,6 @@ class TeliumPaymentTerminalDriver(Thread):
payment_info_dict = simplejson.loads(payment_info)
assert isinstance(payment_info_dict, dict), \
'payment_info_dict should be a dict'
logger.debug("payment_info_dict = %s" % payment_info_dict)
try:
logger.debug(
'Opening serial port %s for payment terminal with baudrate %d'
@ -280,5 +278,7 @@ class TeliumPaymentTerminalProxy(hw_proxy.Proxy):
'/hw_proxy/payment_terminal_transaction_start',
type='json', auth='none', cors='*')
def payment_terminal_transaction_start(self, payment_info):
logger.debug('Telium: Call payment_terminal_transaction_start')
logger.debug(
'Telium: Call payment_terminal_transaction_start with '
'payment_info=%s', payment_info)
driver.push_task('transaction_start', payment_info)

19
hw_telium_payment_terminal/test-scripts/telium-test.py

@ -115,16 +115,15 @@ def send_message(serial, data):
'''We use protocol E+'''
ascii_names = curses.ascii.controlnames
real_msg = (
data['pos_number']
+ data['amount_msg']
+ data['answer_flag']
+ data['payment_mode']
+ data['transaction_type']
+ data['currency_numeric']
+ data['private']
+ data['delay']
+ data['auto']
)
data['pos_number'] +
data['amount_msg'] +
data['answer_flag'] +
data['payment_mode'] +
data['transaction_type'] +
data['currency_numeric'] +
data['private'] +
data['delay'] +
data['auto'])
print 'Real message to send = %s' % real_msg
assert len(real_msg) == 34, 'Wrong length for protocol E+'
real_msg_with_etx = real_msg + chr(ascii_names.index('ETX'))

8
pos_customer_display/customer_display_view.xml

@ -10,6 +10,14 @@
<field name="iface_customer_display"/>
<field name="customer_display_line_length"/>
</field>
<group string="Receipt" position="after">
<group name="customer_display" string="Customer Display">
<field name="customer_display_msg_next_l1"/>
<field name="customer_display_msg_next_l2"/>
<field name="customer_display_msg_closed_l1"/>
<field name="customer_display_msg_closed_l2"/>
</group>
</group>
</field>
</record>
</data>

81
pos_customer_display/i18n/fr.po

@ -6,30 +6,41 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-05-16 23:24+0000\n"
"PO-Revision-Date: 2015-05-16 23:24+0000\n"
"Last-Translator: Alexis de Lattre <alexis.delattre@akretion.com>\n"
"POT-Creation-Date: 2015-06-13 22:12+0000\n"
"PO-Revision-Date: 2015-06-13 22:12+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_customer_display
#: help:pos.config,customer_display_msg_next_l2:0
msgid "Bottom line of the message on the customer display which is displayed after starting POS and also after validation of an order"
msgstr "Ligne du bas du message de l'afficheur client qui est affiché après le démarrage de la caisse et également après validation d'une commande client"
#. module: pos_customer_display
#: help:pos.config,customer_display_msg_closed_l2:0
msgid "Bottom line of the message on the customer display which is displayed when POS is closed"
msgstr "Ligne du bas du message de l'afficheur client qui est affiché quand la caisse est fermée"
#. module: pos_customer_display
#. openerp-web
#: code:addons/pos_customer_display/static/src/js/customer_display.js:58
#: code:addons/pos_customer_display/static/src/js/customer_display.js:56
#, python-format
msgid "Cancel Payment"
msgstr "Paiement annulé"
#. module: pos_customer_display
#: view:pos.config:pos_customer_display.view_pos_config_form2
#: field:pos.config,iface_customer_display:0
msgid "Customer Display"
msgstr "Afficheur client"
#. module: pos_customer_display
#. openerp-web
#: code:addons/pos_customer_display/static/src/js/customer_display.js:42
#: code:addons/pos_customer_display/static/src/js/customer_display.js:41
#, python-format
msgid "Delete Item"
msgstr "Article supprimé"
@ -53,40 +64,68 @@ msgstr "Longueur des lignes de l'afficheur client: nombre de caractères"
#. module: pos_customer_display
#: field:pos.config,customer_display_line_length:0
msgid "Line Length"
msgstr "Longueur des lignes"
msgid "Line Length of the Customer Display"
msgstr "Longueur de ligne de l'afficheur client"
#. module: pos_customer_display
#. openerp-web
#: code:addons/pos_customer_display/static/src/js/customer_display.js:71
#: code:addons/pos_customer_display/pos_customer_display.py:63
#: field:pos.config,customer_display_msg_next_l2:0
#, python-format
msgid "Next Customer"
msgstr "Client suivant"
msgid "Next Customer (bottom line)"
msgstr "Client suivant (ligne du bas)"
#. module: pos_customer_display
#. openerp-web
#: code:addons/pos_customer_display/static/src/js/customer_display.js:83
#: code:addons/pos_customer_display/pos_customer_display.py:62
#: field:pos.config,customer_display_msg_next_l1:0
#, python-format
msgid "Point of Sale Closed"
msgstr "Caisse fermée"
msgid "Next Customer (top line)"
msgstr "Client suivant (ligne du haut)"
#. module: pos_customer_display
#. openerp-web
#: code:addons/pos_customer_display/static/src/js/customer_display.js:77
#: code:addons/pos_customer_display/pos_customer_display.py:66
#: field:pos.config,customer_display_msg_closed_l2:0
#, python-format
msgid "POS Closed (bottom line)"
msgstr "Caisse fermée (ligne du bas)"
#. module: pos_customer_display
#: code:addons/pos_customer_display/pos_customer_display.py:65
#: field:pos.config,customer_display_msg_closed_l1:0
#, python-format
msgid "Point of Sale Open"
msgstr "Caisse ouverte"
msgid "POS Closed (top line)"
msgstr "Caisse fermée (ligne du haut)"
#. module: pos_customer_display
#: view:pos.config:pos_customer_display.view_pos_config_form2
msgid "Receipt"
msgstr "Reçu"
#. module: pos_customer_display
#. openerp-web
#: code:addons/pos_customer_display/static/src/js/customer_display.js:50
#: code:addons/pos_customer_display/static/src/js/customer_display.js:48
#, python-format
msgid "TOTAL: "
msgstr "TOTAL : "
#. module: pos_customer_display
#: code:addons/pos_customer_display/pos_customer_display.py:72
#, python-format
msgid "The message for customer display '%s' is too long: it has %d chars whereas the maximum is %d chars."
msgstr "Le message de l'afficheur client '%s' est trop long : il contient %d caractères alors que le maximum est de %d caractères."
#. module: pos_customer_display
#: help:pos.config,customer_display_msg_next_l1:0
msgid "Top line of the message on the customer display which is displayed after starting POS and also after validation of an order"
msgstr "Ligne du haut du message de l'afficheur client qui est affiché après le démarrage de la caisse et également après validation d'une commande client"
#. module: pos_customer_display
#: help:pos.config,customer_display_msg_closed_l1:0
msgid "Top line of the message on the customer display which is displayed when POS is closed"
msgstr "Ligne du haut du message de l'afficheur client qui est affiché quand la caisse est fermée"
#. module: pos_customer_display
#. openerp-web
#: code:addons/pos_customer_display/static/src/js/customer_display.js:65
#: code:addons/pos_customer_display/static/src/js/customer_display.js:63
#, python-format
msgid "Your Change:"
msgstr "Monnaie à rendre :"

71
pos_customer_display/i18n/pos_customer_display.pot

@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-05-16 23:24+0000\n"
"PO-Revision-Date: 2015-05-16 23:24+0000\n"
"POT-Creation-Date: 2015-06-13 22:11+0000\n"
"PO-Revision-Date: 2015-06-13 22:11+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@ -15,21 +15,32 @@ msgstr ""
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: pos_customer_display
#: help:pos.config,customer_display_msg_next_l2:0
msgid "Bottom line of the message on the customer display which is displayed after starting POS and also after validation of an order"
msgstr ""
#. module: pos_customer_display
#: help:pos.config,customer_display_msg_closed_l2:0
msgid "Bottom line of the message on the customer display which is displayed when POS is closed"
msgstr ""
#. module: pos_customer_display
#. openerp-web
#: code:addons/pos_customer_display/static/src/js/customer_display.js:58
#: code:addons/pos_customer_display/static/src/js/customer_display.js:56
#, python-format
msgid "Cancel Payment"
msgstr ""
#. module: pos_customer_display
#: view:pos.config:pos_customer_display.view_pos_config_form2
#: field:pos.config,iface_customer_display:0
msgid "Customer Display"
msgstr ""
#. module: pos_customer_display
#. openerp-web
#: code:addons/pos_customer_display/static/src/js/customer_display.js:42
#: code:addons/pos_customer_display/static/src/js/customer_display.js:41
#, python-format
msgid "Delete Item"
msgstr ""
@ -53,40 +64,68 @@ msgstr ""
#. module: pos_customer_display
#: field:pos.config,customer_display_line_length:0
msgid "Line Length"
msgid "Line Length of the Customer Display"
msgstr ""
#. module: pos_customer_display
#. openerp-web
#: code:addons/pos_customer_display/static/src/js/customer_display.js:71
#: code:addons/pos_customer_display/pos_customer_display.py:63
#: field:pos.config,customer_display_msg_next_l2:0
#, python-format
msgid "Next Customer"
msgid "Next Customer (bottom line)"
msgstr ""
#. module: pos_customer_display
#. openerp-web
#: code:addons/pos_customer_display/static/src/js/customer_display.js:83
#: code:addons/pos_customer_display/pos_customer_display.py:62
#: field:pos.config,customer_display_msg_next_l1:0
#, python-format
msgid "Point of Sale Closed"
msgid "Next Customer (top line)"
msgstr ""
#. module: pos_customer_display
#. openerp-web
#: code:addons/pos_customer_display/static/src/js/customer_display.js:77
#: code:addons/pos_customer_display/pos_customer_display.py:66
#: field:pos.config,customer_display_msg_closed_l2:0
#, python-format
msgid "POS Closed (bottom line)"
msgstr ""
#. module: pos_customer_display
#: code:addons/pos_customer_display/pos_customer_display.py:65
#: field:pos.config,customer_display_msg_closed_l1:0
#, python-format
msgid "Point of Sale Open"
msgid "POS Closed (top line)"
msgstr ""
#. module: pos_customer_display
#: view:pos.config:pos_customer_display.view_pos_config_form2
msgid "Receipt"
msgstr ""
#. module: pos_customer_display
#. openerp-web
#: code:addons/pos_customer_display/static/src/js/customer_display.js:50
#: code:addons/pos_customer_display/static/src/js/customer_display.js:48
#, python-format
msgid "TOTAL: "
msgstr ""
#. module: pos_customer_display
#: code:addons/pos_customer_display/pos_customer_display.py:72
#, python-format
msgid "The message for customer display '%s' is too long: it has %d chars whereas the maximum is %d chars."
msgstr ""
#. module: pos_customer_display
#: help:pos.config,customer_display_msg_next_l1:0
msgid "Top line of the message on the customer display which is displayed after starting POS and also after validation of an order"
msgstr ""
#. module: pos_customer_display
#: help:pos.config,customer_display_msg_closed_l1:0
msgid "Top line of the message on the customer display which is displayed when POS is closed"
msgstr ""
#. module: pos_customer_display
#. openerp-web
#: code:addons/pos_customer_display/static/src/js/customer_display.js:65
#: code:addons/pos_customer_display/static/src/js/customer_display.js:63
#, python-format
msgid "Your Change:"
msgstr ""

47
pos_customer_display/pos_customer_display.py

@ -21,7 +21,8 @@
#
##############################################################################
from openerp import models, fields
from openerp import models, fields, api, _
from openerp.exceptions import ValidationError
class PosConfig(models.Model):
@ -30,5 +31,47 @@ class PosConfig(models.Model):
iface_customer_display = fields.Boolean(
string='Customer Display', help="Display data on the customer display")
customer_display_line_length = fields.Integer(
string='Line Length', default=20,
string='Line Length of the Customer Display', default=20,
help="Length of the LEDs lines of the customer display")
customer_display_msg_next_l1 = fields.Char(
string="Next Customer (top line)", default="Welcome!",
help="Top line of the message on the customer display which is "
"displayed after starting POS and also after validation of an order")
customer_display_msg_next_l2 = fields.Char(
string="Next Customer (bottom line)", default="Point of Sale Open",
help="Bottom line of the message on the customer display which is "
"displayed after starting POS and also after validation of an order")
customer_display_msg_closed_l1 = fields.Char(
string="POS Closed (top line)", default="Point of Sale Closed",
help="Top line of the message on the customer display which "
"is displayed when POS is closed")
customer_display_msg_closed_l2 = fields.Char(
string="POS Closed (bottom line)", default="See you soon!",
help="Bottom line of the message on the customer display which "
"is displayed when POS is closed")
@api.one
@api.constrains(
'customer_display_line_length',
'customer_display_msg_next_l1', 'customer_display_msg_next_l2',
'customer_display_msg_closed_l1', 'customer_display_msg_closed_l2')
def _check_customer_display_length(self):
if self.customer_display_line_length:
maxsize = self.customer_display_line_length
to_check = {
_('Next Customer (top line)'):
self.customer_display_msg_next_l1,
_('Next Customer (bottom line)'):
self.customer_display_msg_next_l2,
_('POS Closed (top line)'):
self.customer_display_msg_closed_l1,
_('POS Closed (bottom line)'):
self.customer_display_msg_closed_l2,
}
for field, msg in to_check.iteritems():
if msg and len(msg) > maxsize:
raise ValidationError(
_("The message for customer display '%s' is too "
"long: it has %d chars whereas the maximum "
"is %d chars.")
% (field, len(msg), maxsize))

239
pos_customer_display/static/src/js/customer_display.js

@ -12,7 +12,7 @@ openerp.pos_customer_display = function(instance){
module = instance.point_of_sale;
var _t = instance.web._t;
var PosModelSuper = module.PosModel;
module.PosModel = module.PosModel.extend({
prepare_text_customer_display: function(type, data){
@ -66,20 +66,20 @@ openerp.pos_customer_display = function(instance){
} else if (type == 'pushOrder') {
var lines_to_send = new Array(
this.proxy.align_center(_t("Next Customer"), line_length),
this.proxy.align_left(' ', line_length)
this.proxy.align_center(this.config.customer_display_msg_next_l1, line_length),
this.proxy.align_center(this.config.customer_display_msg_next_l2, line_length)
);
} else if (type == 'openPOS') {
var lines_to_send = new Array(
this.proxy.align_center(_t("Point of Sale Open"), line_length),
this.proxy.align_left(' ', line_length)
this.proxy.align_center(this.config.customer_display_msg_next_l1, line_length),
this.proxy.align_center(this.config.customer_display_msg_next_l2, line_length)
);
} else if (type = 'closePOS') {
var lines_to_send = new Array(
this.proxy.align_center(_t("Point of Sale Closed"), line_length),
this.proxy.align_left(' ', line_length)
this.proxy.align_center(this.config.customer_display_msg_closed_l1, line_length),
this.proxy.align_center(this.config.customer_display_msg_closed_l2, line_length)
);
} else {
console.warn('Unknown message type');
@ -90,6 +90,14 @@ openerp.pos_customer_display = function(instance){
//console.log('prepare_text_customer_display type=' + type + ' | l1=' + lines_to_send[0] + ' | l2=' + lines_to_send[1]);
},
push_order: function(order){
res = PosModelSuper.prototype.push_order.call(this, order);
if (order) {
this.prepare_text_customer_display('pushOrder', {'order' : order});
}
return res;
},
});
@ -106,144 +114,143 @@ openerp.pos_customer_display = function(instance){
align_left: function(string, length){
if (string) {
if (string.length > length)
{
return string.substring(0,length);
}
else if (string.length < length)
{
if (string.length > length)
{
string = string.substring(0,length);
}
else if (string.length < length)
{
while(string.length < length)
string = string + ' ';
return string;
}
string = string + ' ';
}
}
else {
string = ' '
while(string.length < length)
string = ' ' + string;
}
return string;
},
align_right: function(string, length){
align_right: function(string, length){
if (string) {
if (string.length > length)
{
return string.substring(0,length);
}
else if (string.length < length)
{
{
string = string.substring(0,length);
}
else if (string.length < length)
{
while(string.length < length)
string = ' ' + string;
return string;
string = ' ' + string;
}
}
return string;
},
}
else {
string = ' '
while(string.length < length)
string = ' ' + string;
}
return string;
},
align_center: function(string, length){
align_center: function(string, length){
if (string) {
if (string.length > length)
{
return string.substring(0, length);
string = string.substring(0, length);
}
else if (string.length < length)
{
ini = (length - string.length) / 2;
while(string.length < length - ini)
string = ' ' + string;
while(string.length < length)
string = string + ' ';
return string;
ini = (length - string.length) / 2;
while(string.length < length - ini)
string = ' ' + string;
while(string.length < length)
string = string + ' ';
}
}
return string;
},
}
else {
string = ' '
while(string.length < length)
string = ' ' + string;
}
return string;
},
});
var _super_addProduct_ = module.Order.prototype.addProduct;
module.Order.prototype.addProduct = function(product, options){
res = _super_addProduct_.call(this, product, options);
if (product) {
this.pos.prepare_text_customer_display('addProduct', {'product' : product, 'options' : options});
}
return res;
};
var OrderSuper = module.Order;
var _super_removeOrderline_ = module.Order.prototype.removeOrderline;
module.Order.prototype.removeOrderline = function(line){
if (line) {
this.pos.prepare_text_customer_display('removeOrderline', {'line' : line});
}
return _super_removeOrderline_.call(this, line);
};
module.Order = module.Order.extend({
addProduct: function(product, options){
res = OrderSuper.prototype.addProduct.call(this, product, options);
if (product) {
this.pos.prepare_text_customer_display('addProduct', {'product' : product, 'options' : options});
}
return res;
},
var _super_removePaymentline_ = module.Order.prototype.removePaymentline;
module.Order.prototype.removePaymentline = function(line){
if (line) {
this.pos.prepare_text_customer_display('removePaymentline', {'line' : line});
}
return _super_removePaymentline_.call(this, line);
};
removeOrderline: function(line){
if (line) {
this.pos.prepare_text_customer_display('removeOrderline', {'line' : line});
}
return OrderSuper.prototype.removeOrderline.call(this, line);
},
var _super_addPaymentline_ = module.Order.prototype.addPaymentline;
module.Order.prototype.addPaymentline = function(cashregister){
res = _super_addPaymentline_.call(this, cashregister);
if (cashregister) {
this.pos.prepare_text_customer_display('addPaymentline', {'cashregister' : cashregister});
}
return res;
};
removePaymentline: function(line){
if (line) {
this.pos.prepare_text_customer_display('removePaymentline', {'line' : line});
}
return OrderSuper.prototype.removePaymentline.call(this, line);
},
var _super_pushOrder_ = module.PosModel.prototype.push_order;
module.PosModel.prototype.push_order = function(order){
res = _super_pushOrder_.call(this, order);
if (order) {
this.prepare_text_customer_display('pushOrder', {'order' : order});
}
return res;
};
addPaymentline: function(cashregister){
res = OrderSuper.prototype.addPaymentline.call(this, cashregister);
if (cashregister) {
this.pos.prepare_text_customer_display('addPaymentline', {'cashregister' : cashregister});
}
return res;
},
var _super_update_payment_summary_ = module.PaymentScreenWidget.prototype.update_payment_summary;
module.PaymentScreenWidget.prototype.update_payment_summary = function(){
res = _super_update_payment_summary_.call(this);
var currentOrder = this.pos.get('selectedOrder');
var paidTotal = currentOrder.getPaidTotal();
var dueTotal = currentOrder.getTotalTaxIncluded();
var change = paidTotal > dueTotal ? paidTotal - dueTotal : 0;
if (change) {
change_rounded = change.toFixed(2);
this.pos.prepare_text_customer_display('update_payment', {'change': change_rounded});
}
return res;
};
});
var _super_closePOS_ = module.PosWidget.prototype.close;
module.PosWidget.prototype.close = function(){
this.pos.prepare_text_customer_display('closePOS', {});
return _super_closePOS_.call(this);
};
module.PaymentScreenWidget.include({
update_payment_summary: function(){
res = this._super();
var currentOrder = this.pos.get('selectedOrder');
var paidTotal = currentOrder.getPaidTotal();
var dueTotal = currentOrder.getTotalTaxIncluded();
var change = paidTotal > dueTotal ? paidTotal - dueTotal : 0;
if (change) {
change_rounded = change.toFixed(2);
this.pos.prepare_text_customer_display('update_payment', {'change': change_rounded});
}
return res;
},
});
var _super_proxy_start_ = module.ProxyStatusWidget.prototype.start;
module.ProxyStatusWidget.prototype.start = function(){
res = _super_proxy_start_.call(this);
this.pos.prepare_text_customer_display('openPOS', {});
return res;
};
module.PosWidget.include({
close: function(){
this._super();
this.pos.prepare_text_customer_display('closePOS', {});
},
});
module.ProxyStatusWidget.include({
start: function(){
this._super();
this.pos.prepare_text_customer_display('openPOS', {});
},
});
/* Handle Button "Display Total to Customer" */
var _super_OrderWidget_init_ = module.OrderWidget.prototype.init;
module.OrderWidget.prototype.init = function(parent, options){
_super_OrderWidget_init_.call(this, parent, options);
var _saved_renderElement = module.OrderWidget.prototype.renderElement;
module.OrderWidget.prototype.renderElement = function() {
_saved_renderElement.apply(this, arguments);
var self = this;
this.prepare_text_customer_display = function(event){
self.pos.prepare_text_customer_display('addPaymentline', {});
event.stopPropagation();
};
};
var _super_update_summary_ = module.OrderWidget.prototype.update_summary;
module.OrderWidget.prototype.update_summary = function(){
_super_update_summary_.call(this);
if (this.pos.config.iface_customer_display){
this.el.querySelector('.show-total-to-customer')
.addEventListener('click', this.prepare_text_customer_display);
}
if (self.pos.config.iface_customer_display) {
self.el.querySelector('.show-total-to-customer')
.addEventListener('click', function(){
self.pos.prepare_text_customer_display('addPaymentline', {})
});
}
};
};

55
pos_payment_terminal/README.rst

@ -0,0 +1,55 @@
POS Payment Terminal
====================
This module adds support for credit card reader and checks printer
in the Point of Sale.
This module has been developped during a POS code sprint at Akretion
France from July 7th to July 10th 2014. This module is part of the POS
project of the Odoo Community Association http://odoo-community.org/.
You are invited to become a member and/or get involved in the
Association !
Installation
============
This module is designed to be installed on the
*main Odoo server*. On the *POSbox*, you should install the module
*hw_x* depending on the protocol implemented in your device.
`Ingenico <http://en.wikipedia.org/wiki/Ingenico>`
and old Sagem devices support the Telium protocol implemented in the
*hw_telium_payment_terminal* module.
Configuration
=============
This module support two payment modes : *card* and *check*. The payment
mode should be configured on the main Odoo server, in the menu *Point
of Sale > Configuration > Payment Methods*, under the *Point of Sale* tab.
Usage
=====
In the frontend of the POS, when you select a payment method that has a payment mode *card* or *check*, you will have a *Start Transaction* button : if you click on that button, the amount, the currency and the payment mode will be sent to the POSbox.
Credits
=======
Contributors
------------
* Aurelien Dumaine
* Alexis de Lattre <alexis.delattre@akretion.com>
Maintainer
----------
.. image:: http://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: http://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.
To contribute to this module, please visit http://odoo-community.org.

24
pos_payment_terminal/__openerp__.py

@ -3,6 +3,7 @@
#
# POS Payment Terminal module for Odoo
# Copyright (C) 2014 Aurélien DUMAINE
# Copyright (C) 2015 Akretion (www.akretion.com)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@ -25,28 +26,7 @@
'version': '0.1',
'category': 'Point Of Sale',
'summary': 'Manage Payment Terminal device from POS front end',
'description': """
POS Payment Terminal
====================
This module adds support for credit card reader and checks printer
in the Point of Sale. This module is designed to be installed on the
*main Odoo server*. On the *POSbox*, you should install the module
*hw_x* depending on the protocol implemented in your device. Ingenico
and Sagem devices support the Telium protocol implemented in the
*hw_telium_payment_terminal* module.
This module support two payment methods : cards and checks. The payment
method should be configured on the main Odoo server, in the menu Point
of Sale > Configuration > Payment Methods.
This module has been developped during a POS code sprint at Akretion
France from July 7th to July 10th 2014. This module is part of the POS
project of the Odoo Community Association http://odoo-community.org/.
You are invited to become a member and/or get involved in the
Association !
""",
'author': "Aurélien DUMAINE,Odoo Community Association (OCA)",
'author': "Aurélien DUMAINE,Akretion,Odoo Community Association (OCA)",
'license': 'AGPL-3',
'depends': ['point_of_sale'],
'data': [

5
pos_payment_terminal/pos_payment_terminal.py

@ -3,6 +3,7 @@
#
# POS Payment Terminal module for Odoo
# Copyright (C) 2014 Aurélien DUMAINE
# Copyright (C) 2015 Akretion (www.akretion.com)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@ -22,7 +23,7 @@
from openerp import models, fields
class account_journal(models.Model):
class AccountJournal(models.Model):
_inherit = 'account.journal'
payment_mode = fields.Selection(
@ -30,7 +31,7 @@ class account_journal(models.Model):
help="Select the payment mode sent to the payment terminal")
class pos_config(models.Model):
class PosConfig(models.Model):
_inherit = 'pos.config'
iface_payment_terminal = fields.Boolean(

4
pos_payment_terminal/pos_payment_terminal_demo.xml

@ -6,5 +6,9 @@
<field name="payment_mode">check</field>
</record>
<record id="point_of_sale.pos_config_main" model="pos.config">
<field name="iface_payment_terminal" eval="True"/>
</record>
</data>
</openerp>

54
pos_payment_terminal/static/src/js/pos_payment_terminal.js

@ -1,3 +1,12 @@
/*
POS Payment Terminal module for Odoo
Copyright (C) 2014 Aurélien DUMAINE
Copyright (C) 2014-2015 Akretion (www.akretion.com)
@author: Aurélien DUMAINE
@author: Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
*/
openerp.pos_payment_terminal = function(instance){
module = instance.point_of_sale;
@ -6,43 +15,20 @@ openerp.pos_payment_terminal = function(instance){
var data = {'amount' : line.get_amount(),
'currency_iso' : currency_iso,
'payment_mode' : line.cashregister.journal.payment_mode};
// alert(JSON.stringify(data));
this.message('payment_terminal_transaction_start', {'payment_info' : JSON.stringify(data)});
},
});
var _super_PaymentScreenWidget_init_ = module.PaymentScreenWidget.prototype.init;
module.PaymentScreenWidget.prototype.init = function(parent, options){
_super_PaymentScreenWidget_init_.call(this, parent, options);
var self = this;
this.payment_terminal_transaction_start = function(event){
var node = this;
while (node && !node.classList.contains('paymentline')){
node = node.parentNode;
}
if (node && !_.isEmpty(node.line) && self.pos.config.iface_payment_terminal){
self.pos.proxy.payment_terminal_transaction_start(node.line, self.pos.currency.name);
}
event.stopPropagation();
};
};
var _super_renderPaymentline_ = module.PaymentScreenWidget.prototype.render_paymentline;
module.PaymentScreenWidget.prototype.render_paymentline = function(line){
var el_node = _super_renderPaymentline_.call(this, line);
if (line.cashregister.journal.payment_mode && this.pos.config.iface_payment_terminal){
if (!this.pos.currency.name){
var self = this;
var currencies = new instance.web.Model('res.currency').query(['name'])
.filter([['id','=',this.pos.currency.id]])
.all().then(function (currency) {
self.pos.currency.name = currency[0].name;
});
}
el_node.querySelector('.payment-terminal-transaction-start')
.addEventListener('click', this.payment_terminal_transaction_start);
}
return el_node;
};
module.PaymentScreenWidget.include({
render_paymentline: function(line){
el_node = this._super(line);
var self = this;
if (line.cashregister.journal.payment_mode && this.pos.config.iface_payment_terminal){
el_node.querySelector('.payment-terminal-transaction-start')
.addEventListener('click', function(){self.pos.proxy.payment_terminal_transaction_start(line, self.pos.config.currency_id[1])});
}
return el_node;
},
});
};
Loading…
Cancel
Save