[REF] stock*,purchase,mrp: used groupby of odoo
Instead of using sort + groupby of itertools (which group only consecutive), use only the groupby of odoo.tools which decrease the complexity of the code and avoid unmatched keys between sort keys and groupby keys task-2648449 Part-of: odoo/odoo#76761
This commit is contained in:
@@ -1668,12 +1668,6 @@ class MrpProduction(models.Model):
|
||||
|
||||
def _log_downside_manufactured_quantity(self, moves_modification, cancel=False):
|
||||
|
||||
def _keys_in_sorted(move):
|
||||
""" sort by picking and the responsible for the product the
|
||||
move.
|
||||
"""
|
||||
return (move.picking_id.id, move.product_id.responsible_id.id)
|
||||
|
||||
def _keys_in_groupby(move):
|
||||
""" group by picking and the responsible for the product the
|
||||
move.
|
||||
@@ -1689,7 +1683,7 @@ class MrpProduction(models.Model):
|
||||
}
|
||||
return self.env.ref('mrp.exception_on_mo')._render(values=values)
|
||||
|
||||
documents = self.env['stock.picking']._log_activity_get_documents(moves_modification, 'move_dest_ids', 'DOWN', _keys_in_sorted, _keys_in_groupby)
|
||||
documents = self.env['stock.picking']._log_activity_get_documents(moves_modification, 'move_dest_ids', 'DOWN', _keys_in_groupby)
|
||||
documents = self.env['stock.picking']._less_quantities_than_expected_add_documents(moves_modification, documents)
|
||||
self.env['stock.picking']._log_activity(_render_note_exception_quantity_mo, documents)
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from datetime import timedelta
|
||||
from itertools import groupby
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.tools import groupby
|
||||
from odoo.tools.float_utils import float_round, float_is_zero
|
||||
|
||||
|
||||
@@ -257,7 +257,7 @@ class ProductProduct(models.Model):
|
||||
self.ensure_one()
|
||||
if not product_template_attribute_value_ids:
|
||||
return True
|
||||
for _, iter_ptav in groupby(product_template_attribute_value_ids.sorted('attribute_line_id'), lambda ptav: ptav.attribute_line_id):
|
||||
for _, iter_ptav in groupby(product_template_attribute_value_ids, lambda ptav: ptav.attribute_line_id):
|
||||
if not any(ptav in self.product_template_attribute_value_ids for ptav in iter_ptav):
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -399,12 +399,6 @@ class StockMove(models.Model):
|
||||
res['cost_share'] = sum(self.mapped('cost_share'))
|
||||
return res
|
||||
|
||||
@api.model
|
||||
def _prepare_merge_move_sort_method(self, move):
|
||||
keys_sorted = super()._prepare_merge_move_sort_method(move)
|
||||
keys_sorted += [move.created_production_id.id, move.cost_share]
|
||||
return keys_sorted
|
||||
|
||||
def _compute_kit_quantities(self, product_id, kit_qty, kit_bom, filters):
|
||||
""" Computes the quantity delivered or received when a kit is sold or purchased.
|
||||
A ratio 'qty_processed/qty_needed' is computed for each component, and the lowest one is kept
|
||||
|
||||
@@ -63,17 +63,11 @@ class StockPicking(models.Model):
|
||||
def _less_quantities_than_expected_add_documents(self, moves, documents):
|
||||
documents = super(StockPicking, self)._less_quantities_than_expected_add_documents(moves, documents)
|
||||
|
||||
def _keys_in_sorted(move):
|
||||
""" sort by picking and the responsible for the product the
|
||||
move.
|
||||
"""
|
||||
return (move.raw_material_production_id.id, move.product_id.responsible_id.id)
|
||||
|
||||
def _keys_in_groupby(move):
|
||||
""" group by picking and the responsible for the product the
|
||||
move.
|
||||
"""
|
||||
return (move.raw_material_production_id, move.product_id.responsible_id)
|
||||
|
||||
production_documents = self._log_activity_get_documents(moves, 'move_dest_ids', 'DOWN', _keys_in_sorted, _keys_in_groupby)
|
||||
production_documents = self._log_activity_get_documents(moves, 'move_dest_ids', 'DOWN', _keys_in_groupby)
|
||||
return {**documents, **production_documents}
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from datetime import datetime, time
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from functools import partial
|
||||
from itertools import groupby
|
||||
import json
|
||||
|
||||
from markupsafe import escape, Markup
|
||||
@@ -12,10 +10,9 @@ from werkzeug.urls import url_encode
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.osv import expression
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, formatLang, get_lang, groupby
|
||||
from odoo.tools.float_utils import float_compare, float_is_zero, float_round
|
||||
from odoo.exceptions import AccessError, UserError, ValidationError
|
||||
from odoo.tools.misc import formatLang, get_lang
|
||||
|
||||
|
||||
class PurchaseOrder(models.Model):
|
||||
|
||||
@@ -151,12 +151,6 @@ class PurchaseOrder(models.Model):
|
||||
|
||||
def _log_decrease_ordered_quantity(self, purchase_order_lines_quantities):
|
||||
|
||||
def _keys_in_sorted(move):
|
||||
""" sort by picking and the responsible for the product the
|
||||
move.
|
||||
"""
|
||||
return (move.picking_id.id, move.product_id.responsible_id.id)
|
||||
|
||||
def _keys_in_groupby(move):
|
||||
""" group by picking and the responsible for the product the
|
||||
move.
|
||||
@@ -175,7 +169,7 @@ class PurchaseOrder(models.Model):
|
||||
}
|
||||
return self.env.ref('purchase_stock.exception_on_po')._render(values=values)
|
||||
|
||||
documents = self.env['stock.picking']._log_activity_get_documents(purchase_order_lines_quantities, 'move_ids', 'DOWN', _keys_in_sorted, _keys_in_groupby)
|
||||
documents = self.env['stock.picking']._log_activity_get_documents(purchase_order_lines_quantities, 'move_ids', 'DOWN', _keys_in_groupby)
|
||||
filtered_documents = {}
|
||||
for (parent, responsible), rendering_context in documents.items():
|
||||
if parent._name == 'stock.picking':
|
||||
|
||||
@@ -26,13 +26,6 @@ class StockMove(models.Model):
|
||||
distinct_fields += ['purchase_line_id', 'created_purchase_line_id']
|
||||
return distinct_fields
|
||||
|
||||
@api.model
|
||||
def _prepare_merge_move_sort_method(self, move):
|
||||
move.ensure_one()
|
||||
keys_sorted = super(StockMove, self)._prepare_merge_move_sort_method(move)
|
||||
keys_sorted += [move.purchase_line_id.id, move.created_purchase_line_id.id]
|
||||
return keys_sorted
|
||||
|
||||
def _get_price_unit(self):
|
||||
""" Returns the unit price for the move"""
|
||||
self.ensure_one()
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
from collections import defaultdict
|
||||
from datetime import datetime
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from itertools import groupby
|
||||
|
||||
from odoo import api, fields, models, SUPERUSER_ID, _
|
||||
from odoo.addons.stock.models.stock_rule import ProcurementException
|
||||
from odoo.tools import groupby
|
||||
|
||||
|
||||
class StockRule(models.Model):
|
||||
@@ -115,9 +115,9 @@ class StockRule(models.Model):
|
||||
procurements = self._merge_procurements(procurements_to_merge)
|
||||
|
||||
po_lines_by_product = {}
|
||||
grouped_po_lines = groupby(po.order_line.filtered(lambda l: not l.display_type and l.product_uom == l.product_id.uom_po_id).sorted(lambda l: l.product_id.id), key=lambda l: l.product_id.id)
|
||||
grouped_po_lines = groupby(po.order_line.filtered(lambda l: not l.display_type and l.product_uom == l.product_id.uom_po_id), key=lambda l: l.product_id.id)
|
||||
for product, po_lines in grouped_po_lines:
|
||||
po_lines_by_product[product] = self.env['purchase.order.line'].concat(*list(po_lines))
|
||||
po_lines_by_product[product] = self.env['purchase.order.line'].concat(*po_lines)
|
||||
po_line_values = []
|
||||
for procurement in procurements:
|
||||
po_lines = po_lines_by_product.get(procurement.product_id.id, self.env['purchase.order.line'])
|
||||
@@ -176,12 +176,6 @@ class StockRule(models.Model):
|
||||
procurement.values.get('product_description_variants'),\
|
||||
(procurement.values.get('orderpoint_id') and not procurement.values.get('move_dest_ids')) and procurement.values['orderpoint_id']
|
||||
|
||||
@api.model
|
||||
def _get_procurements_to_merge_sorted(self, procurement):
|
||||
return procurement.product_id.id, procurement.product_uom.id, procurement.values['propagate_cancel'],\
|
||||
procurement.values.get('product_description_variants'),\
|
||||
(procurement.values.get('orderpoint_id') and not procurement.values.get('move_dest_ids')) and procurement.values['orderpoint_id']
|
||||
|
||||
@api.model
|
||||
def _get_procurements_to_merge(self, procurements):
|
||||
""" Get a list of procurements values and create groups of procurements
|
||||
@@ -190,11 +184,7 @@ class StockRule(models.Model):
|
||||
sorted).
|
||||
return list: procurements requests grouped by their product_id.
|
||||
"""
|
||||
procurements_to_merge = []
|
||||
|
||||
for k, procurements in groupby(sorted(procurements, key=self._get_procurements_to_merge_sorted), key=self._get_procurements_to_merge_groupby):
|
||||
procurements_to_merge.append(list(procurements))
|
||||
return procurements_to_merge
|
||||
return [pro_g for __, pro_g in groupby(procurements, key=self._get_procurements_to_merge_groupby)]
|
||||
|
||||
@api.model
|
||||
def _merge_procurements(self, procurements_to_merge):
|
||||
|
||||
@@ -21,13 +21,6 @@ class StockMove(models.Model):
|
||||
distinct_fields.append('sale_line_id')
|
||||
return distinct_fields
|
||||
|
||||
@api.model
|
||||
def _prepare_merge_move_sort_method(self, move):
|
||||
move.ensure_one()
|
||||
keys_sorted = super(StockMove, self)._prepare_merge_move_sort_method(move)
|
||||
keys_sorted.append(move.sale_line_id.id)
|
||||
return keys_sorted
|
||||
|
||||
def _get_related_invoices(self):
|
||||
""" Overridden from stock_account to return the customer invoices
|
||||
related to this stock move.
|
||||
@@ -116,10 +109,6 @@ class StockPicking(models.Model):
|
||||
new and old quantity as value. eg: {move_1 : (4, 5)}
|
||||
"""
|
||||
|
||||
def _keys_in_sorted(sale_line):
|
||||
""" sort by order_id and the sale_person on the order """
|
||||
return (sale_line.order_id.id, sale_line.order_id.user_id.id)
|
||||
|
||||
def _keys_in_groupby(sale_line):
|
||||
""" group by order_id and the sale_person on the order """
|
||||
return (sale_line.order_id, sale_line.order_id.user_id)
|
||||
@@ -144,7 +133,7 @@ class StockPicking(models.Model):
|
||||
}
|
||||
return self.env.ref('sale_stock.exception_on_picking')._render(values=values)
|
||||
|
||||
documents = self._log_activity_get_documents(moves, 'sale_line_id', 'DOWN', _keys_in_sorted, _keys_in_groupby)
|
||||
documents = self._log_activity_get_documents(moves, 'sale_line_id', 'DOWN', _keys_in_groupby)
|
||||
self._log_activity(_render_note_exception_quantity, documents)
|
||||
|
||||
return super(StockPicking, self)._log_less_quantities_than_expected(moves)
|
||||
|
||||
@@ -4,14 +4,13 @@
|
||||
|
||||
from collections import defaultdict
|
||||
from datetime import timedelta
|
||||
from itertools import groupby
|
||||
from operator import itemgetter
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.osv import expression
|
||||
from odoo.tools.float_utils import float_compare, float_is_zero, float_round
|
||||
from odoo.tools.misc import clean_context, OrderedSet
|
||||
from odoo.tools.misc import clean_context, OrderedSet, groupby
|
||||
|
||||
PROCUREMENT_PRIORITIES = [('0', 'Normal'), ('1', 'Urgent')]
|
||||
|
||||
@@ -805,15 +804,6 @@ class StockMove(models.Model):
|
||||
'product_packaging_id',
|
||||
]
|
||||
|
||||
@api.model
|
||||
def _prepare_merge_move_sort_method(self, move):
|
||||
move.ensure_one()
|
||||
return [
|
||||
move.product_id.id, move.price_unit, move.procure_method, move.location_id, move.location_dest_id,
|
||||
move.product_uom.id, move.restrict_partner_id.id, move.scrapped, move.origin_returned_move_id.id,
|
||||
move.package_level_id.id, move.propagate_cancel, move.description_picking or ""
|
||||
]
|
||||
|
||||
def _clean_merged(self):
|
||||
"""Cleanup hook used when merging moves"""
|
||||
self.write({'propagate_cancel': False})
|
||||
@@ -842,7 +832,7 @@ class StockMove(models.Model):
|
||||
for candidate_moves in candidate_moves_list:
|
||||
# First step find move to merge.
|
||||
candidate_moves = candidate_moves.with_context(prefetch_fields=False)
|
||||
for k, g in groupby(sorted(candidate_moves, key=self._prepare_merge_move_sort_method), key=itemgetter(*distinct_fields)):
|
||||
for __, g in groupby(candidate_moves, key=itemgetter(*distinct_fields)):
|
||||
moves = self.env['stock.move'].concat(*g).filtered(lambda m: m.state not in ('done', 'cancel', 'draft'))
|
||||
# If we have multiple records we will merge then in a single one.
|
||||
if len(moves) > 1:
|
||||
@@ -994,7 +984,7 @@ class StockMove(models.Model):
|
||||
|
||||
def _key_assign_picking(self):
|
||||
self.ensure_one()
|
||||
return self.group_id, self.location_id, self.location_dest_id, self.picking_type_id
|
||||
return (self.group_id, self.location_id, self.location_dest_id, self.picking_type_id)
|
||||
|
||||
def _search_picking_for_assignation_domain(self):
|
||||
return [('group_id', '=', self.group_id.id),
|
||||
@@ -1017,9 +1007,9 @@ class StockMove(models.Model):
|
||||
type (moves should already have them identical). Otherwise, create a new
|
||||
picking to assign them to. """
|
||||
Picking = self.env['stock.picking']
|
||||
grouped_moves = groupby(sorted(self, key=lambda m: [f.id for f in m._key_assign_picking()]), key=lambda m: [m._key_assign_picking()])
|
||||
grouped_moves = groupby(self, key=lambda m: m._key_assign_picking())
|
||||
for group, moves in grouped_moves:
|
||||
moves = self.env['stock.move'].concat(*list(moves))
|
||||
moves = self.env['stock.move'].concat(*moves)
|
||||
new_picking = False
|
||||
# Could pass the arguments contained in group but they are the same
|
||||
# for each move that why moves[0] is acceptable
|
||||
@@ -1345,13 +1335,12 @@ class StockMove(models.Model):
|
||||
|
||||
def _get_available_move_lines(move):
|
||||
move_lines_in = move.move_orig_ids.filtered(lambda m: m.state == 'done').mapped('move_line_ids')
|
||||
keys_in_groupby = ['location_dest_id', 'lot_id', 'result_package_id', 'owner_id']
|
||||
|
||||
def _keys_in_sorted(ml):
|
||||
return (ml.location_dest_id.id, ml.lot_id.id, ml.result_package_id.id, ml.owner_id.id)
|
||||
def _keys_in_groupby(ml):
|
||||
return (ml.location_dest_id, ml.lot_id, ml.result_package_id, ml.owner_id)
|
||||
|
||||
grouped_move_lines_in = {}
|
||||
for k, g in groupby(sorted(move_lines_in, key=_keys_in_sorted), key=itemgetter(*keys_in_groupby)):
|
||||
for k, g in groupby(move_lines_in, key=_keys_in_groupby):
|
||||
qty_done = 0
|
||||
for ml in g:
|
||||
qty_done += ml.product_uom_id._compute_quantity(ml.qty_done, ml.product_id.uom_id)
|
||||
@@ -1365,19 +1354,18 @@ class StockMove(models.Model):
|
||||
moves_out_siblings_to_consider = moves_out_siblings & (StockMove.browse(assigned_moves_ids) + StockMove.browse(partially_available_moves_ids))
|
||||
reserved_moves_out_siblings = moves_out_siblings.filtered(lambda m: m.state in ['partially_available', 'assigned'])
|
||||
move_lines_out_reserved = (reserved_moves_out_siblings | moves_out_siblings_to_consider).mapped('move_line_ids')
|
||||
keys_out_groupby = ['location_id', 'lot_id', 'package_id', 'owner_id']
|
||||
|
||||
def _keys_out_sorted(ml):
|
||||
def _keys_out_groupby(ml):
|
||||
return (ml.location_id.id, ml.lot_id.id, ml.package_id.id, ml.owner_id.id)
|
||||
|
||||
grouped_move_lines_out = {}
|
||||
for k, g in groupby(sorted(move_lines_out_done, key=_keys_out_sorted), key=itemgetter(*keys_out_groupby)):
|
||||
for k, g in groupby(move_lines_out_done, key=_keys_out_groupby):
|
||||
qty_done = 0
|
||||
for ml in g:
|
||||
qty_done += ml.product_uom_id._compute_quantity(ml.qty_done, ml.product_id.uom_id)
|
||||
grouped_move_lines_out[k] = qty_done
|
||||
for k, g in groupby(sorted(move_lines_out_reserved, key=_keys_out_sorted), key=itemgetter(*keys_out_groupby)):
|
||||
grouped_move_lines_out[k] = sum(self.env['stock.move.line'].concat(*list(g)).mapped('product_qty'))
|
||||
for k, g in groupby(move_lines_out_reserved, key=_keys_out_groupby):
|
||||
grouped_move_lines_out[k] = sum(self.env['stock.move.line'].concat(*g).mapped('product_qty'))
|
||||
available_move_lines = {key: grouped_move_lines_in[key] - grouped_move_lines_out.get(key, 0) for key in grouped_move_lines_in}
|
||||
# pop key if the quantity available amount to 0
|
||||
return dict((k, v) for k, v in available_move_lines.items() if v)
|
||||
|
||||
@@ -5,7 +5,6 @@ import logging
|
||||
from collections import defaultdict
|
||||
from datetime import datetime, time
|
||||
from dateutil import relativedelta
|
||||
from itertools import groupby
|
||||
from psycopg2 import OperationalError
|
||||
|
||||
from odoo import SUPERUSER_ID, _, api, fields, models, registry
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from itertools import groupby
|
||||
from operator import itemgetter
|
||||
from collections import defaultdict
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.tools.misc import groupby
|
||||
|
||||
|
||||
class StockPackageLevel(models.Model):
|
||||
@@ -165,19 +165,15 @@ class StockPackageLevel(models.Model):
|
||||
""" should compare in good uom """
|
||||
all_in = True
|
||||
pack_move_lines = self.move_line_ids
|
||||
keys = ['product_id', 'lot_id']
|
||||
|
||||
def sorted_key(object):
|
||||
object.ensure_one()
|
||||
return [object.product_id.id, object.lot_id.id]
|
||||
groupby_keys = ('product_id', 'lot_id')
|
||||
|
||||
grouped_quants = {}
|
||||
for k, g in groupby(sorted(package.quant_ids, key=sorted_key), key=itemgetter(*keys)):
|
||||
grouped_quants[k] = sum(self.env['stock.quant'].concat(*list(g)).mapped('quantity'))
|
||||
for k, g in groupby(package.quant_ids, key=itemgetter(*groupby_keys)):
|
||||
grouped_quants[k] = sum(self.env['stock.quant'].concat(*g).mapped('quantity'))
|
||||
|
||||
grouped_ops = {}
|
||||
for k, g in groupby(sorted(pack_move_lines, key=sorted_key), key=itemgetter(*keys)):
|
||||
grouped_ops[k] = sum(self.env['stock.move.line'].concat(*list(g)).mapped(field))
|
||||
for k, g in groupby(pack_move_lines, key=itemgetter(*groupby_keys)):
|
||||
grouped_ops[k] = sum(self.env['stock.move.line'].concat(*g).mapped(field))
|
||||
if any(grouped_quants.get(key, 0) - grouped_ops.get(key, 0) != 0 for key in grouped_quants) \
|
||||
or any(grouped_ops.get(key, 0) - grouped_quants.get(key, 0) != 0 for key in grouped_ops):
|
||||
all_in = False
|
||||
|
||||
@@ -5,7 +5,6 @@ import json
|
||||
import time
|
||||
from ast import literal_eval
|
||||
from datetime import date, timedelta
|
||||
from itertools import groupby
|
||||
from operator import attrgetter, itemgetter
|
||||
from collections import defaultdict
|
||||
|
||||
@@ -13,9 +12,8 @@ from odoo import SUPERUSER_ID, _, api, fields, models
|
||||
from odoo.addons.stock.models.stock_move import PROCUREMENT_PRIORITIES
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.osv import expression
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, format_datetime
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, format_datetime, format_date, groupby
|
||||
from odoo.tools.float_utils import float_compare, float_is_zero, float_round
|
||||
from odoo.tools.misc import format_date
|
||||
|
||||
|
||||
class PickingType(models.Model):
|
||||
@@ -835,17 +833,16 @@ class Picking(models.Model):
|
||||
""" This method checks that all product of the package (quant) are well present in the move_line_ids of the picking. """
|
||||
all_in = True
|
||||
pack_move_lines = self.move_line_ids.filtered(lambda ml: ml.package_id == package)
|
||||
keys = ['product_id', 'lot_id']
|
||||
keys_ids = ["{}.id".format(fname) for fname in keys]
|
||||
precision_digits = self.env['decimal.precision'].precision_get('Product Unit of Measure')
|
||||
groupby_keys = ('product_id', 'lot_id')
|
||||
|
||||
grouped_quants = {}
|
||||
for k, g in groupby(sorted(package.quant_ids, key=attrgetter(*keys_ids)), key=itemgetter(*keys)):
|
||||
grouped_quants[k] = sum(self.env['stock.quant'].concat(*list(g)).mapped('quantity'))
|
||||
for k, g in groupby(package.quant_ids, key=itemgetter(*groupby_keys)):
|
||||
grouped_quants[k] = sum(self.env['stock.quant'].concat(*g).mapped('quantity'))
|
||||
|
||||
grouped_ops = {}
|
||||
for k, g in groupby(sorted(pack_move_lines, key=attrgetter(*keys_ids)), key=itemgetter(*keys)):
|
||||
grouped_ops[k] = sum(self.env['stock.move.line'].concat(*list(g)).mapped('product_qty'))
|
||||
for k, g in groupby(pack_move_lines, key=itemgetter(*groupby_keys)):
|
||||
grouped_ops[k] = sum(self.env['stock.move.line'].concat(*g).mapped('product_qty'))
|
||||
if any(not float_is_zero(grouped_quants.get(key, 0) - grouped_ops.get(key, 0), precision_digits=precision_digits) for key in grouped_quants) \
|
||||
or any(not float_is_zero(grouped_ops.get(key, 0) - grouped_quants.get(key, 0), precision_digits=precision_digits) for key in grouped_ops):
|
||||
all_in = False
|
||||
@@ -1127,7 +1124,7 @@ class Picking(models.Model):
|
||||
backorders |= backorder_picking
|
||||
return backorders
|
||||
|
||||
def _log_activity_get_documents(self, orig_obj_changes, stream_field, stream, sorted_method=False, groupby_method=False):
|
||||
def _log_activity_get_documents(self, orig_obj_changes, stream_field, stream, groupby_method=False):
|
||||
""" Generic method to log activity. To use with
|
||||
_log_activity method. It either log on uppermost
|
||||
ongoing documents or following documents. This method
|
||||
@@ -1147,8 +1144,8 @@ class Picking(models.Model):
|
||||
- 'UP' if we want to log on the upper most ongoing
|
||||
documents.
|
||||
- 'DOWN' if we want to log on following documents.
|
||||
:param sorted_method method, groupby_method: Only need when
|
||||
stream is 'DOWN', it should sort/group by tuple(object on
|
||||
:param groupby_method: Only need when
|
||||
stream is 'DOWN', it should group by tuple(object on
|
||||
which the activity is log, the responsible for this object)
|
||||
"""
|
||||
if self.env.context.get('skip_activity'):
|
||||
@@ -1162,10 +1159,10 @@ class Picking(models.Model):
|
||||
# '(delivery_picking_2, admin)': stock.move(3)}
|
||||
visited_documents = {}
|
||||
if stream == 'DOWN':
|
||||
if sorted_method and groupby_method:
|
||||
grouped_moves = groupby(sorted(origin_objects.mapped(stream_field), key=sorted_method), key=groupby_method)
|
||||
if groupby_method:
|
||||
grouped_moves = groupby(origin_objects.mapped(stream_field), key=groupby_method)
|
||||
else:
|
||||
raise UserError(_('You have to define a groupby and sorted method and pass them as arguments.'))
|
||||
raise AssertionError('You have to define a groupby method and pass them as arguments.')
|
||||
elif stream == 'UP':
|
||||
# When using upstream document it is required to define
|
||||
# _get_upstream_documents_and_responsibles on
|
||||
@@ -1181,13 +1178,12 @@ class Picking(models.Model):
|
||||
visited_documents[(document, responsible)] = visited
|
||||
grouped_moves = grouped_moves.items()
|
||||
else:
|
||||
raise UserError(_('Unknown stream.'))
|
||||
raise AssertionError('Unknown stream.')
|
||||
|
||||
documents = {}
|
||||
for (parent, responsible), moves in grouped_moves:
|
||||
if not parent:
|
||||
continue
|
||||
moves = list(moves)
|
||||
moves = self.env[moves[0]._name].concat(*moves)
|
||||
# Get the note
|
||||
rendering_context = {move: (orig_object, orig_obj_changes[orig_object]) for move in moves for orig_object in move_to_orig_object_rel[move]}
|
||||
@@ -1233,12 +1229,6 @@ class Picking(models.Model):
|
||||
:param dict moves: a dict with a move as key and tuple with
|
||||
new and old quantity as value. eg: {move_1 : (4, 5)}
|
||||
"""
|
||||
def _keys_in_sorted(move):
|
||||
""" sort by picking and the responsible for the product the
|
||||
move.
|
||||
"""
|
||||
return (move.picking_id.id, move.product_id.responsible_id.id)
|
||||
|
||||
def _keys_in_groupby(move):
|
||||
""" group by picking and the responsible for the product the
|
||||
move.
|
||||
@@ -1260,7 +1250,7 @@ class Picking(models.Model):
|
||||
}
|
||||
return self.env.ref('stock.exception_on_picking')._render(values=values)
|
||||
|
||||
documents = self._log_activity_get_documents(moves, 'move_dest_ids', 'DOWN', _keys_in_sorted, _keys_in_groupby)
|
||||
documents = self._log_activity_get_documents(moves, 'move_dest_ids', 'DOWN', _keys_in_groupby)
|
||||
documents = self._less_quantities_than_expected_add_documents(moves, documents)
|
||||
self._log_activity(_render_note_exception_quantity, documents)
|
||||
|
||||
|
||||
@@ -14,10 +14,6 @@ class StockRule(models.Model):
|
||||
"""
|
||||
return procurement.values.get('sale_line_id'), super(StockRule, self)._get_procurements_to_merge_groupby(procurement)
|
||||
|
||||
@api.model
|
||||
def _get_procurements_to_merge_sorted(self, procurement):
|
||||
return procurement.values.get('sale_line_id'), super(StockRule, self)._get_procurements_to_merge_sorted(procurement)
|
||||
|
||||
|
||||
class ProcurementGroup(models.Model):
|
||||
_inherit = "procurement.group"
|
||||
|
||||
Reference in New Issue
Block a user