final_stock(opening, movements) where movements are (type, qty) tuples with types 'purchase', 'sale', 'return' (customer return: stock comes back), 'damage'. Track the balance; a sale that would drive stock negative is skipped and its index recorded. Return (final_qty, skipped_indexes).final_stock(10, [('sale', 4), ('sale', 8), ('purchase', 5), ('sale', 8)])(3, [1])
The 8-unit sale at index 1 exceeded stock and was skipped.
A dict of type → sign keeps the arithmetic clean.
Check before applying sales/damage.