The biggest performance problem is the usage of cursors. You should modify the procedure so that you update the tables with a single statement without looping through the cursor results.
I'm not sure about the logic since based on the code it's somewhat unclear what the conditions should be but in overall the idea should be that you run an update statement which uses the values from the parameters of the procedure, not from the cursor.
ADDITION:
From what I've gathered the procedure should return the cost for a product based on stock incomes which are used as FIFO.
This could be far off but using the example data would the query in the end return correct results in case different #stockout rows are added
CREATE TABLE #StockIn (
OrderNo int,
Quantity int,
Cost int
);
INSERT INTO #StockIn VALUES (1, 10, 11);
INSERT INTO #StockIn VALUES (2, 10, 12);
INSERT INTO #StockIn VALUES (3, 10, 13);
CREATE TABLE #StockOut (
OrderNo int,
Quantity int,
Cost int
);
INSERT INTO #StockOut VALUES (1, 1, 5);
INSERT INTO #StockOut VALUES (2, 2, 5);
INSERT INTO #StockOut VALUES (3, 12, 5);
INSERT INTO #StockOut VALUES (4, 3, 5);
SELECT TOP 1 *
FROM #StockIn si
WHERE (COALESCE((SELECT SUM(si2.Quantity)
FROM #StockIn si2
WHERE si2.OrderNo < si.OrderNo), 0)
+ si.Quantity) >= (SELECT SUM(so.Quantity)
FROM #StockOut so)
ORDER BY OrderNo;