mirror of
https://gitlab.com/hibou-io/hibou-odoo/suite.git
synced 2025-01-20 12:37:31 +02:00
[ADD] pos_pax: for Odoo 11.0
This commit is contained in:
349
pos_pax/static/src/js/pos_pax.js
Normal file
349
pos_pax/static/src/js/pos_pax.js
Normal file
@@ -0,0 +1,349 @@
|
||||
odoo.define('pos_pax.pos_pax', function (require) {
|
||||
"use strict";
|
||||
|
||||
// Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
||||
|
||||
var core = require('web.core');
|
||||
var screens = require('point_of_sale.screens');
|
||||
var gui = require('point_of_sale.gui');
|
||||
var pos_model = require('point_of_sale.models');
|
||||
var _t = core._t;
|
||||
var PopupWidget = require('point_of_sale.popups');
|
||||
var PaymentScreenWidget = screens.PaymentScreenWidget;
|
||||
var PAX = require('pos_pax.pax_device');
|
||||
|
||||
PAX.mDestinationIP = '';
|
||||
|
||||
pos_model.load_fields("account.journal", "pos_use_pax");
|
||||
|
||||
pos_model.PosModel = pos_model.PosModel.extend({
|
||||
|
||||
getPAXOnlinePaymentJournals: function () {
|
||||
var self = this;
|
||||
var online_payment_journals = [];
|
||||
|
||||
$.each(this.journals, function (i, val) {
|
||||
if (val.pos_use_pax) {
|
||||
online_payment_journals.push({label:self.getCashRegisterByJournalID(val.id).journal_id[1], item:val.id});
|
||||
}
|
||||
});
|
||||
return online_payment_journals;
|
||||
},
|
||||
|
||||
getCashRegisterByJournalID: function (journal_id) {
|
||||
var cashregister_return = false;
|
||||
|
||||
$.each(this.cashregisters, function (index, cashregister) {
|
||||
if (cashregister.journal_id[0] === journal_id) {
|
||||
cashregister_return = cashregister;
|
||||
}
|
||||
});
|
||||
|
||||
return cashregister_return;
|
||||
},
|
||||
|
||||
decodePAXResponse: function (data) {
|
||||
console.log(data);
|
||||
if (data[5] == 'ABORTED') {
|
||||
console.log('aborted');
|
||||
return {fail: 'Transaction Aborted'};
|
||||
} else if (data[5] == 'OK') {
|
||||
return {
|
||||
success: true,
|
||||
approval: data[6][2],
|
||||
txn_id: data[10][0],
|
||||
card_num: '***' + data[9][0],
|
||||
}
|
||||
}
|
||||
return {fail: 'Unknown Response. ' + data};
|
||||
}
|
||||
});
|
||||
|
||||
var _paylineproto = pos_model.Paymentline.prototype;
|
||||
pos_model.Paymentline = pos_model.Paymentline.extend({
|
||||
init_from_JSON: function (json) {
|
||||
_paylineproto.init_from_JSON.apply(this, arguments);
|
||||
|
||||
this.paid = true;
|
||||
this.pax_txn_pending = json.pax_txn_pending;
|
||||
this.pax_card_number = json.pax_card_number;
|
||||
this.pax_approval = json.pax_approval;
|
||||
this.pax_txn_id = json.pax_txn_id;
|
||||
|
||||
this.set_credit_card_name();
|
||||
},
|
||||
export_as_JSON: function () {
|
||||
return _.extend(_paylineproto.export_as_JSON.apply(this, arguments), {
|
||||
paid: this.paid,
|
||||
pax_txn_pending: this.pax_txn_pending,
|
||||
pax_card_number: this.pax_card_number,
|
||||
pax_approval: this.pax_approval,
|
||||
pax_txn_id: this.pax_txn_id,
|
||||
});
|
||||
},
|
||||
set_credit_card_name: function () {
|
||||
if (this.pax_card_number) {
|
||||
this.name = this.pax_card_number;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Popup to show all transaction state for the payment.
|
||||
var PAXPaymentTransactionPopupWidget = PopupWidget.extend({
|
||||
template: 'PAXPaymentTransactionPopupWidget',
|
||||
show: function (options) {
|
||||
var self = this;
|
||||
this._super(options);
|
||||
options.transaction.then(function (data) {
|
||||
if (data.auto_close) {
|
||||
setTimeout(function () {
|
||||
self.gui.close_popup();
|
||||
}, 2000);
|
||||
} else {
|
||||
self.close();
|
||||
self.$el.find('.popup').append('<div class="footer"><div class="button cancel">Ok</div></div>');
|
||||
}
|
||||
|
||||
self.$el.find('p.body').html(data.message);
|
||||
}).progress(function (data) {
|
||||
self.$el.find('p.body').html(data.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
gui.define_popup({name:'pax-payment-transaction', widget: PAXPaymentTransactionPopupWidget});
|
||||
|
||||
PaymentScreenWidget.include({
|
||||
|
||||
_get_pax_txn_pending_line: function () {
|
||||
var i = 0;
|
||||
var lines = this.pos.get_order().get_paymentlines();
|
||||
|
||||
for (i = 0; i < lines.length; i++) {
|
||||
if (lines[i].pax_txn_pending) {
|
||||
return lines[i];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
},
|
||||
|
||||
// Handler to manage the card reader string
|
||||
pax_credit_transaction: function (old_deferred, retry_nr) {
|
||||
var order = this.pos.get_order();
|
||||
|
||||
if(this.pos.getPAXOnlinePaymentJournals().length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var transaction = {};
|
||||
var pending_line = self._get_pax_txn_pending_line();
|
||||
if ( ! pending_line ) {
|
||||
console.log('no pending line found!');
|
||||
return;
|
||||
}
|
||||
|
||||
var purchase_amount = pending_line.get_amount();
|
||||
|
||||
var transactionType = '01'; // SALE
|
||||
if (purchase_amount < 0.0) {
|
||||
purchase_amount = -purchase_amount;
|
||||
transactionType = '02'; // RETURN
|
||||
}
|
||||
|
||||
transaction = {
|
||||
command: 'T00',
|
||||
version: '1.28',
|
||||
transactionType: transactionType,
|
||||
amountInformation: {
|
||||
TransactionAmount: (purchase_amount * 100) | 0, // cast to integer
|
||||
},
|
||||
cashierInformation: {
|
||||
ClerkID: this.pos.user.name,
|
||||
},
|
||||
traceInformation: {
|
||||
ReferenceNumber: self.pos.get_order().uid,
|
||||
// InvoiceNumber: self.pos.get_order().uid,
|
||||
},
|
||||
}
|
||||
|
||||
var def = old_deferred || new $.Deferred();
|
||||
retry_nr = retry_nr || 0;
|
||||
|
||||
// show the transaction popup.
|
||||
// the transaction deferred is used to update transaction status
|
||||
// if we have a previous deferred it indicates that this is a retry
|
||||
if (! old_deferred) {
|
||||
self.gui.show_popup('pax-payment-transaction', {
|
||||
transaction: def
|
||||
});
|
||||
def.notify({
|
||||
message: _t('Handling transaction...'),
|
||||
});
|
||||
}
|
||||
|
||||
PAX.mDestinationIP = this.pos.config.pax_endpoint;
|
||||
PAX.DoCredit(transaction, function (response) {
|
||||
console.log(response);
|
||||
var parsed_response = self.pos.decodePAXResponse(response);
|
||||
if (parsed_response.fail) {
|
||||
def.resolve({message: parsed_response.fail})
|
||||
return;
|
||||
}
|
||||
if (parsed_response.success) {
|
||||
pending_line.paid = true;
|
||||
pending_line.pax_card_number = parsed_response.card_num;
|
||||
pending_line.pax_txn_id = parsed_response.txn_id;
|
||||
pending_line.pax_approval = parsed_response.approval;
|
||||
pending_line.pax_txn_pending = false;
|
||||
pending_line.set_credit_card_name();
|
||||
self.order_changes();
|
||||
self.reset_input();
|
||||
self.render_paymentlines();
|
||||
order.trigger('change', order);
|
||||
def.resolve({message: 'Approval ' + parsed_response.approval, auto_close: true})
|
||||
}
|
||||
def.resolve({message: _t('Unknown response.')})
|
||||
}, function (fail){
|
||||
def.resolve({message: _t('Communication Failure: ') + fail});
|
||||
});
|
||||
},
|
||||
|
||||
remove_paymentline_by_ref: function (line) {
|
||||
this.pos.get_order().remove_paymentline(line);
|
||||
this.reset_input();
|
||||
this.render_paymentlines();
|
||||
},
|
||||
|
||||
pax_do_reversal: function (line) {
|
||||
var def = new $.Deferred();
|
||||
var self = this;
|
||||
var transaction = {};
|
||||
|
||||
// show the transaction popup.
|
||||
// the transaction deferred is used to update transaction status
|
||||
this.gui.show_popup('pax-payment-transaction', {
|
||||
transaction: def
|
||||
});
|
||||
def.notify({
|
||||
message: 'Sending reversal...',
|
||||
});
|
||||
|
||||
transaction = {
|
||||
command: 'T00',
|
||||
version: '1.28',
|
||||
transactionType: (line.get_amount() > 0) ? '17' : '18', // V/SALE, V/RETURN
|
||||
cashierInformation: {
|
||||
ClerkID: this.pos.user.name,
|
||||
},
|
||||
traceInformation: {
|
||||
ReferenceNumber: self.pos.get_order().uid,
|
||||
InvoiceNumber: '',
|
||||
AuthCode: line.pax_approval,
|
||||
TransactionNumber: line.pax_txn_id,
|
||||
},
|
||||
}
|
||||
|
||||
PAX.mDestinationIP = this.pos.config.pax_endpoint;
|
||||
PAX.DoCredit(transaction, function (response) {
|
||||
var parsed_response = self.pos.decodePAXResponse(response);
|
||||
if (parsed_response.fail) {
|
||||
def.resolve({message: parsed_response.fail})
|
||||
return;
|
||||
}
|
||||
if (parsed_response.success) {
|
||||
def.resolve({
|
||||
message: _t('Reversal succeeded.'),
|
||||
auto_close: true,
|
||||
});
|
||||
self.remove_paymentline_by_ref(line);
|
||||
return;
|
||||
}
|
||||
def.resolve({message: _t('Unknown response.')})
|
||||
}, function (fail){
|
||||
def.resolve({message: _t('Communication Failure: ') + fail});
|
||||
});
|
||||
},
|
||||
|
||||
click_delete_paymentline: function (cid) {
|
||||
var lines = this.pos.get_order().get_paymentlines();
|
||||
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
if (lines[i].cid === cid && lines[i].pax_txn_id) {
|
||||
this.pax_do_reversal(lines[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this._super(cid);
|
||||
},
|
||||
|
||||
// make sure there is only one paymentline waiting for a swipe
|
||||
click_paymentmethods: function (id) {
|
||||
var order = this.pos.get_order();
|
||||
var cashregister = null;
|
||||
for (var i = 0; i < this.pos.cashregisters.length; i++) {
|
||||
if (this.pos.cashregisters[i].journal_id[0] === id){
|
||||
cashregister = this.pos.cashregisters[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cashregister.journal.pos_use_pax) {
|
||||
var pending_line = this._get_pax_txn_pending_line();
|
||||
|
||||
if (pending_line) {
|
||||
this.gui.show_popup('error',{
|
||||
'title': _t('Error'),
|
||||
'body': _t('One credit card txn already pending.'),
|
||||
});
|
||||
} else {
|
||||
this._super(id);
|
||||
order.selected_paymentline.pax_txn_pending = true;
|
||||
this.render_paymentlines();
|
||||
order.trigger('change', order); // needed so that export_to_JSON gets triggered
|
||||
}
|
||||
} else {
|
||||
this._super(id);
|
||||
}
|
||||
},
|
||||
|
||||
click_pax_send_transaction: function (id) {
|
||||
var pending_txn_line = this._get_pax_txn_pending_line();
|
||||
if (!pending_txn_line) {
|
||||
this.gui.show_popup('error',{
|
||||
'title': _t('Error'),
|
||||
'body': _t('No pending payment line to send.'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.pax_credit_transaction();
|
||||
},
|
||||
|
||||
render_paymentlines: function() {
|
||||
this._super();
|
||||
var self = this;
|
||||
self.$('.paymentlines-container').on('click', '.pax_send_transaction', function(){
|
||||
self.click_pax_send_transaction();
|
||||
});
|
||||
},
|
||||
|
||||
// before validating, get rid of any paymentlines that are pending
|
||||
validate_order: function(force_validation) {
|
||||
if (this.pos.get_order().is_paid() && ! this.invoicing) {
|
||||
var lines = this.pos.get_order().get_paymentlines();
|
||||
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
if (lines[i].pax_txn_pending) {
|
||||
this.pos.get_order().remove_paymentline(lines[i]);
|
||||
this.render_paymentlines();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._super(force_validation);
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user