How to move field in sale order to stock picking - odoo

I have a problem, I made two custom fields in
Sale.order
Stock.picking
How to do when the sale order is confirmed, the field in stock.picking also filled? and the data was picked up from the field at sale.order I've made before.
I'm using odoo 10
Thanks

Yeah, first, depend in your module of sale_stock, then, inherit the sales confirm button and search for the pickings associated:
#api.multi
def action_confirm(self):
result = super(SaleOrder, self).action_confirm()
for order in self:
order.picking_ids.write({'your_field_in_picking': order.your_field_in_sale})
return result
Put it in a class that inherits from sale.order

Related

How to store relational fields to the database?

I've been searching for this for a week now, and still don't find any satisfying answer. If we make any type of relationship to other model in Odoo (in any framework as well) it won't store the data inside it, it will only store its id. Now when the related model get changed, the change will also true for all the child models that's inheriting it.
I want just like in the Sale module, when I change any product in Products model, it doesn't change the same product that's already stored in the orders. Please, any help, I'm very new here to Odoo I used to develop with Java.
An order correspond to the model named sale.order which is in one2many relationship with the model sale.order.line (SOL). one SOL has it s OWN fields for price, vat... which are computed bases on the current state of product at the time of the customer order. That's why the order and its SOL are not updated when the corresponding product attributes (price...) are changed...
In Odoo : an inherited python class EXTENDS the original class (similar to java extends) : in the sale_coupon module, the model located at src/odoo/addons/sale_coupon/models/sale_order.py is :
class SaleOrder(models.Model):
_inherit = "sale.order"
extends the source class SaleOrder defined in the module sale : src/odoo/addons/sale/models/sale.py:
class SaleOrder(models.Model):
name = "sale.order"
That's mean that the inherited class SaleOrder (_inherit) gets the specific attributes (fields) and methods (def) provided and defined in its source(s) class(es) : saleOrder :
origin = fields.Char(string='Source Document', help="Reference of the document that generated this sales order request.")
def _amount_all(self):
""" Compute the total amounts of the SO."""
for order in self:
amount_untaxed = amount_tax = 0.0
for line in order.order_line:
amount_untaxed += line.price_subtotal
amount_tax += line.price_tax
...
And you can add new fields and new methods in your inherited class SaleOrder scope :
reward_amount = fields.Float(compute='_compute_reward_total')
def action_confirm(self):
self.generated_coupon_ids.write({'state': 'new'})
...
return super(SaleOrder, self).action_confirm()
But, you don t need to instantiate theses Classes in your code (you don t need to create yourself Objects).
Theses classes have the basic CRUD-methods provided from models.Model: def create(), def read(), def write(), def unlink()
The source and the inherited class(es) both are connected to the same database-table : sale_order
So one Class-record (python in Odoo) :
self.env['sale.order'].browse(12)
corresponds to one record in the database-table : sale_order
Theses classes (SaleOrder) have the CRUD-methods from model.Model : def create(), def read(), def write(), def unlink() and they can override them in their own scope, where you can optionally call the "parent"-def : super(SaleOrder, self).unlink() :
def unlink(self):
for order in self:
if order.state not in ('draft', 'cancel'):
raise UserError(_('You can not delete a sent quotation or a confirmed sales order. You must first cancel it.'))
return super(SaleOrder, self).unlink()
Relations betweens models are defined using fields :
A relation between the sale.order model and the res.partner model (contact) is created using fields.Many2one:
class SaleOrder(models.Model):
...
partner_id = fields.Many2one('res.partner')
which is reflected in the corresponding database-table.
First of all, If you change the product details It will these details will change accordingly in the sale order after you refresh, about store the id of relation field its the standard way to use,
but there Is another way I think this is the way you looking for which Is store data as a JSON in column with type JSON as an example for sale order line table if you want to store the product as a JSON column it will be like below:
[{"id": 1, "name": "product 1"},]
of course, there Is a way to read and update and create the data into a JSON column you can read about It.
one more way as an example if you want to store the product to the current record of relation table not just store the Id and query to get the result you can just create new fields for data you want to store like if you want to store the name and price with name and id then you must add fields for this date and when you create in order line rather than add just product Id as a relation just add the product data to the new fields you have added before but this is not a good way.
I hope I understand your question and this answer helps you.

how to get only child name not with parent name in many2many field with many2many_tags widget odoo?

I have the Customer field in the Sale Order form.
I have added a new Many2many field with many2many_tags for Child Contacts of Customers in the Sale order form.
Now when I change Customer this new field fills with its child contacts.
But it comes with a Customer name.
I want to display only the name of child contacts.
Thanks in Advance.
You should inherit the name_get method like below.
#api.multi
def name_get(self):
if not self._context.get('ADD_CONTEXT_ON_SALEORDER_ACTION_AND_ALSO_ON_FIELD'):
return super(ResPartner, self).name_get()
res = []
for partner in self:
res.append((partner.id, partner.name))
return res
as per above code you also you need to add context in sale order action and on that many2many field too.
The values are coming from js file of many2many_tags
In this it shows values of display_name.
You can change the code as per your need.

How can I show one2many field of another model in my form view

I have a custom object "Car" with a one2many relationship to another object "Trips" which captures the various trips made by the car.I added the trips to the form view of the car so i can see all the trips made by each car. I created a custom many2one field in sale.order called "x_car" related to "Car" and added it to the sale.order form view. Now i want to add a one2many field too, which will show the trips of the car when it is selected in the sale.order form view. How can i achieve that?
I have already tried to create a one2many field in sale.order (trips,car_id) and set related to x_car.trips
I hoped it would pull all the records from Trips based on the selected x_car, but it does not return any data. I know a one2many relationship would typically be based on the object_id (in this case sale_order_id) but is there a way to base it on x_car?
You can use a computed many2many field for such purposes:
class SaleOrder(models.Model):
_inherit = "sale.order"
car_id = fields.Many2one(comodel_name="car")
trip_ids = fields.Many2many(
comodel_name="trip", string="Trips",
compute="_compute_trip_ids")
#api.multi
#api.depends('car_id')
def _compute_trip_ids(self):
for order in self:
order.trip_ids = order.car_id.trip_ids.ids
I bet your field names or a bit off of my example, but i always try to stick to the Odoo guidelines. Just substitute them with your names ;-)

How can I modify a selection field from another class in odoo 9?

I want to modify the "invoice_status" field from the "SaleOrder" class asociated to an invoice after the validation of that invoice.
The validation of an invoice is defined in the "AccountInvoice" class, inside the account module:
#api.multi
def invoice_validate(self):
...
I realised that the "name" field from "SaleOrder" class is related with the "origin" field from "AccountInvoice" class.
So, i modified the invoice_validate function like this:
#api.multi
def invoice_validate(self):
for invoice in self:
...
origin = self.origin
sale_order_id = self.env['sale.order'].search([('name', '=', origin)])[0].id
sale_order_obj = self.env['sale.order'].browse(sale_order_id)
sale_order_obj.write({'invoice_status': 'invoiced'})
return self.write({'state': 'open'})
For some reason, the write parte doesn't work.
That is the official definition of the "invoice_status" field from SaleOrder class:
invoice_status = fields.Selection([
('upselling', 'Upselling Opportunity'),
('invoiced', 'Fully Invoiced'),
('to invoice', 'To Invoice'),
('no', 'Nothing to Invoice')
], string='Invoice Status', compute='_get_invoiced', store=True, readonly=True, default='no')
You cannot set the value of invoice_status because it is a compute field. Even if you set it's value, it will be recomputed again when the field it depends on is changed and will eventually find the value it is supposed to have --and write that value instead of yours.
Odoo made it so that it work (it will say invoiced when the order is invoiced). So I don't think you need to do it maually. If you badly need to have your value stored, you should change that field so that it is not computed anymore, or create another field.
Check the selection_add attribute of the Selection class.
If you want to add some items to a selection field you have to redefine it in another class that inherits from the same model and declare it like this:
invoice_status = fields.Selection(selection_add=[("state", "open")])
Check the Selection class documentation and search for selection_add in your codebase to see some examples.

How to send multiple values in many2many field in odoo?

I am trying to generate purchase order from manufacturing order.I have created many2many field for getting multiple products.I want to send multiple product ids to my custom function.I am able to send 1 value but sending more than one gives error as Expected singleton: product.template(4, 3).
from openerp import models,fields,api
class generate_purchase_order(models.Model):
_name = 'mrp_to_purchase_order'
product_id = fields.Many2many('product.template',string='Products',required=True)
#api.multi
def generate_purchase_order2(self):
for wizard in self:
mrp_obj = self.env['mrp.production']
mrp_obj.generate_purchase_order(wizard.product_id.id) #function call
return { 'type': 'ir.actions.act_window_close'}
mrp_custom.py,
from openerp import models,api
class mrp_production(models.Model):
_inherit = 'mrp.production'
#api.multi
def generate_purchase_order(self,product_id):
purchase_line_obj = self.env['purchase.order.line']
context = self._context
for order in self.browse(context['active_ids']):
for line in order.bom_id.bom_line_ids:
if line.product_id.id != product_id:#problem line
continue
#rest of code
singleton: product.template(4, 3)
This error means that code is expecting single record not recordset, so you must change code to allow recordset using or make ensureone with try-catch and avoid errors. Thats general information.
Now if you want to get multiple records from many2many its not problem at all, you must pass this many2many object only and then work with it.
After getting many2many object to work with every record from this recordset you must use for record in recordset:
Also wizard.product_id.id this is error!!! product_id is many2many so you must pass product_id or if you want to browse by yourself you must pass product_id.ids