From ecaf5f66e1aefd9f80a8f335f458de7aa3321ac2 Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Tue, 26 Dec 2017 13:27:24 +0100 Subject: [PATCH 01/18] [FIX] stock: wrong company when creating a route Routes created when creating companie were not set to the correct company. Steps to reproduce: - Go to Settings > General settings: Activate Manage Multiple companies. - Go in Inventory > Configuration>Settings: Click "Manage several Warehouses, each one composed by several stock location". Click "Advanced routing of products using rules". - Go in Settings > Users > Companies: Create new companie "ThisNewCompanie" - Go in Inventory > Configuration>Routes: Open Routes named ThisNewCompanie. Bug: All the routes created automatically by creating the company "ThisNewCompanie" are not set to the company "ThisNewCompanie". They are set to the company of the logged user when "ThisNewCompanie" was created opw:787229 --- addons/stock/models/stock_warehouse.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/addons/stock/models/stock_warehouse.py b/addons/stock/models/stock_warehouse.py index b112d11567b..b132083138e 100644 --- a/addons/stock/models/stock_warehouse.py +++ b/addons/stock/models/stock_warehouse.py @@ -427,6 +427,7 @@ class Warehouse(models.Model): self.Routing(warehouse.lot_stock_id, warehouse.wh_pack_stock_loc_id, warehouse.pick_type_id), self.Routing(warehouse.wh_pack_stock_loc_id, warehouse.wh_output_stock_loc_id, warehouse.pack_type_id), self.Routing(warehouse.wh_output_stock_loc_id, customer_loc, warehouse.out_type_id)], + 'company_id': warehouse.company_id.id, }) for warehouse in self) @api.multi @@ -436,6 +437,7 @@ class Warehouse(models.Model): 'product_categ_selectable': True, 'product_selectable': False, 'sequence': 10, + 'company_id': self.company_id.id, } @api.model @@ -455,7 +457,8 @@ class Warehouse(models.Model): 'product_selectable': True, 'product_categ_selectable': True, 'supplied_wh_id': self.id, - 'supplier_wh_id': supplier_warehouse.id} + 'supplier_wh_id': supplier_warehouse.id, + 'company_id': self.company_id.id} def _get_inter_wh_route(self, supplier_warehouse): # FIXME - remove me in master/saas-14 @@ -469,7 +472,8 @@ class Warehouse(models.Model): 'product_selectable': True, 'product_categ_selectable': True, 'active': self.delivery_steps != 'ship_only' and self.reception_steps != 'one_step', - 'sequence': 20} + 'sequence': 20, + 'company_id': self.company_id.id} def _get_crossdock_route(self, route_name): # FIXME - remove me in master/saas-14 From 36e7847e20b35d3a9f3f965001cab5d2c2d8e896 Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Tue, 2 Jan 2018 15:55:33 +0100 Subject: [PATCH 02/18] [FIX] website_quote: Adding a suggested product in a SO When adding a suggested product which already exists in the SO, it crashed due to a programming error. opw:801047 --- addons/website_quote/models/sale_order.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/website_quote/models/sale_order.py b/addons/website_quote/models/sale_order.py index 8098061b510..88a2015566a 100644 --- a/addons/website_quote/models/sale_order.py +++ b/addons/website_quote/models/sale_order.py @@ -252,7 +252,8 @@ class SaleOrderOption(models.Model): order_line = order.order_line.filtered(lambda line: line.product_id == self.product_id) if order_line: - order_line[0].product_uom_qty += 1 + order_line = order_line[0] + order_line.product_uom_qty += 1 else: vals = { 'price_unit': self.price_unit, From 0e943241fe2408830b9c06c1875a29f96ebe6c48 Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Tue, 2 Jan 2018 14:32:06 +0100 Subject: [PATCH 03/18] [FIX] web: rotate graph label When there are too many labels to display on the x-axis, they overlap and it simply becomes unreadable. By slightly rotating them, this can be avoided in most cases. Back-port of this commit 388e258ce8c2a4fbd5e2ec5ec746bb91ca48d97f opw:802925 --- addons/web/static/src/js/views/graph_widget.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/js/views/graph_widget.js b/addons/web/static/src/js/views/graph_widget.js index 0af4ea9f362..a8994880e70 100644 --- a/addons/web/static/src/js/views/graph_widget.js +++ b/addons/web/static/src/js/views/graph_widget.js @@ -168,7 +168,7 @@ return Widget.extend({ var chart = nv.models.multiBarChart(); var maxVal = _.max(values, function(v) {return v.y}) chart.options({ - margin: {left: 12 * String(maxVal && maxVal.y || 10000000).length}, + margin: {left: 12 * String(maxVal && maxVal.y || 10000000).length, bottom: 60}, delay: 250, transition: 10, showLegend: _.size(data) <= MAX_LEGEND_LENGTH, @@ -177,7 +177,7 @@ return Widget.extend({ rightAlignYAxis: false, stacked: this.stacked, reduceXTicks: false, - // rotateLabels: 40, + rotateLabels: -20, showControls: (this.groupbys.length > 1) }); chart.yAxis.tickFormat(function(d) { return formats.format_value(d, { type : 'float' });}); From ad2d34cf33f8c7ef0e8a04642ccc8f3dffe727b9 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Thu, 7 Sep 2017 22:30:04 -0500 Subject: [PATCH 04/18] [FIX] account: ensure chart template translation in company's lang Before this commit, in the event that the admin user has set the language to english, but the COA's target company had a different language, the admin user's language had been taken instead of the copany's one for the translation of journals and other coa intialization stuff. This is wrong as the CoA is more connected to the company, than to the user, which could be a functional support user that just happens to prefer the english version over the local one. Now, we ensure in two neuralgic places, that the company's language is passed to the context and therefore picked up by the translation's GetTextAlias. Signed-off-by: David Arnold --- addons/account/models/chart_template.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/addons/account/models/chart_template.py b/addons/account/models/chart_template.py index d205afd8e24..ffae12f070c 100644 --- a/addons/account/models/chart_template.py +++ b/addons/account/models/chart_template.py @@ -283,7 +283,8 @@ class AccountChartTemplate(models.Model): tmp1, tmp2 = self.parent_id._install_template(company, code_digits=code_digits, transfer_account_id=transfer_account_id, acc_ref=acc_ref, taxes_ref=taxes_ref) acc_ref.update(tmp1) taxes_ref.update(tmp2) - tmp1, tmp2 = self._load_template(company, code_digits=code_digits, transfer_account_id=transfer_account_id, account_ref=acc_ref, taxes_ref=taxes_ref) + # Ensure, even if individually, that everything is translated according to the company's language. + tmp1, tmp2 = self.with_context(lang=company.partner_id.lang)._load_template(company, code_digits=code_digits, transfer_account_id=transfer_account_id, account_ref=acc_ref, taxes_ref=taxes_ref) acc_ref.update(tmp1) taxes_ref.update(tmp2) return acc_ref, taxes_ref @@ -793,6 +794,8 @@ class WizardMultiChartsAccounts(models.TransientModel): all the provided information to create the accounts, the banks, the journals, the taxes, the accounting properties... accordingly for the chosen company. ''' + # Ensure everything is translated consitingly to the company's language, not the user's one. + self = self.with_context(lang=self.company_id.partner_id.lang) if len(self.env['account.account'].search([('company_id', '=', self.company_id.id)])) > 0: # We are in a case where we already have some accounts existing, meaning that user has probably # created its own accounts and does not need a coa, so skip installation of coa. From 9e19bfad8cc4d59c89d479c5716869ef9b38405f Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Fri, 29 Dec 2017 15:59:36 +0100 Subject: [PATCH 05/18] [FIX] hr_holidays: Leaves by Department The report 'Leaves by Department' only counts full days-off, instead of taking into account the actual number of days. This commit fixes the total number of days per employee. However, there is still a limitation on the display: a day is either fully colored or not at all. opw-801061 --- addons/hr_holidays/report/holidays_summary_report.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/hr_holidays/report/holidays_summary_report.py b/addons/hr_holidays/report/holidays_summary_report.py index 0118429725f..67f4c96a861 100644 --- a/addons/hr_holidays/report/holidays_summary_report.py +++ b/addons/hr_holidays/report/holidays_summary_report.py @@ -68,8 +68,8 @@ class HrHolidaySummaryReport(models.AbstractModel): for index in range(0, ((date_to - date_from).days + 1)): if date_from >= start_date and date_from <= end_date: res[(date_from-start_date).days]['color'] = holiday.holiday_status_id.color_name - count+=1 date_from += timedelta(1) + count += abs(holiday.number_of_days) self.sum = count return res From aaa8a87f36478bca6504b2acfbe5e0a2e236fa4b Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Wed, 3 Jan 2018 12:37:28 +0100 Subject: [PATCH 06/18] [FIX] website_forum: check karma to allow to flag a post without rights to edit If you set 200 kamra to allow to flag a post and 300 to edit all post, you was not able to flag the post before this commit. This commit closes #21274 @kangol: warning, fwd port need to add tag_ids into trusted_keys --- addons/website_forum/models/forum.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py index 8b03a0a809c..cc9b20da7c8 100644 --- a/addons/website_forum/models/forum.py +++ b/addons/website_forum/models/forum.py @@ -436,7 +436,7 @@ class Post(models.Model): elif post.parent_id and not post.can_answer: raise KarmaError('Not enough karma to answer to a question') if not post.parent_id and not post.can_post: - post.state = 'pending' + post.sudo().state = 'pending' # add karma for posting new questions if not post.parent_id and post.state == 'active': @@ -466,11 +466,18 @@ class Post(models.Model): @api.multi def write(self, vals): + trusted_keys = ['active', 'is_correct'] # fields where security is checked manually if 'content' in vals: vals['content'] = self._update_content(vals['content'], self.forum_id.id) if 'state' in vals: - if vals['state'] in ['active', 'close'] and any(not post.can_close for post in self): - raise KarmaError('Not enough karma to close or reopen a post.') + if vals['state'] in ['active', 'close']: + if any(not post.can_close for post in self): + raise KarmaError('Not enough karma to close or reopen a post.') + trusted_keys += ['state', 'closed_uid', 'closed_date', 'closed_reason_id'] + elif vals['state'] == 'flagged': + if any(not post.can_flag for post in self): + raise KarmaError('Not enough karma to flag a post.') + trusted_keys += ['state', 'flag_user_id'] if 'active' in vals: if any(not post.can_unlink for post in self): raise KarmaError('Not enough karma to delete or reactivate a post') @@ -483,7 +490,7 @@ class Post(models.Model): if vals['is_correct'] != post.is_correct and post.create_uid.id != self._uid: post.create_uid.sudo().add_karma(post.forum_id.karma_gen_answer_accepted * mult) self.env.user.sudo().add_karma(post.forum_id.karma_gen_answer_accept * mult) - if any(key not in ['state', 'active', 'is_correct', 'closed_uid', 'closed_date', 'closed_reason_id'] for key in vals.keys()) and any(not post.can_edit for post in self): + if any(key not in trusted_keys for key in vals) and any(not post.can_edit for post in self): raise KarmaError('Not enough karma to edit a post.') res = super(Post, self).write(vals) From 7a31bc60fb67a7322d6f105270cf809f5fc46e5d Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Wed, 3 Jan 2018 13:24:09 +0100 Subject: [PATCH 07/18] [FIX] website_forum: fix tooltip user info Before this commit, all tooltip users was showing website and parent_name from the Main company and not the current focsed partner. This commits closes #18430 @kangol: fwd-port company_name --- addons/website_forum/views/ir_qweb.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/website_forum/views/ir_qweb.xml b/addons/website_forum/views/ir_qweb.xml index 5b236210efa..174987a05d9 100644 --- a/addons/website_forum/views/ir_qweb.xml +++ b/addons/website_forum/views/ir_qweb.xml @@ -5,9 +5,9 @@
From b291494f648517a4e10b78daaec3e27817c1efe8 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Thu, 4 Jan 2018 12:40:37 +0100 Subject: [PATCH 08/18] [FIX] stock: inventory value Add the inventory value in the pivot view. Indeed, the Unit Cost displayed is the cost of the quant, which is not what is expected in case of standard costing method. opw-785872 --- addons/stock/views/stock_quant_views.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/stock/views/stock_quant_views.xml b/addons/stock/views/stock_quant_views.xml index 10f26fdca93..6dec81f7848 100644 --- a/addons/stock/views/stock_quant_views.xml +++ b/addons/stock/views/stock_quant_views.xml @@ -116,6 +116,7 @@ + From deb00a703b6c2f676a551bcff45ddbd3225f8fb8 Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Thu, 4 Jan 2018 11:22:27 +0100 Subject: [PATCH 09/18] [FIX] purchase: Adding a purchase order on a vendor bill To keep the same behavior as in 11.0, you can only add a purchase order to a vendor bill when the vendor bill is in draft. Afterwards it is not longer possible. opw:803068 --- addons/purchase/views/account_invoice_views.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/purchase/views/account_invoice_views.xml b/addons/purchase/views/account_invoice_views.xml index 7f4fc3bf4e0..3f23f6777d0 100644 --- a/addons/purchase/views/account_invoice_views.xml +++ b/addons/purchase/views/account_invoice_views.xml @@ -59,7 +59,7 @@ - From 22da94f147a71ad1a0767ced46510b7265330b75 Mon Sep 17 00:00:00 2001 From: Benjamin Willig Date: Fri, 22 Dec 2017 12:26:38 +0100 Subject: [PATCH 10/18] [FIX] Allow to keep the state of a PO when logging a message Steps to reproduce the bug: - Create a new RFQ - When it's in draft state, log an internal note using the 'mail.compose.message' dialog. Bug: - RFQ is now in 'sent' state. The fix allows to inherit from mail_purchase_order_on_send method to change the base behavior. opw:801549 --- addons/purchase/models/purchase.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py index 2c33f5fb9a3..eba5d4c868f 100644 --- a/addons/purchase/models/purchase.py +++ b/addons/purchase/models/purchase.py @@ -1164,11 +1164,15 @@ class ProductCategory(models.Model): class MailComposeMessage(models.TransientModel): _inherit = 'mail.compose.message' + @api.multi + def mail_purchase_order_on_send(self): + if not self.filtered('subtype_id.internal'): + order = self.env['purchase.order'].browse(self._context['default_res_id']) + if order.state == 'draft': + order.state = 'sent' + @api.multi def send_mail(self, auto_commit=False): if self._context.get('default_model') == 'purchase.order' and self._context.get('default_res_id'): - if not self.filtered('subtype_id.internal'): - order = self.env['purchase.order'].browse([self._context['default_res_id']]) - if order.state == 'draft': - order.state = 'sent' + self.mail_purchase_order_on_send() return super(MailComposeMessage, self.with_context(mail_post_autofollow=True)).send_mail(auto_commit=auto_commit) From 10af3284ab9fe008af9ab1ae5d00feebb28ac918 Mon Sep 17 00:00:00 2001 From: "Lucas Perais (lpe)" Date: Wed, 20 Dec 2017 14:53:14 +0100 Subject: [PATCH 11/18] [FIX] l10n_be_intrastat: manage dropshipping triangular Before this commit, the triangular case was not handled: A transaction in dropshipping which happens outside our country (provider and customer both outside our country) was counted in the intrastat XML when it shouldn't After this commit, those transaction are not accounted for in the XML opw-800342 --- addons/l10n_be_intrastat/wizard/xml_decl.py | 26 +++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/addons/l10n_be_intrastat/wizard/xml_decl.py b/addons/l10n_be_intrastat/wizard/xml_decl.py index ea49dc3887c..37d2082becf 100644 --- a/addons/l10n_be_intrastat/wizard/xml_decl.py +++ b/addons/l10n_be_intrastat/wizard/xml_decl.py @@ -164,6 +164,7 @@ class XmlDeclaration(models.TransientModel): lines = self.env.cr.fetchall() invoicelines_ids = [rec[0] for rec in lines] invoicelines = self.env['account.invoice.line'].browse(invoicelines_ids) + for inv_line in invoicelines: #Check type of transaction @@ -189,6 +190,8 @@ class XmlDeclaration(models.TransientModel): #comes from purchase po_lines = self.env['purchase.order.line'].search([('invoice_lines', 'in', inv_line.id)], limit=1) if po_lines: + if self._is_situation_triangular(company, po_line=po_lines): + continue location = self.env['stock.location'].browse(po_lines.order_id._get_destination_location()) region_id = self.env['stock.warehouse'].get_regionid_from_locationid(location) if region_id: @@ -197,6 +200,8 @@ class XmlDeclaration(models.TransientModel): #comes from sales so_lines = self.env['sale.order.line'].search([('invoice_lines', 'in', inv_line.id)], limit=1) if so_lines: + if self._is_situation_triangular(company, so_line=so_lines): + continue saleorder = so_lines.order_id if saleorder and saleorder.warehouse_id and saleorder.warehouse_id.region_id: exreg = IntrastatRegion.browse(saleorder.warehouse_id.region_id.id).code @@ -286,3 +291,24 @@ class XmlDeclaration(models.TransientModel): dim = ET.SubElement(item, 'Dim') dim.set('prop', prop) dim.text = value + + def _is_situation_triangular(self, company, po_line=False, so_line=False): + # Ignoring what is purchased and sold by us with a dropshipping route + # outside of our country, or completely within it + # https://www.nbb.be/doc/dq/f_pdf_ex/intra2017fr.pdf (ยง 4.x) + dropship_pick_type = self.env.ref('stock_dropshipping.picking_type_dropship', raise_if_not_found=False) + if not dropship_pick_type: + return False + stock_move_domain = [('picking_type_id', '=', dropship_pick_type.id)] + + if po_line: + stock_move_domain.append(('purchase_line_id', '=', po_line.id)) + if so_line: + stock_move_domain.append(('procurement_id.sale_line_id', '=', so_line.id)) + + stock_move = self.env['stock.move'].search(stock_move_domain, limit=1) + return stock_move and ( + (stock_move.partner_id.country_id.code != company.country_id.code and + stock_move.picking_partner_id.country_id.code != company.country_id.code) or + (stock_move.partner_id.country_id.code == company.country_id.code and + stock_move.picking_partner_id.country_id.code == company.country_id.code)) From 18bb3ac71bac3d1a71a9dab37b5731bbc0add8e0 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Fri, 5 Jan 2018 09:56:36 +0100 Subject: [PATCH 12/18] [FIX] mrp: in move validation, take into account the owner Before this commit, the special mrp validate_move method did a call to quants_move with an incomplete signature. IN the use case, that we want to make "own" produced quantities by a third party (maquila), we can do so in downstream modules by restrict the partner on the move so that any moved (or created) quants will belong to this partner (owner). This is certainly important for the case where finished products are not your own property. Courtesy of blaggacao. Closes #21072 --- addons/mrp/models/stock_move.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/mrp/models/stock_move.py b/addons/mrp/models/stock_move.py index b53685eb9fc..6671cb0a215 100644 --- a/addons/mrp/models/stock_move.py +++ b/addons/mrp/models/stock_move.py @@ -282,7 +282,7 @@ class StockMove(models.Model): preferred_domain_list = [preferred_domain] + [fallback_domain] + [fallback_domain2] if move.has_tracking == 'none': quants = quant_obj.quants_get_preferred_domain(move.product_qty, move, domain=main_domain, preferred_domain_list=preferred_domain_list) - self.env['stock.quant'].quants_move(quants, move, move.location_dest_id) + self.env['stock.quant'].quants_move(quants, move, move.location_dest_id, owner_id=move.restrict_partner_id.id) else: for movelot in move.active_move_lot_ids: if float_compare(movelot.quantity_done, 0, precision_rounding=rounding) > 0: @@ -290,7 +290,7 @@ class StockMove(models.Model): raise UserError(_('You need to supply a lot/serial number.')) qty = move.product_uom._compute_quantity(movelot.quantity_done, move.product_id.uom_id) quants = quant_obj.quants_get_preferred_domain(qty, move, lot_id=movelot.lot_id.id, domain=main_domain, preferred_domain_list=preferred_domain_list) - self.env['stock.quant'].quants_move(quants, move, move.location_dest_id, lot_id = movelot.lot_id.id) + self.env['stock.quant'].quants_move(quants, move, move.location_dest_id, lot_id = movelot.lot_id.id, owner_id=move.restrict_partner_id.id) moves_to_unreserve |= move # Next move in production order if move.move_dest_id and move.move_dest_id.state not in ('done', 'cancel'): From b9edb91418de5a9d5855eea166d0149ec0d730bb Mon Sep 17 00:00:00 2001 From: Nicolas Seinlet Date: Fri, 5 Jan 2018 11:14:36 +0100 Subject: [PATCH 13/18] [FIX] stock_account: change standard price Improve performance when 70k+ locations, only use locations where the product is instead of all locations. --- addons/stock_account/models/product.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/stock_account/models/product.py b/addons/stock_account/models/product.py index 1e4ac7ffbe1..751d182d30d 100644 --- a/addons/stock_account/models/product.py +++ b/addons/stock_account/models/product.py @@ -97,7 +97,9 @@ class ProductProduct(models.Model): """ Changes the Standard Price of Product and creates an account move accordingly.""" AccountMove = self.env['account.move'] - locations = self.env['stock.location'].search([('usage', '=', 'internal'), ('company_id', '=', self.env.user.company_id.id)]) + quant_locs = self.env['stock.quant'].sudo().read_group([('product_id', 'in', self.ids)], ['location_id'], ['location_id']) + quant_loc_ids = [loc['location_id'][0] for loc in quant_locs] + locations = self.env['stock.location'].search([('usage', '=', 'internal'), ('company_id', '=', self.env.user.company_id.id), ('id', 'in', quant_loc_ids)]) product_accounts = {product.id: product.product_tmpl_id.get_product_accounts() for product in self} From 35c829f12b28615351cb306397b1a3dfbfdeaccb Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Fri, 5 Jan 2018 13:57:46 +0100 Subject: [PATCH 14/18] [FIX] mail: Discuss: apply default filters Before this rev., the default filters were ignored in Discuss. The SearchView was instantiated and correctly retrieved the default filters. However, a first manual 'do_search' needs to be done by the client action for the search view to provide the domain, and for Discuss to correctly filter the messages. Steps to reproduce the issue: - In Discuss (e.g. in Inbox), add to Favorites a given search, and tick 'Use by default' - Leave Discuss, and then go back: the default filter correctly appears in the search view, but the messages aren't filtered. --- addons/mail/static/src/js/client_action.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/addons/mail/static/src/js/client_action.js b/addons/mail/static/src/js/client_action.js index ca34192488f..5ef150e6d1d 100644 --- a/addons/mail/static/src/js/client_action.js +++ b/addons/mail/static/src/js/client_action.js @@ -231,6 +231,9 @@ var ChatAction = Widget.extend(ControlPanelMixin, { var def3 = this.extended_composer.appendTo(this.$('.o_mail_chat_content')); var def4 = this.searchview.appendTo($("
")).then(function () { self.$searchview_buttons = self.searchview.$buttons.contents(); + // manually call do_search to generate the initial domain and filter + // the messages in the default channel + self.searchview.do_search(); }); this.render_sidebar(); @@ -547,7 +550,12 @@ var ChatAction = Widget.extend(ControlPanelMixin, { }); this.domain = result.domain; - this.fetch_and_render_thread(); + if (this.channel) { + // initially (when do_search is called manually), there is no + // channel set yet, so don't try to fetch and render the thread as + // this will be done as soon as the default channel is set + this.fetch_and_render_thread(); + } }, on_post_message: function (message) { From bc3d5ca7755d8a0d9a3e4c185b26e201ed8fefc3 Mon Sep 17 00:00:00 2001 From: Florent de Labarre Date: Wed, 18 Oct 2017 03:56:42 -0800 Subject: [PATCH 15/18] [FIX] stock.move : add more information in UserError of product_uom Constrains Steps to reproduce the bug: - Create a bom with lines - Change on one product in product view form the uom with diffrent category (exemple : unit -> meter) - Create un manufactoring order : you have an error You try to move a product using a UoM that is not compatible with the UoM of the product moved. Please use an UoM in the same UoM category., the error message doesn't give with product there are an issue. ( if you have hundred of line in your Bom, it is very difficult). This fix improves the error message. opw:800328 --- addons/stock/i18n/stock.pot | 16 ++++++++++++++++ addons/stock/models/stock_move.py | 6 ++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/addons/stock/i18n/stock.pot b/addons/stock/i18n/stock.pot index d3a06ce060f..559aa1d3b85 100644 --- a/addons/stock/i18n/stock.pot +++ b/addons/stock/i18n/stock.pot @@ -15,6 +15,22 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: stock +#: code:addons/stock/models/stock_move.py:230 +#, python-format +msgid "\n" +"\n" +"%s --> Product UoM is %s (%s) - Move UoM is %s (%s)" +msgstr "" + +#. module: stock +#: code:addons/stock/models/stock_move.py:231 +#, python-format +msgid "\n" +"\n" +"Blocking: %s" +msgstr "" + #. module: stock #: model:ir.model.fields,help:stock.field_stock_config_settings_module_stock_dropshipping msgid "\n" diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py index 719bf08ea1a..2cd17da87ed 100644 --- a/addons/stock/models/stock_move.py +++ b/addons/stock/models/stock_move.py @@ -223,10 +223,12 @@ class StockMove(models.Model): @api.constrains('product_uom') def _check_uom(self): - moves_error = self.filtered(lambda move: move.product_id.uom_id.category_id.id != move.product_uom.category_id.id) + moves_error = self.filtered(lambda move: move.product_id.uom_id.category_id != move.product_uom.category_id) if moves_error: user_warning = _('You try to move a product using a UoM that is not compatible with the UoM of the product moved. Please use an UoM in the same UoM category.') - user_warning += '\n\nBlocking: %s' % ' ,'.join(moves_error.mapped('name')) + for move in moves_error: + user_warning += _('\n\n%s --> Product UoM is %s (%s) - Move UoM is %s (%s)') % (move.product_id.display_name, move.product_id.uom_id.name, move.product_id.uom_id.category_id.name, move.product_uom.name, move.product_uom.category_id.name) + user_warning += _('\n\nBlocking: %s') % ' ,'.join(moves_error.mapped('name')) raise UserError(user_warning) @api.model_cr From 684483b634d5fd2e02ddcca43e89747f549d2ee0 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Mon, 8 Jan 2018 15:59:23 +0100 Subject: [PATCH 16/18] [FIX] website_portal_sale: SO state Add the SO state on the payment transaction, in order to be able to spot more easily unconfirmed SO due to incomplete payments. opw-748467 --- addons/website_portal_sale/models/payment.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/website_portal_sale/models/payment.py b/addons/website_portal_sale/models/payment.py index fcc4aa09a40..adc8a66bdc5 100644 --- a/addons/website_portal_sale/models/payment.py +++ b/addons/website_portal_sale/models/payment.py @@ -11,6 +11,7 @@ class PaymentTransaction(models.Model): # link with the sale order sale_order_id = fields.Many2one('sale.order', string='Sale Order') + so_state = fields.Selection('sale.order', string='Sale Order State', related='sale_order_id.state') def _generate_and_pay_invoice(self, tx, acquirer_name): tx.sale_order_id._force_lines_to_invoice_policy_order() From 849d8ffd2193db2001626e455ed86a96bf1cddb7 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Fri, 5 Jan 2018 14:52:55 +0100 Subject: [PATCH 17/18] [FIX] sale: protect SO if done Prevent the modification of the SO line if the SO is locked. opw-803439 --- addons/sale/models/sale.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py index 947aa121a89..3c60e7cb0d9 100644 --- a/addons/sale/models/sale.py +++ b/addons/sale/models/sale.py @@ -729,6 +729,18 @@ class SaleOrderLine(models.Model): msg += _("Invoiced Quantity") + ": %s
" % (line.qty_invoiced,) msg += "" order.message_post(body=msg) + + # Prevent writing on a locked SO. + protected_fields = self._get_protected_fields() + if 'done' in self.mapped('order_id.state') and any(f in values.keys() for f in protected_fields): + fields = self.env['ir.model.fields'].search([ + ('name', 'in', protected_fields), ('model', '=', self._name) + ]) + raise UserError( + _('It is forbidden to modify the following fields in a locked order:\n%s') + % '\n'.join(fields.mapped('field_description')) + ) + result = super(SaleOrderLine, self).write(values) if lines: lines._action_procurement_create() @@ -984,6 +996,12 @@ class SaleOrderLine(models.Model): return product[field_name] * uom_factor * cur_factor, currency_id.id + def _get_protected_fields(self): + return [ + 'product_id', 'name', 'price_unit', 'product_uom', 'product_uom_qty', + 'tax_id', 'analytic_tag_ids' + ] + @api.onchange('product_id', 'price_unit', 'product_uom', 'product_uom_qty', 'tax_id') def _onchange_discount(self): self.discount = 0.0 From a7c081941cde4bc94a8554f322de39cb79f9de00 Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Mon, 8 Jan 2018 15:48:52 +0100 Subject: [PATCH 18/18] [FIX] sale: Description of the product 'Downpayment' not translated When you create a down payment invoice from an SO, the product that is used in the line is 'Down Payment'. The description of this product, which is visible for the customer, was not translated to the language of the customer in the SO and in the invoice. It was translated to the language of the user logged. This fix is made to keep the same behavior for the description of an SO line and for the description of the invoice line. opw:803977 --- addons/sale/wizard/sale_make_invoice_advance.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/addons/sale/wizard/sale_make_invoice_advance.py b/addons/sale/wizard/sale_make_invoice_advance.py index 2b9caf659bb..ac7d9587d22 100644 --- a/addons/sale/wizard/sale_make_invoice_advance.py +++ b/addons/sale/wizard/sale_make_invoice_advance.py @@ -76,12 +76,14 @@ class SaleAdvancePaymentInv(models.TransientModel): if self.amount <= 0.00: raise UserError(_('The value of the down payment amount must be positive.')) + context = {'lang': order.partner_id.lang} if self.advance_payment_method == 'percentage': amount = order.amount_untaxed * self.amount / 100 name = _("Down payment of %s%%") % (self.amount,) else: amount = self.amount name = _('Down Payment') + del context taxes = self.product_id.taxes_id.filtered(lambda r: not order.company_id or r.company_id == order.company_id) if order.fiscal_position_id and taxes: tax_ids = order.fiscal_position_id.map_tax(taxes).ids @@ -152,6 +154,7 @@ class SaleAdvancePaymentInv(models.TransientModel): tax_ids = order.fiscal_position_id.map_tax(taxes).ids else: tax_ids = taxes.ids + context = {'lang': order.partner_id.lang} so_line = sale_line_obj.create({ 'name': _('Advance: %s') % (time.strftime('%m %Y'),), 'price_unit': amount, @@ -163,6 +166,7 @@ class SaleAdvancePaymentInv(models.TransientModel): 'tax_id': [(6, 0, tax_ids)], 'is_downpayment': True, }) + del context self._create_invoice(order, so_line, amount) if self._context.get('open_invoices', False): return sale_orders.action_view_invoice()