summaryrefslogtreecommitdiff
path: root/addons/pos_restaurant/static/src/js/multiprint.js
diff options
context:
space:
mode:
Diffstat (limited to 'addons/pos_restaurant/static/src/js/multiprint.js')
-rw-r--r--addons/pos_restaurant/static/src/js/multiprint.js315
1 files changed, 315 insertions, 0 deletions
diff --git a/addons/pos_restaurant/static/src/js/multiprint.js b/addons/pos_restaurant/static/src/js/multiprint.js
new file mode 100644
index 00000000..709de43e
--- /dev/null
+++ b/addons/pos_restaurant/static/src/js/multiprint.js
@@ -0,0 +1,315 @@
+odoo.define('pos_restaurant.multiprint', function (require) {
+"use strict";
+
+var models = require('point_of_sale.models');
+var core = require('web.core');
+var Printer = require('point_of_sale.Printer').Printer;
+
+var QWeb = core.qweb;
+
+models.PosModel = models.PosModel.extend({
+ create_printer: function (config) {
+ var url = config.proxy_ip || '';
+ if(url.indexOf('//') < 0) {
+ url = window.location.protocol + '//' + url;
+ }
+ if(url.indexOf(':', url.indexOf('//') + 2) < 0 && window.location.protocol !== 'https:') {
+ url = url + ':8069';
+ }
+ return new Printer(url, this);
+ },
+});
+
+models.load_models({
+ model: 'restaurant.printer',
+ fields: ['name','proxy_ip','product_categories_ids', 'printer_type'],
+ domain: null,
+ loaded: function(self,printers){
+ var active_printers = {};
+ for (var i = 0; i < self.config.printer_ids.length; i++) {
+ active_printers[self.config.printer_ids[i]] = true;
+ }
+
+ self.printers = [];
+ self.printers_categories = {}; // list of product categories that belong to
+ // one or more order printer
+
+ for(var i = 0; i < printers.length; i++){
+ if(active_printers[printers[i].id]){
+ var printer = self.create_printer(printers[i]);
+ printer.config = printers[i];
+ self.printers.push(printer);
+
+ for (var j = 0; j < printer.config.product_categories_ids.length; j++) {
+ self.printers_categories[printer.config.product_categories_ids[j]] = true;
+ }
+ }
+ }
+ self.printers_categories = _.keys(self.printers_categories);
+ self.config.iface_printers = !!self.printers.length;
+ },
+});
+
+var _super_orderline = models.Orderline.prototype;
+
+models.Orderline = models.Orderline.extend({
+ initialize: function() {
+ _super_orderline.initialize.apply(this,arguments);
+ if (!this.pos.config.iface_printers) {
+ return;
+ }
+ if (typeof this.mp_dirty === 'undefined') {
+ // mp dirty is true if this orderline has changed
+ // since the last kitchen print
+ // it's left undefined if the orderline does not
+ // need to be printed to a printer.
+
+ this.mp_dirty = this.printable() || undefined;
+ }
+ if (!this.mp_skip) {
+ // mp_skip is true if the cashier want this orderline
+ // not to be sent to the kitchen
+ this.mp_skip = false;
+ }
+ },
+ // can this orderline be potentially printed ?
+ printable: function() {
+ return this.pos.db.is_product_in_category(this.pos.printers_categories, this.get_product().id);
+ },
+ init_from_JSON: function(json) {
+ _super_orderline.init_from_JSON.apply(this,arguments);
+ this.mp_dirty = json.mp_dirty;
+ this.mp_skip = json.mp_skip;
+ },
+ export_as_JSON: function() {
+ var json = _super_orderline.export_as_JSON.apply(this,arguments);
+ json.mp_dirty = this.mp_dirty;
+ json.mp_skip = this.mp_skip;
+ return json;
+ },
+ set_quantity: function(quantity) {
+ if (this.pos.config.iface_printers && quantity !== this.quantity && this.printable()) {
+ this.mp_dirty = true;
+ }
+ _super_orderline.set_quantity.apply(this,arguments);
+ },
+ can_be_merged_with: function(orderline) {
+ return (!this.mp_skip) &&
+ (!orderline.mp_skip) &&
+ _super_orderline.can_be_merged_with.apply(this,arguments);
+ },
+ set_skip: function(skip) {
+ if (this.mp_dirty && skip && !this.mp_skip) {
+ this.mp_skip = true;
+ this.trigger('change',this);
+ }
+ if (this.mp_skip && !skip) {
+ this.mp_dirty = true;
+ this.mp_skip = false;
+ this.trigger('change',this);
+ }
+ },
+ set_dirty: function(dirty) {
+ if (this.mp_dirty !== dirty) {
+ this.mp_dirty = dirty;
+ this.trigger('change', this);
+ }
+ },
+ get_line_diff_hash: function(){
+ if (this.get_note()) {
+ return this.id + '|' + this.get_note();
+ } else {
+ return '' + this.id;
+ }
+ },
+});
+
+var _super_order = models.Order.prototype;
+models.Order = models.Order.extend({
+ build_line_resume: function(){
+ var resume = {};
+ this.orderlines.each(function(line){
+ if (line.mp_skip) {
+ return;
+ }
+ var line_hash = line.get_line_diff_hash();
+ var qty = Number(line.get_quantity());
+ var note = line.get_note();
+ var product_id = line.get_product().id;
+
+ if (typeof resume[line_hash] === 'undefined') {
+ resume[line_hash] = {
+ qty: qty,
+ note: note,
+ product_id: product_id,
+ product_name_wrapped: line.generate_wrapped_product_name(),
+ };
+ } else {
+ resume[line_hash].qty += qty;
+ }
+
+ });
+ return resume;
+ },
+ saveChanges: function(){
+ this.saved_resume = this.build_line_resume();
+ this.orderlines.each(function(line){
+ line.set_dirty(false);
+ });
+ this.trigger('change',this);
+ },
+ computeChanges: function(categories){
+ var current_res = this.build_line_resume();
+ var old_res = this.saved_resume || {};
+ var json = this.export_as_JSON();
+ var add = [];
+ var rem = [];
+ var line_hash;
+
+ for ( line_hash in current_res) {
+ var curr = current_res[line_hash];
+ var old = {};
+ var found = false;
+ for(var id in old_res) {
+ if(old_res[id].product_id === curr.product_id){
+ found = true;
+ old = old_res[id];
+ break;
+ }
+ }
+
+ if (!found) {
+ add.push({
+ 'id': curr.product_id,
+ 'name': this.pos.db.get_product_by_id(curr.product_id).display_name,
+ 'name_wrapped': curr.product_name_wrapped,
+ 'note': curr.note,
+ 'qty': curr.qty,
+ });
+ } else if (old.qty < curr.qty) {
+ add.push({
+ 'id': curr.product_id,
+ 'name': this.pos.db.get_product_by_id(curr.product_id).display_name,
+ 'name_wrapped': curr.product_name_wrapped,
+ 'note': curr.note,
+ 'qty': curr.qty - old.qty,
+ });
+ } else if (old.qty > curr.qty) {
+ rem.push({
+ 'id': curr.product_id,
+ 'name': this.pos.db.get_product_by_id(curr.product_id).display_name,
+ 'name_wrapped': curr.product_name_wrapped,
+ 'note': curr.note,
+ 'qty': old.qty - curr.qty,
+ });
+ }
+ }
+
+ for (line_hash in old_res) {
+ var found = false;
+ for(var id in current_res) {
+ if(current_res[id].product_id === old_res[line_hash].product_id)
+ found = true;
+ }
+ if (!found) {
+ var old = old_res[line_hash];
+ rem.push({
+ 'id': old.product_id,
+ 'name': this.pos.db.get_product_by_id(old.product_id).display_name,
+ 'name_wrapped': old.product_name_wrapped,
+ 'note': old.note,
+ 'qty': old.qty,
+ });
+ }
+ }
+
+ if(categories && categories.length > 0){
+ // filter the added and removed orders to only contains
+ // products that belong to one of the categories supplied as a parameter
+
+ var self = this;
+
+ var _add = [];
+ var _rem = [];
+
+ for(var i = 0; i < add.length; i++){
+ if(self.pos.db.is_product_in_category(categories,add[i].id)){
+ _add.push(add[i]);
+ }
+ }
+ add = _add;
+
+ for(var i = 0; i < rem.length; i++){
+ if(self.pos.db.is_product_in_category(categories,rem[i].id)){
+ _rem.push(rem[i]);
+ }
+ }
+ rem = _rem;
+ }
+
+ var d = new Date();
+ var hours = '' + d.getHours();
+ hours = hours.length < 2 ? ('0' + hours) : hours;
+ var minutes = '' + d.getMinutes();
+ minutes = minutes.length < 2 ? ('0' + minutes) : minutes;
+
+ return {
+ 'new': add,
+ 'cancelled': rem,
+ 'table': json.table || false,
+ 'floor': json.floor || false,
+ 'name': json.name || 'unknown order',
+ 'time': {
+ 'hours': hours,
+ 'minutes': minutes,
+ },
+ };
+
+ },
+ printChanges: async function(){
+ var printers = this.pos.printers;
+ let isPrintSuccessful = true;
+ for(var i = 0; i < printers.length; i++){
+ var changes = this.computeChanges(printers[i].config.product_categories_ids);
+ if ( changes['new'].length > 0 || changes['cancelled'].length > 0){
+ var receipt = QWeb.render('OrderChangeReceipt',{changes:changes, widget:this});
+ const result = await printers[i].print_receipt(receipt);
+ if (!result.successful) {
+ isPrintSuccessful = false;
+ }
+ }
+ }
+ return isPrintSuccessful;
+ },
+ hasChangesToPrint: function(){
+ var printers = this.pos.printers;
+ for(var i = 0; i < printers.length; i++){
+ var changes = this.computeChanges(printers[i].config.product_categories_ids);
+ if ( changes['new'].length > 0 || changes['cancelled'].length > 0){
+ return true;
+ }
+ }
+ return false;
+ },
+ hasSkippedChanges: function() {
+ var orderlines = this.get_orderlines();
+ for (var i = 0; i < orderlines.length; i++) {
+ if (orderlines[i].mp_skip) {
+ return true;
+ }
+ }
+ return false;
+ },
+ export_as_JSON: function(){
+ var json = _super_order.export_as_JSON.apply(this,arguments);
+ json.multiprint_resume = JSON.stringify(this.saved_resume);
+ return json;
+ },
+ init_from_JSON: function(json){
+ _super_order.init_from_JSON.apply(this,arguments);
+ this.saved_resume = json.multiprint_resume && JSON.parse(json.multiprint_resume);
+ },
+});
+
+
+});