CREATE OR ALTER PROCEDURE [HM].[UpdateDocumentReservationsFromXML] (@docHandle INT, 
															@tblDocumentPositions [HM].[DocumentReservationsPositionsType] READONLY,
															@DP [HM].[DocumentPositionsType] READONLY,
															@DeletedDocumentPositionsRZ [HM].[DocumentPositionsType] READONLY,
															@docId INT, 
															@docDate DATETIME,	
															@docKhId INT,		
															@correction BIT, 
															@anyOrderRelatedDocuments BIT,
															@tworzacy int
															)
AS
BEGIN
	DECLARE @dataName varchar(255) = '',
	@positionName varchar(255) = '',
	@docType INT,		
	@bazaDokRZ INT,		
	@bazaPozRZ INT

	SELECT TOP 1 @dataName = localname 
	FROM OPENXML(@docHandle, '/')

	IF (@dataName = 'SaleDocument')
	BEGIN
		SELECT @docType = 0,
		@bazaDokRZ = 16,
		@bazaPozRZ = 18,
		@positionName = 'SalePosition'
	END
	ELSE IF (@dataName = 'ForeignOrderDocument')
	BEGIN
		SELECT @docType = 1,
		@bazaDokRZ = 45,
		@bazaPozRZ = 30,
		@positionName = 'ForeignOrderPosition'
	END
	ELSE IF (@dataName = 'InventoryDocument')
	BEGIN
		SELECT @docType = 2,
		@bazaDokRZ = 33,
		@bazaPozRZ = 37,
		@positionName = 'InventoryPosition'
	END
	ELSE
	BEGIN
		DECLARE @msg varchar(2048) = CONCAT('Nieobslugiwany charakter dokumentu: ', @dataName);
		THROW 51000, @msg, 1;  
	END

	--Tabela tymczasowa odczytywania rezerwacji dokumentu
	DECLARE @tblPositionsReservations AS TABLE
	(
		[Id] INT,
		[PositionId] INT,
		[NodeId] INT,
		[AvailableQuantity] DECIMAL(24,4),
		[ReservedQuantity] DECIMAL(24,4),
		[ReservedQuantityAuxiliary] DECIMAL(24,4),
		[RealizedReservedQuantity] DECIMAL(24,4),
		[InventoryId] INT
	)

	-- Deserializacja danych rezerwacji z xml
	DECLARE @PositionsReservationsXPath varchar(500) = CONCAT('/', @dataName, '/DocumentPositions/', @positionName,'/Reservations/Reservation')

	INSERT INTO @tblPositionsReservations
	SELECT 
		0,
		[PositionId],
		[NodeId],
		[AvailableQuantity],
		[ReservedQuantity],
		[ReservedQuantityAuxiliary],
		[RealizedReservedQuantity],
		[InventoryId]
	FROM 
		OPENXML(@docHandle, @PositionsReservationsXPath)
		WITH
		(
		--[Id] INT 'Id',	--nie możemy polegać na id z xml-a ponieważ może się on zmienić w trakcie edycji rezerwacji (z nie zerowego stać się zerowy)
		[PositionId] INT 'PositionId',
		[NodeId] INT 'NodeId',
		[AvailableQuantity] DECIMAL(24,4) 'AvailableQuantity',
		[ReservedQuantity] DECIMAL(24,4) 'ReservedQuantity',
		[ReservedQuantityAuxiliary] DECIMAL(24,4) 'ReservedQuantityAuxiliary',
		[RealizedReservedQuantity] DECIMAL(24,4) 'RealizedReservedQuantity',
		[InventoryId] INT 'InventoryId',
		[ModificationStatus] VARCHAR(30) './../../@ModificationStatus'
		)
		WHERE [ModificationStatus] <> 'Deleted' OR [ModificationStatus] IS NULL  -- pomijamy pozycje oznaczone jako 'Deleted'
					
	--Zabezpieczenie przed przypadkową rezerwacją przy zapisie dokumentu rezerwowanego wydaniem
	UPDATE @tblPositionsReservations SET ReservedQuantity = IIF(ReservedQuantity - RealizedReservedQuantity < 0,0,ReservedQuantity - RealizedReservedQuantity)
	FROM @tblPositionsReservations
	WHERE RealizedReservedQuantity > 0

	--Aktualizacja Id pozycji (DP), z xmla przyjdą zera dla nowych pozycji
	UPDATE tblRZ SET PositionId = tblDP.Id
	FROM @tblDocumentPositions tblDP
		JOIN @tblPositionsReservations tblRZ ON tblDP.NodeId = tblRZ.NodeId
	WHERE tblRZ.PositionId = 0;

	--odtworzenie id-ów rezerwacji, które już istnieją (z xml-a przyszły same zera)
	UPDATE tblRZ SET tblRZ.Id = RZ.id
	FROM @tblPositionsReservations tblRZ
		JOIN @tblDocumentPositions tblDP ON tblDP.Id = tblRZ.PositionId
		JOIN HM.RZ ON RZ.idpozrz = tblRZ.PositionId AND RZ.magazyn = tblRZ.InventoryId AND RZ.bazapozrz = @bazaPozRZ AND RZ.idtw = tblDP.ProductId 
	WHERE tblDP.ReservationType = IIF(rz.subtyp = 0,2,1) --odtwarzamy jeśli nie został zmieniony typ rezerwacji (ilościowy/ze wskazaniem), w przeciwnym razie traktujemy jako nową

	--usuwamy rezerwacje z pozycji które mają zmieniony typ rezerwacji na 'brak' lub zostały wyzerowane
	DELETE tblRZ
	FROM @tblDocumentPositions tblDP 
		JOIN @tblPositionsReservations tblRZ ON tblRZ.PositionId = tblDP.Id
	WHERE tblDP.ReservationType = 0 OR 
		(tblRZ.ReservedQuantity = 0 AND ISNULL(tblRZ.RealizedReservedQuantity,0) = 0)
	-- ??? and RZ.id not in (SELECT id2 FROM HM.ZZ WHERE typ=96 AND baza1 = 152) chyba chodzi o to że realizuje (pomimo zer w ilości??)


	--Tabela tymczasowa do odczytania rezerwacji ze wskazaniem dostawy
	DECLARE @tblPositionsReservationsDelivery AS TABLE
	(
		[Id] INT,
		[PositionId] INT,
		[NodeId] INT,
		[AvailableQuantity] DECIMAL(24,4),
		[ReservedQuantity] DECIMAL(24,4),
		[ReservedQuantityAuxiliary] DECIMAL(24,4),
		[InventoryId] INT,
		[DeliveryId] INT,
		[Price] DECIMAL(35,15)
	)

	-- Deserializacja danych rezerwacji ze wskazaniem dostawy z xml
	DECLARE @PositionsReservationsDeliveryXPath varchar(500) = CONCAT('/', @dataName, '/DocumentPositions/', @positionName,'/ReservationsDelivery/ReservationDelivery')

	INSERT INTO @tblPositionsReservationsDelivery
	SELECT 
		[Id],
		[PositionId],
		[NodeId],
		[AvailableQuantity],
		[ReservedQuantity],
		[ReservedQuantityAuxiliary],
		[InventoryId],
		[DeliveryId],
		[Price]
	FROM 
		OPENXML(@docHandle, @PositionsReservationsDeliveryXPath)
		WITH
		(
			[Id] INT 'Id',
			[PositionId] INT 'PositionId',
			[NodeId] INT 'NodeId',
			[AvailableQuantity] DECIMAL(24,4) 'AvailableQuantity',
			[ReservedQuantity] DECIMAL(24,4) 'ReservedQuantity',
			[ReservedQuantityAuxiliary] DECIMAL(24,4) 'ReservedQuantityAuxiliary',
			[InventoryId] INT 'Delivery/InventoryId',
			[DeliveryId] INT 'Delivery/Id',
			[Price] DECIMAL(35,15) 'Delivery/Price',
			[ModificationStatus] VARCHAR(30) './../../@ModificationStatus'
		)
		WHERE [ModificationStatus] <> 'Deleted' OR [ModificationStatus] IS NULL  -- pomijamy pozycje oznaczone jako 'Deleted'

	--aktualizacja id pozycji (DP)
	UPDATE tblRZD SET PositionId = tblDP.Id
	FROM @tblDocumentPositions tblDP
	JOIN @tblPositionsReservationsDelivery tblRZD ON tblDP.NodeId = tblRZD.NodeId
	WHERE tblRZD.PositionId = 0;

	--odtworzenie id-ów PW, które już istnieją (z xml-a mogą przyjść nie prawdziwe)
	UPDATE tblRZD SET Id = pw.id
	FROM @tblPositionsReservationsDelivery tblRZD 
		JOIN @tblPositionsReservations tblRZ ON tblRZ.PositionId = tblRZD.PositionId AND tblRZ.InventoryId = tblRZD.InventoryId
		JOIN HM.PW pw ON pw.idmg = tblRZ.Id AND pw.iddw = tblRZD.DeliveryId AND pw.typ = 26

	--Tabela tymczasowa do odczytania realizowanych rezerwacji
	DECLARE @tblDeliverySettlements AS TABLE
	(
		[ReservationId] INT,				
		[DeliverySettlementId] INT,				
		[Quantity] DECIMAL(24,4),
		[RealizationQuantity] DECIMAL(24,4),
		[MaxQuantity] DECIMAL(24,4),
		[DeliveryMaxQuantity] DECIMAL(24,4)
	)

	-- Deserializacja danych realizowanych rezerwacji z xml
	DECLARE @DeliverySettlementsXPath varchar(500) = CONCAT('/', @dataName, '/DocumentPositions/', @positionName,'/Reservations/Reservation/DeliverySettlements/DeliverySettlement')

	INSERT INTO @tblDeliverySettlements
	SELECT 
		[ReservationId],				
		[DeliverySettlementId],				
		[Quantity],
		[RealizationQuantity],
		[MaxQuantity],
		[DeliveryMaxQuantity]
	FROM 
		OPENXML(@docHandle, @DeliverySettlementsXPath)
		WITH
		(
			[ReservationId] INT 'ReservationId',				
			[DeliverySettlementId] INT 'DeliverySettlementId',				
			[Quantity] DECIMAL(24,4) 'Quantity',
			[RealizationQuantity] DECIMAL(24,4) 'RealizationQuantity',
			[MaxQuantity] DECIMAL(24,4) 'MaxQuantity',
			[DeliveryMaxQuantity] DECIMAL(24,4) 'DeliveryMaxQuantity',
			[ModificationStatus] VARCHAR(30) './../../../../@ModificationStatus'
		)
		WHERE [ModificationStatus] <> 'Deleted' OR [ModificationStatus] IS NULL  -- pomijamy pozycje oznaczone jako 'Deleted'

	--uzupełnienie id rezerwacji na potrzeby dalszych obliczeń
	UPDATE @tblDeliverySettlements SET ReservationId = pw.idmg 
	FROM @tblDeliverySettlements tds
	JOIN HM.PW pw ON tds.DeliverySettlementId = pw.id
	WHERE IsNull(tds.ReservationId, 0) = 0


	IF @correction = 0
	BEGIN
		--Aktualizacja typu rezerwacji na pozycji				
		IF (@docType = 0)
		BEGIN
			UPDATE [HM].[DP] SET
				typ = dp.typ | IIF(tblDP.[ReservationType] = 0,0,0x08) | IIF(tblDP.[ReservationType] = 1,IIF(tw.metoda = 0,0,0x04) | 0x02,0x20)
			FROM [HM].[DP] dp
			JOIN [HM].[TW] tw ON dp.idtw = tw.id
			JOIN @tblDocumentPositions tblDP ON DP.[id] = tblDP.[Id]
			WHERE (dp.flag & 0x0200 <> 0) and dp.super = @docId
			--AND tblDP.MofificationStatus IN (@created, @updated)
		END 
		ELSE IF (@docType = 1)
		BEGIN
			UPDATE [HM].[ZP] SET
				typ = zp.typ | IIF(tblDP.[ReservationType] = 0,0,0x08) | IIF(tblDP.[ReservationType] = 1,IIF(tw.metoda = 0,0,0x04) | 0x02,0x20)
			FROM [HM].[ZP] zp
			JOIN [HM].[TW] tw ON zp.idtw = tw.id
			JOIN @tblDocumentPositions tblDP ON ZP.[id] = tblDP.[Id]
			WHERE (zp.flag & 0x0200 <> 0) and zp.super = @docId
			--AND tblDP.MofificationStatus IN (@created, @updated)
		END
		ELSE IF (@docType = 2)
		BEGIN
			UPDATE HM.MZ SET
				typ = mz.typ | IIF(tblDP.ReservationType = 0,0,0x08) | IIF(tblDP.ReservationType = 1,IIF(tw.metoda = 0,0,0x04) | 0x02,0x20)
			FROM HM.MZ mz
			JOIN HM.TW tw ON mz.idtw = tw.id
			JOIN @tblDocumentPositions tblDP ON MZ.id = tblDP.Id
			WHERE (mz.flag & 0x0200 <> 0) and mz.super = @docId
			--AND tblDP.MofificationStatus IN (@created, @updated)
		END
	END

	--aktualizacja kontrahenta na wszystkich rezerwacjach z dokumentu
	IF @docKhId != ISNULL((SELECT TOP 1 rz.idkh FROM HM.RZ rz WHERE rz.iddokrz = @docId AND rz.bazadokrz = @bazaDokRZ), @docKhId)
	BEGIN --jeśli zmienił się kontrahent w jednej to zmień na wszystkich 
		UPDATE HM.RZ SET RZ.idkh = @docKhId WHERE RZ.iddokrz = @docId AND RZ.bazadokrz = @bazaDokRZ
	END

	--indentyfikatory nowo dodanych rezerwacji
	DECLARE @newRzIds TABLE (Id INT, PositionId INT, InventoryId INT)

	-- Dodanie rekordów rezerwacji (RZ), dla pozycji i magazynów dla których ich nie ma
	INSERT INTO [HM].[RZ] (flag, subtyp, typ, idtw, idkh, magazyn, data, termin, iloscrz, iloscrl, wartosc, iddokrz, bazadokrz, idpozrz, bazapozrz, tworzacy) 
	OUTPUT inserted.id, inserted.idpozrz, inserted.magazyn INTO @newRzIds
	SELECT DISTINCT 0,IIF(tblDP.[ReservationType] = 2,0,1),2,tblDP.ProductId,@docKhId,tblRZ.InventoryId, @docDate, DATEADD(DAY, 7, @docDate),0,0,0,@docId,@bazaDokRZ,tblDP.id,@bazaPozRZ,@tworzacy
	FROM @tblDocumentPositions tblDP
		JOIN @tblPositionsReservations tblRZ ON tblRZ.PositionId = tblDP.id
		JOIN [HM].[SM] SM ON SM.idtw = tblDP.ProductId AND SM.magazyn = tblRZ.InventoryId
		LEFT JOIN [HM].[OP] OP ON OP.owner_id = tblDP.id AND OP.owner_base = @bazaPozRZ
	WHERE HM.ROUND4(SM.stanHandl) >= 0 
		--AND (tblDP.id NOT IN (SELECT RR.idpozrz FROM [HM].[RZ] RR WHERE RR.iddokrz = @docId and RR.magazyn = tblRZ.InventoryId) 
		--`		OR tblDP.ProductId NOT IN (SELECT RR.idtw FROM [HM].[RZ] RR WHERE RR.iddokrz = @docId))
		AND tblRZ.Id = 0 AND tblRZ.ReservedQuantity > 0
		AND tblDP.[ReservationType] in (1,2) 		 
		--??? ilość dp rozliczenia większa od 0 AND (tblDP.iloscDP - ISNULL(OP.ilosc_rozl,0)) > 0
	--AND tblDP.MofificationStatus IN (@created, @updated)

	-- Aktualizacja Id nowo dodanych RZ w @tblPositionsReservations
	UPDATE tblRZ SET Id = newRzIds.Id
	FROM @tblPositionsReservations tblRZ
		JOIN @newRzIds newRzIds ON newRzIds.PositionId = tblRZ.PositionId AND newRzIds.InventoryId = tblRZ.InventoryId


	--Aktualizacja ilości w rezerwacji (RZ)
	UPDATE [HM].[RZ] SET 
		iloscrz = pom.Ilosc,
		subtyp = pom.subtyp
	FROM(
		SELECT tblRZ.Id, IIF(
			HM.ROUND4((SM.stanHandl + RZ.iloscrz - tblRZ.ReservedQuantity)) >= 0,
			tblRZ.ReservedQuantity,
			HM.ROUND4(SM.stanHandl + RZ.iloscrz)) as Ilosc,
			IIF(tblDP.[ReservationType] = 2,0,1) subtyp
		FROM @tblPositionsReservations tblRZ  
			JOIN HM.RZ ON RZ.magazyn = tblRZ.InventoryId and RZ.bazapozrz = @bazaPozRZ and RZ.idpozrz = tblRZ.PositionId
			JOIN @tblDocumentPositions tblDP ON tblDP.id = tblRZ.PositionId
			JOIN [HM].[SM] SM ON SM.idtw = tblDP.ProductId AND SM.magazyn = tblRZ.InventoryId
		WHERE --(RZ.iloscrz != tblRZ.ReservedQuantity OR RZ.subtyp != IIF(tblDP.[ReservationType] = 2,0,1)) AND
			tblDP.[ReservationType] in (1,2)
			--AND tblDP.MofificationStatus IN (@created, @updated)
		) pom
	WHERE rz.Id = pom.Id and (rz.iloscrz != pom.Ilosc or rz.subtyp != pom.subtyp)
			

--Rezerwacje przeznaczone do usunięcia
	DECLARE @rzToDel TABLE (Id INT, ProductId INT, InventoryId INT, ReservationType INT)

	--z usuniętych pozycji
	INSERT INTO @rzToDel
	SELECT delRZ.id, delRZ.IdTw, rz.magazyn, IIF(rz.subtyp = 0,2,1)
	FROM @DeletedDocumentPositionsRZ delRZ
		JOIN HM.RZ rz ON rz.id = delRz.Id

	--ze zmodyfikowanych pozycji np. zmiana towaru, magazynu
	INSERT INTO @rzToDel
	SELECT RZ.id, RZ.idtw, RZ.magazyn, IIF(rz.subtyp = 0,2,1)
	FROM @tblDocumentPositions tblDP 
		JOIN HM.RZ ON RZ.idpozrz = tblDP.Id AND RZ.bazapozrz = @bazaPozRZ 
	WHERE RZ.id NOT IN (SELECT Id FROM @tblPositionsReservations) 
	--AND tblDP.MofificationStatus IN (@created, @updated)


	--stany które należy zaktualizować
	DECLARE @smToUpdate TABLE (ProductId INT, InventoryId INT, ReservationType INT)

	--z rezerwacji usuniętych
	INSERT INTO @smToUpdate 
	SELECT DISTINCT ProductId, InventoryId, ReservationType 
	FROM @rzToDel

	--z rezerwacji ze zmodyfikowanych pozycji
	INSERT INTO @smToUpdate 
	SELECT DISTINCT tblDP.ProductId, tblRz.InventoryId, tblDP.ReservationType 
	FROM @tblPositionsReservations tblRz
		JOIN @tblDocumentPositions tblDP ON tblDP.Id = tblRz.PositionId
	--WHERE tblDP.MofificationStatus IN (@created, @updated)


	-- dostawy wartościowe których stany trzeba będzie zauktualizować
	DECLARE @dwToUpdate TABLE (Id INT)

	--pochodzące z usuniętych rezerwacji
	INSERT INTO @dwToUpdate
	SELECT DISTINCT pw.iddw
	FROM @rzToDel rzToDel
		JOIN HM.PW pw ON pw.idmg = rzToDel.Id AND pw.typ = 26
		JOIN HM.DW dw ON dw.id = pw.iddw
	WHERE dw.numer != -dw.magazyn --pomijamy dostawy ilościowe

	-- ze zmodyfikowanych rezerwacji
	INSERT INTO @dwToUpdate
	SELECT DISTINCT tblRZD.DeliveryId
	FROM @tblPositionsReservationsDelivery tblRZD

	--Wyzerowanie rezerwacji do usunięcia
	UPDATE [HM].[RZ] SET 
		iloscrz = 0, 
		iloscrl = 0 
	WHERE id in (SELECT Id FROM @rzToDel)
		and (rz.iloscrz != 0 or rz.iloscrl != 0)
				

	--Dodanie brakujących dostaw rezerwacji ilościowej
	INSERT INTO [HM].[DW] (flag,subtyp,typ,kod,numer,idtw,data,ilosc,iloscdosp,cena,wartoscdosp,magazyn,iloscPz,stan,wartoscst,bufor)
	SELECT 0,0,0,'Rezerwacja ilościowa',-tblRZ.InventoryId,tblDP.ProductId,'9999-01-01 00:00:00.000',0,0,0,0,tblRZ.InventoryId,0,0,0,0
	FROM @tblDocumentPositions tblDP  
		JOIN @tblPositionsReservations tblRZ ON tblRZ.PositionId = tblDP.Id  
	WHERE tblDP.ProductId not in (SELECT idtw FROM [HM].[DW] WHERE idtw = tblDP.ProductId and magazyn = tblRZ.InventoryId and numer = -tblRZ.InventoryId) 
		and tblDP.[ReservationType] = 1

	--Aktualizacja stanu handlowego w dostawach ilościowych (na podstawie sumy z rezerwacji ilościowych)
	UPDATE DW SET DW.iloscdosp = -ISNULL(sumRZ.iloscrz, 0),
				  DW.typ = IIF(ISNULL(sumRZ.iloscrz, 0) > 0,1,0)
	FROM HM.DW DW
		JOIN (SELECT DISTINCT ProductId, InventoryId FROM @smToUpdate WHERE ReservationType = 1) smToUpdate 
				ON smToUpdate.InventoryId = DW.magazyn AND smToUpdate.ProductId = DW.idtw AND DW.numer = -DW.magazyn
		LEFT JOIN (SELECT SUM(HM.ROUND4(iloscrz)) AS iloscrz, idtw, magazyn 
				FROM HM.RZ 
				WHERE RZ.subtyp = 1 
				GROUP BY RZ.idtw, RZ.magazyn) sumRZ ON sumRZ.idtw = DW.idtw AND sumRZ.magazyn = DW.magazyn


	
	IF @anyOrderRelatedDocuments = 1
	BEGIN /* Obsługa rezerwacji powiązanych z zamówieniem przed usunięciem rezerwacji */

		UPDATE HM.RZ SET rz.iloscrz = rz.iloscrz + zz.ilosc
		FROM HM.RZ rz
		JOIN HM.ZZ zz ON rz.id = zz.id1 and zz.typ = 96 and zz.baza1 = 152
		JOIN @DeletedDocumentPositionsRZ ddprz ON ddprz.Id = zz.id2
		WHERE rz.iloscrz != rz.iloscrz + zz.ilosc

		UPDATE zpw SET zpw.ilosc = zpw.ilosc + zz.ilosc
		FROM HM.PW pw
		JOIN @DeletedDocumentPositionsRZ ddprz ON ddprz.Id = pw.idmg
		JOIN HM.ZZ zz ON pw.id = zz.id2 and zz.typ = 96 and zz.baza1 = 36
		JOIN HM.PW zpw ON zpw.id = zz.id1

		--uzupełnienie poprawne powiązań zamówień
		UPDATE HM.ZZ SET zz.ilosc = 0
		FROM HM.ZZ zz 
		JOIN @DeletedDocumentPositionsRZ tds ON tds.Id = zz.id2 and zz.typ = 96 and zz.baza1 = 152

		UPDATE HM.ZZ SET zz.ilosc = 0
		FROM HM.ZZ zz 
		JOIN HM.PW pw ON zz.id2 = pw.id and zz.typ = 96 and zz.baza1 = 36
		JOIN @DeletedDocumentPositionsRZ tds ON tds.Id = pw.idmg 
	END

	--Usunięcie RZ i PW przewidzianych wcześniej do usunięca
	DELETE FROM HM.RZ WHERE id IN (SELECT DISTINCT id FROM @rzToDel)
	DELETE FROM HM.PW WHERE typ = 26 AND idmg IN (SELECT DISTINCT Id FROM @rzToDel)

	--usunięcie pw po aktualizacji ilości dla rezerwacji ze wskazaniem dostaw
	--usuwane są istniejące pozycje które obecnie mają ReservedQuantity = 0
	DELETE FROM HM.PW
	WHERE id IN (SELECT tblRZD.Id 
		 			FROM @tblPositionsReservationsDelivery tblRZD
					WHERE tblRZD.ReservedQuantity <= 0
						AND tblRZD.id NOT IN (SELECT id2 FROM HM.ZZ WHERE baza1 = 36))


	--wyzerowanie rezerwacji dla dokumentu sprzedaży gdy jest powiązany z zamówieniem i ma ReservedQuantity = 0
	UPDATE [HM].[PW] SET 
		ilosc = 0, 
		ilosczreal = 0 
	WHERE pw.id IN (SELECT tblRZD.Id 
		 			FROM @tblPositionsReservationsDelivery tblRZD
					WHERE tblRZD.ReservedQuantity <= 0
						AND tblRZD.id IN (SELECT id2 FROM HM.ZZ WHERE baza1 = 36))
		AND (pw.ilosc != 0 or pw.ilosczreal != 0)


	--dodanie PW dla nowych rezerwacji ilościowych
	INSERT INTO [HM].[PW] (flag,subtyp,typ,idmg,iddw,idtw,ilosc,wartosc,ilosczreal,data)
	SELECT DISTINCT 1, 0, 26, tblRZ.id, dw.id, tblDP.ProductId, tblRZ.ReservedQuantity, 0, 0, @docDate 
		FROM @newRzIds newRz
			JOIN @tblPositionsReservations tblRZ ON tblRZ.Id = newRz.Id
			JOIN @tblDocumentPositions tblDP ON tblDP.Id = tblRZ.PositionId
			JOIN HM.DW dw ON dw.idtw = tblDP.ProductId AND dw.magazyn = tblRZ.InventoryId AND dw.numer = -dw.magazyn
		WHERE tblRZ.ReservedQuantity > 0 AND tblDP.ReservationType = 1

	--aktualizacja PW dla rezerwacji ilościowych
	UPDATE [HM].[PW] SET 
		ilosc = tblRZ.ReservedQuantity, 
		flag = 1
	FROM @tblPositionsReservations tblRZ
	JOIN [HM].[PW] PW ON PW.idmg = tblRZ.id AND PW.typ = 26
	JOIN @tblDocumentPositions tblDP ON tblDP.Id = tblRZ.PositionId
	WHERE tblDP.[ReservationType] = 1
		and (pw.ilosc != tblRZ.ReservedQuantity or pw.flag != 1)


	DECLARE @newPwIds TABLE (Id INT, ReservationId INT, DeliveryId INT)
	--Dodanie PW dla rezerwacji ze wskazaniem dostaw
	INSERT INTO [HM].[PW] (flag, subtyp, typ, idmg, iddw, idtw, ilosc, wartosc, ilosczreal, data)
	OUTPUT inserted.id, inserted.idmg, inserted.iddw INTO @newPwIds
	SELECT DISTINCT IIF((dw.flag & 0x01 != 0), 0x04, 0), 0, 26, tblRZ.Id, tblRZD.DeliveryId, tblDP.ProductId, 0, 0, 0, @docDate 
	FROM @tblPositionsReservationsDelivery tblRZD
		JOIN @tblPositionsReservations tblRZ ON tblRZ.PositionId = tblRZD.PositionId AND tblRZ.InventoryId = tblRZD.InventoryId
		JOIN @tblDocumentPositions tblDP ON tblDP.Id = tblRZD.PositionId
		JOIN HM.DW dw ON dw.id = tblRZD.DeliveryId
	WHERE tblRZD.Id = 0 AND tblRZD.ReservedQuantity > 0

	--aktualizacja nowych identyfikatorów
	UPDATE tblRZD SET id = newPW.Id
	FROM @tblPositionsReservationsDelivery tblRZD
		JOIN @tblPositionsReservations tblRZ ON tblRZ.PositionId = tblRZD.PositionId AND tblRZ.InventoryId = tblRZD.InventoryId
		JOIN @newPwIds newPW ON newPW.ReservationId = tblRZ.Id AND newPW.DeliveryId = tblRZD.DeliveryId
	WHERE tblRZD.Id = 0


	--Aktualizacja PW dla rezerwacji ze wskazaniem dostaw
	UPDATE pw SET 
		ilosc = IIF(tblRZD.ReservedQuantity - pw.ilosc < dw.iloscdosp, tblRZD.ReservedQuantity, pw.ilosc + dw.iloscdosp),
		--flag = 0, 
		iddw = tblRZD.DeliveryId
	FROM HM.PW pw 
		JOIN @tblPositionsReservationsDelivery tblRZD ON tblRZD.Id = pw.id
		JOIN HM.DW dw ON dw.id = tblRZD.DeliveryId


	--aktualizacja wartości PW dla rezerwacji ze wskazaniem dostaw
	UPDATE [HM].[PW] SET 
		wartosc = CASE WHEN dw.iloscdosp = pw.ilosc or dw.iloscdosp = 0 
				THEN wartosc + dw.wartoscdosp 
				ELSE HM.ROUND2((dw.wartoscdosp / dw.iloscdosp) * pw.ilosc) END
	FROM HM.PW pw 
		JOIN @tblPositionsReservationsDelivery tblRZD ON tblRZD.Id = pw.id
		JOIN HM.DW dw ON dw.id = tblRZD.DeliveryId

	-- aktualizacja cen rezerwacji RZ dla rezerwacji ze wskazaniem dostaw
	UPDATE rz SET 
		rz.wartosc = sumPW.wartosc
	FROM HM.RZ rz
		JOIN @tblPositionsReservations tblRZ ON tblRZ.Id = rz.id
		JOIN (SELECT pw.idmg AS ReservationId, SUM(pw.wartosc) AS wartosc 
				FROM HM.PW pw 
				WHERE pw.typ = 26 GROUP BY pw.idmg ) sumPW ON sumPW.ReservationId = tblRz.Id
	WHERE rz.wartosc != sumPW.wartosc


	IF @correction = 0
	BEGIN
		--Aktualizacja typu pozycji			
		IF (@docType = 0)
		BEGIN
			UPDATE [HM].[DP] SET
				typ = dp.typ | IIF(dp.[typ] & 0x08 = 0,0,IIF(dp.ilosc > ISNULL(R.[iloscrz],0),0x40,0))
			FROM [HM].[DP] dp
			JOIN @tblDocumentPositions tblDP ON tblDP.Id = dp.id
			LEFT JOIN HM.RZ R ON dp.id = R.idpozrz AND R.bazapozrz = @bazaPozRZ
			WHERE (dp.flag & 0x0200 <> 0)					
		END
		ELSE IF (@docType = 1)
		BEGIN
			UPDATE [HM].[ZP] SET
				typ = zp.typ | IIF(zp.[typ] & 0x08 = 0,0,IIF(zp.ilosc > ISNULL(R.[iloscrz],0),0x40,0))
			FROM [HM].[ZP] zp
			JOIN @tblDocumentPositions tblDP ON tblDP.Id = zp.id
			LEFT JOIN HM.RZ R ON zp.id = R.idpozrz AND R.bazapozrz = @bazaPozRZ
			WHERE (zp.flag & 0x0200 <> 0)					
		END
		ELSE IF (@docType = 2)
		BEGIN
			UPDATE [HM].[MZ] SET
				typ = mz.typ | IIF(mz.[typ] & 0x08 = 0,0,IIF(mz.ilosc > ISNULL(R.[iloscrz],0),0x40,0))
			FROM [HM].[MZ] mz
			JOIN @tblDocumentPositions tblDP ON tblDP.Id = mz.id
			LEFT JOIN HM.RZ R ON mz.id = R.idpozrz AND R.bazapozrz = @bazaPozRZ
			WHERE (mz.flag & 0x0200 <> 0)					
		END
	END
												
	IF @anyOrderRelatedDocuments = 1
	BEGIN /* Obsługa rezerwacji powiązanych z zamówieniem */	

		UPDATE HM.RZ SET rz.iloscrz = tds.QuantitySum
		FROM HM.RZ rz
		INNER JOIN 
			(
				SELECT ReservationId, SUM(Quantity) as QuantitySum
				FROM @tblDeliverySettlements 
				GROUP BY ReservationId
			) tds ON rz.id = tds.ReservationId
		WHERE rz.iloscrz != tds.QuantitySum

		UPDATE HM.PW SET pw.ilosc = tds.Quantity
		FROM HM.PW pw
		JOIN @tblDeliverySettlements tds ON pw.id = tds.DeliverySettlementId	
		WHERE pw.ilosc != tds.Quantity

		--Uzupełnienie ilości zrealizowanych dla dokumentu sprzedaży
		UPDATE @tblDeliverySettlements SET DeliveryMaxQuantity = DeliveryMaxQuantity * -1
		WHERE DeliveryMaxQuantity < 0

		UPDATE HM.RZ SET rz.iloscrl = IIF(rz.iloscrz > tds.MaxQuantity, tds.MaxQuantity,rz.iloscrz)
		FROM HM.RZ rz
		JOIN HM.ZZ zz ON rz.id = zz.id2 and zz.typ = 96 and zz.baza1 = 152
		JOIN @tblDeliverySettlements tds ON tds.ReservationId = zz.id1
		WHERE rz.iloscrl != IIF(rz.iloscrz > tds.MaxQuantity, tds.MaxQuantity,rz.iloscrz)

		UPDATE HM.PW SET pw.ilosczreal = IIF(pw.ilosc > tds.DeliveryMaxQuantity, tds.DeliveryMaxQuantity,pw.ilosc)
		FROM HM.PW pw
		JOIN HM.ZZ zz ON pw.id = zz.id2 and zz.typ = 96 and zz.baza1 = 36
		JOIN @tblDeliverySettlements tds ON tds.DeliverySettlementId = zz.id1 
		WHERE pw.ilosczreal != IIF(pw.ilosc > tds.DeliveryMaxQuantity, tds.DeliveryMaxQuantity,pw.ilosc)

		--uzupełnienie poprawne powiązań zamówień
		UPDATE HM.ZZ SET zz.ilosc = ISNULL(tds.RealizationQuantity,0)
		FROM HM.ZZ zz 
		JOIN @tblDeliverySettlements tds ON tds.ReservationId = zz.id1 and zz.typ = 96 and zz.baza1 = 152
		JOIN HM.RZ rz ON rz.id = zz.id2 
		WHERE zz.ilosc != ISNULL(tds.RealizationQuantity,0)

		UPDATE HM.ZZ SET zz.ilosc = ISNULL(tds.RealizationQuantity,0)
		FROM HM.ZZ zz 
		JOIN @tblDeliverySettlements tds ON tds.DeliverySettlementId = zz.id1 and zz.typ = 96 and zz.baza1 = 36
		LEFT JOIN HM.PW pw ON pw.id = zz.id2 
		WHERE zz.ilosc != ISNULL(tds.RealizationQuantity,0)
				
	END

	--Aktualizacja stanu handlowego w dostawach wartościowych (na podstawie sumy z PW)
	UPDATE DW SET dw.iloscdosp = dw.stan - ISNULL(sumPW.ilosc, 0),
				  dw.wartoscdosp = dw.wartoscst - ISNULL(sumPW.wartosc, 0)
	FROM HM.DW dw
		JOIN @dwToUpdate dwToUpdate ON dwToUpdate.Id = dw.id
		LEFT JOIN (SELECT pw.iddw, SUM(HM.ROUND4(pw.ilosc)) AS ilosc, SUM(HM.ROUND2(pw.wartosc)) AS wartosc 
					FROM HM.PW pw WHERE pw.typ = 26 GROUP BY pw.iddw) AS sumPW ON sumPW.iddw = dw.id



	--Aktualizacja stanu handlowego, na podstawie sumy rezerwacji
	UPDATE [HM].[SM] SET 
		stanHandl =  SM.stan - pom.Ilosc
	FROM (
		SELECT SM.id, ISNULL(sumRZ.iloscrz, 0) AS ilosc
		FROM HM.SM SM
			JOIN (SELECT DISTINCT ProductId, InventoryId FROM @smToUpdate) smToUpdate 
				ON smToUpdate.InventoryId = SM.magazyn AND smToUpdate.ProductId = SM.idtw
			LEFT JOIN (SELECT SUM(HM.ROUND4(iloscrz)) AS iloscrz, idtw, magazyn 
				FROM HM.RZ 
				GROUP BY RZ.idtw, RZ.magazyn) sumRZ ON sumRZ.idtw = SM.idtw AND sumRZ.magazyn = SM.magazyn
		) pom
	WHERE sm.Id = pom.Id and sm.stanHandl <> (SM.stan - pom.Ilosc)
		
END
