From 4ecf6fef06226e3841ce449e408d65a68675ad7c Mon Sep 17 00:00:00 2001 From: "Divyesh Makwana (Open ERP)" Date: Wed, 11 Jul 2012 18:43:47 +0530 Subject: [PATCH 001/166] [IMP] hr_expense : After the confirmation of the expense, the button should create an account.voucher (instead of an invoice) and confirmed it. It must creates the accounting entries exactly as the current invoice does. bzr revid: mdi@tinyerp.com-20120711131347-4uj73ojgrrfcdjd1 --- addons/hr_expense/__openerp__.py | 2 +- addons/hr_expense/hr_expense.py | 83 +++++++++---------- addons/hr_expense/hr_expense_view.xml | 2 +- addons/hr_expense/hr_expense_workflow.xml | 6 +- addons/hr_expense/report/hr_expense_report.py | 8 +- .../report/hr_expense_report_view.xml | 2 +- 6 files changed, 47 insertions(+), 56 deletions(-) diff --git a/addons/hr_expense/__openerp__.py b/addons/hr_expense/__openerp__.py index 2a1d302e094..d0265372b0c 100644 --- a/addons/hr_expense/__openerp__.py +++ b/addons/hr_expense/__openerp__.py @@ -43,7 +43,7 @@ re-invoice your customer's expenses if your work by project. 'author': 'OpenERP SA', 'website': 'http://www.openerp.com', 'images': ['images/hr_expenses_analysis.jpeg', 'images/hr_expenses.jpeg'], - 'depends': ['hr', 'account'], + 'depends': ['hr', 'account_voucher'], 'init_xml': [], 'update_xml': [ 'security/ir.model.access.csv', diff --git a/addons/hr_expense/hr_expense.py b/addons/hr_expense/hr_expense.py index b1192701dfb..d5f816268cb 100644 --- a/addons/hr_expense/hr_expense.py +++ b/addons/hr_expense/hr_expense.py @@ -73,7 +73,7 @@ class hr_expense_expense(osv.osv): 'line_ids': fields.one2many('hr.expense.line', 'expense_id', 'Expense Lines', readonly=True, states={'draft':[('readonly',False)]} ), 'note': fields.text('Note'), 'amount': fields.function(_amount, string='Total Amount'), - 'invoice_id': fields.many2one('account.invoice', "Employee's Invoice"), + 'voucher_id': fields.many2one('account.voucher', "Employee's Voucher"), 'currency_id': fields.many2one('res.currency', 'Currency', required=True), 'department_id':fields.many2one('hr.department','Department'), 'company_id': fields.many2one('res.company', 'Company', required=True), @@ -131,95 +131,86 @@ class hr_expense_expense(osv.osv): return True def invoice(self, cr, uid, ids, context=None): - wf_service = netsvc.LocalService("workflow") mod_obj = self.pool.get('ir.model.data') - res = mod_obj.get_object_reference(cr, uid, 'account', 'invoice_supplier_form') - inv_ids = [] + wkf_service = netsvc.LocalService("workflow") + + if not ids: return [] + exp = self.browse(cr, uid, ids[0], context=context) + + voucher_ids = [] for id in ids: - wf_service.trg_validate(uid, 'hr.expense.expense', id, 'invoice', cr) - inv_ids.append(self.browse(cr, uid, id).invoice_id.id) + wkf_service.trg_validate(uid, 'hr.expense.expense', id, 'invoice', cr) + voucher_ids.append(self.browse(cr, uid, id, context=context).voucher_id.id) + res = mod_obj.get_object_reference(cr, uid, 'account_voucher', 'view_purchase_receipt_form') + res_id = res and res[1] or False return { - 'name': _('Supplier Invoices'), 'view_type': 'form', 'view_mode': 'form', - 'view_id': [res and res[1] or False], - 'res_model': 'account.invoice', - 'context': "{'type':'out_invoice', 'journal_type': 'purchase'}", + 'res_model': 'account.voucher', + 'views': [(res_id, 'form')], + 'view_id': res_id, 'type': 'ir.actions.act_window', + 'target': 'new', 'nodestroy': True, - 'target': 'current', - 'res_id': inv_ids and inv_ids[0] or False, + 'res_id': voucher_ids and voucher_ids[0] or False, + 'close_after_process': True, } - - def action_invoice_create(self, cr, uid, ids): + def action_voucher_create(self, cr, uid, ids, context=None): res = False invoice_obj = self.pool.get('account.invoice') property_obj = self.pool.get('ir.property') sequence_obj = self.pool.get('ir.sequence') - analytic_journal_obj = self.pool.get('account.analytic.journal') account_journal = self.pool.get('account.journal') - for exp in self.browse(cr, uid, ids): + voucher_obj = self.pool.get('account.voucher') + + for exp in self.browse(cr, uid, ids, context=None): company_id = exp.company_id.id lines = [] + total = 0.0 for l in exp.line_ids: - tax_id = [] if l.product_id: acc = l.product_id.product_tmpl_id.property_account_expense if not acc: acc = l.product_id.categ_id.property_account_expense_categ - tax_id = [x.id for x in l.product_id.supplier_taxes_id] else: acc = property_obj.get(cr, uid, 'property_account_expense_categ', 'product.category', context={'force_company': company_id}) if not acc: raise osv.except_osv(_('Error !'), _('Please configure Default Expense account for Product purchase, `property_account_expense_categ`')) + lines.append((0, False, { 'name': l.name, 'account_id': acc.id, - 'price_unit': l.unit_amount, - 'quantity': l.unit_quantity, - 'uos_id': l.uom_id.id, - 'product_id': l.product_id and l.product_id.id or False, - 'invoice_line_tax_id': tax_id and [(6, 0, tax_id)] or False, - 'account_analytic_id': l.analytic_account.id, + 'amount': l.unit_amount, + 'type': 'dr' })) + total += l.unit_amount if not exp.employee_id.address_home_id: raise osv.except_osv(_('Error !'), _('The employee must have a Home address.')) acc = exp.employee_id.address_home_id.property_account_payable.id - payment_term_id = exp.employee_id.address_home_id.property_payment_term.id - inv = { + voucher = { 'name': exp.name, - 'reference': sequence_obj.get(cr, uid, 'hr.expense.invoice'), + 'number': sequence_obj.get(cr, uid, 'hr.expense.invoice'), 'account_id': acc, - 'type': 'in_invoice', + 'type': 'purchase', 'partner_id': exp.employee_id.address_home_id.id, 'company_id': company_id, - 'origin': exp.name, - 'invoice_line': lines, + # 'origin': exp.name, + 'line_ids': lines, 'currency_id': exp.currency_id.id, - 'payment_term': payment_term_id, - 'fiscal_position': exp.employee_id.address_home_id.property_account_position.id + 'amount': total } - if payment_term_id: - to_update = invoice_obj.onchange_payment_term_date_invoice(cr, uid, [], payment_term_id, None) - if to_update: - inv.update(to_update['value']) journal = False if exp.journal_id: - inv['journal_id']=exp.journal_id.id + voucher['journal_id'] = exp.journal_id.id journal = exp.journal_id else: journal_id = invoice_obj._get_journal(cr, uid, context={'type': 'in_invoice', 'company_id': company_id}) if journal_id: - inv['journal_id'] = journal_id + voucher['journal_id'] = journal_id journal = account_journal.browse(cr, uid, journal_id) - if journal and not journal.analytic_journal_id: - analytic_journal_ids = analytic_journal_obj.search(cr, uid, [('type','=','purchase')]) - if analytic_journal_ids: - account_journal.write(cr, uid, [journal.id],{'analytic_journal_id':analytic_journal_ids[0]}) - inv_id = invoice_obj.create(cr, uid, inv, {'type': 'in_invoice'}) - invoice_obj.button_compute(cr, uid, [inv_id], {'type': 'in_invoice'}, set_total=True) - self.write(cr, uid, [exp.id], {'invoice_id': inv_id, 'state': 'invoiced'}) - res = inv_id + voucher_id = voucher_obj.create(cr, uid, voucher, context) + aaa = self.write(cr, uid, [exp.id], {'voucher_id': voucher_id, 'state': 'invoiced'}) + res = voucher_id return res hr_expense_expense() diff --git a/addons/hr_expense/hr_expense_view.xml b/addons/hr_expense/hr_expense_view.xml index b8868c3319f..f5967c39e21 100644 --- a/addons/hr_expense/hr_expense_view.xml +++ b/addons/hr_expense/hr_expense_view.xml @@ -116,7 +116,7 @@ - + diff --git a/addons/hr_expense/hr_expense_workflow.xml b/addons/hr_expense/hr_expense_workflow.xml index 328a07879a4..730e6d21e5d 100644 --- a/addons/hr_expense/hr_expense_workflow.xml +++ b/addons/hr_expense/hr_expense_workflow.xml @@ -51,8 +51,8 @@ invoice subflow - - action_invoice_create() + + action_voucher_create() @@ -99,7 +99,7 @@ - subflow.paid + subflow.done diff --git a/addons/hr_expense/report/hr_expense_report.py b/addons/hr_expense/report/hr_expense_report.py index adef11f5269..52f155a8e9e 100644 --- a/addons/hr_expense/report/hr_expense_report.py +++ b/addons/hr_expense/report/hr_expense_report.py @@ -43,7 +43,7 @@ class hr_expense_report(osv.osv): 'employee_id': fields.many2one('hr.employee', "Employee's Name", readonly=True), 'date_confirm': fields.date('Confirmation Date', readonly=True), 'date_valid': fields.date('Validation Date', readonly=True), - 'invoice_id': fields.many2one('account.invoice', 'Invoice', readonly=True), + 'voucher_id': fields.many2one('account.voucher', 'Voucher', readonly=True), 'department_id':fields.many2one('hr.department','Department', readonly=True), 'company_id':fields.many2one('res.company', 'Company', readonly=True), 'user_id':fields.many2one('res.users', 'Validation User', readonly=True), @@ -78,8 +78,8 @@ class hr_expense_report(osv.osv): s.currency_id, to_date(to_char(s.date_confirm, 'dd-MM-YYYY'),'dd-MM-YYYY') as date_confirm, to_date(to_char(s.date_valid, 'dd-MM-YYYY'),'dd-MM-YYYY') as date_valid, - s.invoice_id, - count(s.invoice_id) as invoiced, + s.voucher_id, + count(s.voucher_id) as invoiced, s.user_valid as user_id, s.department_id, to_char(date_trunc('day',s.create_date), 'YYYY') as year, @@ -109,7 +109,7 @@ class hr_expense_report(osv.osv): to_date(to_char(s.date_valid, 'dd-MM-YYYY'),'dd-MM-YYYY'), l.product_id, l.analytic_account, - s.invoice_id, + s.voucher_id, s.currency_id, s.user_valid, s.department_id, diff --git a/addons/hr_expense/report/hr_expense_report_view.xml b/addons/hr_expense/report/hr_expense_report_view.xml index 7877edf4b3a..bfd73f8ed7d 100644 --- a/addons/hr_expense/report/hr_expense_report_view.xml +++ b/addons/hr_expense/report/hr_expense_report_view.xml @@ -13,7 +13,7 @@ - + From 7ceed2bb9b25b516caa5128c21fab424a797dbc0 Mon Sep 17 00:00:00 2001 From: "Divyesh Makwana (Open ERP)" Date: Thu, 12 Jul 2012 12:24:55 +0530 Subject: [PATCH 002/166] [IMP] hr_expense : Improved the test cases in accordance with voucher. bzr revid: mdi@tinyerp.com-20120712065455-0xhhss2jcoo4cyxp --- addons/hr_expense/hr_expense.py | 2 +- addons/hr_expense/test/expense_process.yml | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/addons/hr_expense/hr_expense.py b/addons/hr_expense/hr_expense.py index d5f816268cb..5c8aed03d79 100644 --- a/addons/hr_expense/hr_expense.py +++ b/addons/hr_expense/hr_expense.py @@ -183,7 +183,7 @@ class hr_expense_expense(osv.osv): 'amount': l.unit_amount, 'type': 'dr' })) - total += l.unit_amount + total += l.total_amount if not exp.employee_id.address_home_id: raise osv.except_osv(_('Error !'), _('The employee must have a Home address.')) acc = exp.employee_id.address_home_id.property_account_payable.id diff --git a/addons/hr_expense/test/expense_process.yml b/addons/hr_expense/test/expense_process.yml index 5c8a9d53f7c..2f8fffb786d 100644 --- a/addons/hr_expense/test/expense_process.yml +++ b/addons/hr_expense/test/expense_process.yml @@ -17,22 +17,20 @@ !assert {model: hr.expense.expense, id: sep_expenses, severity: error, string: Expense should be in Approved state}: - state == 'accepted' - - I make Invoice for the expense. + I make Voucher for the expense. - !python {model: hr.expense.expense}: | self.invoice(cr, uid, [ref('sep_expenses')]) - - I check invoice details. + I check voucher details. - !python {model: hr.expense.expense}: | sep_expenses = self.browse(cr, uid, ref("sep_expenses"), context=context) assert sep_expenses.state == 'invoiced', "Expense should be in 'Invoiced' state." - assert sep_expenses.invoice_id, "Expense should have link of Invoice." - assert sep_expenses.invoice_id.currency_id == sep_expenses.currency_id,"Invoice currency is not correspond with supplier invoice currency" - assert sep_expenses.invoice_id.origin == sep_expenses.name,"Invoice origin is not correspond with supplier invoice" - assert sep_expenses.invoice_id.type == 'in_invoice', "Invoice type is not supplier invoice" - assert sep_expenses.invoice_id.amount_total == sep_expenses.amount,"Invoice total amount is not correspond with supplier invoice total" - assert len(sep_expenses.invoice_id.invoice_line) == len(sep_expenses.line_ids),"Lines of Invoice and supplier invoice Line are not correspond" + assert sep_expenses.voucher_id.name == sep_expenses.name,"Voucher name is not correspond with expense name." + assert sep_expenses.voucher_id.type == 'purchase', "Voucher type is not purchase voucher." + assert sep_expenses.voucher_id.amount == sep_expenses.amount,"Voucher total amount is not correspond with expense total." + assert len(sep_expenses.voucher_id.line_dr_ids) == len(sep_expenses.line_ids),"Lines of Voucher and expense line are not correspond." #TODO: check invoice line details with Expenses lines - I pay the expenses. From 3512fd1be0b0aa640b8969e37de3348624c23828 Mon Sep 17 00:00:00 2001 From: "Divyesh Makwana (Open ERP)" Date: Thu, 12 Jul 2012 14:14:07 +0530 Subject: [PATCH 003/166] [IMP] hr_expense : Added 'Total Amount' field in form view. bzr revid: mdi@tinyerp.com-20120712084407-s78a0udwp3ww4npd --- addons/hr_expense/hr_expense_view.xml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/addons/hr_expense/hr_expense_view.xml b/addons/hr_expense/hr_expense_view.xml index f5967c39e21..a143a746667 100644 --- a/addons/hr_expense/hr_expense_view.xml +++ b/addons/hr_expense/hr_expense_view.xml @@ -109,8 +109,15 @@ - - + +
+ + +
+ + + +
From 85cf7c94fd69de1fd8bedbeba85ff7920709010d Mon Sep 17 00:00:00 2001 From: "Divyesh Makwana (Open ERP)" Date: Thu, 12 Jul 2012 14:18:25 +0530 Subject: [PATCH 004/166] [IMP] hr_expense : Improved the code. bzr revid: mdi@tinyerp.com-20120712084825-enistrb9u1fum2at --- addons/hr_expense/hr_expense.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/hr_expense/hr_expense.py b/addons/hr_expense/hr_expense.py index 5c8aed03d79..3b8129914f3 100644 --- a/addons/hr_expense/hr_expense.py +++ b/addons/hr_expense/hr_expense.py @@ -180,7 +180,7 @@ class hr_expense_expense(osv.osv): lines.append((0, False, { 'name': l.name, 'account_id': acc.id, - 'amount': l.unit_amount, + 'amount': l.total_amount, 'type': 'dr' })) total += l.total_amount @@ -196,7 +196,6 @@ class hr_expense_expense(osv.osv): 'company_id': company_id, # 'origin': exp.name, 'line_ids': lines, - 'currency_id': exp.currency_id.id, 'amount': total } journal = False From a4e5ec5ce20ed54f5bdb7f71b948ffea90096ca9 Mon Sep 17 00:00:00 2001 From: "Divyesh Makwana (Open ERP)" Date: Thu, 12 Jul 2012 15:16:45 +0530 Subject: [PATCH 005/166] [IMP] hr_recruitment : Opens the purchase receipt form on voucher_id field. bzr revid: mdi@tinyerp.com-20120712094645-4m86lvzxz4d4wjmx --- addons/account_voucher/voucher_sales_purchase_view.xml | 2 +- addons/hr_expense/hr_expense_view.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/account_voucher/voucher_sales_purchase_view.xml b/addons/account_voucher/voucher_sales_purchase_view.xml index adb078fac22..2c3399da31c 100644 --- a/addons/account_voucher/voucher_sales_purchase_view.xml +++ b/addons/account_voucher/voucher_sales_purchase_view.xml @@ -222,7 +222,7 @@ account.voucher form -
+
diff --git a/addons/hr_expense/hr_expense_workflow.xml b/addons/hr_expense/hr_expense_workflow.xml index 730e6d21e5d..58eed45b1d2 100644 --- a/addons/hr_expense/hr_expense_workflow.xml +++ b/addons/hr_expense/hr_expense_workflow.xml @@ -47,12 +47,12 @@ expense_canceled() - + - invoice + receipt subflow - action_voucher_create() + action_receipt_create() @@ -91,13 +91,13 @@ - - invoice + + receipt - + subflow.done diff --git a/addons/hr_expense/test/expense_process.yml b/addons/hr_expense/test/expense_process.yml index 2f8fffb786d..0ddbca537bf 100644 --- a/addons/hr_expense/test/expense_process.yml +++ b/addons/hr_expense/test/expense_process.yml @@ -20,18 +20,18 @@ I make Voucher for the expense. - !python {model: hr.expense.expense}: | - self.invoice(cr, uid, [ref('sep_expenses')]) + self.receipt(cr, uid, [ref('sep_expenses')]) - I check voucher details. - !python {model: hr.expense.expense}: | sep_expenses = self.browse(cr, uid, ref("sep_expenses"), context=context) - assert sep_expenses.state == 'invoiced', "Expense should be in 'Invoiced' state." + assert sep_expenses.state == 'receipted', "Expense should be in 'Receipted' state." assert sep_expenses.voucher_id.name == sep_expenses.name,"Voucher name is not correspond with expense name." assert sep_expenses.voucher_id.type == 'purchase', "Voucher type is not purchase voucher." assert sep_expenses.voucher_id.amount == sep_expenses.amount,"Voucher total amount is not correspond with expense total." assert len(sep_expenses.voucher_id.line_dr_ids) == len(sep_expenses.line_ids),"Lines of Voucher and expense line are not correspond." - #TODO: check invoice line details with Expenses lines + - I pay the expenses. - From 0fee0b9527a0e46bc55e04570a9570df4e4b174b Mon Sep 17 00:00:00 2001 From: "Divyesh Makwana (Open ERP)" Date: Fri, 13 Jul 2012 17:17:17 +0530 Subject: [PATCH 010/166] [IMP] hr_expense : Improved the code. bzr revid: mdi@tinyerp.com-20120713114717-1gg9xygu4ut3nl64 --- addons/hr_expense/hr_expense.py | 20 ++++++++++---------- addons/hr_expense/test/expense_process.yml | 12 ++++++------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/addons/hr_expense/hr_expense.py b/addons/hr_expense/hr_expense.py index d4c2dfbbf7d..0e413c8e1fe 100644 --- a/addons/hr_expense/hr_expense.py +++ b/addons/hr_expense/hr_expense.py @@ -146,7 +146,7 @@ class hr_expense_expense(osv.osv): res = mod_obj.get_object_reference(cr, uid, 'account_voucher', 'view_purchase_receipt_form') res_id = res and res[1] or False return { - 'name': _('Purchase Receipt'), + 'name': _('Expense Receipt'), 'view_type': 'form', 'view_mode': 'form', 'res_model': 'account.voucher', @@ -169,23 +169,23 @@ class hr_expense_expense(osv.osv): company_id = exp.company_id.id lines = [] total = 0.0 - for l in exp.line_ids: - if l.product_id: - acc = l.product_id.product_tmpl_id.property_account_expense + for line in exp.line_ids: + if line.product_id: + acc = line.product_id.product_tmpl_id.property_account_expense if not acc: - acc = l.product_id.categ_id.property_account_expense_categ + acc = line.product_id.categ_id.property_account_expense_categ else: acc = property_obj.get(cr, uid, 'property_account_expense_categ', 'product.category', context={'force_company': company_id}) if not acc: raise osv.except_osv(_('Error !'), _('Please configure Default Expense account for Product purchase, `property_account_expense_categ`')) lines.append((0, False, { - 'name': l.name, + 'name': line.name, 'account_id': acc.id, - 'amount': l.total_amount, + 'amount': line.total_amount, 'type': 'dr' })) - total += l.total_amount + total += line.total_amount if not exp.employee_id.address_home_id: raise osv.except_osv(_('Error !'), _('The employee must have a Home address.')) acc = exp.employee_id.address_home_id.property_account_payable.id @@ -207,9 +207,9 @@ class hr_expense_expense(osv.osv): journal_id = voucher_obj._get_journal(cr, uid, context={'type': 'purchase', 'company_id': company_id}) if journal_id: voucher['journal_id'] = journal_id - journal = account_journal.browse(cr, uid, journal_id) + journal = account_journal.browse(cr, uid, journal_id, context=context) voucher_id = voucher_obj.create(cr, uid, voucher, context) - self.write(cr, uid, [exp.id], {'voucher_id': voucher_id, 'state': 'receipted'}) + self.write(cr, uid, [exp.id], {'voucher_id': voucher_id, 'state': 'receipted'}, context=context) res = voucher_id return res diff --git a/addons/hr_expense/test/expense_process.yml b/addons/hr_expense/test/expense_process.yml index 0ddbca537bf..65359de95ff 100644 --- a/addons/hr_expense/test/expense_process.yml +++ b/addons/hr_expense/test/expense_process.yml @@ -17,20 +17,20 @@ !assert {model: hr.expense.expense, id: sep_expenses, severity: error, string: Expense should be in Approved state}: - state == 'accepted' - - I make Voucher for the expense. + I make Receipt for the expense. - !python {model: hr.expense.expense}: | self.receipt(cr, uid, [ref('sep_expenses')]) - - I check voucher details. + I check receipt details. - !python {model: hr.expense.expense}: | sep_expenses = self.browse(cr, uid, ref("sep_expenses"), context=context) assert sep_expenses.state == 'receipted', "Expense should be in 'Receipted' state." - assert sep_expenses.voucher_id.name == sep_expenses.name,"Voucher name is not correspond with expense name." - assert sep_expenses.voucher_id.type == 'purchase', "Voucher type is not purchase voucher." - assert sep_expenses.voucher_id.amount == sep_expenses.amount,"Voucher total amount is not correspond with expense total." - assert len(sep_expenses.voucher_id.line_dr_ids) == len(sep_expenses.line_ids),"Lines of Voucher and expense line are not correspond." + assert sep_expenses.voucher_id.name == sep_expenses.name,"Receipt name is not correspond with expense name." + assert sep_expenses.voucher_id.type == 'purchase', "Receipt type is not purchase receipt." + assert sep_expenses.voucher_id.amount == sep_expenses.amount,"Receipt total amount is not correspond with expense total." + assert len(sep_expenses.voucher_id.line_dr_ids) == len(sep_expenses.line_ids),"Lines of Receipt and expense line are not correspond." - I pay the expenses. From e068186c172120a210c0a3bd1194ccf0f95f19ea Mon Sep 17 00:00:00 2001 From: "Divyesh Makwana (Open ERP)" Date: Fri, 13 Jul 2012 18:09:52 +0530 Subject: [PATCH 011/166] [IMP] hr_improvement : Added 'Open Receipt' button to open the receipt in 'receipted' state. bzr revid: mdi@tinyerp.com-20120713123952-gr48p943v6rjon57 --- addons/hr_expense/hr_expense.py | 19 +++++++++++++++++++ addons/hr_expense/hr_expense_view.xml | 1 + 2 files changed, 20 insertions(+) diff --git a/addons/hr_expense/hr_expense.py b/addons/hr_expense/hr_expense.py index 0e413c8e1fe..ee2c92cf483 100644 --- a/addons/hr_expense/hr_expense.py +++ b/addons/hr_expense/hr_expense.py @@ -212,6 +212,25 @@ class hr_expense_expense(osv.osv): self.write(cr, uid, [exp.id], {'voucher_id': voucher_id, 'state': 'receipted'}, context=context) res = voucher_id return res + + def action_view_receipt(self, cr, uid, ids, context=None): + ''' + This function returns an action that display existing receipt of given expense ids. + ''' + voucher_id = self.browse(cr, uid, ids[0], context=context).voucher_id.id + res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account_voucher', 'view_purchase_receipt_form') + result = { + 'name': _('Expense Receipt'), + 'view_type': 'form', + 'view_mode': 'form', + 'view_id': res and res[1] or False, + 'res_model': 'account.voucher', + 'type': 'ir.actions.act_window', + 'nodestroy': True, + 'target': 'current', + 'res_id': voucher_id, + } + return result hr_expense_expense() diff --git a/addons/hr_expense/hr_expense_view.xml b/addons/hr_expense/hr_expense_view.xml index c45c743c1c8..78fa22db4d4 100644 --- a/addons/hr_expense/hr_expense_view.xml +++ b/addons/hr_expense/hr_expense_view.xml @@ -69,6 +69,7 @@
    - +
    @@ -44,6 +44,12 @@
    + +
    + +
    +
    +
    There are pending operations that could not be saved into the database, are you sure you want to exit?
    @@ -531,30 +537,7 @@
    -
    -
    -
    - -
    Help
    -
    -
    -
    -
    - -
    Close
    -
    -
    -
    -
    - -
    Client Mode
    -
    -
    -
      -
    From 48f50f9944f72128119d48bea12670899919bcee Mon Sep 17 00:00:00 2001 From: "Dharti Ratani (OpenERP)" Date: Fri, 20 Jul 2012 18:50:03 +0530 Subject: [PATCH 030/166] Adding a rng for label in digram view bzr revid: dhr@tinyerp.com-20120720132003-kq0ikv9b6ewkasxx --- openerp/addons/base/rng/view.rng | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openerp/addons/base/rng/view.rng b/openerp/addons/base/rng/view.rng index c583040495b..8f7b2647237 100644 --- a/openerp/addons/base/rng/view.rng +++ b/openerp/addons/base/rng/view.rng @@ -184,6 +184,9 @@ + + + From bf7e2b0e762601f5aa2c54323158585649c3d7ac Mon Sep 17 00:00:00 2001 From: "Dharti Ratani (OpenERP)" Date: Fri, 20 Jul 2012 18:54:14 +0530 Subject: [PATCH 031/166] Modifying diagram view to set label in diagram header bzr revid: dhr@tinyerp.com-20120720132414-pdftmig39m3ro93b --- addons/web_diagram/static/src/js/diagram.js | 13 +++++++++++++ addons/web_diagram/static/src/xml/base_diagram.xml | 1 + 2 files changed, 14 insertions(+) diff --git a/addons/web_diagram/static/src/js/diagram.js b/addons/web_diagram/static/src/js/diagram.js index f06e757f7f1..e7e85eea96a 100644 --- a/addons/web_diagram/static/src/js/diagram.js +++ b/addons/web_diagram/static/src/js/diagram.js @@ -51,6 +51,9 @@ instance.web.DiagramView = instance.web.View.extend({ var action = $(this).data('pager-action'); self.on_pager_action(action); }); + this.labels = _.filter(this.fields_view.arch.children, function(label){ + return label.tag == "label" ; + }); this.do_update_pager(); @@ -104,11 +107,21 @@ instance.web.DiagramView = instance.web.View.extend({ ); }, + get_label : function(){ + var self = this + var html_label = _.each(self.labels,function(label){ + html_label = "" + label.attrs.string + "" + self.$element.find('.oe_diagram_diagram_header').append(html_label) + }) + + }, + on_diagram_loaded: function(record) { var id_record = record['id']; if(id_record) { this.id = id_record; this.get_diagram_info(); + this.get_label(); } }, diff --git a/addons/web_diagram/static/src/xml/base_diagram.xml b/addons/web_diagram/static/src/xml/base_diagram.xml index 96e32f59648..40a98a59413 100644 --- a/addons/web_diagram/static/src/xml/base_diagram.xml +++ b/addons/web_diagram/static/src/xml/base_diagram.xml @@ -14,6 +14,7 @@
    +
    From 7a1cee1401bf7c5ea97981a69b4f25a0601ba1bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Fri, 20 Jul 2012 17:24:21 +0200 Subject: [PATCH 032/166] [IMP] point_of_sale: refactored the ean checksum method bzr revid: fva@openerp.com-20120720152421-lfq05r6xkczl1y56 --- addons/product/product.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/addons/product/product.py b/addons/product/product.py index 3cbff880cf9..c50ad3c27b9 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -30,15 +30,10 @@ from tools.translate import _ def is_pair(x): return not x%2 -def check_ean(eancode): - if not eancode: - return True +def ean_checksum(eancode): + """returns the checksum of an ean string of length 13, returns -1 if the string has the wrong length""" if len(eancode) <> 13: - return False - try: - int(eancode) - except: - return False + return -1 oddsum=0 evensum=0 total=0 @@ -54,10 +49,20 @@ def check_ean(eancode): total=(oddsum * 3) + evensum check = int(10 - math.ceil(total % 10.0)) %10 + return check - if check != int(eancode[-1]): +def check_ean(eancode): + """returns True if eancode is a valid ean13 string, or null""" + if not eancode: + return True + if len(eancode) <> 13: return False - return True + try: + int(eancode) + except: + return False + return ean_checksum(eancode) == int(eancode[-1]) + #---------------------------------------------------------- # UOM #---------------------------------------------------------- From f1fbf44b5c9ae1275c9fb9e6a5c1ef8e337742a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Fri, 20 Jul 2012 19:00:12 +0200 Subject: [PATCH 033/166] [WIP] point_of_sale: barcode validation wizard (wip) bzr revid: fva@openerp.com-20120720170012-eqp81clbpbfsr3hl --- addons/point_of_sale/point_of_sale.py | 38 ++++++++++++------ addons/point_of_sale/point_of_sale_view.xml | 44 +++++++++++++++------ addons/product/product.py | 13 ++++++ 3 files changed, 70 insertions(+), 25 deletions(-) diff --git a/addons/point_of_sale/point_of_sale.py b/addons/point_of_sale/point_of_sale.py index ed3fa9c1730..d86d4c3d8ad 100644 --- a/addons/point_of_sale/point_of_sale.py +++ b/addons/point_of_sale/point_of_sale.py @@ -22,6 +22,7 @@ import pdb import io import openerp import addons +import openerp.addons.product.product import time from datetime import datetime @@ -143,8 +144,6 @@ class pos_config(osv.osv): obj.sequence_id.unlink() return super(pos_config, self).unlink(cr, uid, ids, context=context) -pos_config() - class pos_session(osv.osv): _name = 'pos.session' _order = 'id desc' @@ -425,8 +424,6 @@ class pos_session(osv.osv): 'context' : context, } -pos_session() - class pos_order(osv.osv): _name = "pos.order" _description = "Point of Sale" @@ -1038,8 +1035,6 @@ class pos_order(osv.osv): self.create_account_move(cr, uid, ids, context=context) return True -pos_order() - class account_bank_statement(osv.osv): _inherit = 'account.bank.statement' _columns= { @@ -1138,8 +1133,6 @@ class pos_order_line(osv.osv): }) return super(pos_order_line, self).copy_data(cr, uid, id, default, context=context) -pos_order_line() - class pos_category(osv.osv): _name = 'pos.category' _description = "Point of Sale Category" @@ -1211,12 +1204,24 @@ class pos_category(osv.osv): # 'category_image': _get_default_image, #} -pos_category() - import io, StringIO +class ean_wizard(osv.osv_memory): + _name = 'pos.ean_wizard' + _columns = { + 'ean13_pattern': fields.char('Ean13 Pattern', size=32, required=True, translate=True), + } + def sanitize_ean13(self, cr, uid, ids, context): + for r in self.browse(cr,uid,ids): + ean13 = openerp.addons.product.product.sanitize_ean13(r.ean13_pattern) + m = context.get('active_model') + m_id = context.get('active_id') + self.pool.get(m).write(cr,uid,[m_id],{'ean13':ean13}) + class product_product(osv.osv): _inherit = 'product.product' + + def _get_small_image(self, cr, uid, ids, prop, unknow_none, context=None): result = {} for obj in self.browse(cr, uid, ids, context=context): @@ -1247,7 +1252,16 @@ class product_product(osv.osv): 'to_weight' : False, } -product_product() - + def add_ean13(self, cr, uid, ids, context): + return { + 'name': _('Return Products'), + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'pos.ean_wizard', + 'target' : 'new', + 'view_id': False, + 'context':context, + } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/point_of_sale_view.xml b/addons/point_of_sale/point_of_sale_view.xml index f3b491116b7..1145189b408 100644 --- a/addons/point_of_sale/point_of_sale_view.xml +++ b/addons/point_of_sale/point_of_sale_view.xml @@ -618,12 +618,22 @@ form - - - - - - + + + + + + + + + + + + + + +
    -
    +
    Change: @@ -269,6 +269,9 @@

    Please scan an item or your member card

    +
    +

    Thank you for shopping with us.

    +
    From 7dabfe49eaa00d42649910af355811c6c2fd2512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 30 Jul 2012 17:42:28 +0200 Subject: [PATCH 054/166] [FIX] point_of_sale: removing useless console.log bzr revid: fva@openerp.com-20120730154228-5vabk5qyvjez9dgk --- addons/point_of_sale/static/src/js/pos_screens.js | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/point_of_sale/static/src/js/pos_screens.js b/addons/point_of_sale/static/src/js/pos_screens.js index f79b60052c0..07f1071fa6d 100644 --- a/addons/point_of_sale/static/src/js/pos_screens.js +++ b/addons/point_of_sale/static/src/js/pos_screens.js @@ -581,7 +581,6 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa var self = this; $('.goodbye-message').css({opacity:1}).show(); setTimeout(function(){ - console.log('kill'); $('.goodbye-message').animate({opacity:0},500,'swing',function(){$('.goodbye-message').hide();}); },3000); }, From 03a3533dc5519e15b3725e037c4017732dca7181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Thu, 2 Aug 2012 16:18:01 +0200 Subject: [PATCH 055/166] [WIP] point_of_sale: IndexedDB Backend bzr revid: fva@openerp.com-20120802141801-hpjqwkwlooqdaddu --- addons/point_of_sale/static/src/js/db.js | 66 ++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 addons/point_of_sale/static/src/js/db.js diff --git a/addons/point_of_sale/static/src/js/db.js b/addons/point_of_sale/static/src/js/db.js new file mode 100644 index 00000000000..86ad9a53a59 --- /dev/null +++ b/addons/point_of_sale/static/src/js/db.js @@ -0,0 +1,66 @@ +function openerp_pos_db(instance, module){ + function importIndexedDB(){ + if('indexedDB' in window){ + return true; + }else if('webkitIndexedDB' in window){ + window.indexedDB = window.webkitIndexedDB; + window.IDBCursor = window.webkitIDBCursor; + window.IDBDatabase = window.webkitIDBDatabase; + window.IDBDatabaseError = window.webkitIDBDatabaseError; + window.IDBDatabaseException = window.webkitIDBDatabaseException; + window.IDBFactory = window.webkitIDBFactory; + window.IDBIndex = window.webkitIDBIndex; + window.IDBKeyRange = window.webkitIDBKeyRange; + window.IDBObjectSrore = window.webkitIDBOjbectStore; + window.IDBRequest = window.webkitIDBRequest; + window.IDBTransaction = window.webkitIDBTransaction; + }else if('mozIndexedDB' in window){ + window.indexedDB = window.mozIndexedDB; + }else{ + throw new Error("DATABASE ERROR: IndexedDB not implemented. Please upgrade your web browser"); + } + } + importIndexedDB(); + + modula.PosDB = modula.Class.extend({ + + state: 'connecting', // 'connecting' || 'connected' || 'failed' + version: 1, + name: 'openerp_pos_db', + + init: function(options){ + var open_request = indexedDB.open(this.name, this.version); + }, + upgrade_db: function(oldversion, transaction){ + this.db = transaction.db; + var productStore = this.db.createObjectStore("products", {keyPath: "id"}); + + productStore.createIndex("ean13", "ean13", {unique:true}); + + productStore.createIndex("name", "name", {unique:false}); + + productStore.createIndex("category","category", {unique:false}); + + var imageStore = this.db.createObjectStore("images", {keyPath: "id"}); + + imageStore.createIndex("product_id", "product_id", {unique:true}); + }, + _add_data: function(store, data, result_callback){ + var transaction = this.db.transaction([store], IDBTransaction.READ_WRITE); + + transaction.oncomplete = function(event){ if(result_callback){ result_callback(event); }}; + + }, + add_product: function(product){ + }, + get_product_by_ean: function(ean, result_callback){ + }, + get_product_by_category: function(category, result_callback){ + }, + get_product_image: function(product, result_callback){ + }, + search_product: function(query,result_callback){ + }, + }); + +} From 996183acf719efb7bf44cef3c9709cedc866a0d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 6 Aug 2012 17:40:54 +0200 Subject: [PATCH 056/166] [WIP] point_of_sale: indexedDB backend bzr revid: fva@openerp.com-20120806154054-1yubgy8o8wwlc5b8 --- addons/point_of_sale/__openerp__.py | 1 + addons/point_of_sale/static/src/js/db.js | 66 ------------------- .../point_of_sale/static/src/js/pos_main.js | 2 + .../point_of_sale/static/src/js/pos_models.js | 1 + .../static/src/js/pos_widgets.js | 2 + 5 files changed, 6 insertions(+), 66 deletions(-) delete mode 100644 addons/point_of_sale/static/src/js/db.js diff --git a/addons/point_of_sale/__openerp__.py b/addons/point_of_sale/__openerp__.py index 9d985d40408..c4258511a68 100644 --- a/addons/point_of_sale/__openerp__.py +++ b/addons/point_of_sale/__openerp__.py @@ -86,6 +86,7 @@ Main features: 'js': [ 'static/lib/backbone/backbone-0.9.2.js', 'static/lib/mousewheel/jquery.mousewheel-3.0.6.js', + 'static/src/js/pos_db.js', 'static/src/js/pos_models.js', 'static/src/js/pos_basewidget.js', 'static/src/js/pos_keyboard_widget.js', diff --git a/addons/point_of_sale/static/src/js/db.js b/addons/point_of_sale/static/src/js/db.js deleted file mode 100644 index 86ad9a53a59..00000000000 --- a/addons/point_of_sale/static/src/js/db.js +++ /dev/null @@ -1,66 +0,0 @@ -function openerp_pos_db(instance, module){ - function importIndexedDB(){ - if('indexedDB' in window){ - return true; - }else if('webkitIndexedDB' in window){ - window.indexedDB = window.webkitIndexedDB; - window.IDBCursor = window.webkitIDBCursor; - window.IDBDatabase = window.webkitIDBDatabase; - window.IDBDatabaseError = window.webkitIDBDatabaseError; - window.IDBDatabaseException = window.webkitIDBDatabaseException; - window.IDBFactory = window.webkitIDBFactory; - window.IDBIndex = window.webkitIDBIndex; - window.IDBKeyRange = window.webkitIDBKeyRange; - window.IDBObjectSrore = window.webkitIDBOjbectStore; - window.IDBRequest = window.webkitIDBRequest; - window.IDBTransaction = window.webkitIDBTransaction; - }else if('mozIndexedDB' in window){ - window.indexedDB = window.mozIndexedDB; - }else{ - throw new Error("DATABASE ERROR: IndexedDB not implemented. Please upgrade your web browser"); - } - } - importIndexedDB(); - - modula.PosDB = modula.Class.extend({ - - state: 'connecting', // 'connecting' || 'connected' || 'failed' - version: 1, - name: 'openerp_pos_db', - - init: function(options){ - var open_request = indexedDB.open(this.name, this.version); - }, - upgrade_db: function(oldversion, transaction){ - this.db = transaction.db; - var productStore = this.db.createObjectStore("products", {keyPath: "id"}); - - productStore.createIndex("ean13", "ean13", {unique:true}); - - productStore.createIndex("name", "name", {unique:false}); - - productStore.createIndex("category","category", {unique:false}); - - var imageStore = this.db.createObjectStore("images", {keyPath: "id"}); - - imageStore.createIndex("product_id", "product_id", {unique:true}); - }, - _add_data: function(store, data, result_callback){ - var transaction = this.db.transaction([store], IDBTransaction.READ_WRITE); - - transaction.oncomplete = function(event){ if(result_callback){ result_callback(event); }}; - - }, - add_product: function(product){ - }, - get_product_by_ean: function(ean, result_callback){ - }, - get_product_by_category: function(category, result_callback){ - }, - get_product_image: function(product, result_callback){ - }, - search_product: function(query,result_callback){ - }, - }); - -} diff --git a/addons/point_of_sale/static/src/js/pos_main.js b/addons/point_of_sale/static/src/js/pos_main.js index 71ac69c6067..b9263b91314 100644 --- a/addons/point_of_sale/static/src/js/pos_main.js +++ b/addons/point_of_sale/static/src/js/pos_main.js @@ -5,6 +5,8 @@ openerp.point_of_sale = function(instance) { var module = instance.point_of_sale; + openerp_pos_db(instance,module); // import db.js + openerp_pos_models(instance,module); // import pos_models.js openerp_pos_basewidget(instance,module); // import pos_basewidget.js diff --git a/addons/point_of_sale/static/src/js/pos_models.js b/addons/point_of_sale/static/src/js/pos_models.js index 548b6b749f9..634e0d9b862 100644 --- a/addons/point_of_sale/static/src/js/pos_models.js +++ b/addons/point_of_sale/static/src/js/pos_models.js @@ -74,6 +74,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal this.weightable_categories = []; // a flat list of all categories that directly contain weightable products this.barcode_reader = new module.BarcodeReader({'pos': this}); // used to read barcodes this.proxy = new module.ProxyDevice(); // used to communicate to the hardware devices via a local proxy + this.db = new module.PosDB(); // a database used to store the products and product images // pos settings this.use_scale = false; diff --git a/addons/point_of_sale/static/src/js/pos_widgets.js b/addons/point_of_sale/static/src/js/pos_widgets.js index b41ccbfcc9a..a30a0ebe521 100644 --- a/addons/point_of_sale/static/src/js/pos_widgets.js +++ b/addons/point_of_sale/static/src/js/pos_widgets.js @@ -968,12 +968,14 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa }); }, close: function() { + var self = this; this.pos.barcode_reader.disconnect(); return new instance.web.Model("ir.model.data").get_func("search_read")([['name', '=', 'action_pos_close_statement']], ['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.result; action.context = _.extend(action.context || {}, {'cancel_action': {type: 'ir.actions.client', tag: 'reload'}}); + //self.destroy(); this.do_action(action); }, this)); }, this)); From dc8f543d17a7840b6c02729c2649d0bb37538710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Tue, 7 Aug 2012 18:18:44 +0200 Subject: [PATCH 057/166] [WIP] point_of_sale: indexeddb : compatible localstorage backend. + anthony's modifications to the views... bzr revid: fva@openerp.com-20120807161844-hd7ioxipnc6794jf --- addons/point_of_sale/point_of_sale_view.xml | 62 +-- addons/point_of_sale/static/src/js/pos_db.js | 466 ++++++++++++++++++ .../point_of_sale/static/src/js/pos_models.js | 2 +- .../wizard/pos_session_opening.xml | 2 +- 4 files changed, 487 insertions(+), 45 deletions(-) create mode 100644 addons/point_of_sale/static/src/js/pos_db.js diff --git a/addons/point_of_sale/point_of_sale_view.xml b/addons/point_of_sale/point_of_sale_view.xml index 6a43cec39be..9aa9c095f65 100644 --- a/addons/point_of_sale/point_of_sale_view.xml +++ b/addons/point_of_sale/point_of_sale_view.xml @@ -3,10 +3,6 @@ - Others @@ -155,9 +151,6 @@ - - - Products @@ -170,10 +163,7 @@ You must define a Product for everything you buy or sell. Products can be raw materials, stockable products, consumables or services. The Product form contains detailed information about your products related to procurement logistics, sales price, product category, suppliers and so on. - + Sale lines @@ -673,11 +663,8 @@ tree,form - - Payment Methods @@ -689,10 +676,6 @@ Payment methods are defined by accounting journals having the field Payment Method checked. - POS Sales Lines @@ -716,9 +699,6 @@ - - - Invoices @@ -729,8 +709,6 @@ [('origin','like','POS')] - Start Point of Sale @@ -848,11 +826,6 @@ - - - - - pos.order.list.select pos.order @@ -1034,7 +993,6 @@ - pos.ean_wizard @@ -1050,6 +1008,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/addons/point_of_sale/static/src/js/pos_db.js b/addons/point_of_sale/static/src/js/pos_db.js new file mode 100644 index 00000000000..a38457a9f8d --- /dev/null +++ b/addons/point_of_sale/static/src/js/pos_db.js @@ -0,0 +1,466 @@ +/** + * This file contains an IndexedDB (html5 database) backend for the Point Of Sale. + * The IDB is used to store the list of products and especially their thumbnails, which may + * not fit in the localStorage. + * The IDB offers a big performance boost for products lookup, but not so much for search as + * searching is not yet implemented in the IndexedDB API and must be performed manually in JS. + * + */ +function openerp_pos_db(instance, module){ + + // this is used for testing + window.gen_products = function(options){ + options = options || {}; + var count = options.count || 100; + var imageSize = options.imageSize || 1800; + + var imagedata = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']; + + function gen_image(){ + var image = ''; + for(var i = 0; i < imageSize; i++){ + image += imagedata[Math.floor(Math.random()*imagedata.length)]; + } + return image; + } + + var categories = [ 'drinks', 'food', 'beers', 'meat', 'fruits', 'candy', 'bread', 'fruity beers', 'tea', 'coffee' ]; + var syllabes = [ + 'ko','no','mo','ro','do','so','ho','to','yo', + 'ke','ne','me','re','de','se','he','te','ye', + 'ki','ni','mi','ri','di','si','hi','ti','yi', + 'ku','nu','mu','ru','du','su','hu','tu','yu', + 'ka','na','ma','ra','da','sa','ha','ta','ya', + ' ', '-', '!', ' ', ' ', '-', ' ', ' ', ' ', + ]; + var id = 1284; + var ean = 845923; + + function gen_product(){ + var name = ''; + var sc = Math.ceil(Math.random()*10); + for(var i = 0; i < sc; i++){ + name = name + syllabes[Math.floor(Math.random()*syllabes.length)]; + } + return { + id: ''+(id++), + price: Math.random()*100, + ean13:''+(ean++), + name: name, + category: categories[Math.floor(Math.random()*categories.length)], + product_image_small: gen_image(), + }; + } + + var products = []; + for(var i = 0; i < count; i++){ + products.push(gen_product()); + } + return products; + }; + + //this is used for testing + window.log = function(x){ + console.log(x); + }; + + function importIndexedDB(){ + if('indexedDB' in window){ + return true; + }else if('webkitIndexedDB' in window){ + window.indexedDB = window.webkitIndexedDB; + window.IDBCursor = window.webkitIDBCursor; + window.IDBDatabase = window.webkitIDBDatabase; + window.IDBDatabaseError = window.webkitIDBDatabaseError; + window.IDBDatabaseException = window.webkitIDBDatabaseException; + window.IDBFactory = window.webkitIDBFactory; + window.IDBIndex = window.webkitIDBIndex; + window.IDBKeyRange = window.webkitIDBKeyRange; + window.IDBObjectSrore = window.webkitIDBOjbectStore; + window.IDBRequest = window.webkitIDBRequest; + window.IDBTransaction = window.webkitIDBTransaction; + }else if('mozIndexedDB' in window){ + window.indexedDB = window.mozIndexedDB; + }else{ + throw new Error("DATABASE ERROR: IndexedDB not implemented. Please upgrade your web browser"); + } + } + importIndexedDB(); + + module.PosDB = instance.web.Class.extend({ + + version: 1, + name: 'openerp_pos_db', + limit: 50, + + init: function(options){ + var self = this; + options = options || {}; + + this.version = options.version || this.version; + this.name = options.name || this.name; + + var open_request = indexedDB.open(this.name, this.version); + + open_request.onblocked = function(event){ + throw new Error("DATABASE ERROR: request blocked."); + }; + + // new API (firefox) + open_request.onupgradeneeded = function(event){ + console.log('using new API'); + var transaction = open_request.transaction; + self._upgrade_db(event.oldVersion,transaction); + }; + + open_request.onsuccess = function(event){ + console.log('db',self.db); + self.db = open_request.result; + var oldVersion = Number(self.db.version); + + if(oldVersion !== self.version){ + // if we get to this point, it means that onupgradeneeded hasn't been called. + // so we try the old api (webkit) + if(!self.db.setVersion){ + throw new Error("DATABASE ERROR: database API is broken. Your web browser is probably out of date"); + } + console.log('using old API'); + var version_request = self.db.setVersion(self.version); + version_request.onsuccess = function(event){ + var transaction = version_request.result; + self._upgrade_db(oldVersion, transaction); + }; + } + }; + }, + _upgrade_db: function(oldversion, transaction){ + console.log('upgrade_db:',oldversion); + + this.db = transaction.db; + var productStore = this.db.createObjectStore('products', {keyPath: 'id'}); + + productStore.createIndex('ean13', 'ean13', {unique:true}); + + productStore.createIndex('name', 'name', {unique:false}); + + productStore.createIndex('category','category', {unique:false}); + + var imageStore = this.db.createObjectStore('images', {keyPath: 'id'}); + }, + + _add_data: function(store, data){ + var transaction = this.db.transaction([store], 'readwrite'); + var objectStore = transaction.objectStore(store); + var request = objectStore.put(data); + }, + /* adds a product to the database, replacing the original product if it is already present. + * the product must be provided as a json as returned by the openerp backend + */ + add_product: function(product){ + if(product instanceof Array){ + for(var i = 0, len = product.length; i < len; i++){ + this.add_product(product[i]); + } + }else{ + if(product.product_image_small){ + var image = product.product_image_small; + var product = _.clone(product); + delete product['product_image_small']; + this._add_data('images', { id: product.id, image:image}); + } + this._add_data('products',product); + } + }, + + /* removes all the data in the database ! */ + clear: function(done_callback){ + var transaction = this.db.transaction(['products','images'],'readwrite'); + transaction.objectStore('products').clear(); + transaction.objectStore('images').clear(); + if(done_callback){ + transaction.oncomplete = function(){ done_callback(); }; + } + }, + + get_product_count: function(result_callback){ + this.db.transaction('products').objectStore('products').count().onsuccess = function(event){ + result_callback(event.target.result); + }; + }, + + get_image_count: function(result_callback){ + this.db.transaction('images').objectStore('images').count().onsuccess = function(event){ + result_callback(event.target.result); + }; + }, + + /* fetches a product with an id of 'id', returns the product as the first parameter + * of the result_callback function + */ + get_product_by_id: function(id, result_callback){ + var transaction = this.db.transaction('products'); + var objectStore = transaction.objectStore('products'); + var request = objectStore.get(id); + request.onsuccess = function(event){ + if(result_callback){ + result_callback(event.target.result); + } + }; + }, + get_product_by_name: function(name, result_callback){ + var transaction = this.db.transaction('products'); + var objectStore = transaction.objectStore('products'); + var index = objectStore.index('name'); + index.get(name).onsuccess = function(event){ + result_callback(event.target.result); + }; + }, + /* fetches the product with the ean13 matching the one provided. returns the product + * as the first parameter of the result_callback function + */ + get_product_by_ean13: function(ean13, result_callback){ + var transaction = this.db.transaction('products'); + var objectStore = transaction.objectStore('products'); + var index = objectStore.index('ean13'); + index.get(ean13).onsuccess = function(event){ + result_callback(event.target.result); + }; + }, + /* fetches all products belonging to a category, and returns the list of products + * as the first paramter of the result_callback function + */ + get_product_by_category: function(category, result_callback){ + var transaction = this.db.transaction('products'); + var objectStore = transaction.objectStore('products'); + var index = objectStore.index('category'); + var list = []; + index.openCursor(IDBKeyRange.only(category)).onsuccess = function(event){ + var cursor = event.target.result; + if(cursor){ + list.push(cursor.value); + cursor.continue(); + }else{ + result_callback(list); + } + }; + }, + /* Fetches a picture associated with a product. + * product: This is a product json object as returned by the openerp backend. + * result_callback: a callback that gets the image data as parameter. + */ + get_product_image: function(product, result_callback){ + var transaction = this.db.transaction('images'); + var objectStore = transaction.objectStore('images'); + var request = objectStore.get(product.id); + request.onsuccess = function(event){ + result_callback(event.target.result.image); + } + }, + /* fields: a string or a list of string representing the list of the fields that + * will be searched. the values of those field must be a string. + * query: a string that will be matched in the content of one of the searched fields. + * result_callback: a function that will be called with a list of all the products with + * a field that match the query. + */ + search_product: function(fields,query,result_callback){ + var transaction = this.db.transaction('products'); + var objectStore = transaction.objectStore('products'); + var list = []; + if(!(fields instanceof Array)){ + fields = [ fields ]; + } + query = query.toLowerCase(); + objectStore.openCursor().onsuccess = function(event){ + var cursor = event.target.result; + if(cursor){ + var obj = cursor.value; + for(var i = 0, len = fields.length; i < len; i++){ + if(obj[fields[i]].toLowerCase().indexOf(query) != -1){ + list.push(obj); + break; + } + } + cursor.continue(); + }else{ + result_callback(list); + } + } + }, + for_all_products: function(callback){ + var transaction = this.db.transaction('products'); + var objectStore = transaction.objectStore('products'); + objectStore.openCursor().onsuccess = function(event){ + var cursor = event.target.result; + if(cursor){ + var ret = callback(cursor.value); + if(ret !== 'break'){ + cursor.continue(); + } + } + }; + }, + }); + window.PosDB = module.PosDB; + + module.PosLS = instance.web.Class.extend({ + name: 'openerp_pos_ls', + limit: 50, + init: function(options){ + options = options || {}; + this.name = options.name || this.name; + this.limit = options.limit || this.limit; + this.products = this.name + '_products'; + this.images = this.name + '_images'; + }, + _get_products: function(){ + var products = localStorage[this.products]; + if(products){ + return JSON.parse(products) || {}; + }else{ + return {}; + } + }, + _set_products: function(products){ + localStorage[this.products] = JSON.stringify(products); + }, + _get_images: function(){ + var images = localStorage[this.images]; + if(images){ + return JSON.parse(images) || {}; + }else{ + return {}; + } + }, + _set_images: function(images){ + localStorage[this.images] = JSON.stringify(images); + }, + add_product: function(products){ + var stored_images = this._get_images(); + var stored_products = this._get_products(); + + if(!products instanceof Array){ + products = [products]; + } + for(var i = 0, len = products.length; i < len; i++){ + var product = products[i]; + if(product.product_image_small){ + product = _.clone(product); + stored_images[product.id] = product.product_image_small; + delete product['product_image_small']; + } + stored_products[product.id] = product; + } + this._set_images(stored_images); + this._set_products(stored_products); + }, + clear: function(done_callback){ + localStorage.removeItem(this.products); + localStorage.removeItem(this.images); + }, + _count_props : function(obj){ + if(obj.__count__){ + return obj.__count__; + }else{ + var count = 0; + for(var prop in obj){ + if(obj.hasOwnProperty(prop)){ + count++; + } + } + return count; + } + }, + get_product_count: function(result_callback){ + result_callback(this._count_props(this._get_products())); + }, + get_image_count: function(result_callback){ + result_callback(this._count_props(this._get_images())); + }, + get_product_by_id: function(id, result_callback){ + var products = this._get_products(); + result_callback( products[id] ); + }, + get_product_by_name: function(name, result_callback){ + var products = this._get_products(); + for(var i in products){ + if(products[i] && products[i].name === name){ + result_callback(products[i]); + return; + } + } + result_callback(undefined); + }, + get_product_by_ean13: function(ean13, result_callback){ + var products = this._get_products(); + for(var i in products){ + if( products[i] && products[i].ean13 === ean13){ + result_callback(products[i]); + return; + } + } + result_callback(undefined); + }, + get_product_by_category: function(category, result_callback){ + var products = this._get_products(); + var list = []; + for(var i in products){ + if( products[i] && products[i].category === category){ + list.push(products[i]); + } + } + result_callback(list); + }, + get_product_image: function(product, result_callback){ + var images = this._get_images(); + result_callback(images[product.id]); + }, + search_product: function(fields, query, result_callback){ + var products = this._get_products(); + var list = []; + if(typeof query !== 'string'){ + if(query.toString){ + query = query.toString(); + }else{ + throw new Error('search_product: the query must be a string or must be convertible to string'); + } + } + + query = query.toLowerCase(); + + if(!(fields instanceof Array)){ + fields = [fields]; + } + for(var i in products){ + for(var j = 0, jlen = fields.length; j < jlen; j++){ + var field = products[i][fields[j]]; + if(field === null || field === undefined){ + continue; + } + if(typeof field !== 'string'){ + if(field.toString){ + field = field.toString(); + }else{ + continue; + } + } + if(field.toLowerCase().indexOf(query) != -1){ + list.push(products[i]); + break; + } + } + } + result_callback(list); + }, + for_all_products: function(callback){ + var products = this._get_products(); + for(var i in products){ + var ret = callback(products[i]); + if(ret === 'break'){ + break; + } + } + }, + }); + + window.PosLS = module.PosLS; +} diff --git a/addons/point_of_sale/static/src/js/pos_models.js b/addons/point_of_sale/static/src/js/pos_models.js index 634e0d9b862..b4684c037b2 100644 --- a/addons/point_of_sale/static/src/js/pos_models.js +++ b/addons/point_of_sale/static/src/js/pos_models.js @@ -74,7 +74,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal this.weightable_categories = []; // a flat list of all categories that directly contain weightable products this.barcode_reader = new module.BarcodeReader({'pos': this}); // used to read barcodes this.proxy = new module.ProxyDevice(); // used to communicate to the hardware devices via a local proxy - this.db = new module.PosDB(); // a database used to store the products and product images + this.db = new module.PosLS(); // a database used to store the products and product images // pos settings this.use_scale = false; diff --git a/addons/point_of_sale/wizard/pos_session_opening.xml b/addons/point_of_sale/wizard/pos_session_opening.xml index 226edf70b62..ec7fae9c07e 100644 --- a/addons/point_of_sale/wizard/pos_session_opening.xml +++ b/addons/point_of_sale/wizard/pos_session_opening.xml @@ -28,7 +28,7 @@ pos.session.opening form form - new + inline From 03b79a983280fab5180ce0f7fe281e320ff729b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Thu, 9 Aug 2012 19:21:13 +0200 Subject: [PATCH 058/166] [WIP] point_of_sale: much progress on the indexeddb backend bzr revid: fva@openerp.com-20120809172113-ex3o5vyt4ckv4au6 --- addons/point_of_sale/static/src/js/pos_db.js | 225 +++++++++++++----- .../static/src/js/pos_devices.js | 63 ++--- .../point_of_sale/static/src/js/pos_models.js | 181 +++----------- .../static/src/js/pos_screens.js | 25 +- .../static/src/js/pos_widgets.js | 132 +++------- 5 files changed, 275 insertions(+), 351 deletions(-) diff --git a/addons/point_of_sale/static/src/js/pos_db.js b/addons/point_of_sale/static/src/js/pos_db.js index a38457a9f8d..59ea0da1684 100644 --- a/addons/point_of_sale/static/src/js/pos_db.js +++ b/addons/point_of_sale/static/src/js/pos_db.js @@ -146,6 +146,8 @@ function openerp_pos_db(instance, module){ productStore.createIndex('category','category', {unique:false}); var imageStore = this.db.createObjectStore('images', {keyPath: 'id'}); + + var categoryStore = this.db.createObjectStore('categories', {keypath:'name'}); }, _add_data: function(store, data){ @@ -286,6 +288,9 @@ function openerp_pos_db(instance, module){ } } }, + /* the callback function will be called with all products as parameter, by increasing id. + * if the callback returns 'break' the iteration will stop + */ for_all_products: function(callback){ var transaction = this.db.transaction('products'); var objectStore = transaction.objectStore('products'); @@ -299,6 +304,29 @@ function openerp_pos_db(instance, module){ } }; }, + /* the callback function will be called with all products as parameter by increasing id. + * if the callback returns 'break', the iteration will stop + * if the callback returns a product object, it will be inserted in the db, possibly + * overwriting an existing product. The intended usage is for the callback to return a + * modified version version of the product with the same id. Anything else and you're on your own. + */ + modify_all_products: function(callback){ + var transaction = this.db.transaction('products','readwrite'); + var objectStore = transaction.objectStore('products'); + objectStore.openCursor().onsuccess = function(event){ + var cursor = event.target.result; + if(cursor){ + var ret = callback(cursor.value); + if(ret === undefined || ret === null){ + cursor.continue(); + }else if(ret === 'break'){ + return; + }else{ + objectStore.put(ret); + } + } + }; + }, }); window.PosDB = module.PosDB; @@ -310,7 +338,74 @@ function openerp_pos_db(instance, module){ this.name = options.name || this.name; this.limit = options.limit || this.limit; this.products = this.name + '_products'; - this.images = this.name + '_images'; + this.categories = this.name + '_categories'; + + this.category_by_id = {}; + this.root_category_id = 0; + this.category_products = {}; + this.category_ancestors = {}; + this.category_childs = {}; + this.category_parent = {}; + }, + get_category_by_id: function(categ_id){ + if(categ_id instanceof Array){ + var list = []; + for(var i = 0, len = categ_id.length; i < len; i++){ + var cat = this.category_by_id[categ_id[i]]; + if(cat){ + list.push(cat); + }else{ + console.error("get_category_by_id: no category has id:",categ_id[i]); + } + } + return list; + }else{ + return this.category_by_id[categ_id]; + } + }, + get_category_childs_ids: function(categ_id){ + return this.category_childs[categ_id] || []; + }, + get_category_ancestors_ids: function(categ_id){ + return this.category_ancestors[categ_id] || []; + }, + get_category_parent_id: function(categ_id){ + return this.category_parent[categ_id] || this.root_category_id; + }, + add_categories: function(categories){ + var self = this; + if(!this.category_by_id[this.root_category_id]){ + this.category_by_id[this.root_category_id] = { + id : this.root_category_id, + name : 'Root', + }; + } + for(var i=0, len = categories.length; i < len; i++){ + console.log('putting category : ',categories[i].id, categories[i].name); + this.category_by_id[categories[i].id] = categories[i]; + } + for(var i=0, len = categories.length; i < len; i++){ + var cat = categories[i]; + var parent_id = cat.parent_id[0] || this.root_category_id; + console.log('category parent',cat.id, parent_id); + this.category_parent[cat.id] = cat.parent_id[0]; + if(!this.category_childs[parent_id]){ + this.category_childs[parent_id] = []; + } + this.category_childs[parent_id].push(cat.id); + } + function make_ancestors(cat_id, ancestors){ + self.category_ancestors[cat_id] = ancestors; + + ancestors = ancestors.slice(0); + ancestors.push(cat_id); + + var childs = self.category_childs[cat_id] || []; + for(var i=0, len = childs.length; i < len; i++){ + make_ancestors(childs[i], ancestors); + } + } + make_ancestors(this.root_category_id, []); }, _get_products: function(){ var products = localStorage[this.products]; @@ -323,39 +418,51 @@ function openerp_pos_db(instance, module){ _set_products: function(products){ localStorage[this.products] = JSON.stringify(products); }, - _get_images: function(){ - var images = localStorage[this.images]; - if(images){ - return JSON.parse(images) || {}; + _get_categories: function(){ + var categories = localStorage[this.categories]; + if(categories){ + return JSON.parse(categories) || {}; }else{ return {}; } }, - _set_images: function(images){ - localStorage[this.images] = JSON.stringify(images); + _set_categories: function(categories){ + localStorage[this.categories] = JSON.stringify(categories); }, add_product: function(products){ - var stored_images = this._get_images(); var stored_products = this._get_products(); + var stored_categories = this._get_categories(); if(!products instanceof Array){ products = [products]; } for(var i = 0, len = products.length; i < len; i++){ var product = products[i]; - if(product.product_image_small){ - product = _.clone(product); - stored_images[product.id] = product.product_image_small; - delete product['product_image_small']; + var categ_id = product.pos_categ_id[0]; + if(!stored_categories[categ_id]){ + stored_categories[categ_id] = []; + } + stored_categories[categ_id].push(product.id); + var ancestors = this.get_category_ancestors_ids(categ_id) || []; + console.log('ancestors:',ancestors); + + for(var j = 0; j < ancestors.length; j++){ + if(! stored_categories[ancestors[j]]){ + stored_categories[ancestors[j]] = []; + } + stored_categories[ancestors[j]].push(product.id); } stored_products[product.id] = product; } - this._set_images(stored_images); this._set_products(stored_products); + this._set_categories(stored_categories); }, clear: function(done_callback){ localStorage.removeItem(this.products); - localStorage.removeItem(this.images); + localStorage.removeItem(this.categories); + if(done_callback){ + done_callback(); + } }, _count_props : function(obj){ if(obj.__count__){ @@ -373,9 +480,6 @@ function openerp_pos_db(instance, module){ get_product_count: function(result_callback){ result_callback(this._count_props(this._get_products())); }, - get_image_count: function(result_callback){ - result_callback(this._count_props(this._get_images())); - }, get_product_by_id: function(id, result_callback){ var products = this._get_products(); result_callback( products[id] ); @@ -400,66 +504,55 @@ function openerp_pos_db(instance, module){ } result_callback(undefined); }, - get_product_by_category: function(category, result_callback){ - var products = this._get_products(); + get_product_by_category: function(category_id, result_callback){ + var stored_categories = this._get_categories(); + var stored_products = this._get_products(); + var product_ids = stored_categories[category_id]; var list = []; - for(var i in products){ - if( products[i] && products[i].category === category){ - list.push(products[i]); - } + for(var i = 0, len = product_ids.length; i < len; i++){ + list.push(stored_products[product_ids[i]]); } result_callback(list); }, - get_product_image: function(product, result_callback){ - var images = this._get_images(); - result_callback(images[product.id]); - }, - search_product: function(fields, query, result_callback){ - var products = this._get_products(); - var list = []; - if(typeof query !== 'string'){ - if(query.toString){ - query = query.toString(); - }else{ - throw new Error('search_product: the query must be a string or must be convertible to string'); + search_product_in_category: function(category_id, fields, query, result_callback){ + var self = this; + this.get_product_by_category(category_id, function(products){ + var list = []; + + query = query.toString().toLowerCase(); + + if(!(fields instanceof Array)){ + fields = [fields]; } - } - - query = query.toLowerCase(); - - if(!(fields instanceof Array)){ - fields = [fields]; - } - for(var i in products){ - for(var j = 0, jlen = fields.length; j < jlen; j++){ - var field = products[i][fields[j]]; - if(field === null || field === undefined){ - continue; - } - if(typeof field !== 'string'){ - if(field.toString){ - field = field.toString(); - }else{ + for(var i in products){ + for(var j = 0, jlen = fields.length; j < jlen; j++){ + var field = products[i][fields[j]]; + if(field === null || field === undefined){ continue; } - } - if(field.toLowerCase().indexOf(query) != -1){ - list.push(products[i]); - break; + if(typeof field !== 'string'){ + if(field.toString){ + field = field.toString(); + }else{ + continue; + } + } + if(field.toLowerCase().indexOf(query) != -1){ + list.push(products[i]); + break; + } } } - } - result_callback(list); + result_callback(list); + }); }, - for_all_products: function(callback){ - var products = this._get_products(); - for(var i in products){ - var ret = callback(products[i]); - if(ret === 'break'){ - break; - } - } + add_order: function(order,done_callback){ }, + remove_order: function(order_id, done_callback){ + }, + get_orders: function(result_callback){ + }, + }); window.PosLS = module.PosLS; diff --git a/addons/point_of_sale/static/src/js/pos_devices.js b/addons/point_of_sale/static/src/js/pos_devices.js index c7d96eccffc..d39597c0b02 100644 --- a/addons/point_of_sale/static/src/js/pos_devices.js +++ b/addons/point_of_sale/static/src/js/pos_devices.js @@ -277,41 +277,37 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal this.action_callback[action] = undefined; } }, - - + // returns the checksum of the ean, or -1 if the ean has not the correct length, ean must be a string + ean_checksum: function(ean){ + var code = ean.split(''); + if(code.length !== 13){ + return -1; + } + var oddsum = 0, evensum = 0, total = 0; + code = code.reverse().splice(1); + for(var i = 0; i < code.length; i++){ + if(i % 2 == 0){ + oddsum += Number(code[i]); + }else{ + evensum += Number(code[i]); + } + } + total = oddsum * 3 + evensum; + return Number((10 - total % 10) % 10); + }, // returns true if the ean is a valid EAN codebar number by checking the control digit. // ean must be a string check_ean: function(ean){ - var code = ean.split(''); - for(var i = 0; i < code.length; i++){ - code[i] = Number(code[i]); + return ean_checksum(ean) === Number(ean[ean.length-1]); + }, + // returns a valid zero padded ean13 from an ean prefix. the ean prefix must be a string. + sanitize_ean:function(ean){ + ean = ean.substr(0,13); + + for(var n = 0, count = (13 - ean.length); n < count; n++){ + ean = ean + '0'; } - var st1 = code.slice(); - var st2 = st1.slice(0,st1.length-1).reverse(); - // some EAN13 barcodes have a length of 12, as they start by 0 - while (st2.length < 12) { - st2.push(0); - } - var countSt3 = 1; - var st3 = 0; - $.each(st2, function() { - if (countSt3%2 === 1) { - st3 += this; - } - countSt3 ++; - }); - st3 *= 3; - var st4 = 0; - var countSt4 = 1; - $.each(st2, function() { - if (countSt4%2 === 0) { - st4 += this; - } - countSt4 ++; - }); - var st5 = st3 + st4; - var cd = (10 - (st5%10)) % 10; - return code[code.length-1] === cd; + return ean.substr(0,12) + this.ean_checksum(ean); }, // attempts to interpret an ean (string encoding an ean) @@ -334,6 +330,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal type:'unknown', // prefix:'', ean:ean, + base_ean: ean, id:'', value: 0, unit: 'none', @@ -355,18 +352,22 @@ 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.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.unit = 'Kg'; } else if( match_prefix(this.client_prefix_set,'client')){ parse_result.id = ean.substring(0,7); + parse_result.unit = 'Kg'; } else if( match_prefix(this.cashier_prefix_set,'cashier')){ 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.value = Number(ean.substring(7,12))/100.0; parse_result.unit = '%'; } else { diff --git a/addons/point_of_sale/static/src/js/pos_models.js b/addons/point_of_sale/static/src/js/pos_models.js index b4684c037b2..ee0c770e6e6 100644 --- a/addons/point_of_sale/static/src/js/pos_models.js +++ b/addons/point_of_sale/static/src/js/pos_models.js @@ -64,17 +64,16 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal initialize: function(session, attributes) { Backbone.Model.prototype.initialize.call(this, attributes); var self = this; + this.session = session; this.dao = new module.LocalStorageDAO(); // used to store the order's data on the Hard Drive this.ready = $.Deferred(); // used to notify the GUI that the PosModel has loaded all resources this.flush_mutex = new $.Mutex(); // used to make sure the orders are sent to the server once at time - //this.build_tree = _.bind(this.build_tree, this); // ??? - this.session = session; - this.categories = {}; - this.root_category = null; - this.weightable_categories = []; // a flat list of all categories that directly contain weightable products + this.barcode_reader = new module.BarcodeReader({'pos': this}); // used to read barcodes - this.proxy = new module.ProxyDevice(); // used to communicate to the hardware devices via a local proxy - this.db = new module.PosLS(); // a database used to store the products and product images + this.proxy = new module.ProxyDevice(); // used to communicate to the hardware devices via a local proxy + this.db = new module.PosLS(); // a database used to store the products and categories + + window.db = this.db; // pos settings this.use_scale = false; @@ -267,30 +266,14 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal return session_data_def; }); - // associate the products with their categories - var prod_process_def = $.when(cat_def, session_def) - .pipe(function(){ - var product_list = self.get('product_list'); - var categories = self.get('categories'); - var cat_by_id = {}; - for(var i = 0; i < categories.length; i++){ - cat_by_id[categories[i].id] = categories[i]; - } - //set the parent in the category - for(var i = 0; i < categories.length; i++){ - categories[i].parent_category = cat_by_id[categories[i].parent_id[0]]; - } - for(var i = 0; i < product_list.length; i++){ - product_list[i].pos_category = cat_by_id[product_list[i].pos_categ_id[0]]; - } - }); - // when all the data has loaded, we compute some stuff, and declare the Pos ready to be used. - $.when(pack_def, cat_def, user_def, users_def, uom_def, session_def, tax_def, prod_process_def, user_def, this.flush()) + $.when(pack_def, cat_def, user_def, users_def, uom_def, session_def, tax_def, user_def, this.flush()) .then(function(){ - self.build_categories(); + self.db.clear(); + self.db.add_categories(self.get('categories')); + self.db.add_product(self.get('product_list')); self.set({'cashRegisters' : new module.CashRegisterCollection(self.get('bank_statements'))}); - //self.log_loaded_data(); //Uncomment if you want to log the data to the console for easier debugging + self.log_loaded_data(); //Uncomment if you want to log the data to the console for easier debugging self.ready.resolve(); },function(){ //we failed to load some backend data, or the backend was badly configured. @@ -325,7 +308,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal // order and a valid selected order on_removed_order: function(removed_order){ if( this.get('orders').isEmpty()){ - this.add_and_select_order(new module.Order({ pos: this })); + this.add_new_order(); } if( this.get('selectedOrder') === removed_order){ this.set({ selectedOrder: this.get('orders').last() }); @@ -340,13 +323,13 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal }); }, - add_and_select_order: function(newOrder) { - (this.get('orders')).add(newOrder); - return this.set({ - selectedOrder: newOrder - }); + //creates a new empty order and sets it as the current order + add_new_order: function(){ + var order = new module.Order({pos:this}); + this.get('orders').add(order); + this.set('selectedOrder', order); }, - + // attemps to send all pending orders ( stored in the DAO ) to the server. // it will do it one by one, and remove the successfully sent ones from the DAO once // it has been confirmed that they have been received. @@ -390,119 +373,25 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal }); }, - // this adds several properties to the categories in order to make it easier to diplay them - // fields added include the list of product relevant to each category, list of child categories, - // list of ancestors, etc. - build_categories : function(){ - var categories = this.get('categories'); - var products = this.get('product_list'); - - //append the content of array2 into array1 - function append(array1, array2){ - for(var i = 0, len = array2.length; i < len; i++){ - array1.push(array2[i]); + scan_product: function(parsed_ean){ + var self = this; + var def = new $.Deferred(); + this.db.get_product_by_ean13(parsed_ean.base_ean, function(product){ + var selectedOrder = this.get('selectedOrder'); + if(!product){ + def.reject('product-not-found: '+parsed_ean.base_ean); + return; } - } - - function appendSet(set1, set2){ - for(key in set2){ - set1[key] = set2[key]; + 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}); + }else{ + selectedOrder.addProduct(new module.Product(product)); } - } - - var categories_by_id = {}; - for(var i = 0; i < categories.length; i++){ - categories_by_id[categories[i].id] = categories[i]; - } - this.categories_by_id = categories_by_id; - - var root_category = { - name : 'Root', - id : 0, - parent : null, - childrens : [], - }; - - // add parent and childrens field to categories, find root_categories - for(var i = 0; i < categories.length; i++){ - var cat = categories[i]; - - cat.parent = categories_by_id[cat.parent_id[0]]; - if(!cat.parent){ - root_category.childrens.push(cat); - cat.parent = root_category; - } - - cat.childrens = []; - for(var j = 0; j < cat.child_id.length; j++){ - cat.childrens.push(categories_by_id[ cat.child_id[j] ]); - } - } - - categories.push(root_category); - - // set some default fields for next steps - for(var i = 0; i < categories.length; i++){ - var cat = categories[i]; - - cat.product_list = []; //list of all products in the category - cat.product_set = {}; // [product.id] === true if product is in category - cat.weightable_product_list = []; - cat.weightable_product_set = {}; - cat.weightable = false; //true if directly contains weightable products - } - - this.root_category = root_category; - - //we add the products to the categories. - for(var i = 0, len = products.length; i < len; i++){ - var product = products[i]; - var cat = categories_by_id[product.pos_categ_id[0]]; - if(cat){ - cat.product_list.push(product); - cat.product_set[product.id] = true; - if(product.to_weight){ - cat.weightable_product_list.push(product); - cat.weightable_product_set[product.id] = true; - cat.weightable = true; - } - } - } - - // we build a flat list of all categories that directly contains weightable products - this.weightable_categories = []; - for(var i = 0, len = categories.length; i < len; i++){ - var cat = categories[i]; - if(cat.weightable){ - this.weightable_categories.push(cat); - } - } - - // add ancestor field to categories, contains the list of parents of parents, from root to parent - function make_ancestors(cat, ancestors){ - cat.ancestors = ancestors.slice(0); - ancestors.push(cat); - - for(var i = 0; i < cat.childrens.length; i++){ - make_ancestors(cat.childrens[i], ancestors.slice(0)); - } - } - - //add the products of the subcategories to the parent categories - function make_products(cat){ - for(var i = 0; i < cat.childrens.length; i++){ - make_products(cat.childrens[i]); - - append(cat.product_list, cat.childrens[i].product_list); - append(cat.weightable_product_list, cat.childrens[i].weightable_product_list); - - appendSet(cat.product_set, cat.childrens[i].product_set); - appendSet(cat.weightable_product_set, cat.childrens[i].weightable_product_set); - } - } - - make_ancestors(root_category,[]); - make_products(root_category); + def.resolve(); + }); + return def; }, }); diff --git a/addons/point_of_sale/static/src/js/pos_screens.js b/addons/point_of_sale/static/src/js/pos_screens.js index 07f1071fa6d..310d80a3603 100644 --- a/addons/point_of_sale/static/src/js/pos_screens.js +++ b/addons/point_of_sale/static/src/js/pos_screens.js @@ -159,17 +159,20 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa // 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){ - if(this.pos_widget.scan_product(ean)){ - this.pos.proxy.scan_item_success(ean); - if(this.barcode_product_screen){ - this.pos_widget.screen_selector.set_current_screen(this.barcode_product_screen); - } - }else{ - this.pos.proxy.scan_item_error_unrecognized(ean); - if(this.barcode_product_error_popup && this.pos_widget.screen_selector.get_user_mode() !== 'cashier'){ - this.pos_widget.screen_selector.show_popup(this.barcode_product_error_popup); - } - } + var self = this; + this.pos_widget.scan_product(ean) + .done(function(){ + self.pos.proxy.scan_item_success(ean); + if(self.barcode_product_screen){ + self.pos_widget.screen_selector.set_current_screen(self.barcode_product_screen); + } + }) + .fail(function(){ + self.pos.proxy.scan_item_error_unrecognized(ean); + 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. diff --git a/addons/point_of_sale/static/src/js/pos_widgets.js b/addons/point_of_sale/static/src/js/pos_widgets.js index a30a0ebe521..34de4cf567f 100644 --- a/addons/point_of_sale/static/src/js/pos_widgets.js +++ b/addons/point_of_sale/static/src/js/pos_widgets.js @@ -396,29 +396,21 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa // changes the category. if undefined, sets to root category set_category : function(category){ + var db = this.pos.db; if(!category){ - this.category = this.pos.root_category; + this.category = db.get_category_by_id(db.root_category_id); }else{ this.category = category; } - this.breadcrumb = []; - for(var i = 1; i < this.category.ancestors.length; i++){ - this.breadcrumb.push(this.category.ancestors[i]); + var ancestors_ids = db.get_category_ancestors_ids(this.category.id); + for(var i = 1; i < ancestors_ids.length; i++){ + this.breadcrumb.push(db.get_category_by_id(ancestors_ids[i])); } - if(this.category !== this.pos.root_category){ + if(this.category.id !== db.root_category_id){ this.breadcrumb.push(this.category); } - if(this.product_type === 'weightable'){ - this.subcategories = []; - for(var i = 0; i < this.category.childrens.length; i++){ - if(this.category.childrens[i].weightable_product_list.length > 0){ - this.subcategories.push( this.category.childrens[i]); - } - } - }else{ - this.subcategories = this.category.childrens || []; - } + this.subcategories = db.get_category_by_id(db.get_category_childs_ids(this.category.id)); }, renderElement: function(){ @@ -443,7 +435,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa $(button).appendTo(this.$('.category-list')).click(function(event){ var id = category.id; - var cat = self.pos.categories_by_id[id]; + var cat = self.pos.db.get_category_by_id(id); self.set_category(cat); self.renderElement(); self.search_and_categories(cat); @@ -452,7 +444,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa // breadcrumb click actions this.$(".oe-pos-categories-list a").click(function(event){ var id = $(event.target).data("category-id"); - var category = self.pos.categories_by_id[id]; + var category = self.pos.db.get_category_by_id(id); self.set_category(category); self.renderElement(); self.search_and_categories(category); @@ -475,50 +467,39 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa // filters the products, and sets up the search callbacks search_and_categories: function(category){ var self = this; - - var all_products = this.pos.get('product_list'); - var all_packages = this.pos.get('product.packaging'); // find all products belonging to the current category - var products = []; - if(this.product_type === 'weightable'){ - products = all_products.filter( function(product){ - return self.category.weightable_product_set[product.id]; - }); - }else{ - products = all_products.filter( function(product){ - return self.category.product_set[product.id]; - }); - } + this.pos.db.get_product_by_category(this.category.id, function(products){ + // product lists watch for reset events on 'products' to re-render. + // FIXME that means all productlist widget re-render... even the hidden ones ! + self.pos.get('products').reset(products); + }); - // product lists watch for reset events on 'products' to re-render. - // FIXME that means all productlist widget re-render... even the hidden ones ! - this.pos.get('products').reset(products); - - // find all the products whose name match the query in the searchbox + // filter the products according to the search string this.$('.searchbox input').keyup(function(){ - var results, search_str; - search_str = $(this).val().toLowerCase(); - if(search_str){ - results = products.filter( function(p){ - return p.name.toLowerCase().indexOf(search_str) != -1 || - (p.ean13 && p.ean13.indexOf(search_str) != -1); + query = $(this).val().toLowerCase(); + if(query){ + self.pos.db.search_product_in_category(self.category.id, ['name','ean13'], query, function(products){ + self.pos.get('products').reset(products); + self.$('.search-clear').fadeIn(); }); - self.$element.find('.search-clear').fadeIn(); }else{ - results = products; - self.$element.find('.search-clear').fadeOut(); + self.pos.db.get_product_by_category(self.category.id, function(products){ + self.pos.get('products').reset(products); + self.$('.search-clear').fadeOut(); + }); } - self.pos.get('products').reset(results); - }); - this.$('.searchbox input').click(function(){ }); + this.$('.searchbox input').click(function(){}); //Why ??? + //reset the search when clicking on reset this.$('.search-clear').click(function(){ - self.pos.get('products').reset(products); - self.$('.searchbox input').val('').focus(); - self.$('.search-clear').fadeOut(); + self.pos.db.get_product_by_category(self.category.id, function(products){ + self.pos.get('products').reset(products); + self.$('.searchbox input').val('').focus(); + self.$('.search-clear').fadeOut(); + }); }); }, }); @@ -693,7 +674,9 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa self.build_currency_template(); self.renderElement(); - self.$('.neworder-button').click(_.bind(self.create_new_order, self)); + self.$('.neworder-button').click(function(){ + self.pos.add_new_order(); + }); //when a new order is created, add an order button widget self.pos.get('orders').bind('add', function(new_order){ @@ -721,7 +704,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa self.screen_selector.show_popup('error', 'Sorry, we could not find any PoS Configuration for this session'); } - self.$('.loader').animate({opacity:0},3000,'swing',function(){self.$('.loader').hide();}); + self.$('.loader').animate({opacity:0},1500,'swing',function(){self.$('.loader').hide();}); self.$('.loader img').hide(); if(jQuery.deparam(jQuery.param.querystring()).debug !== undefined){ @@ -851,51 +834,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa }, - //FIXME this method is probably not at the right place ... - scan_product: function(parsed_ean){ - var selectedOrder = this.pos.get('selectedOrder'); - var scannedProductModel = this.get_product_by_ean(parsed_ean); - if (!scannedProductModel){ - return false; - } else { - if(parsed_ean.type === 'price'){ - selectedOrder.addProduct(new module.Product(scannedProductModel), { price:parsed_ean.value}); - }else if(parsed_ean.type === 'weight'){ - selectedOrder.addProduct(new module.Product(scannedProductModel), { quantity:parsed_ean.value, merge:false}); - }else{ - selectedOrder.addProduct(new module.Product(scannedProductModel)); - } - return true; - } - }, - - get_product_by_ean: function(parsed_ean) { - var allProducts = this.pos.get('product_list'); - var allPackages = this.pos.get('product.packaging'); - var scannedProductModel = undefined; - - if (parsed_ean.type === 'price' || parsed_ean.type === 'weight') { - var itemCode = parsed_ean.id; - var scannedPackaging = _.detect(allPackages, function(pack) { - return pack.ean && pack.ean.substring(0,7) === itemCode; - }); - if (scannedPackaging) { - scannedProductModel = _.detect(allProducts, function(pc) { return pc.id === scannedPackaging.product_id[0];}); - }else{ - scannedProductModel = _.detect(allProducts, function(pc) { return pc.ean13 && (pc.ean13.substring(0,7) === parsed_ean.id);}); - } - } else if(parsed_ean.type === 'unit'){ - scannedProductModel = _.detect(allProducts, function(pc) { return pc.ean13 === parsed_ean.ean;}); //TODO DOES NOT SCALE - } - return scannedProductModel; - }, - // creates a new order, and add it to the list of orders. - create_new_order: function() { - var new_order; - new_order = new module.Order({ pos: this.pos }); - this.pos.get('orders').add(new_order); - this.pos.set({ selectedOrder: new_order }); - }, changed_pending_operations: function () { var self = this; this.synch_notification.on_change_nbr_pending(self.pos.get('nbr_pending_operations').length); From 78d8b5d39498beb45231f8b0bcd093f670ca41b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Thu, 9 Aug 2012 21:55:55 +0200 Subject: [PATCH 059/166] [WIP] point_of_sale: indexeddb : products and categories are no longer in memory bzr revid: fva@openerp.com-20120809195555-oluxe7xe8k2ugcoi --- addons/point_of_sale/static/src/js/pos_db.js | 2 +- .../point_of_sale/static/src/js/pos_models.js | 30 +++++++------------ 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/addons/point_of_sale/static/src/js/pos_db.js b/addons/point_of_sale/static/src/js/pos_db.js index 59ea0da1684..d660b130dd2 100644 --- a/addons/point_of_sale/static/src/js/pos_db.js +++ b/addons/point_of_sale/static/src/js/pos_db.js @@ -429,7 +429,7 @@ function openerp_pos_db(instance, module){ _set_categories: function(categories){ localStorage[this.categories] = JSON.stringify(categories); }, - add_product: function(products){ + add_products: function(products){ var stored_products = this._get_products(); var stored_categories = this._get_categories(); diff --git a/addons/point_of_sale/static/src/js/pos_models.js b/addons/point_of_sale/static/src/js/pos_models.js index ee0c770e6e6..b6b58180f43 100644 --- a/addons/point_of_sale/static/src/js/pos_models.js +++ b/addons/point_of_sale/static/src/js/pos_models.js @@ -72,6 +72,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal this.barcode_reader = new module.BarcodeReader({'pos': this}); // used to read barcodes this.proxy = new module.ProxyDevice(); // used to communicate to the hardware devices via a local proxy this.db = new module.PosLS(); // a database used to store the products and categories + this.db.clear(); window.db = this.db; @@ -98,12 +99,10 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal 'products': new module.ProductCollection(), 'cashRegisters': null, - 'product_list': null, // the list of all products, does not change. 'bank_statements': null, 'taxes': null, 'pos_session': null, 'pos_config': null, - 'categories': null, 'selectedOrder': undefined, }); @@ -139,10 +138,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal self.set('currency',currencies[0]); }); - var cat_def = fetch('pos.category', ['id','name', 'parent_id', 'child_id', 'category_image_small']) - .pipe(function(result){ - return self.set({'categories': result}); - }); var uom_def = fetch( //unit of measure 'product.uom', @@ -213,18 +208,20 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal self.use_selfcheckout = pos_config.iface_self_checkout || false; self.use_cashbox = pos_config.iface_cashdrawer || false; - return shop_def = fetch('sale.shop',[], [['id','=',pos_config.shop_id[0]]]) + return fetch('sale.shop',[], [['id','=',pos_config.shop_id[0]]]) }).pipe(function(shops){ self.set('shop',shops[0]); + return fetch('pos.category', ['id','name', 'parent_id', 'child_id', 'category_image_small']) + }).pipe( function(categories){ + self.db.add_categories(categories); return fetch( 'product.product', - //context {pricelist: shop.pricelist_id[0]} ['name', 'list_price','price','pos_categ_id', 'taxes_id','product_image_small', 'ean13', 'to_weight', 'uom_id', 'uos_id', 'uos_coeff', 'mes_type'], [['pos_categ_id','!=', false]], - {pricelist: shops[0].pricelist_id[0]} // context for price - ); - }).pipe( function(product_list){ - self.set({'product_list': product_list}); + {pricelist: self.get('shop').pricelist_id[0]} // context for price + ); + }).pipe( function(products){ + self.db.add_products(products); }); var bank_def = fetch( @@ -267,13 +264,10 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal }); // when all the data has loaded, we compute some stuff, and declare the Pos ready to be used. - $.when(pack_def, cat_def, user_def, users_def, uom_def, session_def, tax_def, user_def, this.flush()) + $.when(pack_def, user_def, users_def, uom_def, session_def, tax_def, user_def, this.flush()) .then(function(){ - self.db.clear(); - self.db.add_categories(self.get('categories')); - self.db.add_product(self.get('product_list')); self.set({'cashRegisters' : new module.CashRegisterCollection(self.get('bank_statements'))}); - self.log_loaded_data(); //Uncomment if you want to log the data to the console for easier debugging + //self.log_loaded_data(); //Uncomment if you want to log the data to the console for easier debugging self.ready.resolve(); },function(){ //we failed to load some backend data, or the backend was badly configured. @@ -286,7 +280,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal log_loaded_data: function(){ console.log('PosModel data has been loaded:'); console.log('PosModel: categories:',this.get('categories')); - console.log('PosModel: product_list:',this.get('product_list')); console.log('PosModel: units:',this.get('units')); console.log('PosModel: bank_statements:',this.get('bank_statements')); console.log('PosModel: journals:',this.get('journals')); @@ -300,7 +293,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal console.log('PosModel: user_list:',this.get('user_list')); console.log('PosModel: user:',this.get('user')); console.log('PosModel.session:',this.session); - console.log('PosModel.categories:',this.categories); console.log('PosModel end of data log.'); }, From 760939d83f4d51f56e8d4da21501116ac1bceef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Fri, 10 Aug 2012 15:58:32 +0200 Subject: [PATCH 060/166] [IMP] point_of_sale: IndexedDB: the LocalStorage DB is working now bzr revid: fva@openerp.com-20120810135832-7xb3yq0r1p829nv1 --- addons/point_of_sale/static/src/js/pos_db.js | 124 ++++++++++++------- 1 file changed, 80 insertions(+), 44 deletions(-) diff --git a/addons/point_of_sale/static/src/js/pos_db.js b/addons/point_of_sale/static/src/js/pos_db.js index d660b130dd2..7b252bb8c41 100644 --- a/addons/point_of_sale/static/src/js/pos_db.js +++ b/addons/point_of_sale/static/src/js/pos_db.js @@ -1,15 +1,20 @@ /** + * WIP : AS OF THIS COMMIT, THE INDEXEDB BACKEND IS IN A NON WORKING STATE + * * This file contains an IndexedDB (html5 database) backend for the Point Of Sale. * The IDB is used to store the list of products and especially their thumbnails, which may * not fit in the localStorage. * The IDB offers a big performance boost for products lookup, but not so much for search as * searching is not yet implemented in the IndexedDB API and must be performed manually in JS. + * + * this file also contains a localstorage implementation of the database to be used by browsers + * that don't support the indexeddb api. * */ function openerp_pos_db(instance, module){ // this is used for testing - window.gen_products = function(options){ + var gen_products = function(options){ options = options || {}; var count = options.count || 100; var imageSize = options.imageSize || 1800; @@ -60,10 +65,13 @@ function openerp_pos_db(instance, module){ }; //this is used for testing - window.log = function(x){ + var log = function(x){ console.log(x); }; + // window.gen_products = gen_products; + // window.log = log; + function importIndexedDB(){ if('indexedDB' in window){ return true; @@ -330,9 +338,12 @@ function openerp_pos_db(instance, module){ }); window.PosDB = module.PosDB; + /* PosLS is a LocalStorage based implementation of the point of sale database, + it performs better for few products, but does not scale beyond 500 products. + */ module.PosLS = instance.web.Class.extend({ - name: 'openerp_pos_ls', - limit: 50, + name: 'openerp_pos_ls', //the prefix of the localstorage data + limit: 100, // the maximum number of results returned by a search init: function(options){ options = options || {}; this.name = options.name || this.name; @@ -340,6 +351,10 @@ function openerp_pos_db(instance, module){ this.products = this.name + '_products'; this.categories = this.name + '_categories'; + //products cache put the data in memory to avoid roundtrips to the localstorage + this.products_cache = null; + this.categories_cache = null; + this.category_by_id = {}; this.root_category_id = 0; this.category_products = {}; @@ -347,6 +362,7 @@ function openerp_pos_db(instance, module){ this.category_childs = {}; this.category_parent = {}; }, + /* returns the category object from its id */ get_category_by_id: function(categ_id){ if(categ_id instanceof Array){ var list = []; @@ -363,15 +379,24 @@ function openerp_pos_db(instance, module){ return this.category_by_id[categ_id]; } }, + /* returns a list of the category's child categories ids, or an empty list + * if a category has no childs */ get_category_childs_ids: function(categ_id){ return this.category_childs[categ_id] || []; }, + /* returns a list of all ancestors (parent, grand-parent, etc) categories ids + * starting from the root category to the direct parent */ get_category_ancestors_ids: function(categ_id){ return this.category_ancestors[categ_id] || []; }, + /* returns the parent category's id of a category, or the root_category_id if no parent. + * the root category is parent of itself. */ get_category_parent_id: function(categ_id){ return this.category_parent[categ_id] || this.root_category_id; }, + /* adds categories definitions to the database. categories is a list of categories objects as + * returned by the openerp server. Categories must be inserted before the products or the + * product/ categories association may (will) not work properly */ add_categories: function(categories){ var self = this; if(!this.category_by_id[this.root_category_id]){ @@ -381,13 +406,11 @@ function openerp_pos_db(instance, module){ }; } for(var i=0, len = categories.length; i < len; i++){ - console.log('putting category : ',categories[i].id, categories[i].name); this.category_by_id[categories[i].id] = categories[i]; } for(var i=0, len = categories.length; i < len; i++){ var cat = categories[i]; var parent_id = cat.parent_id[0] || this.root_category_id; - console.log('category parent',cat.id, parent_id); this.category_parent[cat.id] = cat.parent_id[0]; if(!this.category_childs[parent_id]){ this.category_childs[parent_id] = []; @@ -407,7 +430,11 @@ function openerp_pos_db(instance, module){ } make_ancestors(this.root_category_id, []); }, + /* this internal method returns from disc a dictionary associating ids to the products */ _get_products: function(){ + if(this.products_cache){ + return this.products_cache; + } var products = localStorage[this.products]; if(products){ return JSON.parse(products) || {}; @@ -415,10 +442,16 @@ function openerp_pos_db(instance, module){ return {}; } }, + /* this internal method saves a dictionary associating ids to product to the disc */ _set_products: function(products){ localStorage[this.products] = JSON.stringify(products); + this.products_cache = products; }, + /* this internal method returns from disc a dictionary associating ids to the categories */ _get_categories: function(){ + if(this.categories_cache){ + return this.categories_cache; + } var categories = localStorage[this.categories]; if(categories){ return JSON.parse(categories) || {}; @@ -426,8 +459,10 @@ function openerp_pos_db(instance, module){ return {}; } }, + /* this internal method saves to disc an array associating ids to the categories */ _set_categories: function(categories){ localStorage[this.categories] = JSON.stringify(categories); + this.categories_cache = categories; }, add_products: function(products){ var stored_products = this._get_products(); @@ -444,7 +479,6 @@ function openerp_pos_db(instance, module){ } stored_categories[categ_id].push(product.id); var ancestors = this.get_category_ancestors_ids(categ_id) || []; - console.log('ancestors:',ancestors); for(var j = 0; j < ancestors.length; j++){ if(! stored_categories[ancestors[j]]){ @@ -457,6 +491,7 @@ function openerp_pos_db(instance, module){ this._set_products(stored_products); this._set_categories(stored_categories); }, + /* removes all the data from the database. TODO : being able to selectively remove data */ clear: function(done_callback){ localStorage.removeItem(this.products); localStorage.removeItem(this.categories); @@ -464,18 +499,15 @@ function openerp_pos_db(instance, module){ done_callback(); } }, + /* this internal methods returns the count of properties in an object. */ _count_props : function(obj){ - if(obj.__count__){ - return obj.__count__; - }else{ - var count = 0; - for(var prop in obj){ - if(obj.hasOwnProperty(prop)){ - count++; - } + var count = 0; + for(var prop in obj){ + if(obj.hasOwnProperty(prop)){ + count++; } - return count; } + return count; }, get_product_count: function(result_callback){ result_callback(this._count_props(this._get_products())); @@ -509,50 +541,54 @@ function openerp_pos_db(instance, module){ var stored_products = this._get_products(); var product_ids = stored_categories[category_id]; var list = []; - for(var i = 0, len = product_ids.length; i < len; i++){ + for(var i = 0, len = Math.min(product_ids.length,this.limit); i < len; i++){ list.push(stored_products[product_ids[i]]); } result_callback(list); }, + /* returns as a parameter of the result_callback function a list of products with : + * - a category that is or is a child of category_id, + * - a field in fields that contains a value that contains the query + * If a search is started before the previous has returned, the previous search may be cancelled + * (and the corresponding result_callback never called) + */ search_product_in_category: function(category_id, fields, query, result_callback){ var self = this; - this.get_product_by_category(category_id, function(products){ - var list = []; + var stored_categories = this._get_categories(); + var stored_products = this._get_products(); + var product_ids = stored_categories[category_id]; + var list = []; + var count = 0; + + query = query.toString().toLowerCase(); - query = query.toString().toLowerCase(); - - if(!(fields instanceof Array)){ - fields = [fields]; - } - for(var i in products){ - for(var j = 0, jlen = fields.length; j < jlen; j++){ - var field = products[i][fields[j]]; - if(field === null || field === undefined){ - continue; - } - if(typeof field !== 'string'){ - if(field.toString){ - field = field.toString(); - }else{ - continue; - } - } - if(field.toLowerCase().indexOf(query) != -1){ - list.push(products[i]); - break; - } + if(!(fields instanceof Array)){ + fields = [fields]; + } + for(var i = 0, len = product_ids.length; i < len && count < this.limit; i++){ + var product = stored_products[product_ids[i]]; + for(var j = 0, jlen = fields.length; j < jlen; j++){ + var field = product[fields[j]]; + if(field === null || field === undefined){ + continue; + } + field = field.toString().toLowerCase(); + if(field.indexOf(query) != -1){ + list.push(product); + count++; + break; } } - result_callback(list); - }); + } + result_callback(list); }, + // TODO move the order storage from the crappy DAO in pos_models.js add_order: function(order,done_callback){ }, remove_order: function(order_id, done_callback){ }, get_orders: function(result_callback){ }, - }); window.PosLS = module.PosLS; From 8759e49b8355eec82709aee70405ecc86f20be3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Fri, 10 Aug 2012 16:19:30 +0200 Subject: [PATCH 061/166] [FIX] point_of_sale: reverting changes on the pos's views bzr revid: fva@openerp.com-20120810141930-3xkh9ny0splzrs75 --- addons/point_of_sale/point_of_sale_view.xml | 62 +++++++++++++------ .../wizard/pos_session_opening.xml | 2 +- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/addons/point_of_sale/point_of_sale_view.xml b/addons/point_of_sale/point_of_sale_view.xml index 9aa9c095f65..6a43cec39be 100644 --- a/addons/point_of_sale/point_of_sale_view.xml +++ b/addons/point_of_sale/point_of_sale_view.xml @@ -3,6 +3,10 @@ + Others @@ -151,6 +155,9 @@ + + + Products @@ -163,7 +170,10 @@ You must define a Product for everything you buy or sell. Products can be raw materials, stockable products, consumables or services. The Product form contains detailed information about your products related to procurement logistics, sales price, product category, suppliers and so on. - + Sale lines @@ -663,8 +673,11 @@ tree,form + + Payment Methods @@ -676,6 +689,10 @@ Payment methods are defined by accounting journals having the field Payment Method checked. + POS Sales Lines @@ -699,6 +716,9 @@ + + + Invoices @@ -709,6 +729,8 @@ [('origin','like','POS')] + Start Point of Sale @@ -826,6 +848,11 @@ + + + + + pos.order.list.select pos.order @@ -993,6 +1034,7 @@ + pos.ean_wizard @@ -1008,24 +1050,6 @@ - - - - - - - - - - - - - - - - - - diff --git a/addons/point_of_sale/wizard/pos_session_opening.xml b/addons/point_of_sale/wizard/pos_session_opening.xml index ec7fae9c07e..226edf70b62 100644 --- a/addons/point_of_sale/wizard/pos_session_opening.xml +++ b/addons/point_of_sale/wizard/pos_session_opening.xml @@ -28,7 +28,7 @@ pos.session.opening form form - inline + new From e8e7c91138608c88b5ca7d92204dc3a44177073e Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Fri, 10 Aug 2012 17:11:08 +0200 Subject: [PATCH 062/166] [IMP] hr_expense: small improvements bzr revid: qdp-launchpad@openerp.com-20120810151108-lxqlaxh7m6yd31fi --- addons/hr_expense/hr_expense_view.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/hr_expense/hr_expense_view.xml b/addons/hr_expense/hr_expense_view.xml index 4e4d221c342..1f9d49ee7c1 100644 --- a/addons/hr_expense/hr_expense_view.xml +++ b/addons/hr_expense/hr_expense_view.xml @@ -68,7 +68,7 @@
    ",label:""},Z:function(){}},dhx.ui.button);dhx.protoUI({name:"label",defaults:{template:"
    #label#
    "},focus:function(){return!1},J:function(){return this.d.firstChild},K:function(a){this.a.label=a;this.d.firstChild.innerHTML=a}},dhx.ui.button); -dhx.protoUI({name:"icon",defaults:{template:"
    ",width:42},Z:function(){}},dhx.ui.button); -dhx.protoUI({name:"segmented",defaults:{template:function(a,b){var c=a.options,d="",e;b.Ba(c);if(!a.selected)a.selected=c[0].value;for(var f=0;f"+c[f].label+"
    ";return"
    "+d+"
    "},s:28,nb:0},K:function(a){if(this.d&& -this.d.firstChild)for(var b=this.d.firstChild.childNodes,c=0;c";d+=h?""+c[f].label+"":"
    "+ -c[f].label+"";d+=""}return"
    "+d+"
    "},s:4}},dhx.ui.segmented); -dhx.protoUI({name:"text",wd:!0,$b:function(a,b,c){c.labelPosition=="left"?a+=b:a=b+a;return"
    "+a+"
    "},pb:function(a,b,c,d){var e=a.inputAlign||"left",f=a.labelAlign||"left",g=dhx.uid(),h="
    ";h+="
    ";var i=this.a.inputWidth-this.a.labelWidth-18;i<0&&(i= -0);h+=d?"
    "+(a.text||a.value||"")+"
    ":"";h+="
    ";return"
    "+h+"
    "},qb:function(a, -b){if(!a.label)return"";var c=a.labelAlign||"left";return"
    "+a.label+"
    "},defaults:{template:function(a,b){return b.pb(a,"text")},labelWidth:80,s:28,nb:0},type_setter:function(a){return a},Z:function(){this.a.inputWidth?this.J().style.width=this.a.inputWidth-this.a.labelWidth-this.a.s+"px":this.J().style.width=this.j-this.a.labelWidth-this.a.s-this.a.nb+"px"},focus:function(){var a=this.d.getElementsByTagName("input")[0]; -a&&a.focus()},K:function(a){this.getInput().value=a},ab:function(){return this.getInput().value}},dhx.ui.button); -dhx.protoUI({name:"toggle",defaults:{template:function(a,b){var c=a.options;b.Ba(c);var d=b.a.inputWidth/2||"auto",e=[c[0].width||d,c[1].width||d],f=b.qb(a,"toggle"),g="";g+="";return b.$b(f,g,a)},label:"",labelWidth:0,s:20},Z:function(){},Aa:function(a){this.setValue(a.value)},$a:function(){return this.d.getElementsByTagName("input")}, -K:function(a){var b=this.$a(),c=this.a.options;a==c[1].value?(b[0].className="dhx_inp_toggle_left_off",b[1].className="dhx_inp_toggle_right_on"):(b[0].className="dhx_inp_toggle_left_on",b[1].className="dhx_inp_toggle_right_off")},ab:function(){var a=this.$a(),b=this.a.options;return a[0].className=="dhx_inp_toggle_left_on"?b[0].value:b[1].value}},dhx.ui.text); -dhx.protoUI({name:"input",defaults:{attributes:["maxlength","disabled","placeholder"],template:function(a,b){for(var c=""+c+""},s:28,labelWidth:0}},dhx.ui.text); -dhx.protoUI({name:"select",defaults:{template:function(a,b){var c=a.options;b.Ba(c);var d=""+c[e].label+"";d+="";return"
    "+d+"
    "},labelWidth:0,nb:0,s:10},getInput:function(){return this.d.firstChild.firstChild}},dhx.ui.text); -dhx.protoUI({name:"textarea",defaults:{template:function(a){return"
    "},cssContant:28},Z:function(){this.a.inputWidth?this.J().style.width=this.a.inputWidth-this.a.cssContant+"px":this.J().style.width=this.j-this.a.nb-this.a.cssContant+"px";this.a.inputHeight?this.J().style.height=this.a.inputHeight+"px":this.J().style.height=this.m-9+"px"},getInput:function(){return this.d.firstChild.firstChild}, -K:function(a){this.getInput().value=a},ab:function(){return this.getInput().value}},dhx.ui.text); -dhx.protoUI({name:"counter",defaults:{template:function(a,b){var c=a.value||0,d=b.qb(a,"counter"),e="";e+="
    "+c+"
    ";e+="";return b.$b(d,e,a)},min:1,step:1,labelWidth:0,label:"",s:145},J:function(){return this.getInput().parentNode},getLabel:function(){return this.getInput().previousSibling||this.getInput().parentNode.lastChild},Z:function(){if(this.a.label&& -!this.a.labelWidth){var a=this.getLabel();if(a)a.style.width=(this.a.inputWidth||this.j)-this.a.s+"px"}},K:function(a){this.getInput().nextSibling.innerHTML=a},getValue:function(){return(this.a.value||0)*1},next:function(a,b,c){a=a||1;this.kd(a,b,c)},prev:function(a,b,c){a=-1*(a||1);this.kd(a,b,c)},kd:function(a,b,c){var b=typeof b=="undefined"?-Infinity:b,c=typeof c=="undefined"?Infinity:c,d=this.getValue()+a;d>=b&&d<=c&&this.setValue(d)}},dhx.ui.text); -dhx.protoUI({name:"checkbox",defaults:{template:function(a,b){var c=a.value?"dhx_inp_checkbox_on":"dhx_inp_checkbox_on hidden",d="
    ",e=b.qb(a,"checkbox");return b.$b(e,d,a)}},K:function(a){var b=this.getInput();b.className=a?"dhx_inp_checkbox_on":"dhx_inp_checkbox_on hidden"},toggle:function(){this.setValue(!this.getValue())},getLabel:function(){var a=this.getInput().parentNode;return a.nextSibling||a.previousSibling}, -getValue:function(){return this.a.value?1:0},J:function(){return this.getInput().parentNode.parentNode}},dhx.ui.counter); -dhx.protoUI({name:"radio",defaults:{template:function(a,b){b.Ba(a.options);for(var c=[],d=0;d");var e="
    ";a.label=a.options[d].label;var f=b.qb(a,"radio");a.labelPosition=="left"?c.push(f+e):c.push(e+f)}return"
    "+ -c.join("
    ")+"
    "}},$getSize:function(){var a=dhx.ui.button.prototype.$getSize.call(this);if(this.a.options){for(var b=1,c=0;c]*>/g,""):this.getInput().innerHTML=c},getValue:function(){return this.a.value}},dhx.ui.text); -dhx.protoUI({name:"combo",defaults:{template:function(a,b){return b.pb(a,"combo")},filter:function(a,b){return a.value.toString().toLowerCase().indexOf(b.toLowerCase())===0?!0:!1}},Y:function(a){a.popup||this.Cb("list",a);this.dc();dhx.event(this.d,"keydown",function(b){var b=b||event,c=b.target||b.srcElement,d=dhx.ui.get(a.popup);window.clearTimeout(d.key_timer);var e=this;d.key_timer=window.setTimeout(function(){d.h.filter(function(a){return e.a.filter.apply(e,[a,c.value])});var a=dhx.ui.get(d.a.master); -a.a.value=d.h.dataCount()==1&&d.h.type.template(d.h.item(d.h.first()))==c.value?d.h.first():""},200);d.show(c,d.h.a.align||"bottom",!0)},this);this.Y=function(){}},Aa:function(a){this.Y(a);dhx.isNotDefined(a.value)||this.setValue(a.value)}},dhx.ui.richselect); -dhx.protoUI({name:"datepicker",defaults:{template:function(a,b){return b.pb(a,"list",!0,!0)}},Y:function(a){a.popup||this.Cb("calendar",a);var b=dhx.ui.get(a.popup);b.h.attachEvent("onDateSelect",function(a){var b=dhx.ui.get(this.getParent().a.master);this.getParent().hide();b.setValue(a)});this.Y=function(){}},Aa:function(a){this.Y(a);dhx.isNotDefined(a.value)||this.setValue(a.value)},K:function(a){var b=dhx.ui.get(this.a.popup.toString()),c=b.h;typeof a=="string"&&a&&(a=(this.a.dateFormat||dhx.i18n.dateFormatDate)(a)); -c.selectDate(a,!0);this.a.value=a?c.config.date:"";this.getInput().innerHTML=a?(this.a.dateFormatStr||dhx.i18n.dateFormatStr)(this.a.value):""},dateFormat_setter:function(a){this.a.dateFormatStr=dhx.Date.dateToStr(a);return dhx.Date.strToDate(a)},getValue:function(){return this.a.value||null}},dhx.ui.richselect); -dhx.ValidateData={validate:function(a){var b=!0,c=this.a.rules;if(c){var d=c.$obj;!a&&this.getValues&&(a=this.getValues());if(d&&!d.call(this,a))return!1;var e=c.$all,f;for(f in c)f.indexOf("$")!==0&&(c[f].call(this,a[f],a,f)&&(!e||e.call(this,a[f],a,f))?this.callEvent("onValidationSuccess",[f,a])&&this.tc&&this.tc(f,a):(b=!1,this.callEvent("onValidationError",[f,a])&&this.Lc&&this.Lc(f,a)))}return b}}; -dhx.rules={isNumber:function(a){return parseFloat(a)==a},isNotEmpty:function(a){return a=="0"||a}}; -dhx.RenderStack={$init:function(){this.F=document.createElement("DIV");this.data.attachEvent("onIdChange",dhx.bind(this.Zb,this));this.attachEvent("onItemClick",this.Dd);if(!this.types)this.types={"default":this.type},this.type.name="default";this.type=dhx.copy(this.types[this.type.name])},customize:function(a){dhx.Type(this,a)},type_setter:function(a){this.types[a]?(this.type=dhx.copy(this.types[a]),this.type.css&&(this.g.className+=" "+this.type.css)):this.customize(a);return a},template_setter:function(a){this.type.template= -dhx.Template(a)},xa:function(a){this.callEvent("onItemRender",[a]);return this.type.templateStart(a,this.type)+(a.$template?this.type["template"+a.$template]:this.type.template)(a,this.type)+this.type.templateEnd(a,this.type)},ld:function(a){this.F.innerHTML=this.xa(a);return this.F.firstChild},Zb:function(a,b){var c=this.pa(a);c&&(c.setAttribute(this.ma,b),this.B[b]=this.B[a],delete this.B[a])},Dd:function(){if(this.a.click){var a=dhx.toFunctor(this.a.click);a&&a.call&&a.apply(this,arguments)}}, -pa:function(a){if(this.B)return this.B[a];this.B={};for(var b=this.d.childNodes,c=0;c0&&(!this.r||!this.a.scroll))this.a.height=a[3];if(a[1]>0&&(this.r||!this.a.scroll))this.a.width=a[1];a=dhx.ui.view.prototype.$getSize.call(this);if(a[3]<=0&&this.Db> -0)a[3]=this.Db,a[2]=0;return a},$setSize:function(a,b){dhx.ui.view.prototype.$setSize.apply(this,arguments);dhx.ui.baselayout.prototype.$setSize.call(this,this.j,this.m)},render:function(){if(this.isVisible(this.a.id)&&this.fc)this.setValues(this.fc),this.fc=null},refresh:function(){this.render()},type_setter:function(a){this.g.className+=" dhx_"+a.toLowerCase()}},dhx.Scrollable,dhx.AtomDataLoader,dhx.Values,dhx.ui.baselayout,dhx.EventSystem,dhx.ValidateData); -dhx.protoUI({name:"form",defaults:{scroll:!0},Db:-1,Vc:function(a){this.g.className+=" dhx_form";if(a.elements)this.Q=a.elements,this.r=!0;delete a.elements;dhx.sa=this},type_setter:function(){}},dhx.ui.toolbar); -dhx.MouseEvents={$init:function(){this.on_click&&dhx.event(this.g,"click",this.me,this);this.on_context&&dhx.event(this.g,"contextmenu",this.ne,this);this.on_dblclick&&dhx.event(this.g,"dblclick",this.oe,this);this.on_mouse_move&&(dhx.event(this.g,"mousemove",this.Rc,this),dhx.event(this.g,dhx.env.isIE?"mouseleave":"mouseout",this.Rc,this))},me:function(a){return this.Ja(a,this.on_click,"ItemClick")},oe:function(a){return this.Ja(a,this.on_dblclick,"ItemDblClick")},ne:function(a){if(this.Ja(a,this.on_context, -"BeforeContextMenu"))return this.Ja(a,{},"AfterContextMenu"),dhx.html.preventEvent(a)},Rc:function(a){dhx.env.isIE&&(a=document.createEventObject(event));this.Nc&&window.clearTimeout(this.Nc);this.callEvent("onMouseMoving",[a]);this.Nc=window.setTimeout(dhx.bind(function(){a.type=="mousemove"?this.pe(a):this.qe(a)},this),500)},pe:function(a){this.Ja(a,this.on_mouse_move,"MouseMove")||this.callEvent("onMouseOut",[a||event])},qe:function(a){this.callEvent("onMouseOut",[a||event])},Ja:function(a,b,c){for(var a= -a||event,d=a.target||a.srcElement,e="",f=null,g=!1;d&&d.parentNode;){if(!g&&d.getAttribute&&(f=d.getAttribute(this.ma))){d.getAttribute("userdata")&&this.callEvent("onLocateData",[f,d]);if(!this.callEvent("on"+c,[f,a,d]))return;g=!0}if(e=d.className)if(e=e.split(" "),e=e[0]||e[1],b[e]){var h=b[e].call(this,a,f||dhx.html.locate(a,this.ma),d);if(typeof h!="undefined"&&h!==!0)return}d=d.parentNode}return g}}; -dhx.SelectionModel={$init:function(){this.i=dhx.toArray();this.data.attachEvent("onStoreUpdated",dhx.bind(this.Pd,this));this.data.attachEvent("onStoreLoad",dhx.bind(this.Od,this));this.data.attachEvent("onAfterFilter",dhx.bind(this.Nd,this));this.data.attachEvent("onChangeId",dhx.bind(this.Zd,this))},Zd:function(a,b){for(var c=this.i.length-1;c>=0;c--)this.i[c]==a&&(this.i[c]=b)},Nd:function(){for(var a=this.i.length-1;a>=0;a--){if(this.data.indexById(this.i[a])<0)var b=this.i[a];var c=this.item(b); -c&&delete c.$selected;this.i.splice(a,1);this.callEvent("onSelectChange",[b])}},Pd:function(a,b,c){if(c=="delete")this.i.remove(a);else if(!this.data.dataCount()&&!this.data.p)this.i=dhx.toArray()},Od:function(){this.a.select&&this.data.each(function(a){a.$selected&&this.select(a.id)},this)},ub:function(a,b,c){if(!c&&!this.callEvent("onBeforeSelect",[a,b]))return!1;this.data.item(a).$selected=b;c?c.push(a):(b?this.i.push(a):this.i.remove(a),this.Vb(a));return!0},select:function(a,b,c){if(!a)return this.selectAll(); -if(dhx.isArray(a))for(var d=0;d100||a.length>this.data.dataCount/ -2},Vb:function(a){typeof a!="object"&&(a=[a]);if(a.length){if(this.ee(a))this.data.refresh();else for(var b=0;b=0?b[c]:null},nextSibling:function(a){var b=this.branch[this.item(a).$parent],c=dhx.PowerArray.find.call(b,a)+1;return c0&&this.groupBy(g,f[l],!0,l,e+1)}else{var n= -arguments,g=[];this.branch={0:[]};for(l=n.length-1;l>=0;l--)g.push(n[l]);this.groupBy(g,this.pull,!0,"0",0);this.refresh()}}};dhx.animate=function(a,b){if(dhx.isArray(a))for(var c=0;c1){for(var d=0;d=0;b--)dhx.html.remove(a[b])}}; -dhx.protoUI({name:"list",$init:function(){this.data.provideApi(this,!0)},defaults:{select:!1,scroll:!0},ma:"dhx_l_id",on_click:{dhx_list_item:function(a,b){if(this.a.select)this.ra=!0,this.a.select=="multiselect"?this.select(b,a.ctrlKey,a.shiftKey):this.select(b),this.ra=!1}},$getSize:function(){if(this.type.width!="auto")this.a.width=this.type.width+(this.type.padding+this.type.margin)*2;if(this.a.yCount)this.a.height=(this.type.height+(this.type.padding+this.type.margin)*2+1)*(this.a.yCount=="auto"? -this.dataCount():this.a.yCount);return dhx.ui.view.prototype.$getSize.call(this)},$setSize:function(){dhx.ui.view.prototype.$setSize.apply(this,arguments)},type:{css:"",widthSize:function(a,b){return b.width+(b.width>-1?"px":"")},heightSize:function(a,b){return b.height+(b.height>-1?"px":"")},template:dhx.Template("#value#"),width:"auto",height:22,margin:0,padding:10,border:1,templateStart:dhx.Template("
    "), -templateEnd:dhx.Template("
    ")}},dhx.MouseEvents,dhx.SelectionModel,dhx.Scrollable,dhx.ui.proto); -dhx.protoUI({name:"grouplist",defaults:{animate:{}},$init:function(){dhx.extend(this.data,dhx.TreeStore,!0);this.data.provideApi(this,!0);this.data.attachEvent("onClearAll",dhx.bind(this.Qc,this));this.b.className+=" dhx_grouplist";this.Qc()},Qc:function(){this.aa=[];this.z=[]},on_click:{dhx_list_item:function(a,b){if(this.oa)return!1;for(var c=0;c"), -templateBack:dhx.Template("< #value#"),templateItem:dhx.Template("#value#"),templateGroup:dhx.Template("#value#"),templateEnd:function(a){var b="";a.$count&&(b+="
    ");b+="";return b}},showItem:function(a){var b,c;if(a&&(b=this.item(a),c=b.$parent,b.$count))c=b.id;this.aa=this.data.branch[c||0];for(this.z=[];c;)this.item(c).$template="Back",this.z.unshift(c),c=this.item(c).$parent;this.ra=!0;this.render();this.ra=!1;dhx.RenderStack.showItem.call(this,a)}},dhx.ui.list); -dhx.Type(dhx.ui.grouplist,{}); -dhx.protoUI({name:"pagelist",defaults:{scroll:"x",panel:!1,scrollOffset:0},Yd:!0,$init:function(a){this.b.className+=" dhx_pagelist";a.scroll=a.scroll=="y"?"y":"x";this.type.layout=a.scroll;this.attachEvent("onAfterRender",this.Ie);this.$ready.push(this.zb);this.l=0},zb:function(){if(this.a.scroll=="x")this.d.style.height="100%";this.type.layout=this.a.scroll;this.attachEvent("onAfterScroll",this.Ld)},Ie:function(){if(this.a.scroll=="x")this.d.style.width=(this.type.width+(this.type.padding+this.type.margin)* -2+this.type.border)*this.dataCount()+"px";this.a.panel&&this.Wb()},panel_setter:function(a){a&&(this.b.className+=" hidden_scroll",a===!0&&(a={}),this.Ia(a,{size:16,itemSize:16,align:"bottom"}));return a},bd:function(a){var b=this.indexById(a);if(typeof b!="undefined"&&this.a.panel)this.l=b,this.Xb()},getActive:function(){return this.l?this.data.order[this.l]:this.first()},Ld:function(a){var b=(this.a.scroll=="y"?this.type.height:this.type.width)+(this.type.padding+this.type.margin)*2+this.type.border, -c=this.a.scroll=="y"?this.d.scrollHeight-this.m:this.d.scrollWidth-this.j,d;this.a.scroll=="y"?(d=Math.round(a.f/b),a.f=d*b,a.f=this.uc(a.f,c)):(d=Math.round(a.e/b),a.e=d*b,a.e=this.uc(a.e,c));this.l=-d;this.a.panel&&this.Xb();return!0},uc:function(a,b){var c=this.a.scrollOffset;if(c&&Math.abs(a)>c){var d=dhx.Touch.A[dhx.Touch.H]>dhx.Touch.w[dhx.Touch.H];a+=d?c:1-c}Math.abs(a)>b&&(a=-b);return a},$getSize:function(){if(this.a.scroll=="y"){if(this.type.width!="auto")this.a.width=this.type.width+(this.type.padding+ -this.type.margin)*2+this.type.border;if(this.a.yCount)this.a.height=(this.type.height+(this.type.padding+this.type.margin)*2+this.type.border)*(this.a.yCount=="auto"?this.dataCount():this.a.yCount)}else if(this.type.height!="auto")this.a.height=this.type.height+(this.type.padding+this.type.margin)*2+this.type.border;return dhx.ui.view.prototype.$getSize.call(this)},$setSize:function(a,b){if(dhx.ui.view.prototype.$setSize.apply(this,arguments)){if(this.type.fullScreen)this.type.width=this.j,this.type.height= -this.m,this.type.padding=0,this.render();this.a.panel&&this.Wb()}},type:{templateStart:function(a,b){var c="dhx_list_item dhx_list_"+b.css+"_item"+(a.$selected?"_selected":""),d="width:"+b.width+"px; height:"+b.height+"px; padding:"+b.padding+"px; margin:"+b.margin+"px; overflow:hidden;"+(b.layout&&b.layout=="x"?"float:left;":"");return"
    "}}},dhx.ui.list,dhx.CarouselPanel); -dhx.protoUI({name:"multiview",defaults:{animate:{}},$init:function(){this.l=0;this.r=1;this.b.style.position="relative";this.b.className+=" dhx_multiview";this.M=[]},xd:function(a,b){var c=dhx.ui.get(a);if(!c.La)c.rb=[],c.La={};c.La[b]||(c.La[b]=!0,c.rb.push(b))},Yb:function(a){var b=dhx.ui.get(a);this.M[this.M.length-2]!=a?(this.M.length==10&&this.M.splice(0,1),this.M.push(a)):this.M.splice(this.M.length-1,1);if(b.La){for(var c=0;c-1)a[3]=this.a.height,a[2]= -0;if(this.a.width>-1)a[1]=this.a.width,a[0]=0;a[0]&&(a[1]=0);a[2]&&(a[3]=0);return a},$setSize:function(a,b){dhx.ui.baseview.prototype.$setSize.call(this,a,b);this.c[this.l].$setSize(a,b)},isVisible:function(a,b){return b&&b!=this.getActive()?(a&&this.xd(b,a),!1):dhx.ui.view.prototype.isVisible.call(this,a,this.a.id)},getActive:function(){return this.c.length?this.c[this.l].a.id:null},back:function(a){a=a||1;if(this.callEvent("onBeforeBack",[this.getActive(),a])&&this.M.length>a){var b=this.M[this.M.length- -a-1];dhx.ui.get(b).show();return b}return null}},dhx.ui.baselayout,dhx.EventSystem);dhx.html.addMeta=function(a,b){document.getElementsByTagName("head").item(0).appendChild(dhx.html.create("meta",{name:a,content:b}))}; -(function(){var a=function(){var a=!!(window.orientation%180);if(dhx.ui.orientation!==a)dhx.ui.orientation=a,dhx.callEvent("onRotate",[a])};dhx.ui.orientation=!!((dhx.isNotDefined(window.orientation)?90:window.orientation)%180);dhx.event(window,"onorientationchange"in window?"orientationchange":"resize",a);dhx.ui.fullScreen=function(){dhx.html.addMeta("apple-mobile-web-app-capable","yes");dhx.html.addMeta("viewport","initial-scale = 1.0, maximum-scale = 1.0, user-scalable = no");if(dhx.env.touch){var b= -document.body.offsetHeight,c=navigator.userAgent.indexOf("iPhone")!=-1,d=c&&(b==356||b==208||b==306||b==158),e=function(){if(c)dhx.ui.orientation?(b=480,e=d?268:300):(b=320,e=d?416:460);else{document.body.style.width=document.body.style.height="1px";document.body.style.overflow="hidden";var a=window.outerWidth/window.innerWidth,b=window.outerWidth/a,e=window.outerHeight/a}document.body.style.height=e+"px";document.body.style.width=b+"px";dhx.ui.yc=!1;dhx.ui.resize();dhx.delay(function(){window.scrollTo(0, -1)})},f=function(){dhx.ui.yc=!0;dhx.env.isSafari?e():dhx.delay(e,null,[],500)};dhx.attachEvent("onClick",function(a){a.target.tagName=="INPUT"||a.target.tagName=="TEXTAREA"||a.target.tagName=="SELECT"||(d&&window.innerHeight<416||!d&&window.innerHeight0;)c=this.Ve[a%16]+c,a=Math.floor(a/16);for(;c.length0?c[0].substr(f,e):c[0].substr(0,e+f),d=g+(d?b.groupDelimiter+d:"")}while(f>0);return d+b.decimalDelimeter+c[1]},numToStr:function(a){return function(b){return dhx.Number.format(b,a)}}}; -dhx.Date={Locale:{month_full:"January,February,March,April,May,June,July,August,September,October,November,December".split(","),month_short:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),day_full:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),day_short:"Sun,Mon,Tue,Wed,Thu,Fri,Sat".split(",")},weekStart:function(a){var b=a.getDay();this.config.start_on_monday&&(b===0?b=6:b--);return this.date_part(this.add(a,-1*b,"day"))},monthStart:function(a){a.setDate(1);return this.date_part(a)}, -yearStart:function(a){a.setMonth(0);return this.month_start(a)},dayStart:function(a){return this.date_part(a)},dateToStr:function(a,b){a=a.replace(/%[a-zA-Z]/g,function(a){switch(a){case "%d":return'"+dhx.math.toFixed(date.getDate())+"';case "%m":return'"+dhx.math.toFixed((date.getMonth()+1))+"';case "%j":return'"+date.getDate()+"';case "%n":return'"+(date.getMonth()+1)+"';case "%y":return'"+dhx.math.toFixed(date.getFullYear()%100)+"';case "%Y":return'"+date.getFullYear()+"';case "%D":return'"+dhx.Date.Locale.day_short[date.getDay()]+"'; -case "%l":return'"+dhx.Date.Locale.day_full[date.getDay()]+"';case "%M":return'"+dhx.Date.Locale.month_short[date.getMonth()]+"';case "%F":return'"+dhx.Date.Locale.month_full[date.getMonth()]+"';case "%h":return'"+dhx.math.toFixed((date.getHours()+11)%12+1)+"';case "%g":return'"+((date.getHours()+11)%12+1)+"';case "%G":return'"+date.getHours()+"';case "%H":return'"+dhx.math.toFixed(date.getHours())+"';case "%i":return'"+dhx.math.toFixed(date.getMinutes())+"';case "%a":return'"+(date.getHours()>11?"pm":"am")+"'; -case "%A":return'"+(date.getHours()>11?"PM":"AM")+"';case "%s":return'"+dhx.math.toFixed(date.getSeconds())+"';case "%W":return'"+dhx.math.toFixed(dhx.Date.getISOWeek(date))+"';default:return a}});b===!0&&(a=a.replace(/date\.get/g,"date.getUTC"));return new Function("date",'return "'+a+'";')},strToDate:function(a,b){for(var c="var temp=date.split(/[^0-9a-zA-Z]+/g);",d=a.match(/%[a-zA-Z]/g),e=0;e50?1900:2000);";break;case "%g":case "%G":case "%h":case "%H":c+="set[3]=temp["+e+"]||0;";break;case "%i":c+="set[4]=temp["+e+"]||0;";break;case "%Y":c+="set[0]=temp["+e+"]||0;";break;case "%a":case "%A":c+="set[3]=set[3]%12+((temp["+e+"]||'').toLowerCase()=='am'?0:12);";break;case "%s":c+="set[5]=temp["+e+"]||0;"}var f="set[0],set[1],set[2],set[3],set[4],set[5]";b&&(f=" Date.UTC("+f+")");return new Function("date", -"var set=[0,0,1,0,0,0]; "+c+" return new Date("+f+");")},getISOWeek:function(a){if(!a)return!1;var b=a.getDay();b===0&&(b=7);var c=new Date(a.valueOf());c.setDate(a.getDate()+(4-b));var d=c.getFullYear(),e=Math.floor((c.getTime()-(new Date(d,0,1)).getTime())/864E5),f=1+Math.floor(e/7);return f},getUTCISOWeek:function(a){return this.getISOWeek(a)},add:function(a,b,c){var d=new Date(a.valueOf());switch(c){case "day":d.setDate(d.getDate()+b);break;case "week":d.setDate(d.getDate()+7*b);break;case "month":d.setMonth(d.getMonth()+ -b);break;case "year":d.setYear(d.getFullYear()+b);break;case "hour":d.setHours(d.getHours()+b);break;case "minute":d.setMinutes(d.getMinutes()+b)}return d},datePart:function(a){var b=this.copy(a);b.setHours(0);b.setMinutes(0);b.setSeconds(0);b.setMilliseconds(0);return b},timePart:function(a){var b=this.copy(a);return(b.valueOf()/1E3-b.getTimezoneOffset()*60)%86400},copy:function(a){return new Date(a.valueOf())}};dhx.i18n.setLocale("en");dhx.format=function(a){a=a||{};this.$init(a)}; -dhx.format.prototype={$init:function(a){this.a={};this.a.groupDelimiter=a.groupDelimiter||" ";this.a.groupNumber=a.groupNumber||3;this.a.decimalPoint=a.decimalPoint||",";this.a.fractNumber=a.fractNumber||5;this.a.dateFormat=a.dateFormat||"%Y/%m/%d";this.a.stringTemplate=a.stringTemplate||"{value}";this.ff=dhx.Date.str_to_date(this.a.dateFormat);this.Qd=dhx.Date.date_to_str(this.a.dateFormat)},define:function(a,b){this.a[a]=b},format:function(a,b){b=b||this.formatAutoDefine(a);return this["format__"+ -b]?this["format__"+b](a):a},formatAutoDefine:function(a){return typeof a=="number"||a instanceof Number?"number":a instanceof Date?"date":typeof a=="string"||a instanceof String?isNaN(parseFloat(a))?"string":"number":!1},format__number:function(a){var b="";typeof a=="number"||a instanceof Number||(a=parseFloat(a));var c=a.toFixed(this.a.fractNumber).toString(),c=c.split("."),d=this.add_delimiter_to_int(c[0]),e=this.str_reverse(this.add_delimiter_to_int(this.str_reverse(c[1])));return b=d+this.a.decimalPoint+ -e},add_delimiter_to_int:function(a){for(var b=0,c="",d=a.length-1;d>=0;d--)c=a[d]+c,b++,b==this.a.groupNumber&&(c=this.a.groupDelimiter+c,b=0);return c},str_reverse:function(a){for(var b="",c=a.length-1;c>=0;c--)b+=a[c];return b},format__date:function(a){var b=this.Qd(a);return b},attachFormat:function(a,b){this["format__"+a]=b},format__string:function(a){var b=this.a.stringTemplate.replace("{value}",a);return b},format__bold:function(a){return typeof a=="string"||a instanceof String?a.bold():a}}; -dhx.i18n.setLocale(); -dhx.protoUI({name:"calendar",defaults:{date:null,startOnMonday:!0,navigation:!0,weekHeader:!1,weekNumber:!1,timeSelect:!1,skipEmptyWeeks:!0,cellHeight:36,minuteStep:15,hourStart:6,hourEnd:24,hourFormat:"%H",calendarHeader:"%F %Y",calendarDay:"%d",calendarWeekHeader:"W#",calendarWeek:"%W",width:300,height:300,selectedCss:"dhx_cal_selected_day"},skin:{monthHeaderHeight:40,weekHeaderHeight:20,timeSelectHeight:32},hourFormat_setter:dhx.Date.dateToStr,calendarHeader_setter:dhx.Date.dateToStr,calendarDay_setter:dhx.Date.dateToStr, -calendarWeekHeader_setter:dhx.Date.dateToStr,calendarWeek_setter:dhx.Date.dateToStr,date_setter:function(a){typeof a=="string"&&(a=dhx.i18n.fullDateFormatDate(a));this.L=this.L||a;return a},$init:function(){this.fa={};this.ec=[];var a="%Y-%m-%d";this.rc=dhx.Date.dateToStr(a);this.Cd=dhx.Date.strToDate(a)},$getSize:function(){var a=this.a;if(a.cellHeight>0)a.height=this.Xd();return dhx.ui.view.prototype.$getSize.call(this)},cellHeight_setter:function(a){return a=="auto"?0:a},$setSize:function(a,b){dhx.ui.view.prototype.$setSize.call(this, -a,b)&&this.render()},Ac:function(){var a=this.a;if(!this.L)this.L=new Date;var b=new Date(this.L);b.setDate(1);var c=b.getDay();this.ke=new Date(b);this.vd=a.startOnMonday?1:0;this.lb=(c-this.vd+7)%7;this.Nb=32-(new Date(b.getFullYear(),b.getMonth(),32)).getDate();var d=42-this.lb-this.Nb;this.df=new Date(b.setDate(this.Nb));this.G=a.skipEmptyWeeks?6-Math.floor(d/7):6;this.Ob=this.G*7-this.lb-this.Nb;this.cf=new Date(b.setDate(b.getDate()+d));this.Dc=this.skin.monthHeaderHeight+(a.weekHeader?this.skin.weekHeaderHeight: -0)+(a.timeSelect?this.skin.timeSelectHeight:0)},Xd:function(){this.Ac();return this.Dc+this.G*this.a.cellHeight},Td:function(){this.Ac();var a=this.a;this.Da=[];this.W=[];var b=this.j;b+=1;for(var c=this.m,d=a.weekNumber?8:7,e=0;e";a.weekHeader&&(b+="
    "+this.Xe()+"
    ");b+="
    "+this.Bd()+"
    ";a.timeSelect&&(b+="
    "+this.Ue()+"
    ");b+="
    ";this.g.innerHTML=b;if(a.timeSelect){for(var c=this.g.getElementsByTagName("select"),d=this.ec,e=0;e"+f+"";d+=this.W[0]}for(var g=0;g<7;g++){var h=(c+g)%7,i=dhx.Date.Locale.day_short[h], -j="dhx_cal_day_name",k=this.W[g+e]-1;g==6&&(j+=" dhx_cal_day_name_last",k+=1);h===0&&(j+=" dhx_sunday");h==6&&(j+=" dhx_saturday");b+="
    "+i+"
    ";d+=this.W[g+e]}return b},Bd:function(){var a=this.a,b=0,c=dhx.Date.add(this.ke,-this.lb,"day"),c=dhx.Date.datePart(c),d=0,e="";if(a.weekNumber){var d=1,f=dhx.Date.add(c,(this.vd+1)%2,"day");e+='';for(var g= -0;g=7||g==this.G-2&&this.Ob==14))k="dhx_next_month",j="";g==this.G-1&&(k+=" dhx_cal_day_num_bborder",h+=1);e+="";f=dhx.Date.add(f,7,"day")}e+="
    ";e+="
    "+j+"
    ";e+="
    "}var o=dhx.Date.datePart(new Date);e+='';for(var m= -this.G*7-1,g=0;g";for(var l=0;l<7;l++){var n=a.calendarDay(c),p=this.rc(c),k="dhx_cal_day_num";bm-this.Ob&&(k="dhx_next_month",p=n="");h=this.Da[g]-2;i=this.W[l+d]-2;l==6&&(k+=" dhx_cal_day_num_rborder",i+=1);g==this.G-1&&(k+=" dhx_cal_day_num_bborder",h+=1);e+=""; -c=dhx.Date.add(c,1,"day");b++}e+=""}e+="
    ";o.valueOf()==c.valueOf()&&(k+=" dhx_cal_current_day");e+="
    "+n+"
    ";e+="
    ";return e},Ue:function(){for(var a=this.a,b="";b+="";return b},le:function(){var a="
    ";return a+"prev"+b+a+"next"+b},on_click:{dhx_cal_arrow:function(a,b,c){var d=c.className.match(/prev/i)?-1:1,e=new Date(this.L),f=new Date(e);f.setDate(1);f=dhx.Date.add(f,d,"month");this.callEvent("onBeforeMonthChange",[e,f])&&(this.showCalendar(f),this.selectDate(this.a.date,!1),this.callEvent("onAfterMonthChange",[f,e]))},dhx_cal_day_num:function(a,b,c){var d=c.getAttribute("date"),e=this.Cd(d);if(this.a.timeSelect){var f=this.ec;e.setMinutes(f[0].value*60+f[1].value* -1)}this.selectDate(e);this.callEvent("onDateSelect",[e]);this.callEvent("onChange",[e])}}},dhx.MouseEvents,dhx.Settings,dhx.EventSystem,dhx.Movable,dhx.ui.view);dhx.Modality={modal_setter:function(a){if(a){if(!this.qa)this.qa=dhx.html.create("div",{"class":a=="rich"?"dhx_modal_rich":"dhx_modal"}),this.qa.style.zIndex=dhx.ui.zIndex(),this.b.style.zIndex=dhx.ui.zIndex(),document.body.appendChild(this.qa)}else this.qa&&dhx.html.remove(this.qa),this.qa=null;return a}}; -dhx.protoUI({name:"window",$init:function(a){this.b.innerHTML="
    ";this.g=this.b.firstChild;this.eb=this.g.childNodes[0];this.pc=this.g.childNodes[1];this.b.className+=" dhx_window";this.R=this.h=null;this.a.k={top:!1,left:!1,right:!1,bottom:!1};if(!a.id)a.id=dhx.uid()},Zc:function(){this.h={destructor:function(){}}},ac:function(a){this.h.destructor();this.h=a;this.h.D=this;this.pc.appendChild(this.h.b); -this.resize()},show:function(a,b,c){this.a.hidden=!1;this.b.style.zIndex=dhx.ui.zIndex();this.a.modal&&this.modal_setter(!0);var d,e,f;if(a){typeof a=="object"&&!a.tagName?(d={x:a.clientX-this.$[0]/2,y:a.clientY},e=document.body.offsetWidth,f=1):a=dhx.toNode(a);var g=document.body.offsetWidth,h=document.body.offsetHeight;e=e||a.offsetWidth;f=f||a.offsetHeight;var i=this.$;d=d||dhx.html.offset(a);var j=6,k=6,o=6,c="top",m=0,l=0,n=0,p=0;b=="right"?(p=d.x+j+e,k=-f,c="left",m=Math.round(d.y+f/2),l=p- -o):b=="left"?(p=d.x-j-i[0]-1,k=-f,c="right",m=Math.round(d.y+f/2),l=p+i[0]+1):(p=g-d.x>i[0]?d.x:g-j-i[0],l=Math.round(d.x+e/2),l>p+i[0]&&(l=p+i[0]/2));h-f-d.y-k>i[1]?(n=f+d.y+k,m||(c="top",m=n-o)):(n=d.y-k-i[1],n<0?(n=0,c=!1):m||(c="bottom",n--,m=n+i[1]+1));this.setPosition(p,n);c&&this.cd&&this.cd(c,l,m)}this.Le=new Date;this.b.style.display="block";if(this.la){for(var q=0;q250&&this.hide()},$getSize:function(){var a=this.h.$getSize();if(a[3])this.a.height=a[3]+this.a.padding*2;if(a[1])this.a.width=a[1]+this.a.padding*2;if(a[0]||a[2])this.a.gravity=Math.max(a[0],a[2]);return dhx.ui.view.prototype.$getSize.call(this)}, -$setSize:function(a,b){if(dhx.ui.view.prototype.$setSize.call(this,a,b))a=this.j-this.a.padding*2,b=this.m-this.a.padding*2,this.g.style.padding=this.a.padding+"px",this.eb.style.display="none",this.h.$setSize(a,b)},body_setter:function(a){a=dhx.ui.window.prototype.body_setter.call(this,a);this.h.a.k={top:!1,left:!1,right:!1,bottom:!1};return a},defaults:{padding:8},head_setter:null,cd:function(a,b,c){this.Fc();document.body.appendChild(this.Ka=dhx.html.create("DIV",{"class":"dhx_point_"+a},"")); -this.Ka.style.zIndex=dhx.ui.zIndex();this.Ka.style.top=c+"px";this.Ka.style.left=b+"px"},Fc:function(){this.Ka=dhx.html.remove(this.Ka)}},dhx.ui.window); -dhx.protoUI({name:"alert",defaults:{position:"center",head:{template:"Info",css:"dhx_alert_template"},height:170,modal:!0,callback:null,body:{type:"clean",rows:[{template:"
    #text#
    ",data:{text:"You have forgot to define the text :) "}},{view:"button",height:60,id:"dhx_alert_ok",type:"big",label:"Ok",click:function(){this.getParent().getParent().Bb(!0)}}]}},$init:function(){(!this.b.parentNode||!this.b.parentNode.tagName)&&document.body.appendChild(this.b);this.$ready.push(this.resize)}, -Yc:function(a){typeof a=="string"&&(a={title:this.defaults.head.template,message:a});dhx.extend(a,this.defaults);delete a.head;delete a.body;this.Rb(a,{});this.resize();this.show()},title_setter:function(a){this.R.define("template",a);this.R.render()},message_setter:function(a){var b=this.h.c[0];b.data={text:a};b.render()},labelOk_setter:function(a){var b=this.h.c[1];b.config.label=a;b.render()},labelCancel_setter:function(a){var b=this.h.c[2];b.config.label=a;b.render()},Bb:function(a){this.hide(); -this.a.callback&&dhx.toFunctor(this.a.callback).call(this,a,this.a.details)}},dhx.ui.window);dhx.alert=dhx.single(dhx.ui.alert); -dhx.protoUI({name:"confirm",defaults:{height:210,body:{type:"clean",rows:[{id:"dhx_confirm_message",template:"
    #text#
    ",data:{text:"You have forgot to define the text :) "}},{height:53,view:"button",type:"big",id:"dhx_confirm_ok",label:"Ok",click:function(){this.getParent().getParent().Bb(!0)}},{height:55,view:"button",type:"biground",id:"dhx_confirm_cancel",label:"Cancel",click:function(){this.getParent().getParent().Bb(!1)}}]}}},dhx.ui.alert);dhx.confirm=dhx.single(dhx.ui.confirm); -dhx.dp=function(a){if(typeof a=="object"&&a.a)a=a.a.id;if(dhx.dp.Tb[a])return dhx.dp.Tb[a];if(typeof a=="string"||typeof a=="number")a={master:dhx.ui.get(a)};var b=new dhx.DataProcessor(a);return dhx.dp.Tb[b.a.master.a.id]=b};dhx.dp.Tb={}; -dhx.DataProcessor=dhx.proto({defaults:{autoupdate:!0,mode:"post"},$init:function(){this.V=[];this.bf=[];this.X=null;this.na=!1;this.name="DataProcessor";this.$ready.push(this.zb)},master_setter:function(a){var b=a;if(a.name!="DataStore")b=a.data;this.a.store=b;return a},zb:function(){this.a.store.attachEvent("onStoreUpdated",dhx.bind(this.Sc,this))},ignore:function(a,b){var c=this.na;this.na=!0;a.call(b||this);this.na=c},off:function(){this.na=!0},on:function(){this.na=!1},Kd:function(a){var b={}, -c;for(c in a)c.indexOf("$")!==0&&(b[c]=a[c]);return b},save:function(a,b){b=b||"update";this.Sc(a,this.a.store.item(a),b)},Sc:function(a,b,c){if(this.na===!0||!c)return!0;var d={id:a,data:this.Kd(b)};switch(c){case "update":d.operation="update";break;case "add":d.operation="insert";break;case "delete":d.operation="delete";break;default:return!0}if(d.operation!="delete"&&!this.validate(d.data))return!1;this.Gd(d)&&this.V.push(d);this.a.autoupdate&&this.send();return!0},Gd:function(a){for(var b=0;b< -this.V.length;b++){var c=this.V[b];if(c.id==a.id){if(a.operation=="delete")c.operation=="insert"?this.V.splice(b,1):c.operation="delete";c.data=a.data;return!1}}return!0},send:function(){this.Ge()},Ge:function(){if(this.a.url){for(var a=this.V,b=[],c=0;c=0&&this.V.splice(i,1),h.tid!=h.sid&&this.a.store.changeId(h.sid,h.tid),this.callEvent("onAfter"+h.type,[h])}this.callEvent("onAfterSync",[f,a,b,c])},escape:function(a){return this.a.escape?this.a.escape(a):encodeURIComponent(a)}},dhx.Settings,dhx.EventSystem,dhx.ValidateData); -(function(){var a=dhx.Touch={config:{longTouchDelay:1E3,scrollDelay:150,gravity:500,deltaStep:30,speed:"0ms",finish:1500},disable:function(){a.Fb=!0},enable:function(){a.Fb=!1},$init:function(){dhx.env.touch?(dhx.event(document.body,"touchstart",a.nd),dhx.event(document.body,"touchmove",a.gc),dhx.event(document.body,"touchend",a.md)):(a.bb=a.Wd,dhx.event(document.body,"mousedown",a.nd),dhx.event(document.body,"mousemove",a.gc),dhx.event(document.body,"mouseup",a.md),document.body.style.overflowX= -document.body.style.overflowY="hidden");dhx.event(document.body,"dragstart",function(a){return dhx.html.preventEvent(a)});dhx.event(document.body,"touchstart",function(b){if(!a.Fb&&dhx.env.isSafari)return b.srcElement.tagName=="SELECT"?!0:dhx.html.preventEvent(b)});a.Ca()},Ca:function(){a.A=a.w=a.ca=null;a.H=a.v=a.n=null;a.I={wb:0,xb:0,Na:0};if(a.Xa)dhx.html.removeCss(a.Xa,"dhx_touch"),a.Xa=null;window.clearTimeout(a.Kc);a.ud=!0;a.Sa=!0;a.Ta=!0;a.ic||a.ua()},md:function(b){if(a.A){if(a.H){var c=a.Hb(a.v), -d=c.e,e=c.f,f=a.config.finish,g=a.Bc(b,!0);if(g.Na){var h=d+a.config.gravity*g.wb/g.Na,i=e+a.config.gravity*g.xb/g.Na,j=a.q[0]?a.Wa(h,!1,!1,a.n.dx,a.n.px):d,k=a.q[1]?a.Wa(i,!1,!1,a.n.dy,a.n.py):e,o=Math.max(Math.abs(j-d),Math.abs(k-e));o<150&&(f=f*o/150);if(j!=d||k!=e)f=Math.round(f*Math.max((j-d)/(h-d),(k-e)/(i-e)));var m={e:j,f:k},l=dhx.ui.get(a.v);l&&l.callEvent&&l.callEvent("onAfterScroll",[m]);f=Math.max(100,f);d!=m.e||e!=m.f?(a.wa(a.v,m.e,m.f,f+"ms"),a.dd(m.e,m.f,f+"ms")):a.ua()}else a.ua()}else if(a.Ta&& -!a.Sa)a.ya("onSwipeX");else if(a.Sa&&!a.Ta)a.ya("onSwipeY");else if(dhx.env.isSafari){var n=a.A.target;dhx.delay(function(){var a=document.createEvent("MouseEvents");a.initEvent("click",!0,!0);n.dispatchEvent(a)})}a.ya("onTouchEnd");a.Ca()}},gc:function(b){if(a.A){var c=a.Bc(b);a.ya("onTouchMove");if(a.H)a.ed(c);else if(a.Sa=a.lc(c.Ye,"x",a.Sa),a.Ta=a.lc(c.Ze,"y",a.Ta),a.H){var d=a.Cc("onBeforeScroll");if(d){var e={};d.callEvent("onBeforeScroll",[e]);if(e.update)a.config.speed=e.speed,a.config.scale= -e.scale}a.ce(c)}return dhx.html.preventEvent(b)}},ed:function(){if(a.v){var b=a.Hb(a.v),c=b.e,d=b.f,e=a.ca||a.A;if(a.q[0])b.e=a.Wa(b.e-e.x+a.w.x,!0,b.e,a.n.dx,a.n.px);if(a.q[1])b.f=a.Wa(b.f-e.y+a.w.y,!0,b.f,a.n.dy,a.n.py);a.wa(a.v,b.e,b.f,"0ms");a.dd(b.e,b.f,"0ms")}},dd:function(b,c,d){var e=a.n.px/a.n.dx*-b,f=a.n.py/a.n.dy*-c;a.q[0]&&a.wa(a.q[0],e,0,d);a.q[1]&&a.wa(a.q[1],0,f,d)},wa:function(b,c,d,e){a.ic=!0;b.style[dhx.env.transformPrefix+"Transform"]=dhx.env.translate+"("+Math.round(c)+"px, "+ -Math.round(d)+"px"+(dhx.env.translate=="translate3d"?", 0":"")+")";b.style[dhx.env.transformPrefix+"TransitionDuration"]=e},Hb:function(a){var c=window.getComputedStyle(a)[dhx.env.transformPrefix+"Transform"];if(c=="none")return{e:0,f:0};else{if(window.WebKitCSSMatrix)return new WebKitCSSMatrix(c);for(var d=c.replace(/(matrix\()(.*)(\))/gi,"$2"),d=d.replace(/\s/gi,""),d=d.split(","),e={},f="a,b,c,d,e,f".split(","),g=0;g0)return c?d+h*Math.sqrt(g):0;var i=e-f;return i+a<0?c?d-Math.sqrt(-(a-d)):-i:a},ce:function(){a.H.indexOf("x")!=-1&&(a.q[0]=a.vc("x",a.n.dx,a.n.px,"width"));a.H.indexOf("y")!=-1&&(a.q[1]=a.vc("y",a.n.dy,a.n.py,"height"));if(!a.v.scroll_enabled){a.v.scroll_enabled=!0;a.v.parentNode.style.position="relative";var b=dhx.env.transformCSSPrefix;a.v.style.cssText+=b+"transition: "+b+"transform; "+b+"user-select:none; "+b+"transform-style:flat;";a.v.addEventListener(dhx.env.transitionEnd, -a.ua,!1)}window.setTimeout(a.ed,1)},vc:function(b,c,d,e){if(c-d<2)return a.H="";var f=dhx.html.create("DIV",{"class":"dhx_scroll_"+b},"");f.style[e]=d*d/c-7+"px";a.v.parentNode.appendChild(f);return f},lc:function(b,c,d){if(b>a.config.deltaStep){if(a.ud&&(a.he(c),(a.H||"").indexOf(c)==-1))a.H="";return!1}return d},ua:function(){if(!a.H)dhx.html.remove(a.q),a.q=[null,null];a.ic=!1},he:function(b){window.clearTimeout(a.Kc);a.ud=!1;a.Jc(b)},nd:function(b){if(!a.Fb){a.A=a.bb(b);a.ya("onTouchStart");a.q[0]|| -a.q[1]?a.Re(b,a.q[0]?"x":"y"):a.Kc=window.setTimeout(a.ie,a.config.longTouchDelay);var c=dhx.ui.get(b);if(c&&c.touchable&&(!b.target.className||b.target.className.indexOf("dhx_view")!==0))a.Xa=c.getNode(b),dhx.html.addCss(a.Xa,"dhx_touch")}},ie:function(){a.ya("onLongTouch");dhx.callEvent("onClick",[a.A]);a.Ca()},Re:function(b,c){a.Jc(c);var d=a.q[0]||a.q[1];if(d&&(!a.v||d.parentNode!=a.v.parentNode))a.Ca(),a.ua(),a.A=a.bb(b);a.gc(b)},Bc:function(b){a.ca=a.w;a.w=a.bb(b);a.I.Ye=Math.abs(a.A.x-a.w.x); -a.I.Ze=Math.abs(a.A.y-a.w.y);if(a.ca)a.w.time-a.ca.time";this.g=this.b.firstChild;this.map=null;this.$ready.push(this.render)},render:function(){var a=this.a,b={zoom:a.zoom,center:a.center,mapTypeId:a.mapType};this.map=new google.maps.Map(this.g,b)},center_setter:function(a){typeof a!="object"&&(a={});this.Ia(a,{x:48.724,y:8.215});a=new google.maps.LatLng(a.x,a.y);this.map&&this.map.setCenter(a);return a}, -mapType_setter:function(a){a=google.maps.MapTypeId[a];this.map&&this.map.setMapTypeId(a);return a},zoom_setter:function(a){this.map&&this.map.setZoom(a);return a},defaults:{zoom:5,center:{},mapType:"ROADMAP"},$setSize:function(){dhx.ui.view.prototype.$setSize.apply(this,arguments);google.maps.event.trigger(this.map,"resize")}},dhx.ui.view);if(!window.scheduler)window.scheduler={config:{},templates:{},xy:{},locale:{}};if(!scheduler.locale)scheduler.locale={}; -scheduler.locale.labels={list_tab:"List",day_tab:"Day",month_tab:"Month",icon_today:"Today",icon_save:"Save",icon_delete:"Delete event",icon_cancel:"Cancel",icon_edit:"Edit",icon_back:"Back",icon_close:"Close form",icon_yes:"Yes",icon_no:"No",confirm_closing:"Your changes will be lost, are your sure ?",confirm_deleting:"Event will be deleted permanently, are you sure?",label_event:"Event",label_start:"Start",label_end:"End",label_details:"Notes",label_from:"from",label_to:"to"}; -scheduler.config={init_date:new Date,form_date:"%d-%m-%Y %H:%i",xml_date:"%Y-%m-%d %H:%i",item_date:"%d.%m.%Y",header_date:"%d.%m.%Y",hour_date:"%H:%i",scale_hour:"%H",calendar_date:"%F %Y"};scheduler.config.form_rules={end_date:function(a,b){return b.start_date.valueOf()";if(dhx.Date.datePart(a.start_date).valueOf()==dhx.Date.datePart(a.end_date).valueOf()){var c=dhx.i18n.dateFormatStr(a.start_date),d=dhx.i18n.timeFormatStr(a.start_date),e=dhx.i18n.timeFormatStr(a.end_date);b+="
    "+c+"
    ";b+="
    "+scheduler.locale.labels.label_from+" "+d+" "+scheduler.locale.labels.label_to+ -" "+e+"
    "}else{var f=dhx.i18n.longDateFormatStr(a.start_date),g=dhx.i18n.longDateFormatStr(a.end_date),d=dhx.i18n.timeFormatStr(a.start_date),e=dhx.i18n.timeFormatStr(a.end_date);b+="
    "+scheduler.locale.labels.label_from+" "+d+" "+f+"
    ";b+="
    "+scheduler.locale.labels.label_to+" "+e+" "+g+"
    "}a.details&&a.details!==""&&(b+="
    "+scheduler.locale.labels.label_details+"
    ",b+="
    "+a.details+"
    "); -b+="";return b},calendar_event:function(a){return a+"
    "},event_date:function(a){return dhx.i18n.dateFormatStr(a)},event_long_date:function(a){return dhx.i18n.longDateFormatStr(a)},event_time:function(a){return dhx.i18n.timeFormatStr(a)},event_color:function(a){return a.color?"background-color:"+a.color:""},event_marker:function(a,b){return"
    "},event_title:function(a,b){return"
    "+ -b.dateStart(a.start_date)+"
    "+b.timeStart(a.start_date)+"
    "+b.marker(a,b)+"
    "+a.text+"
    "},month_event_title:function(a,b){return b.marker(a,b)+"
    "+b.timeStart(a.start_date)+"
    "+a.text+"
    "},day_event:function(a){return a.text}};scheduler.config.views=[]; -dhx.ready(function(){if(scheduler.locale&&scheduler.locale.date)dhx.Date.Locale=scheduler.locale.date;if(!scheduler.config.form)scheduler.config.form=[{view:"text",label:scheduler.locale.labels.label_event,name:"text"},{view:"datepicker",label:scheduler.locale.labels.label_start,name:"start_date",timeSelect:1,dateFormat:scheduler.config.form_date},{view:"datepicker",label:scheduler.locale.labels.label_end,name:"end_date",timeSelect:1,dateFormat:scheduler.config.form_date},{view:"textarea",label:scheduler.locale.labels.label_details, -name:"details",width:300,height:150},{view:"button",label:scheduler.locale.labels.icon_delete,id:"delete",type:"form",css:"delete"}];if(!scheduler.config.bottom_toolbar)scheduler.config.bottom_toolbar=[{view:"button",id:"today",label:scheduler.locale.labels.icon_today,inputWidth:scheduler.xy.icon_today,align:"left",width:scheduler.xy.icon_today+6},{view:"segmented",id:"buttons",selected:"list",align:"center",multiview:!0,options:[{value:"list",label:scheduler.locale.labels.list_tab,width:scheduler.xy.list_tab}, -{value:"day",label:scheduler.locale.labels.day_tab,width:scheduler.xy.day_tab},{value:"month",label:scheduler.locale.labels.month_tab,width:scheduler.xy.month_tab}]},{view:"button",css:"add",id:"add",align:"right",label:"",inputWidth:42,width:50},{view:"label",label:"",inputWidth:42,width:50,batch:"readonly"}];if(!scheduler.config.day_toolbar)scheduler.config.day_toolbar=[{view:"label",id:"prev",align:"left",label:"
    "},{view:"label",id:"date",align:"center", -width:200},{view:"label",id:"next",align:"right",label:"
    "}];if(!scheduler.config.selected_toolbar)scheduler.config.selected_toolbar=[{view:"button",inputWidth:scheduler.xy.icon_back,type:"prev",id:"back",align:"left",label:scheduler.locale.labels.icon_back},{view:"button",inputWidth:scheduler.xy.icon_edit,id:"edit",align:"right",label:scheduler.locale.labels.icon_edit}];if(!scheduler.config.form_toolbar)scheduler.config.form_toolbar=[{view:"button", -inputWidth:scheduler.xy.icon_cancel,id:"cancel",css:"cancel",align:"left",label:scheduler.locale.labels.icon_cancel},{view:"button",inputWidth:scheduler.xy.icon_save,id:"save",align:"right",label:scheduler.locale.labels.icon_save}];scheduler.types={event_list:{name:"EventsList",css:"events",cssNoEvents:"no_events",padding:0,height:scheduler.xy.list_height,width:"auto",dateStart:scheduler.templates.event_date,timeStart:scheduler.templates.event_time,color:scheduler.templates.event_color,marker:scheduler.templates.event_marker, -template:scheduler.templates.event_title},day_event_list:{name:"DayEventsList",css:"day_events",cssNoEvents:"no_events",padding:0,height:scheduler.xy.month_list_height,width:"auto",timeStart:scheduler.templates.event_time,color:scheduler.templates.event_color,marker:scheduler.templates.event_marker,template:scheduler.templates.month_event_title}};dhx.Type(dhx.ui.list,scheduler.types.event_list);dhx.Type(dhx.ui.list,scheduler.types.day_event_list);dhx.DataDriver.scheduler={records:"/*/event"};dhx.extend(dhx.DataDriver.scheduler, -dhx.DataDriver.xml);var a=[{id:"list",view:"list",type:"EventsList",startDate:new Date},{id:"day",rows:[{id:"dayBar",view:"toolbar",css:"dhx_topbar",elements:scheduler.config.day_toolbar},{id:"dayList",view:"dayevents"}]},{id:"month",rows:[{id:"calendar",view:"calendar",dayWithEvents:scheduler.templates.calendar_event,calendarHeader:scheduler.config.calendar_date},{id:"calendarDayEvents",view:"list",type:"DayEventsList"}]},{id:"event",animate:{type:"slide",subtype:"in",direction:"top"},rows:[{id:"eventBar", -view:"toolbar",type:"TopBar",css:"single_event",elements:scheduler.config.selected_toolbar},{id:"eventTemplate",view:"template",template:scheduler.templates.selected_event}]},{id:"form",rows:[{id:"editBar",view:"toolbar",type:"TopBar",elements:scheduler.config.form_toolbar},{id:"editForm",view:"form",elements:scheduler.config.form,rules:scheduler.config.form_rules}]}].concat(scheduler.config.views);dhx.protoUI({name:"scheduler",defaults:{rows:[{view:"multiview",id:"views",cells:a},{view:"toolbar", -id:"bottomBar",type:"SchedulerBar",visibleBatch:"default",elements:scheduler.config.bottom_toolbar}],color:"#color#",textColor:"#textColor#"},$init:function(){this.name="Scheduler";this.b.className+=" dhx_scheduler";dhx.i18n.dateFormat=scheduler.config.item_date;dhx.i18n.timeFormat=scheduler.config.hour_date;dhx.i18n.fullDateFormat=scheduler.config.xml_date;dhx.i18n.headerFormatStr=dhx.Date.dateToStr(scheduler.config.header_date);dhx.i18n.setLocale();this.data.provideApi(this);this.data.extraParser= -dhx.bind(function(a){a.start_date=dhx.i18n.fullDateFormatDate(a.start_date);a.end_date=dhx.i18n.fullDateFormatDate(a.end_date)},this);this.$ready.push(this.$d);this.data.attachEvent("onStoreUpdated",dhx.bind(this.Oe,this))},$d:function(){this.ae();this.de();this.coreData=new dhx.DataValue;this.coreData.setValue(scheduler.config.init_date);this.$$("dayList").define("date",this.coreData);this.selectedEvent=new dhx.DataRecord;this.config.readonly?this.define("readonly",this.config.readonly):scheduler.config.readonly&& -this.define("readonly",!0);if(this.config.save){var a=new dhx.DataProcessor({master:this,url:this.config.save});a.attachEvent("onBeforeDataSend",this.re)}this.$$("date")&&this.$$("date").bind(this.coreData,null,dhx.i18n.headerFormatStr);this.$$("list").sync(this);this.$$("list").bind(this.coreData,function(a,b){return ba.start_date}); -this.$$("calendar").bind(this.coreData);this.$$("calendarDayEvents").sync(this,!0);this.$$("calendarDayEvents").bind(this.coreData,function(a,b){var e=dhx.Date.datePart(b);return ea.start_date});this.$$("eventTemplate").bind(this);this.$$("editForm").bind(this);this.$$("list").attachEvent("onItemClick",dhx.bind(this.Qb,this));this.$$("dayList").attachEvent("onItemClick",dhx.bind(this.Qb,this));this.$$("calendarDayEvents").attachEvent("onItemClick",dhx.bind(this.Qb, -this))},Qb:function(a){this.setCursor(a);this.$$("event").show()},Oe:function(){this.data.blockEvent();this.data.sort(function(a,b){return a.start_date";e+="
    "+a+"
    ";e+="
    ";e+="
    "+c+"
    ";e+="
    "+d+"
    ";e+="
    ";e+="
    ";e+="
    ";e+="
    ";e+="
    ";e+="";return e},type:{templateStart:dhx.Template("
    "),template:scheduler.templates.day_event,templateEnd:dhx.Template("
    "),templateCss:dhx.Template(""),templateColor:dhx.Template("#color#"), -templateTextColor:dhx.Template("#textColor#"),padding:2},we:function(){var a=this.data.getRange(),b=[],c,d,e,f,g;for(d=0;dg)g=b[e].$sorder;c.$sorder=g+1;c.$inner=!1}else c.$sorder=0;b.push(c);if(b.length>(b.max_count||0))b.max_count=b.length}for(d=0;ddhx.Date.datePart(d).valueOf()&&(d=c);dhx.Date.datePart(c).valueOf()dhx.Date.datePart(b).valueOf()&&(d=dhx.Date.datePart(b),d.setMinutes(0),d.setHours(this.config.lastHour));if(e=this.config.lastHour)e=this.config.lastHour&&(d.setMinutes(0), -d.setHours(this.config.lastHour));var g=Math.floor((this.j-this.config.timeScaleWidth-this.config.eventOffset-8)/a.$count);a.$left=a.$sorder*g+this.config.timeScaleWidth+this.config.eventOffset;a.$inner||(g*=a.$count-a.$sorder);a.$width=g-this.config.eventOffset-this.type.padding*2;var h=c.getHours()*60+c.getMinutes(),i=d.getHours()*60+d.getMinutes()||this.config.lastHour*60;a.$top=Math.round((h-this.config.firstHour/60)*(this.config.timeScaleHeight+1)/60);a.$height=Math.max(10,(i-h)*(this.config.timeScaleHeight+ -1)/60-2)-this.type.padding*2}},dhx.MouseEvents,dhx.SelectionModel,dhx.Scrollable,dhx.RenderStack,dhx.DataLoader,dhx.ui.view,dhx.EventSystem,dhx.Settings); diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/blue_tab.png b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/blue_tab.png deleted file mode 100644 index f874fa321f76c0160b4b8f48a9daedd36cee8bd2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 247 zcmeAS@N?(olHy`uVBq!ia0vp^Hb5-K!2~3QS7wv~DYlXzzhEE@1bNHYCjzN8o-U3d z9-VKm8gd;nkZ60jT|%I+@bbcQPDi;T_O`Hp6$;Z=5S?@TU|y`(N|Rpai&^>LliG7K>pl(rSzno3KoOa=R6OQ;>i`)H-Zq+|- rem;NCMy?*i15f`I>27?rBbrhEz?;bOtEaj?aro^_LoO#n0oLiZ?RyuPUpS?GqslgVeZo@nfDPL>Z59ly6Z$XQd?Wp%_+|rv zAin+&({_B_Y(4LETD{imw~SIs%Zs#+$MK)Oc_XY_)5OIud&1wMy*F!&Hls+*7R9w&bR`KG0FOwjF-VBE?4X&3fUtYA4 zZOCxh+_YJ5b5rp9hAQ(dF0b>sFK%4)^arb~S3yWRWAq}R%Naaf{an^LB{Ts5d(dK@ diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/but_repeat.gif b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/but_repeat.gif deleted file mode 100644 index dd6595e5d9ef43bd03c486ff87079f398267e085..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1149 zcmZ?wbhEHblw#0e_|Cu(?klqTfBEyoYklCmVoqenVS|Pe!)>e59cFWsU9>AW zZP8U{yyh;8RlNr303RUE2#_d#_^)>0%x$Xs10t-?UO*$CP9jc$w;rijn>#HZ* ziuOA9HrlOUoN#1EY26vWko7W`kGGuIQyH^LXXo0ihgT<^dANV+jn?#K4u`fCUwwP* z-M5!ZXNH}5yl>s2_-m)ym(2>l`}us|%dq{M3y$q7@2KifR>Y}Mw6)3c8m-~M#w=7-a1 z2lYB02kd$=@8hpG|NsAI7zM*O1QdU=FfuSCFzA512+9-e9RC>(a>#gWSa7hJLs%<@ z!>y62jYpg%f??u==`spD872Y>4UJt1VGkBu+W4e}lTpRt$^pd#JWK}3LKB3T9*Ht> z{5N>MH5zv}sFyVmL)JDz@z9|n~A2ze=aoMTfc#?RCTa!a?fk(jUuvRNSo+m#7 zABgF&Eo)ezv2bzAcA+K}&I`<}M+6xCroGv*gqxjLp!QVD$^#6OloTdwc^t4{g{)f>K6CCawk>Cl{7Cw?#BK3K$BV zSs5kRIOOdXxUhBTvni|)Xl*QJN-QjLPzCavSUfPI0sfDy@jpkeH{?dy!N3 zhQbX7(}VJFMYr8B{IE5rQKCY`;NikW%s2R0UNrDKaC~s&6i8KY$lHF<>b{ktD z&gisyeO}}wWwu=IPQcysynfG5*AoY441ID30dRqYbB2hDj*oeU0SAKw43?OemjIca zmy8XQ2$l?`rlkO-{A0vp~mdytYTbG?msW^U zr#j6lvq09dT+^yuJJf1X0dM0fC;-4L+`9_kQoUzXuU`e6%*y?X_HW+7hz~0^%s6r5 zqF(Vz#(P-uVW*ZU-_3lP;(^MbIg1WWdbDW)xdf)NP2)85Uy zx9{J;VH*OpAUN;?ZyFFc{+kM-;>@E-IQ3E2UV#jV2dz}|K7IbH;;QNrz*VAWT z&%M2R_w3)xkI!-mk0eEOoX77&KNJ1{1{YYw5-_xof)G1|V4wyF7P#Pp5RRZj1OPka Cm_4ij diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/calendar.gif b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/calendar.gif deleted file mode 100644 index 67257083540f7ea06881718da65d749f7284e165..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 622 zcmZ?wbhEHb6k-r!c*ek>prLT)%o*dfGgj$`HW)Az6cjY9_^@!{!iEJG{{Q%I;E^z4 z!G;SD{sW1G2@e`(9Qfam@FBrq!iozH0SOHY9(?%lzo28ogbn{4Djqzr5a{jgov`A= zh65M&@85s>_U->O8UiXVBt#?>EcoD1aG_wvg9k7EH#9UXSaD#%jt2)U1ZK{h8PM>c zVZn$0|NmdSa?Qab;lPOt4J-aPEI9Dt$A5={2S5dnpFCc$;lTAP*C%YaV3lz(dCI*9 z4g$qf)-Kp_;lhmv7j9e#Xtg?cw=gYN-LX^L zkc~}ezmnDRmHU*|uGiL?1^(|-fE8lblbd4od4L*O>-Nnixo_MTBMAhPt^YXsC%yN=J0u$6;9q86(1O;^YnlA`!OMrv9(1`BVyeag@*_CuyPgcJ8^Pz`Z*T|W<~~U06^u> AiU0rr diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/clock_big.gif b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/clock_big.gif deleted file mode 100644 index 61f7dc2e5ac32fc064ffb4e231f344df03d07baf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1321 zcmeH``!m}I0KmVIhu6+xXQh>06V%F?qh)EkZW3)hs&#ZarWvxNoo;QVXEiO_5K$#2 z#3Qb$#AB(~2ueM&NkRnmh*v}-2#b)=1sRIUu7ARQ-{<$wFQ2=Qf1ux~)A*ynQDB=1 z7>!1;SX|9t2@eksi-{YQYbGWpD%+Ooy0mdgS<1zCJfSY5{B?FQxA1qBY<91EWb?-a zY8rbwzjh9PJ6SZWBoGLOt+$f#1qQo*dVaraXydP?75Us=W`#mAuhFjQXBQ7zgwj7H zW17`X{rYA`ei^f}d1T@>wM?E_P*GGfRK%{yd9KW5)d%C^N}J`67;V{XQ8rguRaM1p z=*(bL)_3$%*i-#7jbe7Os&koL+aZu@cm^7wXN@X-Xe8PN?$>z29$mX=EIjrQ&;<*L&i(WN_EhjyG@vvlM zVrG|C$maLSMy7XEnzc#gZu(Qn+TR;gmL!W=PhrdQN*g*QvP4=#R@q>yX!J>8Wo_F) zgFwd@_T@dRlT5CZ)^lYoT|sVFFT;WtZ~AVk=f!jOFMXfDCf7J;?tQP z5%C`}U?5*ByZ}z^p*jFrIHdJ;4H9K?#)Xs)cZ{N1@4aZ2nl#MPhsy56Hr+^JoodF;gB)*blVN`(U9opG zg#^RL$q+kY!O!_tBK$bY7vcjlyJm!XVe*uEfFDFU_%yX* zBpYUP0@)s#hIx?ggB9V?0Qis;U5pAiJBn~N^+G`r2k&g>aq$78=Sj?4a6hoO*D{Cv z^`sPI*MctxtcXOw_a`=p`S@ET5d*XO*gT#5!C_1p3doCqUVxp5`J8S`X!C$rpo6I* zxI0Y+y%=3Z&#dh{Q3Xy-~T6X|NCUj z-+AKAj$^O4oc%v(-P4P=e*FLcf6~g^o6r1jUwo^5;nm*dx0CC)-F@*tt7XTEoe$67 z_;%s`|Hp6s*U!GR{=kbx`@T+Hb}p-J@5KlIx1IZ+(X#u*#rLa^|4XUcG-vJAQ(#*m&j9|EU{aOxyJG*p2@MJ%=AY`_F&_DE?$& zWMD97&;iMV{KUYv@WAW>4;`s~kH?3FUzRA%b1$-r3GorDP~irs!TK&W1KgS zYyNz(**XTyD^~EWWH!*5t)a)Vc?;hbJ&oC#61;5t_V44B(41|qt0=^I>a>ue?olUw ebzx;08D(L0{R_^j3Wi)SnAsUe&p%Yv$JM$_W8+`K+vL zQy1@KV`DF|zZPaRp-Va7Es`fWH{!n_taqfi)L%}l+!NRT_gf~c5vTfPAO=yP@zY`zB-u?Ry@*U>$I(GcT$y28*)fmoQIDhHFx$tYDF7dZ+ zoj;d(|GrD{K0OuZ-`~Uy| diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/controlls5.png b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/controlls5.png deleted file mode 100644 index 24957208fdcb6ec0fdc02a6468100c686eb9ecf2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2835 zcmV+u3+(iXP)eI3b~U|9Lw@OaL0=-?F-$J$v?G>(;HhdOLUSWc=Euekkkj zGgZlDI8+qDuC{u3+`a+m3yDN;_(BX$^LuRIm$j6!GEEs)2Cme-LmKTkZ2s~N3k?kw zASsnfkq8{(bdQJt85|rGpb)1-_sYx5@#!1EHg`TPEsZTnOaS}q-w?ETj#;4c^Yd9| zW+oOaSU`ERJTWnm@@D&|x{}SDa=(UhsxzeN(*X~U;RhNG*u#eyZ0kaI+zRx*94|c% zfIcbyMC6af9g_@N5(&Jzy4og7qPi0Ws9Dp3te_wye0m)I@o$-|)7I8z)jKRH?~tF# z9Mk^=#q-ZY^ZoZ|K6w(Yw{MGQZv39-3opQZ)(kkFIReIpSl@!gNdu}>Q_6M}?!eNe zOL6w>S>w|k34Z@O5jMT#%{{p`)oaUrj&0a*7bu*K6Ir`)@7_K5r>C18Jhu!fH8quy zm5f-HNj`ciH0VJ+sA2Z$$Dj-dK>f9A(6sizC3zG4Ut1;WHGTMN=ER8Y~`kY;3Hsa0dqmoyAikWut!e z_V$WoN#CTaxsdD?Xs@kBd)E*=x9x+{*I)F-Ir}T-t>^|45>U8h3+60e4izs;b&#~y zWV>Hfe8IxJ!w}{bW^i0Lnr^U&_ELyi z@R;xb!Q)>J#gc{dME=LGMBpcJQKHV+hOGstun>s*puuXbB%t#0@(>Xbfph21AtWRO zIXO894-W@rPpyfZG#*XjY}oRg*l$UAAZC_`nbjyXC~dIX!#Z$?Q& z2^;&2?$I*>sI|3~8)zR+pFWLUKip*+q<${^o8M`mQUb-5^(d&QLw?zPaecn1Qt*t+ zr8tvUBJ%&vEfjUE0co-TB5N_kZK3``_JD?4UdXIzx@UA9 zJ%5hiu~GAM_Yz{FtO9AW0MgSm#l-jI{al!QzJbcw8O8u||IHsnKSdc{mg*?YwaevF zQ&WTFtk#lzyodJ& zln?Mz3m!5%;88h#9UT#_cWus+yubdKd9R;*fJR%AF^jSUL`7r_+OyN(>Ei|tDT^$thKR4U%zSs6)!>J93i;F{9S(yMw?1^}uC^t732a*mTQXMH-bap2; zseC*S8a0B~)YYT6{(xqZ^XgB+D}SwQ=NNd?H% znxwt9WID9}(d%gG89)zhTDcoe0L}f~BY+$V&ok%ad*M`9CCX4)s$-6#XGBW`LPkc0 zP~_{^uZu)^x<}8bjK#-7S{K}d@3M(cn>M^AQ9dBxktNYJc~8Wn_`ZR-x#{j8{d{nc zYf{vtThOGOkNF2ns^oWB?Y`|$a{)$?S9q%cP9ML?Ml_hF3v_UR>i9-i_3jQ)$C9=Q zgwI!e&eon-D=bQDK}UXZ#4JGLK#G{9#ILp=f~&I%Q(c_k<~p2Qom6mC*$*FN_VSK) z_oB6ve(fQrQix>4avZFV%Jv}`l z9}^Q}(Yc*&jjgI+otY=motJ^WiW|d6Mj>Hvid_Pi#Gk=FFyw!Fx-Q9IW}kkNKl;fa z$s~g$gCvs-l1!HG;hvR&$bl$wAc`D_LL>*G$bl$wAPSKjh+;d*fhckyiX4byj%*1; zIhAxuG6|9#i1K6uQPNkWn~rgi15uuAAj*X`7tF^v$bl$NE)XUE?R?3i&Fqs1MBxHv zBxG$Os~Fh=NY+}?(-??C!jJrCBr_F=Qnay1vgquNBhDroh(c``d(qfHlsT)5$kbUa z_onLjfGN@3+|tq_zNqr{m`Tka_1uy`6jBCL?K!Ray<{j5Mft{WX;Ei}0#T@rB}zmf z7z;!(2auj6k#{lCK$Pa@X83ST9827_WTOL7YSsV1J>EfgiXm`y#gr*ibX<}oOQsOk z(a~YmT14(Gw*aP8DviFthh#8v$|LE4L|Qk|KoqT?KbALit;cB!ljA3T9$ zYLF%z1x6FMcWVKx_tLPUEJnhmttX~;6EE#f2xYJc(B&-4OOG85Ke=FFKwvB>JD z^1TvqE>y|bluY1LAKKg7g`yB(Bu_UtHz5ZCWb|37c1<2F7ad46aP2u9B?3UV8y^8@ z^tIkba0EDdp*0KsM2M7%)-wX0-aod_x)W_aa8d}eA}$o8!XyujKq46sCxGdmaK}g7 zavGynfRsqvN&78PGOdH8wR}U$V)Qgbjuv|QN&Ye`gCx^q1&O|rdS@SEvWT8M8C;Xh zeI>nGrD4q-edFqRx;h{_(8K1kGFfmeqyuP4BHxE-jD960p~pr3U|eIlMYqQ9XL#9H zBgU6KSA0vBzAe+;@K@4A1UAn`R#ukDucSQ#3e0d<>TzSlBnA9DlzLny8!XA%ucW;L zK-mL^+1`@iy(SL9X%|u3%HZoJ2`-ZjmP9Ai)_y`DQ0DqbD8A1GHwBU%e+vOr-#!eK zooqGrPwWzF2 lR=D6Y$tMmnSxNsDU;ytXnYZ<(0)+qo002ovPDHLkV1l_%QG@^h diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/databg.png b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/databg.png deleted file mode 100644 index f0ffbdabc108e650383ef3df89eacc043db5d9b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 89 zcmeAS@N?(olHy`uVBq!ia0vp^j6kf#$P6SsHY~OWQfvV}A+B%Uefj_Yf7JdxSwIm! mPZ!4!j+x0B2?}CDybM!6aWy6%oWKf{VeoYIb6Mw<&;$Uo3K%*7 diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/databg_now.png b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/databg_now.png deleted file mode 100644 index 9f371b4df716915175019c9422df7c12c27f64ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 89 zcmeAS@N?(olHy`uVBq!ia0vp^j6kf#$P6SsHY~OWQfvV}A+C3xefj_Yf8N#)Y(Nn{ mPZ!4!j+x0B2?}CDybM!6aWy6%oWKf{VeoYIb6Mw<&;$UeBp3Vu diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/event-bg.png b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/event-bg.png deleted file mode 100644 index a3bae3e018613bfa0c160ea6a36723d641e3a415..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^j371(GmxD1Q}Q5?(hcwlasB`Q|B`)I{(pP)|LfiV zpKt#Ebmjkt3;*Ar{{Qy)|2K#JzuNo%<<9@lxBP#$;s2A>$=A-j2WnLEba4#fn3)`q yV31Idz>(mQpplS~Fyp|6hD7GWjBVUJ{0z3Y*cxAN?N9-#X7F_Nb6Mw<&;$TzL__TW diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/icon.png b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/icon.png deleted file mode 100644 index 31d6626cdd40848c6d900eeb8e8d4057f6dfd553..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 230 zcmVsi?L4DSwy6=Gyw9+ zFovGaHzsTy&(`(mA|C-TpGSSX^ClSheK+Y%@EY4KGI}?S^dBdHlI7}ny*~iZxu7XL g^hQK^3Fvj(FC=_u*5-+h;{X5v07*qoM6N<$f}pKl{{R30 diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/left-separator.png b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/left-separator.png deleted file mode 100644 index 22d630927f32a8d4c66b4cbb851f20002aad0e9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^#z4%(!2~3$o)(t^DajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MID|ljv*DdZ2WHv9#-I)EPr>QcFBix7yH*t@Vh9Pq$SxT zu<3%V-R-{5>$oF!%xaa|x+_&9hR3^f$)(@tYA>xRzwqPwv(VfP!nqvDPIKS5)_mcq ep0}TYnc VW}y=sH5X_cgQu&X%Q~loCII&SCFTGC diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/lightbox.png b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/lightbox.png deleted file mode 100644 index f0314fa609946421251eeafe1bd88b61216e671d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{S!3-q3+C<%eR8)XZi0hJlSN;RRw?{v|y!`n2 z!>f?N^}pM%{@r@@@5al2*I)d*`uyLO=l?E0`*-o_ zzY9v zum3Ng%&d+z7H&;jaY@O1TaS?83{1OTQT Bb#(v$ diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/loading.gif b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/loading.gif deleted file mode 100644 index f5e71df6aa432e63b71dc708a929027822689ba0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3951 zcmc(iXH*l|w#Oqe7GM&`C^Co&I;dm2%rFjeMX#u+IM_x-utcd!QIMgFv=BOkE;T^t z1VTwjC8Sq+Cxiq-3rH_g6&}u7_rt7r%Y1q3?N4W&bOz5mxuuAMWm3;;j? za{$1`W{CCHKeepSG1muPZmt1;g!YEYZQ}>`uNd7m{^^V^aLeYV_PWLuS6fRrTN^D; zd$(6wmJXI)PR^D#XYAkDIRms;w(eBkJay{p^{d4ahOC7h>j}W4MdA!TRX4TF37~VV5toY{8&jyL>s7Khd zXWlB|uVA z!Ra58vf^`+(^7I{3o`)esQhd!x*{*LpsI*aQid<5R?={o(i$e4!l~smcy-luVk5ah z$SUq2bvAdmwQyVOSt8khbV$%QGB`Ti-=mO^H%TVPraz+Dbd6=xX&U^RpXar9X~l3JCkRd2i=$ z=N)M8>FWN*B`Q4nTSP#7P)L|Z1Uys&l#vPA1I$4KvvYIu3yN|}(4~ctf^u+WUPUFg z8dr(RB-Ij%85mX>rwV|lQL~+v~d(}VP_k@B}+ac>*^mJ=onY@ z_EB3V#2;tICYKf@i(lqy)+l4|6y>nmpwD2LQkb?x4+16|^)6Ou8;7fb%xpkfTekdL zDy0{WIb^mgt1j>k?h8sYk55iTKjN5T6Qk!X%9lQQ`K+%%W#w#@IjgPa^*4_Ef-p_L zuPohL)`Wo+yBWW|@3J>6-+_H$!KHNMaa8pZ&I`w%?8ngU-MwAmfu24Zettn= z!O|!n9XcHgj3Mf-rCtwCvO;R8g6Nmc1d_evM~jHcDlcBU~y=9 zWEC^fBc5*uX$tPZjC_{*_bw;`It{eg*$E;kmnkj+|U5wL& zZffd(tLBf)*;I|t?XW^+p%%qJ)wGCozc zN>d}VXb`847<5?-$2BhTWGk-ocj@6p4g)jH+GJG|EK;J5RixGhE5I(ChDWB|`ZvUNdi z()1;HfSK=AS3`Fnn=rcwPdF^tImj>8KR)DLly_)o;M3$RRE~p5N_u`uW-c0$U4lIT zs;mM*aaGj>JcLXE1L+JPl*wRoSP;ITme1ofGMgDSBti$SizsZ6G)Y_fxN>^y&|n=v z)J`RfE2n56dKlo}Nc1IIPDZq;?krvJXN`|wl2^mC@iM5!@{cNcaca!Gfj zjf6aDP4_-{=;odsaYHwd%KOa>i>h=)2}k>$1(?L5fBt6Qth~Nx{_^eU^N~9LjbDi` zVyS1lhn0DJRx0|1j%CNt z;E_NYbsYTuO2cnQ9!7Umk*7}96gr{CtseW0uMuc({eE|JJ?QnyIyAyE=zSnEATBss zDbhCCGb%PA-9ID#aEkpqkK8byMBgjUG1+j`VNewg1jXYB#A*nI3Z_AUEH;qIVe$Av z&Ss$!K=>?14TVhX!iz~Qtxa61NM1kKINS_w1-8>WJG!TPW_!nEivCXnD?@7|Uq%7# zl|bE!Y^ul1x?JVe9XT;{srEb58#6DABY+)7Zt9h%k6cGUhqd>3$Jy{gR6pep5nG@C z8lZ9HH_b6eR7k3h<6>L3s{(;K?OoNI`rip+)U=inEcLVjES!~*Cr1NuGVnQ+EaC#C?f=#wC&Ns?Zwmg z7E(`1_bM(ry9EXMyDNF!_xAO%wu=b~Hj1}!Nel>!MB0Yir#ZysIHBK|WEDmfqxAEV z%i!f&ARHb9t;Q2c1PHYTTuUKAfm|Mt!{-V`_54O&GnYxDvZ}kt9c)QAL{!(;-zper z7-<^iwKF=UJ(In&viTW6|1fxY=<`SUYJc~ZT{oJa(JaKfR_i>Sds%*fCSyahyRu90 zeW%Uxy6);(@!g=g7c{?f)!;=h-aTQsJf16vS6zy8TR|TEDe}|L{q>}|%-b>AXT4N? zEQ@~4Y1;i4I4*wBis-o!VwZ{@+-6l?$Hdi}CSC1AiWe_3zdycpHH4V~if5lq{V`u} z)ooYY^+AyaCoQj8!>bUN#2?Yor^=MDJ z-}zZ|Ao8L|#LJNI)X0Q4?=xJpVy-5oeMoljvP?&n#zqDFS;?ECW#InIkxnJEh;7U+ zwz#vl{SS`Ka&W(3K-4Pjp6HqC1&q(hW-5n9M+V25KJ%96l{#~~V*1a+XGb#G{O0Ed z0L50dM6XyYR-np(5jg42ndf@ZYSXWw_T~F7#~-_OVnQ&R%lG@+hW*u|9IcwP?ar_Y zllh=u{Wbh}s;j5|Q-9qj{O82A^ZVkY5rpzFN}&4Z2tB=rznKoI1tU*(9y#u|EAXUj zQjzdO`uT#!ZTTAT8(q7ow{AKbxHxP0#q$U9C%QXekHql?&rbU*me)Rf@c=IS8+qUM z2@bgzY8L47TIcN#?_CjLi4pK5567o*v5|gPKO`rh!&6gU1r(>FbU@g05VWGa3Rejs z5W(bX9Ib+mhX6TTAe6@y2>I;#O{Pq28wJozZEdNQFdBt*{e3(+ue+;9-1|{B!J2B9 zPLGZQ>KnjI!=gd1VqbDZ&T{!>_)K*hH{^LPI$DQ*(T8A|qlj%ih zK|-R=xmwYp4sz`uq{ctJ;Hd%I9c8d<1eE%d1=fjl2T1z&6WiCm`%iX(2`|!m!eJ#9 zapmfI*0x3--$?Wc3S_59+YN*;%sdsoX7J(Cp*?1&c9xwkNbJn;AwMx8=|evVJFHbO zt*E4aPyH$E^47|qhZ#^OT0;D>@p%s=4 z-#NzKBj;XN{v&cj^F+HKcK@@haHvkJ^@rO)q32O)QjJSh{!M`PxP3~>Uy3(^~ z@sfN89m^p#s@hQU{A)#xupr@3M2OzEp4SeX5?k-dyis)J_zq>{uf=5l86CM?25s~;9 z{_-E7>>Lmjos*ZJ3n?lFV+!-j(Uk=yMYwDzkU|BLYbe<23RV>dUq;}OM5O?xfZfam z(-*uuPgg)*6^6g_UGatCWjc-K2{h$!!``~ayT$mNq4V0D+f@Y+nvN9p)TyTC) zR&fR`2uVUjV%o;(hh*3=<@BuAtta?r-ucNi6T_}+? zHTMq6q;-9Yk%o_5qYZNM(AeDg!sLW_co9FdjN9M>te~S)vf7<9z4kLaCpkG}pZbZY pWf!ZHp$(dbz}SD8G>Wgb=uaa1zqEv)*f`MtlO;U=)dv3&{{wX{9B%*s diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/move.png b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/move.png deleted file mode 100644 index 15681b311e095bcf71a016c10b98215d2f62fdeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^j371(GmxD1Q}Q5?(hBeias3Yj{~rDSclZCloB#h^ z`TzIA|G%gI|2_Wy@1g&H_x}I8^Z%bM|Nm_G|7SJho#WC#T}qxVjv*W~lLZn25)2Xw s5;zh(5;PJr5@sCO(2&S{n6ZtU!Ptv+qi^c>nLyPHp00i_>zopr08)lQEdT%j diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/multi-days-bg.png b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/multi-days-bg.png deleted file mode 100644 index f43a46357b2b8a44c62bb6955413ca6c422397b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 350 zcmeAS@N?(olHy`uVBq!ia0vp^j6n2-gBi#={doIQAhj#NC&cyt|NoEQ|GW3*->p~w zu0H>F@#()akD%!6<9|SO4vfw}`3FH4p8UJ;6r>D-E%CiATwRVHQB_&GBsJyf6H$?=Q$jla?0-X33{vuFPP+`eJUrfnOyZZ0n`!f@W=oF diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/second-top-days-bg.png b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/second-top-days-bg.png deleted file mode 100644 index 8f9a4f6da021cb45908bfe9e8d904e042b2f047a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^j6kf#!3HFY>I`du6lZ})WHAE+-w_aIoT|+y4HUHT zba4#fxSkxb>HVqtw*L+XN*+8aW?NSO|37nQJx{^4`Zq~BXM7Zz1ZN)Ya^*R*tKh#R ivt*e81LI3EMh3oTj_Eal|F_ZNmx0r(h1H*=|U3OfpzvHi}DR`OfUbAABv-upo?U|K(>>jf7 X&0u(ba8}zzpe_baS3j3^P6`1px&CF4n_O8yr)Fq>iQ?Oe~R- ZJN}%psYOZYWQNhg04>pOR|ysdYXG(YZ0G<0 diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/white_tab.png b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/white_tab.png deleted file mode 100644 index 7ee9285229449c6b3361135be958566c494f600b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 290 zcmeAS@N?(olHy`uVBq!ia0vp^HbAVx!2~3uq|aRjQfwtbe!)N*2=bP(PXtoeJzX3_ zB3j>G-OY8#K%(uTzJx$wVG#S=qhjd?Up>&>QB}RGinHtkLtax@;ku5}S3yfIH9KFl zY%=}#!9Mud^!^DP4Bp4T{&^th_9K7kqBWtXYBy_6>*GFPB(-bulr??_@=7O=S3O<*T-G@yGywp3=X(MG diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/white_tab_wide.png b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/white_tab_wide.png deleted file mode 100644 index 6e5ffb852f02941eeb6e6b7bf27e6509c93ad44f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 300 zcmeAS@N?(olHy`uVBq!ia0vp^Q9!K1!3HEb8+12=r~;43Vg?4jBOuH;Rhv&5D0t7) z#W5t~-rMWD`3@$?w0*2!+}Uxor7<$&j8OYQ-H5w#tGzEARNUyPVJLhsMNrZ9#q!Mc z2d+!ZyMO8Mk0)oRUz>2@jwRdm-_G;&!#`N>T%)K=Dy9 z8UiCN1S$f&%o!LM8A^iug8wrB^T7xPYptJY1LL2wz$3Dlfr0M`2s2LA=92~rvX^-J zy0YJ9;TPmqcHKEq1uWzmQQ}xyl96A;uyWlQ51tBm$KdF>F7ur5`BF0TK>REXvEwOJ_JB{j41*#tzY6T9lm1@b!Q5 zYnU?U{M_8syb^|QXQu53im`!|g=CiGq%y2{cS#*6qVMVA7$Pw>IpGMG1P7@BN BaBTnp diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_mobile/arrow_left.png b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_mobile/arrow_left.png deleted file mode 100644 index 651215a15ae456fa3036d74224e7eddb127d51de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1955 zcmaJ?Yfuws6paBQW5HUB2vX`2Dqw}Ykc6Z}3~T}nCcH8V29%I2BuaKeb|DeP2M)m( zTD1jfttbMmyiAe$2m+=ff{Kbr!BTA%N)>D|AjYB-+l>|NkJ6pl{a)vsd+&G8%2JgaK(#h7#tIA2+p<0i~Qv zUKJ#y3Dx0{LK&H>ff8~>Vp;Bb8Cy;cT?T~cIJkfc!lZysl?kI99hdw{mxIr3+f*{} z3WBZYlK)96Q5Xw^BN_+@qR;|lG$svT(kb-7r7RZ9A7IevG%Afjr85HPEKVSUL!$w& zA2J?IBTwhVgM!zw@D-P=z%Vt3O4Vw$6m1{{(PU8RY&P4b!C(a7hyZj0j7fC?FzP*} z079rtqf}!`1O{x1(ljI+KbefvAD-gdkv* z5|$%c^c7ktZBHcxHg-my*Jm=<5Wu{{LiUf1BJzB%_u9D!i(9tHBmy8hadwJUC|a%qp* zV$F_S+?C(xvZK*2i}(hM?Hr`rL)Afr(^W~_6mLpHjJ-CC8vV$t(7k5jn zR_lw&L6@spu7OvNO~h%|0!?l#Ju_QAJ^5^e$;eVBsjjmc4f_< zTsNn9^8TZ3ZT#`vW|vt7Ys`HmM~#bs?KxxZDf-5qo*u_oMyX4_)!lQu2>|0U9fQcn8$`+p`n@OX=LcRhC#m>~&0 zmhy?pm}^K8i^cCb+H=H|ku_gl^Kp@Ea->@5=hI<6*vOQE!bo zI;%77+lPAd@I|NWHO<0;Vo%ICN$@K4UY)$7bKce&#S4lAU!|Yga4W&*z+$82iR}5< zkLbv{{+QFmK)(Cl-) zwy}Lq;lS;dy90s78HyzrI>XD=#(00%pA7osPwKFtOkdBtk6bTY1FO5ZbjdspsiZ!#L6hj4pPCt8_eCF( z8Tqr)M(pS%g4P>$j=#^Zb0`i8J7mf<(S~Smay2tt&+y``2lKm9^6Q>I2SS0Uy%Zk7qpmoM1=zVJxRP Tx#+8xw%=wHUj){NrRM()d4nQp diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_mobile/arrow_right.png b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_mobile/arrow_right.png deleted file mode 100644 index 901b5b7fb79f2623717d8673f12eb26e2ca35e55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1975 zcmaJ?YfuyC8V=>A2-Q}Of(2cpsYr9(++a;WAkqYr2qZ|FgG$IQ5J|EjSs>g7VPqIA zMFjK+Eyt=EDbOlsEK)!UUXZ4c0#+;tXg!wE3XT*wV7=hkSh4+aIJ>j^UFLb7_kF+j znfZz%r5}2@t#cy~2p%G#AQ~Ti@XvRd3;u73a%bR!H?~88$8i0SQQwM$accZtEZd z8kkRvWlQK1Ll}~*5oQ??S(a3;&Pq`S!o=VpfM0S<%8V6wPeE*Svn3_6Vt(ik9x!G)M0M5hC< zA0i&j2q!|(g7DX|@D-n!j9~_dM$5>^pk^?ss4O#diBXLuv4H@!Y4{J>~tm4U{f((NTJ0wt3F57p`3 zpiNjb@@KyPQ`jWWG$6ES#Du09)p+9)H`zlOpfDq%!ce0eMYW5k7@3S>s3{pW0AVsV z5UbI{Xol$(S|Wi&dK0G7s}YfaPsI6DjRuA|V4#2%4zk(d0Rarg4tgj9WQ5=^$YF%i z!`b1BTmh<1(;<3nkqiIHSlGZ)}g~ajzS3Q$M{~9!VfLQAC0ex%rkQcBfdT@eFDo zRr*sXK&6}V&?%>fr@y=6deHCE6Jg2W2!pzWajo!L;RmbNR)~pzPhwl)(c|KTGm>lK zL`Ja{7Jk+X69)u}-uV8hmw%prCMud# z@w;!?_9u>Y%swYgxZbS&vg1k4x3S9YE*_y}v%}g8V=*x?@~Ef~XJ==)d8F&`p;M7i z&6&Eot<}emf36_UZ3zCh`)Yp9^5*kFiREEUO-%)U71m{Y;^I90OFUdomTz9}QFMg` zf}!{B-OHQlYZvqCiyA9J{>kESZcRLVn5`}VR|EO~O=&^tA8R}f))#>K+R?U0wv<8xQDV53+1VJvJ*Luyw487&3 z=!B!^lMa679?WI2hJH&3+B-hIM$zdsrwrYP%Iaa75@Z>mpHy4F0s_Og;(`001D zNBukYgH?X(K2f^5xGYqD^Tj#l$+J_I0B`?CyIWJA)A?C*1!r>}Zy_y&{DTtENlL9v zZdQ<6rPYyZ51#VxYkov(K$vNF@`Nwl5AVNK;238FtFUTYVyYWO1P(_GkCV3)*&?_b zUWBi$e(%8#b?N?P?h|(0)T*XaACNy<8C!4llRbWi_Tt(5!u#u=3(zYAX}U`eRPRai zfeRLrU-2iF%x+G(*QWE8RVk#A^@ucfpmeGV6~=xawad3=?xsv!d`NnJw>;)=KH$DH zP;f9xrc!Ut8GM0;VZl$OzMEr<3(wps;%aAm^RGrB(!u`8$;ov1$T7=}+4_$8)(h7M zPg5$Ty|T^kS~WdBejk^~mCC0juC+fv;uT%|J-mx2^y`C#sie@~%yB=i@rnC5PsC=k zgMW5nGMUv)mTBx<<3|rhZdcscJ7J0R``rb;kmHe!-xqp=D!Z+JYQw{RvV~ o=Y}NKLi3ZOY1>y!oF+IDTK_c`b0jYRw*4vDX4gA6@@CTake(qgK=SYet7SF@B8MPv5xjV zwW~L-rYNd55tmbB_PC>_n*4k62R@Ri0Y@{q3*~S@u^|=KP!@uOq4dENRJ5TZ&tWS? zRRKMn!I|VjxEI^yAa)vu_dx> zp-^B7%?z^pSY8kWSHtJ?5`@7Ugk>CQg5+U|7qt zrn6KgQZTltSS-(QZc1ffGWma~VJxE^oPvM+{!`dV4_S~+K?mh+m0VnIvm441B^xRj z*=d9hm#f&(k1%rjkp-kKKj_s>4HcY4bTTO>Ob08b3KMdOCVWQMH8JRyq-Z22`D4K# z&quk46pjf&UW)hvd^8dcl({le^9D3=nXCQb$`!e8BN!HmEJIsA3bmMx46vB6s8{w9 zuBf-f)hc_5ROGV64C`L&U)NkdBE91-mz$PsmfIehq}OfI)GxlzKOzs}aY7EKi*K@X zrBYkf{h%N`xH>i(pO~C{&D=(*r;(e}Ok&fGl(OEaZp^Mbt2bQwvVDM?pZj)Y^z=kF zoL@+_3*BdCrb;8vGP6w|I$t%xi#^%7H7yO*8LKJR`*H`o(6PJoTz6HRKYwTcr-QuU zc~-x1Wc*kuackW|-6iGFlk4@-s`zJi)%)vjBddZIJeA|v* zq&i8L@KOh(f}l%S5lGRG6?E`Y5FwG8mr4*tjF6&o`(|~uL)*YN-w)68ywCf7?>E{R zKT%tAw1yyv+Gs>f;Ca6@_EzKnseJDuo{peU3U$E@Do7?E+7*}vWK@%~AOR$0XmA>| z5=0fLCQ~RCJ1NLeb4w1!ZEFT*6GUs9ZAfxIKx7(ZRXsqhKAxgTRS8hto){A|f*_|x zhE32l98b!_{W7mmZO6%0TfhPuKoV(d1G**H0ji`c;I(s1Q)CH(`UBLasZ^|!3_=r- z9yjBX881V6SvT9<;`8~MNRD9{n&D`cbFn_5nG+a>-1;aS%~Uc%LJV)k!n**KL&y+l zx=<*%3(an5W@(n^c}IieTo~c9hIAy^F5PMxL50$4C_%J||k4NfRS2%11b z&`d%&P_ANU4kBpfpg{(^JY=`3E3jad(6N{h)h#6HGKh)+3iI8nstA0jBkT<|cX+~n zKg)&~p7V#q4v`H9InL{C;mTYQ%6SdwsLWM%xWS5Crx7#*M;3vpo&!qQgc?~&SWqi_ z;VbHGah1wm+ADHtY=(BO^{;C#AK~6{mfKB>H`{FwblmGEZfctS`Wioo@u=9Iv_GW3 z7mICG_x(Ko=-TM{$mOxIw|X|)-F|2K%%ysIW8~-hO0h}2I`?^bxwlVM_kDR#msnm} z>gm(8+IsoL?f3KZPv6bV914x^xss;oyNMge*iWf@jq7V`jd{a(u6ufN-}JeMYsJMk z*9X%FUY(vC_)%P$^*uQ}Vb4x##gUC)(YlKV;li`u#npwW(U-)oY9jJ+cQF&cdCPgZ M(NJ8R=s0`f4|MHo@c;k- diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_mobile/noevents.png b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/imgs_mobile/noevents.png deleted file mode 100644 index 05da890fe1cf4b98f8c955cfedeb53be9cba4462..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1687 zcma)+c~sI_6vuyAxsaliCrivNCoFTxG)4EhJfHhXo8l|ZQjqe%C-O!{(^9W)90K84*Yi?P=kr31XJ%2u;F|Zb{=WM`n zem(LX9l?WcOpr{a1Ep1+9uU$7A%rC{&eAC~kV1_HHffn{hd4~d4^wFgbV@iG1S)hp zT_6hoPU)mjmDCiZM3Df;1zjyDqNR!iP|t&Lp>z^JpslLp8@?x}FwRDXLQ*w z<_!t})`xjw-Ei>*(}QB~fKVfiFGN{!mm||!|2K3~{CM5IJiioJ_GQaPJ#)Tu90B}X z%YJUd_v2;GOrLi`?78ldX~Ey`Jh9QF*3;_fmdb)eMC{yO=_w3Z@mk&91;(C2*;GHZ zJ-1ra(Q+1zMy~^|J;q6Z7PgMoI$y0H^in^$&XU-_RNrYvB9Od(?I%8HZ_gX5EATDF zVJ?2F;q#NE@2qch%r)mAY0 zD=y>WCvjXZxBZ4mwWDc~sJgN;D5tlt&maSPq6k9}gkXw@c)Xtbmb93aB_-M6)v{D7 zySx_H)TbnjNa&L$!D(? zqK*pfYzU1tvw>^mP!pe|(nq_!H4&N5=8e95lS}jRwnm@MAqBm=WffROcyg*d#D%-r zopxH&EESK(KaQIW2lyEt7Nvq~tKBB}%yD=Ioj3=SUO7yjNDhc?5y zaO;RLvnlraAeExjNyH>{{5hGq* zUH$l5e$0qELdz^ZDInl&17qSUnaQj@W3$Px;Y=`r@Dq>h@S&%thPwVqh#fh9yo=+c zyqO)DUt$!Jzk~QnkynziFhhuDkcVIVekdFSL0Xl>>nLt^A&Xu zAGZFAHNPWGq*85($xDhXWWgcxZ%fKYNfzcpJ2>7AmM(0p>L}%8S4bO;{*<~9FXTUW zB?^+KCnxRM1B+-ijg*u3_8KCQn=;y_rlxv&aPqRq*w`E-|8VwVP2@h-L^pTxf=nhG z+=4_tS`Z}2#wUBrv7<8OXrq%6Tm~9sJ{#Q#N?`sG5mt!a{${VHrlx0MSy%0$Bgt+^ zUQV>wIGiiY3WbBmSuFG_U2t)+?%nOQG(2%K*9QzMc?AQ(CTVBP&=I!sHB-cB}uChvDYVsKepkD zdskOidKnF0in{=U{|pP$FC7}1>VGu2)2V>waCACi}TZ1 z^QUMZb3+r8Tp@I`;CQ|H)O9YM)3LgpO@|KwEG z%F0SzU7devTjtAi_Wfe<#mSzXi*^EuX#XDV?RuI^~J@-r=lnt~IW6I)=tan0ou6VSU#UK$c12R?jIbTT3$B3LXA zS{%KQu?cm+*k`#~ZSt_%8eFTV_Ag!@ra$Hapi6;W-`XXmLjNz|dE^AP%01-rzn2#b AcK`qY diff --git a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/readme.txt b/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/readme.txt deleted file mode 100644 index 67cb13ff468..00000000000 --- a/addons/web_calendar/static/lib/dhtmlxScheduler/codebase/readme.txt +++ /dev/null @@ -1,16 +0,0 @@ -There are a lot of files here, but you need only part of them - -Desctop scheduler, default skin - dhtmlxscheduler.js - dhtmlxscheduler.css - imgs\ - -Desctop scheduler, glossy skin - dhtmlxscheduler.js - dhtmlxscheduler_glossy.css - imgs_glossy\ - -Mobile scheduler - dhtmlxscheduler_mobile.js - dhtmlxscheduler_mobile.css - imgs_mobile\ \ No newline at end of file From ccfa1eb25299bb954e16a13b6e065f0b17d1fd34 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sat, 18 Aug 2012 22:16:32 +0200 Subject: [PATCH 120/166] [IMP] abstractfield options replace getter by attribute bzr revid: al@openerp.com-20120818201632-5aoioz8mhu62im3p --- addons/web/static/src/js/view_form.js | 36 +++++++++++---------------- addons/web/static/src/xml/base.xml | 6 ++--- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index e2a254773ae..f39740863f3 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -1908,6 +1908,7 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w this.field = this.field_manager.get_field(this.name); this.widget = this.node.attrs.widget; this.string = this.node.attrs.string || this.field.string || this.name; + this.options = JSON.parse(this.node.attrs.options || '{}'); this.set({'value': false}); this.set({required: this.modifiers['required'] === true}); @@ -1993,16 +1994,6 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w focus: function() { return false; }, - /** - * Utility method to get the widget options defined in the field xml description. - */ - get_definition_options: function() { - if (!this.definition_options) { - var str = this.node.attrs.options || '{}'; - this.definition_options = JSON.parse(str); - } - return this.definition_options; - }, set_input_id: function(id) { this.id_for_label = id; }, @@ -2667,7 +2658,7 @@ instance.web.form.CompletionFieldMixin = { var slow_create = function () { self._search_create_popup("form", undefined, {"default_name": name}); }; - if (self.get_definition_options().quick_create === undefined || self.get_definition_options().quick_create) { + if (self.options.quick_create === undefined || self.options.quick_create) { new instance.web.DataSet(this, this.field.relation, self.build_context()) .name_create(name, function(data) { self.add_id(data[0]); @@ -2924,7 +2915,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc var lines = _.escape(str).split("\n"); var link = ""; var follow = ""; - if (! this.get_definition_options().highlight_first_line) { + if (! this.options.highlight_first_line) { link = lines.join("
    "); } else { link = lines[0]; @@ -2935,7 +2926,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc var $link = this.$element.find('.oe_form_uri') .unbind('click') .html(link); - if (! this.get_definition_options().no_open) + if (! this.options.no_open) $link.click(function () { self.do_action({ type: 'ir.actions.act_window', @@ -2954,7 +2945,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc var self = this; if (value_ instanceof Array) { this.display_value = {}; - if (! this.get_definition_options().always_reload) { + if (! this.options.always_reload) { this.display_value["" + value_[0]] = value_[1]; } value_ = value_[0]; @@ -4683,10 +4674,6 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ if (this.$element.parent().is('header')) { this.$element.after('
    '); } - // preview in start only for selection fields, because of the dynamic behavior of many2one fields. - if (this.field.type in ['selection']) { - this.render_list(); - } }, set_value: function(value_) { var self = this; @@ -4705,7 +4692,6 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ return self.render_list(); }); }, - /** Get the status list and render them * to_show: [[identifier, value_to_display]] where * - identifier = key for a selection, id for a many2one @@ -4715,7 +4701,8 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ render_list: function() { var self = this; // get selection values, filter them and render them - var selection_done = this.get_selection().pipe(self.proxy('filter_selection')).pipe(self.proxy('render_elements')); + var selection_done = + this.get_selection().pipe(self.proxy('filter_selection')).pipe(self.proxy('render_elements')); }, /** Get the selection list to be displayed in the statusbar widget. @@ -4790,12 +4777,15 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ if (this.clickable) { this.$element.addClass("oe_form_steps_clickable"); $('.oe_form_steps_arrow').remove(); + var elemts = this.$element.find('li'); _.each(elemts, function(element){ $item = $(element); if ($item.attr("data-id") != self.selected_value) { $item.click(function(event){ var data_id = parseInt($(this).attr("data-id")) + + return this.view.recursive_save().pipe(exec_action); self.view.dataset.call('stage_set', [[self.view.datarecord.id],data_id]).then(function() { return self.view.reload(); }); @@ -4807,11 +4797,13 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ } var colors = JSON.parse((this.node.attrs || {}).statusbar_colors || "{}"); var color = colors[this.selected_value]; - if (color) { + if (color) { var elem = this.$element.find("li.oe_form_steps_active span"); - elem.css("color", color); + elem.css("color", color); } }, + on_click_stage: function () { + }, }); /** diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 8e6f7ffc3cb..f2e022c74e0 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -1017,12 +1017,12 @@ - - + + - /
    Date: Sat, 18 Aug 2012 22:18:59 +0200 Subject: [PATCH 121/166] [IMP] abstractfield options replace getter by attribute bzr revid: al@openerp.com-20120818201859-xjpvcmipg59f0p3e --- addons/mail/static/src/js/mail.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 5eb9e5e3c72..00242ecee38 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -838,13 +838,13 @@ openerp.mail = function(session) { init: function() { this._super.apply(this, arguments); - this.params = this.get_definition_options(); + this.params = this.options; this.params.thread_level = this.params.thread_level || 0; this.thread = null; this.ds = new session.web.DataSet(this, this.view.model); this.ds_users = new session.web.DataSet(this, 'res.users'); }, - + start: function() { // NB: all the widget should be modified to check the actual_mode property on view, not use // any other method to know if the view is in create mode anymore From e9d39f98a0c9ed6846d07df6323e1be19c9141db Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 19 Aug 2012 00:10:35 +0200 Subject: [PATCH 122/166] [FIX] form field statusbar clean version bzr revid: al@openerp.com-20120818221035-zue58v11r1qmbcbo --- addons/web/static/src/js/view_form.js | 146 +++++++++----------------- addons/web/static/src/xml/base.xml | 30 +----- 2 files changed, 57 insertions(+), 119 deletions(-) diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index f39740863f3..0ef17ac685a 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -4666,11 +4666,17 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ template: "FieldStatus", - clickable: false, start: function() { this._super(); this.selected_value = null; - this.clickable = !!this.node.attrs.clickable; + // backward compatibility + this.options.clickable = this.options.clickable || (this.node.attrs || {}).clickable || false; + this.options.visible = this.options.visible || (this.node.attrs || {}).statusbar_visible || false; + this.loaded = new $.Deferred(); + if (this.options.clickable) { + this.$element.on('click','li',this.on_click_stage); + } + // TODO move the following into css :after if (this.$element.parent().is('header')) { this.$element.after('
    '); } @@ -4688,121 +4694,73 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ } // trick to be sure all values are loaded in the form, therefore // enabling the evaluation of dynamic domains + self.selection = []; $.async_when().then(function() { - return self.render_list(); + self.get_selection(); }); + return this.loaded; }, - /** Get the status list and render them - * to_show: [[identifier, value_to_display]] where - * - identifier = key for a selection, id for a many2one - * - display_val = label that will be displayed - * - ex: [[0, "New"]] (many2one) or [["new", "In Progress"]] (selection) - */ - render_list: function() { - var self = this; - // get selection values, filter them and render them - var selection_done = - this.get_selection().pipe(self.proxy('filter_selection')).pipe(self.proxy('render_elements')); - }, - - /** Get the selection list to be displayed in the statusbar widget. + /** Get the selection and render it + * selection: [[identifier, value_to_display], ...] * For selection fields: this is directly given by this.field.selection - * For many2one fields : - * - perform a search on the relation of the many2one field (given by - * field.relation ) - * - get the field domain for the search - * - self.build_domain() gives the domain given by the view or by - * the field - * - if the optional statusbar_fold attribute is set to true, make - * an AND with build_domain to hide all 'fold=true' columns - * - make an OR with current value, to be sure it is displayed, - * with the correct order, even if it is folded + * For many2one fields: perform a search on the relation of the many2one field */ get_selection: function() { var self = this; if (this.field.type == "many2one") { - this.selection = []; - // get fold information from widget - var fold = ((this.node.attrs || {}).statusbar_fold || true); - // build final domain: if fold option required, add the - if (fold == true) { - var domain = new instance.web.CompoundDomain(['|'], ['&'], self.build_domain(), [['fold', '=', false]], [['id', '=', self.selected_value]]); - } else { - var domain = new instance.web.CompoundDomain(['|'], self.build_domain(), [['id', '=', self.selected_value]]); + var domain = new instance.web.CompoundDomain(['|'], self.build_domain(), [['id', '=', self.selected_value]]); + var ds = new instance.web.DataSetSearch(this, this.field.relation, self.build_context(), domain); + ds.read_slice(['name'], {}).done( function (records) { + for(var i = 0; i < records.length; i++) { + self.selection.push([records[i].id, records[i].name]); + } + self.render_elements(); + self.loaded.resolve(); + }); + } else { + this.loaded.resolve(); + // For field type selection filter values according to + // statusbar_visible attribute of the field. For example: + // statusbar_visible="draft,open". + var selection = this.field.selection; + console.log(selection); + for(var i=0; i< selection.length; i++) { + var key = selection[i][0]; + if(key == this.selected_value || !this.options.visible || this.options.visible.indexOf(key) != -1) { + this.selection.push(selection[i]); + } } - // get a DataSetSearch on the current field relation (ex: crm.lead.stage_id -> crm.case.stage) - var model_ext = new instance.web.DataSetSearch(this, this.field.relation, self.build_context(), domain); - // fetch selection - var read_defer = model_ext.read_slice(['name'], {}).pipe( function (records) { - _(records).each(function (record) { - self.selection.push([record.id, record.name]); - }); - }); - } else { - this.selection = this.field.selection; - var read_defer = new $.Deferred().resolve(); - } - return read_defer; - }, - - /** Filters this.selection, according to values coming from the statusbar_visible - * attribute of the field. For example: statusbar_visible="draft,open" - * Currently, the key of (key, label) pairs has to be used in the - * selection of visible items. This feature is not meant to be used - * with many2one fields. - */ - filter_selection: function() { - var self = this; - var shown = _.map(((this.node.attrs || {}).statusbar_visible || "").split(","), - function(x) { return _.str.trim(x); }); - shown = _.select(shown, function(x) { return x.length > 0; }); - - if (shown.length == 0) { - this.to_show = this.selection; - } else { - this.to_show = _.select(this.selection, function(x) { - return _.indexOf(shown, x[0]) !== -1 || x[0] === self.selected_value; - }); + console.log(this.selection); + this.render_elements(); } }, - /** Renders the widget. This function also checks for statusbar_colors='{"pending": "blue"}' * attribute in the widget. This allows to set a given color to a given * state (given by the key of (key, label)). */ render_elements: function () { var self = this; - var content = instance.web.qweb.render("FieldStatus.content", {widget: this, _:_}); + var content = instance.web.qweb.render("FieldStatus.content", {widget: this}); this.$element.html(content); - if (this.clickable) { - this.$element.addClass("oe_form_steps_clickable"); - $('.oe_form_steps_arrow').remove(); - - var elemts = this.$element.find('li'); - _.each(elemts, function(element){ - $item = $(element); - if ($item.attr("data-id") != self.selected_value) { - $item.click(function(event){ - var data_id = parseInt($(this).attr("data-id")) - - return this.view.recursive_save().pipe(exec_action); - self.view.dataset.call('stage_set', [[self.view.datarecord.id],data_id]).then(function() { - return self.view.reload(); - }); - }); - } - }); - } else { - this.$element.addClass("oe_form_steps"); - } var colors = JSON.parse((this.node.attrs || {}).statusbar_colors || "{}"); var color = colors[this.selected_value]; if (color) { - var elem = this.$element.find("li.oe_form_steps_active span"); - elem.css("color", color); + this.$("oe_active").css("color", color); } }, - on_click_stage: function () { + on_click_stage: function (ev) { + var self = this; + var $li = $(ev.currentTarget); + var val = parseInt($li.data("id")); + if (val != self.selected_value) { + this.view.recursive_save().then(function() { + var change = {}; + change[self.name] = val; + self.view.dataset.write(self.view.datarecord.id, change).then(function() { + self.view.reload(); + }); + }); + } }, }); diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index f2e022c74e0..c91c156a2c4 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -1083,33 +1083,13 @@ -
      +
        - - - - -
      • -
        - - - - - -
        -
      • -
        -
        - - - - - -
      • - - - + +
      • + +
      • From d43eb323f12df787e4b317094aceae8f4e04c330 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 19 Aug 2012 00:51:51 +0200 Subject: [PATCH 123/166] [FIX] form field statusbar clickable class bzr revid: al@openerp.com-20120818225151-y2nymkwwn10uvo7u --- addons/web/static/src/js/view_form.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 0ef17ac685a..4f3f1c62f13 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -4666,12 +4666,15 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ template: "FieldStatus", - start: function() { - this._super(); - this.selected_value = null; - // backward compatibility + init: function(field_manager, node) { + this._super(field_manager, node); this.options.clickable = this.options.clickable || (this.node.attrs || {}).clickable || false; this.options.visible = this.options.visible || (this.node.attrs || {}).statusbar_visible || false; + this.selected_value = null; + }, + start: function() { + this._super(); + // backward compatibility this.loaded = new $.Deferred(); if (this.options.clickable) { this.$element.on('click','li',this.on_click_stage); From 7e7c583d24bbb1605f5a48e2e7b470d638e5b65f Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 19 Aug 2012 03:06:46 +0200 Subject: [PATCH 124/166] [FIX] web_api example, renamed from web_rpc bzr revid: al@openerp.com-20120819010646-ujct3dwe9j0pmjq6 --- addons/{web_rpc => web_api}/__init__.py | 0 addons/web_api/__openerp__.py | 13 +++++ addons/{web_rpc => web_api}/i18n/es_CR.po | 0 addons/{web_rpc => web_api}/i18n/web_rpc.pot | 0 addons/web_api/static/src/example.html | 55 ++++++++++++++++++++ addons/web_rpc/__openerp__.py | 24 --------- addons/web_rpc/static/src/example.html | 51 ------------------ 7 files changed, 68 insertions(+), 75 deletions(-) rename addons/{web_rpc => web_api}/__init__.py (100%) create mode 100644 addons/web_api/__openerp__.py rename addons/{web_rpc => web_api}/i18n/es_CR.po (100%) rename addons/{web_rpc => web_api}/i18n/web_rpc.pot (100%) create mode 100644 addons/web_api/static/src/example.html delete mode 100644 addons/web_rpc/__openerp__.py delete mode 100644 addons/web_rpc/static/src/example.html diff --git a/addons/web_rpc/__init__.py b/addons/web_api/__init__.py similarity index 100% rename from addons/web_rpc/__init__.py rename to addons/web_api/__init__.py diff --git a/addons/web_api/__openerp__.py b/addons/web_api/__openerp__.py new file mode 100644 index 00000000000..efc99afb7a9 --- /dev/null +++ b/addons/web_api/__openerp__.py @@ -0,0 +1,13 @@ +{ + "name" : "OpenERP Web API", + "category" : "Hidden", + "description":"""Openerp Web API.""", + "version" : "2.0", + "depends" : ['web'], + "installable" : True, + 'auto_install': False, + 'js' : [ + ], + 'css' : [ + ], +} diff --git a/addons/web_rpc/i18n/es_CR.po b/addons/web_api/i18n/es_CR.po similarity index 100% rename from addons/web_rpc/i18n/es_CR.po rename to addons/web_api/i18n/es_CR.po diff --git a/addons/web_rpc/i18n/web_rpc.pot b/addons/web_api/i18n/web_rpc.pot similarity index 100% rename from addons/web_rpc/i18n/web_rpc.pot rename to addons/web_api/i18n/web_rpc.pot diff --git a/addons/web_api/static/src/example.html b/addons/web_api/static/src/example.html new file mode 100644 index 00000000000..9c920e31fa2 --- /dev/null +++ b/addons/web_api/static/src/example.html @@ -0,0 +1,55 @@ + + + + + + OpenERP web_api example + + + + +

        OpenERP web_api examples

        +

        Example 1: Load the list of defined ir.model

        +
        +

        Code:

        +
        +<script type="text/javascript" src="/web/webclient/js"></script>
        +<script type="text/javascript">
        +
        +    var instance = openerp.init(["web"]); // get a new instance
        +    instance.session.session_bind(); // bind it to the right hostname
        +    instance.session.session_authenticate("trunk", "admin", "admin", false).then(function() {
        +        var ds = new instance.web.DataSetSearch(null, "ir.model");
        +        ds.read_slice(['name','model'], {}).then(function(models){
        +            _.each(models,function(m,i){
        +                $("#ex1res").append("<li>" + m.model + " (" + m.name + ") </li>")
        +            });
        +        });
        +    });
        +
        </script> +
        +

        Div for output:

        +
        +   +
        +
        +

        Help me to complete this examples on launchpad

        + + + diff --git a/addons/web_rpc/__openerp__.py b/addons/web_rpc/__openerp__.py deleted file mode 100644 index 44946d27cb5..00000000000 --- a/addons/web_rpc/__openerp__.py +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name" : "OpenERP Web Web", - "category" : "Hidden", - "description":"""Openerp Web Web.""", - "version" : "2.0", - "depends" : [], - "installable" : False, - 'auto_install': False, - 'js' : [ - "../web/static/lib/datejs/date-en-US.js", - "../web/static/lib/jquery/jquery-1.6.4.js", - "../web/static/lib/json/json2.js", - "../web/static/lib/qweb/qweb2.js", - "../web/static/lib/underscore/underscore.js", - "../web/static/lib/underscore/underscore.string.js", - "../web/static/src/js/boot.js", - "../web/static/src/js/core.js", - "../web/static/src/js/formats.js", - "../web/static/src/js/chrome.js", - "../web/static/src/js/data.js", - ], - 'css' : [ - ], -} diff --git a/addons/web_rpc/static/src/example.html b/addons/web_rpc/static/src/example.html deleted file mode 100644 index fb5d12f73e3..00000000000 --- a/addons/web_rpc/static/src/example.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - OpenERP web_rpc example - - - - - -

        OpenERP web_rpc examples

        -

        Example 1: Display a list of defined ir.model

        -

        Code:

        -
        -<script type="text/javascript" src="/base/webclient/js?mods=web_rpc"></script> 
        -<script type="text/javascript">
        -
        -    var c = openerp.init(); // get a new webclient
        -    c._modules_loaded = true; // Hack to prevent loading of additional modules
        -
        -    var s = new c.base.Session(); // setup a Session
        -    s.login("web-trunk", "admin", "admin", function() {
        -
        -            var ds = new c.base.DataSetSearch(s, "ir.model"); // DataSetSearch used to search, read
        -            ds.read_slice(['name','model'], {}, function(users){
        -                for(var i in users) { 
        -                    $("#ex1res").append("<li>" + users[i].model + " (" + users[i].name + ") </li>")
        -                }
        -            });
        -        }
        -    );
        -
        </script> -
        -

        Div for output:

        -
        -   -
        -

        Help me to complete this example page on launchpad

        - - - From 185c82348c9bd57f595e2981883dde8e8a38d111 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 20 Aug 2012 09:13:27 +0200 Subject: [PATCH 125/166] [IMP] point_of_sale: todos bzr revid: fva@openerp.com-20120820071327-wfbd7g5wbh5zrnaa --- addons/point_of_sale/static/src/js/TODO.txt | 23 +++++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/addons/point_of_sale/static/src/js/TODO.txt b/addons/point_of_sale/static/src/js/TODO.txt index 74148ce4e80..8da3c2ab262 100644 --- a/addons/point_of_sale/static/src/js/TODO.txt +++ b/addons/point_of_sale/static/src/js/TODO.txt @@ -5,17 +5,12 @@ v Scrolling dans la sélection produit et dans la liste de courses v Réductions v Redesign liste de courses -- Redesign du receipt -x générer les données de printing -x popups d'erreur certainement buggés v bugs scans produits par prix par poids v si pas photo photo par defaut -- WebSQL +v WebSQL v Redesign header, bouton retour aux backend en mode caissière v bouton exit en mode caissière doit retourner au backend. -- user preferences : désactiver la balance etc. -- posting orders -- login alternatif +v posting orders v bug ajout ligne payment à zero + curseur dedans + suppression + design plus grand v si case print via proxy cochée, alors on skip l'ecran receipt v bouton exit self checkout @@ -23,8 +18,18 @@ v demarrage en mode self-checkout si self-checkout v produits poid code barre non reconnus v activer popup client aux écrans self-checkout v discount pas plus grand que 100 +v numpad dans l'écran payment pour pouvoir entrer le montant +v différence de total. Methode d'arrondis + +- login alternatif +- user preferences : désactiver la balance etc. - numpad state parfois sans state - numpad state en mode pesée ?? le cacher ? -v numpad dans l'écran payment pour pouvoir entrer le montant -- différence de total. Methode d'arrondis +- Redesign du receipt +- retirer le receipt screen +- le numpad en mode paymenet marche pas +- l'écran de payement est hyper laid +- l'écran de pesée est hyper laid +x générer les données de printing +x popups d'erreur certainement buggés From b29c4a6113a002528aeed1fa59e823172bfce841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 20 Aug 2012 12:24:01 +0200 Subject: [PATCH 126/166] [IMP] point_of_sale: improved receipt screen bzr revid: fva@openerp.com-20120820102401-t5zkmh2hoamba719 --- addons/point_of_sale/static/src/css/pos.css | 11 ++++++++++- addons/point_of_sale/static/src/js/pos_screens.js | 2 ++ addons/point_of_sale/static/src/xml/pos.xml | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/addons/point_of_sale/static/src/css/pos.css b/addons/point_of_sale/static/src/css/pos.css index 54bf8eb65db..973c8b10d87 100644 --- a/addons/point_of_sale/static/src/css/pos.css +++ b/addons/point_of_sale/static/src/css/pos.css @@ -728,8 +728,17 @@ width: 300px; background-color: white; margin: 20px; - padding: 10px; + padding: 15px; + padding-bottom:30px; display: inline-block; + font-family: "Inconsolata"; + -webkit-box-shadow: 0px 5px 16px rgba(0,0,0, 0.3); + -moz-box-shadow: 0px 5px 16px rgba(0,0,0, 0.3); + box-shadow: 0px 5px 16px rgba(0,0,0, 0.3); +} +.point-of-sale .pos-sale-ticket .emph{ + font-size: 20px; + margin:5px; } .point-of-sale .pos-sale-ticket table { width: 100%; diff --git a/addons/point_of_sale/static/src/js/pos_screens.js b/addons/point_of_sale/static/src/js/pos_screens.js index a007453bd9e..d71199331f3 100644 --- a/addons/point_of_sale/static/src/js/pos_screens.js +++ b/addons/point_of_sale/static/src/js/pos_screens.js @@ -676,6 +676,8 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa icon: '/point_of_sale/static/src/img/icons/png48/go-next.png', click: function() { self.finishOrder(); }, }); + + window.print(); }, print: function() { window.print(); diff --git a/addons/point_of_sale/static/src/xml/pos.xml b/addons/point_of_sale/static/src/xml/pos.xml index 89256dd1286..81f929d50e2 100644 --- a/addons/point_of_sale/static/src/xml/pos.xml +++ b/addons/point_of_sale/static/src/xml/pos.xml @@ -508,7 +508,7 @@ Tax: - Total: + Total: From 0b639b586b12d38065c092ba96f2db3e5cc1c6ec Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Mon, 20 Aug 2012 13:02:07 +0200 Subject: [PATCH 127/166] [FIX] account_voucher: supplier payment in multi-currency. Accounting entries generation fixed bzr revid: qdp-launchpad@openerp.com-20120820110207-w2sow7o2rmpbqykl --- addons/account_voucher/account_voucher.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/account_voucher/account_voucher.py b/addons/account_voucher/account_voucher.py index 1287c7b3c18..223705af85e 100644 --- a/addons/account_voucher/account_voucher.py +++ b/addons/account_voucher/account_voucher.py @@ -1106,7 +1106,8 @@ class account_voucher(osv.osv): # otherwise we use the rates of the system (giving the voucher date in the context) amount_currency = currency_obj.compute(cr, uid, company_currency, line.move_line_id.currency_id.id, move_line['debit']-move_line['credit'], context=ctx) if line.amount == line.amount_unreconciled and line.move_line_id.currency_id.id == voucher_currency: - foreign_currency_diff = line.move_line_id.amount_residual_currency + amount_currency + sign = voucher_brw.type in ('payment', 'purchase') and -1 or 1 + foreign_currency_diff = sign * line.move_line_id.amount_residual_currency + amount_currency move_line['amount_currency'] = amount_currency voucher_line = move_line_obj.create(cr, uid, move_line) From 1450ebd8476d81a5b3a4181a4526c280d85294a7 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Mon, 20 Aug 2012 13:50:42 +0200 Subject: [PATCH 128/166] [FIX] base: restored translations for label 'VAT' changed into 'TIN' in revision 4344 bzr revid: qdp-launchpad@openerp.com-20120820115042-13epfxw99vzvumer --- openerp/addons/base/i18n/ab.po | 4 ++-- openerp/addons/base/i18n/af.po | 4 ++-- openerp/addons/base/i18n/am.po | 4 ++-- openerp/addons/base/i18n/ar.po | 4 ++-- openerp/addons/base/i18n/base.pot | 4 ++-- openerp/addons/base/i18n/bg.po | 4 ++-- openerp/addons/base/i18n/bs.po | 4 ++-- openerp/addons/base/i18n/ca.po | 4 ++-- openerp/addons/base/i18n/cs.po | 4 ++-- openerp/addons/base/i18n/da.po | 4 ++-- openerp/addons/base/i18n/de.po | 4 ++-- openerp/addons/base/i18n/el.po | 4 ++-- openerp/addons/base/i18n/en_GB.po | 4 ++-- openerp/addons/base/i18n/es.po | 4 ++-- openerp/addons/base/i18n/es_AR.po | 4 ++-- openerp/addons/base/i18n/es_CL.po | 4 ++-- openerp/addons/base/i18n/es_CR.po | 6 +++--- openerp/addons/base/i18n/es_EC.po | 4 ++-- openerp/addons/base/i18n/et.po | 4 ++-- openerp/addons/base/i18n/eu.po | 4 ++-- openerp/addons/base/i18n/fa.po | 4 ++-- openerp/addons/base/i18n/fa_AF.po | 4 ++-- openerp/addons/base/i18n/fi.po | 4 ++-- openerp/addons/base/i18n/fr.po | 4 ++-- openerp/addons/base/i18n/gl.po | 4 ++-- openerp/addons/base/i18n/gu.po | 4 ++-- openerp/addons/base/i18n/he.po | 4 ++-- openerp/addons/base/i18n/hr.po | 4 ++-- openerp/addons/base/i18n/hu.po | 4 ++-- openerp/addons/base/i18n/hy.po | 4 ++-- openerp/addons/base/i18n/id.po | 4 ++-- openerp/addons/base/i18n/is.po | 4 ++-- openerp/addons/base/i18n/it.po | 4 ++-- openerp/addons/base/i18n/ja.po | 4 ++-- openerp/addons/base/i18n/ka.po | 4 ++-- openerp/addons/base/i18n/kk.po | 4 ++-- openerp/addons/base/i18n/ko.po | 4 ++-- openerp/addons/base/i18n/lt.po | 4 ++-- openerp/addons/base/i18n/lt_LT.po | 2 +- openerp/addons/base/i18n/lv.po | 4 ++-- openerp/addons/base/i18n/mk.po | 4 ++-- openerp/addons/base/i18n/mn.po | 4 ++-- openerp/addons/base/i18n/nb.po | 4 ++-- openerp/addons/base/i18n/nl.po | 4 ++-- openerp/addons/base/i18n/nl_BE.po | 4 ++-- openerp/addons/base/i18n/nl_NL.po | 2 +- openerp/addons/base/i18n/pl.po | 4 ++-- openerp/addons/base/i18n/pt.po | 4 ++-- openerp/addons/base/i18n/pt_BR.po | 6 +++--- openerp/addons/base/i18n/ro.po | 4 ++-- openerp/addons/base/i18n/ru.po | 4 ++-- openerp/addons/base/i18n/sk.po | 4 ++-- openerp/addons/base/i18n/sl.po | 4 ++-- openerp/addons/base/i18n/sq.po | 4 ++-- openerp/addons/base/i18n/sr.po | 4 ++-- openerp/addons/base/i18n/sr@latin.po | 4 ++-- openerp/addons/base/i18n/sv.po | 4 ++-- openerp/addons/base/i18n/th.po | 4 ++-- openerp/addons/base/i18n/tlh.po | 4 ++-- openerp/addons/base/i18n/tr.po | 4 ++-- openerp/addons/base/i18n/uk.po | 4 ++-- openerp/addons/base/i18n/uk_UA.po | 2 +- openerp/addons/base/i18n/ur.po | 4 ++-- openerp/addons/base/i18n/vi.po | 4 ++-- openerp/addons/base/i18n/zh_CN.po | 4 ++-- openerp/addons/base/i18n/zh_HK.po | 4 ++-- openerp/addons/base/i18n/zh_TW.po | 4 ++-- 67 files changed, 133 insertions(+), 133 deletions(-) diff --git a/openerp/addons/base/i18n/ab.po b/openerp/addons/base/i18n/ab.po index e7888a8a720..5f5c450592a 100644 --- a/openerp/addons/base/i18n/ab.po +++ b/openerp/addons/base/i18n/ab.po @@ -3634,7 +3634,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9845,7 +9845,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/af.po b/openerp/addons/base/i18n/af.po index 4f2dd5fb776..597bf9ab330 100644 --- a/openerp/addons/base/i18n/af.po +++ b/openerp/addons/base/i18n/af.po @@ -3653,7 +3653,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9864,7 +9864,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/am.po b/openerp/addons/base/i18n/am.po index 1ccb028cac0..4627d531674 100644 --- a/openerp/addons/base/i18n/am.po +++ b/openerp/addons/base/i18n/am.po @@ -3634,7 +3634,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9845,7 +9845,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/ar.po b/openerp/addons/base/i18n/ar.po index 1a2642d9e1f..8b2dbeb7c2e 100644 --- a/openerp/addons/base/i18n/ar.po +++ b/openerp/addons/base/i18n/ar.po @@ -3721,7 +3721,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "ضريبة القيمة المضافة" #. module: base @@ -9975,7 +9975,7 @@ msgstr "الأسابيع" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/base.pot b/openerp/addons/base/i18n/base.pot index b4d28052ba8..884dac7d821 100644 --- a/openerp/addons/base/i18n/base.pot +++ b/openerp/addons/base/i18n/base.pot @@ -3383,7 +3383,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9064,7 +9064,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/bg.po b/openerp/addons/base/i18n/bg.po index ab9556f269c..2bb32e19c40 100644 --- a/openerp/addons/base/i18n/bg.po +++ b/openerp/addons/base/i18n/bg.po @@ -3705,7 +3705,7 @@ msgstr "Проверка на EAN" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "ДДС" #. module: base @@ -9961,7 +9961,7 @@ msgstr "Седмици" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/bs.po b/openerp/addons/base/i18n/bs.po index 778679bb04d..97e44c61523 100644 --- a/openerp/addons/base/i18n/bs.po +++ b/openerp/addons/base/i18n/bs.po @@ -3642,7 +3642,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9853,7 +9853,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/ca.po b/openerp/addons/base/i18n/ca.po index fa5f95b14da..340ddb494f5 100644 --- a/openerp/addons/base/i18n/ca.po +++ b/openerp/addons/base/i18n/ca.po @@ -3757,7 +3757,7 @@ msgstr "Verificació EAN" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "CIF/NIF" #. module: base @@ -10082,7 +10082,7 @@ msgstr "Setmanes" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/cs.po b/openerp/addons/base/i18n/cs.po index 4819a321dda..79939664d5c 100644 --- a/openerp/addons/base/i18n/cs.po +++ b/openerp/addons/base/i18n/cs.po @@ -3787,7 +3787,7 @@ msgstr "Kontrola Ean" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "DIČ" #. module: base @@ -10090,7 +10090,7 @@ msgstr "Týdnů" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "DPH: " #. module: base diff --git a/openerp/addons/base/i18n/da.po b/openerp/addons/base/i18n/da.po index 2710b5c4629..854dd6e6293 100644 --- a/openerp/addons/base/i18n/da.po +++ b/openerp/addons/base/i18n/da.po @@ -3634,7 +3634,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "Moms" #. module: base @@ -9845,7 +9845,7 @@ msgstr "Uger" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/de.po b/openerp/addons/base/i18n/de.po index 9db01f56eb0..017a2d48b6b 100644 --- a/openerp/addons/base/i18n/de.po +++ b/openerp/addons/base/i18n/de.po @@ -4266,7 +4266,7 @@ msgstr "EAN Prüfung" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "USt-IdNr. / UID" #. module: base @@ -10907,7 +10907,7 @@ msgstr "Wochen" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "UID: " #. module: base diff --git a/openerp/addons/base/i18n/el.po b/openerp/addons/base/i18n/el.po index 7a9c9db6811..f8975ee4dad 100644 --- a/openerp/addons/base/i18n/el.po +++ b/openerp/addons/base/i18n/el.po @@ -3728,7 +3728,7 @@ msgstr "Έλεγχος ean" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "ΦΠΑ" #. module: base @@ -9997,7 +9997,7 @@ msgstr "Εβδομάδες" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/en_GB.po b/openerp/addons/base/i18n/en_GB.po index d7bc4f79bbf..259f120278d 100644 --- a/openerp/addons/base/i18n/en_GB.po +++ b/openerp/addons/base/i18n/en_GB.po @@ -4123,7 +4123,7 @@ msgstr "Ean check" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "VAT" #. module: base @@ -10427,7 +10427,7 @@ msgstr "Weeks" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/es.po b/openerp/addons/base/i18n/es.po index ef47237de9f..2c3cc3414af 100644 --- a/openerp/addons/base/i18n/es.po +++ b/openerp/addons/base/i18n/es.po @@ -3977,7 +3977,7 @@ msgstr "Verificación EAN" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "CIF/NIF" #. module: base @@ -10306,7 +10306,7 @@ msgstr "Semanas" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/es_AR.po b/openerp/addons/base/i18n/es_AR.po index fdc9c0340dd..b36b88a179a 100644 --- a/openerp/addons/base/i18n/es_AR.po +++ b/openerp/addons/base/i18n/es_AR.po @@ -3668,7 +3668,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "CUIT" #. module: base @@ -9900,7 +9900,7 @@ msgstr "Semanas" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/es_CL.po b/openerp/addons/base/i18n/es_CL.po index 9c200b406c5..d484cdd7f94 100644 --- a/openerp/addons/base/i18n/es_CL.po +++ b/openerp/addons/base/i18n/es_CL.po @@ -3795,7 +3795,7 @@ msgstr "Verificación EAN" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "RUT" #. module: base @@ -10124,7 +10124,7 @@ msgstr "Semanas" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/es_CR.po b/openerp/addons/base/i18n/es_CR.po index a5124cc2596..3eaeea2e0b0 100644 --- a/openerp/addons/base/i18n/es_CR.po +++ b/openerp/addons/base/i18n/es_CR.po @@ -1975,7 +1975,7 @@ msgstr "" "``BE0477472701``\n" "será validado con la normativa belga.\n" "\n" -"Hay dos niveles diferentes de validación del número de VAT: \n" +"Hay dos niveles diferentes de validación del número de TIN: \n" "\n" "*Por defecto, un simple fuera de linea de verificación se realiza mediante " "la validación conocida\n" @@ -4391,7 +4391,7 @@ msgstr "Verificación EAN" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "CIF/NIF" #. module: base @@ -12421,7 +12421,7 @@ msgstr "Semanas" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "IVA: " #. module: base diff --git a/openerp/addons/base/i18n/es_EC.po b/openerp/addons/base/i18n/es_EC.po index 9a8ee789f45..233214a8b3f 100644 --- a/openerp/addons/base/i18n/es_EC.po +++ b/openerp/addons/base/i18n/es_EC.po @@ -3971,7 +3971,7 @@ msgstr "Ean de verificación" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "CIF/NIF" #. module: base @@ -10350,7 +10350,7 @@ msgstr "Semanas" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "IVA " #. module: base diff --git a/openerp/addons/base/i18n/et.po b/openerp/addons/base/i18n/et.po index 92461a33610..164dbde7e9b 100644 --- a/openerp/addons/base/i18n/et.po +++ b/openerp/addons/base/i18n/et.po @@ -3665,7 +3665,7 @@ msgstr "Ean kontroll" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "Käibemaks" #. module: base @@ -9890,7 +9890,7 @@ msgstr "Nädalad" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/eu.po b/openerp/addons/base/i18n/eu.po index cac59f27002..16081128c30 100644 --- a/openerp/addons/base/i18n/eu.po +++ b/openerp/addons/base/i18n/eu.po @@ -3634,7 +3634,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9845,7 +9845,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/fa.po b/openerp/addons/base/i18n/fa.po index 74885636856..fc9e0b5910a 100644 --- a/openerp/addons/base/i18n/fa.po +++ b/openerp/addons/base/i18n/fa.po @@ -3667,7 +3667,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "مالیات بر ارزش افزوده" #. module: base @@ -9894,7 +9894,7 @@ msgstr "هفته‌ها" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/fa_AF.po b/openerp/addons/base/i18n/fa_AF.po index 99a346be694..86d22d26b10 100644 --- a/openerp/addons/base/i18n/fa_AF.po +++ b/openerp/addons/base/i18n/fa_AF.po @@ -3634,7 +3634,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9845,7 +9845,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/fi.po b/openerp/addons/base/i18n/fi.po index c2de09b902d..6cf9e4d0979 100644 --- a/openerp/addons/base/i18n/fi.po +++ b/openerp/addons/base/i18n/fi.po @@ -3751,7 +3751,7 @@ msgstr "EAN tarkistus" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "ALV" #. module: base @@ -10091,7 +10091,7 @@ msgstr "Viikot" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "ALV: " #. module: base diff --git a/openerp/addons/base/i18n/fr.po b/openerp/addons/base/i18n/fr.po index 3f755a59d14..4849ed703f7 100644 --- a/openerp/addons/base/i18n/fr.po +++ b/openerp/addons/base/i18n/fr.po @@ -4371,7 +4371,7 @@ msgstr "Vérification EAN" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "TVA" #. module: base @@ -11707,7 +11707,7 @@ msgstr "Semaines" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "TVA: " #. module: base diff --git a/openerp/addons/base/i18n/gl.po b/openerp/addons/base/i18n/gl.po index 91ac9510620..bce4cfa8d20 100644 --- a/openerp/addons/base/i18n/gl.po +++ b/openerp/addons/base/i18n/gl.po @@ -3757,7 +3757,7 @@ msgstr "comprobar EAN" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "IVE" #. module: base @@ -10069,7 +10069,7 @@ msgstr "Semanas" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/gu.po b/openerp/addons/base/i18n/gu.po index 91597862bf5..91a923c6c5b 100644 --- a/openerp/addons/base/i18n/gu.po +++ b/openerp/addons/base/i18n/gu.po @@ -3692,7 +3692,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9903,7 +9903,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/he.po b/openerp/addons/base/i18n/he.po index 967b11c89a0..51dc0b68178 100644 --- a/openerp/addons/base/i18n/he.po +++ b/openerp/addons/base/i18n/he.po @@ -3654,7 +3654,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "מע\"מ" #. module: base @@ -9877,7 +9877,7 @@ msgstr "שבועות" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/hr.po b/openerp/addons/base/i18n/hr.po index e50c21bd73c..da97294a878 100644 --- a/openerp/addons/base/i18n/hr.po +++ b/openerp/addons/base/i18n/hr.po @@ -3784,7 +3784,7 @@ msgstr "Provjera Ean" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "PDV" #. module: base @@ -10050,7 +10050,7 @@ msgstr "Tjedni" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "PDV " #. module: base diff --git a/openerp/addons/base/i18n/hu.po b/openerp/addons/base/i18n/hu.po index d98ee515473..94525dfaff2 100644 --- a/openerp/addons/base/i18n/hu.po +++ b/openerp/addons/base/i18n/hu.po @@ -3744,7 +3744,7 @@ msgstr "EAN ellenőrzés" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "Közösségi/nemzetközi adószám" #. module: base @@ -10063,7 +10063,7 @@ msgstr "Hetek" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/hy.po b/openerp/addons/base/i18n/hy.po index 2c5ed383c32..8d3072b598f 100644 --- a/openerp/addons/base/i18n/hy.po +++ b/openerp/addons/base/i18n/hy.po @@ -3634,7 +3634,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9845,7 +9845,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/id.po b/openerp/addons/base/i18n/id.po index de2d31683ee..f71c65e63e8 100644 --- a/openerp/addons/base/i18n/id.po +++ b/openerp/addons/base/i18n/id.po @@ -3638,7 +3638,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9849,7 +9849,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/is.po b/openerp/addons/base/i18n/is.po index bab1f557502..d84c81ee518 100644 --- a/openerp/addons/base/i18n/is.po +++ b/openerp/addons/base/i18n/is.po @@ -3668,7 +3668,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "VSK" #. module: base @@ -9880,7 +9880,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/it.po b/openerp/addons/base/i18n/it.po index e1f369680a2..8b33bb7a1e7 100644 --- a/openerp/addons/base/i18n/it.po +++ b/openerp/addons/base/i18n/it.po @@ -3807,7 +3807,7 @@ msgstr "Verifica EAN" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "Partita IVA" #. module: base @@ -10132,7 +10132,7 @@ msgstr "Settimane" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/ja.po b/openerp/addons/base/i18n/ja.po index 35382f62daa..a3fe9843e4e 100644 --- a/openerp/addons/base/i18n/ja.po +++ b/openerp/addons/base/i18n/ja.po @@ -4131,7 +4131,7 @@ msgstr "EANチェック" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "VAT(Value Added Tax)" #. module: base @@ -11571,7 +11571,7 @@ msgstr "週" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/ka.po b/openerp/addons/base/i18n/ka.po index a7a4c233c3c..9edba583232 100644 --- a/openerp/addons/base/i18n/ka.po +++ b/openerp/addons/base/i18n/ka.po @@ -4267,7 +4267,7 @@ msgstr "EAN-ის შემოწმება" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "დღგ" #. module: base @@ -11688,7 +11688,7 @@ msgstr "კვირეები" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "დღგ: " #. module: base diff --git a/openerp/addons/base/i18n/kk.po b/openerp/addons/base/i18n/kk.po index 09a985213b8..bffba2e7eb6 100644 --- a/openerp/addons/base/i18n/kk.po +++ b/openerp/addons/base/i18n/kk.po @@ -3634,7 +3634,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9845,7 +9845,7 @@ msgstr "апта" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/ko.po b/openerp/addons/base/i18n/ko.po index b66cb25933e..95a91eb27cb 100644 --- a/openerp/addons/base/i18n/ko.po +++ b/openerp/addons/base/i18n/ko.po @@ -3681,7 +3681,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "부가세" #. module: base @@ -9906,7 +9906,7 @@ msgstr "주" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/lt.po b/openerp/addons/base/i18n/lt.po index eb59a102506..fd31f08f45d 100644 --- a/openerp/addons/base/i18n/lt.po +++ b/openerp/addons/base/i18n/lt.po @@ -3646,7 +3646,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "PVM" #. module: base @@ -9877,7 +9877,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/lt_LT.po b/openerp/addons/base/i18n/lt_LT.po index 13846af119e..be05dc522d1 100644 --- a/openerp/addons/base/i18n/lt_LT.po +++ b/openerp/addons/base/i18n/lt_LT.po @@ -4533,7 +4533,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/lv.po b/openerp/addons/base/i18n/lv.po index 0a83e177d06..ddffb721e47 100644 --- a/openerp/addons/base/i18n/lv.po +++ b/openerp/addons/base/i18n/lv.po @@ -3678,7 +3678,7 @@ msgstr "EAN pārbaude" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "PVN" #. module: base @@ -9919,7 +9919,7 @@ msgstr "Nedēļas" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/mk.po b/openerp/addons/base/i18n/mk.po index 3414ae7063c..c83e232dc72 100644 --- a/openerp/addons/base/i18n/mk.po +++ b/openerp/addons/base/i18n/mk.po @@ -3645,7 +3645,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9856,7 +9856,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/mn.po b/openerp/addons/base/i18n/mn.po index c80aa9afb14..3dfce8aabd9 100644 --- a/openerp/addons/base/i18n/mn.po +++ b/openerp/addons/base/i18n/mn.po @@ -4166,7 +4166,7 @@ msgstr "Зур.код чеклэх" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "НӨАТ" #. module: base @@ -11762,7 +11762,7 @@ msgstr "7 хоног" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "НӨАТ: " #. module: base diff --git a/openerp/addons/base/i18n/nb.po b/openerp/addons/base/i18n/nb.po index 1542c677529..fc9ab46d995 100644 --- a/openerp/addons/base/i18n/nb.po +++ b/openerp/addons/base/i18n/nb.po @@ -3686,7 +3686,7 @@ msgstr "Ean sjekk" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "MVA" #. module: base @@ -9926,7 +9926,7 @@ msgstr "Uker" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/nl.po b/openerp/addons/base/i18n/nl.po index 45560f7e363..ba5b8b3cd07 100644 --- a/openerp/addons/base/i18n/nl.po +++ b/openerp/addons/base/i18n/nl.po @@ -3863,7 +3863,7 @@ msgstr "Ean controle" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "BTW" #. module: base @@ -10292,7 +10292,7 @@ msgstr "Weken" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "BTW: " #. module: base diff --git a/openerp/addons/base/i18n/nl_BE.po b/openerp/addons/base/i18n/nl_BE.po index cf2cc84f2fd..d7f03b217f4 100644 --- a/openerp/addons/base/i18n/nl_BE.po +++ b/openerp/addons/base/i18n/nl_BE.po @@ -3649,7 +3649,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9860,7 +9860,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/nl_NL.po b/openerp/addons/base/i18n/nl_NL.po index bfb371faf05..267b058bfef 100644 --- a/openerp/addons/base/i18n/nl_NL.po +++ b/openerp/addons/base/i18n/nl_NL.po @@ -4711,7 +4711,7 @@ msgstr "html" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "BTW" #. module: base diff --git a/openerp/addons/base/i18n/pl.po b/openerp/addons/base/i18n/pl.po index b0e489d3b03..a58a4b07acc 100644 --- a/openerp/addons/base/i18n/pl.po +++ b/openerp/addons/base/i18n/pl.po @@ -3730,7 +3730,7 @@ msgstr "Sprawdzanie EAN" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "NIP" #. module: base @@ -10025,7 +10025,7 @@ msgstr "Tygodni" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "NIP: " #. module: base diff --git a/openerp/addons/base/i18n/pt.po b/openerp/addons/base/i18n/pt.po index b60b9b98d76..ef27a385d12 100644 --- a/openerp/addons/base/i18n/pt.po +++ b/openerp/addons/base/i18n/pt.po @@ -3959,7 +3959,7 @@ msgstr "Verificar EAN" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "IVA" #. module: base @@ -10340,7 +10340,7 @@ msgstr "Semanas" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "IVA: " #. module: base diff --git a/openerp/addons/base/i18n/pt_BR.po b/openerp/addons/base/i18n/pt_BR.po index 97cbcce0eb6..01db31d7ebe 100644 --- a/openerp/addons/base/i18n/pt_BR.po +++ b/openerp/addons/base/i18n/pt_BR.po @@ -4164,7 +4164,7 @@ msgstr "Verificar EAN" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "Imposto" #. module: base @@ -10849,8 +10849,8 @@ msgstr "Semanas" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " -msgstr "VAT: " +msgid "TIN: " +msgstr "TIN: " #. module: base #: model:res.country,name:base.af diff --git a/openerp/addons/base/i18n/ro.po b/openerp/addons/base/i18n/ro.po index f079b8bd10a..aa7d5de6a86 100644 --- a/openerp/addons/base/i18n/ro.po +++ b/openerp/addons/base/i18n/ro.po @@ -4363,7 +4363,7 @@ msgstr "Verificati codul EAN" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "TVA" #. module: base @@ -12351,7 +12351,7 @@ msgstr "Saptamani" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "TVA: " #. module: base diff --git a/openerp/addons/base/i18n/ru.po b/openerp/addons/base/i18n/ru.po index c3ba2f63acd..d879ea9fefc 100644 --- a/openerp/addons/base/i18n/ru.po +++ b/openerp/addons/base/i18n/ru.po @@ -3811,7 +3811,7 @@ msgstr "Проверка кода Ean" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "ИНН" #. module: base @@ -10154,7 +10154,7 @@ msgstr "Недели" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/sk.po b/openerp/addons/base/i18n/sk.po index 94ee24e819d..d1da2e46b6d 100644 --- a/openerp/addons/base/i18n/sk.po +++ b/openerp/addons/base/i18n/sk.po @@ -3712,7 +3712,7 @@ msgstr "Ean kontrola" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "DPH" #. module: base @@ -9991,7 +9991,7 @@ msgstr "Týždne" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/sl.po b/openerp/addons/base/i18n/sl.po index f9eeb1456c2..8a800c2d8ea 100644 --- a/openerp/addons/base/i18n/sl.po +++ b/openerp/addons/base/i18n/sl.po @@ -3741,7 +3741,7 @@ msgstr "Preveri ean" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "DDV" #. module: base @@ -10047,7 +10047,7 @@ msgstr "Tedni" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/sq.po b/openerp/addons/base/i18n/sq.po index b1f0478ed8a..735a237fbed 100644 --- a/openerp/addons/base/i18n/sq.po +++ b/openerp/addons/base/i18n/sq.po @@ -3633,7 +3633,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9844,7 +9844,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/sr.po b/openerp/addons/base/i18n/sr.po index e8c74060cc3..a1d444c03b0 100644 --- a/openerp/addons/base/i18n/sr.po +++ b/openerp/addons/base/i18n/sr.po @@ -3710,7 +3710,7 @@ msgstr "EAN provera" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "PDV" #. module: base @@ -9975,7 +9975,7 @@ msgstr "Nedelje" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/sr@latin.po b/openerp/addons/base/i18n/sr@latin.po index 5c187aeec8b..2632130f415 100644 --- a/openerp/addons/base/i18n/sr@latin.po +++ b/openerp/addons/base/i18n/sr@latin.po @@ -4309,7 +4309,7 @@ msgstr "EAN provera" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "PDV" #. module: base @@ -11242,7 +11242,7 @@ msgstr "Nedelje" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "PDV: " #. module: base diff --git a/openerp/addons/base/i18n/sv.po b/openerp/addons/base/i18n/sv.po index 2e9ff2e0539..ba4f6334f63 100644 --- a/openerp/addons/base/i18n/sv.po +++ b/openerp/addons/base/i18n/sv.po @@ -3952,7 +3952,7 @@ msgstr "EAN kontroll" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "Moms" #. module: base @@ -10426,7 +10426,7 @@ msgstr "Veckor" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "Moms: " #. module: base diff --git a/openerp/addons/base/i18n/th.po b/openerp/addons/base/i18n/th.po index df20f7a2adc..2e53f3a9734 100644 --- a/openerp/addons/base/i18n/th.po +++ b/openerp/addons/base/i18n/th.po @@ -3634,7 +3634,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9845,7 +9845,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/tlh.po b/openerp/addons/base/i18n/tlh.po index 805035cf850..58b349f8bbd 100644 --- a/openerp/addons/base/i18n/tlh.po +++ b/openerp/addons/base/i18n/tlh.po @@ -3633,7 +3633,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9844,7 +9844,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/tr.po b/openerp/addons/base/i18n/tr.po index b6670894b5c..9d54b0aed7e 100644 --- a/openerp/addons/base/i18n/tr.po +++ b/openerp/addons/base/i18n/tr.po @@ -3773,7 +3773,7 @@ msgstr "EAN kontrolü" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "KDV" #. module: base @@ -10097,7 +10097,7 @@ msgstr "Hafta" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "VNO: " #. module: base diff --git a/openerp/addons/base/i18n/uk.po b/openerp/addons/base/i18n/uk.po index 79d5db6ef59..8310cd833ce 100644 --- a/openerp/addons/base/i18n/uk.po +++ b/openerp/addons/base/i18n/uk.po @@ -3669,7 +3669,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "ПДВ" #. module: base @@ -9893,7 +9893,7 @@ msgstr "Тижні" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/uk_UA.po b/openerp/addons/base/i18n/uk_UA.po index 8263fde5c5e..8a8f1d3613f 100644 --- a/openerp/addons/base/i18n/uk_UA.po +++ b/openerp/addons/base/i18n/uk_UA.po @@ -4551,7 +4551,7 @@ msgstr "html" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "ПДВ" #. module: base diff --git a/openerp/addons/base/i18n/ur.po b/openerp/addons/base/i18n/ur.po index 4239bc2adf3..c48f39785d1 100644 --- a/openerp/addons/base/i18n/ur.po +++ b/openerp/addons/base/i18n/ur.po @@ -3634,7 +3634,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9845,7 +9845,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/vi.po b/openerp/addons/base/i18n/vi.po index 0255aaf2f57..51c018a9672 100644 --- a/openerp/addons/base/i18n/vi.po +++ b/openerp/addons/base/i18n/vi.po @@ -3661,7 +3661,7 @@ msgstr "Kiểm tra EAN" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "Thuế GTGT" #. module: base @@ -9878,7 +9878,7 @@ msgstr "Tuần" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/zh_CN.po b/openerp/addons/base/i18n/zh_CN.po index ee0f43d8372..3cf1f1365fb 100644 --- a/openerp/addons/base/i18n/zh_CN.po +++ b/openerp/addons/base/i18n/zh_CN.po @@ -4032,7 +4032,7 @@ msgstr "条码检查" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "增值税" #. module: base @@ -10638,7 +10638,7 @@ msgstr "周" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "增值税: " #. module: base diff --git a/openerp/addons/base/i18n/zh_HK.po b/openerp/addons/base/i18n/zh_HK.po index 96313cd3e58..216a05705bb 100644 --- a/openerp/addons/base/i18n/zh_HK.po +++ b/openerp/addons/base/i18n/zh_HK.po @@ -3634,7 +3634,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "" #. module: base @@ -9845,7 +9845,7 @@ msgstr "" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/zh_TW.po b/openerp/addons/base/i18n/zh_TW.po index a4804f29e56..aad1201ccfa 100644 --- a/openerp/addons/base/i18n/zh_TW.po +++ b/openerp/addons/base/i18n/zh_TW.po @@ -3639,7 +3639,7 @@ msgstr "Ean 檢查" #. module: base #: field:res.partner,vat:0 -msgid "VAT" +msgid "TIN" msgstr "增值稅" #. module: base @@ -9858,7 +9858,7 @@ msgstr "週" #. module: base #: code:addons/base/res/res_company.py:157 #, python-format -msgid "VAT: " +msgid "TIN: " msgstr "" #. module: base From 2501b06ca0dec18c98f2b9d73b64a7b0aebe13e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 20 Aug 2012 14:22:43 +0200 Subject: [PATCH 129/166] [IMP] removed left and top bar from printing bzr revid: fva@openerp.com-20120820122243-z9wtrkpb2ub79enf --- addons/web/static/src/css/base.css | 41 ++++++++++++++++------------- addons/web/static/src/css/base.sass | 4 +++ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index 87a83b4c70e..2276bb2445e 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -64,6 +64,11 @@ } } +@media print { + .oe_topbar, .oe_leftbar, .oe_loading { + display: none !important; + } +} .openerp.openerp_webclient_container { height: 100%; position: relative; @@ -234,7 +239,7 @@ font-size: 13px; } .openerp .ui-widget-content a { - color: #8a89ba; + color: #7c7bad; } .openerp .ui-menu .ui-menu-item { margin: 0 8px 0 0; @@ -336,7 +341,7 @@ border-radius: 0 0 2px 2px; } .openerp.ui-dialog .oe_about a { - color: #8a89ba; + color: #7c7bad; } .openerp.ui-dialog .oe_about a:hover { text-decoration: underline; @@ -547,7 +552,7 @@ -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; - color: #8a89ba; + color: #7c7bad; font-weight: bold; } .openerp .oe_button.oe_link span:hover { @@ -578,7 +583,7 @@ color: #4c4c4c; } .openerp .oe_tag_dark { - background: #8786b7; + background: #7c7bad; color: #eeeeee; } .openerp .oe_tags.oe_inline { @@ -1007,7 +1012,7 @@ .openerp .oe_topbar { width: 100%; height: 31px; - border-top: solid 1px #d3d3d3; + border-top: solid 1px lightgrey; background-color: #646060; background-image: -webkit-gradient(linear, left top, left bottom, from(#646060), to(#262626)); background-image: -webkit-linear-gradient(top, #646060, #262626); @@ -1180,7 +1185,7 @@ .openerp .oe_secondary_menu_section { font-weight: bold; margin-left: 8px; - color: #8a89ba; + color: #7c7bad; } .openerp .oe_secondary_submenu { padding: 2px 0 8px 0; @@ -1202,11 +1207,11 @@ top: 1px; right: 1px; font-size: 10px; - background: #8a89ba; + background: #7c7bad; color: white; padding: 2px 4px; margin: 1px 6px 0 0; - border: 1px solid lightGray; + border: 1px solid lightgrey; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); -moz-border-radius: 4px; -webkit-border-radius: 4px; @@ -1222,9 +1227,9 @@ padding: 1px 4px; } .openerp .oe_secondary_submenu .oe_active { - background: #8a89ba; - border-top: 1px solid lightGray; - border-bottom: 1px solid lightGray; + background: #7c7bad; + border-top: 1px solid lightgrey; + border-bottom: 1px solid lightgrey; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.2); -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.2); @@ -1235,7 +1240,7 @@ } .openerp .oe_secondary_submenu .oe_active .oe_menu_label { background: #eeeeee; - color: #8a89ba; + color: #7c7bad; text-shadow: 0 1px 1px white; -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); @@ -1243,7 +1248,7 @@ } .openerp .oe_secondary_submenu .oe_active .oe_menu_counter { background: #eeeeee; - color: #8a89ba; + color: #7c7bad; } .openerp .oe_secondary_submenu .oe_menu_toggler:before { width: 0; @@ -1273,7 +1278,7 @@ width: 100%; } .openerp .oe_application a { - color: #8a89ba; + color: #7c7bad; } .openerp .oe_application a:hover { text-decoration: underline; @@ -1314,7 +1319,7 @@ float: left; } .openerp .oe_view_manager table.oe_view_manager_header h2 a { - color: #8a89ba; + color: #7c7bad; } .openerp .oe_view_manager table.oe_view_manager_header .oe_button_group { display: inline-block; @@ -1673,7 +1678,7 @@ } .openerp .oe_searchview .oe_searchview_drawer h3 { margin: 8px 4px 4px 12px; - color: #8786b7; + color: #7c7bad; font-size: 13px; } .openerp .oe_searchview .oe_searchview_drawer h4, .openerp .oe_searchview .oe_searchview_drawer h4 * { @@ -2074,7 +2079,7 @@ background-image: linear-gradient(to bottom, #e8e8e8, #cacaca); } .openerp ul.oe_form_steps_clickable li .label { - color: #8a89ba; + color: #7c7bad; } .openerp ul.oe_form_steps_clickable li.oe_active:hover { background-color: #4c85c2; @@ -2174,7 +2179,7 @@ } .openerp .oe_form .oe_form_label_help[for] span, .openerp .oe_form .oe_form_label[for] span { font-size: 80%; - color: darkGreen; + color: darkgreen; vertical-align: top; position: relative; top: -4px; diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index 6472f7aaacd..653adad7813 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -142,6 +142,10 @@ $sheet-max-width: 860px opacity: 1 // }}} +@media print + .oe_topbar, .oe_leftbar, .oe_loading + display: none !important + .openerp.openerp_webclient_container height: 100% position: relative From c447533f7d999c191aa0e9e04713fb2f614804bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 20 Aug 2012 14:40:07 +0200 Subject: [PATCH 130/166] [FIX] point_of_sale: fix css for receipt printing bzr revid: fva@openerp.com-20120820124007-fg36abyblxpboiyi --- addons/point_of_sale/static/src/css/pos.css | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/point_of_sale/static/src/css/pos.css b/addons/point_of_sale/static/src/css/pos.css index 973c8b10d87..ff361ab2e2d 100644 --- a/addons/point_of_sale/static/src/css/pos.css +++ b/addons/point_of_sale/static/src/css/pos.css @@ -749,18 +749,18 @@ } @media print { - #oe_header, #oe_menu, .point-of-sale #topheader, .point-of-sale #leftpane { - display: none; + .point-of-sale #topheader, .point-of-sale #leftpane { + display: none !important; } .point-of-sale #content { - top: 0px; + top: 0px !important; } .point-of-sale #rightpane { - left: 0px; + left: 0px !important; background-color: white; } #receipt-screen header { - display: none; + display: none !important; } #receipt-screen { text-align: left; From 8d052c96bc0ea24751d3709beee18437a969ea18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 20 Aug 2012 15:59:57 +0200 Subject: [PATCH 131/166] [FIX] point_of_sale: added contact_address to print info, empty order styling bzr revid: fva@openerp.com-20120820135957-o5exttxak611e624 --- addons/point_of_sale/static/src/css/pos.css | 4 ++++ addons/point_of_sale/static/src/js/TODO.txt | 7 ++++--- addons/point_of_sale/static/src/js/pos_models.js | 14 ++++++++------ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/addons/point_of_sale/static/src/css/pos.css b/addons/point_of_sale/static/src/css/pos.css index ff361ab2e2d..a9baf041942 100644 --- a/addons/point_of_sale/static/src/css/pos.css +++ b/addons/point_of_sale/static/src/css/pos.css @@ -957,6 +957,10 @@ -moz-transition: background 50ms ease-in-out; transition: background 50ms ease-in-out; } +.point-of-sale .order .orderline.empty:hover{ + background: transparent; + cursor: default; +} .point-of-sale .order .orderline.selected{ background: rgba(140,143,183,0.2); diff --git a/addons/point_of_sale/static/src/js/TODO.txt b/addons/point_of_sale/static/src/js/TODO.txt index f0df899bf34..edadbe188ea 100644 --- a/addons/point_of_sale/static/src/js/TODO.txt +++ b/addons/point_of_sale/static/src/js/TODO.txt @@ -41,11 +41,12 @@ TODO AUG 20 * TRUNK - Connection status tooltip - - Remove receipt screen + v Remove receipt screen - Finish the receipt JSON generation - Modifie le widget de liste course - - supprimer l'écran - - bloquer sur l'impression + v supprimer l'écran + v bloquer sur l'impression + v L'impression est foireuse * CLIENT - create a new branch diff --git a/addons/point_of_sale/static/src/js/pos_models.js b/addons/point_of_sale/static/src/js/pos_models.js index 4cc39bbb498..03e37b81342 100644 --- a/addons/point_of_sale/static/src/js/pos_models.js +++ b/addons/point_of_sale/static/src/js/pos_models.js @@ -28,8 +28,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal this.db = new module.PosLS(); // a database used to store the products and categories this.db.clear('products','categories'); - window.db = this.db; - // pos settings this.use_scale = false; this.use_proxy_printer = false; @@ -76,16 +74,19 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal 'email', 'website', 'company_registry', - //TODO contact_address 'vat', 'name', - 'phone' + 'phone', + 'partner_id', ], [['id','=',user.company_id[0]]]) }).pipe(function(companies){ var company = companies[0]; self.set('company',company); - + fetch('res.partner',['contact_address'],[['id','=',company.partner_id[0]]]) + .then(function(partner){ + company.contact_address = partner[0].contact_address; + }); return fetch('res.currency',['symbol','position'],[['id','=',company.currency_id[0]]]); }).pipe(function (currencies){ self.set('currency',currencies[0]); @@ -700,6 +701,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal change: this.getChange(), name : this.getName(), client: client ? client.name : null , + invoice_id: null, //TODO cashier: cashier ? cashier.name : null, date: { year: date.getFullYear(), @@ -713,7 +715,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal email: company.email, website: company.website, company_registry: company.company_registry, - contact_address: null, //TODO + contact_address: company.contact_address, vat: company.vat, name: company.name, phone: company.phone, From b3cecb21624401f7b1ca2bb6c32501a04e17a5c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Tue, 21 Aug 2012 09:54:34 +0200 Subject: [PATCH 132/166] [IMP] point_of_sale: renamed the js files bzr revid: fva@openerp.com-20120821075434-dy4oqwuok39i4eyj --- addons/point_of_sale/__openerp__.py | 18 +++++++++--------- .../static/src/js/{pos_db.js => db.js} | 0 .../src/js/{pos_devices.js => devices.js} | 0 .../static/src/js/{pos_main.js => main.js} | 0 .../static/src/js/{pos_models.js => models.js} | 0 .../src/js/{pos_screens.js => screens.js} | 0 .../js/{pos_basewidget.js => widget_base.js} | 0 ...s_keyboard_widget.js => widget_keyboard.js} | 0 ...scrollbar_widget.js => widget_scrollbar.js} | 0 .../src/js/{pos_widgets.js => widgets.js} | 0 10 files changed, 9 insertions(+), 9 deletions(-) rename addons/point_of_sale/static/src/js/{pos_db.js => db.js} (100%) rename addons/point_of_sale/static/src/js/{pos_devices.js => devices.js} (100%) rename addons/point_of_sale/static/src/js/{pos_main.js => main.js} (100%) rename addons/point_of_sale/static/src/js/{pos_models.js => models.js} (100%) rename addons/point_of_sale/static/src/js/{pos_screens.js => screens.js} (100%) rename addons/point_of_sale/static/src/js/{pos_basewidget.js => widget_base.js} (100%) rename addons/point_of_sale/static/src/js/{pos_keyboard_widget.js => widget_keyboard.js} (100%) rename addons/point_of_sale/static/src/js/{pos_scrollbar_widget.js => widget_scrollbar.js} (100%) rename addons/point_of_sale/static/src/js/{pos_widgets.js => widgets.js} (100%) diff --git a/addons/point_of_sale/__openerp__.py b/addons/point_of_sale/__openerp__.py index 1b6a6f1390f..e0722f12395 100644 --- a/addons/point_of_sale/__openerp__.py +++ b/addons/point_of_sale/__openerp__.py @@ -84,15 +84,15 @@ Main features: # Web client 'js': [ 'static/lib/mousewheel/jquery.mousewheel-3.0.6.js', - 'static/src/js/pos_db.js', - 'static/src/js/pos_models.js', - 'static/src/js/pos_basewidget.js', - 'static/src/js/pos_keyboard_widget.js', - 'static/src/js/pos_scrollbar_widget.js', - 'static/src/js/pos_widgets.js', - 'static/src/js/pos_devices.js', - 'static/src/js/pos_screens.js', - 'static/src/js/pos_main.js' + 'static/src/js/db.js', + 'static/src/js/models.js', + 'static/src/js/widget_base.js', + 'static/src/js/widget_keyboard.js', + 'static/src/js/widget_scrollbar.js', + 'static/src/js/widgets.js', + 'static/src/js/devices.js', + 'static/src/js/screens.js', + 'static/src/js/main.js' ], 'css': [ 'static/src/css/pos.css', diff --git a/addons/point_of_sale/static/src/js/pos_db.js b/addons/point_of_sale/static/src/js/db.js similarity index 100% rename from addons/point_of_sale/static/src/js/pos_db.js rename to addons/point_of_sale/static/src/js/db.js diff --git a/addons/point_of_sale/static/src/js/pos_devices.js b/addons/point_of_sale/static/src/js/devices.js similarity index 100% rename from addons/point_of_sale/static/src/js/pos_devices.js rename to addons/point_of_sale/static/src/js/devices.js diff --git a/addons/point_of_sale/static/src/js/pos_main.js b/addons/point_of_sale/static/src/js/main.js similarity index 100% rename from addons/point_of_sale/static/src/js/pos_main.js rename to addons/point_of_sale/static/src/js/main.js diff --git a/addons/point_of_sale/static/src/js/pos_models.js b/addons/point_of_sale/static/src/js/models.js similarity index 100% rename from addons/point_of_sale/static/src/js/pos_models.js rename to addons/point_of_sale/static/src/js/models.js diff --git a/addons/point_of_sale/static/src/js/pos_screens.js b/addons/point_of_sale/static/src/js/screens.js similarity index 100% rename from addons/point_of_sale/static/src/js/pos_screens.js rename to addons/point_of_sale/static/src/js/screens.js diff --git a/addons/point_of_sale/static/src/js/pos_basewidget.js b/addons/point_of_sale/static/src/js/widget_base.js similarity index 100% rename from addons/point_of_sale/static/src/js/pos_basewidget.js rename to addons/point_of_sale/static/src/js/widget_base.js diff --git a/addons/point_of_sale/static/src/js/pos_keyboard_widget.js b/addons/point_of_sale/static/src/js/widget_keyboard.js similarity index 100% rename from addons/point_of_sale/static/src/js/pos_keyboard_widget.js rename to addons/point_of_sale/static/src/js/widget_keyboard.js diff --git a/addons/point_of_sale/static/src/js/pos_scrollbar_widget.js b/addons/point_of_sale/static/src/js/widget_scrollbar.js similarity index 100% rename from addons/point_of_sale/static/src/js/pos_scrollbar_widget.js rename to addons/point_of_sale/static/src/js/widget_scrollbar.js diff --git a/addons/point_of_sale/static/src/js/pos_widgets.js b/addons/point_of_sale/static/src/js/widgets.js similarity index 100% rename from addons/point_of_sale/static/src/js/pos_widgets.js rename to addons/point_of_sale/static/src/js/widgets.js From ca93a52e6468a926737bdbe41e6872cf48c43c04 Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Tue, 21 Aug 2012 10:23:43 +0200 Subject: [PATCH 133/166] [FIX] point_of_sale: fix a report bzr revid: stw@openerp.com-20120821082343-mu1p8231c4wa0kjm --- addons/point_of_sale/report/pos_sales_user.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/point_of_sale/report/pos_sales_user.py b/addons/point_of_sale/report/pos_sales_user.py index e49528441b9..6ac2e1892c1 100644 --- a/addons/point_of_sale/report/pos_sales_user.py +++ b/addons/point_of_sale/report/pos_sales_user.py @@ -37,14 +37,14 @@ class pos_sales_user(report_sxw.rml_parse): dt1 = form['date_start'] + ' 00:00:00' dt2 = form['date_end'] + ' 23:59:59' data={} - self.cr.execute("select po.name as pos,po.date_order,ru.name as user,po.state,rc.name " \ - "from pos_order as po,res_users as ru,res_company as rc " \ + self.cr.execute("select po.name as pos,po.date_order,rp.name as user,po.state,rc.name " \ + "from pos_order as po,res_users as ru,res_company as rc, res_partner as rp " \ "where po.date_order >= %s and po.date_order <= %s " \ - "and po.company_id=rc.id and po.user_id=ru.id and po.user_id IN %s " \ + "and po.company_id=rc.id and po.user_id=ru.id and po.user_id IN %s and ru.partner_id = rp.id" \ ,(dt1,dt2,tuple(form['user_id']))) return self.cr.dictfetchall() report_sxw.report_sxw('report.pos.sales.user', 'pos.order', 'addons/point_of_sale/report/pos_sales_user.rml', parser=pos_sales_user,header='internal') -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From c803243a38285e1418954968e6857013e5005fc2 Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Tue, 21 Aug 2012 10:23:56 +0200 Subject: [PATCH 134/166] [FIX] point_of_sale: remove an useless test bzr revid: stw@openerp.com-20120821082356-dr4vdka5u796ho9w --- addons/point_of_sale/test/00_register_open.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/addons/point_of_sale/test/00_register_open.yml b/addons/point_of_sale/test/00_register_open.yml index 7d5aabbcdc3..ce13f3c0f26 100644 --- a/addons/point_of_sale/test/00_register_open.yml +++ b/addons/point_of_sale/test/00_register_open.yml @@ -9,9 +9,3 @@ - !python {model: pos.open.statement}: | self.open_statement(cr, uid, [ref('new_statement_open')], context={}) -- - I check that I have some bank statements open for the admin user -- - !python {model: account.bank.statement}: | - ids = self.search(cr, uid, [('state', 'in', ('open','new')), ('user_id', '=', 1)]) - assert (len(ids)>0), 'No statement open for the admin user!' From 28c036aef0bafe0921a5d135f273fba43d193875 Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Tue, 21 Aug 2012 10:38:28 +0200 Subject: [PATCH 135/166] [FIX] point_of_sale: A manager can create a ir.sequence for the pos.config bzr revid: stw@openerp.com-20120821083828-as5sqvatvvseaj9d --- addons/point_of_sale/security/ir.model.access.csv | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/point_of_sale/security/ir.model.access.csv b/addons/point_of_sale/security/ir.model.access.csv index 06673fc3da8..74b4bbf5753 100644 --- a/addons/point_of_sale/security/ir.model.access.csv +++ b/addons/point_of_sale/security/ir.model.access.csv @@ -60,7 +60,8 @@ access_product_uom_manager,product.uom manager,product.model_product_uom,group_p access_res_partner_manager,res.partner manager,base.model_res_partner,group_pos_manager,1,0,0,0 access_product_category_manager,product.category manager,product.model_product_category,group_pos_manager,1,1,1,1 access_product_pricelist_manager,product.pricelist manager,product.model_product_pricelist,group_pos_manager,1,0,0,0 -access_product_category_pos_manager,pos.category manager,model_pos_category,group_pos_manager,1,1,1,"1""" -access_product_category_pos_user,pos.category user,model_pos_category,group_pos_user,1,0,0,"0""" +access_product_category_pos_manager,pos.category manager,model_pos_category,group_pos_manager,1,1,1,1 +access_product_category_pos_user,pos.category user,model_pos_category,group_pos_user,1,0,0,0 access_pos_session_user,pos.session user,model_pos_session,group_pos_user,1,1,1,0 access_pos_config_user,pos.config user,model_pos_config,group_pos_user,1,1,1,0 +access_ir_sequence_manager,ir.sequence manager,base.model_ir_sequence,group_pos_manager,1,1,1,1 From bc1f8e6d4be5b5905712b0c2359390049e99cc7a Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Tue, 21 Aug 2012 10:48:57 +0200 Subject: [PATCH 136/166] [IMP] point_of_sale: improve the layout of the pos.order bzr revid: stw@openerp.com-20120821084857-4ieoknwcsivdooa1 --- addons/point_of_sale/point_of_sale_view.xml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/addons/point_of_sale/point_of_sale_view.xml b/addons/point_of_sale/point_of_sale_view.xml index e40cbc756b8..c45cedbfbc6 100644 --- a/addons/point_of_sale/point_of_sale_view.xml +++ b/addons/point_of_sale/point_of_sale_view.xml @@ -55,10 +55,14 @@ - + - -
    + From 219aff63af41fdc2f45222ac0d923890bb5d0317 Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Tue, 21 Aug 2012 11:01:45 +0200 Subject: [PATCH 137/166] [FIX] product: avoid a traceback in the product_category#name_get method if the ids is an integer bzr revid: stw@openerp.com-20120821090145-pp2jm318g0kyn9wi --- addons/product/product.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/product/product.py b/addons/product/product.py index 142a4e0d393..58f47f9adc3 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -208,8 +208,10 @@ product_ul() class product_category(osv.osv): def name_get(self, cr, uid, ids, context=None): - if not len(ids): + if isinstance(ids, (list, tuple)) and not len(ids): return [] + if isinstance(ids, (long, int)): + ids = [ids] reads = self.read(cr, uid, ids, ['name','parent_id'], context=context) res = [] for record in reads: From 8d1836bd30f8d06b2da6e36c8b34d250b73847b0 Mon Sep 17 00:00:00 2001 From: niv-openerp Date: Tue, 21 Aug 2012 11:30:00 +0200 Subject: [PATCH 138/166] [IMP] improved loading messages bzr revid: nicolas.vanhoren@openerp.com-20120821093000-4jf6lh7a8o124hsd --- addons/web/static/src/js/coresetup.js | 25 +++++++++++++++++++++++++ addons/web/static/src/xml/base.xml | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/js/coresetup.js b/addons/web/static/src/js/coresetup.js index 229a82a1784..a34a7dadd30 100644 --- a/addons/web/static/src/js/coresetup.js +++ b/addons/web/static/src/js/coresetup.js @@ -528,6 +528,14 @@ if ($.blockUI) { $.blockUI.defaults.css["background-color"] = ''; } +var messages_by_seconds = [ + [0, "Loading..."], + [30, "Still Loading..."], + [60, "Still Loading...
    Please be patient."], + [120, "Hey, guess what?
    It's still loading."], + [300, "You may not believe it,
    but the application is actually loading..."], +]; + instance.web.Throbber = instance.web.Widget.extend({ template: "Throbber", start: function() { @@ -548,6 +556,23 @@ instance.web.Throbber = instance.web.Widget.extend({ left: 'auto' // Left position relative to parent in px }; this.spin = new Spinner(opts).spin(this.$element[0]); + this.start_time = new Date().getTime(); + this.act_message(); + }, + act_message: function() { + var self = this; + setTimeout(function() { + if (self.isDestroyed()) + return; + var seconds = (new Date().getTime() - self.start_time) / 1000; + var mes; + _.each(messages_by_seconds, function(el) { + if (seconds >= el[0]) + mes = el[1]; + }); + self.$(".oe_throbber_message").html(mes); + self.act_message(); + }, 1000); }, destroy: function() { if (this.spin) diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index c91c156a2c4..330a5b3928f 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -1736,7 +1736,7 @@

    -
    Loading...
    +
    From 23de15d82b777af2ae9aa4c05af39c1d67bcbb81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Tue, 21 Aug 2012 12:04:52 +0200 Subject: [PATCH 139/166] [IMP] point_of_sale: simpler way to load models bzr revid: fva@openerp.com-20120821100452-zop43cmqyxq0del0 --- addons/point_of_sale/static/src/js/models.js | 212 ++++++++----------- 1 file changed, 88 insertions(+), 124 deletions(-) diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 03e37b81342..d824d0a043f 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -54,6 +54,8 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal 'taxes': null, 'pos_session': null, 'pos_config': null, + 'units': null, + 'units_by_id': null, 'selectedOrder': undefined, }); @@ -63,10 +65,9 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal // We fetch the backend data on the server asynchronously. this is done only when the pos user interface is launched, // Any change on this data made on the server is thus not reflected on the point of sale until it is relaunched. - var user_def = fetch('res.users',['name','company_id'],[['id','=',this.session.uid]]) + var loaded = fetch('res.users',['name','company_id'],[['id','=',this.session.uid]]) .pipe(function(users){ - var user = users[0]; - self.set('user',user); + self.set('user',users[0]); return fetch('res.company', [ @@ -79,147 +80,110 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal 'phone', 'partner_id', ], - [['id','=',user.company_id[0]]]) + [['id','=',users[0].company_id[0]]]); }).pipe(function(companies){ - var company = companies[0]; - self.set('company',company); - fetch('res.partner',['contact_address'],[['id','=',company.partner_id[0]]]) - .then(function(partner){ - company.contact_address = partner[0].contact_address; - }); - return fetch('res.currency',['symbol','position'],[['id','=',company.currency_id[0]]]); - }).pipe(function (currencies){ + self.set('company',companies[0]); + + return fetch('res.partner',['contact_address'],[['id','=',companies[0].partner_id[0]]]); + }).pipe(function(company_partners){ + self.get('company').contact_address = company_partners[0].contact_address; + + return fetch('res.currency',['symbol','position'],[['id','=',self.get('company').currency_id[0]]]); + }).pipe(function(currencies){ self.set('currency',currencies[0]); - }); - - var uom_def = fetch( //unit of measure - 'product.uom', - null, - null - ).then(function(result){ - self.set({'units': result}); + return fetch('product.uom', null, null); + }).pipe(function(units){ + self.set('units',units); var units_by_id = {}; - for(var i = 0, len = result.length; i < len; i++){ - units_by_id[result[i].id] = result[i]; + for(var i = 0, len = units.length; i < len; i++){ + units_by_id[units[i].id] = units[i]; } - self.set({'units_by_id':units_by_id}); - }); - - var pack_def = fetch( - 'product.packaging', - null, - null - ).then(function(packaging){ - self.set('product.packaging',packaging); - }); - - var users_def = fetch( - 'res.users', - ['name','ean13'], - [['ean13', '!=', false]] - ).then(function(result){ - self.set({'user_list':result}); - }); - - var tax_def = fetch('account.tax', ['amount','price_include','type']) - .then(function(result){ - self.set({'taxes': result}); - }); - - var session_def = fetch( // loading the PoS Session. - 'pos.session', - ['id', 'journal_ids','name','user_id','config_id','start_at','stop_at'], - [['state', '=', 'opened'], ['user_id', '=', this.session.uid]] - ).pipe(function(result) { - - // some data are associated with the pos session, like the pos config and bank statements. - // we must have a valid session before we can read those. + self.set('units_by_id',units_by_id); - var session_data_def = new $.Deferred(); + return fetch('product.packaging', null, null); + }).pipe(function(packagings){ + self.set('product.packaging',packagings); - if( result.length !== 0 ) { - var pos_session = result[0]; + return fetch('res.users', ['name','ean13'], [['ean13', '!=', false]]); + }).pipe(function(users){ + self.set('user_list',users); - self.set({'pos_session': pos_session}); + return fetch('account.tax', ['amount', 'price_include', 'type']); + }).pipe(function(taxes){ + self.set('taxes', taxes); - var pos_config_def = fetch( - 'pos.config', - ['name','journal_ids','shop_id','journal_id', - 'iface_self_checkout', 'iface_led', 'iface_cashdrawer', - 'iface_payment_terminal', 'iface_electronic_scale', 'iface_barscan', 'iface_vkeyboard', - 'iface_print_via_proxy','iface_cashdrawer','state','sequence_id','session_ids'], - [['id','=', pos_session.config_id[0]]] - ).pipe(function(result){ - var pos_config = result[0] - - self.set({'pos_config': pos_config}); - self.use_scale = pos_config.iface_electronic_scale || false; - self.use_proxy_printer = pos_config.iface_print_via_proxy || false; - self.use_virtual_keyboard = pos_config.iface_vkeyboard || false; - self.use_barcode_scanner = pos_config.iface_barscan || false; - self.use_selfcheckout = pos_config.iface_self_checkout || false; - self.use_cashbox = pos_config.iface_cashdrawer || false; + return fetch( + 'pos.session', + ['id', 'journal_ids','name','user_id','config_id','start_at','stop_at'], + [['state', '=', 'opened'], ['user_id', '=', self.session.uid]] + ); + }).pipe(function(sessions){ + self.set('pos_session', sessions[0]); - return fetch('sale.shop',[], [['id','=',pos_config.shop_id[0]]]) - }).pipe(function(shops){ - self.set('shop',shops[0]); - return fetch('pos.category', ['id','name', 'parent_id', 'child_id', 'image']) - }).pipe( function(categories){ - self.db.add_categories(categories); - return fetch( - 'product.product', - ['name', 'list_price','price','pos_categ_id', 'taxes_id', 'ean13', 'to_weight', 'uom_id', 'uos_id', 'uos_coeff', 'mes_type'], - [['pos_categ_id','!=', false]], - {pricelist: self.get('shop').pricelist_id[0]} // context for price - ); - }).pipe( function(products){ - self.db.add_products(products); - }); + return fetch( + 'pos.config', + ['name','journal_ids','shop_id','journal_id', + 'iface_self_checkout', 'iface_led', 'iface_cashdrawer', + 'iface_payment_terminal', 'iface_electronic_scale', 'iface_barscan', 'iface_vkeyboard', + 'iface_print_via_proxy','iface_cashdrawer','state','sequence_id','session_ids'], + [['id','=', self.get('pos_session').config_id[0]]] + ); + }).pipe(function(configs){ + var pos_config = configs[0]; + self.set('pos_config', pos_config); + self.use_scale = !!pos_config.iface_electronic_scale; + self.use_proxy_printer = !!pos_config.iface_print_via_proxy; + self.use_virtual_keyboard = !!pos_config.iface_vkeyboard; + self.use_barcode_scanner = !!pos_config.iface_barscan; + self.use_selfcheckout = !!pos_config.iface_self_checkout; + self.use_cashbox = !!pos_config.iface_cashdrawer; - var bank_def = fetch( - 'account.bank.statement', - ['account_id','currency','journal_id','state','name','user_id','pos_session_id'], - [['state','=','open'],['pos_session_id', '=', pos_session.id]] - ).then(function(result){ - self.set({'bank_statements':result}); - }); + return fetch('sale.shop',[],[['id','=',pos_config.shop_id[0]]]); + }).pipe(function(shops){ + self.set('shop',shops[0]); - var journal_def = fetch( - 'account.journal', - undefined, - [['user_id','=',pos_session.user_id[0]]] - ).then(function(result){ - self.set({'journals':result}); - }); + return fetch('pos.category', ['id','name','parent_id','child_id','image']) + }).pipe(function(categories){ + self.db.add_categories(categories); - // associate the bank statements with their journals. - var bank_process_def = $.when(bank_def, journal_def) - .then(function(){ - var bank_statements = self.get('bank_statements'); - var journals = self.get('journals'); - for(var i = 0, ilen = bank_statements.length; i < ilen; i++){ - for(var j = 0, jlen = journals.length; j < jlen; j++){ - if(bank_statements[i].journal_id[0] === journals[j].id){ - bank_statements[i].journal = journals[j]; - bank_statements[i].self_checkout_payment_method = journals[j].self_checkout_payment_method; - } - } - } - }); + return fetch( + 'product.product', + ['name', 'list_price','price','pos_categ_id', 'taxes_id', 'ean13', 'to_weight', 'uom_id', 'uos_id', 'uos_coeff', 'mes_type'], + [['pos_categ_id','!=', false]], + {pricelist: self.get('shop').pricelist_id[0]} // context for price + ); + }).pipe(function(products){ + self.db.add_products(products); - session_data_def = $.when(pos_config_def,bank_def,journal_def,bank_process_def); + return fetch( + 'account.bank.statement', + ['account_id','currency','journal_id','state','name','user_id','pos_session_id'], + [['state','=','open'],['pos_session_id', '=', self.get('pos_session').id]] + ); + }).pipe(function(bank_statements){ + self.set('bank_statements', bank_statements); - }else{ - session_data_def.reject(); + return fetch('account.journal', undefined, [['user_id','=', self.get('pos_session').user_id[0]]]); + }).pipe(function(journals){ + self.set('journals',journals); + + // associate the bank statements with their journals. + var bank_statements = self.get('bank_statements'); + for(var i = 0, ilen = bank_statements.length; i < ilen; i++){ + for(var j = 0, jlen = journals.length; j < jlen; j++){ + if(bank_statements[i].journal_id[0] === journals[j].id){ + bank_statements[i].journal = journals[j]; + bank_statements[i].self_checkout_payment_method = journals[j].self_checkout_payment_method; + } + } } - return session_data_def; + self.set({'cashRegisters' : new module.CashRegisterCollection(self.get('bank_statements'))}); }); // when all the data has loaded, we compute some stuff, and declare the Pos ready to be used. - $.when(pack_def, user_def, users_def, uom_def, session_def, tax_def, user_def, this.flush()) + $.when(loaded) .then(function(){ - self.set({'cashRegisters' : new module.CashRegisterCollection(self.get('bank_statements'))}); //self.log_loaded_data(); //Uncomment if you want to log the data to the console for easier debugging self.ready.resolve(); },function(){ From 0fdded4d4e8dd77ec8ee1739bbb97f20f0a8b557 Mon Sep 17 00:00:00 2001 From: niv-openerp Date: Tue, 21 Aug 2012 12:44:03 +0200 Subject: [PATCH 140/166] [IMP] minor improvement in linkedin module bzr revid: nicolas.vanhoren@openerp.com-20120821104403-qbmv0tjyngauwfou --- addons/web_linkedin/static/src/js/linkedin.js | 1 + addons/web_linkedin/static/src/xml/linkedin.xml | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/web_linkedin/static/src/js/linkedin.js b/addons/web_linkedin/static/src/js/linkedin.js index c15b995bff9..5bcb03aab33 100644 --- a/addons/web_linkedin/static/src/js/linkedin.js +++ b/addons/web_linkedin/static/src/js/linkedin.js @@ -270,6 +270,7 @@ openerp.web_linkedin = function(instance) { template: "LinkedIn.KeyWizard", init: function(parent, text) { this._super(parent, {title:_t("LinkedIn API Key")}); + this.api_domain = window.location.origin; }, start: function() { this._super(); diff --git a/addons/web_linkedin/static/src/xml/linkedin.xml b/addons/web_linkedin/static/src/xml/linkedin.xml index 0d062e6fd8c..f114fa53803 100644 --- a/addons/web_linkedin/static/src/xml/linkedin.xml +++ b/addons/web_linkedin/static/src/xml/linkedin.xml @@ -41,8 +41,7 @@
  1. Log into LinkedIn.
  2. Add a new application and fill the form:
      -
    • JavaScript API Domain is Your domain name (e.g. https://yourcompany.my.openerp.com)
    • -
    • You can give multiple domain (e.g. yourcompany.my.openerp.com)
    • +
    • JavaScript API Domain:
    • The programming tool is Javascript
  3. From 2e4d656dcbe92ea0b51fc22e214a61e17bdad834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Tue, 21 Aug 2012 12:48:14 +0200 Subject: [PATCH 141/166] [IMP] point_of_sale: removed useless settings, Wubbit Twarks bzr revid: fva@openerp.com-20120821104814-wuxk1qptj7xqr1i9 --- addons/point_of_sale/point_of_sale.py | 2 -- addons/point_of_sale/point_of_sale_view.xml | 2 -- addons/point_of_sale/static/src/js/models.js | 17 +++++------------ addons/point_of_sale/static/src/js/screens.js | 10 +++++----- addons/point_of_sale/static/src/js/widgets.js | 2 +- 5 files changed, 11 insertions(+), 22 deletions(-) diff --git a/addons/point_of_sale/point_of_sale.py b/addons/point_of_sale/point_of_sale.py index 414ff1c3302..f4d32985688 100644 --- a/addons/point_of_sale/point_of_sale.py +++ b/addons/point_of_sale/point_of_sale.py @@ -60,11 +60,9 @@ class pos_config(osv.osv): help="Accounting journal used to post sales entries."), 'iface_self_checkout' : fields.boolean('Self Checkout Mode', help="Check this if this point of sale should open by default in a self checkout mode. If unchecked, OpenERP uses the normal cashier mode by default."), - 'iface_led' : fields.boolean('Help Notification'), 'iface_cashdrawer' : fields.boolean('Cashdrawer Interface'), 'iface_payment_terminal' : fields.boolean('Payment Terminal Interface'), 'iface_electronic_scale' : fields.boolean('Electronic Scale Interface'), - 'iface_barscan' : fields.boolean('BarScan Interface'), 'iface_vkeyboard' : fields.boolean('Virtual KeyBoard Interface'), 'iface_print_via_proxy' : fields.boolean('Print via Proxy'), diff --git a/addons/point_of_sale/point_of_sale_view.xml b/addons/point_of_sale/point_of_sale_view.xml index e40cbc756b8..2079c50be78 100644 --- a/addons/point_of_sale/point_of_sale_view.xml +++ b/addons/point_of_sale/point_of_sale_view.xml @@ -794,13 +794,11 @@ - - diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index d824d0a043f..a1f6def6bf3 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -28,12 +28,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal this.db = new module.PosLS(); // a database used to store the products and categories this.db.clear('products','categories'); - // pos settings - this.use_scale = false; - this.use_proxy_printer = false; - this.use_virtual_keyboard = false; - this.use_barcode_scanner = false; - // default attributes values. If null, it will be loaded below. this.set({ 'nbr_pending_operations': 0, @@ -132,12 +126,11 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal }).pipe(function(configs){ var pos_config = configs[0]; self.set('pos_config', pos_config); - self.use_scale = !!pos_config.iface_electronic_scale; - self.use_proxy_printer = !!pos_config.iface_print_via_proxy; - self.use_virtual_keyboard = !!pos_config.iface_vkeyboard; - self.use_barcode_scanner = !!pos_config.iface_barscan; - self.use_selfcheckout = !!pos_config.iface_self_checkout; - self.use_cashbox = !!pos_config.iface_cashdrawer; + self.iface_electronic_scale = !!pos_config.iface_electronic_scale; + self.iface_print_via_proxy = !!pos_config.iface_print_via_proxy; + self.iface_vkeyboard = !!pos_config.iface_vkeyboard; + self.iface_self_checkout = !!pos_config.iface_self_checkout; + self.iface_cashdrawer = !!pos_config.iface_cashdrawer; return fetch('sale.shop',[],[['id','=',pos_config.shop_id[0]]]); }).pipe(function(shops){ diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js index d71199331f3..738eadb08c5 100644 --- a/addons/point_of_sale/static/src/js/screens.js +++ b/addons/point_of_sale/static/src/js/screens.js @@ -276,7 +276,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa this.pos_widget.set_left_action_bar_visible(this.show_leftpane && !cashier_mode); this.pos_widget.set_cashier_controls_visible(cashier_mode); - if(cashier_mode && this.pos.use_selfcheckout){ + if(cashier_mode && this.pos.iface_self_checkout){ this.pos_widget.client_button.show(); }else{ this.pos_widget.client_button.hide(); @@ -603,7 +603,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa this.product_list_widget = new module.ProductListWidget(this,{ click_product_action: function(product){ - if(product.get('to_weight') && self.pos.use_scale){ + if(product.get('to_weight') && self.pos.iface_electronic_scale){ self.pos_widget.screen_selector.set_current_screen(self.scale_screen, {product: product}); }else{ self.pos.get('selectedOrder').addProduct(product); @@ -620,7 +620,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa this.product_categories_widget.reset_category(); this.pos_widget.order_widget.set_numpad_state(this.pos_widget.numpad.state); - if(this.pos.use_virtual_keyboard){ + if(this.pos.iface_vkeyboard){ this.pos_widget.onscreen_keyboard.connect(); } @@ -719,7 +719,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa this._super(); var self = this; - if(this.pos.use_cashbox){ + if(this.pos.iface_cashdrawer){ this.pos.proxy.open_cashbox(); } @@ -753,7 +753,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa var currentOrder = this.pos.get('selectedOrder'); this.pos.push_order(currentOrder.exportAsJSON()) - if(this.pos.use_proxy_printer){ + if(this.pos.iface_print_via_proxy){ this.pos.proxy.print_receipt(currentOrder.export_for_printing()); this.pos.get('selectedOrder').destroy(); //finish order and go back to scan screen }else{ diff --git a/addons/point_of_sale/static/src/js/widgets.js b/addons/point_of_sale/static/src/js/widgets.js index f6840e402de..c3bd73ca35a 100644 --- a/addons/point_of_sale/static/src/js/widgets.js +++ b/addons/point_of_sale/static/src/js/widgets.js @@ -875,7 +875,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa }, default_client_screen: 'welcome', default_cashier_screen: 'products', - default_mode: this.pos.use_selfcheckout ? 'client' : 'cashier', + default_mode: this.pos.iface_self_checkout ? 'client' : 'cashier', }); }, From 552f5f8ef4b97bdd030f59f96763c821a36f5287 Mon Sep 17 00:00:00 2001 From: Antonin Bourguignon Date: Tue, 21 Aug 2012 12:51:13 +0200 Subject: [PATCH 142/166] [FIX] add a missing dependence bzr revid: abo@openerp.com-20120821105113-u7bty92d2lfea8q5 --- addons/portal/__openerp__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/portal/__openerp__.py b/addons/portal/__openerp__.py index 84a3b562133..84091a54347 100644 --- a/addons/portal/__openerp__.py +++ b/addons/portal/__openerp__.py @@ -25,6 +25,7 @@ 'depends' : [ 'base', 'share', + 'auth_anonymous', 'auth_signup', ], 'author' : 'OpenERP SA', @@ -45,8 +46,8 @@ very handy when used in combination with the module 'share'. 'data': [ 'security/portal_security.xml', 'security/ir.model.access.csv', - 'portal_view.xml', 'portal_data.xml', + 'portal_view.xml', 'wizard/portal_wizard_view.xml', 'wizard/share_wizard_view.xml', ], From c06c6930718807781bc45052d2bea6cd0765abbb Mon Sep 17 00:00:00 2001 From: Antonin Bourguignon Date: Tue, 21 Aug 2012 13:01:35 +0200 Subject: [PATCH 143/166] [IMP] organization of views and data bzr revid: abo@openerp.com-20120821110135-12mud78ddjwhmd8c --- addons/portal/portal_data.xml | 23 ++--------------------- addons/portal/portal_view.xml | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/addons/portal/portal_data.xml b/addons/portal/portal_data.xml index 58f2fc3e9d4..ddfb4cc6729 100644 --- a/addons/portal/portal_data.xml +++ b/addons/portal/portal_data.xml @@ -1,6 +1,6 @@ - + Portal @@ -10,7 +10,7 @@ - Company's news feed + Company's news @@ -32,24 +32,5 @@ form - - - - - - - - - - - - - diff --git a/addons/portal/portal_view.xml b/addons/portal/portal_view.xml index 831db25e26a..dd720d448ef 100644 --- a/addons/portal/portal_view.xml +++ b/addons/portal/portal_view.xml @@ -2,6 +2,25 @@ + + + + + + + + + + + + + Portal List From 197e6731005960058ae8ca5f5d9ad839ed056516 Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Tue, 21 Aug 2012 17:06:12 +0200 Subject: [PATCH 144/166] [IMP] point_of_sale: improve the layout of 'your session' bzr revid: stw@openerp.com-20120821150612-4ikdil8vzmkc0wwz --- .../wizard/pos_session_opening.py | 22 ++++++++++--------- .../wizard/pos_session_opening.xml | 5 +++-- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/addons/point_of_sale/wizard/pos_session_opening.py b/addons/point_of_sale/wizard/pos_session_opening.py index 056856d8365..d3b6ea28b17 100644 --- a/addons/point_of_sale/wizard/pos_session_opening.py +++ b/addons/point_of_sale/wizard/pos_session_opening.py @@ -4,13 +4,17 @@ from osv import osv, fields from tools.translate import _ import netsvc +from openerp.addons.point_of_sale.point_of_sale import pos_session + class pos_session_opening(osv.osv_memory): _name = 'pos.session.opening' _columns = { 'pos_config_id' : fields.many2one('pos.config', 'Point of Sale', required=True), 'pos_session_id' : fields.many2one('pos.session', 'PoS Session'), - 'pos_state' : fields.char('Session State', readonly=True), + 'pos_state' : fields.selection(pos_session.POS_SESSION_STATE, + 'Session State', readonly=True), + 'show_config' : fields.boolean('Show Config', readonly=True), } def open_ui(self, cr, uid, ids, context=None): @@ -19,7 +23,7 @@ class pos_session_opening(osv.osv_memory): context['active_id'] = data.pos_session_id.id return { 'type' : 'ir.actions.client', - 'name' : 'Start Point Of Sale', + 'name' : _('Start Point Of Sale'), 'tag' : 'pos.ui', 'context' : context } @@ -60,12 +64,6 @@ class pos_session_opening(osv.osv_memory): } def on_change_config(self, cr, uid, ids, config_id, context=None): - states = { - 'opening_control': _('Opening Control'), - 'opened': _('In Progress'), - 'closing_control': _('Closing Control'), - 'closed': _('Closed & Posted'), - } result = { 'pos_session_id': False, 'pos_state': False @@ -78,7 +76,7 @@ class pos_session_opening(osv.osv_memory): ('config_id', '=', config_id), ], context=context) if session_ids: - result['pos_state'] = states.get(proxy.browse(cr, uid, session_ids[0], context=context).state, False) + result['pos_state'] = proxy.browse(cr, uid, session_ids[0], context=context).state result['pos_session_id'] = session_ids[0] return {'value' : result} @@ -93,7 +91,11 @@ class pos_session_opening(osv.osv_memory): if not result: r = self.pool.get('pos.config').search(cr, uid, [], context=context) result = r and r[0] or False + + count = self.pool.get('pos.config').search_count(cr, uid, [('state', '=', 'active')], context=context) + show_config = bool(count > 1) return { - 'pos_config_id' : result + 'pos_config_id' : result, + 'show_config' : show_config, } pos_session_opening() diff --git a/addons/point_of_sale/wizard/pos_session_opening.xml b/addons/point_of_sale/wizard/pos_session_opening.xml index 8711aa5e5fb..948f1db8c61 100644 --- a/addons/point_of_sale/wizard/pos_session_opening.xml +++ b/addons/point_of_sale/wizard/pos_session_opening.xml @@ -6,8 +6,9 @@ pos.session.opening
    - - + + + From 47175ac608ff67d70a72a68bb817caf4e7326735 Mon Sep 17 00:00:00 2001 From: niv-openerp Date: Tue, 21 Aug 2012 17:43:43 +0200 Subject: [PATCH 145/166] [IMP] changed partners view to work correctly with linkedin module (still need improvements in the web client to support preview_image) bzr revid: nicolas.vanhoren@openerp.com-20120821154343-iv42z1ztvjkowp2e --- openerp/addons/base/res/res_partner_view.xml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/openerp/addons/base/res/res_partner_view.xml b/openerp/addons/base/res/res_partner_view.xml index 43a37d1a79c..e3614ad9b97 100644 --- a/openerp/addons/base/res/res_partner_view.xml +++ b/openerp/addons/base/res/res_partner_view.xml @@ -95,7 +95,7 @@ - +