[MERGE]: with trunk

bzr revid: aja@tinyerp.com-20130926132044-oj0q4sqqu8u1nu7c
This commit is contained in:
ajay javiya (OpenERP)
2013-09-26 18:50:44 +05:30
21 changed files with 424 additions and 128 deletions
+9 -9
View File
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
"PO-Revision-Date: 2013-03-21 19:22+0000\n"
"Last-Translator: Liuming <gumdam20@me.com>\n"
"PO-Revision-Date: 2013-09-24 02:46+0000\n"
"Last-Translator: DWXXX <Unknown>\n"
"Language-Team: Chinese (Simplified) <zh_CN@li.org>\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
+5 -1
View File
@@ -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',
Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

@@ -0,0 +1,227 @@
<section class="oe_container">
<div class="oe_row oe_spaced">
<h2 class="oe_slogan">Mass Mailing Made Easy</h2>
<h3 class="oe_slogan">Design, Send, Track Emails</h3>
<div class="oe_span6">
<div class="oe_bg_img">
<img src="mass_mailing_campaign.png" class="oe_picture oe_screenshot">
</div>
</div>
<div class="oe_span6">
<p class='oe_mt32'>
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.
</p>
<div class="oe_centeralign oe_websiteonly">
<a href="http://www.openerp.com/start" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
</div>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row">
<h2 class="oe_slogan">Send Professional Emails</h2>
<div class="oe_span6">
<p class='oe_mt32'>
Import database of prospects or filter on
existing leads, opportunities and customers in just a few clicks.
</p><p>
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.
</p>
</div>
<div class="oe_span6">
<div class="oe_bg_img">
<img class="oe_picture oe_screenshot" src="mass_mailing_composer.png">
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row">
<h2 class="oe_slogan">Organize Marketing Campaigns</h2>
<h3 class="oe_slogan">Design, Send, Track by Campaigns</h3>
<div class="oe_span6">
<div class="oe_bg_img">
<img class="oe_picture oe_screenshot" src="mass_mailing_campaign.png">
</div>
</div>
<div class="oe_span6">
<p class='oe_mt32'>
Get real time statistics on campaigns performance to improve your
conversion rate. Track mails sent, received, opened and
answered.
</p><p>
Easily manage your marketing campaigns, discussion groups,
leads and opportunities in one simple and powerful platform.
</p>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row">
<h2 class="oe_slogan">Integrated with OpenERP Apps</h2>
<h2 class="oe_slogan"></h2>
<div class="oe_span6">
<p class='oe_mt32'>
Get access to mass mailing features from every OpenERP app to improve
the way your users communicate.
</p><p>
Send template of emails from <a href="/apps/crm">CRM</a> opportunities, select leads based on
marketing segments, send <a href="/apps/hr_recruitment">jobs offers</a> and automate answers to applicants, reuse
email template in the <a href="/apps/marketing_campaign">lead automation marketing campaigns</a>.
</p><p>
Answers to your emails appears automatically in the history of every document with the
<a href="/apps/mail">social network</a> module.
</p>
</div>
<div class="oe_span6">
<div class="oe_bg_img">
<img class="oe_picture oe_screenshot" src="mass_mailing_tasks.png">
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row">
<h2 class="oe_slogan">Clean Your Lead Database</h2>
<h3 class="oe_slogan">Handle bounce and conversion rates</h3>
<div class="oe_span6">
<div class="oe_bg_img">
<img class="oe_picture oe_screenshot" src="mass_mailing_mailing.png">
</div>
</div>
<div class="oe_span6">
<p class='oe_mt32'>
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.
</p>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row">
<h2 class="oe_slogan">One click emails send</h2>
<h3 class="oe_slogan">Select any documents, send emails</h3>
<div class="oe_span6">
<p class='oe_mt32'>
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.
</p><p>
Select a few documents (e.g. leads, support tickets, suppliers, applicants,
...) and send emails to their contacts in one click, reusing existing emails
templates.
</p>
</div>
<div class="oe_span6">
<div class="oe_bg_img">
<img class="oe_picture oe_screenshot" src="mass_mailing_composer.png">
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row">
<h2 class="oe_slogan">Follow-up On Answers</h2>
<h3 class="oe_slogan">Communicate efficiently with prospects</h3>
<div class="oe_span6">
<div class="oe_bg_img">
<img class="oe_picture oe_screenshot" src="mass_mailing_history.png">
</div>
</div>
<div class="oe_span6">
<p class='oe_mt32'>
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.
</p><p>
Get all the negotiations and discussions attached to the right document
and relevent managers notified on specific events.
</p>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<h2 class="oe_slogan">Campaigns Dashboard</h2>
<h3 class="oe_slogan">Analyse the performance of your campaigns</h3>
<div class="oe_span6">
<p class="oe_mt32">
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.
</p>
</div>
<div class="oe_span6">
<div class="oe_bg_img">
<img class="oe_picture oe_screenshot" src="mass_mailing_dashboard.png">
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row">
<h2 class="oe_slogan">Fully Integrated With Others Apps</h2>
<h3 class="oe_slogan">Efficient mailing for every users</h3>
</div>
<div class="oe_row">
<div class="oe_span4">
<a href="/apps/marketing_campaign">
<h3>Lead Automation</h3>
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="app_marketing_campaign.png">
</div>
</a>
<p>
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.)
</p><p>
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.
</p>
</div>
<div class="oe_span4">
<a href="/apps/website_crm">
<h3>Website Forms</h3>
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="app_website_crm.png">
</div>
</a>
<p>
Integrate a contact form in your website easily. Forms
submissions create leads automatically in OpenERP CRM. Leads
can be used in marketing campaigns.
</p>
</div>
<div class="oe_span4">
<a href="/apps/crm">
<h3>CRM</h3>
<div class="oe_row_img oe_centered">
<img class="oe_picture oe_screenshot" src="app_crm.png">
</div>
</a>
<p>
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.
</p>
</div>
</div>
</section>
Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

+1 -1
View File
@@ -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
+7
View File
@@ -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 = [];
+68 -43
View File
@@ -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)
},
});
+20 -11
View File
@@ -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));
}
+24 -24
View File
@@ -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');
},
@@ -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
+53 -35
View File
@@ -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();
@@ -494,6 +494,7 @@
<li class="button lemon_price">1.54€ Lemon</li>
<li class="button unknown_product">Unknown Product</li>
<li class="button invalid_ean">Invalid Ean</li>
<li class="button reference">Reference</li>
</ul>
<p class="category">Hardware Status</p>