[IMP] *: optimize code with search_fetch() and fetch()
closes odoo/odoo#112126 Related: odoo/enterprise#36782 Signed-off-by: Raphael Collet <rco@odoo.com>
This commit is contained in:
@@ -63,8 +63,7 @@ class CompanyLDAP(models.Model):
|
||||
:rtype: list of dictionaries
|
||||
"""
|
||||
|
||||
ldaps = self.sudo().search([('ldap_server', '!=', False)], order='sequence')
|
||||
res = ldaps.read([
|
||||
res = self.sudo().search_read([('ldap_server', '!=', False)], [
|
||||
'id',
|
||||
'company',
|
||||
'ldap_server',
|
||||
@@ -76,7 +75,7 @@ class CompanyLDAP(models.Model):
|
||||
'user',
|
||||
'create_user',
|
||||
'ldap_tls'
|
||||
])
|
||||
], order='sequence')
|
||||
return res
|
||||
|
||||
def _connect(self, conf):
|
||||
|
||||
@@ -23,7 +23,10 @@ class Partner(models.Model):
|
||||
|
||||
def _compute_meeting(self):
|
||||
if self.ids:
|
||||
all_partners = self.with_context(active_test=False).search([('id', 'child_of', self.ids)])
|
||||
# prefetch 'parent_id'
|
||||
all_partners = self.with_context(active_test=False).search_fetch(
|
||||
[('id', 'child_of', self.ids)], ['parent_id'],
|
||||
)
|
||||
|
||||
query = self.env['calendar.event']._search([]) # ir.rules will be applied
|
||||
query_str, params = query.subselect()
|
||||
@@ -43,7 +46,6 @@ class Partner(models.Model):
|
||||
meetings[m[0]].add(m[1])
|
||||
|
||||
# Add the events linked to the children of the partner
|
||||
all_partners.read(['parent_id'])
|
||||
for p in all_partners:
|
||||
partner = p
|
||||
while partner:
|
||||
|
||||
@@ -45,8 +45,9 @@ class Partner(models.Model):
|
||||
|
||||
def _compute_opportunity_count(self):
|
||||
# retrieve all children partners and prefetch 'parent_id' on them
|
||||
all_partners = self.with_context(active_test=False).search([('id', 'child_of', self.ids)])
|
||||
all_partners.read(['parent_id'])
|
||||
all_partners = self.with_context(active_test=False).search_fetch(
|
||||
[('id', 'child_of', self.ids)], ['parent_id'],
|
||||
)
|
||||
|
||||
opportunity_data = self.env['crm.lead'].with_context(active_test=False)._read_group(
|
||||
domain=[('partner_id', 'in', all_partners.ids)],
|
||||
|
||||
@@ -513,13 +513,16 @@ class Challenge(models.Model):
|
||||
|
||||
domain.append(('user_id', '=', user.id))
|
||||
|
||||
goal = Goals.search(domain, limit=1)
|
||||
goal = Goals.search_fetch(domain, ['current', 'completeness', 'state'], limit=1)
|
||||
if not goal:
|
||||
continue
|
||||
|
||||
if goal.state != 'reached':
|
||||
return []
|
||||
line_data.update(goal.read(['id', 'current', 'completeness', 'state'])[0])
|
||||
line_data.update({
|
||||
fname: goal[fname]
|
||||
for fname in ['id', 'current', 'completeness', 'state']
|
||||
})
|
||||
res_lines.append(line_data)
|
||||
continue
|
||||
|
||||
|
||||
@@ -594,11 +594,12 @@ class MailActivity(models.Model):
|
||||
|
||||
def activity_format(self):
|
||||
activities = self.read()
|
||||
mail_template_ids = set([template_id for activity in activities for template_id in activity["mail_template_ids"]])
|
||||
mail_template_info = self.env["mail.template"].browse(mail_template_ids).read(['id', 'name'])
|
||||
mail_template_dict = dict([(mail_template['id'], mail_template) for mail_template in mail_template_info])
|
||||
for activity in activities:
|
||||
activity['mail_template_ids'] = [mail_template_dict[mail_template_id] for mail_template_id in activity['mail_template_ids']]
|
||||
self.mail_template_ids.fetch(['name'])
|
||||
for record, activity in zip(self, activities):
|
||||
activity['mail_template_ids'] = [
|
||||
{'id': mail_template.id, 'name': mail_template.name}
|
||||
for mail_template in record.mail_template_ids
|
||||
]
|
||||
return activities
|
||||
|
||||
@api.model
|
||||
|
||||
@@ -742,26 +742,23 @@ class Message(models.Model):
|
||||
messages.set_message_done()
|
||||
return messages.ids
|
||||
|
||||
notifications = self.env['mail.notification'].sudo().search(notif_domain)
|
||||
notifications = self.env['mail.notification'].sudo().search_fetch(notif_domain, ['mail_message_id'])
|
||||
notifications.write({'is_read': True})
|
||||
|
||||
ids = [n['mail_message_id'] for n in notifications.read(['mail_message_id'])]
|
||||
|
||||
self.env['bus.bus']._sendone(self.env.user.partner_id, 'mail.message/mark_as_read', {
|
||||
'message_ids': [id[0] for id in ids],
|
||||
'message_ids': notifications.mail_message_id.ids,
|
||||
'needaction_inbox_counter': self.env.user.partner_id._get_needaction_count(),
|
||||
})
|
||||
|
||||
return ids
|
||||
|
||||
def set_message_done(self):
|
||||
""" Remove the needaction from messages for the current partner. """
|
||||
partner_id = self.env.user.partner_id
|
||||
|
||||
notifications = self.env['mail.notification'].sudo().search([
|
||||
notifications = self.env['mail.notification'].sudo().search_fetch([
|
||||
('mail_message_id', 'in', self.ids),
|
||||
('res_partner_id', '=', partner_id.id),
|
||||
('is_read', '=', False)])
|
||||
('is_read', '=', False),
|
||||
], ['mail_message_id'])
|
||||
|
||||
if not notifications:
|
||||
return
|
||||
@@ -782,9 +779,8 @@ class Message(models.Model):
|
||||
starred_messages = self.search([('starred_partner_ids', 'in', partner_id)])
|
||||
starred_messages.write({'starred_partner_ids': [Command.unlink(partner_id)]})
|
||||
|
||||
ids = [m.id for m in starred_messages]
|
||||
self.env['bus.bus']._sendone(self.env.user.partner_id, 'mail.message/toggle_star', {
|
||||
'message_ids': ids,
|
||||
'message_ids': starred_messages.ids,
|
||||
'starred': False,
|
||||
})
|
||||
|
||||
|
||||
@@ -132,37 +132,34 @@ class MailThread(models.AbstractModel):
|
||||
"""
|
||||
# TOFIX make it work with not in
|
||||
assert operator != "not in", "Do not search message_follower_ids with 'not in'"
|
||||
followers = self.env['mail.followers'].sudo().search([
|
||||
('res_model', '=', self._name),
|
||||
('partner_id', operator, operand)])
|
||||
# using read() below is much faster than followers.mapped('res_id')
|
||||
return [('id', 'in', [res['res_id'] for res in followers.read(['res_id'])])]
|
||||
# prefetch 'res_id' for the performance of mapped() below
|
||||
followers = self.env['mail.followers'].sudo().search_fetch(
|
||||
[('res_model', '=', self._name), ('partner_id', operator, operand)],
|
||||
['res_id'],
|
||||
)
|
||||
return [('id', 'in', followers.mapped('res_id'))]
|
||||
|
||||
@api.depends('message_follower_ids')
|
||||
def _compute_message_is_follower(self):
|
||||
followers = self.env['mail.followers'].sudo().search([
|
||||
('res_model', '=', self._name),
|
||||
('res_id', 'in', self.ids),
|
||||
('partner_id', '=', self.env.user.partner_id.id),
|
||||
])
|
||||
# using read() below is much faster than followers.mapped('res_id')
|
||||
following_ids = [res['res_id'] for res in followers.read(['res_id'])]
|
||||
followers = self.env['mail.followers'].sudo().search_fetch(
|
||||
[('res_model', '=', self._name), ('res_id', 'in', self.ids), ('partner_id', '=', self.env.user.partner_id.id)],
|
||||
['res_id'],
|
||||
)
|
||||
following_ids = set(followers.mapped('res_id'))
|
||||
for record in self:
|
||||
record.message_is_follower = record.id in following_ids
|
||||
|
||||
@api.model
|
||||
def _search_message_is_follower(self, operator, operand):
|
||||
followers = self.env['mail.followers'].sudo().search([
|
||||
('res_model', '=', self._name),
|
||||
('partner_id', '=', self.env.user.partner_id.id),
|
||||
])
|
||||
followers = self.env['mail.followers'].sudo().search_fetch(
|
||||
[('res_model', '=', self._name), ('partner_id', '=', self.env.user.partner_id.id)],
|
||||
['res_id'],
|
||||
)
|
||||
# Cases ('message_is_follower', '=', True) or ('message_is_follower', '!=', False)
|
||||
if (operator == '=' and operand) or (operator == '!=' and not operand):
|
||||
# using read() below is much faster than followers.mapped('res_id')
|
||||
return [('id', 'in', [res['res_id'] for res in followers.read(['res_id'])])]
|
||||
return [('id', 'in', followers.mapped('res_id'))]
|
||||
else:
|
||||
# using read() below is much faster than followers.mapped('res_id')
|
||||
return [('id', 'not in', [res['res_id'] for res in followers.read(['res_id'])])]
|
||||
return [('id', 'not in', followers.mapped('res_id'))]
|
||||
|
||||
def _compute_has_message(self):
|
||||
self.env['mail.message'].flush_model()
|
||||
@@ -172,7 +169,7 @@ class MailThread(models.AbstractModel):
|
||||
WHERE res_id = any(%s)
|
||||
AND mm.model=%s
|
||||
""", [self.ids, self._name])
|
||||
channel_ids = [r[0] for r in self.env.cr.fetchall()]
|
||||
channel_ids = {r[0] for r in self.env.cr.fetchall()}
|
||||
for record in self:
|
||||
record.has_message = record.id in channel_ids
|
||||
|
||||
|
||||
@@ -1104,10 +1104,11 @@ class MailComposer(models.TransientModel):
|
||||
self._cr.execute("SELECT email FROM mail_blacklist WHERE active=true")
|
||||
blacklist = {x[0] for x in self._cr.fetchall()}
|
||||
if blacklist:
|
||||
targets = self.env[self.model].browse(mail_values_dict.keys()).read(['email_normalized'])
|
||||
targets = self.env[self.model].browse(mail_values_dict.keys())
|
||||
targets.fetch(['email_normalized'])
|
||||
# First extract email from recipient before comparing with blacklist
|
||||
blacklisted_rec_ids.update(target['id'] for target in targets
|
||||
if target['email_normalized'] in blacklist)
|
||||
blacklisted_rec_ids.update(target.id for target in targets
|
||||
if target.email_normalized in blacklist)
|
||||
return blacklisted_rec_ids
|
||||
|
||||
def _get_done_emails(self, mail_values_dict):
|
||||
|
||||
@@ -91,13 +91,14 @@ class ReportBomStructure(models.AbstractModel):
|
||||
route_info = product_info.get(parent_product.id, {}).get(parent_bom.id, {})
|
||||
if route_info and route_info['route_type'] == 'subcontract':
|
||||
subcontracting_loc = route_info['supplier'].partner_id.property_stock_subcontractor
|
||||
subloc_product = product.with_context(location=subcontracting_loc.id, warehouse=False).read(['free_qty', 'qty_available'])[0]
|
||||
subloc_product = product.with_context(location=subcontracting_loc.id, warehouse=False)
|
||||
subloc_product.fetch(['free_qty', 'qty_available'])
|
||||
stock_loc = f"subcontract_{subcontracting_loc.id}"
|
||||
if not product_info[product.id]['consumptions'].get(stock_loc, False):
|
||||
product_info[product.id]['consumptions'][stock_loc] = 0
|
||||
return {
|
||||
'free_qty': product.uom_id._compute_quantity(subloc_product['free_qty'], bom_uom),
|
||||
'on_hand_qty': product.uom_id._compute_quantity(subloc_product['qty_available'], bom_uom),
|
||||
'free_qty': product.uom_id._compute_quantity(subloc_product.free_qty, bom_uom),
|
||||
'on_hand_qty': product.uom_id._compute_quantity(subloc_product.qty_available, bom_uom),
|
||||
'stock_loc': stock_loc,
|
||||
}
|
||||
|
||||
|
||||
@@ -13,12 +13,10 @@ class AccountTax(models.Model):
|
||||
'include_base_amount', 'is_base_affected',
|
||||
])
|
||||
if forbidden_fields & set(vals.keys()):
|
||||
tax_ids = self.env['pos.order.line'].sudo().search([
|
||||
open_lines = self.env['pos.order.line'].sudo().search([
|
||||
('order_id.session_id.state', '!=', 'closed')
|
||||
]).read(['tax_ids'])
|
||||
# Flatten the list of taxes, see https://stackoverflow.com/questions/952914
|
||||
tax_ids = set([i for sl in [t['tax_ids'] for t in tax_ids] for i in sl])
|
||||
if tax_ids & set(self.ids):
|
||||
])
|
||||
if not set(self.ids).isdisjoint(open_lines.tax_ids.ids):
|
||||
raise UserError(_(
|
||||
'It is forbidden to modify a tax used in a POS order not posted. '
|
||||
'You must close the POS sessions before modifying the tax.'
|
||||
|
||||
@@ -1586,21 +1586,29 @@ class PosSession(models.Model):
|
||||
return loaded_data
|
||||
|
||||
def _get_attributes_by_ptal_id(self):
|
||||
product_attributes = self.env['product.attribute'].search([('create_variant', '=', 'no_variant')])
|
||||
product_attributes_by_id = {product_attribute.id: product_attribute for product_attribute in product_attributes}
|
||||
domain = [('attribute_id', 'in', product_attributes.mapped('id'))]
|
||||
product_template_attribute_values = self.env['product.template.attribute.value'].search(domain)
|
||||
key = lambda ptav: (ptav.attribute_line_id.id, ptav.attribute_id.id)
|
||||
# performance trick: prefetch fields with search_fetch() and fetch()
|
||||
product_attributes = self.env['product.attribute'].search_fetch(
|
||||
[('create_variant', '=', 'no_variant')],
|
||||
['name', 'display_type'],
|
||||
)
|
||||
product_template_attribute_values = self.env['product.template.attribute.value'].search_fetch(
|
||||
[('attribute_id', 'in', product_attributes.ids)],
|
||||
['attribute_id', 'attribute_line_id', 'product_attribute_value_id', 'price_extra'],
|
||||
)
|
||||
product_template_attribute_values.product_attribute_value_id.fetch(['name', 'is_custom', 'html_color'])
|
||||
|
||||
key1 = lambda ptav: (ptav.attribute_line_id.id, ptav.attribute_id.id)
|
||||
key2 = lambda ptav: (ptav.attribute_line_id.id, ptav.attribute_id)
|
||||
res = {}
|
||||
for key, group in groupby(sorted(product_template_attribute_values, key=key), key=key):
|
||||
attribute_line_id, attribute_id = key
|
||||
for key, group in groupby(sorted(product_template_attribute_values, key=key1), key=key2):
|
||||
attribute_line_id, attribute = key
|
||||
values = [{**ptav.product_attribute_value_id.read(['name', 'is_custom', 'html_color'])[0],
|
||||
'price_extra': ptav.price_extra} for ptav in list(group)]
|
||||
res[attribute_line_id] = {
|
||||
'id': attribute_line_id,
|
||||
'name': product_attributes_by_id[attribute_id].name,
|
||||
'display_type': product_attributes_by_id[attribute_id].display_type,
|
||||
'values': values
|
||||
'name': attribute.name,
|
||||
'display_type': attribute.display_type,
|
||||
'values': values,
|
||||
}
|
||||
|
||||
return res
|
||||
|
||||
@@ -16,9 +16,10 @@ class ResPartner(models.Model):
|
||||
|
||||
def _compute_pos_order(self):
|
||||
# retrieve all children partners and prefetch 'parent_id' on them
|
||||
all_partners = self.with_context(active_test=False).search([('id', 'child_of', self.ids)])
|
||||
all_partners.read(['parent_id'])
|
||||
|
||||
all_partners = self.with_context(active_test=False).search_fetch(
|
||||
[('id', 'child_of', self.ids)],
|
||||
['parent_id'],
|
||||
)
|
||||
pos_order_data = self.env['pos.order']._read_group(
|
||||
domain=[('partner_id', 'in', all_partners.ids)],
|
||||
fields=['partner_id'], groupby=['partner_id']
|
||||
|
||||
@@ -9,7 +9,10 @@ class PortalRating(http.Controller):
|
||||
|
||||
@http.route(['/website/rating/comment'], type='json', auth="user", methods=['POST'], website=True)
|
||||
def publish_rating_comment(self, rating_id, publisher_comment):
|
||||
rating = request.env['rating.rating'].search([('id', '=', int(rating_id))])
|
||||
rating = request.env['rating.rating'].search_fetch(
|
||||
[('id', '=', int(rating_id))],
|
||||
['publisher_comment', 'publisher_id', 'publisher_datetime'],
|
||||
)
|
||||
if not rating:
|
||||
return {'error': _('Invalid rating')}
|
||||
rating.write({'publisher_comment': publisher_comment})
|
||||
|
||||
@@ -444,23 +444,21 @@ class ProductProduct(models.Model):
|
||||
|
||||
result = []
|
||||
|
||||
# Prefetch the fields used by the `name_get`, so `browse` doesn't fetch other fields
|
||||
# Use `load=False` to not call `name_get` for the `product_tmpl_id`
|
||||
self.sudo().read(['name', 'default_code', 'product_tmpl_id'], load=False)
|
||||
# prefetch the fields used by the `name_get`
|
||||
self.sudo().fetch(['name', 'default_code', 'product_tmpl_id'])
|
||||
|
||||
product_template_ids = self.sudo().mapped('product_tmpl_id').ids
|
||||
product_template_ids = self.sudo().product_tmpl_id.ids
|
||||
|
||||
if partner_ids:
|
||||
supplier_info = self.env['product.supplierinfo'].sudo().search([
|
||||
('product_tmpl_id', 'in', product_template_ids),
|
||||
('partner_id', 'in', partner_ids),
|
||||
])
|
||||
# Prefetch the fields used by the `name_get`, so `browse` doesn't fetch other fields
|
||||
# Use `load=False` to not call `name_get` for the `product_tmpl_id` and `product_id`
|
||||
supplier_info.sudo().read(['product_tmpl_id', 'product_id', 'product_name', 'product_code'], load=False)
|
||||
# prefetch the fields used by the `name_get`
|
||||
supplier_info = self.env['product.supplierinfo'].sudo().search_fetch(
|
||||
[('product_tmpl_id', 'in', product_template_ids), ('partner_id', 'in', partner_ids)],
|
||||
['product_tmpl_id', 'product_id', 'company_id', 'product_name', 'product_code'],
|
||||
)
|
||||
supplier_info_by_template = {}
|
||||
for r in supplier_info:
|
||||
supplier_info_by_template.setdefault(r.product_tmpl_id, []).append(r)
|
||||
|
||||
for product in self.sudo():
|
||||
variant = product.product_template_attribute_value_ids._get_combination_name()
|
||||
|
||||
@@ -496,6 +494,7 @@ class ProductProduct(models.Model):
|
||||
'default_code': product.default_code,
|
||||
}
|
||||
result.append(_name_get(mydict))
|
||||
|
||||
return result
|
||||
|
||||
@api.model
|
||||
|
||||
@@ -485,7 +485,7 @@ class ProductTemplate(models.Model):
|
||||
|
||||
def name_get(self):
|
||||
# Prefetch the fields used by the `name_get`, so `browse` doesn't fetch other fields
|
||||
self.browse(self.ids).read(['name', 'default_code'])
|
||||
self.fetch(['name', 'default_code'])
|
||||
return [(template.id, '%s%s' % (template.default_code and '[%s] ' % template.default_code or '', template.name))
|
||||
for template in self]
|
||||
|
||||
|
||||
@@ -16,9 +16,10 @@ class ResPartner(models.Model):
|
||||
|
||||
def _compute_task_count(self):
|
||||
# retrieve all children partners and prefetch 'parent_id' on them
|
||||
all_partners = self.with_context(active_test=False).search([('id', 'child_of', self.ids)])
|
||||
all_partners.read(['parent_id'])
|
||||
|
||||
all_partners = self.with_context(active_test=False).search_fetch(
|
||||
[('id', 'child_of', self.ids)],
|
||||
['parent_id'],
|
||||
)
|
||||
task_data = self.env['project.task']._read_group(
|
||||
domain=[('partner_id', 'in', all_partners.ids)],
|
||||
fields=['partner_id'], groupby=['partner_id']
|
||||
|
||||
@@ -11,9 +11,10 @@ class res_partner(models.Model):
|
||||
|
||||
def _compute_purchase_order_count(self):
|
||||
# retrieve all children partners and prefetch 'parent_id' on them
|
||||
all_partners = self.with_context(active_test=False).search([('id', 'child_of', self.ids)])
|
||||
all_partners.read(['parent_id'])
|
||||
|
||||
all_partners = self.with_context(active_test=False).search_fetch(
|
||||
[('id', 'child_of', self.ids)],
|
||||
['parent_id'],
|
||||
)
|
||||
purchase_order_groups = self.env['purchase.order']._read_group(
|
||||
domain=[('partner_id', 'in', all_partners.ids)],
|
||||
fields=['partner_id'], groupby=['partner_id']
|
||||
@@ -30,9 +31,10 @@ class res_partner(models.Model):
|
||||
|
||||
def _compute_supplier_invoice_count(self):
|
||||
# retrieve all children partners and prefetch 'parent_id' on them
|
||||
all_partners = self.with_context(active_test=False).search([('id', 'child_of', self.ids)])
|
||||
all_partners.read(['parent_id'])
|
||||
|
||||
all_partners = self.with_context(active_test=False).search_fetch(
|
||||
[('id', 'child_of', self.ids)],
|
||||
['parent_id'],
|
||||
)
|
||||
supplier_invoice_groups = self.env['account.move']._read_group(
|
||||
domain=[('partner_id', 'in', all_partners.ids),
|
||||
('move_type', 'in', ('in_invoice', 'in_refund'))],
|
||||
|
||||
@@ -19,9 +19,10 @@ class ResPartner(models.Model):
|
||||
|
||||
def _compute_sale_order_count(self):
|
||||
# retrieve all children partners and prefetch 'parent_id' on them
|
||||
all_partners = self.with_context(active_test=False).search([('id', 'child_of', self.ids)])
|
||||
all_partners.read(['parent_id'])
|
||||
|
||||
all_partners = self.with_context(active_test=False).search_fetch(
|
||||
[('id', 'child_of', self.ids)],
|
||||
['parent_id'],
|
||||
)
|
||||
sale_order_groups = self.env['sale.order']._read_group(
|
||||
domain=expression.AND([self._get_sale_order_domain_count(), [('partner_id', 'in', all_partners.ids)]]),
|
||||
fields=['partner_id'], groupby=['partner_id']
|
||||
|
||||
@@ -83,7 +83,7 @@ class SaleOrderLine(models.Model):
|
||||
('product_tmpl_id', 'in', self.env.registry.populated_models["product.template"])
|
||||
]).ids
|
||||
|
||||
self.env['product.product'].browse(product_ids).read(['uom_id']) # prefetch all uom_id
|
||||
self.env['product.product'].browse(product_ids).fetch(['uom_id']) # prefetch all uom_id
|
||||
|
||||
def get_product_uom(values, counter, random):
|
||||
return self.env['product.product'].browse(values['product_id']).uom_id.id
|
||||
|
||||
@@ -13,7 +13,7 @@ class ResCompany(models.Model):
|
||||
)
|
||||
existing_companies = companies.exists()
|
||||
# prefetch both fields
|
||||
existing_companies.read(["fiscalyear_last_day", "fiscalyear_last_month"])
|
||||
existing_companies.fetch(["fiscalyear_last_day", "fiscalyear_last_month"])
|
||||
results = []
|
||||
|
||||
for data, company in zip(payload, companies):
|
||||
|
||||
@@ -481,7 +481,7 @@ Please change the quantity done or the rounding precision of your unit of measur
|
||||
self.forecast_expected_date = False
|
||||
|
||||
# Prefetch product info to avoid fetching all product fields
|
||||
self.product_id.read(['type', 'uom_id'], load=False)
|
||||
self.product_id.fetch(['type', 'uom_id'])
|
||||
|
||||
not_product_moves = self.filtered(lambda move: move.product_id.type != 'product')
|
||||
for move in not_product_moves:
|
||||
@@ -2167,17 +2167,24 @@ Please change the quantity done or the rounding precision of your unit of measur
|
||||
product_ids = self.product_id
|
||||
wh_location_query = self.env['stock.location']._search([('id', 'child_of', warehouse.view_location_id.id)])
|
||||
|
||||
# Prefetch data to avoid future request
|
||||
in_domain, out_domain = self.env['stock.forecasted_product_product']._move_confirmed_domain(
|
||||
None, product_ids.ids, wh_location_query
|
||||
)
|
||||
outs = self.env['stock.move'].search(out_domain, order='reservation_date, priority desc, date, id')
|
||||
reserved_outs = self.env['stock.move'].search(
|
||||
outs = self.env['stock.move'].search_fetch(
|
||||
out_domain,
|
||||
['product_id', 'product_uom', 'product_qty', 'state'],
|
||||
order='reservation_date, priority desc, date, id',
|
||||
)
|
||||
reserved_outs = self.env['stock.move'].search_fetch(
|
||||
out_domain + [('state', 'in', ('partially_available', 'assigned'))],
|
||||
['product_id', 'product_uom'],
|
||||
order='priority desc, date, id')
|
||||
ins = self.env['stock.move'].search(in_domain, order='priority desc, date, id')
|
||||
# Prefetch data to avoid future request
|
||||
(outs - self).read(['product_id', 'product_uom', 'product_qty', 'state'], load=False) # remove self because data is already fetch
|
||||
ins.read(['product_id', 'product_qty', 'date', 'move_dest_ids'], load=False)
|
||||
ins = self.env['stock.move'].search_fetch(
|
||||
in_domain,
|
||||
['product_id', 'product_qty', 'date', 'move_dest_ids'],
|
||||
order='priority desc, date, id',
|
||||
)
|
||||
|
||||
currents = product_ids.with_context(warehouse=warehouse.id)._get_only_qty_available()
|
||||
|
||||
|
||||
@@ -180,5 +180,8 @@ class Http(models.AbstractModel):
|
||||
|
||||
def get_currencies(self):
|
||||
Currency = self.env['res.currency']
|
||||
currencies = Currency.search([]).read(['symbol', 'position', 'decimal_places'])
|
||||
return {c['id']: {'symbol': c['symbol'], 'position': c['position'], 'digits': [69,c['decimal_places']]} for c in currencies}
|
||||
currencies = Currency.search_fetch([], ['symbol', 'position', 'decimal_places'])
|
||||
return {
|
||||
c.id: {'symbol': c.symbol, 'position': c.position, 'digits': [69, c.decimal_places]}
|
||||
for c in currencies
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user