Merge sale order line in Odoo programmatically - odoo-15

How can I merge sale order line on a sale order in Odoo programmatically? I have duplicated products in sale order line, I want to remove the duplicated lines but merge the quantity.
Thank you

The best way would be to deal with it at the origin: on sale order line creation : update quantity of an existing line having the same product instead of creating a new sale order line:
class SaleOrderLine(models.Model):
_inherit= 'sale.order.line'
#api.model_create_multi
def create(self, vals_list):
vals_list_newproduct=[]
for values in vals_list:
# if one order line contains a product already existing in this order:
existing_product_soline = self.search(
[('order_id','=',values['order_id'],('product_id','=',values['product_id'])])
if existing_product_soline:
existing_product_soline[0].write({
'product_uom_qty':
float(existing_product_soline[0]['product_uom_qty']) + float(values['product_uom_qty'])
})
else:
#this order line contains a new product for the sale order
vals_list_newproduct.append(values)
#create one new order_line as usual for lines containing new products
super(SaleOrderLine, self).create(vals_list_newproduct)

Related

Odoo-14: How to add orderline in current POS order

I need to append a "specific" product in current order's orderline on the the click on particular button, same functionality needs to be used i.e. when you click on any product and it gets added to orderline. With following line of code, unable to get order id:
this.env.pos.get_order()
I am unable to get in-process order id as it is not yet created in backend until its paid.
To get the order and add a new orderline you can use
var order = this.env.pos.get_order();
order.add_product(product, { quantity: 1, price: total_price });

Odoo - field from sales order to purchase order

I am using Odoo 10. I have a custom field call linear_units in Sales Order. I have make to order ticked and it creates an automatic Purchase order. I would like to include the field linear_units from Sales order to the purchase order. With below code I can select the Sales order but I cant figure out how to add a field.
class PurchaseOrder(models.Model):
_inherit = 'purchase.order'
sale_order_id = fields.Many2one(
'sale.order',
"Sale Order",
help="Reference to Sale Order")
The above code works for selecting a sales order in purchase order. I have a float field in Sales order called linear_units. I need this field to copy to purchase order. I tried below but does not work
class PurchaseOrder(models.Model):
_inherit = 'purchase.order'
linear_units2 = fields.Float("Linear Units")
#api.onchange('product_id','linear_units')
def _onchange_product_qty(self):
if self.product_id:
self.linear_units2 = self.sale.order.linear_units
you can add a related field in the purchase order for linear_units like below
class PurchaseOrder(models.Model):
_inherit = 'purchase.order'
sale_order_id = fields.Many2one('sale.order', "Sale Order", help="Reference to Sale Order")
linear_units = fields.Float(related='sale_order_id.linear_units')
It will fetch the related linear_units value from the selected sale_order_id
hope this helps!
What is the purpose of this field. Is it supposed to be on each order line or is it supposed to be on the sale order as a whole. With the setup you have, you two options: First
sale_order_lines = fields.One2many('sale.order.line', 'Sale Order Lines')
Then from there you can reference your order number and your linear units.
sale_order_id = fields.Many2one('sale.order', related='sale_order_lines.order_id', string='Sale Order')
linear_units2 = fields.Float(related='sale_order_lines.linear_units', string='Linear Units')
and Second:
sale_order_id = fields.Many2one('sale.order', string='Sale Order')
linear_units = fields.Float(related='sale_order_id.sale_order_lines.linear_units', string='Linear units')
Though I'm not entirely certain that the second option will work. If this is the same value on all order lines then I would suggest putting linear_units on sale.order, then if you need it on the order lines you can put a related field on the order lines and then your fields will look like below
class SaleOrder(model.Models):
_inherit='sale.order'
linear_units = fields.Float(string='Linear Units')
class SaleOrderLines(model.Models):
_inherit='sale.order.lines'
linear_units = fields.Float(related='order_id.linear_units', string='Linear Units', readonly=True)
class PurchaseOrder(models.Models):
_inherit='purchase.order'
sale_order_id = fields.Many2one('sale.order', string='Sale Order')
linear_units = fields.Float(related='sale_order_id.linear_units', string='Linear Units', readonly=True)
(I suggest putting the read only on your related fields because if they are changed on your inherited view it will change it for that sale order and all of its relations.)

Method to get product price for a given customer

I need to retrieve product price via XMLRPC.
I am using Product Price Lists so each customer can be assigned a given price list which gives specific discounts based on categories, etc.
I am struggling to find which method can be used to retrieve the price for a given product_template id at a given quantity, if that is actually possible.
So far I have not been able to try any specific method as I can not identify how can this be achieved without actually creating a sales order.
The module 'product' holds the pricelist mechanics. The model product.pricelist has a really nice method get_product_price(), which could be easily used server-side but not for the external/web API.
But if you have the possibility to write a little custom module, do that and override the model product.pricelist. Add the possibility to use this method, like:
Origin Method which can't be used because parameters are RecordSets:
def get_product_price(self, product, quantity, partner, date=False, uom_id=False):
""" For a given pricelist, return price for a given product """
self.ensure_one()
return self._compute_price_rule([(product, quantity, partner)], date=date, uom_id=uom_id)[product.id][0]
"Wrapper" for external/web API:
def web_api_get_product_price(
self, product_id, quantity, partner_id, date=False, uom_id=False):
""" For a given pricelist, return price for a given product
callable from web api"""
self.ensure_one()
# get records
product = self.env['product.product'].browse(product_id)
partner = self.env['res.partner'].browse(partner_id)
# call origin method
return self.get_product_price(
product, quantity, partner, date=date, uom_id=uom_id)
Now you can call this method, an example:
import xmlrpclib
db = 'db_name'
password = 'admin'
common = xmlrpclib.ServerProxy('http://localhost:8069/xmlrpc/2/common')
uid = common.authenticate(db, 'admin', password, {})
models = xmlrpclib.ServerProxy('http://localhost:8069/xmlrpc/2/object')
pricelist_id = 1
product_id = 5
partner_id = 7
quantity = 20
price = models.execute_kw(
db, uid, password, 'product.pricelist',
'web_api_get_product_price',
[[pricelist_id], product_id, quantity, partner_id], {})

Set sales order fields reference in picking - odoo

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

openerp 7: displaying Manufacturing Orders for Sales Order

I have created a custom entity that lets us select a sales order. The desire is that when a sales order is selected, it should show a list of manufacturing orders linked to that sales order.
How to go about getting this in place? And what should be in the mode? fields.related or fields.one2many?
Thanks
code:
class my_custom(osv.osv):
_name = 'mrp.mycustom'
_columns={
'name': fields.char('Name',size=64),
'salesorder_id': fields.many2one('sale.order','Sales Order')
}
my_custom()
There is no direct link between sale order and manufacturing order. You need to add a link first.then you you can use a one2many to show your manufacturing order