Skip to content

Instantly share code, notes, and snippets.

@gurneyalex
Created October 18, 2021 09:55
Show Gist options
  • Save gurneyalex/78b6b7d920c056a4cafe5524f76c26fa to your computer and use it in GitHub Desktop.
Save gurneyalex/78b6b7d920c056a4cafe5524f76c26fa to your computer and use it in GitHub Desktop.
odoo issue #62139 - scheduled action to fix the quants in stock
log('Start fixing stock level')
query = """
WITH product AS
(
select distinct product_id from stock_move where state='done' and create_date > '2020-11-14 00:00:00'
),
location AS (SELECT id AS location_id, usage FROM stock_location),
error_move_lines AS (SELECT * FROM (
SELECT sml.id,
ROW_NUMBER() OVER (PARTITION BY move_id) as row,
sml.qty_done
FROM stock_move_line sml
JOIN stock_move sm
ON sm.id = sml.move_id
WHERE sm.inventory_id IS NOT NULL
AND sm.state = 'done'
AND sm.product_uom_qty < (
SELECT SUM(qty_done)
FROM stock_move_line sml2
WHERE sml2.move_id = sm.id
GROUP BY sml2.move_id
)
) duplicates
WHERE duplicates.row > 1)
SELECT product_id, location_dest_id AS location_id, usage, package_id, result_package_id as result_package_id, SUM(qty_done) AS qty
FROM stock_move_line sml natural join product join location on (location_dest_id = location.location_id)
WHERE state = 'done' and sml.id not in (select id from error_move_lines)
GROUP BY product_id, location_dest_id, usage, package_id, result_package_id
UNION ALL
SELECT product_id, sml.location_id, usage, package_id, result_package_id, -SUM(qty_done) AS qty
FROM stock_move_line sml natural join product join location on (sml.location_id = location.location_id)
WHERE state = 'done' and sml.id not in (select id from error_move_lines)
GROUP BY product_id, sml.location_id, usage, package_id, result_package_id
"""
env.cr.execute(query)
quantities = {}
while True:
fetched = env.cr.fetchmany(500)
if not fetched:
break
for product_id, location_id, usage, package_id, result_package_id, qty in fetched:
if qty < 0: # when we remove, we may put in a pack
key = product_id, location_id, usage, package_id
else:
key = product_id, location_id, usage, result_package_id
if key not in quantities:
quantities[key] = 0.
quantities[key] += qty
for (product_id, location_id, usage, package_id), qty in quantities.items():
if usage != 'internal':
continue
product = env['product.product'].sudo().browse(product_id)
package = env['stock.quant.package'].sudo().browse(package_id)
location = env['stock.location'].sudo().browse(location_id)
quants = env['stock.quant'].sudo()._gather(product, location, package_id=package, strict=True)
actual_qty = sum(quants.mapped('quantity'))
delta = qty - actual_qty
if delta > 0:
env['stock.quant'].sudo()._update_available_quantity(product, location, delta, package_id=package)
log("Product %s in location %s (package: %s): updated qty from %.1f to %.1f" % (product.display_name, location.display_name, package.name, actual_qty, qty))
log('End fixing stock level')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment