Index an inherited ProductTemplate field on ProductProduct - sql

I've added a field to product.template, source_id, via:
class ProductTemplate(models.Model):
_inherit = 'product.template'
source_id = fields.Integer('Original Source ID', help="The original source ID", index=True, required=False)
Right now my SQL DELETE queries on product.product are taking forever because source_id isn't an actual indexable field on product.product.
What I would like to do is inherit this same field on product.product, so that I can search product.product by source_id and perform large SQL DELETE queries on product.product.
Any suggestions for how to approach this?
An alternative solution would be to figure out a way to destroy dependent product.product records when DELETE is run on product.template. I'm not sure how to do this in Odoo/Postgres.

Please use the below code:
class ProductProduct(models.Model):
_inherit = 'product.product'
source_id = fields.Integer('Original Source ID',related='product_tmpl_id.source_id', help="The original source ID")

Related

TypeError: Many2many fields library.book.partner.channel_ids and res.partner.channel_ids use the same table and columns

I'm trying to develop simple library app with Odoo but I get an error with manytomany relationship.
Here are classes:
class Book(models.Model):
_name = "library.book"
publisher_id = fields.Many2one(comodel_name="library.book.partner", string="Publisher")
author_ids = fields.Many2many(comodel_name="library.book.partner", relation='library_book_profile_partner_authors', column1='book_id', column2='partner_id', string="Authors")
class Partner(models.Model):
_name = "library.book.partner"
_inherit = "res.partner"
published_book_ids = fields.One2many("library.book", "publisher_id", string="Published Books")
book_ids = fields.Many2many("library.book", 'partner_books', 'book_id', 'partner_id', string="Authored Books")
This is the error I always get when installing the app
TypeError: Many2many fields library.book.partner.channel_ids and res.partner.channel_ids use the same table and columns
Someone can help to solve this please ?
It's the _inherit = "res.partner". Odoo is inheriting the model with a new model name which means it's creating a new table and copying all fields. For channel_ids it's trying to create the many2many "join" table, but with the same name as in res.partner. That happens because the table name is directly defined in the field (mail_channel_partner).
channel_ids = fields.Many2many('mail.channel', 'mail_channel_partner',
'partner_id', 'channel_id', string='Channels', copy=False)
So to solve the problem you have to "redefine" channel_ids on your new model again and change the table name, for example like:
channel_ids = fields.Many2many(relation='mail_channel_library_book_partner')

how can I create a computed fields that is depending on another model

I have two models reservation(inherit from sale.order) and places . I want to make a one2many field in the places model so when a reservation(sale.order) is confirmed, the new customer who reserved the place is added to this field
here is my code
model reservation
from odoo import fields, models,api,_
from odoo.exceptions import Validation-error
class Customers2(models.Model):
_inherit='sale.order'
client=fields.Many2one('res.partner',string='client')
secure_place=fields.Many2one(comodel_name='product.template',string='Secure place')
guests=fields.Integer(string='guests')
hotel_reser=fields.Many2one('product.template')
start_date=fields.Datetime(string='start date')
end_date=fields.Datetime(string='end date')
reserv_price=fields.Monetary(string='Price')
currency_id = fields.Many2one(comodel_name='res.currency',string='Currency')
reserv_status = fields.Selection(
[('C', 'Confirmed'), ('D', 'Draft')],
string='Reservation type')
model places
from odoo import fields , models,api
class Place(models.Model):
_inherit='product.template'
hotel=fields.Selection([('H', 'Habit'),('Y','Yasmine'),('M','movenpick')],string='Hotel')
type_of_room=fields.Selection([('S', 'spa'),('M','meeting room'),('N','Nightclub')],string='Room')
reserv_persons=fields.One2many('sale.order','hotel_reser',string='clients reserved',compute='_compute_reservations')
To add the new customer who reserved the place in the reserv_persons field, the related model should be res.partner and its type many2many.
You want to use a computed field (the value is computed when needed), so you can search for sale orders in the sale state to show all customers who reserved the place
Example:
from odoo import api, fields, models, _, Command
class Place(models.Model):
_inherit = 'product.template'
reserv_persons = fields.Many2many('res.partner', string='clients reserved', compute='_compute_reservations')
def _compute_reservations(self):
sale_order = self.env['sale.order']
for tmpl in self:
tmpl.reserv_persons = [Command.link(so.client.id) for so in sale_order.search(
[('secure_place', '=', tmpl.id), ('state', '=', 'sale')])]
The Command used above is a special command to manipulate the relation of One2many and Many2many

Constraints with better performence

In my model, client_id must be one per product. So I want to make a constraint for this situation.
class ClientSystemCode(models.Model):
_name = 'client.system.code'
_description = 'Client System Code'
client_id = fields.Many2one('res.partner', 'Client')
product_id = fields.Many2one('product.template', 'Product')
client_sys_code = fields.Char('Client system code')
in product.template model my constraints look like this.
#api.constrains('client_system_code_ids')
def _client_system_code_constraint(self):
duplicates = []
for line in self.client_system_code_ids:
if line.client_id.id not in duplicates:
duplicates.append(line.client_id.id)
else:
raise ValidationError(_("Product can't have more than one client code with same client"))
it is ok as it triggered from product form view and there always be not that much lines. But constraint in client.system.code should be better performance wise because there can be thousands of lines. So is there any kind of better solutions?
You will get it done easily using an sql constraint like:
class ClientSystemCode(models.Model):
_name = 'client.system.code'
_sql_constraints = [
('client_product_unique', 'unique (client_id, product_id)', 'Product can't have more than one client code with same client'),
]

two many2many fields with different partner

i have two fields that should be related to res.partner
in partner_ids i want to choose partner and in recipients_ids i want to choose another partner that will get a copy of the document. the problem that in form view if i change partner_ids or recipient_ids both fields became the same. how can i do that i can choose different partners in those fields?
partners_ids = fields.Many2many('res.partner', string='Companys Names')
recipients_ids = fields.Many2many('res.partner', string='Copys for')
You are getting the error because the two field work on the same table in postgres
because odoo create a table for that name like this:
current_model_name_co_model_name_rel
in your case
your_model_res_partner_rel
so you need to tell odoo that every field has it's own relation
partners_ids = fields.Many2many('res.partner', # co_model
'your_model_partners_rel', # relation name change your_model to much your model name
string='Companys Names')
recipients_ids = fields.Many2many('res.partner',
'your_model_recipients_rel',
string='Copys for')
when you create m2m field it's better to specify this value by keyarguement
_name = 'my.model'
# exmple
user_ids = fields.Many2many(comodel_name='res.users', # name of the model
relation='my_model_users_rel', # name of relation in postgres
column1='session_id', # id reference to current mode
column2='user_id', # id reference to co_model
string='Allowed users')

Odoo 8 : how to link a Many2one field automatically with the parent model?

I created a new model 'sale.order.category' in order to group Sale Order Lines in specific subcategories (allowing to display subtotals, etc.)
class SaleOrderCategory(models.Model):
_name = 'sale.order.category'
name = fields.Char('Name', required=True)
line_ids = fields.One2many('sale.order.line', 'category_id', 'Order Lines in this category')
order_id = fields.Many2one('sale.order', 'Order', required=True, readonly=True)
class SaleOrder(models.Model):
_name = 'sale.order'
_inherit = 'sale.order'
order_category_ids = fields.One2many('sale.order.category', 'order_id', 'Categories in this order', readonly=True, copy=True)
Just for info, here is my Order lines tree view modification to add the Category column :
<!-- adds a category column in the order lines list -->
<xpath expr="//field[#name='order_line']/tree/field[#name='name']" position="after">
<field name="category_id"/>
</xpath>
My question is : how can I automatically populate the order_id field with the current Sales Order ID when I create a new Category through the Order Lines Tree (inside a Sales Order) ?
Many thanks,
Max
Preliminary remark: your use case seems related to what the official sale_layout module does, so you might want to have a look at it before going any further. Perhaps you could extend it instead of starting from scratch.
Next, the most basic answer to your question is to pass a default value for the order_id field of your sale.order.category model when you create it from the view. You can do that by setting a context with an appropriate default value on the many2one field from which you will create the value:
<xpath expr="//field[#name='order_line']/tree/field[#name='name']" position="after">
<field name="category_id" context="{'default_order_id': parent.id}"/>
</xpath>
Your category_id field is defined on the sale.order.line tree view, so parent will dynamically refer to the parent record inside the web client interface, here the sale.order.
However this option will not work well:
When you're creating a new sales order, you will have to create your categories before the sales order is even saved, so there is no possible value for order_id yet. For this reason, you cannot make order_id required, and you will have to set its value again later, or you will need to save your orders before starting to add the categories.
You already have an order_lines one2many field in your sale.order.category model. The order_id field is redundant with the line_ids field, because all lines presumably belong to the same order.
A simple alternative would be to entirely omit the order_id field (use lines_id[0].order_id when you need it), or to replace it with a related field that will be automatically computed from the lines (it will take the value from the first order line):
order_id = fields.Many2one('sale.order', related='line_ids.order_id', readonly=True)
What you should do depends on your requirements, it's difficult to say based only on your question.