From 66cadcdb18c9ce0f48a05cf7d13cb98ed2f171e5 Mon Sep 17 00:00:00 2001 From: Anael Closson Date: Fri, 10 May 2013 17:19:34 +0200 Subject: [PATCH 001/417] [FIX] OPW 591344 : internal reports don't show images Cleaner method, and shows images. bzr revid: acl@openerp.com-20130510151934-e2kvwiexdzp3zc12 --- openerp/report/render/rml2pdf/trml2pdf.py | 54 +++++++---------------- 1 file changed, 17 insertions(+), 37 deletions(-) diff --git a/openerp/report/render/rml2pdf/trml2pdf.py b/openerp/report/render/rml2pdf/trml2pdf.py index e8d6375c98e..153eff14b65 100644 --- a/openerp/report/render/rml2pdf/trml2pdf.py +++ b/openerp/report/render/rml2pdf/trml2pdf.py @@ -82,53 +82,33 @@ def _open_image(filename, path=None): pass raise IOError("File %s cannot be found in image path" % filename) + class NumberedCanvas(canvas.Canvas): def __init__(self, *args, **kwargs): canvas.Canvas.__init__(self, *args, **kwargs) - self._codes = [] - self._flag=False - self._pageCount=0 - self._currentPage =0 - self._pageCounter=0 - self.pages={} + self._saved_page_states = [] def showPage(self): - self._currentPage +=1 - if not self._flag: - self._pageCount += 1 - else: - self.pages.update({self._currentPage:self._pageCount}) - self._codes.append({'code': self._code, 'stack': self._codeStack}) + self._saved_page_states.append(dict(self.__dict__)) self._startPage() - self._flag=False - - def pageCount(self): - if self.pages.get(self._pageCounter,False): - self._pageNumber=0 - self._pageCounter +=1 - key=self._pageCounter - if not self.pages.get(key,False): - while not self.pages.get(key,False): - key += 1 - self.setFont("Helvetica", 8) - self.drawRightString((self._pagesize[0]-30), (self._pagesize[1]-40), - " %(this)i / %(total)i" % { - 'this': self._pageNumber+1, - 'total': self.pages.get(key,False), - } - ) def save(self): """add page info to each page (page x of y)""" - # reset page counter - self._pageNumber = 0 - for code in self._codes: - self._code = code['code'] - self._codeStack = code['stack'] - self.pageCount() + num_pages = len(self._saved_page_states) + for state in self._saved_page_states: + self.__dict__.update(state) + self.draw_page_number(num_pages) canvas.Canvas.showPage(self) -# self.restoreState() - self._doc.SaveToFile(self._filename, self) + canvas.Canvas.save(self) + + def draw_page_number(self, page_count): + self.drawRightString((self._pagesize[0]-30), (self._pagesize[1]-40), + " %(this)i / %(total)i" % { + 'this': self._pageNumber, + 'total': page_count, + } + ) + class PageCount(platypus.Flowable): def __init__(self, story_count=0): From 46e89d6dd1427ac5c7fa144f3b36e6ea1779771d Mon Sep 17 00:00:00 2001 From: Mohammed Shekha Date: Thu, 20 Jun 2013 16:16:06 +0530 Subject: [PATCH 002/417] [FIX]Fixed the issue of recurrent rule, there is no need of passing 'Z' after end_date as end_date converted to UNTIL parameter in rrule, and date given in UNTIL is not converted to any other timezone until you specifically passed timezone difference or timezone name like 20130620T121012+3:30 or 20130620T121012TZOFFSET, currently Z creates issue when recurrent rule is created with end_date, TypeError: can't compare offset-naive and offset-aware datetimes. bzr revid: msh@openerp.com-20130620104606-g3dyr1mafzo8fpgg --- addons/base_calendar/base_calendar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index 25bfcac448c..41a142cde68 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -1269,7 +1269,7 @@ rule or repeating pattern of time to exclude from the recurring rule."), def get_end_date(data): if data.get('end_date'): - data['end_date_new'] = ''.join((re.compile('\d')).findall(data.get('end_date'))) + 'T235959Z' + data['end_date_new'] = ''.join((re.compile('\d')).findall(data.get('end_date'))) + 'T235959' return (data.get('end_type') == 'count' and (';COUNT=' + str(data.get('count'))) or '') +\ ((data.get('end_date_new') and data.get('end_type') == 'end_date' and (';UNTIL=' + data.get('end_date_new'))) or '') From 3276861ff6125d02e08b5c5b12b75925e056c4bc Mon Sep 17 00:00:00 2001 From: "Xavier Fernandez http://www.smile.fr" <> Date: Wed, 28 Aug 2013 17:21:17 +0200 Subject: [PATCH 003/417] [FIX] port Xavier Fernandez's fix for Bug #971412: Translations export has no fixed order lp bug: https://launchpad.net/bugs/971412 fixed bzr revid: ls@numerigraphe.com-20130828152117-e1h0yljgbn538v9o --- openerp/tools/translate.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 41113b8ccd9..53762b87970 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -458,7 +458,8 @@ def trans_export(lang, modules, buffer, format, cr): row.setdefault('tnrs', []).append((type, name, res_id)) row.setdefault('comments', set()).update(comments) - for src, row in grouped_rows.items(): + for src in sorted(grouped_rows): + row = grouped_rows[src] if not lang: # translation template, so no translation value row['translation'] = '' From 1f3a482f4fc309262802b980e143234a56b9503d Mon Sep 17 00:00:00 2001 From: Lionel Sausin Date: Thu, 29 Aug 2013 09:50:35 +0200 Subject: [PATCH 004/417] [REF] avoid the lookup in sorted translation export as suggested by Guewen Baconnier @ Camptocamp bzr revid: ls@numerigraphe.com-20130829075035-lml81a7bbn66c8qu --- openerp/tools/translate.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 53762b87970..6e9eb50f162 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -458,8 +458,7 @@ def trans_export(lang, modules, buffer, format, cr): row.setdefault('tnrs', []).append((type, name, res_id)) row.setdefault('comments', set()).update(comments) - for src in sorted(grouped_rows): - row = grouped_rows[src] + for src, row in sorted(grouped_rows.items()): if not lang: # translation template, so no translation value row['translation'] = '' From 0dcc62426c3689191798fbe33717eea5d4659a96 Mon Sep 17 00:00:00 2001 From: Yanina Aular Date: Fri, 15 Nov 2013 17:57:17 -0430 Subject: [PATCH 005/417] [FIX] function field with wrong type int instead of integer bzr revid: yanina.aular@vauxoo.com-20131115222717-12bplq7rnv3rorbm --- addons/project/project.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/project/project.py b/addons/project/project.py index 5bd2e604368..c7b394ad376 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -288,7 +288,8 @@ class project(osv.osv): help="The kind of document created when an email is received on this project's email alias"), 'privacy_visibility': fields.selection(_visibility_selection, 'Privacy / Visibility', required=True), 'state': fields.selection([('template', 'Template'),('draft','New'),('open','In Progress'), ('cancelled', 'Cancelled'),('pending','Pending'),('close','Closed')], 'Status', required=True,), - 'doc_count':fields.function(_get_attached_docs, string="Number of documents attached", type='int') + 'doc_count':fields.function(_get_attached_docs, string="Number of documents attached", + type='integer') } def _get_type_common(self, cr, uid, context): From 02224a3f112426c9e15a8af7cde2e7a5406d1885 Mon Sep 17 00:00:00 2001 From: "Dharti Ratani (Open ERP)" Date: Thu, 12 Dec 2013 10:55:44 +0530 Subject: [PATCH 006/417] [FIX]Added the refernce of the supplier in price_get method while creating purchase order from purchase requisition, as without supplier the price unit in PO was 0 when the pricelist item was based on Supplier Price in the product form bzr revid: dhr@tinyerp.com-20131212052544-skljxsrxea4o8efm --- addons/purchase_requisition/purchase_requisition.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/purchase_requisition/purchase_requisition.py b/addons/purchase_requisition/purchase_requisition.py index c1d80c7bf46..c31f8a69a37 100644 --- a/addons/purchase_requisition/purchase_requisition.py +++ b/addons/purchase_requisition/purchase_requisition.py @@ -109,7 +109,7 @@ class purchase_requisition(osv.osv): seller_delay = product_supplier.delay seller_qty = product_supplier.qty supplier_pricelist = supplier.property_product_pricelist_purchase or False - seller_price = pricelist.price_get(cr, uid, [supplier_pricelist.id], product.id, qty, False, {'uom': default_uom_po_id})[supplier_pricelist.id] + seller_price = pricelist.price_get(cr, uid, [supplier_pricelist.id], product.id, qty, supplier.id, {'uom': default_uom_po_id})[supplier_pricelist.id] if seller_qty: qty = max(qty,seller_qty) date_planned = self._planned_date(requisition_line.requisition_id, seller_delay) From f6349ffb7fd9c075573953be2ac0f0dc20520743 Mon Sep 17 00:00:00 2001 From: Leonardo Pistone Date: Wed, 18 Dec 2013 17:45:26 +0100 Subject: [PATCH 007/417] [merge] [fix] action should return True lp bug: https://launchpad.net/bugs/1262265 fixed bzr revid: leonardo.pistone@camptocamp.com-20131218164526-rgyo6p9hlpk28sxg --- addons/mrp_repair/mrp_repair.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/mrp_repair/mrp_repair.py b/addons/mrp_repair/mrp_repair.py index 9c0ab0e2c18..9335d395714 100644 --- a/addons/mrp_repair/mrp_repair.py +++ b/addons/mrp_repair/mrp_repair.py @@ -350,7 +350,8 @@ class mrp_repair(osv.osv): return self.write(cr,uid,ids,{'state':'cancel'}) def wkf_invoice_create(self, cr, uid, ids, *args): - return self.action_invoice_create(cr, uid, ids) + self.action_invoice_create(cr, uid, ids) + return True def action_invoice_create(self, cr, uid, ids, group=False, context=None): """ Creates invoice(s) for repair order. From 262a405b0ab1018bde19e61d38a4525582831a16 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Fri, 3 Jan 2014 14:07:03 +0100 Subject: [PATCH 008/417] Remove old FR VAT taxes 19.6% and 7.0%. Remove the FR VAT tax 5.0% that has never seen the light ! bzr revid: alexis@via.ecp.fr-20140103130703-kpf5rojc4azwq8w1 --- addons/l10n_fr/fr_fiscal_templates.xml | 79 ----- addons/l10n_fr/fr_tax.xml | 387 ------------------------- 2 files changed, 466 deletions(-) diff --git a/addons/l10n_fr/fr_fiscal_templates.xml b/addons/l10n_fr/fr_fiscal_templates.xml index bf49d15e08c..cca96422c22 100644 --- a/addons/l10n_fr/fr_fiscal_templates.xml +++ b/addons/l10n_fr/fr_fiscal_templates.xml @@ -40,11 +40,6 @@ - - - - - @@ -57,22 +52,12 @@ - - - - - - - - - - @@ -91,17 +76,6 @@ - - - - - - - - - - - @@ -124,17 +98,6 @@ - - - - - - - - - - - @@ -146,17 +109,6 @@ - - - - - - - - - - - @@ -177,11 +129,6 @@ - - - - - @@ -194,22 +141,12 @@ - - - - - - - - - - @@ -224,11 +161,6 @@ - - - - - @@ -241,23 +173,12 @@ - - - - - - - - - - - diff --git a/addons/l10n_fr/fr_tax.xml b/addons/l10n_fr/fr_tax.xml index 8633cca7141..22e1e12f03c 100644 --- a/addons/l10n_fr/fr_tax.xml +++ b/addons/l10n_fr/fr_tax.xml @@ -29,28 +29,6 @@ sale - - - - TVA collectée (vente) 19,6% - 19.6 - - percent - - - - - - - - - - - - - - sale - @@ -96,51 +74,7 @@ sale - - - TVA collectée (vente) 7,0% - 7.0 - - percent - - - - - - - - - - - - - - sale - - - - TVA collectée (vente) 5,0% - 5.0 - - percent - - - - - - - - - - - - - - sale - - - TVA collectée (vente) 5,5% 5.5 @@ -208,28 +142,6 @@ purchase - - - TVA déductible (achat) 19,6% - ACH-19.6 - - percent - - - - - - - - - - - - - - purchase - - TVA déductible (achat) 8,5% @@ -274,51 +186,7 @@ purchase - - - TVA déductible (achat) 7,0% - ACH-7.0 - - percent - - - - - - - - - - - - - - purchase - - - - TVA déductible (achat) 5,0% - ACH-5.0 - - percent - - - - - - - - - - - - - - purchase - - - TVA déductible (achat) 5,5% ACH-5.5 @@ -387,29 +255,6 @@ purchase - - - TVA déductible (achat) 19,6% TTC - ACH-19.6-TTC - - - percent - - - - - - - - - - - - - - purchase - - TVA déductible (achat) 8,5% TTC @@ -456,53 +301,7 @@ purchase - - - TVA déductible (achat) 7,0% TTC - ACH-7.0-TTC - - - percent - - - - - - - - - - - - - - purchase - - - - TVA déductible (achat) 5,0% TTC - ACH-5.0-TTC - - - percent - - - - - - - - - - - - - - purchase - - - TVA déductible (achat) 5,5% TTC ACH-5.5-TTC @@ -573,28 +372,6 @@ purchase - - - TVA déd./immobilisation (achat) 19,6% - IMMO-19.6 - - percent - - - - - - - - - - - - - - purchase - - TVA déd./immobilisation (achat) 8,5% @@ -639,51 +416,7 @@ purchase - - - TVA déd./immobilisation (achat) 7,0% - IMMO-7.0 - - percent - - - - - - - - - - - - - - purchase - - - - TVA déd./immobilisation (achat) 5,0% - IMMO-5.0 - - percent - - - - - - - - - - - - - - purchase - - - TVA déd./immobilisation (achat) 5,5% IMMO-5.5 @@ -751,28 +484,6 @@ purchase - - - TVA due s/ acq. intracommunautaire (achat) 19,6% - ACH_UE_due-19.6 - - percent - - - - - - - - - - - - - - purchase - - TVA due s/ acq. intracommunautaire (achat) 8,5% @@ -817,51 +528,7 @@ purchase - - - TVA due s/ acq. intracommunautaire (achat) 7,0% - ACH_UE_due-7.0 - - percent - - - - - - - - - - - - - - purchase - - - - TVA due s/ acq. intracommunautaire (achat) 5,0% - ACH_UE_due-5.0 - - percent - - - - - - - - - - - - - - purchase - - - TVA due s/ acq. intracommunautaire (achat) 5,5% ACH_UE_due-5.5 @@ -925,24 +592,6 @@ purchase - - - TVA déd. s/ acq. intracommunautaire (achat) 19,6% - ACH_UE_ded.-19.6 - - percent - - - - - - - - - - purchase - - TVA déd. s/ acq. intracommunautaire (achat) 8,5% @@ -979,43 +628,7 @@ purchase - - - TVA déd. s/ acq. intracommunautaire (achat) 7,0% - ACH_UE_ded.-7.0 - - percent - - - - - - - - - - purchase - - - - TVA déd. s/ acq. intracommunautaire (achat) 5,0% - ACH_UE_ded.-5.0 - - percent - - - - - - - - - - purchase - - - TVA déd. s/ acq. intracommunautaire (achat) 5,5% ACH_UE_ded.-5.5 From 6abf20906e7b5d3e319a227301fbcf1a6d4492b7 Mon Sep 17 00:00:00 2001 From: jke-openerp Date: Sat, 1 Feb 2014 21:04:13 +0100 Subject: [PATCH 009/417] [Typo] Replace t-esc in t-field for amount_untaxed in checkout of website_sale. Else display monetary does not work bzr revid: jke@openerp.com-20140201200413-zww5pcobl6vmvqe1 --- addons/website_sale/views/website_sale.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_sale/views/website_sale.xml b/addons/website_sale/views/website_sale.xml index ed2007e27c7..cc1220a57e7 100644 --- a/addons/website_sale/views/website_sale.xml +++ b/addons/website_sale/views/website_sale.xml @@ -832,7 +832,7 @@
Subtotal:
-
From c18d3504689228807d6703b920b43d6c4e6e6721 Mon Sep 17 00:00:00 2001 From: jke-openerp Date: Sat, 1 Feb 2014 21:47:41 +0100 Subject: [PATCH 010/417] [FIX] Fix bug where button with contenteditable does not work in cross browser. Fix : replace tag 'button' by 'a' with class 'a-submit' bzr revid: jke@openerp.com-20140201204741-ygdxaauq0m5axttg --- addons/website_sale/static/src/js/website_sale.js | 4 ++++ addons/website_sale/views/website_sale.xml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/addons/website_sale/static/src/js/website_sale.js b/addons/website_sale/static/src/js/website_sale.js index 7f6d24373f7..eedbb5a046c 100644 --- a/addons/website_sale/static/src/js/website_sale.js +++ b/addons/website_sale/static/src/js/website_sale.js @@ -60,6 +60,10 @@ $(document).ready(function () { return false; }); + $('.a-submit').on('click', function () { + $(this).closest('form').submit(); + }); + // change price when they are variants $('form.js_add_cart_json label').on('mouseup', function (ev) { ev.preventDefault(); diff --git a/addons/website_sale/views/website_sale.xml b/addons/website_sale/views/website_sale.xml index ed2007e27c7..d6c86c81e8b 100644 --- a/addons/website_sale/views/website_sale.xml +++ b/addons/website_sale/views/website_sale.xml @@ -331,7 +331,7 @@ }'/>
- + Add to Cart


From 8bbb20650464b5784fd3afa0eb219ed1802e2a4f Mon Sep 17 00:00:00 2001 From: "ddm@openerp.com" <> Date: Thu, 13 Feb 2014 16:24:49 +0100 Subject: [PATCH 011/417] [IMP] save new orders only bzr revid: ddm@openerp.com-20140213152449-tarl15agw9r3teqg --- addons/point_of_sale/point_of_sale.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/addons/point_of_sale/point_of_sale.py b/addons/point_of_sale/point_of_sale.py index 30fcff2e5e6..dec4431a15c 100644 --- a/addons/point_of_sale/point_of_sale.py +++ b/addons/point_of_sale/point_of_sale.py @@ -513,13 +513,18 @@ class pos_order(osv.osv): _order = "id desc" def create_from_ui(self, cr, uid, orders, context=None): - #_logger.info("orders: %r", orders) + + # Keep only new orders + submitted_references = [o['data']['name'] for o in orders] + existing_orders = self.search_read(cr, uid, [('pos_reference', 'in', submitted_references)], context) + existing_references = set([o['pos_reference'] for o in existing_orders]) + orders_to_save = [o for o in orders if o['data']['name'] not in existing_references] + order_ids = [] - for tmp_order in orders: + for tmp_order in orders_to_save: to_invoice = tmp_order['to_invoice'] order = tmp_order['data'] - order_id = self.create(cr, uid, { 'name': order['name'], 'user_id': order['user_id'] or False, From e7f238615ca1c79700a0deacb1d1799b797a0472 Mon Sep 17 00:00:00 2001 From: "ddm@openerp.com" <> Date: Thu, 13 Feb 2014 17:38:49 +0100 Subject: [PATCH 012/417] [IMP] fetch only relevant fields when checking for dupes bzr revid: ddm@openerp.com-20140213163849-8v485vq5v4xmeocg --- addons/point_of_sale/point_of_sale.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/point_of_sale/point_of_sale.py b/addons/point_of_sale/point_of_sale.py index 9e78a29cfec..01e7a49ec8c 100644 --- a/addons/point_of_sale/point_of_sale.py +++ b/addons/point_of_sale/point_of_sale.py @@ -517,7 +517,7 @@ class pos_order(osv.osv): # Keep only new orders submitted_references = [o['data']['name'] for o in orders] - existing_orders = self.search_read(cr, uid, [('pos_reference', 'in', submitted_references)], context) + existing_orders = self.search_read(cr, uid, domain=[('pos_reference', 'in', submitted_references)], fields=['pos_reference'], context=context) existing_references = set([o['pos_reference'] for o in existing_orders]) orders_to_save = [o for o in orders if o['data']['name'] not in existing_references] From 3ea931c48637265183ce17b8cfb21c858f90a56d Mon Sep 17 00:00:00 2001 From: "ddm@openerp.com" <> Date: Fri, 14 Feb 2014 15:49:30 +0100 Subject: [PATCH 013/417] [IMP] save all orders at once (client) bzr revid: ddm@openerp.com-20140214144930-5zpn3miys1hwrdoa --- addons/point_of_sale/static/src/js/models.js | 97 ++++++++++---------- 1 file changed, 51 insertions(+), 46 deletions(-) diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 6b54c14113d..90aa5fece05 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -421,62 +421,67 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal // it is therefore important to only call this method from inside a mutex // this method returns a deferred indicating wether the sending was successful or not // there is a timeout parameter which is set to 2 seconds by default. - _flush_order: function(order_id, options){ - var self = this; - options = options || {}; - timeout = typeof options.timeout === 'number' ? options.timeout : 7500; - - this.set('synch',{state:'connecting', pending: this.get('synch').pending}); - - var order = this.db.get_order(order_id); - order.to_invoice = options.to_invoice || false; - - if(!order){ - // flushing a non existing order always fails - return (new $.Deferred()).reject(); - } - - // we try to send the order. shadow prevents a spinner if it takes too long. (unless we are sending an invoice, - // then we want to notify the user that we are waiting on something ) - var rpc = (new instance.web.Model('pos.order')).call('create_from_ui',[[order]],undefined,{shadow: !options.to_invoice, timeout:timeout}); - - rpc.fail(function(unused,event){ - // prevent an error popup creation by the rpc failure - // we want the failure to be silent as we send the orders in the background - event.preventDefault(); - console.error('Failed to send order:',order); - }); - - rpc.done(function(){ - self.db.remove_order(order_id); - var pending = self.db.get_orders().length; - self.set('synch',{state: pending ? 'connecting' : 'connected', pending:pending}); - }); - - return rpc; + _flush_order: function( order_id, options) { + return this._flush_all_orders([this.db.get_order(order_id)], options); }, // attempts to send all the locally stored orders. As with _flush_order, it should only be // called from within a mutex. // this method returns a deferred that always succeeds when all orders have been tried to be sent, // even if none of them could actually be sent. - _flush_all_orders: function(){ + _flush_all_orders: function () { var self = this; - var orders = this.db.get_orders(); - var tried_all = new $.Deferred(); + self.set('synch', { + state: 'connecting', + pending: self.get('synch').pending + }); + return self._save_to_server(self.db.get_orders()).done(function () { + var pending = self.db.get_orders().length; + self.set('synch', { + state: pending ? 'connecting' : 'connected', + pending: pending + }); + }); + }, - function rec_flush(index){ - if(index < orders.length){ - self._flush_order(orders[index].id).always(function(){ - rec_flush(index+1); - }) - }else{ - tried_all.resolve(); - } + // send an array of orders to the server + // available options: + // - timeout: timeout for the rpc call in ms + _save_to_server: function (orders, options) { + if (!orders || !orders.length) { + var result = $.Deferred(); + result.resolve(); + return result; } - rec_flush(0); + + options = options || {}; - return tried_all; + var self = this; + var timeout = typeof options.timeout === 'number' ? options.timeout : 7500; + + // we try to send the order. shadow prevents a spinner if it takes too long. (unless we are sending an invoice, + // then we want to notify the user that we are waiting on something ) + var posOrderModel = new instance.web.Model('pos.order'); + return posOrderModel.call('create_from_ui', + [_.map(orders, function (order) { + order.to_invoice = options.to_invoice || false; + return order; + })], + undefined, + { + shadow: !options.to_invoice, + timeout: timeout + } + ).then(function () { + _.each(orders, function (order) { + self.db.remove_order(order.id); + }); + }).fail(function (unused, event){ + // prevent an error popup creation by the rpc failure + // we want the failure to be silent as we send the orders in the background + event.preventDefault(); + console.error('Failed to send orders:', orders); + }); }, scan_product: function(parsed_code){ From e776245b8b597b57877b99aef2a15a127ee6a55e Mon Sep 17 00:00:00 2001 From: Paramjit Singh Sahota Date: Thu, 20 Feb 2014 15:37:16 +0530 Subject: [PATCH 014/417] [ADD] Added jquery.placeholder lib. because IE9 is not supporting the placeholders. bzr revid: psa@tinyerp.com-20140220100716-01mjib3w692qdgi1 --- .../jquery.placeholder/jquery.placeholder.js | 185 ++++++++++++++++++ addons/website/static/src/js/website.js | 1 + addons/website/views/website_templates.xml | 2 + 3 files changed, 188 insertions(+) create mode 100644 addons/website/static/lib/jquery.placeholder/jquery.placeholder.js diff --git a/addons/website/static/lib/jquery.placeholder/jquery.placeholder.js b/addons/website/static/lib/jquery.placeholder/jquery.placeholder.js new file mode 100644 index 00000000000..4e296b7ac4e --- /dev/null +++ b/addons/website/static/lib/jquery.placeholder/jquery.placeholder.js @@ -0,0 +1,185 @@ +/*! http://mths.be/placeholder v2.0.7 by @mathias */ +;(function(window, document, $) { + + // Opera Mini v7 doesn’t support placeholder although its DOM seems to indicate so + var isOperaMini = Object.prototype.toString.call(window.operamini) == '[object OperaMini]'; + var isInputSupported = 'placeholder' in document.createElement('input') && !isOperaMini; + var isTextareaSupported = 'placeholder' in document.createElement('textarea') && !isOperaMini; + var prototype = $.fn; + var valHooks = $.valHooks; + var propHooks = $.propHooks; + var hooks; + var placeholder; + + if (isInputSupported && isTextareaSupported) { + + placeholder = prototype.placeholder = function() { + return this; + }; + + placeholder.input = placeholder.textarea = true; + + } else { + + placeholder = prototype.placeholder = function() { + var $this = this; + $this + .filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]') + .not('.placeholder') + .bind({ + 'focus.placeholder': clearPlaceholder, + 'blur.placeholder': setPlaceholder + }) + .data('placeholder-enabled', true) + .trigger('blur.placeholder'); + return $this; + }; + + placeholder.input = isInputSupported; + placeholder.textarea = isTextareaSupported; + + hooks = { + 'get': function(element) { + var $element = $(element); + + var $passwordInput = $element.data('placeholder-password'); + if ($passwordInput) { + return $passwordInput[0].value; + } + + return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value; + }, + 'set': function(element, value) { + var $element = $(element); + + var $passwordInput = $element.data('placeholder-password'); + if ($passwordInput) { + return $passwordInput[0].value = value; + } + + if (!$element.data('placeholder-enabled')) { + return element.value = value; + } + if (value == '') { + element.value = value; + // Issue #56: Setting the placeholder causes problems if the element continues to have focus. + if (element != safeActiveElement()) { + // We can't use `triggerHandler` here because of dummy text/password inputs :( + setPlaceholder.call(element); + } + } else if ($element.hasClass('placeholder')) { + clearPlaceholder.call(element, true, value) || (element.value = value); + } else { + element.value = value; + } + // `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363 + return $element; + } + }; + + if (!isInputSupported) { + valHooks.input = hooks; + propHooks.value = hooks; + } + if (!isTextareaSupported) { + valHooks.textarea = hooks; + propHooks.value = hooks; + } + + $(function() { + // Look for forms + $(document).delegate('form', 'submit.placeholder', function() { + // Clear the placeholder values so they don't get submitted + var $inputs = $('.placeholder', this).each(clearPlaceholder); + setTimeout(function() { + $inputs.each(setPlaceholder); + }, 10); + }); + }); + + // Clear placeholder values upon page reload + $(window).bind('beforeunload.placeholder', function() { + $('.placeholder').each(function() { + this.value = ''; + }); + }); + + } + + function args(elem) { + // Return an object of element attributes + var newAttrs = {}; + var rinlinejQuery = /^jQuery\d+$/; + $.each(elem.attributes, function(i, attr) { + if (attr.specified && !rinlinejQuery.test(attr.name)) { + newAttrs[attr.name] = attr.value; + } + }); + return newAttrs; + } + + function clearPlaceholder(event, value) { + var input = this; + var $input = $(input); + if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) { + if ($input.data('placeholder-password')) { + $input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id')); + // If `clearPlaceholder` was called from `$.valHooks.input.set` + if (event === true) { + return $input[0].value = value; + } + $input.focus(); + } else { + input.value = ''; + $input.removeClass('placeholder'); + input == safeActiveElement() && input.select(); + } + } + } + + function setPlaceholder() { + var $replacement; + var input = this; + var $input = $(input); + var id = this.id; + if (input.value == '') { + if (input.type == 'password') { + if (!$input.data('placeholder-textinput')) { + try { + $replacement = $input.clone().attr({ 'type': 'text' }); + } catch(e) { + $replacement = $('').attr($.extend(args(this), { 'type': 'text' })); + } + $replacement + .removeAttr('name') + .data({ + 'placeholder-password': $input, + 'placeholder-id': id + }) + .bind('focus.placeholder', clearPlaceholder); + $input + .data({ + 'placeholder-textinput': $replacement, + 'placeholder-id': id + }) + .before($replacement); + } + $input = $input.removeAttr('id').hide().prev().attr('id', id).show(); + // Note: `$input[0] != input` now! + } + $input.addClass('placeholder'); + $input[0].value = $input.attr('placeholder'); + } else { + $input.removeClass('placeholder'); + } + } + + function safeActiveElement() { + // Avoid IE9 `document.activeElement` of death + // https://github.com/mathiasbynens/jquery-placeholder/pull/99 + try { + return document.activeElement; + } catch (err) {} + } + +}(this, document, jQuery)); \ No newline at end of file diff --git a/addons/website/static/src/js/website.js b/addons/website/static/src/js/website.js index b249fb7136f..3faae6ee1ef 100644 --- a/addons/website/static/src/js/website.js +++ b/addons/website/static/src/js/website.js @@ -69,6 +69,7 @@ website.is_editable = website.is_editable || $('html').data('editable'); website.is_editable_button= website.is_editable_button || $('html').data('editable'); dom_ready.resolve(); + $('input, textarea').placeholder(); }); website.init_kanban = function ($kanban) { diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml index 5649ded4d4d..96e184a32a1 100644 --- a/addons/website/views/website_templates.xml +++ b/addons/website/views/website_templates.xml @@ -272,6 +272,8 @@ + + From 2e3e44255ebb4e7530c48b35df62a12c99b4323c Mon Sep 17 00:00:00 2001 From: Paramjit Singh Sahota Date: Thu, 20 Feb 2014 15:52:00 +0530 Subject: [PATCH 015/417] [FIX] Editor bar is showing border. bzr revid: psa@tinyerp.com-20140220102200-2r2urlrrkngv20at --- addons/website/static/src/css/editor.css | 1 + addons/website/static/src/css/editor.sass | 1 + 2 files changed, 2 insertions(+) diff --git a/addons/website/static/src/css/editor.css b/addons/website/static/src/css/editor.css index 4fb4496e692..df2188e794d 100644 --- a/addons/website/static/src/css/editor.css +++ b/addons/website/static/src/css/editor.css @@ -26,6 +26,7 @@ -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; + -ms-filter: "alpha(opacity=50)"; } /* ---- OpenERP Style ---- {{{ */ diff --git a/addons/website/static/src/css/editor.sass b/addons/website/static/src/css/editor.sass index 2e6513f7c1d..49b71ffefdf 100644 --- a/addons/website/static/src/css/editor.sass +++ b/addons/website/static/src/css/editor.sass @@ -23,6 +23,7 @@ background: transparent border: none +box-shadow(none) + -ms-filter: "alpha(opacity=50)" // }}} From 6305ac409444ca01388ce1ad66ef2af3783360bf Mon Sep 17 00:00:00 2001 From: Kersten Jeremy Date: Thu, 20 Feb 2014 16:08:17 +0100 Subject: [PATCH 016/417] [FIX] Disable traceback popup when rpc /calendar/notify fail bzr revid: jke@openerp.com-20140220150817-3rvvm8neeqviba6o --- addons/calendar/static/src/js/base_calendar.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/addons/calendar/static/src/js/base_calendar.js b/addons/calendar/static/src/js/base_calendar.js index 18fd4dfa20e..4384964575c 100644 --- a/addons/calendar/static/src/js/base_calendar.js +++ b/addons/calendar/static/src/js/base_calendar.js @@ -11,7 +11,7 @@ openerp.calendar = function(instance) { get_next_notif: function() { var self= this; this.rpc("/calendar/notify") - .then( + .done( function(result) { _.each(result, function(res) { setTimeout(function() { @@ -44,6 +44,12 @@ openerp.calendar = function(instance) { },res.timer * 1000); }); } + ) + .fail( + // To override error from framework.js in RPC function + function(error, event) { + event.preventDefault(); + } ); }, check_notifications: function() { @@ -51,14 +57,14 @@ openerp.calendar = function(instance) { self.get_next_notif(); setInterval(function(){ self.get_next_notif(); - }, 5 * 60 * 1000 ); + }, 5 * 60 * 1000 ); }, //Override the show_application of addons/web/static/src/js/chrome.js show_application: function() { this._super(); this.check_notifications(); - }, + }, }); From 8d8ede7f7d075c29f903b2714028c009b7a337ec Mon Sep 17 00:00:00 2001 From: Kersten Jeremy Date: Thu, 20 Feb 2014 16:08:17 +0100 Subject: [PATCH 017/417] [FIX] Disable traceback popup when rpc /calendar/notify fail bzr revid: jke@openerp.com-20140220150817-0yyovkr4ooqu8ejc --- addons/calendar/static/src/js/base_calendar.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/addons/calendar/static/src/js/base_calendar.js b/addons/calendar/static/src/js/base_calendar.js index 18fd4dfa20e..4384964575c 100644 --- a/addons/calendar/static/src/js/base_calendar.js +++ b/addons/calendar/static/src/js/base_calendar.js @@ -11,7 +11,7 @@ openerp.calendar = function(instance) { get_next_notif: function() { var self= this; this.rpc("/calendar/notify") - .then( + .done( function(result) { _.each(result, function(res) { setTimeout(function() { @@ -44,6 +44,12 @@ openerp.calendar = function(instance) { },res.timer * 1000); }); } + ) + .fail( + // To override error from framework.js in RPC function + function(error, event) { + event.preventDefault(); + } ); }, check_notifications: function() { @@ -51,14 +57,14 @@ openerp.calendar = function(instance) { self.get_next_notif(); setInterval(function(){ self.get_next_notif(); - }, 5 * 60 * 1000 ); + }, 5 * 60 * 1000 ); }, //Override the show_application of addons/web/static/src/js/chrome.js show_application: function() { this._super(); this.check_notifications(); - }, + }, }); From 2e49e46698c52edf29c7a42b1a67f8f2cb110e34 Mon Sep 17 00:00:00 2001 From: Paramjit Singh Sahota Date: Fri, 21 Feb 2014 11:42:36 +0530 Subject: [PATCH 018/417] [FIX] Fixed the sliding issue of carousel library in IE9. The transition was not working in any snippet bzr revid: psa@tinyerp.com-20140221061236-7jcbgae7m081pjv8 --- addons/website/static/lib/bootstrap/js/bootstrap.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/addons/website/static/lib/bootstrap/js/bootstrap.js b/addons/website/static/lib/bootstrap/js/bootstrap.js index b22be6fce1d..2d31d0eb3c3 100644 --- a/addons/website/static/lib/bootstrap/js/bootstrap.js +++ b/addons/website/static/lib/bootstrap/js/bootstrap.js @@ -418,6 +418,17 @@ if (typeof jQuery === "undefined") { throw new Error("Bootstrap requires jQuery" setTimeout(function () { that.$element.trigger('slid') }, 0) }) .emulateTransitionEnd(600) + } else if(this.$element.hasClass('slide')) { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $active.animate({left: (direction == 'right' ? '100%' : '-100%')}, 600, function(){ + $active.removeClass('active') + that.sliding = false + setTimeout(function() { that.$element.trigger('slid')}, 0) + }) + $next.addClass(type).css({left: (direction == 'right' ? '-100%' : '100%')}).animate({left: 0}, 600, function() { + $next.removeClass(type).addClass('active') + }) } else { this.$element.trigger(e) if (e.isDefaultPrevented()) return From 777506617af86dad56743ae014866b5bb6224c59 Mon Sep 17 00:00:00 2001 From: Paramjit Singh Sahota Date: Fri, 21 Feb 2014 12:45:12 +0530 Subject: [PATCH 019/417] [FIX] 'window.location.origin' is not found in IE browser thats why generated manually. bzr revid: psa@tinyerp.com-20140221071512-4uky4k2wiu6miysi --- addons/website/static/src/js/website.mobile.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addons/website/static/src/js/website.mobile.js b/addons/website/static/src/js/website.mobile.js index 4acf2d78db8..ac3b17ddad7 100644 --- a/addons/website/static/src/js/website.mobile.js +++ b/addons/website/static/src/js/website.mobile.js @@ -17,6 +17,9 @@ 'hidden.bs.modal': 'destroy' }, start: function () { + if (!window.location.origin) { + window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: ''); + } document.getElementById("mobile-viewport").src = window.location.origin + window.location.pathname + "#mobile-preview"; this.$el.modal(); }, From 467ec6a91953378904f2462631cc4d169a2773ba Mon Sep 17 00:00:00 2001 From: Pariket Trivedi Date: Fri, 21 Feb 2014 18:42:15 +0530 Subject: [PATCH 020/417] [FIX] Fixed a small problem which falls to load the template in mobile bzr revid: psa@tinyerp.com-20140221131215-nf1y2t3qbeiosujb --- addons/website/static/src/js/website.mobile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website/static/src/js/website.mobile.js b/addons/website/static/src/js/website.mobile.js index ac3b17ddad7..35b3e7c5acd 100644 --- a/addons/website/static/src/js/website.mobile.js +++ b/addons/website/static/src/js/website.mobile.js @@ -18,7 +18,7 @@ }, start: function () { if (!window.location.origin) { - window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: ''); + window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: '') + '/'; } document.getElementById("mobile-viewport").src = window.location.origin + window.location.pathname + "#mobile-preview"; this.$el.modal(); From 1bc89c97383b572ee3c199dbc1524ab7f27c7010 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 24 Feb 2014 10:48:29 +0100 Subject: [PATCH 021/417] [FIX] unbreak website_blog.css bzr revid: xmo@openerp.com-20140224094829-99ayhh5shzwu6n44 --- addons/website_blog/static/src/css/website_blog.css | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/website_blog/static/src/css/website_blog.css b/addons/website_blog/static/src/css/website_blog.css index 96045adb914..f7355ce783d 100644 --- a/addons/website_blog/static/src/css/website_blog.css +++ b/addons/website_blog/static/src/css/website_blog.css @@ -1,5 +1,4 @@ -@charset "utf-8"; -@import url(compass/css3.css); +@charset "UTF-8"; .css_website_mail .has-error { border-color: red; } From d1bbeb21a1dfb6001f68a7859801f3d961019c2a Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Mon, 24 Feb 2014 11:43:01 +0100 Subject: [PATCH 022/417] [FIX] website's translation problems on multiple view inheritance bzr revid: fme@openerp.com-20140224104301-n8dqg0lx4oijf66b --- openerp/addons/base/ir/ir_ui_view.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/openerp/addons/base/ir/ir_ui_view.py b/openerp/addons/base/ir/ir_ui_view.py index aafce29b7eb..d4655bf8b9c 100644 --- a/openerp/addons/base/ir/ir_ui_view.py +++ b/openerp/addons/base/ir/ir_ui_view.py @@ -316,14 +316,14 @@ class view(osv.osv): return node return None - def inherit_branding(self, specs_tree, view_id, source_id): + def inherit_branding(self, specs_tree, view_id, root_id): for node in specs_tree.iterchildren(tag=etree.Element): xpath = node.getroottree().getpath(node) if node.tag == 'data' or node.tag == 'xpath': - self.inherit_branding(node, view_id, source_id) + self.inherit_branding(node, view_id, root_id) else: node.set('data-oe-id', str(view_id)) - node.set('data-oe-source-id', str(source_id)) + node.set('data-oe-source-id', str(root_id)) node.set('data-oe-xpath', xpath) node.set('data-oe-model', 'ir.ui.view') node.set('data-oe-field', 'arch') @@ -397,7 +397,7 @@ class view(osv.osv): return source - def apply_view_inheritance(self, cr, uid, source, source_id, model, context=None): + def apply_view_inheritance(self, cr, uid, source, source_id, model, root_id=None, context=None): """ Apply all the (directly and indirectly) inheriting views. :param source: a parent architecture to modify (with parent modifications already applied) @@ -408,13 +408,15 @@ class view(osv.osv): :return: a modified source where all the modifying architecture are applied """ if context is None: context = {} + if root_id is None: + root_id = source_id sql_inherit = self.pool.get('ir.ui.view').get_inheriting_views_arch(cr, uid, source_id, model, context=context) for (specs, view_id) in sql_inherit: specs_tree = etree.fromstring(specs.encode('utf-8')) if context.get('inherit_branding'): - self.inherit_branding(specs_tree, view_id, source_id) + self.inherit_branding(specs_tree, view_id, root_id) source = self.apply_inheritance_specs(cr, uid, source, specs_tree, view_id, context=context) - source = self.apply_view_inheritance(cr, uid, source, view_id, model, context=context) + source = self.apply_view_inheritance(cr, uid, source, view_id, model, root_id=root_id, context=context) return source def read_combined(self, cr, uid, view_id, fields=None, context=None): From ad86d1afdc168562637dfa19e309745f8b5b0dc2 Mon Sep 17 00:00:00 2001 From: Kersten Jeremy Date: Mon, 24 Feb 2014 11:47:45 +0100 Subject: [PATCH 023/417] [FIX] Remove unused field from crm for calendar. By consequence, bug with email attendee is removed. bzr revid: jke@openerp.com-20140224104745-egf6hutwzk9gcweh --- addons/crm/calendar_event.py | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/addons/crm/calendar_event.py b/addons/crm/calendar_event.py index df50d99b72b..4f57e364282 100644 --- a/addons/crm/calendar_event.py +++ b/addons/crm/calendar_event.py @@ -48,31 +48,11 @@ class calendar_attendee(osv.osv): _inherit = 'calendar.attendee' _description = 'Calendar Attendee' - def _compute_data(self, cr, uid, ids, name, arg, context=None): - """ - @param self: The object pointer - @param cr: the current row, from the database cursor, - @param uid: the current user’s ID for security checks, - @param ids: List of compute data’s IDs - @param context: A standard dictionary for contextual values - """ - name = name[0] - result = super(calendar_attendee, self)._compute_data(cr, uid, ids, name, arg, context=context) - - for attdata in self.browse(cr, uid, ids, context=context): - id = attdata.id - result[id] = {} - if name == 'categ_id': - if attdata.ref and 'categ_id' in attdata.ref._columns: - result[id][name] = (attdata.ref.categ_id.id, attdata.ref.categ_id.name,) - else: - result[id][name] = False - return result + def _noop(self, cr, uid, ids, name, arg, context=None): + return dict.fromkeys(ids,False) _columns = { - 'categ_id': fields.function(_compute_data, \ - string='Event Type', type="many2one", \ - relation="crm.case.categ", multi='categ_id'), + 'categ_id': fields.function(_noop, string='Event Type', deprecated="Unused Field - TODO : Remove it in trunk", type="many2one", relation="crm.case.categ"), } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From bfaa40266d9ea0dec15daf1c383bc4ade262bd28 Mon Sep 17 00:00:00 2001 From: Kersten Jeremy Date: Mon, 24 Feb 2014 11:48:50 +0100 Subject: [PATCH 024/417] [IMP] Calendar : Check that user are not disconnected before to check next_potential_notif, that avoid to see an error in console every 5 minutes bzr revid: jke@openerp.com-20140224104850-wty7kk230s72tdcy --- addons/calendar/calendar.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/addons/calendar/calendar.py b/addons/calendar/calendar.py index ca4d00eb85e..96c1e2b68e9 100644 --- a/addons/calendar/calendar.py +++ b/addons/calendar/calendar.py @@ -483,8 +483,12 @@ class calendar_alarm_manager(osv.AbstractModel): def get_next_notif(self,cr,uid,context=None): ajax_check_every_seconds = 300 - partner = self.pool.get('res.users').browse(cr,uid,uid,context=context).partner_id; + partner = self.pool.get('res.users').browse(cr, uid, uid, context=context).partner_id all_notif = [] + + if not partner or not partner.id: # If user is disconnected + return [] + all_events = self.get_next_potential_limit_alarm(cr,uid,ajax_check_every_seconds,partner_id=partner.id,mail=False,context=context) for event in all_events: # .values() From f94f50c7e86a444508b096c8e9693c8d22a7abb4 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 24 Feb 2014 12:05:54 +0100 Subject: [PATCH 025/417] [FIX] fixes a crash caused by incorrect use of date/datetime fields of the form 'date:interval': the list view in some case tried to format the strings as a date, and it could not parse it. lp bug: https://launchpad.net/bugs/1279382 fixed bzr revid: ged@openerp.com-20140224110554-y007810prx7qg5yi --- addons/web/static/src/js/data.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index cc595c30688..24a4dc3dd2a 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -221,11 +221,12 @@ instance.web.QueryGroup = instance.web.Class.extend({ {__context: {group_by: []}, __domain: []}, read_group_group); + var raw_field = grouping_field && grouping_field.split(':')[0]; var aggregates = {}; _(fixed_group).each(function (value, key) { if (key.indexOf('__') === 0 - || key === grouping_field - || key === grouping_field + '_count') { + || key === raw_field + || key === raw_field + '_count') { return; } aggregates[key] = value || 0; @@ -234,7 +235,6 @@ instance.web.QueryGroup = instance.web.Class.extend({ this.model = new instance.web.Model( model, fixed_group.__context, fixed_group.__domain); - var raw_field = grouping_field && grouping_field.split(':')[0]; var group_size = fixed_group[raw_field + '_count'] || fixed_group.__count || 0; var leaf_group = fixed_group.__context.group_by.length === 0; From bff00ec6df967f95b41493afb5c81aef1944e758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 24 Feb 2014 13:10:04 +0100 Subject: [PATCH 026/417] [FIX] res_partner: avoid duplicating users when duplicating partners, because I think your database wil hate you. bzr revid: tde@openerp.com-20140224121004-lgy2rsszsomy7mji --- openerp/addons/base/res/res_partner.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openerp/addons/base/res/res_partner.py b/openerp/addons/base/res/res_partner.py index e9573088680..46f0218e21f 100644 --- a/openerp/addons/base/res/res_partner.py +++ b/openerp/addons/base/res/res_partner.py @@ -350,6 +350,7 @@ class res_partner(osv.osv, format_address): def copy(self, cr, uid, id, default=None, context=None): if default is None: default = {} + default['user_ids'] = False name = self.read(cr, uid, [id], ['name'], context)[0]['name'] default.update({'name': _('%s (copy)') % name}) return super(res_partner, self).copy(cr, uid, id, default, context) From 60c75d38bfc948ed723cde3a00b1c3871ff89148 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Mon, 24 Feb 2014 15:27:51 +0100 Subject: [PATCH 027/417] [FIX] website placeholder; website_hr_recruitment required for ie bzr revid: chm@openerp.com-20140224142751-7bolxomy2nc717w0 --- addons/website/static/src/js/website.js | 3 +- .../controllers/main.py | 31 ++++++++++++++----- .../views/templates.xml | 15 ++++----- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/addons/website/static/src/js/website.js b/addons/website/static/src/js/website.js index 3be70b9b404..54ee4689814 100644 --- a/addons/website/static/src/js/website.js +++ b/addons/website/static/src/js/website.js @@ -69,7 +69,8 @@ website.is_editable = website.is_editable || $('html').data('editable'); website.is_editable_button= website.is_editable_button || $('html').data('editable'); dom_ready.resolve(); - $('input, textarea').placeholder(); + // fix for ie + if($.fn.placeholder) $('input, textarea').placeholder(); }); website.init_kanban = function ($kanban) { diff --git a/addons/website_hr_recruitment/controllers/main.py b/addons/website_hr_recruitment/controllers/main.py index c50bc6a0428..a3cbbe3cbc4 100644 --- a/addons/website_hr_recruitment/controllers/main.py +++ b/addons/website_hr_recruitment/controllers/main.py @@ -7,7 +7,6 @@ from openerp.tools.translate import _ from openerp.addons.web.http import request class website_hr_recruitment(http.Controller): - @http.route([ '/jobs', '/jobs/department/', @@ -61,27 +60,45 @@ class website_hr_recruitment(http.Controller): @http.route(['/jobs/apply/'], type='http', auth="public", website=True, multilang=True) def jobs_apply(self, job): - return request.website.render("website_hr_recruitment.apply", { 'job': job }) + error = {} + default = {} + if 'website_hr_recruitment_error' in request.session: + error = request.session.pop('website_hr_recruitment_error') + default = request.session.pop('website_hr_recruitment_default') + return request.website.render("website_hr_recruitment.apply", { 'job': job, 'error': error, 'default': default}) @http.route(['/jobs/thankyou'], methods=['POST'], type='http', auth="public", website=True, multilang=True) def jobs_thankyou(self, **post): cr, uid, context = request.cr, request.uid, request.context imd = request.registry['ir.model.data'] + + error = {} + for field_name in ["partner_name", "phone", "email_from"]: + if not post.get(field_name): + error[field_name] = 'missing' + if error: + request.session['website_hr_recruitment_error'] = error + ufile = post.pop('ufile') + if ufile: + error['ufile'] = 'reset' + request.session['website_hr_recruitment_default'] = post + return request.redirect('/jobs/apply/%s' % post.get("job_id")) + value = { - 'name': _('Online Form'), - 'user_id': False, 'source_id' : imd.xmlid_to_res_id(cr, SUPERUSER_ID, 'hr_recruitment.source_website_company'), } - for f in ['phone', 'email_from', 'partner_name', 'description', 'department_id', 'job_id']: + for f in ['phone', 'email_from', 'partner_name', 'description']: value[f] = post.get(f) + for f in ['department_id', 'job_id']: + value[f] = int(post.get(f) or 0) - job_id = request.registry['hr.applicant'].create(cr, SUPERUSER_ID, value, context=context) + applicant_id = request.registry['hr.applicant'].create(cr, SUPERUSER_ID, value, context=context) if post['ufile']: attachment_value = { 'name': post['ufile'].filename, 'res_name': value['partner_name'], 'res_model': 'hr.applicant', - 'res_id': job_id, + 'res_id': applicant_id, 'datas': base64.encodestring(post['ufile'].read()), 'datas_fname': post['ufile'].filename, } diff --git a/addons/website_hr_recruitment/views/templates.xml b/addons/website_hr_recruitment/views/templates.xml index 3e057d249f2..9dab6c6accc 100644 --- a/addons/website_hr_recruitment/views/templates.xml +++ b/addons/website_hr_recruitment/views/templates.xml @@ -161,34 +161,35 @@
-
+
- +
-
+
- +
-
+
- +
-
'); + else if (popupName === "pastetext") { + $popup.html('Paste your content here and click submit.

'); popupTypeClass = PROMPT_CLASS; } @@ -720,12 +734,12 @@ } // Execute the command and check for error - var success = true, description; - if (ie && command.toLowerCase() == "inserthtml") + var success = true, message; + if (ie && command.toLowerCase() === "inserthtml") getRange(editor).pasteHTML(value); else { try { success = editor.doc.execCommand(command, 0, value || null); } - catch (err) { description = err.description; success = false; } + catch (err) { message = err.message; success = false; } if (!success) { if ("cutcopypaste".indexOf(command) > -1) showMessage(editor, "For security reasons, your browser does not support the " + @@ -733,13 +747,14 @@ button); else showMessage(editor, - (description ? description : "Error executing the " + command + " command."), + (message ? message : "Error executing the " + command + " command."), button); } } - // Enable the buttons + // Enable the buttons and update the textarea refreshButtons(editor); + updateTextArea(editor, true); return success; } @@ -765,19 +780,26 @@ return editor.$frame[0].contentWindow.getSelection(); } - // Returns the hex value for the passed in string. - // hex("rgb(255, 0, 0)"); // #FF0000 - // hex("#FF0000"); // #FF0000 - // hex("#F00"); // #FF0000 + // hex - returns the hex value for the passed in color string function hex(s) { - var m = /rgba?\((\d+), (\d+), (\d+)/.exec(s), - c = s.split(""); + + // hex("rgb(255, 0, 0)") returns #FF0000 + var m = /rgba?\((\d+), (\d+), (\d+)/.exec(s); if (m) { - s = ( m[1] << 16 | m[2] << 8 | m[3] ).toString(16); + s = (m[1] << 16 | m[2] << 8 | m[3]).toString(16); while (s.length < 6) s = "0" + s; + return "#" + s; } - return "#" + (s.length == 6 ? s : c[1] + c[1] + c[2] + c[2] + c[3] + c[3]); + + // hex("#F00") returns #FF0000 + var c = s.split(""); + if (s.length === 4) + return "#" + c[1] + c[1] + c[2] + c[2] + c[3] + c[3]; + + // hex("#FF0000") returns #FF0000 + return s; + } // hidePopups - hides all popups @@ -792,9 +814,8 @@ // imagesPath - returns the path to the images folder function imagesPath() { - var cssFile = "jquery.cleditor.css", - href = $("link[href$='" + cssFile +"']").attr("href"); - return href.substr(0, href.length - cssFile.length) + "images/"; + var href = $("link[href*=cleditor]").attr("href"); + return href.replace(/^(.*\/)[^\/]+$/, '$1') + "images/"; } // imageUrl - Returns the css url string for a filemane @@ -813,7 +834,7 @@ editor.$frame.remove(); // Create a new iframe - var $frame = editor.$frame = $(' diff --git a/addons/website_customer/controllers/main.py b/addons/website_customer/controllers/main.py index 173b0871dbe..5f0825e132c 100644 --- a/addons/website_customer/controllers/main.py +++ b/addons/website_customer/controllers/main.py @@ -12,12 +12,12 @@ class WebsiteCustomer(http.Controller): _references_per_page = 20 @http.route([ - '/customers/', - '/customers/page//', + '/customers', + '/customers/page/', '/customers/country/', '/customers/country/-', - '/customers/country//page//', - '/customers/country/-/page//', + '/customers/country//page/', + '/customers/country/-/page/', ], type='http', auth="public", website=True, multilang=True) def customers(self, country_id=0, page=0, **post): cr, uid, context = request.cr, request.uid, request.context @@ -62,7 +62,7 @@ class WebsiteCustomer(http.Controller): # pager pager = request.website.pager( - url="/customers/", total=len(partner_ids), page=page, step=self._references_per_page, + url="/customers", total=len(partner_ids), page=page, step=self._references_per_page, scope=7, url_args=post ) @@ -83,7 +83,7 @@ class WebsiteCustomer(http.Controller): } return request.website.render("website_customer.index", values) - @http.route(['/customers//', '/customers/-/'], type='http', auth="public", website=True, multilang=True) + @http.route(['/customers/', '/customers/-'], type='http', auth="public", website=True, multilang=True) def customer(self, partner_id, **post): partner = request.registry['res.partner'].browse(request.cr, SUPERUSER_ID, partner_id, context=request.context) values = website_partner.get_partner_template_value(partner) diff --git a/addons/website_customer/views/website_customer.xml b/addons/website_customer/views/website_customer.xml index ad924cba55d..ba89f456e23 100644 --- a/addons/website_customer/views/website_customer.xml +++ b/addons/website_customer/views/website_customer.xml @@ -5,7 +5,7 @@ @@ -44,11 +44,11 @@ @@ -158,11 +158,11 @@

References

- +
- +
diff --git a/addons/website_event/controllers/main.py b/addons/website_event/controllers/main.py index eb38e2dbe55..c410536a0b5 100644 --- a/addons/website_event/controllers/main.py +++ b/addons/website_event/controllers/main.py @@ -33,7 +33,7 @@ from openerp import tools import werkzeug.urls class website_event(http.Controller): - @http.route(['/event/', '/event/page/'], type='http', auth="public", website=True, multilang=True) + @http.route(['/event', '/event/page/'], type='http', auth="public", website=True, multilang=True) def events(self, page=1, **searches): cr, uid, context = request.cr, request.uid, request.context event_obj = request.registry['event.event'] @@ -134,7 +134,7 @@ class website_event(http.Controller): event_count = event_obj.search( request.cr, request.uid, dom_without("none"), count=True, context=request.context) - pager = request.website.pager(url="/event/", total=event_count, page=page, step=step, scope=5) + pager = request.website.pager(url="/event", total=event_count, page=page, step=step, scope=5) order = 'website_published desc, date_begin' if searches.get('date','all') == 'old': diff --git a/addons/website_event/views/website_event.xml b/addons/website_event/views/website_event.xml index e490b1a0687..1096287bb3b 100644 --- a/addons/website_event/views/website_event.xml +++ b/addons/website_event/views/website_event.xml @@ -50,7 +50,7 @@
  • - + not published

    @@ -243,7 +243,7 @@

    Event not found!

    Sorry, the requested event is not available anymore.

    -

    Return to the event list.

    +

    Return to the event list.

    diff --git a/addons/website_event_sale/controllers/main.py b/addons/website_event_sale/controllers/main.py index cc9ddc0ad56..2db874cf5b7 100644 --- a/addons/website_event_sale/controllers/main.py +++ b/addons/website_event_sale/controllers/main.py @@ -78,7 +78,7 @@ class website_event(website_event): order_obj.write(request.cr, SUPERUSER_ID, [order.id], {'order_line': [(4, order_line_id)]}, context=request.context) if not _values: - return request.redirect("/event/%s/" % event_id) + return request.redirect("/event/%s" % event_id) return request.redirect("/shop/checkout") def _add_event(self, event_name="New Event", context={}, **kwargs): diff --git a/addons/website_event_sale/static/src/js/website.tour.event_sale.js b/addons/website_event_sale/static/src/js/website.tour.event_sale.js index 3c74cc2317e..c67c412d7d2 100644 --- a/addons/website_event_sale/static/src/js/website.tour.event_sale.js +++ b/addons/website_event_sale/static/src/js/website.tour.event_sale.js @@ -44,7 +44,7 @@ { title: "Complete checkout", waitFor: '#top_menu .my_cart_quantity:contains(5)', - element: 'form[action="/shop/confirm_order/"] .btn:contains("Confirm")', + element: 'form[action="/shop/confirm_order"] .btn:contains("Confirm")', onload: function (tour) { if ($("input[name='name']").val() === "") $("input[name='name']").val("website_sale-test-shoptest"); diff --git a/addons/website_event_track/controllers/event.py b/addons/website_event_track/controllers/event.py index d4b7177814d..466e3d37a40 100644 --- a/addons/website_event_track/controllers/event.py +++ b/addons/website_event_track/controllers/event.py @@ -38,7 +38,7 @@ class website_event(http.Controller): return request.website.render("website_event_track.track_view", values) # TODO: not implemented - @http.route(['/event//agenda/'], type='http', auth="public", website=True, multilang=True) + @http.route(['/event//agenda'], type='http', auth="public", website=True, multilang=True) def event_agenda(self, event, tag=None, **post): values = { 'event': event, @@ -47,7 +47,7 @@ class website_event(http.Controller): return request.website.render("website_event_track.agenda", values) @http.route([ - '/event//track/', + '/event//track', '/event//track/tag/' ], type='http', auth="public", website=True, multilang=True) def event_tracks(self, event, tag=None, **post): @@ -74,7 +74,7 @@ class website_event(http.Controller): } return request.website.render("website_event_track.tracks", values) - @http.route(['/event//track_proposal/'], type='http', auth="public", website=True, multilang=True) + @http.route(['/event//track_proposal'], type='http', auth="public", website=True, multilang=True) def event_track_proposal(self, event, **post): values = { 'event': event } return request.website.render("website_event_track.event_track_proposal", values) diff --git a/addons/website_event_track/models/event.py b/addons/website_event_track/models/event.py index cfba63cfc6b..1c098232a2e 100644 --- a/addons/website_event_track/models/event.py +++ b/addons/website_event_track/models/event.py @@ -142,12 +142,12 @@ class event_event(osv.osv): context = context or {} result = super(event_event, self)._get_new_menu_pages(cr, uid, event, context=context) if event.show_tracks: - result.append( (_('Talks'), '/event/%s/track/' % slug(event))) - result.append( (_('Agenda'), '/event/%s/agenda/' % slug(event))) + result.append( (_('Talks'), '/event/%s/track' % slug(event))) + result.append( (_('Agenda'), '/event/%s/agenda' % slug(event))) if event.blog_id: - result.append( (_('News'), '/blogpost/'+slug(event.blog_ig))) + result.append( (_('News'), '/blogpost'+slug(event.blog_ig))) if event.show_track_proposal: - result.append( (_('Talk Proposals'), '/event/%s/track_proposal/' % slug(event))) + result.append( (_('Talk Proposals'), '/event/%s/track_proposal' % slug(event))) return result # diff --git a/addons/website_event_track/views/website_event.xml b/addons/website_event_track/views/website_event.xml index 03f6f750b6f..3eb2a4bbbde 100644 --- a/addons/website_event_track/views/website_event.xml +++ b/addons/website_event_track/views/website_event.xml @@ -174,7 +174,7 @@