diff --git a/addons/hr_expense/hr_expense.py b/addons/hr_expense/hr_expense.py index e14952db2f5..0d245aa929b 100644 --- a/addons/hr_expense/hr_expense.py +++ b/addons/hr_expense/hr_expense.py @@ -311,16 +311,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'], diff --git a/addons/l10n_ro/res_partner.py b/addons/l10n_ro/res_partner.py index 79933dc468e..26fd08bd2ec 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 diff --git a/addons/mrp_repair/mrp_repair.py b/addons/mrp_repair/mrp_repair.py index b1aec60a4f4..fc3c65df8b4 100644 --- a/addons/mrp_repair/mrp_repair.py +++ b/addons/mrp_repair/mrp_repair.py @@ -392,7 +392,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 diff --git a/addons/stock/wizard/stock_return_picking.py b/addons/stock/wizard/stock_return_picking.py index 57ca03a8205..f6a20c81586 100644 --- a/addons/stock/wizard/stock_return_picking.py +++ b/addons/stock/wizard/stock_return_picking.py @@ -203,6 +203,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: diff --git a/addons/survey/wizard/survey_answer.py b/addons/survey/wizard/survey_answer.py index 98ca022d884..405f6210f12 100644 --- a/addons/survey/wizard/survey_answer.py +++ b/addons/survey/wizard/survey_answer.py @@ -159,7 +159,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)}) diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 69a1476a95b..3ad8c60b8a3 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1015,7 +1015,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'); @@ -1044,10 +1044,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'); }); } }, diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index 73f244bc6a3..6c289441d73 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -923,6 +923,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]); diff --git a/openerp/addons/base/ir/ir_mail_server.py b/openerp/addons/base/ir/ir_mail_server.py index 4af52bdea41..a21d8e67176 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 @@ -120,6 +120,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'([^ ,<@]+@[^> ,]+)') @@ -143,15 +144,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: diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 356365ab440..8e2cd695436 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -3699,6 +3699,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), @@ -3737,6 +3738,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, obj_name, store_ids, fields in result_store: if obj_name == self._name: effective_store_ids = list(set(store_ids) - set(ids))