2026-10-14 09:07:11 +00:00
-- Planlama kararı : talep kaleminin planlanacak kalanı ndan p_plan_quantity kadarı nı satı nalmaya ya da iç transfere ayı rı r; kalanı n geri kalanı
-- listede kalı r. Planla diyaloğunun onayı (Prc_P_MaterialRequestPlanConfirm) her taslak plan satı rı için çağı rı r.
-- Purchase: tedarikçinin talebin şubesi ve deposu için taslak teklif talebi varsa kalem ona eklenir (kalem zaten oradaysa miktarı artar), yoksa
-- talebin deposunun alı m operasyon türüyle yeni taslak teklif talebi açı lı r (para birimi ve koşullar kontak kartı ndan; alı cı — satı nalma sorumlusu —
-- planlayan). Fiyat tedarikçinin fiyat listesinden gelir; teklif → sipariş → alı m akı şı oradan sürer.
2026-10-14 19:26:03 +00:00
-- Transfer: kaynak konumun (lot/seri takipli üründe p_plan_lot_no lotunun) serbest stoğu (Prc_V_MaterialRequestPlanSource) yetmelidir; aynı
-- kaynak → talebin konumu için taslak iç transfer varsa satı r ona, yoksa kaynak deponun iç transfer operasyon türüyle yeni
-- taslak açı lı r. Depoda aynı türden birkaç operasyon türü olabilir (Bakı m Sarf Tüketimi, Departman Sarf Çı kı şı …); türün kendi
2026-10-19 14:35:08 +00:00
-- numaratörünü taşı yanı (SequenceName '….InternalTransfer' / '….Receipt' ile biter) seçilir, taslak da yalnı z o türde aranı r. Lot planlandı ysa transfer satı rı nı n lot dağı lı mı na (Stk_T_TransferLineLot, satı rı n biriminde) eklenir; depo Detaylar ya da
2026-10-14 19:26:03 +00:00
-- Otomatik Ata ile değiştirebilir. Kalanı n tamamı transferle
2026-10-14 09:07:11 +00:00
-- planlanan, satı nalma payı olmayan kalem transfer belgesinin yeniden hesabı nda kapanı r (Prc_P_MaterialRequestItemSync).
2026-10-14 19:26:03 +00:00
-- Stock: stok talebin teslim konumundadı r; Transfer gibi iç transfer açı lı r, kaynak ve hedef teslim konumudur (Doğrula stoğa dokunmaz,
-- teslimi kaydeder: kalemin teslim edilen miktarı artar). Belge numarası ve durumu Plan Takibi'ne transferden yansı r.
2026-10-14 09:07:11 +00:00
CREATE OR REPLACE PROCEDURE public . " Prc_P_MaterialRequestPlan " (
p_id uuid ,
p_plan_method varchar ,
p_plan_quantity numeric ( 18 , 4 ) ,
p_plan_supplier_id uuid ,
p_plan_source_location_id uuid ,
2026-10-14 19:26:03 +00:00
p_plan_lot_no varchar ,
2026-10-14 09:07:11 +00:00
p_tenant_id uuid ,
p_last_modifier_id uuid
)
LANGUAGE plpgsql AS $ $
DECLARE v_product uuid ; v_uom varchar ( 64 ) ; v_due timestamp ; v_reason varchar ( 256 ) ; v_branch uuid ; v_warehouse uuid ; v_location uuid ;
v_request_no varchar ( 32 ) ; v_remaining numeric ( 18 , 4 ) ; v_doc uuid ; v_line uuid ; v_op_type uuid ; v_src_warehouse uuid ;
v_free numeric ( 18 , 4 ) ; v_no varchar ( 128 ) ;
BEGIN
-- Kalem kilitlenir: aynı kalemin eşzamanlı iki planı kalanı iki kez dağı tamaz.
SELECT i . " ProductId " , i . " UomId " , i . " DueDate " , i . " RequestReason " , r . " BranchId " , r . " WarehouseId " , r . " LocationId " , r . " RequestNo "
INTO v_product , v_uom , v_due , v_reason , v_branch , v_warehouse , v_location , v_request_no
FROM " Prc_T_MaterialRequestItem " i
INNER JOIN " Prc_T_MaterialRequest " r ON r . " Id " = i . " MaterialRequestId "
WHERE i . " Id " = p_id AND i . " IsDeleted " = false AND i . " LineStatus " = ' Waiting ' AND r . " IsDeleted " = false
AND i . " TenantId " IS NOT DISTINCT FROM p_tenant_id
AND r . " ApprovalStatus " IN ( ' Onaylandı ' , ' Teklif Talebi ' , ' Teklif Talebi Gönderildi ' , ' Satı nalma Siparişi ' )
FOR UPDATE OF i ;
IF v_product IS NULL THEN
RAISE EXCEPTION ' Kalem planlanamaz: talep onaylı değil ya da kalem kapalı . ' USING ERRCODE = ' P0001 ' , DETAIL = ' 50191 ' ;
END IF ;
SELECT " RemainingQuantity " INTO v_remaining FROM public . " Prc_V_MaterialRequestItemPlan " WHERE " Id " = p_id ;
IF COALESCE ( p_plan_quantity , 0 ) < = 0 THEN
RAISE EXCEPTION ' Plan miktarı sı fı rdan büyük olmalı dı r. ' USING ERRCODE = ' P0001 ' , DETAIL = ' 50192 ' ;
END IF ;
IF p_plan_quantity > v_remaining THEN
RAISE EXCEPTION ' Plan miktarı planlanacak kalanı aşamaz (kalan: % %). ' , trim_scale ( v_remaining ) , v_uom USING ERRCODE = ' P0001 ' , DETAIL = ' 50193 ' ;
END IF ;
IF p_plan_method = ' Purchase ' THEN
IF p_plan_supplier_id IS NULL THEN
RAISE EXCEPTION ' Satı nalma kararı nda tedarikçi seçilmelidir. ' USING ERRCODE = ' P0001 ' , DETAIL = ' 50194 ' ;
END IF ;
SELECT " Id " INTO v_doc
FROM " Prc_T_PurchaseRfq "
WHERE " IsDeleted " = false AND " Status " = ' Draft ' AND " SupplierId " = p_plan_supplier_id AND " BranchId " = v_branch AND " WarehouseId " = v_warehouse
AND " TenantId " IS NOT DISTINCT FROM p_tenant_id
ORDER BY " CreationTime " DESC
LIMIT 1 ;
IF v_doc IS NULL THEN
SELECT " Id " INTO v_op_type
2026-10-19 14:35:08 +00:00
FROM " Stk_T_OperationType "
2026-10-14 09:07:11 +00:00
WHERE " IsDeleted " = false AND " IsActive " = true AND " OperationKind " = ' Receipt ' AND " WarehouseId " = v_warehouse
2026-10-14 19:26:03 +00:00
AND " TenantId " IS NOT DISTINCT FROM p_tenant_id
ORDER BY CASE WHEN " SequenceName " LIKE ' %. ' | | " OperationKind " THEN 0 ELSE 1 END , " Name "
2026-10-14 09:07:11 +00:00
LIMIT 1 ;
IF v_op_type IS NULL THEN
RAISE EXCEPTION ' Talebin deposu için aktif bir alı m operasyon türü tanı mlı değil. ' USING ERRCODE = ' P0001 ' , DETAIL = ' 50195 ' ;
END IF ;
v_doc : = gen_random_uuid ( ) ;
CALL public . " Adm_P_SequenceNext " ( ' Prc.PurchaseRfq ' , p_tenant_id , v_no ) ;
INSERT INTO " Prc_T_PurchaseRfq " ( " Id " , " TenantId " , " RfqNo " , " TenderGroupId " , " SupplierId " , " BranchId " , " OperationTypeId " , " WarehouseId " , " CurrencyId " ,
" BuyerUserId " , " IncotermId " , " IncotermLocation " , " PaymentTermId " , " CreationTime " , " CreatorId " , " IsDeleted " )
SELECT v_doc , p_tenant_id , left ( v_no , 32 ) , v_doc , c . " Id " , v_branch , v_op_type , v_warehouse , COALESCE ( c . " SupplierCurrency " , ' TRY ' ) ,
p_last_modifier_id , c . " PurchaseIncotermId " , c . " PurchaseIncotermLocation " , c . " PurchasePaymentTermId " ,
NOW ( ) AT TIME ZONE ' UTC ' , p_last_modifier_id , false
FROM " Adm_T_Contact " c
WHERE c . " Id " = p_plan_supplier_id AND c . " IsDeleted " = false ;
IF NOT FOUND THEN
RAISE EXCEPTION ' Satı nalma kararı nda tedarikçi seçilmelidir. ' USING ERRCODE = ' P0001 ' , DETAIL = ' 50194 ' ;
END IF ;
END IF ;
SELECT " Id " INTO v_line FROM " Prc_T_PurchaseRfqLine " WHERE " PurchaseRfqId " = v_doc AND " MaterialRequestItemId " = p_id AND " IsDeleted " = false LIMIT 1 ;
IF v_line IS NOT NULL THEN
UPDATE " Prc_T_PurchaseRfqLine "
2026-10-19 14:35:08 +00:00
SET " Quantity " = " Quantity " + public . " Stk_F_UomConvert " ( p_plan_quantity , v_uom , " UomId " ) ,
2026-10-14 09:07:11 +00:00
" LastModificationTime " = NOW ( ) AT TIME ZONE ' UTC ' , " LastModifierId " = p_last_modifier_id
WHERE " Id " = v_line ;
ELSE
INSERT INTO " Prc_T_PurchaseRfqLine " ( " Id " , " TenantId " , " PurchaseRfqId " , " ProductId " , " Description " , " Quantity " , " UomId " , " UnitPrice " , " TaxRate " , " Amount " ,
" DeliveryDate " , " MaterialRequestItemId " , " CreationTime " , " CreatorId " , " IsDeleted " )
SELECT gen_random_uuid ( ) , p_tenant_id , v_doc , v_product , v_reason , p_plan_quantity , v_uom ,
2026-10-19 14:35:08 +00:00
COALESCE ( ( SELECT ps . " Price " FROM " Stk_T_ProductSupplier " ps
2026-10-14 09:07:11 +00:00
WHERE ps . " ProductId " = v_product AND ps . " ContactId " = p_plan_supplier_id AND ps . " IsDeleted " = false
ORDER BY ps . " MinQuantity " LIMIT 1 ) , 0 ) ,
COALESCE ( p . " PurchaseTaxRate " , 0 ) , 0 , v_due , p_id , NOW ( ) AT TIME ZONE ' UTC ' , p_last_modifier_id , false
2026-10-19 14:35:08 +00:00
FROM " Stk_T_Product " p
2026-10-14 09:07:11 +00:00
WHERE p . " Id " = v_product ;
END IF ;
CALL public . " Prc_P_PurchaseRfqRecalc " ( v_doc ) ;
2026-10-14 19:26:03 +00:00
ELSIF p_plan_method IN ( ' Transfer ' , ' Stock ' ) THEN
IF p_plan_method = ' Stock ' THEN
p_plan_source_location_id : = v_location ;
END IF ;
2026-10-14 09:07:11 +00:00
IF p_plan_source_location_id IS NULL THEN
RAISE EXCEPTION ' İç transfer kararı nda kaynak konum seçilmelidir. ' USING ERRCODE = ' P0001 ' , DETAIL = ' 50196 ' ;
END IF ;
-- Konum ve serbest stok kuralı diyaloğun İç Transfer ı zgarası yla aynı dı r.
SELECT " WarehouseId " , " FreeQuantity " INTO v_src_warehouse , v_free
FROM public . " Prc_V_MaterialRequestPlanSource "
2026-10-14 19:26:03 +00:00
WHERE " BaseId " = p_id AND " LocationId " = p_plan_source_location_id AND COALESCE ( " LotNo " , ' ' ) = COALESCE ( p_plan_lot_no , ' ' ) ;
IF v_src_warehouse IS NULL OR ( p_plan_method = ' Transfer ' AND p_plan_source_location_id = v_location ) THEN
RAISE EXCEPTION ' Kaynak konum, talebin teslim konumundan farklı ve ürünün (lot/seri takipli üründe lotun) stoğu olan bir iç konum olmalı dı r. ' USING ERRCODE = ' P0001 ' , DETAIL = ' 50197 ' ;
2026-10-14 09:07:11 +00:00
END IF ;
IF p_plan_quantity > v_free THEN
RAISE EXCEPTION ' Kaynak konumda yeterli serbest stok yok (serbest: % %). ' , trim_scale ( GREATEST ( v_free , 0 ) ) , v_uom USING ERRCODE = ' P0001 ' , DETAIL = ' 50198 ' ;
END IF ;
2026-10-14 19:26:03 +00:00
SELECT " Id " INTO v_op_type
2026-10-19 14:35:08 +00:00
FROM " Stk_T_OperationType "
2026-10-14 19:26:03 +00:00
WHERE " IsDeleted " = false AND " IsActive " = true AND " OperationKind " = ' InternalTransfer ' AND " WarehouseId " = v_src_warehouse
AND " TenantId " IS NOT DISTINCT FROM p_tenant_id
ORDER BY CASE WHEN " SequenceName " LIKE ' %. ' | | " OperationKind " THEN 0 ELSE 1 END , " Name "
LIMIT 1 ;
IF v_op_type IS NULL THEN
RAISE EXCEPTION ' Kaynak depo için aktif bir iç transfer operasyon türü tanı mlı değil. ' USING ERRCODE = ' P0001 ' , DETAIL = ' 50199 ' ;
END IF ;
2026-10-14 09:07:11 +00:00
SELECT " Id " INTO v_doc
2026-10-19 14:35:08 +00:00
FROM " Stk_T_Transfer "
2026-10-14 19:26:03 +00:00
WHERE " IsDeleted " = false AND " OperationTypeId " = v_op_type AND " Status " = ' Draft ' AND " ReturnOfId " IS NULL AND " BackorderOfId " IS NULL
2026-10-14 09:07:11 +00:00
AND " SourceLocationId " = p_plan_source_location_id AND " DestinationLocationId " = v_location
AND " TenantId " IS NOT DISTINCT FROM p_tenant_id
ORDER BY " CreationTime " DESC
LIMIT 1 ;
IF v_doc IS NULL THEN
v_doc : = gen_random_uuid ( ) ;
2026-10-19 14:35:08 +00:00
INSERT INTO " Stk_T_Transfer " ( " Id " , " TenantId " , " BranchId " , " WarehouseId " , " OperationTypeId " , " OperationKind " , " SourceLocationId " , " DestinationLocationId " ,
2026-10-14 09:07:11 +00:00
" SourceDocument " , " ResponsibleUserId " , " Status " , " CreationTime " , " CreatorId " , " IsDeleted " )
SELECT v_doc , p_tenant_id , ot . " BranchId " , ot . " WarehouseId " , ot . " Id " , ' InternalTransfer ' , p_plan_source_location_id , v_location ,
v_request_no , p_last_modifier_id , ' Draft ' , NOW ( ) AT TIME ZONE ' UTC ' , p_last_modifier_id , false
2026-10-19 14:35:08 +00:00
FROM " Stk_T_OperationType " ot
2026-10-14 09:07:11 +00:00
WHERE ot . " Id " = v_op_type ;
ELSE
2026-10-19 14:35:08 +00:00
UPDATE " Stk_T_Transfer "
2026-10-14 09:07:11 +00:00
SET " SourceDocument " = left ( COALESCE ( " SourceDocument " , ' ' ) | | CASE WHEN COALESCE ( " SourceDocument " , ' ' ) = ' ' THEN ' ' ELSE ' , ' END | | v_request_no , 128 )
WHERE " Id " = v_doc AND strpos ( COALESCE ( " SourceDocument " , ' ' ) , v_request_no ) = 0 ;
END IF ;
2026-10-19 14:35:08 +00:00
-- Planlanan miktar yapı lacak miktardı r: lotsuz satı rda doğrudan yazı lı r, lotlu satı rda lot dağı lı mı ndan (Stk_P_TransferRecalc) gelir.
SELECT " Id " INTO v_line FROM " Stk_T_TransferLine " WHERE " TransferId " = v_doc AND " MaterialRequestItemId " = p_id AND " IsDeleted " = false LIMIT 1 ;
2026-10-14 09:07:11 +00:00
IF v_line IS NOT NULL THEN
2026-10-19 14:35:08 +00:00
UPDATE " Stk_T_TransferLine "
SET " DemandQuantity " = " DemandQuantity " + public . " Stk_F_UomConvert " ( p_plan_quantity , v_uom , " UomId " ) ,
" Quantity " = " Quantity " + CASE WHEN COALESCE ( p_plan_lot_no , ' ' ) = ' ' THEN public . " Stk_F_UomConvert " ( p_plan_quantity , v_uom , " UomId " ) ELSE 0 END ,
2026-10-14 09:07:11 +00:00
" LastModificationTime " = NOW ( ) AT TIME ZONE ' UTC ' , " LastModifierId " = p_last_modifier_id
WHERE " Id " = v_line ;
ELSE
2026-10-14 19:26:03 +00:00
v_line : = gen_random_uuid ( ) ;
2026-10-19 14:35:08 +00:00
INSERT INTO " Stk_T_TransferLine " ( " Id " , " TenantId " , " TransferId " , " ProductId " , " Description " , " DemandQuantity " , " Quantity " , " UomId " , " MaterialRequestItemId " ,
2026-10-14 09:07:11 +00:00
" CreationTime " , " CreatorId " , " IsDeleted " )
2026-10-14 19:26:03 +00:00
VALUES ( v_line , p_tenant_id , v_doc , v_product , v_reason , p_plan_quantity , CASE WHEN COALESCE ( p_plan_lot_no , ' ' ) = ' ' THEN p_plan_quantity ELSE 0 END , v_uom , p_id ,
NOW ( ) AT TIME ZONE ' UTC ' , p_last_modifier_id , false ) ;
2026-10-14 09:07:11 +00:00
END IF ;
2026-10-14 19:26:03 +00:00
IF COALESCE ( p_plan_lot_no , ' ' ) < > ' ' THEN
2026-10-19 14:35:08 +00:00
UPDATE " Stk_T_TransferLineLot " ll
SET " Quantity " = ll . " Quantity " + public . " Stk_F_UomConvert " ( p_plan_quantity , v_uom , tl . " UomId " ) ,
2026-10-14 19:26:03 +00:00
" LastModificationTime " = NOW ( ) AT TIME ZONE ' UTC ' , " LastModifierId " = p_last_modifier_id
2026-10-19 14:35:08 +00:00
FROM " Stk_T_TransferLine " tl
2026-10-14 19:26:03 +00:00
WHERE tl . " Id " = ll . " TransferLineId " AND ll . " TransferLineId " = v_line AND ll . " LotNo " = p_plan_lot_no AND ll . " IsDeleted " = false ;
IF NOT FOUND THEN
2026-10-19 14:35:08 +00:00
INSERT INTO " Stk_T_TransferLineLot " ( " Id " , " TenantId " , " TransferLineId " , " LotNo " , " Quantity " , " CreationTime " , " CreatorId " , " IsDeleted " )
SELECT gen_random_uuid ( ) , p_tenant_id , tl . " Id " , p_plan_lot_no , public . " Stk_F_UomConvert " ( p_plan_quantity , v_uom , tl . " UomId " ) ,
2026-10-14 19:26:03 +00:00
NOW ( ) AT TIME ZONE ' UTC ' , p_last_modifier_id , false
2026-10-19 14:35:08 +00:00
FROM " Stk_T_TransferLine " tl
2026-10-14 19:26:03 +00:00
WHERE tl . " Id " = v_line ;
END IF ;
2026-10-14 09:07:11 +00:00
END IF ;
2026-10-14 19:26:03 +00:00
-- Numara ve yeniden hesap (kalemin kapanması dahil) belge kaydı sonrası yla aynı dı r.
2026-10-19 14:35:08 +00:00
CALL public . " Stk_P_TransferAfterSave " ( v_doc , p_last_modifier_id ) ;
2026-10-14 09:07:11 +00:00
ELSE
RAISE EXCEPTION ' Karar Satı nalma, İç Transfer ya da Stoktan olmalı dı r. ' USING ERRCODE = ' P0001 ' , DETAIL = ' 50192 ' ;
END IF ;
END ;
$ $ ;