From 2459cd5dd14282b485f9e6e39df857c3b8cfa636 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Wed, 10 Sep 2014 12:18:14 +0200 Subject: [PATCH 1/9] [FIX] ir_attachment: attachements removed on record unlink --- openerp/osv/orm.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index cd625bc2009..9bf10df39d6 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -4050,6 +4050,7 @@ class BaseModel(object): self.check_access_rights(cr, uid, 'unlink') ir_property = self.pool.get('ir.property') + ir_attachment_obj = self.pool.get('ir.attachment') # Check if the records are used as default properties. domain = [('res_id', '=', False), @@ -4088,6 +4089,13 @@ class BaseModel(object): if ir_value_ids: ir_values_obj.unlink(cr, uid, ir_value_ids, context=context) + # For the same reason, removing the record relevant to ir_attachment + # The search is performed with sql as the search method of ir_attachment is overridden to hide attachments of deleted records + cr.execute('select id from ir_attachment where res_model = %s and res_id in %s', (self._name, sub_ids)) + ir_attachment_ids = [ir_attachment[0] for ir_attachment in cr.fetchall()] + if ir_attachment_ids: + ir_attachment_obj.unlink(cr, uid, ir_attachment_ids, context=context) + for order, object, store_ids, fields in result_store: if object == self._name: effective_store_ids = list(set(store_ids) - set(ids)) From f2cf6ced17d3477b8858e3a8f955a42cc8a629ff Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 10 Sep 2014 17:35:44 +0200 Subject: [PATCH 2/9] [FIX] mail: encoding of sender name with unicode When sending an email, both formats 'Name ' or '"Name" ' can be used for fields 'From', 'To' and others. If the name contains unicode characters, a regex only matching '"Name" ' was used to encode the name with RFC2047. That meant that the name was not encoded and eventually dropped, using only the email part. Instead of using a limited regex, use the parseaddr method from email library. Fixes lp:1272610, opw 607683 --- openerp/addons/base/ir/ir_mail_server.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/openerp/addons/base/ir/ir_mail_server.py b/openerp/addons/base/ir/ir_mail_server.py index ec5b12fc10d..7851d700133 100644 --- a/openerp/addons/base/ir/ir_mail_server.py +++ b/openerp/addons/base/ir/ir_mail_server.py @@ -24,7 +24,7 @@ from email.MIMEBase import MIMEBase from email.MIMEMultipart import MIMEMultipart from email.Charset import Charset from email.Header import Header -from email.Utils import formatdate, make_msgid, COMMASPACE +from email.Utils import formatdate, make_msgid, COMMASPACE, parseaddr from email import Encoders import logging import re @@ -118,6 +118,7 @@ def encode_header_param(param_text): return param_text_ascii if param_text_ascii\ else Charset('utf8').header_encode(param_text_utf8) +# TODO master, remove me, no longer used internaly name_with_email_pattern = re.compile(r'("[^<@>]+")\s*<([^ ,<@]+@[^> ,]+)>') address_pattern = re.compile(r'([^ ,<@]+@[^> ,]+)') @@ -141,15 +142,16 @@ def encode_rfc2822_address_header(header_text): header_text_ascii = try_coerce_ascii(header_text_utf8) if header_text_ascii: return header_text_ascii + + name, email = parseaddr(header_text_utf8) + if not name: + return email + # non-ASCII characters are present, attempt to # replace all "Name" patterns with the RFC2047- # encoded version - def replace(match_obj): - name, email = match_obj.group(1), match_obj.group(2) - name_encoded = str(Header(name, 'utf-8')) - return "%s <%s>" % (name_encoded, email) - header_text_utf8 = name_with_email_pattern.sub(replace, - header_text_utf8) + name_encoded = str(Header(name, 'utf-8')) + header_text_utf8 = "%s <%s>" % (name_encoded, email) # try again after encoding header_text_ascii = try_coerce_ascii(header_text_utf8) if header_text_ascii: From 948c554a830b803fd72839190efe42b2faa5f02c Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 11 Sep 2014 09:58:38 +0200 Subject: [PATCH 3/9] [FIX] web: *.openerp.com to *.odoo.com --- addons/web/static/src/js/chrome.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index a541fc6f3d1..d0f14a63804 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1129,7 +1129,7 @@ instance.web.UserMenu = instance.web.Widget.extend({ this.update_promise = this.update_promise.then(fct, fct); }, on_menu_help: function() { - window.open('http://help.openerp.com', '_blank'); + window.open('http://help.odoo.com', '_blank'); }, on_menu_logout: function() { this.trigger('user_logout'); @@ -1158,10 +1158,10 @@ instance.web.UserMenu = instance.web.Widget.extend({ state: JSON.stringify(state), scope: 'userinfo', }; - instance.web.redirect('https://accounts.openerp.com/oauth2/auth?'+$.param(params)); + instance.web.redirect('https://accounts.odoo.com/oauth2/auth?'+$.param(params)); }).fail(function(result, ev){ ev.preventDefault(); - instance.web.redirect('https://accounts.openerp.com/web'); + instance.web.redirect('https://accounts.odoo.com/web'); }); } }, From bf9a3723c0cc9b7139a627e43eb7219ca75f064b Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 10 Sep 2014 18:06:38 +0200 Subject: [PATCH 4/9] [FIX] hr_expense: tax amount computation The tax_amount field should contain the basic amount (without tax) for base tax code. (opw 613470) --- addons/hr_expense/hr_expense.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/addons/hr_expense/hr_expense.py b/addons/hr_expense/hr_expense.py index 54c411a6159..17547a57ce0 100644 --- a/addons/hr_expense/hr_expense.py +++ b/addons/hr_expense/hr_expense.py @@ -309,16 +309,19 @@ class hr_expense_expense(osv.osv): line.unit_quantity, line.product_id, exp.user_id.partner_id)['taxes']: tax_code_id = tax['base_code_id'] - tax_amount = line.total_amount * tax['base_sign'] if not tax_code_id: continue res[-1]['tax_code_id'] = tax_code_id - res[-1]['tax_amount'] = cur_obj.compute(cr, uid, exp.currency_id.id, company_currency, tax_amount, context={'date': exp.date_confirm}) ## is_price_include = tax_obj.read(cr,uid,tax['id'],['price_include'],context)['price_include'] if is_price_include: ## We need to deduce the price for the tax res[-1]['price'] = res[-1]['price'] - (tax['amount'] * tax['base_sign'] or 0.0) + # tax amount countains base amount without the tax + tax_amount = (line.total_amount - tax['amount']) * tax['base_sign'] + else: + tax_amount = line.total_amount * tax['base_sign'] + res[-1]['tax_amount'] = cur_obj.compute(cr, uid, exp.currency_id.id, company_currency, tax_amount, context={'date': exp.date_confirm}) assoc_tax = { 'type':'tax', 'name':tax['name'], From 386174cf0eee7a378c3dc0ccfa557a858ae7f300 Mon Sep 17 00:00:00 2001 From: Dharti Ratani Date: Thu, 11 Sep 2014 17:01:03 +0200 Subject: [PATCH 5/9] [FIX] survey: access rights error when editing The wizard 'Edit Survey' > 'Add Question' was trowing an access rights error as the id was passed as a string instead of a real id. opw 607854 --- addons/survey/wizard/survey_answer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/survey/wizard/survey_answer.py b/addons/survey/wizard/survey_answer.py index c87a87c3e77..fad82663469 100644 --- a/addons/survey/wizard/survey_answer.py +++ b/addons/survey/wizard/survey_answer.py @@ -157,7 +157,7 @@ class survey_question_wiz(osv.osv_memory): title = sur_rec.title xml_form = etree.Element('form', {'string': tools.ustr(title)}) if context.has_key('active') and context.get('active',False) and context.has_key('edit'): - context.update({'page_id' : tools.ustr(p_id),'page_number' : sur_name_rec.page_no , 'transfer' : sur_name_read.transfer}) + context.update({'page_id' : p_id,'page_number' : sur_name_rec.page_no , 'transfer' : sur_name_read.transfer}) xml_group3 = etree.SubElement(xml_form, 'group', {'col': '4', 'colspan': '4'}) etree.SubElement(xml_group3, 'button', {'string' :'Add Page','icon': "gtk-new", 'type' :'object','name':"action_new_page", 'context' : tools.ustr(context)}) etree.SubElement(xml_group3, 'button', {'string' :'Edit Page','icon': "gtk-edit", 'type' :'object','name':"action_edit_page", 'context' : tools.ustr(context)}) From 8c3924165176571120cb416bb7d9e0dcfe9afb91 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 11 Sep 2014 17:20:27 +0200 Subject: [PATCH 6/9] [FIX] stock: return picking, pass serial number value when returning --- addons/stock/wizard/stock_return_picking.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/stock/wizard/stock_return_picking.py b/addons/stock/wizard/stock_return_picking.py index 2b920676b28..8e30fc01bd8 100644 --- a/addons/stock/wizard/stock_return_picking.py +++ b/addons/stock/wizard/stock_return_picking.py @@ -206,6 +206,7 @@ class stock_return_picking(osv.osv_memory): 'location_id': new_location, 'location_dest_id': move.location_id.id, 'date': date_cur, + 'prodlot_id': data_get.prodlot_id.id, }) move_obj.write(cr, uid, [move.id], {'move_history_ids2':[(4,new_move)]}, context=context) if not returned_lines: From 875d7ed38ec05daa5d91229cd0a085023b47810d Mon Sep 17 00:00:00 2001 From: fka-odoo Date: Wed, 2 Jul 2014 14:08:41 +0530 Subject: [PATCH 7/9] [FIX] web: sort with undefined value In this awesome programming language called javascript, undefined is neither bigger nor smaller than a string. Previous code was then considering undefined values equal to any string. This fix allows to sort in a column of a o2m field and group the undefined values together. opw 607704 --- addons/web/static/src/js/data.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index 6ae69fbe67b..5553572a12e 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -898,6 +898,8 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({ sign = -1; field = field.slice(1); } + if(!a[field] && a[field] !== 0){ return sign} + if(!b[field] && b[field] !== 0){ return (sign == -1) ? 1 : -1} //m2o should be searched based on value[1] not based whole value(i.e. [id, value]) if(_.isArray(a[field]) && a[field].length == 2 && _.isString(a[field][1])){ return sign * compare(a[field][1], b[field][1]); From 5f9682c35304af14a58b9160ec15ccfd44c96c67 Mon Sep 17 00:00:00 2001 From: Fekete Mihai Date: Fri, 12 Sep 2014 16:04:22 +0200 Subject: [PATCH 8/9] [FIX] l10n_ro: backport of fix done in res_partner.py from aa76885 PR #720 --- addons/l10n_ro/res_partner.py | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/addons/l10n_ro/res_partner.py b/addons/l10n_ro/res_partner.py index 4835f75bb40..103a5d616d0 100644 --- a/addons/l10n_ro/res_partner.py +++ b/addons/l10n_ro/res_partner.py @@ -28,26 +28,15 @@ class res_partner(osv.osv): 'nrc' : fields.char('NRC', size=16, help='Registration number at the Registry of Commerce'), } - # The SQL constraints are no-ops but present only to display the right error message to the - # user when the partial unique indexes defined below raise errors/ - # The real constraints need to be implemented with PARTIAL UNIQUE INDEXES (see auto_init), - # due to the way accounting data is delegated by contacts to their companies in OpenERP 7.0. - _sql_constraints = [ - ('vat_uniq', 'unique (id)', 'The vat of the partner must be unique !'), - ('nrc_uniq', 'unique (id)', 'The code of the partner must be unique !') - ] - def _auto_init(self, cr, context=None): result = super(res_partner, self)._auto_init(cr, context=context) - # Real implementation of the vat/nrc constraints: only "commercial entities" need to have - # unique numbers, and the condition for being a commercial entity is "is_company or parent_id IS NULL". - # Contacts inside a company automatically have a copy of the company's commercial fields - # (see _commercial_fields()), so they are automatically consistent. + # Remove constrains for vat, nrc on "commercial entities" because is not mandatory by legislation + # Even that VAT numbers are unique, the NRC field is not unique, and there are certain entities that + # doesn't have a NRC number plus the formatting was changed few times, so we cannot have a base rule for + # checking if available and emmited by the Ministry of Finance, only online on their website. cr.execute(""" DROP INDEX IF EXISTS res_partner_vat_uniq_for_companies; DROP INDEX IF EXISTS res_partner_nrc_uniq_for_companies; - CREATE UNIQUE INDEX res_partner_vat_uniq_for_companies ON res_partner (vat) WHERE is_company OR parent_id IS NULL; - CREATE UNIQUE INDEX res_partner_nrc_uniq_for_companies ON res_partner (nrc) WHERE is_company OR parent_id IS NULL; """) return result From 9b1cdea223b8b5bcc0decd3e55512b391e16673d Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Fri, 12 Sep 2014 16:25:48 +0200 Subject: [PATCH 9/9] [FIX] mrp_repair: invoice the actual invoice partner id --- addons/mrp_repair/mrp_repair.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mrp_repair/mrp_repair.py b/addons/mrp_repair/mrp_repair.py index 9132094bf97..74085debad7 100644 --- a/addons/mrp_repair/mrp_repair.py +++ b/addons/mrp_repair/mrp_repair.py @@ -395,7 +395,7 @@ class mrp_repair(osv.osv): 'origin':repair.name, 'type': 'out_invoice', 'account_id': account_id, - 'partner_id': repair.partner_id.id, + 'partner_id': repair.partner_invoice_id.id or repair.partner_id.id, 'currency_id': repair.pricelist_id.currency_id.id, 'comment': repair.quotation_notes, 'fiscal_position': repair.partner_id.property_account_position.id