[MERGE] Forward-port of latest 7.0 bugfixes, up to rev. 9789 revid:dle@openerp.com-20140124120102-we2yxio553ws2yz4

bzr revid: dle@openerp.com-20140120174449-tui0a24zgn9bien2
bzr revid: dle@openerp.com-20140121125538-ke7i6kaz486hwgl8
bzr revid: dle@openerp.com-20140122134115-0ogjemlqe327xoac
bzr revid: dle@openerp.com-20140123103655-mf2zslfbgue97ed2
bzr revid: dle@openerp.com-20140124121027-uk9zy4dx9tqlsblr
This commit is contained in:
Denis Ledoux 2014-01-24 13:10:27 +01:00
commit 1fb1a6f2af
15 changed files with 64 additions and 34 deletions

View File

@ -35,9 +35,9 @@ class account_asset_category(osv.osv):
'name': fields.char('Name', size=64, required=True, select=1),
'note': fields.text('Note'),
'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic account'),
'account_asset_id': fields.many2one('account.account', 'Asset Account', required=True),
'account_depreciation_id': fields.many2one('account.account', 'Depreciation Account', required=True),
'account_expense_depreciation_id': fields.many2one('account.account', 'Depr. Expense Account', required=True),
'account_asset_id': fields.many2one('account.account', 'Asset Account', required=True, domain=[('type','=','other')]),
'account_depreciation_id': fields.many2one('account.account', 'Depreciation Account', required=True, domain=[('type','=','other')]),
'account_expense_depreciation_id': fields.many2one('account.account', 'Depr. Expense Account', required=True, domain=[('type','=','other')]),
'journal_id': fields.many2one('account.journal', 'Journal', required=True),
'company_id': fields.many2one('res.company', 'Company', required=True),
'method': fields.selection([('linear','Linear'),('degressive','Degressive')], 'Computation Method', required=True, help="Choose the method to use to compute the amount of depreciation lines.\n"\

View File

@ -262,6 +262,7 @@ class abstracted_fs(object):
if path == '/' and mode in ('list', 'cwd'):
return (None, None, None )
if path == '..': path = self.cwd + '/..'
path = _to_unicode(os.path.normpath(path)) # again, for '/db/../ss'
if path == '.': path = ''

View File

@ -410,8 +410,8 @@ class email_template(osv.osv):
# create a mail_mail based on values, without attachments
values = self.generate_email(cr, uid, template_id, res_id, context=context)
assert values.get('email_from'), 'email_from is missing or empty after template rendering, send_mail() cannot proceed'
if not values.get('email_from'):
raise osv.except_osv(_('Warning!'),_("Sender email is missing or empty after template rendering. Specify one to deliver your message"))
# process partner_to field that is a comma separated list of partner_ids -> recipient_ids
# NOTE: only usable if force_send is True, because otherwise the value is
# not stored on the mail_mail, and therefore lost -> fixed in v8

View File

@ -320,10 +320,9 @@ class mrp_bom(osv.osv):
"""
routing_obj = self.pool.get('mrp.routing')
factor = factor / (bom.product_efficiency or 1.0)
max_rounding = max(bom.product_rounding, bom.product_uom.rounding)
factor = rounding(factor, max_rounding)
if factor < max_rounding:
factor = max_rounding
factor = rounding(factor, bom.product_rounding)
if factor < bom.product_rounding:
factor = bom.product_rounding
result = []
result2 = []
phantom = False
@ -772,7 +771,7 @@ class mrp_production(osv.osv):
# qty available for consume and produce
qty_avail = scheduled.product_qty - consumed_data.get(scheduled.product_id.id, 0.0)
if qty_avail <= 0.0:
if float_compare(qty_avail, 0, precision_rounding=scheduled.product_id.uom_id.rounding) <= 0:
# there will be nothing to consume for this raw material
continue
@ -784,7 +783,7 @@ class mrp_production(osv.osv):
# if qtys we have to consume is more than qtys available to consume
prod_name = scheduled.product_id.name_get()[0][1]
raise osv.except_osv(_('Warning!'), _('You are going to consume total %s quantities of "%s".\nBut you can only consume up to total %s quantities.') % (qty, prod_name, qty_avail))
if qty <= 0.0:
if float_compare(qty, 0, precision_rounding=scheduled.product_id.uom_id.rounding) <= 0:
# we already have more qtys consumed than we need
continue

View File

@ -764,7 +764,7 @@
<field name="workcenter_id"/>
<field name="sequence"/>
<field name="cycle"/>
<field name="hour"/>
<field name="hour" widget="float_time"/>
</group>
</form>
<tree string="Production Work Centers">
@ -772,7 +772,7 @@
<field name="name"/>
<field name="workcenter_id"/>
<field name="cycle"/>
<field name="hour"/>
<field name="hour" widget="float_time"/>
</tree>
</field>
</page>

View File

@ -51,7 +51,7 @@
<field name="name"/>
<field name="workcenter_id" widget="selection"/>
<field name="cycle"/>
<field name="hour"/>
<field name="hour" widget="float_time"/>
<field name="state" />
</tree>
</field>

View File

@ -93,8 +93,9 @@ class plugin_handler(osv.osv_memory):
"""
mail_message = self.pool.get('mail.message')
model_obj = self.pool[model]
msg = self.pool.get('mail.thread').message_parse(cr, uid, email)
message_id = msg.get('message-id')
mail_thread_obj = self.pool.get('mail.thread')
msg = mail_thread_obj.message_parse(cr, uid, email)
message_id = msg.get('message_id')
mail_ids = mail_message.search(cr, uid, [('message_id', '=', message_id), ('res_id', '=', res_id), ('model', '=', model)])
if message_id and mail_ids:
mail_record = mail_message.browse(cr, uid, mail_ids)[0]
@ -107,12 +108,22 @@ class plugin_handler(osv.osv_memory):
res_id = model_obj.message_process(cr, uid, model, email)
notify = _("Mail successfully pushed, a new %s has been created.") % model
else:
email_from = msg.get('email_from')
if email_from:
author_id = False
else:
authors = mail_thread_obj.message_find_partner_from_emails(cr, uid, [res_id], [email_from])
author_id = authors and authors[0].get('partner_id') or False
model_obj.message_post(cr, uid, [res_id],
body=msg.get('body'),
subject=msg.get('subject'),
type='comment' if model == 'res.partner' else 'email',
parent_id=msg.get('parent_id'),
attachments=msg.get('attachments'))
attachments=msg.get('attachments'),
message_id=message_id,
email_from=email_from,
author_id=author_id)
notify = _("Mail successfully pushed")
url = self._make_url(cr, uid, res_id, model)
return (model, res_id, url, notify)
@ -151,7 +162,7 @@ class plugin_handler(osv.osv_memory):
ir_attachment_obj = self.pool.get('ir.attachment')
attach_ids = []
msg = self.pool.get('mail.thread').message_parse(cr, uid, headers)
message_id = msg.get('message-id')
message_id = msg.get('message_id')
push_mail = self.push_message(cr, uid, model, headers, res_id)
res_id = push_mail[1]
model = push_mail[0]
@ -165,6 +176,6 @@ class plugin_handler(osv.osv_memory):
attach_ids.append(ir_attachment_obj.create(cr, uid, vals))
mail_ids = mail_message.search(cr, uid, [('message_id', '=', message_id), ('res_id', '=', res_id), ('model', '=', model)])
if mail_ids:
mail_message.write(cr, uid, mail_ids[0], {'attachment_ids': [(6, 0, attach_ids)], 'body': body, 'body_html': body_html})
mail_message.write(cr, uid, mail_ids[0], {'attachment_ids': [(6, 0, attach_ids)], 'body': body_html})
url = self._make_url(cr, uid, res_id, model)
return (model, res_id, url, notify)

View File

@ -52,7 +52,8 @@ class project_compute_phases(osv.osv_memory):
else:
project_ids = project_pool.search(cr, uid, [('user_id','=',uid)], context=context)
project_pool.schedule_phases(cr, uid, project_ids, context=context)
if project_ids:
project_pool.schedule_phases(cr, uid, project_ids, context=context)
return self._open_phases_list(cr, uid, data, context=context)
def _open_phases_list(self, cr, uid, data, context=None):

View File

@ -909,6 +909,15 @@ class purchase_order_line(osv.osv):
default.update({'state':'draft', 'move_ids':[],'invoiced':0,'invoice_lines':[]})
return super(purchase_order_line, self).copy_data(cr, uid, id, default, context)
def unlink(self, cr, uid, ids, context=None):
procurement_ids_to_cancel = []
for line in self.browse(cr, uid, ids, context=context):
if line.move_dest_id:
procurement_ids_to_cancel.extend(procurement.id for procurement in line.move_dest_id.procurements)
if procurement_ids_to_cancel:
self.pool['procurement.order'].action_cancel(cr, uid, procurement_ids_to_cancel)
return super(purchase_order_line, self).unlink(cr, uid, ids, context=context)
def onchange_product_uom(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id,
partner_id, date_order=False, fiscal_position_id=False, date_planned=False,
name=False, price_unit=False, context=None):

View File

@ -208,7 +208,7 @@
<page string="Purchase Order">
<field name="order_line">
<tree string="Purchase Order Lines" editable="bottom">
<field name="product_id" on_change="onchange_product_id(parent.pricelist_id,product_id,0,product_uom,parent.partner_id, parent.date_order,parent.fiscal_position,date_planned,name,price_unit,context)"/>
<field name="product_id" on_change="onchange_product_id(parent.pricelist_id,product_id,0,False,parent.partner_id, parent.date_order,parent.fiscal_position,date_planned,name,price_unit,context)"/>
<field name="name"/>
<field name="date_planned"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
@ -387,7 +387,7 @@
<sheet>
<group>
<group>
<field name="product_id" on_change="onchange_product_id(parent.pricelist_id,product_id,0,product_uom,parent.partner_id, parent.date_order,parent.fiscal_position,date_planned,name,price_unit,context)"/>
<field name="product_id" on_change="onchange_product_id(parent.pricelist_id,product_id,0,False,parent.partner_id, parent.date_order,parent.fiscal_position,date_planned,name,price_unit,context)"/>
<label for="product_qty"/>
<div>
<field name="product_qty" on_change="onchange_product_id(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id,parent.date_order,parent.fiscal_position,date_planned,name,price_unit,context)" class="oe_inline"/>

View File

@ -24,3 +24,13 @@
!python {model: procurement.order}: |
procurement = self.browse(cr, uid, ref('procurement_order_testcase0'))
assert procurement.purchase_id, 'RFQ should be generated!'
-
I delete the line from the purchase order and check that the move and the procurement are cancelled
-
!python {model: procurement.order}: |
procurement = self.browse(cr, uid, ref('procurement_order_testcase0'))
move = procurement.purchase_id.order_line[0].move_dest_id
procurement.purchase_id.order_line[0].unlink()
assert move.state == 'cancel', 'Move should be cancelled'
procurement.refresh()
assert procurement.state == 'cancel', 'Procurement should be cancelled'

View File

@ -125,7 +125,7 @@
<field name="product_id"
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom}"
groups="base.group_user"
on_change="product_id_change(parent.pricelist_id, product_id, product_uom_qty, product_uom, product_uos_qty, product_uos, name, parent.partner_id, False, True, parent.date_order, False, parent.fiscal_position, False, context)"/>
on_change="product_id_change(parent.pricelist_id, product_id, product_uom_qty, False, product_uos_qty, False, name, parent.partner_id, False, True, parent.date_order, False, parent.fiscal_position, False, context)"/>
<label for="product_uom_qty"/>
<div>
<field
@ -169,7 +169,7 @@
<field name="product_id"
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom}"
groups="base.group_user"
on_change="product_id_change(parent.pricelist_id, product_id, product_uom_qty, product_uom, product_uos_qty, product_uos, name, parent.partner_id, False, True, parent.date_order, False, parent.fiscal_position, False, context)"/>
on_change="product_id_change(parent.pricelist_id, product_id, product_uom_qty, False, product_uos_qty, False, name, parent.partner_id, False, True, parent.date_order, False, parent.fiscal_position, False, context)"/>
<field name="name"/>
<field name="product_uom_qty"
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom}"

View File

@ -33,7 +33,7 @@
<field name="product_id"
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom}"
groups="base.group_user"
on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, False, True, parent.date_order, product_packaging, parent.fiscal_position, False, context)"/>
on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,False,product_uos_qty,False,name,parent.partner_id, False, True, parent.date_order, product_packaging, parent.fiscal_position, False, context)"/>
</field>
<field name="product_uom_qty" position="replace">
<field context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom}"

View File

@ -90,13 +90,14 @@ class product_product(osv.osv):
stock_output_acc = datas.get('stock_output_account', False)
stock_input_acc = datas.get('stock_input_account', False)
journal_id = datas.get('stock_journal', False)
product_obj=self.browse(cr, uid, ids, context=context)[0]
account_valuation = product_obj.categ_id.property_stock_valuation_account_id
account_valuation_id = account_valuation and account_valuation.id or False
if not account_valuation_id: raise osv.except_osv(_('Error!'), _('Specify valuation Account for Product Category: %s.') % (product_obj.categ_id.name))
move_ids = []
loc_ids = location_obj.search(cr, uid,[('usage','=','internal')])
for rec_id in ids:
for product in self.browse(cr, uid, ids, context=context):
if product.valuation != 'real_time':
continue
account_valuation = product.categ_id.property_stock_valuation_account_id
account_valuation_id = account_valuation and account_valuation.id or False
if not account_valuation_id: raise osv.except_osv(_('Error!'), _('Specify valuation Account for Product Category: %s.') % (product.categ_id.name))
for location in location_obj.browse(cr, uid, loc_ids, context=context):
c = context.copy()
c.update({
@ -104,7 +105,6 @@ class product_product(osv.osv):
'compute_child': False
})
product = self.browse(cr, uid, rec_id, context=c)
qty = product.qty_available
diff = product.standard_price - new_price
if not diff: raise osv.except_osv(_('Error!'), _("No difference between standard price and new price!"))
@ -182,8 +182,7 @@ class product_product(osv.osv):
'debit': amount_diff,
'move_id': move_id
})
self.write(cr, uid, rec_id, {'standard_price': new_price})
self.write(cr, uid, ids, {'standard_price': new_price})
return move_ids

View File

@ -2625,7 +2625,7 @@ class stock_move(osv.osv):
quantity = move.product_qty
uos_qty = quantity / move_qty * move.product_uos_qty
if quantity_rest > 0:
if float_compare(quantity_rest, 0, precision_rounding=move.product_id.uom_id.rounding):
default_val = {
'product_qty': quantity,
'product_uos_qty': uos_qty,