So in class 1 for example I calculate a price and I want to assign this price to a field from class 2 for example.
How can I achieve this, I tried the following without success:
self.browse(cr, uid, ids[0]).task_id.xx_new_price = new_price
xx_new_price is a field from another class which I can access trough task_id. new_price just contains a number.
EDIT: Updated with code
class PurchaseOrder(osv.Model):
_inherit = 'purchase.order'
def wkf_confirm_order(self, cr, uid, ids, context=None):
new_price = self.pool.get('price.calculation').calculate_price(cr, uid, ids, context=context)
for purchase_order in self.browse(cr, uid, ids):
if purchase_order.task_id:
task = self.pool.get('project.task').browse(cr, uid, purchase_order.task_id)[0]
task.write({'xx_new_price': new_price})
_columns = {
'project_id': fields.many2one('project.project', 'Project'),
'task_id': fields.many2one('project.task', 'Task')
}
So I inherit the wkf_confirm method from purchase order (I left all the standard code out for this example). Because when I confirm an order I want it to assign a value to another field from another class (in this case the to the field xx_new_price in project.task. new_price calculates a price and contains a float.
For write a new value in table, you need to call write of ORM for that class.
First you should take a task_id from the current object and than assign a new_price
For example:
for project in self.browse(cr, uid, ids):
if project.task_id:
project.task_id.write({'xx_new_price': new_price})
Related
I would like to set Sales Team reference in picking directly when sales order confirm and picking is getting created.
But I didn't get enough hint how can I achieve this. Because the method which is called at the time of sales order confirmation is as follow.
def action_button_confirm(self, cr, uid, ids, context=None):
if not context:
context = {}
assert len(ids) == 1, 'This option should only be used for a single id at a time.'
self.signal_workflow(cr, uid, ids, 'order_confirm')
if context.get('send_email'):
self.force_quotation_send(cr, uid, ids, context=context)
return True
Here there is no any hint how can I pass it to picking ?
Purpose:
My aim is to set sales team reference in picking / shipment.
It's not that easy. Odoo uses procurement.orders for creating stock.moves and for them stock.pickings. Problem: Maybe a picking has more than one sales orders as origin. So there could be more than one sales team referenced.
But try to use a computed field:
section_id = fields.Many2one(
comodel_name="crm.case.section", string="Sales Team",
compute="_compute_section_id")
#api.multi
def _compute_section_id(self):
for picking in self:
section_ids = set()
for move in picking.move_lines:
if move.sale_line_id.order_id.section_id
section_ids.add(move.sale_line_id.order_id.section_id.id)
if len(section_ids) == 1:
picking.section_id = section_ids.pop()
You could also use a related field, but that could have really bad side effects. Because Odoo will take the first move.
section_id = fields.Many2one(
comodel_name="crm.case.section", string="Sales Team",
related="move_lines.sale_line_id.order_id.section_id")
I got that method from where it create picking. So I have just inherited it and added my code. action_ship_create will always get called at the time of shipment creation from the sales order.
#api.cr_uid_ids_context
def action_ship_create(self,cr,uid,ids,context={}):
result=super(sale_order,self).action_ship_create(cr,uid,ids,context=context)
for order in self.browse(cr,uid,ids,context=context):
order.picking_ids.write({'section_id':order.section_id.id})
return result
I am working in odoo 8, i have to update the stock move which is done. i.e. suppose the move was done and state becomes "done" but the quantity entered was incorrect, so to correct it i need to reduce the quantity of that move.
I am trying to update the quantity but it gives me error as :
_('Quantities, Units of Measure, Products and Locations cannot be modified on stock moves that have already been processed (except by the Administrator).'))
I was trying as below:
move.write({'product_uos_qty':correct_qty})
I also tried this:
move.sudo().write({'product_uos_qty':correct_qty})
Always i get the same error.
Please Help
Thanks,
The easiest way without getting into security or removing the constrains or restrictions Odoo put in place is to use sql. Just write the raw sql that accomplishes your task and execute it where you were trying to do your write above. Not sure if it is the best way. But in your addon you can inherit stock.move and completely override the function. Or just edit the file manually and restart your server. Not sure about the other problems it might cause but it should let your write to the field.
sql = ".....YOUR SQL HERE"
self.env.cr.execute(sql)
self.env.cr.commit()
Override the write function in addons/stock/stock.py
def write(self, cr, uid, ids, vals, context=None):
if context is None:
context = {}
if isinstance(ids, (int, long)):
ids = [ids]
# Check that we do not modify a stock.move which is done
frozen_fields = set(['product_qty', 'product_uom', 'product_uos_qty', 'product_uos', 'location_id', 'location_dest_id', 'product_id'])
for move in self.browse(cr, uid, ids, context=context):
if move.state == 'done':
#if frozen_fields.intersection(vals):
# raise osv.except_osv(_('Operation Forbidden!'),
# _('Quantities, Units of Measure, Products and Locations cannot be modified on stock moves that have already been processed (except by the Administrator).'))
propagated_changes_dict = {}
#propagation of quantity change
if vals.get('product_uom_qty'):
propagated_changes_dict['product_uom_qty'] = vals['product_uom_qty']
if vals.get('product_uom_id'):
propagated_changes_dict['product_uom_id'] = vals['product_uom_id']
#propagation of expected date:
propagated_date_field = False
if vals.get('date_expected'):
#propagate any manual change of the expected date
propagated_date_field = 'date_expected'
elif (vals.get('state', '') == 'done' and vals.get('date')):
#propagate also any delta observed when setting the move as done
propagated_date_field = 'date'
if not context.get('do_not_propagate', False) and (propagated_date_field or propagated_changes_dict):
#any propagation is (maybe) needed
for move in self.browse(cr, uid, ids, context=context):
if move.move_dest_id and move.propagate:
if 'date_expected' in propagated_changes_dict:
propagated_changes_dict.pop('date_expected')
if propagated_date_field:
current_date = datetime.strptime(move.date_expected, DEFAULT_SERVER_DATETIME_FORMAT)
new_date = datetime.strptime(vals.get(propagated_date_field), DEFAULT_SERVER_DATETIME_FORMAT)
delta = new_date - current_date
if abs(delta.days) >= move.company_id.propagation_minimum_delta:
old_move_date = datetime.strptime(move.move_dest_id.date_expected, DEFAULT_SERVER_DATETIME_FORMAT)
new_move_date = (old_move_date + relativedelta.relativedelta(days=delta.days or 0)).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
propagated_changes_dict['date_expected'] = new_move_date
#For pushed moves as well as for pulled moves, propagate by recursive call of write().
#Note that, for pulled moves we intentionally don't propagate on the procurement.
if propagated_changes_dict:
self.write(cr, uid, [move.move_dest_id.id], propagated_changes_dict, context=context)
return super(stock_move, self).write(cr, uid, ids, vals, context=context)
I have extended the hr_attendance module and I want to get the last value of 'action' of the current logged user (It can be 'sign_in' or 'sign_out')
I don't know how to access to that value.
In the attendance module there are these functions:
def _altern_si_so(self, cr, uid, ids, context=None):
...
def _state(self, cr, uid, ids, name, args, context=None)
...
But I don't know how to call that functions inside the extended module or if there is another way to get that value.
Looking the database tables I found the solution:
First we obtain the employee_id associated to the logged user
employee_id = {}
cr.execute('SELECT hr.id \
FROM resource_resource AS res JOIN hr_employee AS hr \
ON res.id = hr.resource_id \
WHERE res.user_id = %s',[uid])
for res in cr.fetchall():
employee_id = res[0]
Then, we get the last action of the employee_id
last_action = {}
cr.execute('SELECT hr_attendance.action \
FROM hr_attendance \
WHERE employee_id = %s',[employee_id])
for res in cr.fetchall():
last_action = res[0]
'last_action' has now "sign_in" or "sign_out" (The last action done by the current user in the attendance module)
What should i do to show error message in openerp when there is a duplicate line in sale order line record?
I can't get any way to test it in my project.
You can use _sql_constraints
This e.g is from account_payment:
_sql_constraints = [
('name_uniq', 'UNIQUE(name)', 'The payment line name must be unique!'),
]
Hope this will help you.
Regards,
You should create a module that extends the sale.order.line model and adds the constraint that checks for the duplicate. You can find further information here:
https://doc.openerp.com/v6.1/developer/03_modules_2/
You can display the warning message using osv package,
if True:
raise osv.except_osv(_('Warning!'),_('You cannot delete a leave'))
def action_confirm(self, cr, uid, ids, context=None):
move_obj = self.pool.get('stock.move')
for procurement in self.browse(cr, uid, ids, context=context):
cr.execute("select id,order_id,foc from sale_order_line where product_id = %s and order_id= %s and foc = %s", (procurement.product_id.id, procurement.move_id.sale_line_id.order_id.id, procurement.foc,))
data = cr.fetchall()
count = len(data)
if count >= 2:
raise osv.except_osv(_('Data Duplicate!'),
_('Please check the sale order line.Duplicate
I am using Openerp 6.1.1.
I want to create a sequence for only leads that become opportunity but not for all leads.
Since both leads and opportunity are modelled using the same table, it's not clear how to achieve this. Please suggest.
Thanks in advance.
You can add a sequence field in object. And when click on Button "Convert to Opportunity"
you can assign the sequence to this lead.
OR when you want to create opportunity from Opportunity menu then you overwrite the create method and in create method check type of record if type 'opportunity' then assign the sequence in record.
Thanks
i got this working finally.
Overriding convert_opportunity() was not possible since it may contain a list of ids which I couldn't figure out how to pass the sequence to. So I had to overwrite the _convert_opportunity_data() method (not a good choice though !).
def create(self, cr, uid, vals, context={}):
if vals['type']=='opportunity':
next_seq = self.pool.get('ir.sequence').get(cr, uid, 'crm.lead')
vals['seq'] = next_seq
res = super(crm_sequence, self).create(cr, uid, vals, context)
return res
def _convert_opportunity_data(self, cr, uid, lead, customer, section_id=False, context=None):
vals = super(crm_sequence, self)._convert_opportunity_data(cr, uid, lead, customer, section_id, context)
next_eq = self.pool.get('ir.sequence').get(cr, uid, 'crm.lead')
vals['seq'] = next_seq
return vals