You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

310 lines
14 KiB

  1. /*
  2. Copyright 2019 Coop IT Easy SCRLfs
  3. Vincent Van Rossem <vvrossem@gmail.com>
  4. License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  5. */
  6. odoo.define('pos_customer_display_currency.pos_customer_display_currency', function (require) {
  7. "use strict";
  8. var chrome = require('point_of_sale.chrome');
  9. var core = require('web.core');
  10. var utils = require('web.utils')
  11. var devices = require('point_of_sale.devices');
  12. var gui = require('point_of_sale.gui');
  13. var models = require('point_of_sale.models');
  14. var screens = require('point_of_sale.screens');
  15. var _t = core._t;
  16. var timerID_total;
  17. var timerID_updated;
  18. var round_pr = utils.round_precision;
  19. models.PosModel = models.PosModel.extend({
  20. /**
  21. * Prepare and send the currency data to the customer display device
  22. */
  23. prepare_currency_data_customer_display: function () {
  24. var currency_data = {
  25. 'currency_code': this.currency.name || this.company_currency.name,
  26. 'currency_char': this.config.customer_display_currency_char
  27. };
  28. this.proxy.send_currency_data_customer_display(currency_data);
  29. },
  30. /**
  31. * Prepare and send a text to the customer display device according to param type
  32. * @override prepare_text_customer_display from customer_display.js (module pos_customer_display)
  33. * @param {string} type
  34. * @param data
  35. */
  36. prepare_text_customer_display: function (type, data) {
  37. if (!this.config.iface_customer_display)
  38. return;
  39. var line_length = this.config.customer_display_line_length || 20;
  40. var currency_rounding = this.currency.decimals;
  41. var currency_char = this.config.customer_display_currency_char;
  42. var previous_lines_to_send, updated_lines_to_send, lines_to_send, total_lines = [];
  43. var line, product, container = {};
  44. var l21 = "";
  45. var l22 = "";
  46. var total = "";
  47. var mode = $('.selected-mode').attr('data-mode'); // numpad selected mode
  48. if (timerID_updated){
  49. clearTimeout(timerID_updated);
  50. }
  51. if (timerID_total){
  52. clearTimeout(timerID_total);
  53. }
  54. switch(type) {
  55. case 'add_update_line':
  56. line = data['line'];
  57. if ((line.qty_manually_set && mode === 'quantity') || mode === 'tare' || mode === 'price') {
  58. // first display "Manual Entry"
  59. l21 = line.get_quantity_str_with_uom()
  60. + 'x'
  61. + line.get_unit_price_with_uom_currency(currency_char, currency_rounding);
  62. previous_lines_to_send = [
  63. this.proxy.align_left(_t('Manual Entry'), line_length),
  64. this.proxy.align_right(l21, line_length)
  65. ];
  66. this.proxy.send_text_customer_display(previous_lines_to_send, line_length);
  67. // then display updated product after 3s
  68. l22 = ' ' + line.get_display_price().toFixed(currency_rounding) + currency_char;
  69. updated_lines_to_send = [
  70. this.proxy.align_left(line.get_product().display_name, line_length - l22.length) + l22,
  71. this.proxy.align_left(l21, line_length)
  72. ];
  73. timerID_updated = setTimeout(function () {
  74. this.proxy.send_text_customer_display(updated_lines_to_send, line_length);
  75. }.bind(this),3000);
  76. } else if (!line.qty_manually_set && mode === 'quantity') {
  77. // first display added product
  78. l21 = line.get_quantity_str_with_uom()
  79. + 'x'
  80. + line.get_unit_price_with_uom_currency(currency_char, currency_rounding);
  81. l22 = ' ' + line.get_display_price().toFixed(currency_rounding) + currency_char;
  82. previous_lines_to_send = [
  83. this.proxy.align_left(line.get_product().display_name, line_length - l22.length) + l22,
  84. this.proxy.align_left(l21, line_length)
  85. ];
  86. this.proxy.send_text_customer_display(previous_lines_to_send, line_length);
  87. } else if (mode === 'discount') {
  88. // first display discount information
  89. var discount = line.get_discount();
  90. l22 = ' ' + line.get_base_price().toFixed(currency_rounding) + currency_char;
  91. previous_lines_to_send = [
  92. this.proxy.align_left(line.get_product().display_name, line_length - l22.length) + l22,
  93. this.proxy.align_left(_t("Discount:") + discount + '%', line_length)
  94. ];
  95. this.proxy.send_text_customer_display(previous_lines_to_send, line_length);
  96. // then display updated product after 3s
  97. l21 = line.get_quantity_str_with_uom()
  98. + 'x'
  99. + line.get_base_price().toFixed(currency_rounding) + currency_char;
  100. updated_lines_to_send = [
  101. this.proxy.align_left(line.get_product().display_name, line_length - l22.length) + l22,
  102. this.proxy.align_left(l21, line_length)
  103. ];
  104. timerID_updated = setTimeout(function () {
  105. this.proxy.send_text_customer_display(updated_lines_to_send, line_length);
  106. }.bind(this),3000);
  107. }
  108. break;
  109. case 'add_container':
  110. line = data['line'];
  111. container = line.get_container();
  112. previous_lines_to_send = [
  113. this.proxy.align_left(container.name, line_length),
  114. this.proxy.align_right(container.weight.toString() + ' kg', line_length)
  115. ];
  116. this.proxy.send_text_customer_display(previous_lines_to_send, line_length);
  117. break;
  118. case 'remove_orderline':
  119. // first click on the backspace button set the amount to 0
  120. // => we can't precise the deleted quantity and price
  121. line = data['line'];
  122. product = line.get_product();
  123. if (line.container) {
  124. lines_to_send = [
  125. this.proxy.align_left(_t("Delete Container"), line_length),
  126. this.proxy.align_right(line.container.name, line_length)
  127. ];
  128. } else if (product) {
  129. lines_to_send = [
  130. this.proxy.align_left(_t("Delete Item"), line_length),
  131. this.proxy.align_right(product.display_name, line_length)
  132. ];
  133. }
  134. this.proxy.send_text_customer_display(lines_to_send, line_length);
  135. break;
  136. case 'add_paymentline':
  137. total = this.get('selectedOrder').get_total_with_tax().toFixed(currency_rounding) + currency_char;
  138. lines_to_send = [
  139. this.proxy.align_left(_t("TOTAL:"), line_length),
  140. this.proxy.align_right(total, line_length)
  141. ];
  142. this.proxy.send_text_customer_display(lines_to_send, line_length);
  143. break;
  144. case 'remove_paymentline':
  145. line = data['line'];
  146. var amount = line.get_amount().toFixed(currency_rounding) + currency_char;
  147. lines_to_send = [
  148. this.proxy.align_left(_t("Cancel Payment"), line_length),
  149. this.proxy.align_right(line.cashregister.journal_id[1], line_length - 1 - amount.length) + ' ' + amount
  150. ];
  151. this.proxy.send_text_customer_display(lines_to_send, line_length);
  152. break;
  153. case 'update_payment':
  154. var change = data['change'] + currency_char;
  155. lines_to_send = [
  156. this.proxy.align_left(_t("Your Change:"), line_length),
  157. this.proxy.align_right(change, line_length)
  158. ];
  159. this.proxy.send_text_customer_display(lines_to_send, line_length);
  160. break;
  161. // same display for both types
  162. case 'push_order':
  163. case 'openPOS':
  164. lines_to_send = [
  165. this.proxy.align_center(this.config.customer_display_msg_next_l1, line_length),
  166. this.proxy.align_center(this.config.customer_display_msg_next_l2, line_length)
  167. ];
  168. this.proxy.send_text_customer_display(lines_to_send, line_length);
  169. break;
  170. case 'closePOS':
  171. lines_to_send = [
  172. this.proxy.align_center(this.config.customer_display_msg_closed_l1, line_length),
  173. this.proxy.align_center(this.config.customer_display_msg_closed_l2, line_length)
  174. ];
  175. this.proxy.send_text_customer_display(lines_to_send, line_length);
  176. break;
  177. default:
  178. console.warn('Unknown message type');
  179. return;
  180. }
  181. if ((type === 'add_update_line' && mode === 'quantity' && !line.qty_manually_set)
  182. || type === 'add_container' || type === 'remove_orderline') {
  183. // display total after 3s
  184. var order = this.get('selectedOrder');
  185. if (order){
  186. total = order.get_total_with_tax().toFixed(currency_rounding) + currency_char;
  187. total_lines = [
  188. this.proxy.align_left(_t("TOTAL:"), line_length),
  189. this.proxy.align_right(total, line_length)
  190. ];
  191. timerID_total = setTimeout(function() {this.proxy.send_text_customer_display(total_lines, line_length); }.bind(this), 3000);
  192. }
  193. } else if ((type === 'add_update_line' && mode === 'quantity' && line.qty_manually_set)
  194. || mode === 'price' || mode === 'discount' || mode === 'tare') {
  195. // then display total after 6s
  196. total = this.get('selectedOrder').get_total_with_tax().toFixed(currency_rounding) + currency_char;
  197. total_lines = [
  198. this.proxy.align_left(_t("TOTAL:"), line_length),
  199. this.proxy.align_right(total, line_length)
  200. ];
  201. timerID_total = setTimeout(function() {this.proxy.send_text_customer_display(total_lines, line_length); }.bind(this), 6000);
  202. }
  203. },
  204. });
  205. devices.ProxyDevice = devices.ProxyDevice.extend({
  206. /**
  207. * Send currency data to the customer display device
  208. * @param currency_data
  209. * @returns {*}
  210. */
  211. send_currency_data_customer_display: function (currency_data) {
  212. return this.message('send_currency_data_customer_display',
  213. {
  214. 'currency_data': JSON.stringify(currency_data)
  215. });
  216. },
  217. });
  218. models.Orderline = models.Orderline.extend({
  219. /**
  220. * This function is for the Bixolon only
  221. * Returns quantityStr with or without the name of the unit of measure (uom)
  222. */
  223. get_quantity_str_with_uom: function(){
  224. var unit = this.get_unit();
  225. if(unit && !unit.is_pos_groupable){
  226. return this.quantityStr + '' + unit.name;
  227. }else{
  228. return round_pr(this.quantity, 0.1);
  229. }
  230. },
  231. /**
  232. * This function is for the Bixolon display device only.
  233. * Returns the unit price with the user-defined currency symbol (default: '$')
  234. */
  235. get_unit_price_with_uom_currency: function(currency_char, currency_rounding){
  236. var unit = this.get_unit();
  237. if(unit && !unit.is_pos_groupable){
  238. return this.get_unit_price().toFixed(currency_rounding) + currency_char + '/' + unit.name;
  239. }else{
  240. return this.get_unit_price().toFixed(currency_rounding) + currency_char;
  241. }
  242. },
  243. });
  244. var OrderSuper = models.Order;
  245. models.Order = models.Order.extend({
  246. /**
  247. * @extends add_container from models_and_db.js (module: pos_container)
  248. */
  249. add_container: function(container, options){
  250. // invoke parent object's implementation
  251. var res = OrderSuper.prototype.add_container.call(this, container, options);
  252. if (container){
  253. // parent ends with this.select_orderline(this.get_last_orderline());
  254. var line = this.get_last_orderline();
  255. this.pos.prepare_text_customer_display('add_container', {'line': line });
  256. }
  257. return res;
  258. },
  259. });
  260. /**
  261. * Fetch and set currency data when the ProxyStatusWidget starts
  262. */
  263. chrome.ProxyStatusWidget.include({
  264. start: function () {
  265. this._super();
  266. this.pos.prepare_currency_data_customer_display();
  267. },
  268. });
  269. screens.OrderWidget.include({
  270. set_value: function(val) {
  271. var order = this.pos.get_order();
  272. var selected_orderline = order.get_selected_orderline();
  273. if (selected_orderline) {
  274. var mode = this.numpad_state.get('mode');
  275. if( mode === 'quantity' ) {
  276. selected_orderline.qty_manually_set = true;
  277. }
  278. }
  279. this._super(val);
  280. },
  281. });
  282. });