Odoo : OpenERP7 _prepare_purchase_order_line method equivalent in Odoo 12 - odoo

I'm working on migrating an old module from OpenERP 7 to Odoo 12. I'm stuck in this method called _prepare_purchase_order_line, you can find it in model purchase.requisition.
Here is its code :
def make_purchase_order(self, cr, uid, ids, partner_id, context=None):
"""
Create New RFQ for Supplier
"""
context = dict(context or {})
assert partner_id, 'Supplier should be specified'
purchase_order = self.pool.get('purchase.order')
purchase_order_line = self.pool.get('purchase.order.line')
res_partner = self.pool.get('res.partner')
supplier = res_partner.browse(cr, uid, partner_id, context=context)
res = {}
for requisition in self.browse(cr, uid, ids, context=context):
if not requisition.multiple_rfq_per_supplier and supplier.id in filter(lambda x: x, [rfq.state != 'cancel' and rfq.partner_id.id or None for rfq in requisition.purchase_ids]):
raise osv.except_osv(_('Warning!'), _('You have already one %s purchase order for this partner, you must cancel this purchase order to create a new quotation.') % rfq.state)
context.update({'mail_create_nolog': True})
purchase_id = purchase_order.create(cr, uid, self._prepare_purchase_order(cr, uid, requisition, supplier, context=context), context=context)
purchase_order.message_post(cr, uid, [purchase_id], body=_("RFQ created"), context=context)
res[requisition.id] = purchase_id
for line in requisition.line_ids:
purchase_order_line.create(cr, uid, self._prepare_purchase_order_line(cr, uid, requisition, line, purchase_id, supplier, context=context), context=context)
return res
I want to know what is the equivalent of this method in Odoo 12.
Can you help me?

I can see this method exist with the same name in odoo 12 but it is in purchase.requisition.line model.
#api.multi
def _prepare_purchase_order_line(self, name, product_qty=0.0, price_unit=0.0, taxes_ids=False):
self.ensure_one()
requisition = self.requisition_id
if requisition.schedule_date:
date_planned = datetime.combine(requisition.schedule_date, time.min)
else:
date_planned = datetime.now()
return {
'name': name,
'product_id': self.product_id.id,
'product_uom': self.product_id.uom_po_id.id,
'product_qty': product_qty,
'price_unit': price_unit,
'taxes_id': [(6, 0, taxes_ids)],
'date_planned': date_planned,
'account_analytic_id': self.account_analytic_id.id,
'analytic_tag_ids': self.analytic_tag_ids.ids,
'move_dest_ids': self.move_dest_id and [(4, self.move_dest_id.id)] or []
}

Related

How to use many2one field in the function in openerp

how can I use many2one field in the function?
this is my code:
def _get_unit(self, cr, uid, ids, fields,arg, context=None):
res = {}
list_data = []
for record in self.browse(cr, uid, ids,unit):
list_data.append(record[unit.id])
return super(learning_course, self)._get_unit(cr, uid, ids, context=context)
_columns = {
'unit': fields.many2one('hr.department', 'unit'),
'department': fields.function(_get_unit, string='department' , store=True ,type='many2one' ,relation='hr.department'),
}
def onchange_user(self, cr, uid, ids, user_id, context=None):
unit = False
if user_id:
unit = self.pool.get('res.users').browse(cr, uid, user_id, context=context).context_department_id.id
return {'value': {'unit' : unit }}
return {'value': {} }
but I get this error:
for record in self.browse(cr, uid, ids,unit):
AttributeError: 'browse_record_list' object has no attribute 'id'
what should I do?
def _get_unit(self, cr, uid, ids, prop, unknow_none, context=None):
res = {}
for record in self.browse(cr, uid, ids):
res [record.id] = record.user_id.context_department_id.id
return res
_columns = {
'user_id': fields.many2one('res.users', 'user', readonly=True),
'unit_id': fields.function(_get_unit, string='dep' , store=True ,type='many2one',relation='hr.department'),
}

Show product default_code in purchase order line

When creating a new purchase order I want to remove the product_name under the product_id so for that I did this function:
class snc_product(osv.osv):
_name='product.product'
_inherit='product.product'
def name_get(self, cr, uid, ids, context=None):
return_val = super(snc_product, self).name_get(cr, uid, ids, context=context)
res = []
def _name_get(d):
code = d.get('code','')
if d.get('variants'):
code = code + ' - %s' % (d['variants'],)
return (d['id'], code)
for product in self.browse(cr, uid, ids, context=context):
res.append((product.id, (product.code)))
return res or return_val
The problem now is even under description I'm getting the default_code instead of the name.
http://imgur.com/afLNQMS
How could I fix this problem?
Seems like you redefined also the name_get() method of the purchase.order.line model. The second column, named 'Description' is showing the name field ot the purchase.order.line model. That's why I suppose you redefined it.
Your solution is working for me - I have the product code in the first column and the description in the second. Only one thing - you don't need this internal _name_get() method as you don't use it.
Here is the code that worked for me:
from openerp.osv import osv, fields
class snc_product(osv.osv):
_name = 'product.product'
_inherit = 'product.product'
def name_get(self, cr, uid, ids, context=None):
return_val = super(snc_product, self).name_get(cr, uid, ids,
context=context)
res = []
for product in self.browse(cr, uid, ids, context=context):
res.append((product.id, (product.code)))
return res or return_val
snc_product()

Store parameter in a function

I have a relation between the fuel and voucher classes with the field 'amount_used' that calculates the number of voucher x used in fuel without problems
_name = 'fleet.vehicle.log.fuel'
'voucher_id': fields.many2one('fleet.voucher', 'Voucher'),
_name = 'fleet.voucher'
'amount_used': fields.function(_count_all, type='integer', string="Amount Used")
def _count_all(self, cr, uid, ids, field_name, arg, context=None):
Fuel = self.pool['fleet.vehicle.log.fuel']
return {
voucher_id: Fuel.search_count(cr, uid, [('voucher_id', '=', voucher_id)], context=context)
for voucher_id in ids
}
when I add the store parameter in 'amount_used' I have an update problem
store=True or store={'fleet.vehicle.log.fuel': (lambda self, cr, uid, ids, c={}: ids, ['voucher_id'], 10)}
store={'fleet.vehicle.log.fuel': (_get_voucher, ['voucher_id'], 10)}
def _get_voucher(self, cr, uid, ids, context=None):
res = []
for fuel in self.pool.get('fleet.vehicle.log.fuel').browse(cr, uid, ids, context=context):
if fuel.voucher_id:
res.append(fuel.voucher_id.id)
return res

how can we deny transfer of stock move if qty > order qty?

the new stock management in odoo allow to transfer more than commanded quantity!
how can we deny do_detailed_transfer in stock.picking when the quantity > order.quantity ?
raise an warrning if there is extra moves like:
raise osv.except_osv(_('Warning !'),
_(u'The quantity is more than validate quantity !!') )
#api.cr_uid_ids_context
def do_transfer(self, cr, uid, picking_ids, context=None):
"""
If no pack operation, we do simple action_done of the picking
Otherwise, do the pack operations
"""
if not context:
context = {}
stock_move_obj = self.pool.get('stock.move')
for picking in self.browse(cr, uid, picking_ids, context=context):
if not picking.pack_operation_ids:
self.action_done(cr, uid, [picking.id], context=context)
continue
else:
need_rereserve, all_op_processed = self.picking_recompute_remaining_quantities(cr, uid, picking, context=context)
#create extra moves in the picking (unexpected product moves coming from pack operations)
todo_move_ids = []
if not all_op_processed:
todo_move_ids += self._create_extra_moves(cr, uid, picking, context=context)
**raise osv.except_osv(_('Warning !'),
_(u'The quantity is more than validate quantity !!') )**
#split move lines if needed
toassign_move_ids = []
for move in picking.move_lines:
remaining_qty = move.remaining_qty
if move.state in ('done', 'cancel'):
#ignore stock moves cancelled or already done
continue
elif move.state == 'draft':
toassign_move_ids.append(move.id)
if float_compare(remaining_qty, 0, precision_rounding = move.product_id.uom_id.rounding) == 0:
if move.state in ('draft', 'assigned', 'confirmed'):
todo_move_ids.append(move.id)
elif float_compare(remaining_qty,0, precision_rounding = move.product_id.uom_id.rounding) > 0 and \
float_compare(remaining_qty, move.product_qty, precision_rounding = move.product_id.uom_id.rounding) < 0:
raise osv.except_osv(_('Warning !'),
_(u'La quantity doit être inferieur à %s'% move.product_qty) )
return False
new_move = stock_move_obj.split(cr, uid, move, remaining_qty, context=context)
todo_move_ids.append(move.id)
#Assign move as it was assigned before
toassign_move_ids.append(new_move)
if need_rereserve or not all_op_processed:
if not picking.location_id.usage in ("supplier", "production", "inventory"):
self.rereserve_quants(cr, uid, picking, move_ids=todo_move_ids, context=context)
self.do_recompute_remaining_quantities(cr, uid, [picking.id], context=context)
if todo_move_ids and not context.get('do_only_split'):
self.pool.get('stock.move').action_done(cr, uid, todo_move_ids, context=context)
elif context.get('do_only_split'):
context = dict(context, split=todo_move_ids)
self._create_backorder(cr, uid, picking, context=context)
if toassign_move_ids:
stock_move_obj.action_assign(cr, uid, toassign_move_ids, context=context)
return True

take field date from another database

in ticket.py. I have two class. class deposit.line and res_partner (inherit). I want to take the date of the class deposit.line but its function in the class res_partner(inherit)
def _compute_dept2(self, cr, uid, ids, amount, arg, context=None):
result = {}
obj2 = self.pool.get('deposit.line')
for record in obj2.deposit_line:
temp1 = record.date
print temp1
print result
return result
but the results of its existing print false. what wrong ? please correct my code
PS:
My explanation is less good. but look at my code,surely knowing my explanation.
THIS MY COMPLETE CODE:
class deposit_line(osv.osv):
_name ="deposit.line"
_description = "Deposit Line"
_columns = {
'name': fields.char('Name', size=64),
'ref': fields.char('Reference', size=64),
'amount': fields.float('Amount'),
'date': fields.date('Date', required=True),
'deposit_id': fields.many2one('res.partner', 'Deposit ', required=True, ondelete='cascade'),
}
deposit_line()
class res_partner(osv.osv):
_inherit = 'res.partner'
def _compute_age(self, cr, uid, ids,date_birth,age,arg, context=None):
result = {}
for r in self.browse(cr, uid, ids, context=context):
age=0
if r.date_birth:
age = (datetime.now()-datetime.strptime(r.date_birth,"%Y-%m-%d")).days/365.25
result[r.id] = age
return result
def _compute_dept(self, cr, uid, ids, deposit, available, arg, context=None):
result = {}
for r in self.browse(cr, uid, ids, context=context):
avail=0
temp = r.available
if r.deposit:
avail = r.deposit + temp
result[r.id] = avail
return result
def _compute_dept2(self, cr, uid, ids, amount, arg, context=None):
result = {}
obj2 = self.pool.get('deposit.line')
for record in obj2.deposit_line:
temp1 = record.date
print temp1
print result
return result
_columns = {
'speaker': fields.boolean('Leader'),
'event_ids': fields.one2many('event.event','main_speaker_id', readonly=True),
'event_registration_ids': fields.one2many('event.registration','partner_id', readonly=True),
'airline': fields.boolean('Airlines'),
'hotel': fields.boolean('Hotel'),
'date_birth': fields.date('Date of Birth'),
'id_no': fields.char('ID. No', size=20),
'id_expired': fields.date('Expired Date'),
'sex':fields.selection([('male','Male'),('female','Female')],'Sex'),
'age' : fields.function(_compute_age, type='float', method=True, store=True, string='Age', readonly=True),
'deposit': fields.function(_compute_dept2, type='float', method=True, store=True, string='Deposit', readonly=True),
'available': fields.function(_compute_dept, type='float', method=True, store=True, string='Available', readonly=True),
'deposit_ids':fields.one2many('deposit.line', 'deposit_id', 'Deposit Line'),
}
res_partner()
Since you have one2many field for deposit_line defined in the res.partner model, you do not need the to access deposit_line object directly.
def _compute_dept2(self, cr, uid, ids, amount, arg, context=None):
result = {}
for partner in self.browse(cr, uid, id, context=context)
result[partner.id]=0
for deposit_line in partner.deposit_ids:
result[partner.id] += deposit_line.amount
return result
After line 3, you forgot to:
obj2.browse(cr, uid, ids, context=context)
You should learn to use the debugger:
Add the line import pdb; pdb.set_trace() where you want to place a breakpoint. When the Python reaches the breakpoint it stops at the console with a (pdb) prompt. There type p obj to print variable obj, n to step to the next instruction, and hfor help. You might find more info in this post and in the docs.