diff --git a/addons/account_test/i18n/zh_CN.po b/addons/account_test/i18n/zh_CN.po index 71d962610b7..67aeab3353e 100644 --- a/addons/account_test/i18n/zh_CN.po +++ b/addons/account_test/i18n/zh_CN.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2013-03-21 19:22+0000\n" -"Last-Translator: Liuming \n" +"PO-Revision-Date: 2013-09-24 02:46+0000\n" +"Last-Translator: DWXXX \n" "Language-Team: Chinese (Simplified) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-09-12 06:40+0000\n" -"X-Generator: Launchpad (build 16761)\n" +"X-Launchpad-Export-Date: 2013-09-25 05:28+0000\n" +"X-Generator: Launchpad (build 16771)\n" #. module: account_test #: view:accounting.assert.test:0 @@ -106,7 +106,7 @@ msgstr "" #. module: account_test #: view:accounting.assert.test:0 msgid "Description" -msgstr "" +msgstr "描述" #. module: account_test #: model:accounting.assert.test,desc:account_test.account_test_06_1 @@ -123,13 +123,13 @@ msgstr "" #: model:ir.actions.report.xml,name:account_test.account_assert_test_report #: model:ir.ui.menu,name:account_test.menu_action_license msgid "Accounting Tests" -msgstr "" +msgstr "帐户测试" #. module: account_test #: code:addons/account_test/report/account_test_report.py:74 #, python-format msgid "The test was passed successfully" -msgstr "" +msgstr "测试通过" #. module: account_test #: field:accounting.assert.test,active:0 @@ -155,7 +155,7 @@ msgstr "" #. module: account_test #: field:accounting.assert.test,code_exec:0 msgid "Python code" -msgstr "" +msgstr "Python代码" #. module: account_test #: model:accounting.assert.test,desc:account_test.account_test_07 @@ -209,7 +209,7 @@ msgstr "" #. module: account_test #: view:accounting.assert.test:0 msgid "Python Code" -msgstr "" +msgstr "Python代码" #. module: account_test #: model:ir.actions.act_window,help:account_test.action_accounting_assert diff --git a/addons/mass_mailing/__openerp__.py b/addons/mass_mailing/__openerp__.py index db7ac54263a..b8ca21c60d7 100644 --- a/addons/mass_mailing/__openerp__.py +++ b/addons/mass_mailing/__openerp__.py @@ -21,7 +21,11 @@ { 'name': 'Mass Mailing Campaigns', - 'description': """TODO""", + 'description': """ +Easily send mass mailing to your leads, opportunities or customers. Track +marketing campaigns performance to improve conversion rates. Design +professional emails and reuse templates in a few clicks. + """, 'version': '1.0', 'author': 'OpenERP', 'website': 'http://www.openerp.com', diff --git a/addons/mass_mailing/static/description/app_crm.png b/addons/mass_mailing/static/description/app_crm.png new file mode 100644 index 00000000000..e20c44836ba Binary files /dev/null and b/addons/mass_mailing/static/description/app_crm.png differ diff --git a/addons/mass_mailing/static/description/app_marketing_campaign.png b/addons/mass_mailing/static/description/app_marketing_campaign.png new file mode 100644 index 00000000000..f7662587969 Binary files /dev/null and b/addons/mass_mailing/static/description/app_marketing_campaign.png differ diff --git a/addons/mass_mailing/static/description/app_website_crm.png b/addons/mass_mailing/static/description/app_website_crm.png new file mode 100644 index 00000000000..7f19f68db61 Binary files /dev/null and b/addons/mass_mailing/static/description/app_website_crm.png differ diff --git a/addons/mass_mailing/static/description/icon.png b/addons/mass_mailing/static/description/icon.png new file mode 100644 index 00000000000..6ef68f30952 Binary files /dev/null and b/addons/mass_mailing/static/description/icon.png differ diff --git a/addons/mass_mailing/static/description/index.html b/addons/mass_mailing/static/description/index.html new file mode 100644 index 00000000000..49f4d99e80f --- /dev/null +++ b/addons/mass_mailing/static/description/index.html @@ -0,0 +1,227 @@ +
+
+

Mass Mailing Made Easy

+

Design, Send, Track Emails

+
+
+ +
+
+
+

+Easily send mass mailing to your leads, opportunities or customers. Track +marketing campaigns performance to improve conversion rates. Design +professional emails and reuse templates in a few clicks. +

+ +
+
+
+ +
+
+

Send Professional Emails

+
+

+Import database of prospects or filter on +existing leads, opportunities and customers in just a few clicks. +

+Define email templates to reuse content or specific design for your newsletter. +Setup several email servers with their own IP/domain to optimise opening rates. +

+
+
+
+ +
+
+
+
+ +
+
+

Organize Marketing Campaigns

+

Design, Send, Track by Campaigns

+
+
+ +
+
+
+

+ Get real time statistics on campaigns performance to improve your + conversion rate. Track mails sent, received, opened and + answered. +

+ Easily manage your marketing campaigns, discussion groups, + leads and opportunities in one simple and powerful platform. +

+
+
+
+ +
+
+

Integrated with OpenERP Apps

+

+
+

+Get access to mass mailing features from every OpenERP app to improve +the way your users communicate. +

+Send template of emails from CRM opportunities, select leads based on +marketing segments, send jobs offers and automate answers to applicants, reuse +email template in the lead automation marketing campaigns. +

+Answers to your emails appears automatically in the history of every document with the +social network module. +

+
+
+
+ +
+
+
+
+ +
+
+

Clean Your Lead Database

+

Handle bounce and conversion rates

+
+
+ +
+
+
+

+ Get a clean lead database that improves over the time using the + performance of your mails. OpenERP handle bounce mails + efficiently, flag erroneous leads accordingly and gives you + statistics on the quality of your leads. +

+
+
+
+ +
+
+

One click emails send

+

Select any documents, send emails

+
+

+The marketing department will love working on campaigns. But you can also +give a one click mass mailing facility to all others users on their own +prospects or documents. +

+Select a few documents (e.g. leads, support tickets, suppliers, applicants, +...) and send emails to their contacts in one click, reusing existing emails +templates. +

+
+
+
+ +
+
+ +
+
+ +
+
+

Follow-up On Answers

+

Communicate efficiently with prospects

+
+
+ +
+
+
+

+The chatter feature enables you to communicate faster and more efficiently with +your customer. Get documents created automatically (leads, opportunities, +tasks, ...) based on answers to your mass mailing campaigns Follow the +discussion directly on the business documents within OpenERP or via email. +

+Get all the negotiations and discussions attached to the right document +and relevent managers notified on specific events. +

+
+
+
+ +
+
+

Campaigns Dashboard

+

Analyse the performance of your campaigns

+
+

+Get the insights you need to make smarter marketing campaign. Track statistics +per campaign: bounce rates, sent mails, best content, etc. The clear dashboards +gives you a direct overview of your campaign performance. +

+
+
+
+ +
+
+
+
+ +
+
+

Fully Integrated With Others Apps

+

Efficient mailing for every users

+
+
+
+ +

Lead Automation

+
+ +
+
+

+ Define automated actions (e.g. ask a salesperson to call, send + an email, ...) based on triggers (no activity since 20 days, + answered a promotional email, etc.) +

+ Optimize campaigns from lead to close, on every channel. Make + smarter decisions about where to invest and show the impact of + your marketing activities on your company's bottom line. +

+
+
+ +

Website Forms

+
+ +
+
+

+ Integrate a contact form in your website easily. Forms + submissions create leads automatically in OpenERP CRM. Leads + can be used in marketing campaigns. +

+
+
+ +

CRM

+
+ +
+
+

+Manage your sales funnel with no effort. Attract leads, follow-up on phone +calls and meetings. Analyse the quality of your leads to make informed +decisions and save time by integrating emails directly into the application. +

+
+
+
+ diff --git a/addons/mass_mailing/static/description/mass_mailing_campaign.png b/addons/mass_mailing/static/description/mass_mailing_campaign.png new file mode 100644 index 00000000000..961e25a5f19 Binary files /dev/null and b/addons/mass_mailing/static/description/mass_mailing_campaign.png differ diff --git a/addons/mass_mailing/static/description/mass_mailing_composer.png b/addons/mass_mailing/static/description/mass_mailing_composer.png new file mode 100644 index 00000000000..64f8996ec63 Binary files /dev/null and b/addons/mass_mailing/static/description/mass_mailing_composer.png differ diff --git a/addons/mass_mailing/static/description/mass_mailing_dashboard.png b/addons/mass_mailing/static/description/mass_mailing_dashboard.png new file mode 100644 index 00000000000..8f1ff1e95fe Binary files /dev/null and b/addons/mass_mailing/static/description/mass_mailing_dashboard.png differ diff --git a/addons/mass_mailing/static/description/mass_mailing_history.png b/addons/mass_mailing/static/description/mass_mailing_history.png new file mode 100644 index 00000000000..483e5eec09b Binary files /dev/null and b/addons/mass_mailing/static/description/mass_mailing_history.png differ diff --git a/addons/mass_mailing/static/description/mass_mailing_mailing.png b/addons/mass_mailing/static/description/mass_mailing_mailing.png new file mode 100644 index 00000000000..1bed96aed81 Binary files /dev/null and b/addons/mass_mailing/static/description/mass_mailing_mailing.png differ diff --git a/addons/mass_mailing/static/description/mass_mailing_tasks.png b/addons/mass_mailing/static/description/mass_mailing_tasks.png new file mode 100644 index 00000000000..418eebe4ab8 Binary files /dev/null and b/addons/mass_mailing/static/description/mass_mailing_tasks.png differ diff --git a/addons/point_of_sale/controllers/main.py b/addons/point_of_sale/controllers/main.py index de757238d6f..419f5bc2efa 100644 --- a/addons/point_of_sale/controllers/main.py +++ b/addons/point_of_sale/controllers/main.py @@ -82,7 +82,7 @@ class PointOfSaleController(http.Controller): """ print 'scan_item_success: ' + str(ean) - @http.route('/pos/scan_item_error_unrecognized') + @http.route('/pos/scan_item_error_unrecognized', type='json', auth='admin') def scan_item_error_unrecognized(self, ean): """ A product has been scanned without success diff --git a/addons/point_of_sale/static/src/js/db.js b/addons/point_of_sale/static/src/js/db.js index bb0acfb285c..66791bb3c8b 100644 --- a/addons/point_of_sale/static/src/js/db.js +++ b/addons/point_of_sale/static/src/js/db.js @@ -43,6 +43,7 @@ function openerp_pos_db(instance, module){ this.product_by_id = {}; this.product_by_ean13 = {}; this.product_by_category_id = {}; + this.product_by_reference = {}; this.category_by_id = {}; this.root_category_id = 0; @@ -197,6 +198,9 @@ function openerp_pos_db(instance, module){ if(product.ean13){ this.product_by_ean13[product.ean13] = product; } + if(product.default_code){ + this.product_by_reference[product.default_code] = product; + } } }, add_packagings: function(packagings){ @@ -241,6 +245,9 @@ function openerp_pos_db(instance, module){ } return undefined; }, + get_product_by_reference: function(ref){ + return this.product_by_reference[ref]; + }, get_product_by_category: function(category_id){ var product_ids = this.product_by_category_id[category_id]; var list = []; diff --git a/addons/point_of_sale/static/src/js/devices.js b/addons/point_of_sale/static/src/js/devices.js index bc697e96aca..67fde81136a 100644 --- a/addons/point_of_sale/static/src/js/devices.js +++ b/addons/point_of_sale/static/src/js/devices.js @@ -450,7 +450,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal // it will check its validity then return an object containing various // information about the ean. // most importantly : - // - ean : the ean + // - code : the ean // - type : the type of the ean: // 'price' | 'weight' | 'unit' | 'cashier' | 'client' | 'discount' | 'error' // @@ -460,13 +460,16 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal // - unit : if the encoded value has a unit, it will be put there. // not to be confused with the 'unit' type, which represent an unit of a // unique product + // - base_code : the ean code with all the encoding parts set to zero; the one put on + // the product in the backend parse_ean: function(ean){ var parse_result = { - type:'unknown', // + encoding: 'ean13', + type:'unknown', prefix:'', - ean:ean, - base_ean: ean, + code:ean, + base_code: ean, id:'', value: 0, unit: 'none', @@ -487,13 +490,13 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal parse_result.type = 'error'; } else if( match_prefix(this.price_prefix_set,'price')){ parse_result.id = ean.substring(0,7); - parse_result.base_ean = this.sanitize_ean(ean.substring(0,7)); + parse_result.base_code = this.sanitize_ean(ean.substring(0,7)); parse_result.value = Number(ean.substring(7,12))/100.0; parse_result.unit = 'euro'; } else if( match_prefix(this.weight_prefix_set,'weight')){ parse_result.id = ean.substring(0,7); parse_result.value = Number(ean.substring(7,12))/1000.0; - parse_result.base_ean = this.sanitize_ean(ean.substring(0,7)); + parse_result.base_code = this.sanitize_ean(ean.substring(0,7)); parse_result.unit = 'Kg'; } else if( match_prefix(this.client_prefix_set,'client')){ parse_result.id = ean.substring(0,7); @@ -502,7 +505,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal parse_result.id = ean.substring(0,7); } else if( match_prefix(this.discount_prefix_set,'discount')){ parse_result.id = ean.substring(0,7); - parse_result.base_ean = this.sanitize_ean(ean.substring(0,7)); + parse_result.base_code = this.sanitize_ean(ean.substring(0,7)); parse_result.value = Number(ean.substring(7,12))/100.0; parse_result.unit = '%'; } else { @@ -512,9 +515,18 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal } return parse_result; }, - - on_ean: function(ean){ - var parse_result = this.parse_ean(ean); + + scan: function(type,code){ + if (type === 'ean13'){ + var parse_result = this.parse_ean(code); + }else if(type === 'reference'){ + var parse_result = { + encoding: 'reference', + type: 'unit', + code: code, + prefix: '', + }; + } if (parse_result.type === 'error') { //most likely a checksum error, raise warning console.warn('WARNING: barcode checksum error:',parse_result); @@ -522,7 +534,6 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal if(this.action_callback['product']){ this.action_callback['product'](parse_result); } - //this.trigger("codebar",parse_result ); }else{ if(this.action_callback[parse_result.type]){ this.action_callback[parse_result.type](parse_result); @@ -530,49 +541,63 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal } }, + on_reference: function(code){ + if(this.action_callback['reference']){ + this.action_callback['reference'](code); + } + }, + // starts catching keyboard events and tries to interpret codebar // calling the callbacks when needed. connect: function(){ + var self = this; - var codeNumbers = []; - var timeStamp = 0; - var lastTimeStamp = 0; + var code = ""; + var timeStamp = 0; + var onlynumbers = true; + var timeout = null; - // The barcode readers acts as a keyboard, we catch all keyup events and try to find a - // barcode sequence in the typed keys, then act accordingly. - $('body').delegate('','keypress', function (e){ - //console.log('keyup:'+String.fromCharCode(e.keyCode)+' '+e.keyCode,e); - //We only care about numbers - if (e.keyCode >= 48 && e.keyCode < 58){ + this.handler = function(e){ - // The barcode reader sends keystrokes with a specific interval. - // We look if the typed keys fit in the interval. - if (codeNumbers.length === 0) { - timeStamp = new Date().getTime(); - } else { - if (lastTimeStamp + 30 < new Date().getTime()) { - // not a barcode reader - codeNumbers = []; - timeStamp = new Date().getTime(); - } - } - codeNumbers.push(e.keyCode - 48); - lastTimeStamp = new Date().getTime(); - if (codeNumbers.length === 13) { - //We have found what seems to be a valid codebar - self.on_ean(codeNumbers.join('')); - codeNumbers = []; - } - } else { - // NaN - codeNumbers = []; + if(e.which === 13){ //ignore returns + return; } - }); + + if(timeStamp + 50 < new Date().getTime()){ + code = ""; + onlynumbers = true; + } + + timeStamp = new Date().getTime(); + clearTimeout(timeout); + + if( e.which < 48 || e.which >= 58 ){ // not a number + onlynumbers = false; + } + + code += String.fromCharCode(e.which); + + // we wait for a while after the last input to be sure that we are not mistakingly + // returning a code which is a prefix of a bigger one : + // Internal Ref 5449 vs EAN13 5449000... + + timeout = setTimeout(function(){ + if(code.length === 13 && onlynumbers){ + self.scan('ean13',code); + }else if(code.length >= 3 && self.pos.db.get_product_by_reference(code)){ + self.scan('reference',code); + } + code = ""; + onlynumbers = true; + },100); + }; + + $('body').on('keypress', this.handler); }, // stops catching keyboard events disconnect: function(){ - $('body').undelegate('', 'keyup') + $('body').off('keypress', this.handler) }, }); diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 6d5fd1fc422..e47101ce27d 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -52,6 +52,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal 'pos_config': null, 'units': null, 'units_by_id': null, + 'pricelist': null, 'selectedOrder': null, }); @@ -113,10 +114,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal }).then(function(company_partners){ self.get('company').contact_address = company_partners[0].contact_address; - return self.fetch('res.currency',['symbol','position','rounding','accuracy'],[['id','=',self.get('company').currency_id[0]]]); - }).then(function(currencies){ - self.set('currency',currencies[0]); - return self.fetch('product.uom', null, null); }).then(function(units){ self.set('units',units); @@ -172,6 +169,14 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal }).then(function(shops){ self.set('shop',shops[0]); + return self.fetch('product.pricelist',['currency_id'],[['id','=',self.get('pos_config').pricelist_id[0]]]); + }).then(function(pricelists){ + self.set('pricelist',pricelists[0]); + + return self.fetch('res.currency',['symbol','position','rounding','accuracy'],[['id','=',self.get('pricelist').currency_id[0]]]); + }).then(function(currencies){ + self.set('currency',currencies[0]); + return self.fetch('product.packaging',['ean','product_id']); }).then(function(packagings){ self.db.add_packagings(packagings); @@ -185,7 +190,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal ['name', 'list_price','price','pos_categ_id', 'taxes_id', 'ean13', 'default_code', 'to_weight', 'uom_id', 'uos_id', 'uos_coeff', 'mes_type', 'description_sale', 'description'], [['sale_ok','=',true],['available_in_pos','=',true]], - {pricelist: self.get('pos_config').pricelist_id[0]} // context for price + {pricelist: self.get('pricelist').id} // context for price ); }).then(function(products){ self.db.add_products(products); @@ -423,19 +428,23 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal return tried_all; }, - scan_product: function(parsed_ean){ + scan_product: function(parsed_code){ var self = this; - var product = this.db.get_product_by_ean13(parsed_ean.base_ean); var selectedOrder = this.get('selectedOrder'); + if(parsed_code.encoding === 'ean13'){ + var product = this.db.get_product_by_ean13(parsed_code.base_code); + }else if(parsed_code.encoding === 'reference'){ + var product = this.db.get_product_by_reference(parsed_code.code); + } if(!product){ return false; } - if(parsed_ean.type === 'price'){ - selectedOrder.addProduct(new module.Product(product), {price:parsed_ean.value}); - }else if(parsed_ean.type === 'weight'){ - selectedOrder.addProduct(new module.Product(product), {quantity:parsed_ean.value, merge:false}); + if(parsed_code.type === 'price'){ + selectedOrder.addProduct(new module.Product(product), {price:parsed_code.value}); + }else if(parsed_code.type === 'weight'){ + selectedOrder.addProduct(new module.Product(product), {quantity:parsed_code.value, merge:false}); }else{ selectedOrder.addProduct(new module.Product(product)); } diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js index 4d453099690..77a542ff93c 100644 --- a/addons/point_of_sale/static/src/js/screens.js +++ b/addons/point_of_sale/static/src/js/screens.js @@ -160,29 +160,29 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa // what happens when a product is scanned : // it will add the product to the order and go to barcode_product_screen. Or show barcode_product_error_popup if // there's an error. - barcode_product_action: function(ean){ + barcode_product_action: function(code){ var self = this; - if(self.pos.scan_product(ean)){ - self.pos.proxy.scan_item_success(ean); + if(self.pos.scan_product(code)){ + self.pos.proxy.scan_item_success(code); if(self.barcode_product_screen){ self.pos_widget.screen_selector.set_current_screen(self.barcode_product_screen); } }else{ - self.pos.proxy.scan_item_error_unrecognized(ean); + self.pos.proxy.scan_item_error_unrecognized(code); if(self.barcode_product_error_popup && self.pos_widget.screen_selector.get_user_mode() !== 'cashier'){ self.pos_widget.screen_selector.show_popup(self.barcode_product_error_popup); } } }, - + // what happens when a cashier id barcode is scanned. // the default behavior is the following : // - if there's a user with a matching ean, put it as the active 'cashier', go to cashier mode, and return true // - else : do nothing and return false. You probably want to extend this to show and appropriate error popup... - barcode_cashier_action: function(ean){ + barcode_cashier_action: function(code){ var users = this.pos.get('user_list'); for(var i = 0, len = users.length; i < len; i++){ - if(users[i].ean13 === ean.ean){ + if(users[i].ean13 === code.code){ this.pos.set('cashier',users[i]); this.pos_widget.username.refresh(); this.pos.proxy.cashier_mode_activated(); @@ -190,7 +190,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa return true; } } - this.pos.proxy.scan_item_error_unrecognized(ean); + this.pos.proxy.scan_item_error_unrecognized(code); return false; }, @@ -198,28 +198,28 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa // the default behavior is the following : // - if there's a user with a matching ean, put it as the active 'client' and return true // - else : return false. - barcode_client_action: function(ean){ + barcode_client_action: function(code){ var partners = this.pos.get('partner_list'); for(var i = 0, len = partners.length; i < len; i++){ - if(partners[i].ean13 === ean.ean){ + if(partners[i].ean13 === code.code){ this.pos.get('selectedOrder').set_client(partners[i]); this.pos_widget.username.refresh(); - this.pos.proxy.scan_item_success(ean); + this.pos.proxy.scan_item_success(code); return true; } } - this.pos.proxy.scan_item_error_unrecognized(ean); + this.pos.proxy.scan_item_error_unrecognized(code); return false; //TODO start the transaction }, // what happens when a discount barcode is scanned : the default behavior // is to set the discount on the last order. - barcode_discount_action: function(ean){ - this.pos.proxy.scan_item_success(ean); + barcode_discount_action: function(code){ + this.pos.proxy.scan_item_success(code); var last_orderline = this.pos.get('selectedOrder').getLastOrderline(); if(last_orderline){ - last_orderline.set_discount(ean.value) + last_orderline.set_discount(code.value) } }, @@ -292,10 +292,10 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa this.pos_widget.username.set_user_mode(this.pos_widget.screen_selector.get_user_mode()); this.pos.barcode_reader.set_action_callback({ - 'cashier': self.barcode_cashier_action ? function(ean){ self.barcode_cashier_action(ean); } : undefined , - 'product': self.barcode_product_action ? function(ean){ self.barcode_product_action(ean); } : undefined , - 'client' : self.barcode_client_action ? function(ean){ self.barcode_client_action(ean); } : undefined , - 'discount': self.barcode_discount_action ? function(ean){ self.barcode_discount_action(ean); } : undefined, + 'cashier': self.barcode_cashier_action ? function(code){ self.barcode_cashier_action(code); } : undefined , + 'product': self.barcode_product_action ? function(code){ self.barcode_product_action(code); } : undefined , + 'client' : self.barcode_client_action ? function(code){ self.barcode_client_action(code); } : undefined , + 'discount': self.barcode_discount_action ? function(code){ self.barcode_discount_action(code); } : undefined, }); }, @@ -405,7 +405,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa this.pos.barcode_reader.save_callbacks(); this.pos.barcode_reader.reset_action_callbacks(); this.pos.barcode_reader.set_action_callback({ - 'cashier': function(ean){ + 'cashier': function(code){ clearInterval(this.intervalID); self.pos.proxy.cashier_mode_activated(); self.pos_widget.screen_selector.set_user_mode('cashier'); @@ -683,14 +683,14 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa show_numpad: false, show_leftpane: false, - barcode_product_action: function(ean){ + barcode_product_action: function(code){ this.pos.proxy.transaction_start(); - this._super(ean); + this._super(code); }, - barcode_client_action: function(ean){ + barcode_client_action: function(code){ this.pos.proxy.transaction_start(); - this._super(ean); + this._super(code); $('.goodbye-message').addClass('oe_hidden'); this.pos_widget.screen_selector.show_popup('choose-receipt'); }, diff --git a/addons/point_of_sale/static/src/js/widget_keyboard.js b/addons/point_of_sale/static/src/js/widget_keyboard.js index 05ccdd78ca6..22245b31227 100644 --- a/addons/point_of_sale/static/src/js/widget_keyboard.js +++ b/addons/point_of_sale/static/src/js/widget_keyboard.js @@ -43,10 +43,15 @@ function openerp_pos_keyboard(instance, module){ //module is instance.point_of_s // Write a character to the input zone writeCharacter: function(character){ - var $input = this.$target - $input[0].value += character; - $input.keydown(); - $input.keyup(); + var $input = this.$target; + if(character === '\n'){ + $input.trigger($.Event('keydown',{which:13})); + $input.trigger($.Event('keyup',{which:13})); + }else{ + $input[0].value += character; + $input.keydown(); + $input.keyup(); + } }, // Sends a 'return' character to the input zone. TODO diff --git a/addons/point_of_sale/static/src/js/widgets.js b/addons/point_of_sale/static/src/js/widgets.js index 0768791651b..291c8bfdaae 100644 --- a/addons/point_of_sale/static/src/js/widgets.js +++ b/addons/point_of_sale/static/src/js/widgets.js @@ -516,7 +516,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa var cat = self.pos.db.get_category_by_id(id); self.set_category(cat); self.renderElement(); - self.search_and_categories(cat); }); }); // breadcrumb click actions @@ -525,12 +524,13 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa var category = self.pos.db.get_category_by_id(id); self.set_category(category); self.renderElement(); - self.search_and_categories(category); }); + + this.search_and_categories(); + if(this.pos.iface_vkeyboard && this.pos_widget.onscreen_keyboard){ this.pos_widget.onscreen_keyboard.connect(this.$('.searchbox input')); } - this.search_and_categories(); }, set_product_type: function(type){ // 'all' | 'weightable' @@ -542,7 +542,14 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa reset_category: function(){ this.set_category(); this.renderElement(); - this.search_and_categories(); + }, + + // empties the content of the search box + clear_search: function(){ + var products = this.pos.db.get_product_by_category(this.category.id); + this.pos.get('products').reset(products); + this.$('.searchbox input').val('').focus(); + this.$('.search-clear').fadeOut(); }, // filters the products, and sets up the search callbacks @@ -554,12 +561,20 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa self.pos.get('products').reset(products); // filter the products according to the search string - this.$('.searchbox input').keyup(function(){ + this.$('.searchbox input').keyup(function(event){ + console.log('event',event); query = $(this).val().toLowerCase(); if(query){ - var products = self.pos.db.search_product_in_category(self.category.id, query); - self.pos.get('products').reset(products); - self.$('.search-clear').fadeIn(); + if(event.which === 13){ + if( self.pos.get('products').size() === 1 ){ + self.pos.get('selectedOrder').addProduct(self.pos.get('products').at(0)); + self.clear_search(); + } + }else{ + var products = self.pos.db.search_product_in_category(self.category.id, query); + self.pos.get('products').reset(products); + self.$('.search-clear').fadeIn(); + } }else{ var products = self.pos.db.get_product_by_category(self.category.id); self.pos.get('products').reset(products); @@ -567,14 +582,9 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa } }); - this.$('.searchbox input').click(function(){}); //Why ??? - //reset the search when clicking on reset this.$('.search-clear').click(function(){ - var products = self.pos.db.get_product_by_category(self.category.id); - self.pos.get('products').reset(products); - self.$('.searchbox input').val('').focus(); - self.$('.search-clear').fadeOut(); + self.clear_search(); }); }, }); @@ -669,16 +679,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa this._super(); if(this.action){ this.$el.click(function(){ - var draft_order = _.find( self.pos.get('orders').models, function(order){ - return order.get('orderLines').length !== 0 && order.get('paymentLines').length === 0; - }); - if(draft_order){ - if (confirm(_t("Pending orders will be lost.\nAre you sure you want to leave this session?"))) { - self.action(); - } - }else{ - self.action(); - } + self.action(); }); } }, @@ -743,12 +744,15 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa this.$('.button.custom_ean').click(function(){ var ean = self.pos.barcode_reader.sanitize_ean(self.$('input.ean').val() || '0'); self.$('input.ean').val(ean); - self.pos.barcode_reader.on_ean(ean); + self.pos.barcode_reader.scan('ean13',ean); + }); + this.$('.button.reference').click(function(){ + self.pos.barcode_reader.scan('reference',self.$('input.ean').val()); }); _.each(this.eans, function(ean, name){ self.$('.button.'+name).click(function(){ self.$('input.ean').val(ean); - self.pos.barcode_reader.on_ean(ean); + self.pos.barcode_reader.scan('ean13',ean); }); }); _.each(this.events, function(name){ @@ -1093,15 +1097,29 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa }, close: function() { var self = this; - return new instance.web.Model("ir.model.data").get_func("search_read")([['name', '=', 'action_client_pos_menu']], ['res_id']).pipe( - _.bind(function(res) { - return this.rpc('/web/action/load', {'action_id': res[0]['res_id']}).pipe(_.bind(function(result) { - var action = result; - action.context = _.extend(action.context || {}, {'cancel_action': {type: 'ir.actions.client', tag: 'reload'}}); - //self.destroy(); - this.do_action(action); - }, this)); - }, this)); + + function close(){ + return new instance.web.Model("ir.model.data").get_func("search_read")([['name', '=', 'action_client_pos_menu']], ['res_id']).pipe( + _.bind(function(res) { + return this.rpc('/web/action/load', {'action_id': res[0]['res_id']}).pipe(_.bind(function(result) { + var action = result; + action.context = _.extend(action.context || {}, {'cancel_action': {type: 'ir.actions.client', tag: 'reload'}}); + //self.destroy(); + this.do_action(action); + }, this)); + }, self)); + } + + var draft_order = _.find( self.pos.get('orders').models, function(order){ + return order.get('orderLines').length !== 0 && order.get('paymentLines').length === 0; + }); + if(draft_order){ + if (confirm(_t("Pending orders will be lost.\nAre you sure you want to leave this session?"))) { + return close(); + } + }else{ + return close(); + } }, destroy: function() { this.pos.destroy(); diff --git a/addons/point_of_sale/static/src/xml/pos.xml b/addons/point_of_sale/static/src/xml/pos.xml index d9f021fc219..d5f57e099f7 100644 --- a/addons/point_of_sale/static/src/xml/pos.xml +++ b/addons/point_of_sale/static/src/xml/pos.xml @@ -494,6 +494,7 @@
  • 1.54€ Lemon
  • Unknown Product
  • Invalid Ean
  • +
  • Reference
  • Hardware Status