From 987b54fde3531e4eb9c546f5b27b26cf4bb74acb Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Wed, 1 Mar 2017 18:23:19 +0100 Subject: [PATCH 01/36] [FIX] base: create user not from company_id=1 In new API conversion (7eab8e26d3d) a SUPERUSER_ID was dropped hence we could get an error instead of the default groups_id of a res.users (if the user has no read permission for `default user`). opw-687521 --- openerp/addons/base/res/res_users.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/addons/base/res/res_users.py b/openerp/addons/base/res/res_users.py index becd0a86a6e..06040b91db9 100644 --- a/openerp/addons/base/res/res_users.py +++ b/openerp/addons/base/res/res_users.py @@ -181,7 +181,7 @@ class Users(models.Model): def _default_groups(self): default_user = self.env.ref('base.default_user', raise_if_not_found=False) - return (default_user or self.env['res.users']).groups_id + return (default_user or self.env['res.users']).sudo().groups_id def _companies_count(self): return self.env['res.company'].sudo().search_count([]) From 2b8605c6e21a3b6fceb20352295e8148df69cbd8 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 1 Mar 2017 18:39:34 +0100 Subject: [PATCH 02/36] [FIX] google_drive: show icon via css instead of injecting html --- .../static/src/css/google_drive.css | 5 +++++ .../static/src/img/drive_icon.png | Bin 2148 -> 1542 bytes addons/google_drive/static/src/js/gdrive.js | 4 ++-- addons/google_drive/views/google_drive.xml | 1 + 4 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 addons/google_drive/static/src/css/google_drive.css diff --git a/addons/google_drive/static/src/css/google_drive.css b/addons/google_drive/static/src/css/google_drive.css new file mode 100644 index 00000000000..ce2b22599b0 --- /dev/null +++ b/addons/google_drive/static/src/css/google_drive.css @@ -0,0 +1,5 @@ +li.oe_share_gdoc > a:after { + content: url('/google_drive/static/src/img/drive_icon.png'); + position: absolute; + right: 5px; +} diff --git a/addons/google_drive/static/src/img/drive_icon.png b/addons/google_drive/static/src/img/drive_icon.png index 590dde867f4bd46b2d836b9e5e8a8e2940b13ff0..1553aa319a672a99e77433287df3e5086ce58a32 100644 GIT binary patch literal 1542 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VV{wqX6T`Z5GB1G~&H|6fVg?3o zVGw3ym^DWNs30;kB%&n3*T*V3KUXg?B|j-uuOhbqsG5Pnrosxy%uOvxRH(?!$t$+1 zuvG%9umZ9{!um=IU?nBlwn`Dc0SeCfMX3s=dM0`XN_Jcd3JNwwDQQ+gE^bimK%T8q zMoCG5mA-y?dAVM>v0i>ry1t>MrKP@sk-m|UE>MMTab;dfVufyAu`tKo-FP#GNIXX$YJ0ilN>DdQcxEqi?8Zpbs}2sMQ7}YUN*) znF_QSWWJrD4Ok_L7}OpceURlyj)C|TEDH3h9hZ$hJlO2Gd=9BcGBB{XdAc};SO`uH ziOq;{6|sAM=FHym_i2;Weq8oYirRWZKG>`KsMpd(KNjikTax4}pmU?iN$}&s+9(mN zjDzwM95UCk1)4l)Uf}A|`GYz1(z2!7LXIXm-j2xHbk}#&_j7YC=iOAf;ZXbG4PW`Q zJI43_KC4ORJ7C%)`9bQP>$?A47rPfd6Yn?>U-Rw3E#9YY^I1$Bg|#Z5OGr-j68Twp zB;TLqfb`IY)(AC=i(ukc^rS0?biI>weC%w{H^KrKeA6ocF##?h!j3(^=Q#Cy;mLKPhOO7 z|29wV;p+bX`U$0*g*@7vnX~nn?U?T!ygc2jX4^cclnIV23t|#iNffat{muFI_}SG6 zR{q7C%I`g6m?^kwvFnGag5Ul{_F2CRiM!@jU$C&r_+G)9ttn>|CS5u=@$%Fa!HHYc z-yHny-px9#xPiTF+YwKGew$NW+orB*<_swb_B^;R>SX`bQ!G(}lfJF!nP8$3#CrSQ zpN9)|*WSFbON`A?An7?H_u=ML%j0rd?h6FDR(D*QAu*}r-rgH#QzK)8XSFo^Xj%R} zKts@D;r+wU&D3|)oiX~Z-E?_%)TZf-Wr11mj@{WL)BU6%Abi$zUC##rx>bgK4^%Ze zZ!w%{Qgd^?+vN8`&YID>nc1yrQ_{%~57x5$*y`o0FJ?Ev_{qVbNi$x*y1CN0+4l8} z{-iP;JF)O9UiNplFx;yMkI21|a{1@aNWFKj_k90-KiblT|9rCLtEX!;o^ZQ)SR`g% zFfviN#U5~0us@|Y?MqSJQAcCt%V(yP`^~PI*0m#O*UcZNiW_Cr-rIa+FsSpI*tOJR zPKxKJ1#`RtZ@#(n@KQrvSt;I9a zKgmo`N=sUvK6U1+#(Txqr*e0{uVB>Pwn;_n^YgRcj$QcSzch62amCGHqO2YzicvrJ ztX{m<#P)85%;V}_&-V4ENMZt`UN)oW|FcQj=yriTagYHj^`;p6RN3TBfH=Q&-iQdf8r zTyR61tIWGDZ%X&pkc8cjH$|N~+brI`D}J^x>qpTQxA*TUl*&oE{qM$sC$}Xp7rib! zvsKt}BHzKF_Ddy4u1bmdrsUX_Dz?4+t9YK}s#dD?J?n0ny@4-0BR+jso9lB=FQM~J z&cYXSMGPl@p4V0IJVk_WgFwi`9GO=auEp8^dX~H2VXE`f{%sLv)A#-jv)Y-or}&v* zNa6IDtuA)cInuP08TCIiDQhh>wOWahpT>atF^WjTt3Geyi{_oyfZEX;I@XV)gpTXbz=N&Tc a{bTe@yp`pA=;$L*;q2+^=d#Wzp$Pz)@1@EB literal 2148 zcmV-q2%GnbP)Mwm4`kVS#<|WZ|&Ja z)7Sg^{(x6EwE!{Ccy2hdr(yVDgw5q`A5X6~gvQm&p}BteWj@L^9@9aOpn>K-nseX- zaB@{^fTG`^scsE^@yrHD6pEB_U=0@f=bgdA4eS|MZ+~9jy($in@im%8UBCsx$tzW8 zwkkp7A@@A%jLkxNKE7HRc!|bW0%ZLBWWCngg&RAdwZ@AKKP?(jPY!Q;Njx1 zFGLTmnhr5~LmjA2?p1}m#YJ9NMCpeMedTnMc#0l$_EYg-{opao9e_p37G;T;I z?wi`Hit03t8f&hA61_xFFMoCcI|`mMy3m%3e8y`i|}+ z*x*aRdXGR2m2?&wMyeh}>VRe&1*yw2f;VUT0x{c!l?e`xdowT#QECk_-AMHgXMuq3 zAQ%qA_M8lmon-0V1xcSVQBRT>lrxv+W4JKafw{|Fm^az+br3p2fAy=MY-8u4_Z9Kw@O5 zmJo^s^?VuD1b`xit$o{1wuFiJD7{e&BJ3&5r_{p7;nifJ8@FUPS;pRu9HWf2Y$np| z(Yb%U>NgkS zk=Ap^CYH03n*E@DfQ%khyBU%UOQgvL-O!Ip3<_kL0c2!XAn9JDLGxxT9~xA0;X`hC zj}zcE7zV%r=s&vyZaMd;(?EKWg66sag;F)3E(u-(-MjwVbUQ{x-9kw@AlKCJKG4&uqzrhw3vUjz$;uAD^a29}EgOX!)Er^(f8V1LceNIEu4Q zU{nH8?DLBst5gH!D#HCC@Sn5w<{%8bXI-zc(@R!@;{+%iftQy|w3SC9xIeH-7&D6gnHo_^J~nd>h3|2)l18IQQo?BVJe5 zLCGbBmlDnIUcY_kN_Xbcf?hwn4T{~{T;zial#(?*uV)fwn1)WmWJ40XFFAxbd^A4C zR=lxAP->Ru?>KSG%r4I~i$qa+y!vR`ArlWFYkU$yE0E`YjXXusZ(ein?dJbV+;rf7 a?!aG7`ph;%20c*#0000', + label: res.name, config_id: res.id, res_id: res_id, res_model: view.dataset.model, @@ -73,4 +73,4 @@ openerp.google_drive = function (instance, m) { }, }); -}; \ No newline at end of file +}; diff --git a/addons/google_drive/views/google_drive.xml b/addons/google_drive/views/google_drive.xml index 5017f53f1a8..0f9887e1602 100644 --- a/addons/google_drive/views/google_drive.xml +++ b/addons/google_drive/views/google_drive.xml @@ -5,6 +5,7 @@ From 2971ffb70ee0235b11c7683c31d50eb7389ce062 Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Wed, 1 Mar 2017 14:09:48 +0100 Subject: [PATCH 03/36] [FIX] website_slides: Unpublished slides not visible The rules "Channel: public: published only" and "Slide: public: published only" must also be applied on portal user. The portal user doesnt have to be allowed to create or write on slide.slide records(introduced by 51be5bb). opw:708499 --- addons/website_slides/security/ir.model.access.csv | 2 +- addons/website_slides/security/website_slides_security.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/website_slides/security/ir.model.access.csv b/addons/website_slides/security/ir.model.access.csv index 39d871b2863..07d087f7db9 100644 --- a/addons/website_slides/security/ir.model.access.csv +++ b/addons/website_slides/security/ir.model.access.csv @@ -1,6 +1,6 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_slide_slide_public,slide.slide.public,model_slide_slide,base.group_public,1,0,0,0 -access_slide_slide_portal,slide.slide.portal,model_slide_slide,base.group_portal,1,1,1,0 +access_slide_slide_portal,slide.slide.portal,model_slide_slide,base.group_portal,1,0,0,0 access_slide_slide_user,slide.slide.user,model_slide_slide,base.group_user,1,1,1,1 access_slide_tag_public,slide.tag.public,model_slide_tag,base.group_public,1,0,0,0 access_slide_tag_portal,slide.tag.portal,model_slide_tag,base.group_portal,1,0,0,0 diff --git a/addons/website_slides/security/website_slides_security.xml b/addons/website_slides/security/website_slides_security.xml index c34ab413263..1b09a2955bb 100644 --- a/addons/website_slides/security/website_slides_security.xml +++ b/addons/website_slides/security/website_slides_security.xml @@ -17,7 +17,7 @@ Channel: public: published only - + [('website_published', '=', True)] @@ -36,7 +36,7 @@ Slide: public: published only - + [('channel_id.website_published', '=', True), ('website_published', '=', True)] From 2d199ed460553856c8c2a65524dba28719d9d96b Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Thu, 2 Mar 2017 10:35:43 +0100 Subject: [PATCH 04/36] [FIX] stock: do not compute unrelevant inventory quantity The total quantity of an inventory only makes sense if the same product is counted. This commit avoids useless recompute of the field when a ligne is changed. The trigger were missing meaning it was recomputed after any change, slowing down already unefficiant large inventory. --- addons/stock/models/stock_inventory.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/addons/stock/models/stock_inventory.py b/addons/stock/models/stock_inventory.py index f6c36541990..5cc88ee7237 100644 --- a/addons/stock/models/stock_inventory.py +++ b/addons/stock/models/stock_inventory.py @@ -88,8 +88,13 @@ class Inventory(models.Model): exhausted = fields.Boolean('Include Exhausted Products', readonly=True, states={'draft': [('readonly', False)]}) @api.one + @api.depends('product_id', 'line_ids.product_qty') def _compute_total_qty(self): - self.total_qty = sum(self.mapped('line_ids').mapped('product_qty')) + """ For single product inventory, total quantity of the counted """ + if self.product_id: + self.total_qty = sum(self.mapped('line_ids').mapped('product_qty')) + else: + self.total_qty = 0 @api.model def _selection_filter(self): From 28ea1bcb5a5e5f9349b6c03310504c3bfd2abd0a Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 2 Mar 2017 12:40:45 +0100 Subject: [PATCH 05/36] [FIX] product_visible_discount: recursive show discount MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a pricelist PL1 set with the discount policy `Show discount in the sale order` was based on another pricelist PL2 with the same discount policy, the discount applied by the second pricelist PL2 was set directly in the price, rather to be displayed as a discount. e.g. PL 1: 10% on all products, show discount PL 2: 15% on all prices of the PL1 pricelist, show discount The discount displayed on the sales order should be 100 − (100 × (1−0,15) × (1−0,10)) = 23.5% And the unit price of the product must remain the initial price of the product, not the discounted price. opw-709708 --- .../product_visible_discount/product_visible_discount.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/addons/product_visible_discount/product_visible_discount.py b/addons/product_visible_discount/product_visible_discount.py index 91ecccc380d..358e14d0abb 100644 --- a/addons/product_visible_discount/product_visible_discount.py +++ b/addons/product_visible_discount/product_visible_discount.py @@ -28,7 +28,12 @@ class sale_order_line(osv.osv): else: rule_id = False if rule_id: + pricelist_context = dict(context, uom=uom) item = item_obj.browse(cr, uid, rule_id, context=context) + if item.pricelist_id.discount_policy == 'without_discount': + while item.base == 'pricelist' and item.base_pricelist_id and item.base_pricelist_id.discount_policy == 'without_discount': + price, rule_id = item.base_pricelist_id.with_context(pricelist_context).price_rule_get(product_id, qty, context.get('partner_id'))[item.base_pricelist_id.id] + item = item_obj.browse(cr, uid, rule_id, context=context) if item.base == 'standard_price': field_name = 'standard_price' if item.base == 'pricelist' and item.base_pricelist_id: @@ -67,7 +72,7 @@ class sale_order_line(osv.osv): pricelist_context = dict(context_partner, uom=line.product_uom.id, date=line.order_id.date_order) list_price_dict = line.order_id.pricelist_id.with_context(pricelist_context).price_rule_get(line.product_id.id, line.product_uom_qty or 1.0, line.order_id.partner_id) list_price = list_price_dict[line.order_id.pricelist_id.id][0] - new_list_price, currency_id = line.with_context(context_partner)._get_real_price_currency(line.product_id.id, list_price_dict, line.product_uom_qty, line.product_uom.id, line.order_id.pricelist_id.id) + new_list_price, currency_id = line.with_context(dict(context_partner, date=line.order_id.date_order))._get_real_price_currency(line.product_id.id, list_price_dict, line.product_uom_qty, line.product_uom.id, line.order_id.pricelist_id.id) new_list_price = self.env['account.tax']._fix_tax_included_price(new_list_price, line.product_id.taxes_id, line.tax_id) if line.order_id.pricelist_id.discount_policy == 'without_discount' and list_price != 0 and new_list_price != 0: if line.product_id.company_id and line.order_id.pricelist_id.currency_id.id != line.product_id.company_id.currency_id.id: @@ -97,7 +102,7 @@ class sale_order_line(osv.osv): pricelist_context = dict(context_partner, uom=self.product_uom.id, date=self.order_id.date_order) list_price_dict = self.order_id.pricelist_id.with_context(pricelist_context).price_rule_get(self.product_id.id, self.product_uom_qty or 1.0, self.order_id.partner_id) list_price = list_price_dict[self.order_id.pricelist_id.id][0] - new_list_price, currency_id = self.with_context(context_partner)._get_real_price_currency(self.product_id.id, list_price_dict, self.product_uom_qty, self.product_uom.id, self.order_id.pricelist_id.id) + new_list_price, currency_id = self.with_context(dict(context_partner, date=self.order_id.date_order))._get_real_price_currency(self.product_id.id, list_price_dict, self.product_uom_qty, self.product_uom.id, self.order_id.pricelist_id.id) new_list_price = self.env['account.tax']._fix_tax_included_price(new_list_price, self.product_id.taxes_id, self.tax_id) if self.order_id.pricelist_id.discount_policy == 'without_discount' and list_price != 0 and new_list_price != 0: if self.product_id.company_id and self.order_id.pricelist_id.currency_id.id != self.product_id.company_id.currency_id.id: From a9b8bbac48aec808eb69a5a0e87af5bccb6906c3 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 2 Mar 2017 15:12:50 +0100 Subject: [PATCH 06/36] [FIX] point_of_sale: re-print order invoice for pos users only If a user has as access right the POS User only, it wasn't possible for him to re-print the invoice of a pos order, through the "re-print" button in the "Extra Info" tab of the pos orders. opw-710163 --- addons/point_of_sale/report/pos_invoice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/point_of_sale/report/pos_invoice.py b/addons/point_of_sale/report/pos_invoice.py index 9ae226d4c56..71627f77682 100644 --- a/addons/point_of_sale/report/pos_invoice.py +++ b/addons/point_of_sale/report/pos_invoice.py @@ -24,4 +24,4 @@ class PosInvoiceReport(models.AbstractModel): not_invoiced_orders_names = list(map(lambda a: a.name, not_invoiced_posorders)) raise UserError(_('No link to an invoice for %s.') % ', '.join(not_invoiced_orders_names)) - return Report.sudo().render('account.report_invoice', {'docs': self.env['account.invoice'].browse(ids_to_print)}) + return Report.sudo().render('account.report_invoice', {'docs': self.env['account.invoice'].sudo().browse(ids_to_print)}) From 2e467a7c0c6e55c616e5edb4f3d331ed58cb0a5c Mon Sep 17 00:00:00 2001 From: Yannick Tivisse Date: Thu, 2 Mar 2017 15:29:59 +0100 Subject: [PATCH 07/36] [FIX] sale: Set the default tax display at 'Tax Excluded' --- addons/sale/models/sale_config_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sale/models/sale_config_settings.py b/addons/sale/models/sale_config_settings.py index ebb69208465..d934772c921 100644 --- a/addons/sale/models/sale_config_settings.py +++ b/addons/sale/models/sale_config_settings.py @@ -51,7 +51,7 @@ class SaleConfiguration(models.TransientModel): sale_show_tax = fields.Selection([ ('subtotal', 'Tax-Included Prices'), ('total', 'Tax-Excluded Prices')], "Tax Display", - default='subtotal', + default='total', required=True) default_invoice_policy = fields.Selection([ ('order', 'Ordered quantities'), From 95d32633383c4af7a26a9e4a4376c5bc3a6f0de8 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 2 Mar 2017 17:53:00 +0100 Subject: [PATCH 08/36] [FIX] web_editor: change of iframe URL on record loaded When changing of record, through the pager or the breadcrumb, the URL of the iframe must change, as the model and id of the record is included in the URL This wasn't done before this revision, and it could lead to an INTERNAL SERVER ERROR in case of a deletion followed by the loading of another record: the URL of the iframe was still set to the former record, and this URL crashed as the record no longer existed. e.g. - Create a new mass mailing, subject 1, add a random block in the content then save - From this newly created mass mailing, Create a new mass mailing (directly with the create button) Subject 2, add a random black in the content and save - Delete the second mass mailing - Return in the mass mailing kanban view through the breadcrumb - Open the mass mailing 1 - You had an internel server error, due to the fact the URL of the iframe was still the one of the second mass mailing. opw-710239 --- addons/web_editor/static/src/js/backend.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/addons/web_editor/static/src/js/backend.js b/addons/web_editor/static/src/js/backend.js index 025a09f3d83..87407bdfd64 100644 --- a/addons/web_editor/static/src/js/backend.js +++ b/addons/web_editor/static/src/js/backend.js @@ -285,6 +285,7 @@ var FieldTextHtml = widget.extend({ return src; }, initialize_content: function() { + var self = this; this.$el.closest('.modal-body').css('max-height', 'none'); this.$iframe = this.$el.find('iframe'); this.document = null; @@ -293,6 +294,14 @@ var FieldTextHtml = widget.extend({ this.editor = false; window.odoo[this.callback+"_updown"] = null; this.$iframe.attr("src", this.get_url()); + this.view.on("load_record", this, function(r){ + if (!self.$body.find('.o_dirty').length){ + var url = self.get_url(); + if(url !== self.$iframe.attr("src")){ + self.$iframe.attr("src", url); + } + } + }); }, on_content_loaded: function () { var self = this; From 9f62be8387c76633dc84229c6f768c1ab6293b13 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 2 Mar 2017 18:45:29 +0100 Subject: [PATCH 09/36] [FIX] point_of_sale: sale details datetime in user UTC and lang format The time in the sales details were in the UTC timezone, instead of the user timezone, which confused the user Besides, the datetime was formatted in the database format, rather than in the language format opw-710290 --- addons/point_of_sale/views/report_saledetails.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/point_of_sale/views/report_saledetails.xml b/addons/point_of_sale/views/report_saledetails.xml index 888eab47217..c7cb58c6c4f 100644 --- a/addons/point_of_sale/views/report_saledetails.xml +++ b/addons/point_of_sale/views/report_saledetails.xml @@ -9,7 +9,7 @@

Sale Details

- - + -
From 2580a6d04d4296fc3ed9a2b896f79c136b42cc91 Mon Sep 17 00:00:00 2001 From: bluesoft83 Date: Fri, 3 Mar 2017 08:15:06 +0100 Subject: [PATCH 10/36] [CLA] signature for bluesoft83 Done at #15705 --- doc/cla/individual/bluesoft83.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 doc/cla/individual/bluesoft83.md diff --git a/doc/cla/individual/bluesoft83.md b/doc/cla/individual/bluesoft83.md new file mode 100644 index 00000000000..e8caabb578a --- /dev/null +++ b/doc/cla/individual/bluesoft83.md @@ -0,0 +1,11 @@ +Bosnia and Herzegovina, 2017-03-02 + +I hereby agree to the terms of the Odoo Individual Contributor License +Agreement v1.0. + +I declare that I am authorized and able to make this agreement and sign this +declaration. + +Signed, + +Boško Stojaković bluesoft83@gmail.com https://github.com/bluesoft83 From b3fa61c7c57c5b17b637180dd0a4ae6ada5a6f79 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Fri, 3 Mar 2017 08:28:14 +0100 Subject: [PATCH 11/36] [FIX] hr_timesheet_attendance: remove trailing parenthesis In the error message, bad migration --- addons/hr_timesheet_attendance/i18n/hr_timesheet_attendance.pot | 2 +- addons/hr_timesheet_attendance/models/hr_timesheet_sheet.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/hr_timesheet_attendance/i18n/hr_timesheet_attendance.pot b/addons/hr_timesheet_attendance/i18n/hr_timesheet_attendance.pot index e79805dff73..a29b7061412 100644 --- a/addons/hr_timesheet_attendance/i18n/hr_timesheet_attendance.pot +++ b/addons/hr_timesheet_attendance/i18n/hr_timesheet_attendance.pot @@ -108,7 +108,7 @@ msgstr "" #. module: hr_timesheet_attendance #: code:addons/hr_timesheet_attendance/models/hr_timesheet_sheet.py:85 #, python-format -msgid "The timesheet cannot be validated as it contains an attendance record with no Check Out)." +msgid "The timesheet cannot be validated as it contains an attendance record with no Check Out." msgstr "" #. module: hr_timesheet_attendance diff --git a/addons/hr_timesheet_attendance/models/hr_timesheet_sheet.py b/addons/hr_timesheet_attendance/models/hr_timesheet_sheet.py index 965789a35ed..edb11786749 100644 --- a/addons/hr_timesheet_attendance/models/hr_timesheet_sheet.py +++ b/addons/hr_timesheet_attendance/models/hr_timesheet_sheet.py @@ -82,7 +82,7 @@ class HrTimesheetSheet(models.Model): """ self.ensure_one() if any(self.attendances_ids.filtered(lambda r: not r.check_out)): - raise UserError(_("The timesheet cannot be validated as it contains an attendance record with no Check Out).")) + raise UserError(_("The timesheet cannot be validated as it contains an attendance record with no Check Out.")) return True From bf8cc11e7e8bae4b3c49e5cb76a1556a6abfdea6 Mon Sep 17 00:00:00 2001 From: Leonardo Rochael Almeida Date: Fri, 30 Dec 2016 11:13:34 -0200 Subject: [PATCH 12/36] [FIX] web: QUnit context in js tests Previously, the context for `options.{before,after}Each()` functions was isolated from the context created by the odoo `test` function, making it impossible to save attributes in the test during `options.beforeEach()` that are accessible from the test itself, or to clear resources created in the test in `options.afterEach()` Moreover, the odoo test infrastructure was set up completely inside the test wrapper, after `options.beforeContext()` had already run, making it impossible for `options.beforeContext()` to use this infrastructure. Here we use the QUnit context directly in the test, but move the initialization previously done in the test wrapper to a `beforeEach` wrapper (and, symetrically, on `afterEach`), making it possible to use the odoo infrastructure in the javascript test setup, including declared section dependencies. --- addons/web/static/test/testing.js | 41 +++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/addons/web/static/test/testing.js b/addons/web/static/test/testing.js index 2ec911740b2..46368c38259 100644 --- a/addons/web/static/test/testing.js +++ b/addons/web/static/test/testing.js @@ -81,8 +81,33 @@ odoo.define_section = function (name, section_deps) { section_body = arguments[3]; } - QUnit.module(name, options); + mock = new odoo.testing.MockRPC(); + function dummyfunc () {}; + + function beforeEach(assert) { + var services = odoo.testing.start_services(); + this.deps = services; + this.getServiceDeps = function getServiceDeps(dep_names) { + return _.map(dep_names, function (name) { return services[name]; }) + } + services['web.core'].qweb.add_template(odoo.testing.templates); + this.mock = mock; + this.mock.interceptRPC(services['web.session']); + this.assert = assert; + (options.beforeEach || dummyfunc).apply(this, [assert].concat(this.getServiceDeps(section_deps))); + } + function afterEach(assert) { + (options.afterEach || dummyfunc).apply(this, [assert].concat(this.getServiceDeps(section_deps))); + this.mock.clear(); + } + + QUnit.module(name, { + before: options.before, + beforeEach: beforeEach, + afterEach: afterEach, + after: options.after + }); function test () { var name = arguments[0], @@ -90,21 +115,11 @@ odoo.define_section = function (name, section_deps) { body = arguments[arguments.length - 1]; QUnit.test(name, function (assert) { - var services = odoo.testing.start_services(); - var deps = _.map(section_deps.concat(dep_names), function (name) { return services[name]; }); - services['web.core'].qweb.add_template(odoo.testing.templates); - mock.clear(); - mock.interceptRPC(services['web.session']); - var info = { - assert: assert, - mock: mock, - deps: _.pick.apply(null, [services].concat(section_deps).concat(dep_names)), - } - return body.apply(info, [assert].concat(deps)); + var deps = this.getServiceDeps(section_deps.concat(dep_names)); + return body.apply(this, [assert].concat(deps)); }); } - var mock = new odoo.testing.MockRPC(); section_body(test, mock); }; From 6eb15a6263dea13e91ed4ffa7a0a43742748cc87 Mon Sep 17 00:00:00 2001 From: Leonardo Rochael Almeida Date: Fri, 30 Dec 2016 10:53:41 -0200 Subject: [PATCH 13/36] [IMP] web: Remove tiny code duplication --- addons/web/static/test/testing.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/static/test/testing.js b/addons/web/static/test/testing.js index 46368c38259..927ca512060 100644 --- a/addons/web/static/test/testing.js +++ b/addons/web/static/test/testing.js @@ -16,7 +16,7 @@ odoo.testing.start_services = function () { }; odoo.testing.MockRPC = function (session) { - this.responses = {}; + this.clear(); }; odoo.testing.MockRPC.prototype.clear = function () { From 2b5e879957341d8f6fe5bfda886754d04ea737ff Mon Sep 17 00:00:00 2001 From: Leonardo Rochael Almeida Date: Fri, 30 Dec 2016 10:50:34 -0200 Subject: [PATCH 14/36] [IMP] web: Enhance registry.js tests Make sure we're really setting and getting registry values instead of just `undefined` values. --- addons/web/static/test/registry.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/addons/web/static/test/registry.js b/addons/web/static/test/registry.js index 132444c332a..58996837ec6 100644 --- a/addons/web/static/test/registry.js +++ b/addons/web/static/test/registry.js @@ -1,8 +1,8 @@ odoo.define_section('web.registry', ['web.Registry'], { beforeEach: function () { - this.Foo = {}; - this.Bar = {}; - this.Foo2 = {}; + this.Foo = {bar: 1}; + this.Bar = {foo: 0}; + this.Foo2 = {fred: -1}; }, }, function (test) { @@ -14,6 +14,8 @@ odoo.define_section('web.registry', ['web.Registry'], { .add('bar', this.Bar); assert.strictEqual(registry.get('foo'), this.Foo); + // make sure we're comparing actual objects instead of just undefineds + assert.deepEqual(registry.get('foo'), {bar: 1}); }); test('extension', function (assert, Registry) { From df5f0f2570e9ab23be08b54a3f08ffe89ef735c2 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Fri, 3 Mar 2017 10:53:22 +0100 Subject: [PATCH 15/36] [FIX] sale: The order lines weight must change when the quantity change This is a regression of 1cedcf6abb433beb78675557fabd9ee6e49c504e and a following of 9a9720ac14d3508e93339e351ba19de4b3ca2fd6 opw-709700 --- addons/sale/sale.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index a3a982bc42b..10b38d38a31 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -1225,8 +1225,9 @@ class sale_order_line(osv.osv): result.update({'price_unit': price}) if context.get('uom_qty_change', False): values = {'price_unit': price} - if result.get('product_uos_qty'): - values['product_uos_qty'] = result['product_uos_qty'] + for field in ['product_uos_qty', 'th_weight']: + if result.get(field): + values[field] = result[field] return {'value': values, 'domain': {}, 'warning': False} if warning_msgs: warning = { From 0c3659e14be76a86b35925527644aabe4ed00ec2 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Fri, 3 Mar 2017 11:38:44 +0100 Subject: [PATCH 16/36] [I18N] translation correction for nl_BE Regional languages are not on Transifex --- addons/account/i18n/nl_BE.po | 8 ++++---- addons/analytic/i18n/nl_BE.po | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/account/i18n/nl_BE.po b/addons/account/i18n/nl_BE.po index b7ad8ee1f09..12fc9e4a611 100644 --- a/addons/account/i18n/nl_BE.po +++ b/addons/account/i18n/nl_BE.po @@ -585,7 +585,7 @@ msgstr "Afpunten toelaten" #. module: account #: model:ir.model.fields,field_description:account.field_account_config_settings_group_multi_currency msgid "Allow multi currencies" -msgstr "Werken met meerdere munten" +msgstr "Werken met meerdere munteenheden" #. module: account #: model:ir.model.fields,field_description:account.field_account_config_settings_group_proforma_invoices @@ -1469,7 +1469,7 @@ msgstr "Wisselkoers" #. module: account #: model:ir.model.fields,help:account.field_wizard_multi_charts_accounts_currency_id msgid "Currency as per company's country." -msgstr "Munt volgens land van de firma." +msgstr "Munteenheid volgens land van de firma." #. module: account #: selection:account.abstract.payment,partner_type:0 @@ -1618,7 +1618,7 @@ msgstr "Standaard-btw" #. module: account #: model:ir.model.fields,field_description:account.field_account_config_settings_currency_id msgid "Default company currency" -msgstr "Standaard firmamunt" +msgstr "Standaard bedrijfsmunteenheid" #. module: account #: model:ir.model.fields,field_description:account.field_account_config_settings_purchase_tax_id @@ -2050,7 +2050,7 @@ msgstr "" #: model:ir.model.fields,help:account.field_account_account_template_currency_id #: model:ir.model.fields,help:account.field_account_bank_accounts_wizard_currency_id msgid "Forces all moves for this account to have this secondary currency." -msgstr "Alle bewegingen op deze rekening worden in secundaire munt geboekt." +msgstr "Alle bewegingen op deze rekening worden in secundaire munteenheid geboekt." #. module: account #: code:addons/account/models/account_invoice.py:81 diff --git a/addons/analytic/i18n/nl_BE.po b/addons/analytic/i18n/nl_BE.po index da1f38c7eab..f540b03d7be 100644 --- a/addons/analytic/i18n/nl_BE.po +++ b/addons/analytic/i18n/nl_BE.po @@ -209,7 +209,7 @@ msgstr "Labels" #. module: analytic #: model:ir.model.fields,help:analytic.field_account_analytic_line_currency_id msgid "The related account currency if not equal to the company one." -msgstr "De gekoppelde munt indien deze verschilt van de firmamunt." +msgstr "De gekoppelde munteenheid indien deze verschilt van de firmamunt." #. module: analytic #: model:ir.ui.view,arch_db:analytic.view_account_analytic_line_tree From faa3d6a69bb6e806ae429c95214b4b4f0ba36762 Mon Sep 17 00:00:00 2001 From: Yannick Tivisse Date: Fri, 3 Mar 2017 11:42:38 +0100 Subject: [PATCH 17/36] [FIX] website_sale: Deactivate Pricelist/Coupon code box by default --- addons/website_sale/views/templates.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml index e2c4e0f713b..8ccbf410bf9 100644 --- a/addons/website_sale/views/templates.xml +++ b/addons/website_sale/views/templates.xml @@ -1029,7 +1029,7 @@ -