mirror of
https://gitlab.com/hibou-io/hibou-odoo/suite.git
synced 2025-01-20 12:37:31 +02:00
350 lines
11 KiB
JavaScript
350 lines
11 KiB
JavaScript
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);
|
|
},
|
|
|
|
});
|
|
|
|
});
|