-- Otomatik Ata: stoktan çıkan satırın lot dağılımını kaynak konumun stoğundan ürün kategorisinin çıkış stratejisiyle yeniden kurar -- (FIFO: ilk giren ilk çıkar, LIFO: son giren ilk çıkar — InDate, aynı anda girenlerde lot/seri no; kategorisiz ürün FIFO). Planlama'nın Öner'i aynı kuralı izler. -- Stok yetmezse karşılanabilen kadar atanır; eksik Tamamla'da bildirilir. CREATE OR REPLACE PROCEDURE public."Stk_P_TransferLineLotAssign"(p_id uuid, p_user_id uuid DEFAULT NULL) LANGUAGE plpgsql AS $$ DECLARE v_tenant uuid; v_method varchar(16); v_src uuid; v_src_internal boolean; v_product uuid; v_line_uom varchar(64); v_product_uom varchar(64); v_need numeric(18, 4); v_strategy varchar(16); BEGIN SELECT l."TenantId", CASE WHEN p."TrackInventory" THEN p."TrackingMethod" END, t."SourceLocationId", COALESCE(src."LocationType" = 'Internal', false), l."ProductId", l."UomId", p."UomId", COALESCE(pc."RemovalStrategy", 'FIFO'), public."Stk_F_UomConvert"(CASE WHEN l."Quantity" > 0 THEN l."Quantity" ELSE l."DemandQuantity" END, l."UomId", p."UomId") INTO v_tenant, v_method, v_src, v_src_internal, v_product, v_line_uom, v_product_uom, v_strategy, v_need FROM "Stk_T_TransferLine" l INNER JOIN "Stk_T_Transfer" t ON t."Id" = l."TransferId" INNER JOIN "Stk_T_Product" p ON p."Id" = l."ProductId" LEFT JOIN "Stk_T_ProductCategory" pc ON pc."Id" = p."CategoryId" LEFT JOIN "Stk_T_Location" src ON src."Id" = t."SourceLocationId" WHERE l."Id" = p_id; IF COALESCE(v_method, '') NOT IN ('Lot', 'Serial') THEN RAISE EXCEPTION 'Ürün lot/seri numarasıyla takip edilmiyor.' USING ERRCODE = 'P0001', DETAIL = '50314'; END IF; IF NOT COALESCE(v_src_internal, false) THEN RAISE EXCEPTION 'Otomatik atama yalnız stoktan çıkan satırda yapılır.' USING ERRCODE = 'P0001', DETAIL = '50317'; END IF; UPDATE "Stk_T_TransferLineLot" SET "IsDeleted" = true, "DeletionTime" = NOW() AT TIME ZONE 'UTC', "DeleterId" = p_user_id WHERE "TransferLineId" = p_id AND "IsDeleted" = false; INSERT INTO "Stk_T_TransferLineLot" ("Id", "TenantId", "TransferLineId", "LotNo", "Quantity", "CreationTime", "CreatorId", "IsDeleted") SELECT gen_random_uuid(), v_tenant, p_id, s."LotNo", public."Stk_F_UomConvert"(LEAST(s."Quantity", v_need - s."Before"), v_product_uom, v_line_uom), NOW() AT TIME ZONE 'UTC', p_user_id, false FROM (SELECT "LotNo", "Quantity", SUM("Quantity") OVER (ORDER BY CASE WHEN v_strategy = 'LIFO' THEN NULL ELSE COALESCE("InDate", '9999-12-31') END NULLS FIRST, CASE WHEN v_strategy = 'LIFO' THEN COALESCE("InDate", '1900-01-01') END DESC NULLS LAST, CASE WHEN v_strategy = 'LIFO' THEN NULL ELSE "LotNo" END, CASE WHEN v_strategy = 'LIFO' THEN "LotNo" END DESC NULLS LAST ROWS UNBOUNDED PRECEDING) - "Quantity" AS "Before" FROM "Stk_T_Stock" WHERE "LocationId" = v_src AND "ProductId" = v_product AND "LotNo" <> '' AND "Quantity" > 0 AND "TenantId" IS NOT DISTINCT FROM v_tenant) s WHERE s."Before" < v_need; END; $$;