Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IMP] Scontrino di cortesia #4408

Open
wants to merge 1 commit into
base: 12.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions fiscal_epos_print/models/point_of_sale.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ class PosConfig(models.Model):
fiscal_printer_serial = fields.Char(string='Fiscal Printer Serial')

fiscal_cashdrawer = fields.Boolean(string='Fiscal Printer Open CashDrawer')
epos_print_courtesy_receipt = fields.Boolean(
string="Print courtesy receipt",
help="Print a courtesy receipt when the order has to be invoiced",
)

@api.constrains('printer_ip', 'iface_reprint_done_order')
def _check_fiscal_epos_reprint(self):
Expand Down
252 changes: 251 additions & 1 deletion fiscal_epos_print/static/src/js/epson_epos_print.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,33 @@ odoo.define("fiscal_epos_print.epson_epos_print", function (require) {
var _t = core._t;
var round_pr = utils.round_precision;

/**
* Return true if the fiscal printer will print a fiscal receipt for `order`.
*/
function eposWillPrintReceipt(order) {
return order.pos.config.printer_ip && !order.is_to_invoice();
};
/**
* Return true if the fiscal printer will print a courtesy receipt for `order`.
*/
function eposWillPrintCourtesyReceipt(order) {
return order.pos.config.printer_ip && order.is_to_invoice() && order.pos.config.epos_print_courtesy_receipt;
};
/**
* Send `receipt` to the fiscal `printer`,
* this might print a receipt (fiscal or not) for `receipt`.
*/
function eposPrint(printer, receipt) {
var order = printer.order;
var result;
if (eposWillPrintReceipt(order)) {
result = printer.printFiscalReceipt(receipt);
} else if (eposWillPrintCourtesyReceipt(order)) {
result = printer.printNonFiscalReceipt(receipt);
}
return result
}

function addPadding(str, padding=4) {
var pad = new Array(padding).fill(0).join('') + str;
return pad.substr(pad.length - padding, padding);
Expand Down Expand Up @@ -436,6 +463,226 @@ odoo.define("fiscal_epos_print.epson_epos_print", function (require) {
console.log(xml);
},

addNonFiscalNode: function(xml, data, {font="1", operator="1"}) {
var node = xml.createElement("printNormal");
node.setAttribute("data", data);
node.setAttribute("font", font);
node.setAttribute("operator", operator);
xml.documentElement.appendChild(node);
},

formatAmountCurrency: function(amount, currency) {
if (currency.position === "after") {
return amount + " " + (currency.symbol || "");
} else {
return (currency.symbol || "") + " " + amount;
}
},

addNonFiscalEmptyLine: function(xml) {
var node = xml.createElement("printNormal");
node.setAttribute("data", "");
node.setAttribute("font", "1");
node.setAttribute("operator", "1");
xml.documentElement.appendChild(node);
},

addXMLNonFiscalHeader: function(xml, receipt) {
var beginNonFiscal = xml.createElement("beginNonFiscal");
beginNonFiscal.setAttribute("operator", receipt.operator || "1");
xml.documentElement.appendChild(beginNonFiscal);

this.addNonFiscalNode(
xml,
_t(`Courtesy receipt`),
{
font: "3",
operator: receipt.operator,
},
);

var invoice = receipt.epos_invoice;
this.addNonFiscalNode(
xml,
_t(`Copy of invoice ${invoice.name} of ${invoice.date}`),
{
operator: receipt.operator,
},
);
},

addXMLNonFiscalClient: function(xml, receipt) {
var client = this.order.get_client();

var clientName = client.name;
this.addNonFiscalNode(
xml,
_t(`Customer: ${clientName}`),
{
operator: receipt.operator,
},
);

var clientAddress = client.address;
if (clientAddress) {
this.addNonFiscalNode(
xml,
_t(`Address: ${clientAddress}`),
{
operator: receipt.operator,
},
);
}

var clientVAT = client.vat;
if (clientVAT) {
this.addNonFiscalNode(
xml,
_t(`VAT: ${clientVAT}`),
{
operator: receipt.operator,
},
);
}
},

addXMLNonFiscalOrderLine: function(xml, line, receipt) {
this.addNonFiscalNode(
xml,
line.product_name,
{
operator: receipt.operator,
},
);
var currency = receipt.currency;
var unit_amount = this.formatAmountCurrency(line.full_price, currency);
var total_amount = this.formatAmountCurrency(line.price_display, currency);
this.addNonFiscalNode(
xml,
_t(`${line.quantity} x ${unit_amount} = ${total_amount}`),
{
operator: receipt.operator,
},
);
var tax_amount = this.formatAmountCurrency(line.tax, currency);
this.addNonFiscalNode(
xml,
_t(`Tax code ${line.tax_department.code}: ${tax_amount}`),
{
operator: receipt.operator,
},
);
},

addXMLNonFiscalTaxDetail: function(xml, tax_detail, receipt) {
this.addNonFiscalNode(
xml,
_t(`Tax code ${tax_detail.tax.fpdeptax}: ${tax_detail.name}`),
{
operator: receipt.operator,
},
);
this.addNonFiscalNode(
xml,
this.formatAmountCurrency(tax_detail.amount, receipt.currency),
{
operator: receipt.operator,
},
);
},

addXMLNonFiscalTotal: function(xml, receipt) {
var invoice = this.order.epos_invoice;
this.addNonFiscalNode(
xml,
_t(`Total`),
{
operator: receipt.operator,
},
);
var currency = receipt.currency;
this.addNonFiscalNode(
xml,
_t(`Base: ${this.formatAmountCurrency(invoice.amount_untaxed, currency)}`),
{
operator: receipt.operator,
},
);
this.addNonFiscalNode(
xml,
_t(`Tax: ${this.formatAmountCurrency(invoice.amount_tax, currency)}`),
{
operator: receipt.operator,
},
);
this.addNonFiscalNode(
xml,
_t(`Total: ${this.formatAmountCurrency(invoice.amount_total, currency)}`),
{
operator: receipt.operator,
},
);
},

addXMLNonFiscalFooter: function(xml, receipt) {
this.addNonFiscalNode(
xml,
_t("Courtesy copy not valid for tax purposes. " +
"The original invoice has been sent to the SdI " +
"and can be consulted on the Revenue Agency website, " +
"in the Reserved Area."),
{
operator: receipt.operator,
},
);

var endNonFiscal = xml.createElement("endNonFiscal");
endNonFiscal.setAttribute("operator", receipt.operator || "1");
xml.documentElement.appendChild(endNonFiscal);
},

prepareXMLNonFiscalReceipt: function(receipt) {
var xml = document.implementation.createDocument(null, "printerNonFiscal");

this.addXMLNonFiscalHeader(xml, receipt);
this.addNonFiscalEmptyLine(xml);

this.addXMLNonFiscalClient(xml, receipt);
this.addNonFiscalEmptyLine(xml);

for (let line of receipt.orderlines) {
this.addXMLNonFiscalOrderLine(xml, line, receipt);
this.addNonFiscalEmptyLine(xml);
}
this.addNonFiscalEmptyLine(xml);

this.addNonFiscalNode(
xml,
_t("Taxes summary"),
{
operator: receipt.operator,
},
);
for (let tax_detail of receipt.tax_details) {
this.addXMLNonFiscalTaxDetail(xml, tax_detail, receipt);
this.addNonFiscalEmptyLine(xml);
}
this.addNonFiscalEmptyLine(xml);

this.addXMLNonFiscalTotal(xml, receipt);
this.addNonFiscalEmptyLine(xml);

this.addXMLNonFiscalFooter(xml, receipt);
return xml;
},

printNonFiscalReceipt: function(receipt) {
var xml = this.prepareXMLNonFiscalReceipt(receipt);
var xmlString = new XMLSerializer().serializeToString(xml);
this.fiscalPrinter.send(this.url, xmlString);
console.log(xmlString);
},

printFiscalReport: function() {
var xml = '<printerFiscalReport>';
xml += '<printZReport operator="" />';
Expand Down Expand Up @@ -474,7 +721,10 @@ odoo.define("fiscal_epos_print.epson_epos_print", function (require) {
});

return {
eposDriver: eposDriver
eposDriver: eposDriver,
eposWillPrintReceipt: eposWillPrintReceipt,
eposWillPrintCourtesyReceipt: eposWillPrintCourtesyReceipt,
eposPrint: eposPrint,
}

});
35 changes: 35 additions & 0 deletions fiscal_epos_print/static/src/js/models.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ odoo.define('fiscal_epos_print.models', function (require) {
var _t = core._t;
var round_pr = utils.round_precision;
var OrderSuper = models.Order;
var epson_epos_print = require('fiscal_epos_print.epson_epos_print');

models.load_fields("account.journal",
["fiscalprinter_payment_type", "fiscalprinter_payment_index"]);
Expand Down Expand Up @@ -92,6 +93,7 @@ odoo.define('fiscal_epos_print.models', function (require) {
receipt.fiscal_z_rep_number = this.fiscal_z_rep_number;
receipt.fiscal_printer_serial = this.fiscal_printer_serial;
receipt.fiscal_printer_debug_info = this.fiscal_printer_debug_info;
receipt.epos_invoice = this.epos_invoice;

return receipt
},
Expand Down Expand Up @@ -204,6 +206,39 @@ odoo.define('fiscal_epos_print.models', function (require) {
tax_model.fields.push('fpdeptax');
return _super_posmodel.initialize.call(this, session, attributes);
},
push_and_invoice_order: function(order) {
var self = this;
var invoiced = _super_posmodel.push_and_invoice_order.apply(this, arguments);
invoiced.done(function(){
// Get invoice from PoS `order`
self.chrome._rpc({
model: "pos.order",
method: "search_read",
args: [[["pos_reference", "=", order.name]], ["invoice_id",]],
}).then(function (server_orders) {
if (server_orders.length) {
var invoice_id = server_orders[0].invoice_id[0];
// Read invoice fields
self.chrome._rpc({
model: "account.invoice",
method: "read",
args: [invoice_id],
}).then(function (server_invoices) {
if (server_invoices.length) {
// Update `order` and print courtesy receipt
order.epos_invoice = server_invoices[0];
var printer_options = order.getPrinterOptions();
printer_options.order = order;
var receipt = order.export_for_printing();
var fp90 = new epson_epos_print.eposDriver(printer_options, order.pos.gui.current_screen);
return epson_epos_print.eposPrint(fp90, receipt);
}
});
}
});
});
return invoiced;
},
});

});
4 changes: 2 additions & 2 deletions fiscal_epos_print/static/src/js/pos_order_mgmt.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ odoo.define("fiscal_epos_print.pos_order_mgmt", function (require) {
// copiato da screens.PaymentScreenWidget
sendToFP90Printer: function(receipt, printer_options) {
var fp90 = new eposDriver(printer_options, this);
fp90.printFiscalReceipt(receipt);
return epson_epos_print.eposPrint(fp90, receipt);
},
action_print: function (order_data, order) {
if (this.pos.config.printer_ip) {
if (epson_epos_print.eposWillPrintReceipt(currentOrder)) {
if (order_data.fiscal_receipt_number) {
this.pos.gui.show_popup('error', {
'title': _t('Order already printed'),
Expand Down
6 changes: 3 additions & 3 deletions fiscal_epos_print/static/src/js/screens.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ odoo.define("fiscal_epos_print.screens", function (require) {

sendToFP90Printer: function(receipt, printer_options) {
var fp90 = new eposDriver(printer_options, this);
fp90.printFiscalReceipt(receipt);
return epson_epos_print.eposPrint(fp90, receipt);
},

render_receipt: function() {
Expand Down Expand Up @@ -59,15 +59,15 @@ odoo.define("fiscal_epos_print.screens", function (require) {
},
sendToFP90Printer: function(receipt, printer_options) {
var fp90 = new eposDriver(printer_options, this);
fp90.printFiscalReceipt(receipt);
return epson_epos_print.eposPrint(fp90, receipt);
},
finalize_validation: function() {
// we need to get currentOrder before calling the _super()
// otherwise we will likely get a empty order when we want to skip
// the receipt preview
var currentOrder = this.pos.get('selectedOrder');
this._super.apply(this, arguments);
if (this.pos.config.printer_ip && !currentOrder.is_to_invoice()) {
if (epson_epos_print.eposWillPrintReceipt(currentOrder)) {
this.chrome.loading_show();
this.chrome.loading_message(_t('Connecting to the fiscal printer'));
var printer_options = currentOrder.getPrinterOptions();
Expand Down
10 changes: 10 additions & 0 deletions fiscal_epos_print/views/point_of_sale.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@
<div class="o_setting_right_pane">
<label for="fiscal_cashdrawer"/>
</div>
<br/>
<div class="o_setting_left_pane">
<field name="epos_print_courtesy_receipt"/>
</div>
<div class="o_setting_right_pane">
<label for="epos_print_courtesy_receipt"/>
<div class="text-muted">
Print a courtesy receipt when the order has to be invoiced
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="fiscal_printer_serial">
<div class="o_setting_right_pane">
Expand Down
Loading