[MERGE] Forward-port of latest 7.0 fixes up to rev 9618 rev-id: dle@openerp.com-20131120142131-s333lyva85cyn41o
bzr revid: odo@openerp.com-20131120144059-yyh7emvgdarff09b bzr revid: odo@openerp.com-20131120144318-11nmn1zj00zmi10z
This commit is contained in:
commit
44664076da
|
@ -1447,6 +1447,8 @@ class account_move(osv.osv):
|
||||||
def unlink(self, cr, uid, ids, context=None, check=True):
|
def unlink(self, cr, uid, ids, context=None, check=True):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
|
if isinstance(ids, (int, long)):
|
||||||
|
ids = [ids]
|
||||||
toremove = []
|
toremove = []
|
||||||
obj_move_line = self.pool.get('account.move.line')
|
obj_move_line = self.pool.get('account.move.line')
|
||||||
for move in self.browse(cr, uid, ids, context=context):
|
for move in self.browse(cr, uid, ids, context=context):
|
||||||
|
|
|
@ -311,13 +311,13 @@ class account_move_line(osv.osv):
|
||||||
context = {}
|
context = {}
|
||||||
c = context.copy()
|
c = context.copy()
|
||||||
c['initital_bal'] = True
|
c['initital_bal'] = True
|
||||||
sql = """SELECT l2.id, SUM(l1.debit-l1.credit)
|
sql = """SELECT l1.id, COALESCE(SUM(l2.debit-l2.credit), 0)
|
||||||
FROM account_move_line l1, account_move_line l2
|
FROM account_move_line l1 LEFT JOIN account_move_line l2
|
||||||
WHERE l2.account_id = l1.account_id
|
ON (l1.account_id = l2.account_id
|
||||||
AND l1.id <= l2.id
|
AND l2.id <= l1.id
|
||||||
AND l2.id IN %s AND """ + \
|
AND """ + \
|
||||||
self._query_get(cr, uid, obj='l1', context=c) + \
|
self._query_get(cr, uid, obj='l2', context=c) + \
|
||||||
" GROUP BY l2.id"
|
") WHERE l1.id IN %s GROUP BY l1.id"
|
||||||
|
|
||||||
cr.execute(sql, [tuple(ids)])
|
cr.execute(sql, [tuple(ids)])
|
||||||
return dict(cr.fetchall())
|
return dict(cr.fetchall())
|
||||||
|
|
|
@ -52,10 +52,19 @@ class account_invoice_refund(osv.osv_memory):
|
||||||
journal = obj_journal.search(cr, uid, [('type', '=', type), ('company_id','=',company_id)], limit=1, context=context)
|
journal = obj_journal.search(cr, uid, [('type', '=', type), ('company_id','=',company_id)], limit=1, context=context)
|
||||||
return journal and journal[0] or False
|
return journal and journal[0] or False
|
||||||
|
|
||||||
|
def _get_reason(self, cr, uid, context=None):
|
||||||
|
active_id = context and context.get('active_id', False)
|
||||||
|
if active_id:
|
||||||
|
inv = self.pool.get('account.invoice').browse(cr, uid, active_id, context=context)
|
||||||
|
return inv.name
|
||||||
|
else:
|
||||||
|
return ''
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'date': lambda *a: time.strftime('%Y-%m-%d'),
|
'date': lambda *a: time.strftime('%Y-%m-%d'),
|
||||||
'journal_id': _get_journal,
|
'journal_id': _get_journal,
|
||||||
'filter_refund': 'refund',
|
'filter_refund': 'refund',
|
||||||
|
'description': _get_reason,
|
||||||
}
|
}
|
||||||
|
|
||||||
def fields_view_get(self, cr, uid, view_id=None, view_type=False, context=None, toolbar=False, submenu=False):
|
def fields_view_get(self, cr, uid, view_id=None, view_type=False, context=None, toolbar=False, submenu=False):
|
||||||
|
|
|
@ -39,12 +39,6 @@ openerp.auth_signup = function(instance) {
|
||||||
delete self.params.error_message;
|
delete self.params.error_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
// in case of a signup, retrieve the user information from the token
|
|
||||||
if (dbname && self.params.token) {
|
|
||||||
self.rpc("/auth_signup/retrieve", {dbname: dbname, token: self.params.token})
|
|
||||||
.done(self.on_token_loaded)
|
|
||||||
.fail(self.on_token_failed);
|
|
||||||
}
|
|
||||||
if (dbname && self.params.login) {
|
if (dbname && self.params.login) {
|
||||||
self.$("form input[name=login]").val(self.params.login);
|
self.$("form input[name=login]").val(self.params.login);
|
||||||
}
|
}
|
||||||
|
@ -53,7 +47,7 @@ openerp.auth_signup = function(instance) {
|
||||||
self.$('a.oe_signup_reset_password').click(self.do_reset_password);
|
self.$('a.oe_signup_reset_password').click(self.do_reset_password);
|
||||||
|
|
||||||
if (dbname) {
|
if (dbname) {
|
||||||
self.rpc("/auth_signup/get_config", {dbname: dbname}).done(function(result) {
|
self.rpc("/auth_signup/get_config", {dbname: dbname}).then(function(result) {
|
||||||
self.signup_enabled = result.signup;
|
self.signup_enabled = result.signup;
|
||||||
self.reset_password_enabled = result.reset_password;
|
self.reset_password_enabled = result.reset_password;
|
||||||
if (!self.signup_enabled || self.$("form input[name=login]").val()){
|
if (!self.signup_enabled || self.$("form input[name=login]").val()){
|
||||||
|
@ -61,6 +55,13 @@ openerp.auth_signup = function(instance) {
|
||||||
} else {
|
} else {
|
||||||
self.set('login_mode', 'signup');
|
self.set('login_mode', 'signup');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// in case of a signup, retrieve the user information from the token
|
||||||
|
if (self.params.token) {
|
||||||
|
self.rpc("/auth_signup/retrieve", {dbname: dbname, token: self.params.token})
|
||||||
|
.then(self.on_token_loaded, self.on_token_failed);
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// TODO: support multiple database mode
|
// TODO: support multiple database mode
|
||||||
|
|
|
@ -836,9 +836,11 @@ class crm_lead(format_address, osv.osv):
|
||||||
model_data = self.pool.get('ir.model.data')
|
model_data = self.pool.get('ir.model.data')
|
||||||
phonecall_dict = {}
|
phonecall_dict = {}
|
||||||
if not categ_id:
|
if not categ_id:
|
||||||
res_id = model_data._get_id(cr, uid, 'crm', 'categ_phone2')
|
try:
|
||||||
if res_id:
|
res_id = model_data._get_id(cr, uid, 'crm', 'categ_phone2')
|
||||||
categ_id = model_data.browse(cr, uid, res_id, context=context).res_id
|
categ_id = model_data.browse(cr, uid, res_id, context=context).res_id
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
for lead in self.browse(cr, uid, ids, context=context):
|
for lead in self.browse(cr, uid, ids, context=context):
|
||||||
if not section_id:
|
if not section_id:
|
||||||
section_id = lead.section_id and lead.section_id.id or False
|
section_id = lead.section_id and lead.section_id.id or False
|
||||||
|
@ -945,6 +947,23 @@ class crm_lead(format_address, osv.osv):
|
||||||
vals.update(onchange_stage_values)
|
vals.update(onchange_stage_values)
|
||||||
return super(crm_lead, self).write(cr, uid, ids, vals, context=context)
|
return super(crm_lead, self).write(cr, uid, ids, vals, context=context)
|
||||||
|
|
||||||
|
def copy(self, cr, uid, id, default=None, context=None):
|
||||||
|
if not default:
|
||||||
|
default = {}
|
||||||
|
if not context:
|
||||||
|
context = {}
|
||||||
|
lead = self.browse(cr, uid, id, context=context)
|
||||||
|
local_context = dict(context)
|
||||||
|
local_context.setdefault('default_type', lead.type)
|
||||||
|
local_context.setdefault('default_section_id', lead.section_id)
|
||||||
|
if lead.type == 'opportunity':
|
||||||
|
default['date_open'] = fields.datetime.now()
|
||||||
|
else:
|
||||||
|
default['date_open'] = False
|
||||||
|
default['date_closed'] = False
|
||||||
|
default['stage_id'] = self._get_default_stage_id(cr, uid, local_context)
|
||||||
|
return super(crm_lead, self).copy(cr, uid, id, default, context=context)
|
||||||
|
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
# Mail Gateway
|
# Mail Gateway
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
|
|
|
@ -323,7 +323,7 @@
|
||||||
<field name="model">crm.lead</field>
|
<field name="model">crm.lead</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<search string="Search Leads">
|
<search string="Search Leads">
|
||||||
<field name="name" string="Lead / Customer" filter_domain="['|','|',('partner_name','ilike',self),('email_from','ilike',self),('name','ilike',self)]"/>
|
<field name="name" string="Lead / Customer" filter_domain="['|','|','|',('partner_name','ilike',self),('email_from','ilike',self),('contact_name','ilike',self),('name','ilike',self)]"/>
|
||||||
<field name="categ_ids" string="Category" filter_domain="[('categ_ids','ilike',self)]"/>
|
<field name="categ_ids" string="Category" filter_domain="[('categ_ids','ilike',self)]"/>
|
||||||
<field name="section_id" context="{'invisible_section': False}" groups="base.group_multi_salesteams"/>
|
<field name="section_id" context="{'invisible_section': False}" groups="base.group_multi_salesteams"/>
|
||||||
<field name="user_id"/>
|
<field name="user_id"/>
|
||||||
|
|
|
@ -117,9 +117,11 @@ class crm_phonecall(osv.osv):
|
||||||
model_data = self.pool.get('ir.model.data')
|
model_data = self.pool.get('ir.model.data')
|
||||||
phonecall_dict = {}
|
phonecall_dict = {}
|
||||||
if not categ_id:
|
if not categ_id:
|
||||||
res_id = model_data._get_id(cr, uid, 'crm', 'categ_phone2')
|
try:
|
||||||
if res_id:
|
res_id = model_data._get_id(cr, uid, 'crm', 'categ_phone2')
|
||||||
categ_id = model_data.browse(cr, uid, res_id, context=context).res_id
|
categ_id = model_data.browse(cr, uid, res_id, context=context).res_id
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
for call in self.browse(cr, uid, ids, context=context):
|
for call in self.browse(cr, uid, ids, context=context):
|
||||||
if not section_id:
|
if not section_id:
|
||||||
section_id = call.section_id and call.section_id.id or False
|
section_id = call.section_id and call.section_id.id or False
|
||||||
|
|
|
@ -34,9 +34,11 @@ class crm_opportunity2phonecall(osv.osv_memory):
|
||||||
opp_obj = self.pool.get('crm.lead')
|
opp_obj = self.pool.get('crm.lead')
|
||||||
categ_id = False
|
categ_id = False
|
||||||
data_obj = self.pool.get('ir.model.data')
|
data_obj = self.pool.get('ir.model.data')
|
||||||
res_id = data_obj._get_id(cr, uid, 'crm', 'categ_phone2')
|
try:
|
||||||
if res_id:
|
res_id = data_obj._get_id(cr, uid, 'crm', 'categ_phone2')
|
||||||
categ_id = data_obj.browse(cr, uid, res_id, context=context).res_id
|
categ_id = data_obj.browse(cr, uid, res_id, context=context).res_id
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
record_ids = context and context.get('active_ids', []) or []
|
record_ids = context and context.get('active_ids', []) or []
|
||||||
res = {}
|
res = {}
|
||||||
|
|
|
@ -78,9 +78,11 @@ class crm_phonecall2phonecall(osv.osv_memory):
|
||||||
|
|
||||||
categ_id = False
|
categ_id = False
|
||||||
data_obj = self.pool.get('ir.model.data')
|
data_obj = self.pool.get('ir.model.data')
|
||||||
res_id = data_obj._get_id(cr, uid, 'crm', 'categ_phone2')
|
try:
|
||||||
if res_id:
|
res_id = data_obj._get_id(cr, uid, 'crm', 'categ_phone2')
|
||||||
categ_id = data_obj.browse(cr, uid, res_id, context=context).res_id
|
categ_id = data_obj.browse(cr, uid, res_id, context=context).res_id
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
if 'name' in fields:
|
if 'name' in fields:
|
||||||
res.update({'name': phonecall.name})
|
res.update({'name': phonecall.name})
|
||||||
|
|
|
@ -108,7 +108,7 @@ class crm_claim(osv.osv):
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'user_id': lambda s, cr, uid, c: uid,
|
'user_id': lambda s, cr, uid, c: uid,
|
||||||
'section_id': lambda s, cr, uid, c: s._get_default_section_id(cr, uid, c),
|
'section_id': lambda s, cr, uid, c: s._get_default_section_id(cr, uid, c),
|
||||||
'date': fields.datetime.now(),
|
'date': fields.datetime.now,
|
||||||
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.case', context=c),
|
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.case', context=c),
|
||||||
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
|
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
|
||||||
'active': lambda *a: 1,
|
'active': lambda *a: 1,
|
||||||
|
@ -172,7 +172,8 @@ class crm_claim(osv.osv):
|
||||||
through message_process.
|
through message_process.
|
||||||
This override updates the document according to the email.
|
This override updates the document according to the email.
|
||||||
"""
|
"""
|
||||||
if custom_values is None: custom_values = {}
|
if custom_values is None:
|
||||||
|
custom_values = {}
|
||||||
desc = html2plaintext(msg.get('body')) if msg.get('body') else ''
|
desc = html2plaintext(msg.get('body')) if msg.get('body') else ''
|
||||||
defaults = {
|
defaults = {
|
||||||
'name': msg.get('subject') or _("No Subject"),
|
'name': msg.get('subject') or _("No Subject"),
|
||||||
|
@ -184,33 +185,7 @@ class crm_claim(osv.osv):
|
||||||
if msg.get('priority'):
|
if msg.get('priority'):
|
||||||
defaults['priority'] = msg.get('priority')
|
defaults['priority'] = msg.get('priority')
|
||||||
defaults.update(custom_values)
|
defaults.update(custom_values)
|
||||||
return super(crm_claim,self).message_new(cr, uid, msg, custom_values=defaults, context=context)
|
return super(crm_claim, self).message_new(cr, uid, msg, custom_values=defaults, context=context)
|
||||||
|
|
||||||
def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
|
|
||||||
""" Overrides mail_thread message_update that is called by the mailgateway
|
|
||||||
through message_process.
|
|
||||||
This method updates the document according to the email.
|
|
||||||
"""
|
|
||||||
if isinstance(ids, (str, int, long)):
|
|
||||||
ids = [ids]
|
|
||||||
if update_vals is None: update_vals = {}
|
|
||||||
|
|
||||||
if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
|
|
||||||
update_vals['priority'] = msg.get('priority')
|
|
||||||
|
|
||||||
maps = {
|
|
||||||
'cost':'planned_cost',
|
|
||||||
'revenue': 'planned_revenue',
|
|
||||||
'probability':'probability'
|
|
||||||
}
|
|
||||||
for line in msg['body'].split('\n'):
|
|
||||||
line = line.strip()
|
|
||||||
res = tools.command_re.match(line)
|
|
||||||
if res and maps.get(res.group(1).lower()):
|
|
||||||
key = maps.get(res.group(1).lower())
|
|
||||||
update_vals[key] = res.group(2).lower()
|
|
||||||
|
|
||||||
return super(crm_claim,self).message_update(cr, uid, ids, msg, update_vals=update_vals, context=context)
|
|
||||||
|
|
||||||
class res_partner(osv.osv):
|
class res_partner(osv.osv):
|
||||||
_inherit = 'res.partner'
|
_inherit = 'res.partner'
|
||||||
|
|
|
@ -80,7 +80,7 @@ class crm_helpdesk(osv.osv):
|
||||||
'active': lambda *a: 1,
|
'active': lambda *a: 1,
|
||||||
'user_id': lambda s, cr, uid, c: uid,
|
'user_id': lambda s, cr, uid, c: uid,
|
||||||
'state': lambda *a: 'draft',
|
'state': lambda *a: 'draft',
|
||||||
'date': lambda *a: fields.datetime.now(),
|
'date': fields.datetime.now,
|
||||||
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.helpdesk', context=c),
|
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.helpdesk', context=c),
|
||||||
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
|
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,8 @@ class crm_helpdesk(osv.osv):
|
||||||
through message_process.
|
through message_process.
|
||||||
This override updates the document according to the email.
|
This override updates the document according to the email.
|
||||||
"""
|
"""
|
||||||
if custom_values is None: custom_values = {}
|
if custom_values is None:
|
||||||
|
custom_values = {}
|
||||||
desc = html2plaintext(msg.get('body')) if msg.get('body') else ''
|
desc = html2plaintext(msg.get('body')) if msg.get('body') else ''
|
||||||
defaults = {
|
defaults = {
|
||||||
'name': msg.get('subject') or _("No Subject"),
|
'name': msg.get('subject') or _("No Subject"),
|
||||||
|
@ -137,32 +138,6 @@ class crm_helpdesk(osv.osv):
|
||||||
'partner_id': msg.get('author_id', False),
|
'partner_id': msg.get('author_id', False),
|
||||||
}
|
}
|
||||||
defaults.update(custom_values)
|
defaults.update(custom_values)
|
||||||
return super(crm_helpdesk,self).message_new(cr, uid, msg, custom_values=defaults, context=context)
|
return super(crm_helpdesk, self).message_new(cr, uid, msg, custom_values=defaults, context=context)
|
||||||
|
|
||||||
def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
|
|
||||||
""" Overrides mail_thread message_update that is called by the mailgateway
|
|
||||||
through message_process.
|
|
||||||
This method updates the document according to the email.
|
|
||||||
"""
|
|
||||||
if isinstance(ids, (str, int, long)):
|
|
||||||
ids = [ids]
|
|
||||||
if update_vals is None: update_vals = {}
|
|
||||||
|
|
||||||
if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
|
|
||||||
update_vals['priority'] = msg.get('priority')
|
|
||||||
|
|
||||||
maps = {
|
|
||||||
'cost':'planned_cost',
|
|
||||||
'revenue': 'planned_revenue',
|
|
||||||
'probability':'probability'
|
|
||||||
}
|
|
||||||
for line in msg['body'].split('\n'):
|
|
||||||
line = line.strip()
|
|
||||||
res = tools.command_re.match(line)
|
|
||||||
if res and maps.get(res.group(1).lower()):
|
|
||||||
key = maps.get(res.group(1).lower())
|
|
||||||
update_vals[key] = res.group(2).lower()
|
|
||||||
|
|
||||||
return super(crm_helpdesk,self).message_update(cr, uid, ids, msg, update_vals=update_vals, context=context)
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -187,6 +187,9 @@ class stock_move(osv.osv):
|
||||||
# Redefinition of the new fields in order to update the model stock.picking.out in the orm
|
# Redefinition of the new fields in order to update the model stock.picking.out in the orm
|
||||||
# FIXME: this is a temporary workaround because of a framework bug (ref: lp996816). It should be removed as soon as
|
# FIXME: this is a temporary workaround because of a framework bug (ref: lp996816). It should be removed as soon as
|
||||||
# the bug is fixed
|
# the bug is fixed
|
||||||
|
|
||||||
|
# TODO in trunk: Remove the duplication below using a mixin class!
|
||||||
|
|
||||||
class stock_picking_out(osv.osv):
|
class stock_picking_out(osv.osv):
|
||||||
_inherit = 'stock.picking.out'
|
_inherit = 'stock.picking.out'
|
||||||
|
|
||||||
|
@ -212,6 +215,7 @@ class stock_picking_out(osv.osv):
|
||||||
}),
|
}),
|
||||||
'carrier_tracking_ref': fields.char('Carrier Tracking Ref', size=32),
|
'carrier_tracking_ref': fields.char('Carrier Tracking Ref', size=32),
|
||||||
'number_of_packages': fields.integer('Number of Packages'),
|
'number_of_packages': fields.integer('Number of Packages'),
|
||||||
|
'weight_uom_id': fields.many2one('product.uom', 'Unit of Measure', required=True,readonly="1",help="Unit of measurement for Weight",),
|
||||||
}
|
}
|
||||||
|
|
||||||
class stock_picking_in(osv.osv):
|
class stock_picking_in(osv.osv):
|
||||||
|
@ -224,6 +228,8 @@ class stock_picking_in(osv.osv):
|
||||||
return self.pool.get('stock.picking')._get_picking_line(cr, uid, ids, context=context)
|
return self.pool.get('stock.picking')._get_picking_line(cr, uid, ids, context=context)
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
|
'carrier_id':fields.many2one("delivery.carrier","Carrier"),
|
||||||
|
'volume': fields.float('Volume'),
|
||||||
'weight': fields.function(_cal_weight, type='float', string='Weight', digits_compute= dp.get_precision('Stock Weight'), multi='_cal_weight',
|
'weight': fields.function(_cal_weight, type='float', string='Weight', digits_compute= dp.get_precision('Stock Weight'), multi='_cal_weight',
|
||||||
store={
|
store={
|
||||||
'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 20),
|
'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 20),
|
||||||
|
@ -234,6 +240,9 @@ class stock_picking_in(osv.osv):
|
||||||
'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 20),
|
'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 20),
|
||||||
'stock.move': (_get_picking_line, ['product_id','product_qty','product_uom','product_uos_qty'], 20),
|
'stock.move': (_get_picking_line, ['product_id','product_qty','product_uom','product_uos_qty'], 20),
|
||||||
}),
|
}),
|
||||||
|
'carrier_tracking_ref': fields.char('Carrier Tracking Ref', size=32),
|
||||||
|
'number_of_packages': fields.integer('Number of Packages'),
|
||||||
|
'weight_uom_id': fields.many2one('product.uom', 'Unit of Measure', required=True,readonly="1",help="Unit of measurement for Weight",),
|
||||||
}
|
}
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -9,7 +9,7 @@ openerp.document = function (instance) {
|
||||||
on_attachments_loaded: function(attachments) {
|
on_attachments_loaded: function(attachments) {
|
||||||
//to display number in name if more then one attachment which has same name.
|
//to display number in name if more then one attachment which has same name.
|
||||||
var self = this;
|
var self = this;
|
||||||
_.chain(attachments.reverse())
|
_.chain(attachments)
|
||||||
.groupBy(function(attachment) { return attachment.name})
|
.groupBy(function(attachment) { return attachment.name})
|
||||||
.each(function(attachment){
|
.each(function(attachment){
|
||||||
if(attachment.length > 1)
|
if(attachment.length > 1)
|
||||||
|
|
|
@ -333,7 +333,8 @@ class hr_applicant(osv.Model):
|
||||||
through message_process.
|
through message_process.
|
||||||
This override updates the document according to the email.
|
This override updates the document according to the email.
|
||||||
"""
|
"""
|
||||||
if custom_values is None: custom_values = {}
|
if custom_values is None:
|
||||||
|
custom_values = {}
|
||||||
val = msg.get('from').split('<')[0]
|
val = msg.get('from').split('<')[0]
|
||||||
defaults = {
|
defaults = {
|
||||||
'name': msg.get('subject') or _("No Subject"),
|
'name': msg.get('subject') or _("No Subject"),
|
||||||
|
@ -346,38 +347,7 @@ class hr_applicant(osv.Model):
|
||||||
if msg.get('priority'):
|
if msg.get('priority'):
|
||||||
defaults['priority'] = msg.get('priority')
|
defaults['priority'] = msg.get('priority')
|
||||||
defaults.update(custom_values)
|
defaults.update(custom_values)
|
||||||
return super(hr_applicant,self).message_new(cr, uid, msg, custom_values=defaults, context=context)
|
return super(hr_applicant, self).message_new(cr, uid, msg, custom_values=defaults, context=context)
|
||||||
|
|
||||||
def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
|
|
||||||
""" Override mail_thread message_update that is called by the mailgateway
|
|
||||||
through message_process.
|
|
||||||
This method updates the document according to the email.
|
|
||||||
"""
|
|
||||||
if isinstance(ids, (str, int, long)):
|
|
||||||
ids = [ids]
|
|
||||||
if update_vals is None:
|
|
||||||
update_vals = {}
|
|
||||||
|
|
||||||
update_vals.update({
|
|
||||||
'email_from': msg.get('from'),
|
|
||||||
'email_cc': msg.get('cc'),
|
|
||||||
})
|
|
||||||
if msg.get('priority'):
|
|
||||||
update_vals['priority'] = msg.get('priority')
|
|
||||||
|
|
||||||
maps = {
|
|
||||||
'cost': 'planned_cost',
|
|
||||||
'revenue': 'planned_revenue',
|
|
||||||
'probability': 'probability',
|
|
||||||
}
|
|
||||||
for line in msg.get('body', '').split('\n'):
|
|
||||||
line = line.strip()
|
|
||||||
res = tools.command_re.match(line)
|
|
||||||
if res and maps.get(res.group(1).lower(), False):
|
|
||||||
key = maps.get(res.group(1).lower())
|
|
||||||
update_vals[key] = res.group(2).lower()
|
|
||||||
|
|
||||||
return super(hr_applicant, self).message_update(cr, uid, ids, msg, update_vals=update_vals, context=context)
|
|
||||||
|
|
||||||
def create(self, cr, uid, vals, context=None):
|
def create(self, cr, uid, vals, context=None):
|
||||||
if context is None:
|
if context is None:
|
||||||
|
|
|
@ -185,7 +185,7 @@ class l10n_be_vat_declaration(osv.osv_memory):
|
||||||
for item in cases_list:
|
for item in cases_list:
|
||||||
grid_amount_data = {
|
grid_amount_data = {
|
||||||
'code': str(int(item['code'])),
|
'code': str(int(item['code'])),
|
||||||
'amount': str(abs(item['sum_period'])),
|
'amount': '%.2f' % abs(item['sum_period']),
|
||||||
}
|
}
|
||||||
data_of_file += '\n\t\t\t<ns2:Amount GridNumber="%(code)s">%(amount)s</ns2:Amount''>' % (grid_amount_data)
|
data_of_file += '\n\t\t\t<ns2:Amount GridNumber="%(code)s">%(amount)s</ns2:Amount''>' % (grid_amount_data)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
"id","amount_select","condition_range_min","condition_range_max","amount_percentage","amount_fix","name","category_id","sequence","code","parent_rule_id/id","condition_select","condition_range","amount_percentage_base"
|
"id","amount_select","condition_range_min","condition_range_max","amount_percentage","amount_fix","name","category_id/id","sequence","code","parent_rule_id/id","condition_select","condition_range","amount_percentage_base"
|
||||||
1,"fix",1,1,,100,"Education Allowance For One Child","Allowance",23,"CHEAONE","hr_payroll_rule_child1","range","employee.children",
|
1,"fix",1,1,,100,"Education Allowance For One Child",hr_payroll.ALW,23,"CHEAONE","hr_payroll_rule_child1","range","employee.children",
|
||||||
2,"fix",2,10,,200,"Education Allowance For Two Child","Allowance",24,"CHEATWO","hr_payroll_rule_child1","range","employee.children",
|
2,"fix",2,10,,200,"Education Allowance For Two Child",hr_payroll.ALW,24,"CHEATWO","hr_payroll_rule_child1","range","employee.children",
|
||||||
3,"fix",1,1,,300,"Child Hostel Allowance For One Child","Allowance",26,"CHOONE","hr_payroll_rule_child2","range","employee.children",
|
3,"fix",1,1,,300,"Child Hostel Allowance For One Child",hr_payroll.ALW,26,"CHOONE","hr_payroll_rule_child2","range","employee.children",
|
||||||
4,"fix",2,10,,600,"Child Hostel Allowance For Two Child","Allowance",27,"CHOTWO","hr_payroll_rule_child2","range","employee.children",
|
4,"fix",2,10,,600,"Child Hostel Allowance For Two Child",hr_payroll.ALW,27,"CHOTWO","hr_payroll_rule_child2","range","employee.children",
|
||||||
|
|
|
|
@ -33,6 +33,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
|
||||||
"""
|
"""
|
||||||
_inherit = 'wizard.multi.charts.accounts'
|
_inherit = 'wizard.multi.charts.accounts'
|
||||||
|
|
||||||
|
# FIXME: in trunk, drop the force_write param entirely
|
||||||
def process_translations(self, cr, uid, langs, in_obj, in_field, in_ids, out_obj, out_ids, force_write=False, context=None):
|
def process_translations(self, cr, uid, langs, in_obj, in_field, in_ids, out_obj, out_ids, force_write=False, context=None):
|
||||||
"""
|
"""
|
||||||
This method copies translations values of templates into new Accounts/Taxes/Journals for languages selected
|
This method copies translations values of templates into new Accounts/Taxes/Journals for languages selected
|
||||||
|
@ -45,8 +46,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
|
||||||
:param in_ids: List of ids of source object
|
:param in_ids: List of ids of source object
|
||||||
:param out_obj: Destination object for which translation is to be copied
|
:param out_obj: Destination object for which translation is to be copied
|
||||||
:param out_ids: List of ids of destination object
|
:param out_ids: List of ids of destination object
|
||||||
:param force_write: boolean that depicts if we need to create a translation OR simply replace the actual value
|
:param force_write: Deprecated as of 7.0, do not use
|
||||||
with the translation in the uid's language by doing a write (in case it's TRUE)
|
|
||||||
:param context: usual context information. May contain the key 'lang', which is the language of the user running
|
:param context: usual context information. May contain the key 'lang', which is the language of the user running
|
||||||
the wizard, that will be used if force_write is True
|
the wizard, that will be used if force_write is True
|
||||||
|
|
||||||
|
@ -65,26 +65,25 @@ class wizard_multi_charts_accounts(osv.osv_memory):
|
||||||
for j in range(len(in_ids)):
|
for j in range(len(in_ids)):
|
||||||
in_id = in_ids[j]
|
in_id = in_ids[j]
|
||||||
if value[in_id]:
|
if value[in_id]:
|
||||||
if not force_write:
|
#copy Translation from Source to Destination object
|
||||||
#copy Translation from Source to Destination object
|
xlat_obj.create(cr, uid, {
|
||||||
xlat_obj.create(cr, uid, {
|
'name': out_obj._name + ',' + in_field,
|
||||||
'name': out_obj._name + ',' + in_field,
|
'type': 'model',
|
||||||
'type': 'model',
|
'res_id': out_ids[j],
|
||||||
'res_id': out_ids[j],
|
'lang': lang,
|
||||||
'lang': lang,
|
'src': src[in_id],
|
||||||
'src': src[in_id],
|
'value': value[in_id],
|
||||||
'value': value[in_id],
|
|
||||||
})
|
})
|
||||||
else:
|
|
||||||
#replace the value in the destination object only if it's the user lang
|
|
||||||
if context.get('lang') == lang:
|
|
||||||
self.pool[out_obj._name].write(cr, uid, out_ids[j], {in_field: value[in_id]})
|
|
||||||
else:
|
else:
|
||||||
_logger.info('Language: %s. Translation from template: there is no translation available for %s!' %(lang, src[in_id]))#out_obj._name))
|
_logger.info('Language: %s. Translation from template: there is no translation available for %s!' %(lang, src[in_id]))#out_obj._name))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def execute(self, cr, uid, ids, context=None):
|
def execute(self, cr, uid, ids, context=None):
|
||||||
res = super(wizard_multi_charts_accounts, self).execute(cr, uid, ids, context=context)
|
if not context:
|
||||||
|
context = {}
|
||||||
|
# remove the lang to get the untranslated value
|
||||||
|
ctx = dict(context, lang=None)
|
||||||
|
res = super(wizard_multi_charts_accounts, self).execute(cr, uid, ids, context=ctx)
|
||||||
|
|
||||||
obj_multi = self.browse(cr, uid, ids[0], context=context)
|
obj_multi = self.browse(cr, uid, ids[0], context=context)
|
||||||
company_id = obj_multi.company_id.id
|
company_id = obj_multi.company_id.id
|
||||||
|
@ -125,7 +124,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
|
||||||
acc_root_id = obj_acc.search(cr, uid, [('company_id', '=', company_id), ('parent_id', '=', None)])[0]
|
acc_root_id = obj_acc.search(cr, uid, [('company_id', '=', company_id), ('parent_id', '=', None)])[0]
|
||||||
in_ids = obj_acc_template.search(cr, uid, [('id', 'child_of', [acc_template_root_id])], order='id')[1:]
|
in_ids = obj_acc_template.search(cr, uid, [('id', 'child_of', [acc_template_root_id])], order='id')[1:]
|
||||||
out_ids = obj_acc.search(cr, uid, [('id', 'child_of', [acc_root_id])], order='id')[1:]
|
out_ids = obj_acc.search(cr, uid, [('id', 'child_of', [acc_root_id])], order='id')[1:]
|
||||||
return self.process_translations(cr, uid, langs, obj_acc_template, field, in_ids, obj_acc, out_ids, force_write=True, context=context)
|
return self.process_translations(cr, uid, langs, obj_acc_template, field, in_ids, obj_acc, out_ids, context=context)
|
||||||
|
|
||||||
def _process_tax_codes_translations(self, cr, uid, obj_multi, company_id, langs, field, context=None):
|
def _process_tax_codes_translations(self, cr, uid, obj_multi, company_id, langs, field, context=None):
|
||||||
obj_tax_code_template = self.pool.get('account.tax.code.template')
|
obj_tax_code_template = self.pool.get('account.tax.code.template')
|
||||||
|
@ -134,21 +133,21 @@ class wizard_multi_charts_accounts(osv.osv_memory):
|
||||||
tax_code_root_id = obj_tax_code.search(cr, uid, [('company_id', '=', company_id), ('parent_id', '=', None)])[0]
|
tax_code_root_id = obj_tax_code.search(cr, uid, [('company_id', '=', company_id), ('parent_id', '=', None)])[0]
|
||||||
in_ids = obj_tax_code_template.search(cr, uid, [('id', 'child_of', [tax_code_template_root_id])], order='id')[1:]
|
in_ids = obj_tax_code_template.search(cr, uid, [('id', 'child_of', [tax_code_template_root_id])], order='id')[1:]
|
||||||
out_ids = obj_tax_code.search(cr, uid, [('id', 'child_of', [tax_code_root_id])], order='id')[1:]
|
out_ids = obj_tax_code.search(cr, uid, [('id', 'child_of', [tax_code_root_id])], order='id')[1:]
|
||||||
return self.process_translations(cr, uid, langs, obj_tax_code_template, field, in_ids, obj_tax_code, out_ids, force_write=False, context=context)
|
return self.process_translations(cr, uid, langs, obj_tax_code_template, field, in_ids, obj_tax_code, out_ids, context=context)
|
||||||
|
|
||||||
def _process_taxes_translations(self, cr, uid, obj_multi, company_id, langs, field, context=None):
|
def _process_taxes_translations(self, cr, uid, obj_multi, company_id, langs, field, context=None):
|
||||||
obj_tax_template = self.pool.get('account.tax.template')
|
obj_tax_template = self.pool.get('account.tax.template')
|
||||||
obj_tax = self.pool.get('account.tax')
|
obj_tax = self.pool.get('account.tax')
|
||||||
in_ids = sorted([x.id for x in obj_multi.chart_template_id.tax_template_ids])
|
in_ids = sorted([x.id for x in obj_multi.chart_template_id.tax_template_ids])
|
||||||
out_ids = obj_tax.search(cr, uid, [('company_id', '=', company_id)], order='id')
|
out_ids = obj_tax.search(cr, uid, [('company_id', '=', company_id)], order='id')
|
||||||
return self.process_translations(cr, uid, langs, obj_tax_template, field, in_ids, obj_tax, out_ids, force_write=False, context=context)
|
return self.process_translations(cr, uid, langs, obj_tax_template, field, in_ids, obj_tax, out_ids, context=context)
|
||||||
|
|
||||||
def _process_fiscal_pos_translations(self, cr, uid, obj_multi, company_id, langs, field, context=None):
|
def _process_fiscal_pos_translations(self, cr, uid, obj_multi, company_id, langs, field, context=None):
|
||||||
obj_fiscal_position_template = self.pool.get('account.fiscal.position.template')
|
obj_fiscal_position_template = self.pool.get('account.fiscal.position.template')
|
||||||
obj_fiscal_position = self.pool.get('account.fiscal.position')
|
obj_fiscal_position = self.pool.get('account.fiscal.position')
|
||||||
in_ids = obj_fiscal_position_template.search(cr, uid, [('chart_template_id', '=', obj_multi.chart_template_id.id)], order='id')
|
in_ids = obj_fiscal_position_template.search(cr, uid, [('chart_template_id', '=', obj_multi.chart_template_id.id)], order='id')
|
||||||
out_ids = obj_fiscal_position.search(cr, uid, [('company_id', '=', company_id)], order='id')
|
out_ids = obj_fiscal_position.search(cr, uid, [('company_id', '=', company_id)], order='id')
|
||||||
return self.process_translations(cr, uid, langs, obj_fiscal_position_template, field, in_ids, obj_fiscal_position, out_ids, force_write=False, context=context)
|
return self.process_translations(cr, uid, langs, obj_fiscal_position_template, field, in_ids, obj_fiscal_position, out_ids, context=context)
|
||||||
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -33,6 +33,7 @@ from openerp import tools
|
||||||
from openerp import SUPERUSER_ID
|
from openerp import SUPERUSER_ID
|
||||||
from openerp.addons.mail.mail_message import decode
|
from openerp.addons.mail.mail_message import decode
|
||||||
from openerp.osv import fields, osv, orm
|
from openerp.osv import fields, osv, orm
|
||||||
|
from openerp.osv.orm import browse_record, browse_null
|
||||||
from openerp.tools.safe_eval import safe_eval as eval
|
from openerp.tools.safe_eval import safe_eval as eval
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
|
|
||||||
|
@ -328,11 +329,11 @@ class mail_thread(osv.AbstractModel):
|
||||||
if not context.get('mail_create_nosubscribe'):
|
if not context.get('mail_create_nosubscribe'):
|
||||||
self.message_subscribe_users(cr, uid, [thread_id], [uid], context=context)
|
self.message_subscribe_users(cr, uid, [thread_id], [uid], context=context)
|
||||||
# auto_subscribe: take values and defaults into account
|
# auto_subscribe: take values and defaults into account
|
||||||
create_values = set(values.keys())
|
create_values = dict(values)
|
||||||
for key, val in context.iteritems():
|
for key, val in context.iteritems():
|
||||||
if key.startswith('default_'):
|
if key.startswith('default_'):
|
||||||
create_values.add(key[8:])
|
create_values[key[8:]] = val
|
||||||
self.message_auto_subscribe(cr, uid, [thread_id], list(create_values), context=context)
|
self.message_auto_subscribe(cr, uid, [thread_id], create_values.keys(), context=context, values=create_values)
|
||||||
|
|
||||||
# track values
|
# track values
|
||||||
tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=context)
|
tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=context)
|
||||||
|
@ -353,7 +354,7 @@ class mail_thread(osv.AbstractModel):
|
||||||
|
|
||||||
# Perform write, update followers
|
# Perform write, update followers
|
||||||
result = super(mail_thread, self).write(cr, uid, ids, values, context=context)
|
result = super(mail_thread, self).write(cr, uid, ids, values, context=context)
|
||||||
self.message_auto_subscribe(cr, uid, ids, values.keys(), context=context)
|
self.message_auto_subscribe(cr, uid, ids, values.keys(), context=context, values=values)
|
||||||
|
|
||||||
# Perform the tracking
|
# Perform the tracking
|
||||||
if tracked_fields:
|
if tracked_fields:
|
||||||
|
@ -1539,75 +1540,100 @@ class mail_thread(osv.AbstractModel):
|
||||||
user_field_lst.append(name)
|
user_field_lst.append(name)
|
||||||
return user_field_lst
|
return user_field_lst
|
||||||
|
|
||||||
def message_auto_subscribe(self, cr, uid, ids, updated_fields, context=None):
|
def message_auto_subscribe(self, cr, uid, ids, updated_fields, context=None, values=None):
|
||||||
"""
|
""" Handle auto subscription. Two methods for auto subscription exist:
|
||||||
1. fetch project subtype related to task (parent_id.res_model = 'project.task')
|
|
||||||
2. for each project subtype: subscribe the follower to the task
|
- tracked res.users relational fields, such as user_id fields. Those fields
|
||||||
|
must be relation fields toward a res.users record, and must have the
|
||||||
|
track_visilibity attribute set.
|
||||||
|
- using subtypes parent relationship: check if the current model being
|
||||||
|
modified has an header record (such as a project for tasks) whose followers
|
||||||
|
can be added as followers of the current records. Example of structure
|
||||||
|
with project and task:
|
||||||
|
|
||||||
|
- st_project_1.parent_id = st_task_1
|
||||||
|
- st_project_1.res_model = 'project.project'
|
||||||
|
- st_project_1.relation_field = 'project_id'
|
||||||
|
- st_task_1.model = 'project.task'
|
||||||
|
|
||||||
|
:param list updated_fields: list of updated fields to track
|
||||||
|
:param dict values: updated values; if None, the first record will be browsed
|
||||||
|
to get the values. Added after releasing 7.0, therefore
|
||||||
|
not merged with updated_fields argumment.
|
||||||
"""
|
"""
|
||||||
subtype_obj = self.pool.get('mail.message.subtype')
|
subtype_obj = self.pool.get('mail.message.subtype')
|
||||||
follower_obj = self.pool.get('mail.followers')
|
follower_obj = self.pool.get('mail.followers')
|
||||||
|
new_followers = dict()
|
||||||
|
|
||||||
# fetch auto_follow_fields
|
# fetch auto_follow_fields: res.users relation fields whose changes are tracked for subscription
|
||||||
user_field_lst = self._message_get_auto_subscribe_fields(cr, uid, updated_fields, context=context)
|
user_field_lst = self._message_get_auto_subscribe_fields(cr, uid, updated_fields, context=context)
|
||||||
|
|
||||||
# fetch related record subtypes
|
# fetch header subtypes
|
||||||
related_subtype_ids = subtype_obj.search(cr, uid, ['|', ('res_model', '=', False), ('parent_id.res_model', '=', self._name)], context=context)
|
header_subtype_ids = subtype_obj.search(cr, uid, ['|', ('res_model', '=', False), ('parent_id.res_model', '=', self._name)], context=context)
|
||||||
subtypes = subtype_obj.browse(cr, uid, related_subtype_ids, context=context)
|
subtypes = subtype_obj.browse(cr, uid, header_subtype_ids, context=context)
|
||||||
default_subtypes = [subtype for subtype in subtypes if subtype.res_model == False]
|
|
||||||
related_subtypes = [subtype for subtype in subtypes if subtype.res_model != False]
|
# if no change in tracked field or no change in tracked relational field: quit
|
||||||
relation_fields = set([subtype.relation_field for subtype in subtypes if subtype.relation_field != False])
|
relation_fields = set([subtype.relation_field for subtype in subtypes if subtype.relation_field is not False])
|
||||||
if (not related_subtypes or not any(relation in updated_fields for relation in relation_fields)) and not user_field_lst:
|
if not any(relation in updated_fields for relation in relation_fields) and not user_field_lst:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
for record in self.browse(cr, uid, ids, context=context):
|
# legacy behavior: if values is not given, compute the values by browsing
|
||||||
new_followers = dict()
|
# @TDENOTE: remove me in 8.0
|
||||||
parent_res_id = False
|
if values is None:
|
||||||
parent_model = False
|
record = self.browse(cr, uid, ids[0], context=context)
|
||||||
for subtype in related_subtypes:
|
for updated_field in updated_fields:
|
||||||
if not subtype.relation_field or not subtype.parent_id:
|
field_value = getattr(record, updated_field)
|
||||||
continue
|
if isinstance(field_value, browse_record):
|
||||||
if not subtype.relation_field in self._columns or not getattr(record, subtype.relation_field, False):
|
field_value = field_value.id
|
||||||
continue
|
elif isinstance(field_value, browse_null):
|
||||||
parent_res_id = getattr(record, subtype.relation_field).id
|
field_value = False
|
||||||
parent_model = subtype.res_model
|
values[updated_field] = field_value
|
||||||
follower_ids = follower_obj.search(cr, SUPERUSER_ID, [
|
|
||||||
('res_model', '=', parent_model),
|
|
||||||
('res_id', '=', parent_res_id),
|
|
||||||
('subtype_ids', 'in', [subtype.id])
|
|
||||||
], context=context)
|
|
||||||
for follower in follower_obj.browse(cr, SUPERUSER_ID, follower_ids, context=context):
|
|
||||||
new_followers.setdefault(follower.partner_id.id, set()).add(subtype.parent_id.id)
|
|
||||||
|
|
||||||
if parent_res_id and parent_model:
|
# find followers of headers, update structure for new followers
|
||||||
for subtype in default_subtypes:
|
headers = set()
|
||||||
follower_ids = follower_obj.search(cr, SUPERUSER_ID, [
|
for subtype in subtypes:
|
||||||
('res_model', '=', parent_model),
|
if subtype.relation_field and values.get(subtype.relation_field):
|
||||||
('res_id', '=', parent_res_id),
|
headers.add((subtype.res_model, values.get(subtype.relation_field)))
|
||||||
('subtype_ids', 'in', [subtype.id])
|
if headers:
|
||||||
], context=context)
|
header_domain = ['|'] * (len(headers) - 1)
|
||||||
for follower in follower_obj.browse(cr, SUPERUSER_ID, follower_ids, context=context):
|
for header in headers:
|
||||||
new_followers.setdefault(follower.partner_id.id, set()).add(subtype.id)
|
header_domain += ['&', ('res_model', '=', header[0]), ('res_id', '=', header[1])]
|
||||||
|
header_follower_ids = follower_obj.search(
|
||||||
|
cr, SUPERUSER_ID,
|
||||||
|
header_domain,
|
||||||
|
context=context
|
||||||
|
)
|
||||||
|
for header_follower in follower_obj.browse(cr, SUPERUSER_ID, header_follower_ids, context=context):
|
||||||
|
for subtype in header_follower.subtype_ids:
|
||||||
|
if subtype.res_model and subtype.parent_id:
|
||||||
|
new_followers.setdefault(header_follower.partner_id.id, set()).add(subtype.parent_id.id)
|
||||||
|
elif subtype.res_model is False:
|
||||||
|
new_followers.setdefault(header_follower.partner_id.id, set()).add(subtype.id)
|
||||||
|
|
||||||
# add followers coming from res.users relational fields that are tracked
|
# add followers coming from res.users relational fields that are tracked
|
||||||
user_ids = [getattr(record, name).id for name in user_field_lst if getattr(record, name)]
|
user_ids = [values[name] for name in user_field_lst if values.get(name)]
|
||||||
user_id_partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, SUPERUSER_ID, user_ids, context=context)]
|
user_pids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, SUPERUSER_ID, user_ids, context=context)]
|
||||||
for partner_id in user_id_partner_ids:
|
for partner_id in user_pids:
|
||||||
new_followers.setdefault(partner_id, None)
|
new_followers.setdefault(partner_id, None)
|
||||||
|
|
||||||
for pid, subtypes in new_followers.items():
|
for pid, subtypes in new_followers.items():
|
||||||
subtypes = list(subtypes) if subtypes is not None else None
|
subtypes = list(subtypes) if subtypes is not None else None
|
||||||
self.message_subscribe(cr, uid, [record.id], [pid], subtypes, context=context)
|
self.message_subscribe(cr, uid, ids, [pid], subtypes, context=context)
|
||||||
|
|
||||||
# find first email message, set it as unread for auto_subscribe fields for them to have a notification
|
# find first email message, set it as unread for auto_subscribe fields for them to have a notification
|
||||||
if user_id_partner_ids:
|
if user_pids:
|
||||||
msg_ids = self.pool.get('mail.message').search(cr, uid, [
|
for record_id in ids:
|
||||||
('model', '=', self._name),
|
message_obj = self.pool.get('mail.message')
|
||||||
('res_id', '=', record.id),
|
msg_ids = message_obj.search(cr, SUPERUSER_ID, [
|
||||||
('type', '=', 'email')], limit=1, context=context)
|
('model', '=', self._name),
|
||||||
if not msg_ids and record.message_ids:
|
('res_id', '=', record_id),
|
||||||
msg_ids = [record.message_ids[-1].id]
|
('type', '=', 'email')], limit=1, context=context)
|
||||||
|
if not msg_ids:
|
||||||
|
msg_ids = message_obj.search(cr, SUPERUSER_ID, [
|
||||||
|
('model', '=', self._name),
|
||||||
|
('res_id', '=', record_id)], limit=1, context=context)
|
||||||
if msg_ids:
|
if msg_ids:
|
||||||
self.pool.get('mail.notification')._notify(cr, uid, msg_ids[0], partners_to_notify=user_id_partner_ids, context=context)
|
self.pool.get('mail.notification')._notify(cr, uid, msg_ids[0], partners_to_notify=user_pids, context=context)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
@ -965,7 +965,10 @@ class mrp_production(osv.osv):
|
||||||
partner_id = routing_loc.partner_id and routing_loc.partner_id.id or False
|
partner_id = routing_loc.partner_id and routing_loc.partner_id.id or False
|
||||||
|
|
||||||
# Take next Sequence number of shipment base on type
|
# Take next Sequence number of shipment base on type
|
||||||
pick_name = ir_sequence.get(cr, uid, 'stock.picking.' + pick_type)
|
if pick_type!='internal':
|
||||||
|
pick_name = ir_sequence.get(cr, uid, 'stock.picking.' + pick_type)
|
||||||
|
else:
|
||||||
|
pick_name = ir_sequence.get(cr, uid, 'stock.picking')
|
||||||
|
|
||||||
picking_id = stock_picking.create(cr, uid, {
|
picking_id = stock_picking.create(cr, uid, {
|
||||||
'name': pick_name,
|
'name': pick_name,
|
||||||
|
|
|
@ -80,11 +80,11 @@ class mrp_production(osv.osv):
|
||||||
_inherit= 'mrp.production'
|
_inherit= 'mrp.production'
|
||||||
|
|
||||||
|
|
||||||
def action_confirm(self, cr, uid, ids):
|
def action_confirm(self, cr, uid, ids, context=None):
|
||||||
""" Confirms production order and calculates quantity based on subproduct_type.
|
""" Confirms production order and calculates quantity based on subproduct_type.
|
||||||
@return: Newly generated picking Id.
|
@return: Newly generated picking Id.
|
||||||
"""
|
"""
|
||||||
picking_id = super(mrp_production,self).action_confirm(cr, uid, ids)
|
picking_id = super(mrp_production,self).action_confirm(cr, uid, ids, context=context)
|
||||||
product_uom_obj = self.pool.get('product.uom')
|
product_uom_obj = self.pool.get('product.uom')
|
||||||
for production in self.browse(cr, uid, ids):
|
for production in self.browse(cr, uid, ids):
|
||||||
source = production.product_id.property_stock_production.id
|
source = production.product_id.property_stock_production.id
|
||||||
|
|
|
@ -39,7 +39,11 @@ class pad_common(osv.osv_memory):
|
||||||
#if create with content
|
#if create with content
|
||||||
if "field_name" in context and "model" in context and "object_id" in context:
|
if "field_name" in context and "model" in context and "object_id" in context:
|
||||||
myPad = EtherpadLiteClient( pad["key"], pad["server"]+'/api')
|
myPad = EtherpadLiteClient( pad["key"], pad["server"]+'/api')
|
||||||
myPad.createPad(path)
|
try:
|
||||||
|
myPad.createPad(path)
|
||||||
|
except urllib2.URLError:
|
||||||
|
raise osv.except_osv(_("Error"), _("Pad creation failed, \
|
||||||
|
either there is a problem with your pad server URL or with your connection."))
|
||||||
|
|
||||||
#get attr on the field model
|
#get attr on the field model
|
||||||
model = self.pool[context["model"]]
|
model = self.pool[context["model"]]
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<data>
|
<data>
|
||||||
|
|
||||||
<record id="base.main_company" model="res.company">
|
<record id="base.main_company" model="res.company">
|
||||||
<field name="pad_server">pad.openerp.com</field>
|
<field name="pad_server">https://pad.openerp.com</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="base.main_company" model="res.company">
|
<record id="base.main_company" model="res.company">
|
||||||
|
|
|
@ -694,7 +694,7 @@ class pos_order(osv.osv):
|
||||||
|
|
||||||
def create_picking(self, cr, uid, ids, context=None):
|
def create_picking(self, cr, uid, ids, context=None):
|
||||||
"""Create a picking for each order and validate it."""
|
"""Create a picking for each order and validate it."""
|
||||||
picking_obj = self.pool.get('stock.picking')
|
picking_obj = self.pool.get('stock.picking.out')
|
||||||
partner_obj = self.pool.get('res.partner')
|
partner_obj = self.pool.get('res.partner')
|
||||||
move_obj = self.pool.get('stock.move')
|
move_obj = self.pool.get('stock.move')
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
<div class="oe_subtotal_footer_separator oe_inline">
|
<div class="oe_subtotal_footer_separator oe_inline">
|
||||||
<label for="amount_total" />
|
<label for="amount_total" />
|
||||||
<button name="button_dummy"
|
<button name="button_dummy"
|
||||||
states="draft" string="(update)" type="object" class="oe_edit_only oe_link"/>
|
states="draft" string="(update)" class="oe_edit_only oe_link"/>
|
||||||
</div>
|
</div>
|
||||||
<field name="amount_total" nolabel="1" class="oe_subtotal_footer_separator"/>
|
<field name="amount_total" nolabel="1" class="oe_subtotal_footer_separator"/>
|
||||||
</group>
|
</group>
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
from openerp import SUPERUSER_ID
|
||||||
from openerp.osv import osv, orm
|
from openerp.osv import osv, orm
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
|
|
||||||
|
@ -32,6 +33,9 @@ class mail_message(osv.Model):
|
||||||
""" Override that adds specific access rights of mail.message, to remove
|
""" Override that adds specific access rights of mail.message, to remove
|
||||||
all internal notes if uid is a non-employee
|
all internal notes if uid is a non-employee
|
||||||
"""
|
"""
|
||||||
|
if uid == SUPERUSER_ID:
|
||||||
|
return super(mail_message, self)._search(cr, uid, args, offset=offset, limit=limit, order=order,
|
||||||
|
context=context, count=False, access_rights_uid=access_rights_uid)
|
||||||
group_ids = self.pool.get('res.users').browse(cr, uid, uid, context=context).groups_id
|
group_ids = self.pool.get('res.users').browse(cr, uid, uid, context=context).groups_id
|
||||||
group_user_id = self.pool.get("ir.model.data").get_object_reference(cr, uid, 'base', 'group_user')[1]
|
group_user_id = self.pool.get("ir.model.data").get_object_reference(cr, uid, 'base', 'group_user')[1]
|
||||||
if group_user_id not in [group.id for group in group_ids]:
|
if group_user_id not in [group.id for group in group_ids]:
|
||||||
|
@ -45,6 +49,8 @@ class mail_message(osv.Model):
|
||||||
- read:
|
- read:
|
||||||
- raise if the type is comment and subtype NULL (internal note)
|
- raise if the type is comment and subtype NULL (internal note)
|
||||||
"""
|
"""
|
||||||
|
if uid == SUPERUSER_ID:
|
||||||
|
return super(mail_message, self).check_access_rule(cr, uid, ids=ids, operation=operation, context=context)
|
||||||
group_ids = self.pool.get('res.users').browse(cr, uid, uid, context=context).groups_id
|
group_ids = self.pool.get('res.users').browse(cr, uid, uid, context=context).groups_id
|
||||||
group_user_id = self.pool.get("ir.model.data").get_object_reference(cr, uid, 'base', 'group_user')[1]
|
group_user_id = self.pool.get("ir.model.data").get_object_reference(cr, uid, 'base', 'group_user')[1]
|
||||||
if group_user_id not in [group.id for group in group_ids]:
|
if group_user_id not in [group.id for group in group_ids]:
|
||||||
|
|
|
@ -73,6 +73,9 @@ class test_portal(TestMail):
|
||||||
for message in chell_pigs.message_ids:
|
for message in chell_pigs.message_ids:
|
||||||
trigger_read = message.subject
|
trigger_read = message.subject
|
||||||
for partner in chell_pigs.message_follower_ids:
|
for partner in chell_pigs.message_follower_ids:
|
||||||
|
if partner.id == self.partner_chell_id:
|
||||||
|
# Chell can read her own partner record
|
||||||
|
continue
|
||||||
with self.assertRaises(except_orm):
|
with self.assertRaises(except_orm):
|
||||||
trigger_read = partner.name
|
trigger_read = partner.name
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<openerp>
|
<openerp>
|
||||||
<data noupdate="1">
|
<data>
|
||||||
|
|
||||||
<record id="portal_claim_rule" model="ir.rule">
|
<record id="portal_claim_rule" model="ir.rule">
|
||||||
<field name="name">Portal Personal Claims</field>
|
<field name="name">Portal Personal Claims</field>
|
||||||
<field ref="crm_claim.model_crm_claim" name="model_id"/>
|
<field ref="crm_claim.model_crm_claim" name="model_id"/>
|
||||||
<field name="domain_force">[('message_follower_ids','in', [user.partner_id.id])]</field>
|
<field name="domain_force">['|', ('message_follower_ids','in', [user.partner_id.id]), ('partner_id','=', user.partner_id.id)]</field>
|
||||||
<field name="groups" eval="[(4, ref('portal.group_portal'))]"/>
|
<field name="groups" eval="[(4, ref('portal.group_portal'))]"/>
|
||||||
<field eval="1" name="perm_unlink"/>
|
<field eval="0" name="perm_unlink"/>
|
||||||
<field eval="1" name="perm_write"/>
|
<field eval="0" name="perm_write"/>
|
||||||
<field eval="1" name="perm_read"/>
|
<field eval="1" name="perm_read"/>
|
||||||
<field eval="0" name="perm_create"/>
|
<field eval="1" name="perm_create"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
||||||
|
|
|
@ -181,10 +181,6 @@ class procurement_order(osv.osv):
|
||||||
"""
|
"""
|
||||||
return all(procurement.move_id.state == 'cancel' for procurement in self.browse(cr, uid, ids, context=context))
|
return all(procurement.move_id.state == 'cancel' for procurement in self.browse(cr, uid, ids, context=context))
|
||||||
|
|
||||||
#This Function is create to avoid a server side Error Like 'ERROR:tests.mrp:name 'check_move' is not defined'
|
|
||||||
def check_move(self, cr, uid, ids, context=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def check_move_done(self, cr, uid, ids, context=None):
|
def check_move_done(self, cr, uid, ids, context=None):
|
||||||
""" Checks if move is done or not.
|
""" Checks if move is done or not.
|
||||||
@return: True or False.
|
@return: True or False.
|
||||||
|
@ -297,6 +293,12 @@ class procurement_order(osv.osv):
|
||||||
"""
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def check_move(self, cr, uid, ids, context=None):
|
||||||
|
""" Check whether the given procurement can be satisfied by an internal move,
|
||||||
|
typically a pulled flow. By default, it's False. Overwritten by the `stock_location` module.
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
def check_conditions_confirm2wait(self, cr, uid, ids):
|
def check_conditions_confirm2wait(self, cr, uid, ids):
|
||||||
""" condition on the transition to go from 'confirm' activity to 'confirm_wait' activity """
|
""" condition on the transition to go from 'confirm' activity to 'confirm_wait' activity """
|
||||||
return not self.test_cancel(cr, uid, ids)
|
return not self.test_cancel(cr, uid, ids)
|
||||||
|
|
|
@ -147,13 +147,15 @@
|
||||||
|
|
||||||
<record id="trans_confirm_mto_make_done" model="workflow.transition">
|
<record id="trans_confirm_mto_make_done" model="workflow.transition">
|
||||||
<!-- This transition is there to unblock products that would be in MTO with a supply method that would be
|
<!-- This transition is there to unblock products that would be in MTO with a supply method that would be
|
||||||
produce or buy without MRP or purchase module installed. These modules overwrite the check_produce()
|
produce or buy, and without MRP or Purchase modules installed. These modules overwrite the check_produce()
|
||||||
and check_buy() methods -so that it invalidates their part of this 'bypass transition'-, and define
|
and check_buy() methods -so that it invalidates their part of this 'bypass transition'-, and define
|
||||||
their own workflow paths.
|
their own workflow paths.
|
||||||
|
The stock_location module also introduces a check_move() alternative, for pulled flows that are
|
||||||
|
satisfied with an internal product move. This yields a threefold test for the bypass transition.
|
||||||
-->
|
-->
|
||||||
<field name="act_from" ref="act_confirm_mto"/>
|
<field name="act_from" ref="act_confirm_mto"/>
|
||||||
<field name="act_to" ref="act_make_done"/>
|
<field name="act_to" ref="act_make_done"/>
|
||||||
<field name="condition">not check_produce() and not check_buy()</field>
|
<field name="condition">not check_produce() and not check_buy() and not check_move()</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="trans_make_to_stock_make_done" model="workflow.transition">
|
<record id="trans_make_to_stock_make_done" model="workflow.transition">
|
||||||
|
|
|
@ -194,6 +194,7 @@ class procurement_order(osv.osv):
|
||||||
'company_id': orderpoint.company_id.id,
|
'company_id': orderpoint.company_id.id,
|
||||||
'product_uom': orderpoint.product_uom.id,
|
'product_uom': orderpoint.product_uom.id,
|
||||||
'location_id': orderpoint.location_id.id,
|
'location_id': orderpoint.location_id.id,
|
||||||
|
'warehouse_id': orderpoint.warehouse_id.id,
|
||||||
'procure_method': 'make_to_order',
|
'procure_method': 'make_to_order',
|
||||||
'origin': orderpoint.name}
|
'origin': orderpoint.name}
|
||||||
|
|
||||||
|
|
|
@ -86,78 +86,13 @@ class sale_order_line(osv.osv):
|
||||||
pricelists = pricelist_obj.read(cr,uid,[pricelist],['visible_discount'])
|
pricelists = pricelist_obj.read(cr,uid,[pricelist],['visible_discount'])
|
||||||
|
|
||||||
new_list_price = get_real_price(list_price, product.id, qty, uom, pricelist)
|
new_list_price = get_real_price(list_price, product.id, qty, uom, pricelist)
|
||||||
if(len(pricelists)>0 and pricelists[0]['visible_discount'] and list_price[pricelist] != 0):
|
if len(pricelists)>0 and pricelists[0]['visible_discount'] and list_price[pricelist] != 0 and new_list_price != 0:
|
||||||
discount = (new_list_price - price) / new_list_price * 100
|
discount = (new_list_price - price) / new_list_price * 100
|
||||||
result['price_unit'] = new_list_price
|
if discount > 0:
|
||||||
result['discount'] = discount
|
result['price_unit'] = new_list_price
|
||||||
|
result['discount'] = discount
|
||||||
|
else:
|
||||||
|
result['discount'] = 0.0
|
||||||
else:
|
else:
|
||||||
result['discount'] = 0.0
|
result['discount'] = 0.0
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
class account_invoice_line(osv.osv):
|
|
||||||
_inherit = "account.invoice.line"
|
|
||||||
|
|
||||||
def product_id_change(self, cr, uid, ids, product, uom_id, qty=0, name='', type='out_invoice', partner_id=False, fposition_id=False, price_unit=False, currency_id=False, context=None, company_id=None):
|
|
||||||
res = super(account_invoice_line, self).product_id_change(cr, uid, ids, product, uom_id, qty, name, type, partner_id, fposition_id, price_unit,currency_id, context=context, company_id=company_id)
|
|
||||||
|
|
||||||
def get_real_price(res_dict, product_id, qty, uom_id, pricelist):
|
|
||||||
item_obj = self.pool.get('product.pricelist.item')
|
|
||||||
price_type_obj = self.pool.get('product.price.type')
|
|
||||||
product_obj = self.pool.get('product.product')
|
|
||||||
field_name = 'list_price'
|
|
||||||
|
|
||||||
if res_dict.get('item_id',False) and res_dict['item_id'].get(pricelist,False):
|
|
||||||
item = res_dict['item_id'].get(pricelist,False)
|
|
||||||
item_read = item_obj.read(cr, uid, [item], ['base'])
|
|
||||||
if item_read:
|
|
||||||
item_base = item_read[0]['base']
|
|
||||||
if item_base > 0:
|
|
||||||
field_name = price_type_obj.browse(cr, uid, item_base).field
|
|
||||||
|
|
||||||
product = product_obj.browse(cr, uid, product_id, context)
|
|
||||||
product_read = product_obj.read(cr, uid, product_id, [field_name], context=context)
|
|
||||||
|
|
||||||
factor = 1.0
|
|
||||||
if uom_id and uom_id != product.uom_id.id:
|
|
||||||
product_uom_obj = self.pool.get('product.uom')
|
|
||||||
uom_data = product_uom_obj.browse(cr, uid, product.uom_id.id)
|
|
||||||
factor = uom_data.factor
|
|
||||||
return product_read[field_name] * factor
|
|
||||||
|
|
||||||
if product:
|
|
||||||
pricelist_obj = self.pool.get('product.pricelist')
|
|
||||||
partner_obj = self.pool.get('res.partner')
|
|
||||||
product = self.pool.get('product.product').browse(cr, uid, product, context=context)
|
|
||||||
result = res['value']
|
|
||||||
pricelist = False
|
|
||||||
real_price = 0.00
|
|
||||||
if type in ('in_invoice', 'in_refund'):
|
|
||||||
if not price_unit and partner_id:
|
|
||||||
pricelist =partner_obj.browse(cr, uid, partner_id).property_product_pricelist_purchase.id
|
|
||||||
if not pricelist:
|
|
||||||
raise osv.except_osv(_('No Purchase Pricelist Found!'),_("You must first define a pricelist on the supplier form!"))
|
|
||||||
price_unit_res = pricelist_obj.price_get(cr, uid, [pricelist], product.id, qty or 1.0, partner_id, {'uom': uom_id})
|
|
||||||
price_unit = price_unit_res[pricelist]
|
|
||||||
real_price = get_real_price(price_unit_res, product.id, qty, uom_id, pricelist)
|
|
||||||
else:
|
|
||||||
if partner_id:
|
|
||||||
pricelist = partner_obj.browse(cr, uid, partner_id).property_product_pricelist.id
|
|
||||||
if not pricelist:
|
|
||||||
raise osv.except_osv(_('No Sale Pricelist Found!'),_("You must first define a pricelist on the customer form!"))
|
|
||||||
price_unit_res = pricelist_obj.price_get(cr, uid, [pricelist], product.id, qty or 1.0, partner_id, {'uom': uom_id})
|
|
||||||
price_unit = price_unit_res[pricelist]
|
|
||||||
|
|
||||||
real_price = get_real_price(price_unit_res, product.id, qty, uom_id, pricelist)
|
|
||||||
if pricelist:
|
|
||||||
pricelists=pricelist_obj.read(cr,uid,[pricelist],['visible_discount'])
|
|
||||||
if(len(pricelists)>0 and pricelists[0]['visible_discount'] and real_price != 0):
|
|
||||||
discount=(real_price-price_unit) / real_price * 100
|
|
||||||
result['price_unit'] = real_price
|
|
||||||
result['discount'] = discount
|
|
||||||
else:
|
|
||||||
result['discount']=0.0
|
|
||||||
return res
|
|
||||||
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
||||||
|
|
|
@ -1131,7 +1131,8 @@ class task(osv.osv):
|
||||||
|
|
||||||
def message_new(self, cr, uid, msg, custom_values=None, context=None):
|
def message_new(self, cr, uid, msg, custom_values=None, context=None):
|
||||||
""" Override to updates the document according to the email. """
|
""" Override to updates the document according to the email. """
|
||||||
if custom_values is None: custom_values = {}
|
if custom_values is None:
|
||||||
|
custom_values = {}
|
||||||
defaults = {
|
defaults = {
|
||||||
'name': msg.get('subject'),
|
'name': msg.get('subject'),
|
||||||
'planned_hours': 0.0,
|
'planned_hours': 0.0,
|
||||||
|
@ -1141,10 +1142,10 @@ class task(osv.osv):
|
||||||
|
|
||||||
def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
|
def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
|
||||||
""" Override to update the task according to the email. """
|
""" Override to update the task according to the email. """
|
||||||
if update_vals is None: update_vals = {}
|
if update_vals is None:
|
||||||
act = False
|
update_vals = {}
|
||||||
maps = {
|
maps = {
|
||||||
'cost':'planned_hours',
|
'cost': 'planned_hours',
|
||||||
}
|
}
|
||||||
for line in msg['body'].split('\n'):
|
for line in msg['body'].split('\n'):
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
|
@ -1157,9 +1158,7 @@ class task(osv.osv):
|
||||||
update_vals[field] = float(res.group(2).lower())
|
update_vals[field] = float(res.group(2).lower())
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
pass
|
pass
|
||||||
if act:
|
return super(task, self).message_update(cr, uid, ids, msg, update_vals=update_vals, context=context)
|
||||||
getattr(self,act)(cr, uid, ids, context=context)
|
|
||||||
return super(task,self).message_update(cr, uid, ids, msg, update_vals=update_vals, context=context)
|
|
||||||
|
|
||||||
class project_work(osv.osv):
|
class project_work(osv.osv):
|
||||||
_name = "project.task.work"
|
_name = "project.task.work"
|
||||||
|
|
|
@ -519,40 +519,10 @@ class project_issue(osv.Model):
|
||||||
'partner_id': msg.get('author_id', False),
|
'partner_id': msg.get('author_id', False),
|
||||||
'user_id': False,
|
'user_id': False,
|
||||||
}
|
}
|
||||||
if msg.get('priority'):
|
|
||||||
defaults['priority'] = msg.get('priority')
|
|
||||||
|
|
||||||
defaults.update(custom_values)
|
defaults.update(custom_values)
|
||||||
res_id = super(project_issue, self).message_new(cr, uid, msg, custom_values=defaults, context=context)
|
res_id = super(project_issue, self).message_new(cr, uid, msg, custom_values=defaults, context=context)
|
||||||
return res_id
|
return res_id
|
||||||
|
|
||||||
def message_update(self, cr, uid, ids, msg, update_vals=None, context=None):
|
|
||||||
""" Overrides mail_thread message_update that is called by the mailgateway
|
|
||||||
through message_process.
|
|
||||||
This method updates the document according to the email.
|
|
||||||
"""
|
|
||||||
if isinstance(ids, (str, int, long)):
|
|
||||||
ids = [ids]
|
|
||||||
if update_vals is None: update_vals = {}
|
|
||||||
|
|
||||||
# Update doc values according to the message
|
|
||||||
if msg.get('priority'):
|
|
||||||
update_vals['priority'] = msg.get('priority')
|
|
||||||
# Parse 'body' to find values to update
|
|
||||||
maps = {
|
|
||||||
'cost': 'planned_cost',
|
|
||||||
'revenue': 'planned_revenue',
|
|
||||||
'probability': 'probability',
|
|
||||||
}
|
|
||||||
for line in msg.get('body', '').split('\n'):
|
|
||||||
line = line.strip()
|
|
||||||
res = tools.command_re.match(line)
|
|
||||||
if res and maps.get(res.group(1).lower(), False):
|
|
||||||
key = maps.get(res.group(1).lower())
|
|
||||||
update_vals[key] = res.group(2).lower()
|
|
||||||
|
|
||||||
return super(project_issue, self).message_update(cr, uid, ids, msg, update_vals=update_vals, context=context)
|
|
||||||
|
|
||||||
def message_post(self, cr, uid, thread_id, body='', subject=None, type='notification', subtype=None, parent_id=False, attachments=None, context=None, content_subtype='html', **kwargs):
|
def message_post(self, cr, uid, thread_id, body='', subject=None, type='notification', subtype=None, parent_id=False, attachments=None, context=None, content_subtype='html', **kwargs):
|
||||||
""" Overrides mail_thread message_post so that we can set the date of last action field when
|
""" Overrides mail_thread message_post so that we can set the date of last action field when
|
||||||
a new message is posted on the issue.
|
a new message is posted on the issue.
|
||||||
|
|
|
@ -36,6 +36,9 @@
|
||||||
<menuitem
|
<menuitem
|
||||||
id="menu_purchase_config_pricelist" name="Pricelists"
|
id="menu_purchase_config_pricelist" name="Pricelists"
|
||||||
parent="menu_purchase_config_purchase" sequence="50" groups="product.group_purchase_pricelist"/>
|
parent="menu_purchase_config_purchase" sequence="50" groups="product.group_purchase_pricelist"/>
|
||||||
|
<menuitem
|
||||||
|
action="product.product_pricelist_action_for_purchase" id="menu_product_pricelist_action2_purchase"
|
||||||
|
parent="menu_purchase_config_pricelist" sequence="1" groups="product.group_purchase_pricelist" />
|
||||||
|
|
||||||
<menuitem
|
<menuitem
|
||||||
action="product.product_pricelist_action_for_purchase" id="menu_product_pricelist_action2_purchase"
|
action="product.product_pricelist_action_for_purchase" id="menu_product_pricelist_action2_purchase"
|
||||||
|
|
|
@ -94,23 +94,20 @@ class purchase_report(osv.osv):
|
||||||
extract(epoch from age(s.date_approve,s.date_order))/(24*60*60)::decimal(16,2) as delay,
|
extract(epoch from age(s.date_approve,s.date_order))/(24*60*60)::decimal(16,2) as delay,
|
||||||
extract(epoch from age(l.date_planned,s.date_order))/(24*60*60)::decimal(16,2) as delay_pass,
|
extract(epoch from age(l.date_planned,s.date_order))/(24*60*60)::decimal(16,2) as delay_pass,
|
||||||
count(*) as nbr,
|
count(*) as nbr,
|
||||||
(l.price_unit*l.product_qty)::decimal(16,2) as price_total,
|
sum(l.price_unit*l.product_qty)::decimal(16,2) as price_total,
|
||||||
avg(100.0 * (l.price_unit*l.product_qty) / NULLIF(t.standard_price*l.product_qty/u.factor*u2.factor, 0.0))::decimal(16,2) as negociation,
|
avg(100.0 * (l.price_unit*l.product_qty) / NULLIF(t.standard_price*l.product_qty/u.factor*u2.factor, 0.0))::decimal(16,2) as negociation,
|
||||||
|
|
||||||
sum(t.standard_price*l.product_qty/u.factor*u2.factor)::decimal(16,2) as price_standard,
|
sum(t.standard_price*l.product_qty/u.factor*u2.factor)::decimal(16,2) as price_standard,
|
||||||
(sum(l.product_qty*l.price_unit)/NULLIF(sum(l.product_qty/u.factor*u2.factor),0.0))::decimal(16,2) as price_average
|
(sum(l.product_qty*l.price_unit)/NULLIF(sum(l.product_qty/u.factor*u2.factor),0.0))::decimal(16,2) as price_average
|
||||||
from purchase_order s
|
from purchase_order_line l
|
||||||
left join purchase_order_line l on (s.id=l.order_id)
|
join purchase_order s on (l.order_id=s.id)
|
||||||
left join product_product p on (l.product_id=p.id)
|
left join product_product p on (l.product_id=p.id)
|
||||||
left join product_template t on (p.product_tmpl_id=t.id)
|
left join product_template t on (p.product_tmpl_id=t.id)
|
||||||
left join product_uom u on (u.id=l.product_uom)
|
left join product_uom u on (u.id=l.product_uom)
|
||||||
left join product_uom u2 on (u2.id=t.uom_id)
|
left join product_uom u2 on (u2.id=t.uom_id)
|
||||||
where l.product_id is not null
|
|
||||||
group by
|
group by
|
||||||
s.company_id,
|
s.company_id,
|
||||||
s.create_uid,
|
s.create_uid,
|
||||||
s.partner_id,
|
s.partner_id,
|
||||||
l.product_qty,
|
|
||||||
u.factor,
|
u.factor,
|
||||||
s.location_id,
|
s.location_id,
|
||||||
l.price_unit,
|
l.price_unit,
|
||||||
|
|
|
@ -177,8 +177,8 @@ class resource_calendar(osv.osv):
|
||||||
if leave_flag:
|
if leave_flag:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
d1 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(m)), int((m%1) * 60))
|
d1 = datetime(dt_from.year, dt_from.month, dt_from.day) + timedelta(hours=int(math.floor(m)), minutes=int((m%1) * 60))
|
||||||
d2 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(hour_to)), int((hour_to%1) * 60))
|
d2 = datetime(dt_from.year, dt_from.month, dt_from.day) + timedelta(hours=int(math.floor(hour_to)), minutes=int((hour_to%1) * 60))
|
||||||
result.append((d1, d2))
|
result.append((d1, d2))
|
||||||
current_hour = hour_to
|
current_hour = hour_to
|
||||||
todo -= (hour_to - m)
|
todo -= (hour_to - m)
|
||||||
|
|
|
@ -70,7 +70,7 @@ class sale_report(osv.osv):
|
||||||
t.uom_id as product_uom,
|
t.uom_id as product_uom,
|
||||||
sum(l.product_uom_qty / u.factor * u2.factor) as product_uom_qty,
|
sum(l.product_uom_qty / u.factor * u2.factor) as product_uom_qty,
|
||||||
sum(l.product_uom_qty * l.price_unit * (100.0-l.discount) / 100.0) as price_total,
|
sum(l.product_uom_qty * l.price_unit * (100.0-l.discount) / 100.0) as price_total,
|
||||||
1 as nbr,
|
count(*) as nbr,
|
||||||
s.date_order as date,
|
s.date_order as date,
|
||||||
s.date_confirm as date_confirm,
|
s.date_confirm as date_confirm,
|
||||||
to_char(s.date_order, 'YYYY') as year,
|
to_char(s.date_order, 'YYYY') as year,
|
||||||
|
@ -85,15 +85,14 @@ class sale_report(osv.osv):
|
||||||
s.pricelist_id as pricelist_id,
|
s.pricelist_id as pricelist_id,
|
||||||
s.project_id as analytic_account_id
|
s.project_id as analytic_account_id
|
||||||
from
|
from
|
||||||
sale_order s
|
sale_order_line l
|
||||||
join sale_order_line l on (s.id=l.order_id)
|
join sale_order s on (l.order_id=s.id)
|
||||||
left join product_product p on (l.product_id=p.id)
|
left join product_product p on (l.product_id=p.id)
|
||||||
left join product_template t on (p.product_tmpl_id=t.id)
|
left join product_template t on (p.product_tmpl_id=t.id)
|
||||||
left join product_uom u on (u.id=l.product_uom)
|
left join product_uom u on (u.id=l.product_uom)
|
||||||
left join product_uom u2 on (u2.id=t.uom_id)
|
left join product_uom u2 on (u2.id=t.uom_id)
|
||||||
group by
|
group by
|
||||||
l.product_id,
|
l.product_id,
|
||||||
l.product_uom_qty,
|
|
||||||
l.order_id,
|
l.order_id,
|
||||||
t.uom_id,
|
t.uom_id,
|
||||||
t.categ_id,
|
t.categ_id,
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<field name="inherit_id" ref="sale.view_order_form"/>
|
<field name="inherit_id" ref="sale.view_order_form"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<group name="sale_pay" position="after">
|
<group name="sale_pay" position="after">
|
||||||
<group colspan="2" col="2" groups="base.group_no_one">
|
<group colspan="2" col="2" >
|
||||||
<separator string="Dates" colspan="2"/>
|
<separator string="Dates" colspan="2"/>
|
||||||
<field name="requested_date"/>
|
<field name="requested_date"/>
|
||||||
<field name="commitment_date"/>
|
<field name="commitment_date"/>
|
||||||
|
|
|
@ -42,6 +42,8 @@ class sale_report(osv.osv):
|
||||||
|
|
||||||
def init(self, cr):
|
def init(self, cr):
|
||||||
tools.drop_view_if_exists(cr, 'sale_report')
|
tools.drop_view_if_exists(cr, 'sale_report')
|
||||||
|
# TODO: make parent view extensible similarly to invoice analysis and
|
||||||
|
# remove the duplication
|
||||||
cr.execute("""
|
cr.execute("""
|
||||||
create or replace view sale_report as (
|
create or replace view sale_report as (
|
||||||
select
|
select
|
||||||
|
@ -50,7 +52,7 @@ class sale_report(osv.osv):
|
||||||
t.uom_id as product_uom,
|
t.uom_id as product_uom,
|
||||||
sum(l.product_uom_qty / u.factor * u2.factor) as product_uom_qty,
|
sum(l.product_uom_qty / u.factor * u2.factor) as product_uom_qty,
|
||||||
sum(l.product_uom_qty * l.price_unit * (100.0-l.discount) / 100.0) as price_total,
|
sum(l.product_uom_qty * l.price_unit * (100.0-l.discount) / 100.0) as price_total,
|
||||||
1 as nbr,
|
count(*) as nbr,
|
||||||
s.date_order as date,
|
s.date_order as date,
|
||||||
s.date_confirm as date_confirm,
|
s.date_confirm as date_confirm,
|
||||||
to_char(s.date_order, 'YYYY') as year,
|
to_char(s.date_order, 'YYYY') as year,
|
||||||
|
@ -68,15 +70,14 @@ class sale_report(osv.osv):
|
||||||
s.pricelist_id as pricelist_id,
|
s.pricelist_id as pricelist_id,
|
||||||
s.project_id as analytic_account_id
|
s.project_id as analytic_account_id
|
||||||
from
|
from
|
||||||
sale_order s
|
sale_order_line l
|
||||||
join sale_order_line l on (s.id=l.order_id)
|
join sale_order s on (l.order_id=s.id)
|
||||||
left join product_product p on (l.product_id=p.id)
|
left join product_product p on (l.product_id=p.id)
|
||||||
left join product_template t on (p.product_tmpl_id=t.id)
|
left join product_template t on (p.product_tmpl_id=t.id)
|
||||||
left join product_uom u on (u.id=l.product_uom)
|
left join product_uom u on (u.id=l.product_uom)
|
||||||
left join product_uom u2 on (u2.id=t.uom_id)
|
left join product_uom u2 on (u2.id=t.uom_id)
|
||||||
group by
|
group by
|
||||||
l.product_id,
|
l.product_id,
|
||||||
l.product_uom_qty,
|
|
||||||
l.order_id,
|
l.order_id,
|
||||||
t.uom_id,
|
t.uom_id,
|
||||||
t.categ_id,
|
t.categ_id,
|
||||||
|
|
|
@ -62,6 +62,15 @@ class stock_picking(osv.osv):
|
||||||
return picking.note or picking.sale_id.note
|
return picking.note or picking.sale_id.note
|
||||||
return super(stock_picking, self)._get_comment_invoice(cursor, user, picking)
|
return super(stock_picking, self)._get_comment_invoice(cursor, user, picking)
|
||||||
|
|
||||||
|
def _prepare_invoice_group(self, cr, uid, picking, partner, invoice, context=None):
|
||||||
|
""" Inherit the original function of the 'stock' module in order to override name field
|
||||||
|
to pass the customer reference form the sales order
|
||||||
|
"""
|
||||||
|
invoice_vals = super(stock_picking, self)._prepare_invoice_group(cr, uid, picking, partner, invoice, context)
|
||||||
|
if picking.sale_id:
|
||||||
|
invoice_vals['name'] = (invoice.name or '') + ', ' + (picking.sale_id.client_order_ref or '')
|
||||||
|
return invoice_vals
|
||||||
|
|
||||||
def _prepare_invoice(self, cr, uid, picking, partner, inv_type, journal_id, context=None):
|
def _prepare_invoice(self, cr, uid, picking, partner, inv_type, journal_id, context=None):
|
||||||
""" Inherit the original function of the 'stock' module in order to override some
|
""" Inherit the original function of the 'stock' module in order to override some
|
||||||
values if the picking has been generated by a sales order
|
values if the picking has been generated by a sales order
|
||||||
|
|
|
@ -224,12 +224,18 @@
|
||||||
<field name="delivery_count"/>
|
<field name="delivery_count"/>
|
||||||
</field>
|
</field>
|
||||||
<xpath expr="//div[@name='tags']" position="inside">
|
<xpath expr="//div[@name='tags']" position="inside">
|
||||||
<a name="%(action_receive_move)d" type="action" t-if="record.reception_count.raw_value>0">
|
<a name="%(action_receive_move)d" type="action" t-if="record.reception_count.raw_value>1">
|
||||||
<t t-esc="record.reception_count.value"/> Receptions
|
<t t-esc="record.reception_count.value"/> Receptions
|
||||||
</a>
|
</a>
|
||||||
<a name="%(action_deliver_move)d" type="action" t-if="record.delivery_count.raw_value>0">
|
<a name="%(action_receive_move)d" type="action" t-if="record.reception_count.raw_value==1">
|
||||||
|
<t t-esc="record.reception_count.value"/> Reception
|
||||||
|
</a>
|
||||||
|
<a name="%(action_deliver_move)d" type="action" t-if="record.delivery_count.raw_value>1">
|
||||||
<t t-esc="record.delivery_count.value"/> Deliveries
|
<t t-esc="record.delivery_count.value"/> Deliveries
|
||||||
</a>
|
</a>
|
||||||
|
<a name="%(action_deliver_move)d" type="action" t-if="record.delivery_count.raw_value==1">
|
||||||
|
<t t-esc="record.delivery_count.value"/> Delivery
|
||||||
|
</a>
|
||||||
</xpath>
|
</xpath>
|
||||||
<ul position="inside">
|
<ul position="inside">
|
||||||
<li t-if="record.type.raw_value != 'service'">On hand: <field name="qty_available"/> <field name="uom_id"/></li>
|
<li t-if="record.type.raw_value != 'service'">On hand: <field name="qty_available"/> <field name="uom_id"/></li>
|
||||||
|
|
|
@ -243,6 +243,9 @@ class stock_location(osv.osv):
|
||||||
if location.chained_location_type == 'customer':
|
if location.chained_location_type == 'customer':
|
||||||
if partner:
|
if partner:
|
||||||
result = partner.property_stock_customer
|
result = partner.property_stock_customer
|
||||||
|
else:
|
||||||
|
loc_id = self.pool['res.partner'].default_get(cr, uid, ['property_stock_customer'], context=context)['property_stock_customer']
|
||||||
|
result = self.pool['stock.location'].browse(cr, uid, loc_id, context=context)
|
||||||
elif location.chained_location_type == 'fixed':
|
elif location.chained_location_type == 'fixed':
|
||||||
result = location.chained_location_id
|
result = location.chained_location_id
|
||||||
if result:
|
if result:
|
||||||
|
@ -1267,17 +1270,17 @@ class stock_picking(osv.osv):
|
||||||
context['currency_id'] = move_currency_id
|
context['currency_id'] = move_currency_id
|
||||||
qty = uom_obj._compute_qty(cr, uid, product_uom, product_qty, product.uom_id.id)
|
qty = uom_obj._compute_qty(cr, uid, product_uom, product_qty, product.uom_id.id)
|
||||||
|
|
||||||
if product.id in product_avail:
|
if product.id not in product_avail:
|
||||||
product_avail[product.id] += qty
|
# keep track of stock on hand including processed lines not yet marked as done
|
||||||
else:
|
|
||||||
product_avail[product.id] = product.qty_available
|
product_avail[product.id] = product.qty_available
|
||||||
|
|
||||||
if qty > 0:
|
if qty > 0:
|
||||||
new_price = currency_obj.compute(cr, uid, product_currency,
|
new_price = currency_obj.compute(cr, uid, product_currency,
|
||||||
move_currency_id, product_price)
|
move_currency_id, product_price, round=False)
|
||||||
new_price = uom_obj._compute_price(cr, uid, product_uom, new_price,
|
new_price = uom_obj._compute_price(cr, uid, product_uom, new_price,
|
||||||
product.uom_id.id)
|
product.uom_id.id)
|
||||||
if product.qty_available <= 0:
|
if product_avail[product.id] <= 0:
|
||||||
|
product_avail[product.id] = 0
|
||||||
new_std_price = new_price
|
new_std_price = new_price
|
||||||
else:
|
else:
|
||||||
# Get the standard price
|
# Get the standard price
|
||||||
|
@ -1293,6 +1296,9 @@ class stock_picking(osv.osv):
|
||||||
{'price_unit': product_price,
|
{'price_unit': product_price,
|
||||||
'price_currency_id': product_currency})
|
'price_currency_id': product_currency})
|
||||||
|
|
||||||
|
product_avail[product.id] += qty
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for move in too_few:
|
for move in too_few:
|
||||||
product_qty = move_product_qty[move.id]
|
product_qty = move_product_qty[move.id]
|
||||||
|
@ -2359,7 +2365,7 @@ class stock_move(osv.osv):
|
||||||
{
|
{
|
||||||
'journal_id': j_id,
|
'journal_id': j_id,
|
||||||
'line_id': move_lines,
|
'line_id': move_lines,
|
||||||
'ref': move.picking_id and move.picking_id.name})
|
'ref': move.picking_id and move.picking_id.name}, context=context)
|
||||||
|
|
||||||
def action_done(self, cr, uid, ids, context=None):
|
def action_done(self, cr, uid, ids, context=None):
|
||||||
""" Makes the move done and if all moves are done, it will finish the picking.
|
""" Makes the move done and if all moves are done, it will finish the picking.
|
||||||
|
@ -2697,7 +2703,7 @@ class stock_move(osv.osv):
|
||||||
qty = uom_obj._compute_qty(cr, uid, product_uom, product_qty, product.uom_id.id)
|
qty = uom_obj._compute_qty(cr, uid, product_uom, product_qty, product.uom_id.id)
|
||||||
if qty > 0:
|
if qty > 0:
|
||||||
new_price = currency_obj.compute(cr, uid, product_currency,
|
new_price = currency_obj.compute(cr, uid, product_currency,
|
||||||
move_currency_id, product_price)
|
move_currency_id, product_price, round=False)
|
||||||
new_price = uom_obj._compute_price(cr, uid, product_uom, new_price,
|
new_price = uom_obj._compute_price(cr, uid, product_uom, new_price,
|
||||||
product.uom_id.id)
|
product.uom_id.id)
|
||||||
if product.qty_available <= 0:
|
if product.qty_available <= 0:
|
||||||
|
@ -3031,6 +3037,13 @@ class stock_picking_in(osv.osv):
|
||||||
"""Send the unsubscribe action on stock.picking model to match with subscribe"""
|
"""Send the unsubscribe action on stock.picking model to match with subscribe"""
|
||||||
return self.pool.get('stock.picking').message_unsubscribe(*args, **kwargs)
|
return self.pool.get('stock.picking').message_unsubscribe(*args, **kwargs)
|
||||||
|
|
||||||
|
def default_get(self, cr, uid, fields_list, context=None):
|
||||||
|
# merge defaults from stock.picking with possible defaults defined on stock.picking.in
|
||||||
|
defaults = self.pool['stock.picking'].default_get(cr, uid, fields_list, context=context)
|
||||||
|
out_defaults = super(stock_picking_in, self).default_get(cr, uid, fields_list, context=context)
|
||||||
|
defaults.update(in_defaults)
|
||||||
|
return defaults
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'backorder_id': fields.many2one('stock.picking.in', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True),
|
'backorder_id': fields.many2one('stock.picking.in', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True),
|
||||||
'state': fields.selection(
|
'state': fields.selection(
|
||||||
|
@ -3104,6 +3117,13 @@ class stock_picking_out(osv.osv):
|
||||||
"""Send the unsubscribe action on stock.picking model to match with subscribe"""
|
"""Send the unsubscribe action on stock.picking model to match with subscribe"""
|
||||||
return self.pool.get('stock.picking').message_unsubscribe(*args, **kwargs)
|
return self.pool.get('stock.picking').message_unsubscribe(*args, **kwargs)
|
||||||
|
|
||||||
|
def default_get(self, cr, uid, fields_list, context=None):
|
||||||
|
# merge defaults from stock.picking with possible defaults defined on stock.picking.out
|
||||||
|
defaults = self.pool['stock.picking'].default_get(cr, uid, fields_list, context=context)
|
||||||
|
out_defaults = super(stock_picking_out, self).default_get(cr, uid, fields_list, context=context)
|
||||||
|
defaults.update(out_defaults)
|
||||||
|
return defaults
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'backorder_id': fields.many2one('stock.picking.out', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True),
|
'backorder_id': fields.many2one('stock.picking.out', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True),
|
||||||
'state': fields.selection(
|
'state': fields.selection(
|
||||||
|
|
|
@ -1251,7 +1251,7 @@
|
||||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||||
</group>
|
</group>
|
||||||
<group name="origin_grp" string="Origin">
|
<group name="origin_grp" string="Origin">
|
||||||
<field name="origin"/>
|
<field name="origin" attrs="{'invisible': [('picking_id', '=', False)]}"/>
|
||||||
<field name="picking_id" domain="[('type','=',type)]"/>
|
<field name="picking_id" domain="[('type','=',type)]"/>
|
||||||
<field name="type" on_change="onchange_move_type(type)"/>
|
<field name="type" on_change="onchange_move_type(type)"/>
|
||||||
<field name="location_id" groups="stock.group_locations"/>
|
<field name="location_id" groups="stock.group_locations"/>
|
||||||
|
|
|
@ -51,7 +51,7 @@ class stock_partial_picking_line(osv.TransientModel):
|
||||||
'move_id' : fields.many2one('stock.move', "Move", ondelete='CASCADE'),
|
'move_id' : fields.many2one('stock.move', "Move", ondelete='CASCADE'),
|
||||||
'wizard_id' : fields.many2one('stock.partial.picking', string="Wizard", ondelete='CASCADE'),
|
'wizard_id' : fields.many2one('stock.partial.picking', string="Wizard", ondelete='CASCADE'),
|
||||||
'update_cost': fields.boolean('Need cost update'),
|
'update_cost': fields.boolean('Need cost update'),
|
||||||
'cost' : fields.float("Cost", help="Unit Cost for this product line"),
|
'cost' : fields.float("Cost", help="Unit Cost for this product line", digits_compute=dp.get_precision('Product Price')),
|
||||||
'currency' : fields.many2one('res.currency', string="Currency", help="Currency in which Unit cost is expressed", ondelete='CASCADE'),
|
'currency' : fields.many2one('res.currency', string="Currency", help="Currency in which Unit cost is expressed", ondelete='CASCADE'),
|
||||||
'tracking': fields.function(_tracking, string='Tracking', type='boolean'),
|
'tracking': fields.function(_tracking, string='Tracking', type='boolean'),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue