[MERGE] forward port of branch 7.0 up to 9b1cdea
This commit is contained in:
commit
fdc62713a5
|
@ -311,16 +311,19 @@ class hr_expense_expense(osv.osv):
|
||||||
line.unit_quantity, line.product_id,
|
line.unit_quantity, line.product_id,
|
||||||
exp.user_id.partner_id)['taxes']:
|
exp.user_id.partner_id)['taxes']:
|
||||||
tax_code_id = tax['base_code_id']
|
tax_code_id = tax['base_code_id']
|
||||||
tax_amount = line.total_amount * tax['base_sign']
|
|
||||||
if not tax_code_id:
|
if not tax_code_id:
|
||||||
continue
|
continue
|
||||||
res[-1]['tax_code_id'] = tax_code_id
|
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']
|
is_price_include = tax_obj.read(cr,uid,tax['id'],['price_include'],context)['price_include']
|
||||||
if is_price_include:
|
if is_price_include:
|
||||||
## We need to deduce the price for the tax
|
## We need to deduce the price for the tax
|
||||||
res[-1]['price'] = res[-1]['price'] - (tax['amount'] * tax['base_sign'] or 0.0)
|
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 = {
|
assoc_tax = {
|
||||||
'type':'tax',
|
'type':'tax',
|
||||||
'name':tax['name'],
|
'name':tax['name'],
|
||||||
|
|
|
@ -28,26 +28,15 @@ class res_partner(osv.osv):
|
||||||
'nrc' : fields.char('NRC', size=16, help='Registration number at the Registry of Commerce'),
|
'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):
|
def _auto_init(self, cr, context=None):
|
||||||
result = super(res_partner, self)._auto_init(cr, context=context)
|
result = super(res_partner, self)._auto_init(cr, context=context)
|
||||||
# Real implementation of the vat/nrc constraints: only "commercial entities" need to have
|
# Remove constrains for vat, nrc on "commercial entities" because is not mandatory by legislation
|
||||||
# unique numbers, and the condition for being a commercial entity is "is_company or parent_id IS NULL".
|
# Even that VAT numbers are unique, the NRC field is not unique, and there are certain entities that
|
||||||
# Contacts inside a company automatically have a copy of the company's commercial fields
|
# doesn't have a NRC number plus the formatting was changed few times, so we cannot have a base rule for
|
||||||
# (see _commercial_fields()), so they are automatically consistent.
|
# checking if available and emmited by the Ministry of Finance, only online on their website.
|
||||||
cr.execute("""
|
cr.execute("""
|
||||||
DROP INDEX IF EXISTS res_partner_vat_uniq_for_companies;
|
DROP INDEX IF EXISTS res_partner_vat_uniq_for_companies;
|
||||||
DROP INDEX IF EXISTS res_partner_nrc_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
|
return result
|
||||||
|
|
||||||
|
|
|
@ -392,7 +392,7 @@ class mrp_repair(osv.osv):
|
||||||
'origin':repair.name,
|
'origin':repair.name,
|
||||||
'type': 'out_invoice',
|
'type': 'out_invoice',
|
||||||
'account_id': account_id,
|
'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,
|
'currency_id': repair.pricelist_id.currency_id.id,
|
||||||
'comment': repair.quotation_notes,
|
'comment': repair.quotation_notes,
|
||||||
'fiscal_position': repair.partner_id.property_account_position.id
|
'fiscal_position': repair.partner_id.property_account_position.id
|
||||||
|
|
|
@ -203,6 +203,7 @@ class stock_return_picking(osv.osv_memory):
|
||||||
'location_id': new_location,
|
'location_id': new_location,
|
||||||
'location_dest_id': move.location_id.id,
|
'location_dest_id': move.location_id.id,
|
||||||
'date': date_cur,
|
'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)
|
move_obj.write(cr, uid, [move.id], {'move_history_ids2':[(4,new_move)]}, context=context)
|
||||||
if not returned_lines:
|
if not returned_lines:
|
||||||
|
|
|
@ -159,7 +159,7 @@ class survey_question_wiz(osv.osv_memory):
|
||||||
title = sur_rec.title
|
title = sur_rec.title
|
||||||
xml_form = etree.Element('form', {'string': tools.ustr(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'):
|
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'})
|
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' :'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)})
|
etree.SubElement(xml_group3, 'button', {'string' :'Edit Page','icon': "gtk-edit", 'type' :'object','name':"action_edit_page", 'context' : tools.ustr(context)})
|
||||||
|
|
|
@ -1015,7 +1015,7 @@ instance.web.UserMenu = instance.web.Widget.extend({
|
||||||
this.update_promise = this.update_promise.then(fct, fct);
|
this.update_promise = this.update_promise.then(fct, fct);
|
||||||
},
|
},
|
||||||
on_menu_help: function() {
|
on_menu_help: function() {
|
||||||
window.open('http://help.openerp.com', '_blank');
|
window.open('http://help.odoo.com', '_blank');
|
||||||
},
|
},
|
||||||
on_menu_logout: function() {
|
on_menu_logout: function() {
|
||||||
this.trigger('user_logout');
|
this.trigger('user_logout');
|
||||||
|
@ -1044,10 +1044,10 @@ instance.web.UserMenu = instance.web.Widget.extend({
|
||||||
state: JSON.stringify(state),
|
state: JSON.stringify(state),
|
||||||
scope: 'userinfo',
|
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){
|
}).fail(function(result, ev){
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
instance.web.redirect('https://accounts.openerp.com/web');
|
instance.web.redirect('https://accounts.odoo.com/web');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -923,6 +923,8 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({
|
||||||
sign = -1;
|
sign = -1;
|
||||||
field = field.slice(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])
|
//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])){
|
if(_.isArray(a[field]) && a[field].length == 2 && _.isString(a[field][1])){
|
||||||
return sign * compare(a[field][1], b[field][1]);
|
return sign * compare(a[field][1], b[field][1]);
|
||||||
|
|
|
@ -24,7 +24,7 @@ from email.MIMEBase import MIMEBase
|
||||||
from email.MIMEMultipart import MIMEMultipart
|
from email.MIMEMultipart import MIMEMultipart
|
||||||
from email.Charset import Charset
|
from email.Charset import Charset
|
||||||
from email.Header import Header
|
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
|
from email import Encoders
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
@ -120,6 +120,7 @@ def encode_header_param(param_text):
|
||||||
return param_text_ascii if param_text_ascii\
|
return param_text_ascii if param_text_ascii\
|
||||||
else Charset('utf8').header_encode(param_text_utf8)
|
else Charset('utf8').header_encode(param_text_utf8)
|
||||||
|
|
||||||
|
# TODO master, remove me, no longer used internaly
|
||||||
name_with_email_pattern = re.compile(r'("[^<@>]+")\s*<([^ ,<@]+@[^> ,]+)>')
|
name_with_email_pattern = re.compile(r'("[^<@>]+")\s*<([^ ,<@]+@[^> ,]+)>')
|
||||||
address_pattern = re.compile(r'([^ ,<@]+@[^> ,]+)')
|
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)
|
header_text_ascii = try_coerce_ascii(header_text_utf8)
|
||||||
if header_text_ascii:
|
if header_text_ascii:
|
||||||
return 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
|
# non-ASCII characters are present, attempt to
|
||||||
# replace all "Name" patterns with the RFC2047-
|
# replace all "Name" patterns with the RFC2047-
|
||||||
# encoded version
|
# encoded version
|
||||||
def replace(match_obj):
|
name_encoded = str(Header(name, 'utf-8'))
|
||||||
name, email = match_obj.group(1), match_obj.group(2)
|
header_text_utf8 = "%s <%s>" % (name_encoded, email)
|
||||||
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)
|
|
||||||
# try again after encoding
|
# try again after encoding
|
||||||
header_text_ascii = try_coerce_ascii(header_text_utf8)
|
header_text_ascii = try_coerce_ascii(header_text_utf8)
|
||||||
if header_text_ascii:
|
if header_text_ascii:
|
||||||
|
|
|
@ -3699,6 +3699,7 @@ class BaseModel(object):
|
||||||
self.check_access_rights(cr, uid, 'unlink')
|
self.check_access_rights(cr, uid, 'unlink')
|
||||||
|
|
||||||
ir_property = self.pool.get('ir.property')
|
ir_property = self.pool.get('ir.property')
|
||||||
|
ir_attachment_obj = self.pool.get('ir.attachment')
|
||||||
|
|
||||||
# Check if the records are used as default properties.
|
# Check if the records are used as default properties.
|
||||||
domain = [('res_id', '=', False),
|
domain = [('res_id', '=', False),
|
||||||
|
@ -3737,6 +3738,13 @@ class BaseModel(object):
|
||||||
if ir_value_ids:
|
if ir_value_ids:
|
||||||
ir_values_obj.unlink(cr, uid, ir_value_ids, context=context)
|
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:
|
for order, obj_name, store_ids, fields in result_store:
|
||||||
if obj_name == self._name:
|
if obj_name == self._name:
|
||||||
effective_store_ids = list(set(store_ids) - set(ids))
|
effective_store_ids = list(set(store_ids) - set(ids))
|
||||||
|
|
Loading…
Reference in New Issue