IF EXISTS (SELECT * FROM sys.objects WHERE [type] IN (N'P', N'PC') AND OBJECT_ID = OBJECT_ID(N'[HM].[UpdateSaleDocumentFromXML]'))
DROP PROCEDURE [HM].[UpdateSaleDocumentFromXML];
GO

CREATE PROCEDURE [HM].[UpdateSaleDocumentFromXML] (@docData XML, @userId int, @moduleCode nvarchar(255), @warehouseId INT)
AS
BEGIN
	SET NOCOUNT ON; -- Stops the message that shows the count of the number of rows affected by a Transact-SQL statement or stored procedure from being returned as part of the result set.
	SET XACT_ABORT ON; -- Specifies whether SQL Server automatically rolls back the current transaction when a Transact-SQL statement raises a run-time error.
	
	BEGIN TRY
		BEGIN TRANSACTION;
			-- Tabela tymczasowa na dane dokumentu sprzedażowego
			DECLARE @tblSaleDocument TABLE
			(
				[Id] INT,
				[Guid] UNIQUEIDENTIFIER,
				[DocumentNumber] VARCHAR(40),
				[Name] VARCHAR(40),
				[IssueDate] DATETIME,
				[OperationDate] DATETIME,
				[Description] VARCHAR(80),
				[CorrectionCause] VARCHAR(80),
				[RecipientPerson] VARCHAR(40),
				[BaseType] SMALLINT,
				[DocumentTypeShortcut] VARCHAR(4),
				[DocumentNumerationShortcut] VARCHAR(5),
				[SeriesNo] INT,
				[KindId] INT,
				[CatalogId] INT,
				[Marker] SMALLINT,
				[IsIssued] BIT,
				[DocumentStatus] SMALLINT,
				[DocumentStatusDescription] VARCHAR(40),
				[HmImported] BIT,
				[Archived] BIT,
				[FkExported] BIT,
				[ForeignOrder] BIT,
				[Canceled] SMALLINT,
				[IsActive] BIT,
				[MigrationStatus] SMALLINT,
				[ContractorId] INT,
				[AccountingPattern] VARCHAR(4),
				[IssuerId] INT,
				[ReceiverId] INT,
				[DepartmentId] INT,
				[PayRegistryId] INT,
				[PaymentFormClientId] INT,
				[PaymentDeadline] DATETIME,
				[Value] DECIMAL(24,2),
				[ValueVat] DECIMAL(24,2),
				[ValueGross] DECIMAL(24,2),
				[ValuePLN] DECIMAL(24,2),
				[ValueVatPLN] DECIMAL(24,2),
				[ValueGrossPLN] DECIMAL(24,2),
				[PriceKind] SMALLINT,
				[Currency] VARCHAR(3),	
				[ExchangeRate] DECIMAL(24,8),
				[ExchangeRatePIT] DECIMAL(24,8),
				[CalculateVatMethod] SMALLINT,
				[InventorySettlementStatus] INT,
				[NoticeText] NVARCHAR(MAX),
				[PriceTypeId] INT,
				[Discount] DECIMAL(24,2),
				[ReservationType] SMALLINT,
				[FiscalizationState] SMALLINT,
				[PublishInventoryDocumentMode] SMALLINT,
				ReceiptNumber VARCHAR(40),
				UniqueCashBoxNumber VARCHAR(40),
				[JPK_V7] VARCHAR(256),
				[JPK] SMALLINT,
				[SplitPayment] BIT,
				[InRegisterDate] DATETIME,
				[SaleRegister] INT,
				[RegisterMethod] SMALLINT,
				[CashSettled] SMALLINT,
				[DepartmentInSeries] INTEGER,
				[Period] SMALLINT,
				[CorrectedDocumentId] INTEGER,
				[IsGroupCorrection] BIT
			)
			-- Tabela tymczasowa na dane pozycji dokumentu sprzedażowego
			DECLARE @tblDocumentPositions TABLE
			(
				[Id] INT,
				[Compensation] SMALLINT,
				[NodeId] INT,
				[ParentId] INT,
				[OrdinalNumber] SMALLINT,
				[Guid] UNIQUEIDENTIFIER,
				[ProductId] INT,
				[ProductShortcut] VARCHAR(40),
				[Description] VARCHAR(max),
				[UnitOfMeasurement] VARCHAR(8),
				[EvidenceUnitOfMeasurement] VARCHAR(8),
				[Quantity] DECIMAL(24,4),
				[UnitQuantity] DECIMAL(24,4),
				[EvidenceQuantity] DECIMAL(24,4),
				[ReservationType] SMALLINT,
				[AccountingPattern] VARCHAR(4),
				[VatRateId] INT,
				[Price] DECIMAL(35,15),
				[PriceGross] DECIMAL(35,15),
				[Value] DECIMAL(24,2),
				[ValueVat] DECIMAL(24,2),
				[ValueGross] DECIMAL(24,2),
				[ValuePLN] DECIMAL(24,2),
				[ValueVatPLN] DECIMAL(24,2),
				[ValueGrossPLN] DECIMAL(24,2),
				[PriceTypeId] SMALLINT,
				[PriceListPrice] DECIMAL(35,15),
				[PriceListPriceGross] DECIMAL(35,15),
				[JPK_V7] VARCHAR(10),
				[CN] VARCHAR(10),
				[CodePKWIU] VARCHAR(20),
				[VatRegister] INT,
				[CorrectedPositionId] INT,
				[IsNewCorrectPosition] BIT,
				[IsSet] BIT,
				[IsElementOfSet] BIT,
				[NoEditOfSet] BIT,
				[PriceOfSetCalculatedBasedOfElements] BIT,
				[VatUE] BIT,
				[ServiceExport] BIT,
				[DomesticVatRateId] INT,
				[OriginalPriceListPrice] DECIMAL(35,15),
				[OriginalPriceListPriceCurrency] VARCHAR(3),
				[OriginalBasePrice] DECIMAL(35,15),
				[OriginalBasePriceCurrency] VARCHAR(3),
				[BasePricePLN] DECIMAL(35,15),
				[CorrectedDocumentId] INT,
				[OO] BIT,
				[ServiceExpense] DECIMAL(35,15),
				[IsService] BIT
			)

			DECLARE  @tblRelatedDocuments TABLE
			(
				[Id] INT,
				[DocumentType] NVARCHAR(100),
				[Number] NVARCHAR(100),
				[CharacterId] INT,
				[InBuffer] BIT
			)

			-- Przygotowanie xml
			DECLARE @handle INT, @prepareXmlStatus INT, @shortDescriptionLength INT = 40
			EXEC @prepareXmlStatus = sp_xml_preparedocument @handle OUTPUT, @docData
			
			-- Deserializacja danych dokumentu sprzedażowego z xml
			INSERT INTO @tblSaleDocument
			SELECT 
					[Id],
					CASE WHEN [Guid] IS NULL OR [Guid] = '' OR [Guid] = '00000000-0000-0000-0000-000000000000' THEN NEWID() ELSE [GUID] END,
					[DocumentNumber],
					[Name],
					IIF(CAST([IssueDate] AS DATETIME2) = CAST('' AS DATETIME2), NULL, CAST([IssueDate] AS DATETIME2)),					
					IIF(CAST([OperationDate] AS DATETIME2) = CAST('' AS DATETIME2), NULL, CAST([OperationDate] AS DATETIME2)),	
					[Description],
					[CorrectionCause],
					[RecipientPerson],
					[BaseType],
					[DocumentTypeShortcut],
					[DocumentNumerationShortcut],
					[SeriesNo],
					[KindId],
					[CatalogId],
					[Marker],
					[IsIssued],
					[DocumentStatus],
					[DocumentStatusDescription],
					[HmImported],
					[Archived],
					[FkExported],
					[ForeignOrder],
					[Canceled],
					[IsActive],
					[MigrationStatus],
					[ContractorId],
					[AccountingPattern],
					[IssuerId],
					[ReceiverId],
					[DepartmentId],
					IIF([PayRegistryId] = -1, NULL, [PayRegistryId]),
					[PaymentFormClientId],
					IIF(CAST([PaymentDeadline] AS DATETIME2) = CAST('' AS DATETIME2), NULL, CAST([PaymentDeadline] AS DATETIME2)),
					[Value],
					[ValueVat],
					[ValueGross],
					[ValuePLN],
					[ValueVatPLN],
					[ValueGrossPLN],
					[PriceKind],
					[Currency],	
					--domyślnie ustawiamy 1 - wsteczna kompatybilność
					CASE WHEN 0 = ISNUMERIC([ExchangeRate]) THEN 1 ELSE CAST([ExchangeRate] AS DECIMAL(24,8)) END,
					CASE WHEN 0 = ISNUMERIC([ExchangeRatePIT]) THEN 1 ELSE CAST([ExchangeRatePIT] AS DECIMAL(24,8)) END,
					[CalculateVatMethod],
					[InventorySettlementStatus],
					[NoticeText],
					[PriceTypeId],
					[Discount],
					[ReservationType],
					[FiscalizationState],
					[PublishInventoryDocumentMode],
					ReceiptNumber,
					UniqueCashBoxNumber,
					[JPK_V7],
					[JPK],
					[SplitPayment],
					IIF(CAST([InRegisterDate] AS DATETIME2) = CAST('' AS DATETIME2), NULL, CAST([InRegisterDate] AS DATETIME2)),
					[SaleRegister],
					[RegisterMethod],
					[CashSettled],
					[DepartmentInSeries],
					[Period],
					IIF([CorrectedDocumentId] = 0, NULL, [CorrectedDocumentId]),
					[IsGroupCorrection]
			FROM 
				OPENXML(@handle, '/SaleDocument')
				WITH
				(
					[Id] INT 'Id',
					[Guid] NVARCHAR(36) 'Guid',
					[DocumentNumber] VARCHAR(40) 'DocumentNumber',
					[Name] VARCHAR(40) 'Name',
					[IssueDate] NVARCHAR(100) 'IssueDate',
					[OperationDate] NVARCHAR(100) 'OperationDate',
					[Description] VARCHAR(80) 'Description',
					[CorrectionCause] VARCHAR(80) 'CorrectionCause',
					[RecipientPerson] VARCHAR(40) 'RecipientPerson',
					[BaseType] SMALLINT 'BaseType',
					[DocumentTypeShortcut] VARCHAR(4) 'DocumentTypeShortcut',
					[DocumentNumerationShortcut] VARCHAR(5) 'DocumentNumerationShortcut',
					[SeriesNo] VARCHAR(5) 'SeriesNo',
					[KindId] INT 'KindId',
					[CatalogId] INT 'CatalogId',
					[Marker] SMALLINT 'Marker',
					[IsIssued] BIT 'IsIssued',
					[DocumentStatus] SMALLINT 'DocumentStatus',
					[DocumentStatusDescription] VARCHAR(40) 'DocumentStatusDescription',
					[HmImported] BIT 'HmImported',
					[Archived] BIT 'Archived',
					[FkExported] BIT 'FkExported',
					[ForeignOrder] BIT 'ForeignOrder',
					[Canceled] BIT 'Canceled',
					[IsActive] BIT 'IsActive',
					[MigrationStatus] SMALLINT 'MigrationStatus',
					[ContractorId] INT 'ContractorId',
					[AccountingPattern] VARCHAR(4) 'AccountingPattern',
					[IssuerId] INT 'IssuerId',
					[ReceiverId] INT 'ReceiverId',
					[DepartmentId] INT 'DepartmentId',
					[PayRegistryId] INT 'PayRegistryId',
					[PaymentFormClientId] INT 'PaymentFormClientId',
					[PaymentDeadline] NVARCHAR(100) 'PaymentDeadline',
					[Value] DECIMAL(24,2) 'Value',
					[ValueVat] DECIMAL(24,2) 'ValueVat',
					[ValueGross] DECIMAL(24,2) 'ValueGross',
					[ValuePLN] DECIMAL(24,2) 'ValuePLN',
					[ValueVatPLN] DECIMAL(24,2) 'ValueVatPLN',
					[ValueGrossPLN] DECIMAL(24,2) 'ValueGrossPLN',
					[PriceKind] SMALLINT 'PriceKind',
					[Currency] VARCHAR(3) 'Currency',	
					[ExchangeRate] NVARCHAR(20) 'ExchangeRate',
					[ExchangeRatePIT] NVARCHAR(20) 'ExchangeRatePIT',
					[CalculateVatMethod] SMALLINT 'CalculateVatMethod',
					[InventorySettlementStatus] INT 'InventorySettlementStatus',
					[NoticeText] NVARCHAR(MAX) 'NoticeText',
					[PriceTypeId] INT 'PriceTypeId',
					[Discount] DECIMAL(24,2) 'Discount',
					[ReservationType] SMALLINT 'ReservationType',
					[FiscalizationState] SMALLINT 'FiscalizationState',
					[PublishInventoryDocumentMode] SMALLINT 'PublishInventoryDocumentMode',					
					ReceiptNumber VARCHAR(40) 'ReceiptNumber',
					UniqueCashBoxNumber VARCHAR(40) 'UniqueCashBoxNumber',
					[JPK_V7] VARCHAR(256) 'JPK_V7',
					[JPK] SMALLINT 'JPK',
					[SplitPayment] BIT 'SplitPayment',
					[InRegisterDate] NVARCHAR(100) 'InRegisterDate',
					[SaleRegister] INT 'SaleRegister',
					[RegisterMethod] SMALLINT 'RegisterMethod',
					[CashSettled] SMALLINT 'CashSettled',
					[DepartmentInSeries] INTEGER 'DepartmentInSeries',
					[Period] SMALLINT 'Period',
					[CorrectedDocumentId] INT 'CorrectedDocumentId',
					[IsGroupCorrection] BIT 'IsGroupCorrection'
				)	

			DECLARE @isIssued BIT 
			SELECT @isIssued = IsIssued FROM @tblSaleDocument

			IF @isIssued = 1
			BEGIN	--nie robimy nic, zwracamy tego samego XML-a który przyszedł do procedury 
				ROLLBACK TRANSACTION
				SELECT @docData
				RETURN
			END

			-- Pobranie identyfikatora i numeru dokumentu sprzedażowego
			DECLARE @docId INT,
					@docNumber VARCHAR(40),
					@department INT,
					@issueDate DATETIME,
					@saleRegister INT,
					@foreignOrder BIT,
					@isBufor SMALLINT
			SELECT @docId = [Id], @docNumber = [DocumentNumber], @department = [DepartmentId], @issueDate = [IssueDate], @saleRegister = [SaleRegister], @foreignOrder = [ForeignOrder]
			FROM @tblSaleDocument

			IF IsNull(@docId, 0) != 0
			BEGIN
				SELECT @isBufor = bufor FROM HM.DK WHERE id = @docId
				IF @isBufor = 0
				BEGIN	--nie robimy nic 
					ROLLBACK TRANSACTION
					EXEC [HM].[ReadSaleDocumentAsXML] @docId, @userId, @moduleCode
					RETURN
				END
			END

			DECLARE @correction BIT
			SELECT @correction = COUNT(Id) FROM @tblSaleDocument WHERE ISNULL(CorrectedDocumentId, 0) > 0 OR IsGroupCorrection = 1
				
			-- dokument i pozycje w cenie netto / brutto
			DECLARE @IsNet SMALLINT
			SELECT @IsNet = CASE WHEN [PriceKind] = 2 THEN 1 ELSE 0 END FROM @tblSaleDocument

			DECLARE @ExchangeRate FLOAT
			SELECT @ExchangeRate = [ExchangeRate] FROM @tblSaleDocument

			-- Deserializacja danych pozycji dokumentu sprzedażowego z xml
			INSERT INTO @tblDocumentPositions
			SELECT 
					[Id],		
					[Compensation],
					[NodeId],
					[ParentId],
					[OrdinalNumber],
					CASE WHEN [Guid] IS NULL OR [Guid] = '' OR [Guid] = '00000000-0000-0000-0000-000000000000' THEN NEWID() ELSE [GUID] END,
					[ProductId],
					[ProductShortcut],
					[Description],
					[UnitOfMeasurement],
					[EvidenceUnitOfMeasurement],
					CASE WHEN 0 = ISNUMERIC([Quantity]) THEN 0.0000 ELSE CAST([Quantity] AS DECIMAL(24, 4)) END AS [Quantity],
					CASE WHEN 0 = ISNUMERIC([UnitQuantity]) THEN 0.0000 ELSE CAST([UnitQuantity] AS DECIMAL(24, 4)) END AS [UnitQuantity],
					CASE WHEN 0 = ISNUMERIC([EvidenceQuantity]) THEN 0.0000 ELSE CAST([EvidenceQuantity] AS DECIMAL(24, 4)) END AS [EvidenceQuantity],
					[ReservationType],
					[AccountingPattern],
					[VatRateId],
					CASE WHEN 0 = ISNUMERIC([Price]) THEN 0.0000 ELSE CAST([Price] AS DECIMAL(35,15)) END AS [Price],
					CASE WHEN 0 = ISNUMERIC([PriceGross]) THEN 0.0000 ELSE CAST([PriceGross] AS DECIMAL(35,15)) END AS [PriceGross],
					CASE WHEN 0 = ISNUMERIC([Value]) THEN 0.00 ELSE CAST([Value] AS DECIMAL(24, 2)) END AS [Value],
					CASE WHEN 0 = ISNUMERIC([ValueVat]) THEN 0.00 ELSE CAST([ValueVat] AS DECIMAL(24, 2)) END AS [ValueVat],
					CASE WHEN 0 = ISNUMERIC([ValueGross]) THEN 0.00 ELSE CAST([ValueGross] AS DECIMAL(24, 2)) END AS [ValueGross],
					CASE WHEN 0 = ISNUMERIC([ValuePLN]) THEN 0.00 ELSE CAST([ValuePLN] AS DECIMAL(24, 2)) END AS [ValuePLN],
					CASE WHEN 0 = ISNUMERIC([ValueVatPLN]) THEN 0.00 ELSE CAST([ValueVatPLN] AS DECIMAL(24, 2)) END AS [ValueVatPLN],
					CASE WHEN 0 = ISNUMERIC([ValueGrossPLN]) THEN 0.00 ELSE CAST([ValueGrossPLN] AS DECIMAL(24, 2)) END AS [ValueGrossPLN],
					[PriceTypeId],
					CASE WHEN 0 = ISNUMERIC([PriceListPrice]) THEN 0.0000 ELSE CAST([PriceListPrice] AS DECIMAL(35,15)) END AS [PriceListPrice],
					CASE WHEN 0 = ISNUMERIC([PriceListPriceGross]) THEN 0.0000 ELSE CAST([PriceListPriceGross] AS DECIMAL(35,15)) END AS [PriceListPriceGross],
					[JPK_V7],
					[CN],
					[CodePKWIU],
					[VatRegister],
					IIF(CorrectedPositionId = 0, NULL, CorrectedPositionId),
					[IsNewCorrectPosition],
					[IsSet],
					[IsElementofSet],
					[NoEditOfSet],
					[PriceOfSetCalculatedBasedOfElements],
					[VatUE],
				    [ServiceExport],
					[DomesticVatRateId],
					CASE WHEN 0 = ISNUMERIC([OriginalPriceListPrice]) THEN 0.0000 ELSE CAST([OriginalPriceListPrice] AS DECIMAL(35,15)) END AS [OriginalPriceListPrice],
					[OriginalPriceListPriceCurrency],
					CASE WHEN 0 = ISNUMERIC([OriginalBasePrice]) THEN 0.0000 ELSE CAST([OriginalBasePrice] AS DECIMAL(35,15)) END AS [OriginalBasePrice],
					[OriginalBasePriceCurrency],
					CASE WHEN 0 = ISNUMERIC([BasePricePLN]) THEN 0.0000 ELSE CAST([BasePricePLN] AS DECIMAL(35,15)) END AS [BasePricePLN],
					[CorrectedDocumentId],
					[OO],
					CASE WHEN 0 = ISNUMERIC([ServiceExpense]) THEN 0.0000 ELSE CAST([ServiceExpense] AS DECIMAL(35,15)) END AS [ServiceExpense],
					[IsService]
			FROM 
				OPENXML(@handle, '/SaleDocument/DocumentPositions/SalePosition')
				WITH
				(
					[Id] INT 'Id',	
					[Compensation] SMALLINT 'Compensation',
					[NodeId] INT 'NodeId',
					[ParentId] INT 'ParentId',
					[OrdinalNumber] SMALLINT 'OrdinalNumber',
					[Guid] NVARCHAR(36) 'Guid',
					[ProductId] INT 'ProductId',
					[ProductShortcut] VARCHAR(40) 'ProductShortcut',
					[Description] VARCHAR(max) 'Description',
					[UnitOfMeasurement] VARCHAR(8) 'UnitOfMeasurement',
					[EvidenceUnitOfMeasurement] VARCHAR(8) 'EvidenceUnitOfMeasurement',
					[Quantity] VARCHAR(24) 'Quantity',
					[UnitQuantity] VARCHAR(24) 'UnitQuantity',
					[EvidenceQuantity] VARCHAR(24) 'EvidenceQuantity',
					[ReservationType] SMALLINT 'ReservationType',
					[AccountingPattern] VARCHAR(4) 'AccountingPattern',
					[VatRateId] INT 'VatRateId',
					[Price] VARCHAR(36) 'Price',
					[PriceGross] VARCHAR(36) 'PriceGross',
					[Value] VARCHAR(24) 'Value',
					[ValueVat] VARCHAR(24) 'ValueVat',
					[ValueGross] VARCHAR(24) 'ValueGross',
					[ValuePLN] VARCHAR(24) 'ValuePLN',
					[ValueVatPLN] VARCHAR(24) 'ValueVatPLN',
					[ValueGrossPLN] VARCHAR(24) 'ValueGrossPLN',
					[PriceTypeId] SMALLINT 'PriceTypeId',
					[PriceListPrice] VARCHAR(36) 'PriceListPrice',
					[PriceListPriceGross] VARCHAR(36) 'PriceListPriceGross',
					[JPK_V7] VARCHAR(10) 'JPK_V7',
					[CN] VARCHAR(10) 'CN',
					[CodePKWIU] VARCHAR(40) 'CodePKWIU',
					[VatRegister] INT 'VatRegister',
					CorrectedPositionId INT 'CorrectedPositionId',
					[IsNewCorrectPosition] BIT 'IsNewCorrectPosition',
					[IsSet] BIT 'IsSet',
					[IsElementOfSet] BIT 'IsElementOfSet',
					[NoEditOfSet] BIT 'NoEditOfSet',
					[PriceOfSetCalculatedBasedOfElements] BIT 'PriceOfSetCalculatedBasedOfElements',
					[VatUE] BIT 'VatUE',
					[ServiceExport] BIT 'ServiceExport',
					[DomesticVatRateId] INT 'DomesticVatRateId',
					[OriginalPriceListPrice] VARCHAR(36) 'OriginalPriceListPrice',
					[OriginalPriceListPriceCurrency] VARCHAR(3) 'OriginalPriceListPriceCurrency',
					[OriginalBasePrice] VARCHAR(35) 'OriginalBasePrice',
					[OriginalBasePriceCurrency] VARCHAR(3) 'OriginalBasePriceCurrency',
					[BasePricePLN] VARCHAR(35) 'BasePricePLN',
					[CorrectedDocumentId] INT 'CorrectedDocumentId',
					[OO] BIT 'OO',
					[ServiceExpense] VARCHAR(24) 'ServiceExpense',
					[IsService] BIT 'IsService'
				)		


			IF @correction <> 0
			BEGIN
				-- XML korekty zawiera wszystkie pozycje, takze niekorygowane ktorych dalej nie uwzgledniamy
				DELETE
					FROM @tblDocumentPositions
					WHERE Compensation = 0 AND ISNULL(CorrectedPositionId, 0) = 0 AND IsNewCorrectPosition <> 'true'

				UPDATE @tblDocumentPositions
					SET EvidenceQuantity = -EvidenceQuantity, ValuePLN = -ValuePLN, ValueVatPLN = -ValueVatPLN, Quantity = -Quantity,
						Value = -Value, ValueGross = -ValueGross
					WHERE Compensation <> 0
			END

			--odczyt parametru pracy
			DECLARE @IsShownOnSaleStatementWorkingParameter BIT = ISNULL((
									SELECT IIF(cena = 1, 1, 0) 
									FROM [HM].ZZ 
									WHERE typ = 32 AND baza1 = 20 AND id1 = 1 AND baza2 = 6 AND id2 = 1184), 1)

			DECLARE @CalculateVatMethod INT = (SELECT [CalculateVatMethod] FROM @tblSaleDocument)

			-- dane dla tabeli pozycji, zgodne z formatem DP
			DECLARE @valuesForDP TABLE (NodeId INT, flag SMALLINT, typ SMALLINT, cenabaztow FLOAT, walcenybaz VARCHAR(3), zyskdod FLOAT, wartstvat SMALLINT, 
				koszt FLOAT, iloscRLKS FLOAT, wartTowaru FLOAT)

			INSERT INTO @valuesForDP
			SELECT	position.NodeId, 

					CONVERT(SMALLINT, 
						IIF(@CalculateVatMethod = 1, CAST(0x8000 AS SMALLINT), 0) |		-- sumacyjny vat
						IIF(product.[subtyp] = 0, 0x0200, 0) |			-- pozycja towarowa
						IIF(position.[IsElementOfSet] = 1, 0x4000, 0) |	-- elementu kompletu
						IIF(position.[IsSet] = 1, 0x1000, 0) |			-- nagłówek kompletu
						IIF(position.[NoEditOfSet] = 1, 0x0800, 0)		-- nagłówek lub element kompletu nieedycyjnego
					) AS [flag],

					IIF(position.VatUE = 1,0x0200,0) | IIF(position.ServiceExport = 1,0x0100,0) |
					CASE --pierszy bit (0x01) mówiący o tym czy pozycja wchodzi na zestawienia czy nie, zależy to od ustawienia w definicji kompletu lub od parametru pracy
						WHEN position.IsSet = 1 THEN IIF(product.Id IS NOT NULL, [HM].fnIsFlagSet(product.flag, 0x2000), @IsShownOnSaleStatementWorkingParameter)
						WHEN position.IsElementOfSet = 1 THEN IIF(prodSetForElement.Id IS NOT NULL, ~[HM].fnIsFlagSet(prodSetForElement.flag, 0x2000), ~@IsShownOnSaleStatementWorkingParameter)
						ELSE 0 
					END	AS [typ],

					CASE 
						WHEN position.IsSet = 1 AND position.PriceOfSetCalculatedBasedOfElements = 1 THEN 0
						ELSE CAST(position.[OriginalBasePrice] AS FLOAT)
					END AS [cenabaztow],

					CASE 
						WHEN position.IsSet = 1 AND position.PriceOfSetCalculatedBasedOfElements = 1 THEN ''
						ELSE position.[OriginalBasePriceCurrency]
					END AS [walcenybaz],

					CASE 
						WHEN position.IsSet = 1 AND position.PriceOfSetCalculatedBasedOfElements = 1 THEN 0
						ELSE CAST(position.[BasePricePLN] AS FLOAT)
					END AS [zyskdod],

					CAST(ISNULL(vatRate.wartosc, 0) * 10000 AS SMALLINT) AS [wartstvat],

					CAST(position.[ServiceExpense] AS FLOAT) AS [koszt],
					CAST(IIF(position.[IsService] = 1 OR ISNULL(product.[id],0) = 0,position.[EvidenceQuantity],0) AS FLOAT) AS [iloscRLKS],

					IIF(position.[IsService] = 1, HM.ROUND2(position.[EvidenceQuantity] * position.[BasePricePLN]), 0) AS [wartTowaru]

			FROM @tblDocumentPositions AS position
				LEFT JOIN @tblDocumentPositions AS posSetForElement ON position.IsElementOfSet = 1 AND posSetForElement.IsSet = 1 AND position.ParentId = posSetForElement.NodeId
				LEFT JOIN [HM].[TW] AS product ON product.Id = position.ProductId
				LEFT JOIN [HM].[TW] AS prodSetForElement ON prodSetForElement.Id = posSetForElement.ProductId
				LEFT JOIN [HM].[XT] AS vatRate ON vatRate.id = position.[VatRateId]


			-- Deserializacja danych dokumentów powiązannych z xml
			INSERT INTO @tblRelatedDocuments
			SELECT 
				[Id],
				[DocumentType],
				[Number],
				[CharacterId],
				[InBuffer]
			FROM 
				OPENXML(@handle, '/SaleDocument/RelatedDocuments/RelatedDocument')
				WITH
				(
					[Id] INT 'Id',
					[DocumentType] NVARCHAR(100) 'DocumentType',
					[Number] NVARCHAR(100) 'Number',
					[CharacterId] INT 'CharacterId',
					[InBuffer] BIT 'InBuffer'
				)


			DECLARE @ContractorId INT, 
					@ContractorAddressId INT = 0, 
					@ReceiverId INT,	
					@ReceiverAddressId INT = 0;

			-- Jeśli 0 to incydentalny - ustawiamy NULL
			SELECT @ContractorId = CASE WHEN [ContractorId] = 0 THEN NULL ELSE [ContractorId] END,
				   @ReceiverId = CASE WHEN [ReceiverId] = 0 THEN NULL ELSE [ReceiverId] END
			FROM @tblSaleDocument;
			-- Aktualizacja na NULL jeśli były 0
			UPDATE @tblSaleDocument
			SET [ContractorId] = @ContractorId, [ReceiverId] = @ReceiverId
			

			-- Zapis danych adresowych kontrahenta i odbiorcy
			EXEC [HM].[UpdateDocumentContractorAdressFromXML] @handle, @ContractorId, @ReceiverId, @ContractorAddressId OUT, @ReceiverAddressId OUT


			DECLARE @correctedDocsIds TABLE (Id INT)
			INSERT INTO @correctedDocsIds SELECT Id FROM HM.[GetDocumentsIdsForGroupCorrection](@docId)
			IF ((SELECT iddokkoryg FROM HM.DK WHERE id = @docId) IS NOT NULL)
				INSERT INTO @correctedDocsIds SELECT iddokkoryg FROM HM.DK WHERE id = @docId

			DECLARE @correctedOrDocId TABLE (Id INT) --jeśli jest jakiś dokument korygowany, to jego id, jeśli nie to docId
			IF NOT EXISTS (SELECT * FROM @correctedDocsIds)
			BEGIN
				INSERT INTO @correctedOrDocId SELECT @docId
			END
			ELSE
			BEGIN
				INSERT INTO @correctedOrDocId SELECT * FROM @correctedDocsIds
			END

			DECLARE @defaultVatRateId INT,
					@defaultVatRateValue FLOAT,
					@flag SMALLINT;
			SELECT TOP 1
					@defaultVatRateId = id,
					@defaultVatRateValue = wartosc
			FROM HM.XT
			WHERE wartosc = 0.23;
			
			-- Numer dokumentu
			--
			-- Jeśli brak dokumentu w bazie lub właśnie wystawiamy dokument przy automatycznym generowaniu numeracji to zawsze generuj serie i numer
			IF ISNULL(@docId, 0) = 0
				or 
				(
					exists(select 1 from hm.WorkParameters where id = 1070 and NumericValue = 1)
					and exists(select 1 from @tblSaleDocument t inner join hm.DK dk on dk.Id = t.Id and dk.bufor = 1 where t.IsIssued = 1)
				)
			BEGIN
				DECLARE 
					@id_dok INT,
					@DocumentTypeId INT,
					@DocumentNumerationCode VARCHAR(10),
					@genContractorId INT,
					@departmentId INT,
					@currency VARCHAR(3),
					@buffer BIT,
					@date DATE,
					@tableId SMALLINT,
					@code VARCHAR(40),
					@numberInSeries INT,
					@period INT,
					@departmentInSeries INT

				SELECT 
					@id_dok = Id,
					@DocumentTypeId = (select ID from hm.td where kod = DocumentTypeShortcut),
					@DocumentNumerationCode = DocumentNumerationShortcut,
					@UserId = @userId,
					@genContractorId = ContractorId,
					@DepartmentId = DepartmentId,
					@Currency = ISNULL(Currency, ''),
					@buffer = IIF(IsIssued = 1, 0, 1),
					@Date = IssueDate,
					@TableId = 16,
					@numberInSeries = 0
				FROM @tblSaleDocument

				EXEC [HM].[GenerateDocumentNumber]    
					@id_dok,
					@DocumentTypeId,
					@DocumentNumerationCode,
					@userId,
					@genContractorId,
					@departmentId,
					@currency,
					@buffer,
					@date,
					@tableId,    
					@code OUT,
					@numberInSeries OUT,
					@period OUT,
					@departmentInSeries OUT

				UPDATE @tblSaleDocument set
					DocumentNumber = ISNULL(IIF(@code = '@0', NULL, @code), NEWID()),
					SeriesNo = @numberInSeries,
					Period = @period,
					DepartmentInSeries = @departmentInSeries

				SET @docNumber = ISNULL(IIF(@code = '@0', NULL, @code), NEWID());

			end;

			DECLARE @shortcutMessage NVARCHAR(200) = CONCAT('Dokument sprzedaży o numerze "', @docNumber, '" istnieje w bazie danych.')
			IF EXISTS(SELECT * FROM [HM].[DK] dk WHERE dk.[kod] = @docNumber and Id <> @id_dok)
					THROW 50000, @shortcutMessage, 1;
			
			--Dokument z odwrotnym obciążeniem, jeśli jakaś pozycja ma zaznaczony ten znacznik
			DECLARE @oO BIT;
			IF EXISTS(SELECT * FROM @tblDocumentPositions WHERE OO = 1)
				SET @oO = 1
			ELSE
				SET @oO = 0

			-- Koniec Numeru dokumentu

			-- Tabela przechowująca id operacji pozycji zamówienia powiązane z operacjami pozycji dokumentu, 
			-- po usunięciu pozycji z dokumentu sprzedaży
			DECLARE @deleted_operations TABLE(id int);

			-- Wyciągnięcie informacji czy jest to nowy dokument sprzedażowy czy istniejący
			IF (@docId IS NULL OR @docId = 0)
			BEGIN
				-- Zapis nowego dokumentu
				INSERT INTO [HM].[DK]
				(
					[guid],
					[kod],
					[nazwa],
					[data],
					[datasp],
					[opis],
					[odebrane],
					[subtyp],
					[typ_dk],
					[seria],
					[serianr],
					[rodzaj],
					[katalog],
					[znacznik],
					[bufor],					
					[anulowany],
					[aktywny],
					[statusMig],
					[schemat],
					[wystawil],
					[khid],
					[odid],
					[khadid],
					[odadid],
					[magazyn],
					[plattyp],
					[formaplatn],
					[plattermin],
					[walNetto],
					[walBrutto],
					[netto],
					[vat],
					[grupacen],
					[waluta],
					[kurs],
					[kursDoch],				
					[typceny],
					paragon,
					fiscalDeviceNo,
					[rabat],
					[jpk_v7],
					[jpk],
					[flag],
					[typ],
					[info],
					[seriadzial],					
					[okres],					
					[ok],
					[rr],
					[wplaty],
					[wartoscSP],
					[exp_fk],
					[zyskdod],
					[kod_obcy],
					[rozlmg],
					[efaktura],
					[statusRdf],          
					[data_obcy],
					[koszt],
					[kosztaproksymowany],
					[statusfk],
					[splitPayment],
					[datarej],
					[rejestrVat],
					[dataZest1],
					[createdBy],
					[createdDate],
					[modifiedBy],
					[modifiedDate],
					[wartPrzychod]
				)
				SELECT					
					[Guid] AS [guid],
					[DocumentNumber] AS [kod],
					[Name] AS [nazwa],
					[IssueDate] AS [data],
					[OperationDate] AS [datasp],
					IIF([CorrectedDocumentId] IS NOT NULL, [CorrectionCause], [Description]) AS [opis], --dla korekty, jej przyczyna
					[RecipientPerson] AS [odebrane],
					(SELECT td.charakter FROM [HM].[TD] td WHERE td.[kod] = [DocumentTypeShortcut]) AS [subtyp],
					[DocumentTypeShortcut] AS [typ_dk],
					[DocumentNumerationShortcut] AS [seria],
					[SeriesNo] as serianr,
					[KindId] AS [rodzaj],
					[CatalogId] AS [katalog],
					[Marker] AS [znacznik],
					1^(CAST([IsIssued] as bit)) AS [bufor],
					[Canceled] AS [anulowany],
					1 AS [aktywny],
					[MigrationStatus] AS [statusMig],
					[AccountingPattern] AS [schemat],
					[IssuerId] AS [wystawil],
					[ContractorId] AS [khid],
					[ReceiverId] AS [odid],
					@ContractorAddressId AS [khadid],
					@ReceiverAddressId AS [odadid],
					[DepartmentId] AS [magazyn],
					[PayRegistryId] AS [plattyp],
					[PaymentFormClientId] AS [formaplatn],
					[PaymentDeadline] AS [plattermin],
					[Value] AS [walNetto],
					[ValueGross] AS [walBrutto],
					[ValuePLN] AS [netto],
					[ValueVatPLN] AS [vat],
					@IsNet AS [grupacen],
					[Currency] AS [waluta],
					[ExchangeRate] AS [kurs],
					[ExchangeRatePIT] AS [kursDoch],				
					[PriceTypeId] AS [typceny],
					CONVERT(INTEGER, ReceiptNumber) AS paragon,
					UniqueCashBoxNumber AS fiscalDeviceNo,
					[Discount] AS [rabat],					
					[JPK_V7] AS [jpk_v7],
					[JPK],
					(hm.SetFlag(0, 0x8000, CalculateVatMethod) | hm.SetFlag(0, 0x80, RegisterMethod - 1) | IIF(ForeignOrder = 'true', 0x1000, 0) | IIF(IsGroupCorrection = 'true', 0x20,0)) AS [flag],
					0 AS [typ],
					0 AS [info],
					[DepartmentInSeries] AS [seriadzial],
					[Period] AS [okres],
					[CashSettled] AS [ok],
					0 AS [rr],
					0 AS [wplaty],
					0 AS [wartoscSP],
					2 * [FiscalizationState] | 8 * [PublishInventoryDocumentMode] | 64 * @oO AS [exp_fk],
					0 AS [zyskdod],
					'' AS [kod_obcy],
					[ReservationType] AS [rozlmg],
					0 AS [efaktura],
					0 AS [statusRdf],           
					NULL AS [data_obcy],
					0 AS [koszt],
					0 AS [kosztaproksymowany],
					0 AS [statusfk],
					SplitPayment AS [splitPayment],
					InRegisterDate AS [datarej],
					SaleRegister AS [rejestrVat],
					CONVERT(DATE, GETDATE()) AS [dataZest1],
					[IssuerId] AS [createdBy],
					GETDATE() AS [createdDate],
					[IssuerId] AS [modifiedBy],
					GETDATE() AS [modifiedDate],
					[ValuePLN] AS [wartPrzychod]
				FROM @tblSaleDocument

				DECLARE @docType SMALLINT;

				-- Pobranie id nowo utworzonego dokumentu
				SET @docId = SCOPE_IDENTITY()

				SELECT @isBufor = bufor,
					   @docType = subtyp 
					   FROM HM.DK WHERE id = @docId

				-- Zapis pozycji nowego dokumentu
				INSERT INTO [HM].[DP]
				(
					[lp],
					[idkh],
					[idtw],
					[kod],
					[opis],
					[jmwp],
					[jm],
					[iloscwp],
					[iloscjedn],
					[ilosc],
					[schemat],
					[stvat],
					[cena],
					[walNetto],						
					[walBrutto],
					[wartNetto],
					[wartVat],
					[grupacen],
					[cenaBazaPl],
					[cenaBaza],
					[JPK_V7],
					[super],
					[superkoryg],
					[subtyp],
					[flag],
					[typ],
					[opisDod],
					[waluta],
					[wartTowaru],
					[cenabaztow],
					[walcenybaz],
					[wartstvat],
					[zyskdod],
					[cenawal],
					[bufor],
					[kompensata],
					[typceny],
					[kosztmarzy],
					[cn],
					[rejestrVAT],
					[magazyn],
					[data],
					[wartPrzychod],
					idpozkoryg,
					[odwrotneObc],
					[koszt],
					[iloscRLKS]
				)
				SELECT
					CASE WHEN @correction = 0 THEN tblDP.NodeId
					     ELSE                      (SELECT DP.lp FROM HM.DP WHERE DP.id = tblDP.CorrectedPositionId)
					END AS lp,
					@ContractorId AS [idkh],
					IIF([ProductId] = 0, NULL, [ProductId]) AS [idtw],
					(
						CASE
							WHEN ([ProductId] = 0) THEN ''
							ELSE (Select [kod] from HM.TW where [id] = [ProductId])
						END
					) AS [kod],
					(
						CASE
							WHEN (LEN([Description]) <= @shortDescriptionLength) THEN [Description]
							ELSE CONCAT(LEFT ([Description], @shortDescriptionLength-3), '...')
						END
					) AS [opis],
					[UnitOfMeasurement] AS [jmwp],
					[EvidenceUnitOfMeasurement] AS [jm],
					[Quantity] AS [iloscwp],
					[UnitQuantity] AS [iloscjedn],
					[EvidenceQuantity] AS [ilosc],
					[AccountingPattern] AS [schemat],
					IIF(@docType = 46,[DomesticVatRateId],ISNULL(NULLIF([VatRateId], ''), @defaultVatRateId)) AS [stvat],
					CASE WHEN @IsNet = 1 THEN [Price] ELSE [PriceGross] END * @ExchangeRate AS [cena], --celowo bez zaokrąglenia
					[Value] AS [walNetto],						
					[ValueGross] AS [walBrutto],
					[ValuePLN] AS [wartNetto],
					[ValueVatPLN] AS [wartVat],
					@IsNet AS [grupacen],
					CASE WHEN @IsNet = 1 THEN [PriceListPrice] ELSE [PriceListPriceGross] END * @ExchangeRate AS [cenaBazaPl], --celowo bez zaokrąglenia
					[OriginalPriceListPrice] AS [cenaBaza],
					[JPK_V7] AS [JPK_V7],
					@docId AS [super],
					IIF([CorrectedDocumentId] = 0, @docId, [CorrectedDocumentId]) AS [superkoryg],
					0 AS [subtyp],
					valuesForDP.flag AS [flag],
					valuesForDP.typ AS [typ],
					[CodePKWIU] AS [opisdod],
					[OriginalPriceListPriceCurrency] AS [waluta],
					valuesForDP.wartTowaru AS [wartTowaru],
					valuesForDP.cenabaztow AS [cenabaztow],
					valuesForDP.walcenybaz AS [walcenybaz],
					valuesForDP.wartstvat AS [wartstvat],
					valuesForDP.zyskdod AS [zyskdod],
					CASE WHEN @IsNet = 1 THEN [Price] ELSE [PriceGross] END AS [cenawal],
					@isBufor AS [bufor],
					Compensation AS [kompensata],
					[PriceTypeId] AS [typceny],
					0 AS [kosztmarzy],
					[CN] as [cn],
					IIF([VatRegister] = 0, NULL, [VatRegister]) AS [rejestrVAT],
					@department AS [magazyn],
					@issueDate as [data],
					[ValuePLN] as [wartPrzychod],
					CorrectedPositionId AS idpozkoryg,
					[OO] AS odwrotneObc,
					valuesForDP.koszt AS koszt,
					valuesForDP.iloscRLKS AS iloscRLKS
				FROM @tblDocumentPositions AS tblDP
				JOIN @valuesForDP valuesForDP ON valuesForDP.NodeId = tblDP.NodeId
				ORDER BY tblDP.NodeId	--istotna jest kolejność dodanych pozycji

				-- Zapis notatki nowego dokumentu
				INSERT INTO [HM].[DocumentNotes] ([DocumentId], [TableId], [Text])
				VALUES (@docId, 16, (SELECT [NoticeText]  FROM @tblSaleDocument))
				
				-- Zapis transakcji nowego dokumentu
				INSERT INTO HM.TR
				(
					[owner_id],
					[kod],
					[id_kto],
					[dzial],
					[id_komu],
					[datarozl],
					[data],
					[termin],
					[flag],
					[typ],
					[subtyp],
					[owner_base],
					[ok],
					[nrozl_oper],
					[wartosc],
					[wartosc_rozl],
					[nrozlilosc],
					[status]
				)
				SELECT 
					@docId AS [owner_id],
					dk.[kod] AS [kod],
					[ContractorId] AS [id_kto],
					[DepartmentId] AS [dzial],
					NULL AS [id_komu],
					NULL AS [datarozl],
					GETDATE() AS [data],
					GETDATE() AS [termin],
					16896 AS [flag],
					1 AS [typ],
					1 AS [subtyp],
					16 AS [owner_base],
					0 AS [ok],
					0 AS [nrozl_oper],
					0 AS [wartosc],
					0 AS [wartosc_rozl],
					0 AS [nrozlilosc],
					4 AS [status]
				FROM @tblSaleDocument
				JOIN [HM].[DK] dk ON dk.[id] = @docId;

			END
			ELSE
			BEGIN
				-- Aktualizacja dokumentu
				UPDATE [HM].[DK]
				SET dk.[kod] = tblSD.[DocumentNumber],
					dk.[nazwa] = tblSD.[Name],
					dk.[data] = tblSD.[IssueDate],
					dk.[datasp] = tblSD.[OperationDate],
					dk.[opis] = IIF(tblSD.[CorrectedDocumentId] IS NOT NULL, tblSD.[CorrectionCause], tblSD.[Description]), -- dla korekty przyczyna korekty
					dk.[odebrane] = tblSD.[RecipientPerson],
					dk.[subtyp] = tblSD.[BaseType],
					dk.[typ_dk] = tblSD.[DocumentTypeShortcut],
					dk.[seria] = tblSD.[DocumentNumerationShortcut],
					dk.[serianr] = tblSD.[SeriesNo],
					dk.[rodzaj] = tblSD.[KindId],
					dk.[katalog] = tblSD.[CatalogId],
					dk.[znacznik] = tblSD.[Marker],
					dk.[bufor] = 1^(CAST(tblSD.[IsIssued] as bit)),
					dk.[anulowany] = tblSD.[Canceled],
					dk.[aktywny] = tblSD.[IsActive],
					dk.[statusMig] = tblSD.[MigrationStatus],
					dk.[schemat] = tblSD.[AccountingPattern],
					dk.[wystawil] = tblSD.[IssuerId],
					dk.[khid] = tblSD.[ContractorId],
					dk.[odid] = tblSD.[ReceiverId],
					dk.[khadid] = @ContractorAddressId,
					dk.[odadid] = @ReceiverAddressId,
					dk.[magazyn] = tblSD.[DepartmentId],
					dk.[plattyp] = IIF(tblSD.[PayRegistryId] = -1, NULL, tblSD.[PayRegistryId]),
					dk.[formaplatn] = tblSD.[PaymentFormClientId],
					dk.[plattermin] = tblSD.[PaymentDeadline],
					dk.[walNetto] = tblSD.[Value],
					dk.[walBrutto] = tblSD.[ValueGross],
					dk.[netto] = tblSD.[ValuePLN],
					dk.[vat] = tblSD.[ValueVatPLN],
					dk.[grupacen] = @IsNet,
					dk.[waluta] = tblSD.[Currency],
					dk.[kurs] = tblSD.[ExchangeRate],
					dk.[kursDoch] = tblSD.[ExchangeRatePIT],				
					dk.[typceny] = tblSD.[PriceTypeId],
					dk.[rabat] = tblSD.[Discount],
					dk.paragon = CONVERT(INTEGER, tblSD.ReceiptNumber),
					dk.fiscalDeviceNo = tblSD.UniqueCashBoxNumber,
					dk.[jpk_v7] = tblSD.[JPK_V7],
					dk.[jpk] = tblSD.[JPK],
					dk.[flag] = hm.SetFlag(0, 0x8000, CalculateVatMethod) | hm.SetFlag(0, 0x80, RegisterMethod - 1) | IIF(ForeignOrder = 'true', 0x1000, 0) | IIF(IsGroupCorrection = 'true', 0x20,0),
					dk.[typ] = 0,
					dk.[info] = 0,
					dk.[seriadzial] = IsNull(tblSD.DepartmentInSeries, 0),
					dk.[okres] = IsNull(tblSD.Period, 0),
					dk.[ok] = tblSD.[CashSettled],
					dk.[rr] = 0,
					dk.[wplaty] = 0,
					dk.[wartoscSP] = 0,
					dk.[exp_fk] = ( dk.[exp_fk] & ~74 ) | 2 * [FiscalizationState] | 8 * [PublishInventoryDocumentMode] | 64 * @oO,
					dk.[zyskdod] = 0,
					dk.[kod_obcy] = '',
					dk.[rozlmg] = tblSD.[ReservationType],
					dk.[efaktura] = 0,
					dk.[statusRdf] = 0,          
					dk.[data_obcy] = NULL,
					dk.[koszt] = 0,
					dk.[kosztaproksymowany] = 0,
					dk.[statusfk] = 0,
					dk.[splitPayment] = tblSD.[SplitPayment],
					dk.[datarej] = tblSD.[InRegisterDate],
					dk.[rejestrVat] = tblSD.[SaleRegister],
					dk.[wartPrzychod] = tblSD.[ValuePLN]
				FROM [HM].[DK] dk, @tblSaleDocument tblSD
				WHERE dk.[id] = @docId			
				
				SELECT @isBufor = bufor,
					   @docType = subtyp 
					   FROM HM.DK WHERE id = @docId;
				
				-- Zapamiętanie id operacji zamówienia powiązanych z usuwanymi pozycjami
				INSERT INTO @deleted_operations
				SELECT ro.id1
				FROM HM.DP dp
				JOIN HM.OP op_dp ON op_dp.owner_id = dp.id AND op_dp.owner_base = 18
				JOIN HM.RO ro ON op_dp.id = ro.id2
				LEFT JOIN @tblDocumentPositions tblDP ON dp.id = tblDP.Id
				WHERE dp.super = @docId AND (tblDP.Id IS NULL OR tblDP.Id = 0)

				--Usunięcie powiązań operacji
				DELETE FROM [HM].[RO]
				WHERE id2 IN(
						SELECT op.id 
						FROM [HM].[DP] dp
						JOIN [HM].[OP] op ON op.owner_id = dp.id AND op.[owner_base] = 18
						LEFT JOIN @tblDocumentPositions tblDP ON dp.[id] = tblDP.[Id]
						WHERE dp.[super] = @docId
						AND (tblDP.[Id] IS NULL OR tblDP.[Id] = 0)
				);

				-- Usunięcie skasowanych operacji
				DELETE FROM [HM].[OP]
				WHERE [owner_id] IN (
						SELECT dp.[id] 
						FROM [HM].[DP] dp
						LEFT JOIN @tblDocumentPositions tblDP ON dp.[id] = tblDP.[Id]
						WHERE dp.[super] = @docId
						AND (tblDP.[Id] IS NULL OR tblDP.[Id] = 0)
						AND [owner_base] = 18
				) AND [owner_base] = 18
				
				-- Na potrzeby rezerwacji
				DECLARE @DeletedSaleDocumentPositionsRZ [HM].[DocumentPositionsType]
				INSERT INTO @DeletedSaleDocumentPositionsRZ
				SELECT rz.id,dp.idtw, dp.super,rz.iloscrz 
						FROM [HM].[RZ] rz
						JOIN HM.DP dp ON rz.bazapozrz = 18 and rz.idpozrz = dp.id
						LEFT JOIN @tblDocumentPositions tblDP ON dp.[id] = tblDP.[Id]
						WHERE dp.[super] = @docId
						AND (tblDP.[Id] IS NULL OR tblDP.[Id] = 0)

				-- Usunięcie skasowanych pozycji
				DECLARE @tblDeletedPositions TABLE
				(
					[Id] INT,
					[Idlongname] INT
				)
				INSERT INTO @tblDeletedPositions([Id], [Idlongname])
						SELECT dp.[id], dp.[Idlongname]
						FROM [HM].[DP] dp
						LEFT JOIN @tblDocumentPositions tblDP ON dp.[id] = tblDP.[Id]
						WHERE dp.[super] = @docId
						AND (tblDP.[Id] IS NULL OR tblDP.[Id] = 0)

				-- Dane podstawowe pozycji
				DELETE FROM [HM].[DP]
				WHERE [super] = @docId
				AND [id] IN (SELECT [Id] FROM @tblDeletedPositions)

				-- Długie nazwy pozycji
				DELETE FROM [HM].[TX]
				WHERE [typ] = 16
				AND [id] IN (SELECT [Idlongname] FROM @tblDeletedPositions WHERE [Idlongname] IS NOT NULL)

				--Zapis nowych pozycji
				INSERT INTO [HM].[DP]
				(
					[guid],
					[lp],
					[idkh],
					[idtw],
					[kod],
					[opis],
					[jmwp],
					[jm],
					[iloscwp],
					[iloscjedn],
					[ilosc],
					[schemat],
					[stvat],
					[cena],
					[walNetto],						
					[walBrutto],
					[wartNetto],
					[wartVat],
					[grupacen],
					[cenaBazaPl],
					[cenaBaza],
					[JPK_V7],
					[super],
					[superkoryg],
					[subtyp],
					[flag],
					[typ],
					[opisdod],
					[waluta],
					[wartTowaru],
					[cenabaztow],
					[walcenybaz],
					[wartstvat],
					[zyskdod],
					[cenawal],
					[bufor],
					[kompensata],
					[typceny],
					[kosztmarzy],
					[cn],
					[rejestrVAT],
					[magazyn],
					[data],
					[wartPrzychod],
					idpozkoryg,
					[odwrotneObc],
					[koszt],
					[iloscRLKS]
				)
				SELECT
					[Guid] AS [guid],
					CASE WHEN @correction = 0 OR [IsNewCorrectPosition] = 'true' THEN tblDP.NodeId
					     ELSE                      (SELECT DP.lp FROM HM.DP WHERE DP.id = tblDP.CorrectedPositionId)
					END AS lp,
					@ContractorId AS [idkh],
					IIF([ProductId] = 0, NULL, [ProductId]) AS [idtw],
					(
						CASE
							WHEN ([ProductId] = 0) THEN ''
							ELSE (Select [kod] from HM.TW where [id] = [ProductId])
						END
					) AS [kod],
					(
						CASE
							WHEN (LEN([Description]) <= @shortDescriptionLength) THEN [Description]
							ELSE CONCAT(LEFT ([Description], @shortDescriptionLength-3), '...')
						END
					) AS [opis],
					[UnitOfMeasurement] AS [jmwp],
					[EvidenceUnitOfMeasurement] AS [jm],
					[Quantity] AS [iloscwp],
					[UnitQuantity] AS [iloscjedn],
					[EvidenceQuantity] AS [ilosc],
					[AccountingPattern] AS [schemat],
					IIF(@docType = 46,[DomesticVatRateId],ISNULL(NULLIF([VatRateId], ''), @defaultVatRateId)) AS [stvat],
					CASE WHEN @IsNet = 1 THEN [Price] ELSE [PriceGross] END * @ExchangeRate AS [cena], --celowo bez zaokrąglenia
					[Value] AS [walNetto],						
					[ValueGross] AS [walBrutto],
					[ValuePLN] AS [wartNetto],
					[ValueVatPLN] AS [wartVat],
					@IsNet AS [grupacen],
					CASE WHEN @IsNet = 1 THEN [PriceListPrice] ELSE [PriceListPriceGross] END * @ExchangeRate AS [cenaBazaPl], --celowo bez zaokrąglenia
					[OriginalPriceListPrice] AS [cenaBaza],
					[JPK_V7] AS [JPK_V7],
					@docId AS [super],
					IIF([CorrectedDocumentId] = 0, @docId, [CorrectedDocumentId]) AS [superkoryg],
					0 AS [subtyp],					
					valuesForDP.flag AS [flag],
					valuesForDP.typ AS [typ],
					[CodePKWIU] AS [opisdod],
					[OriginalPriceListPriceCurrency] AS [waluta],
					valuesForDP.wartTowaru AS [wartTowaru],
					valuesForDP.cenabaztow AS [cenabaztow],
					valuesForDP.walcenybaz AS [walcenybaz],
					valuesForDP.wartstvat AS [wartstvat],
					valuesForDP.zyskdod AS [zyskdod],
					CASE WHEN @IsNet = 1 THEN [Price] ELSE [PriceGross] END AS [cenawal],
					@isBufor AS [bufor],
					Compensation AS [kompensata],
					[PriceTypeId] AS [typceny],
					0 AS [kosztmarzy],
					[CN] as [cn],
					IIF([VatRegister] = 0, NULL, [VatRegister]) AS [rejestrVAT],
					@department AS [magazyn],
					@issueDate as [data],
					[ValuePLN] AS [wartPrzychod],
					CorrectedPositionId AS idpozkoryg,
					[OO] AS odwrotneObc,
					valuesForDP.koszt AS koszt,
					valuesForDP.iloscRLKS AS iloscRLKS
				FROM @tblDocumentPositions AS tblDP
				JOIN @valuesForDP valuesForDP ON valuesForDP.NodeId = tblDP.NodeId
				WHERE [Id] IS NULL OR [Id] = 0
				ORDER BY tblDP.NodeId;	--istotna jest kolejność dodanych pozycji

				
				INSERT INTO [HM].[OP]
				(
					[flag],
					[subtyp],
					[owner_id],
					[owner_base],
					[kod],
					[id_co],
					[id_transakcji],
					[ok],
					[ilosc],
					[ilosc_rozl],
					[wartosc],
					[wartosc_rozl],
					[datarozl]
				)
				SELECT
					CASE WHEN dp.[super] != dp.[superkoryg] and dp.[idpozkoryg] is not null and dp.[kompensata] = 1 THEN 0x1800
						 WHEN dp.[super] != dp.[superkoryg] and dp.[idpozkoryg] is not null and dp.[kompensata] = 0 THEN 0x1000
						 ELSE IIF(ISNULL(TW.subtypext, 1) = 1, 512, 0) END AS [flag],
					1 AS [subtyp],
					dp.[id] AS [owner_id],
					18 AS [owner_base],
					dp.[kod] AS [kod],
					dp.[idtw] AS [id_co],
					TR.id AS [id_transakcji],
					IIF(tblDP.CorrectedPositionId is NULL, 0, 1) AS [ok],
					Abs(dp.ilosc) AS [ilosc],
					IIF(tblDP.CorrectedPositionId is NULL, 0, Abs(dp.ilosc)) AS [ilosc_rozl],
					Abs(dp.ilosc) * dp.cenabaztow AS [wartosc],
					IIF(tblDP.CorrectedPositionId is NULL, 0, Abs(dp.ilosc) * dp.cenabaztow) AS [wartosc_rozl],
					IIF(tblDP.CorrectedPositionId is NULL, NULL, CONVERT(date, GETDATE())) AS [datarozl]
				FROM [HM].[DP] dp
				JOIN @tblDocumentPositions tblDP ON dp.super = @docId
				JOIN HM.TR ON TR.typ = 1 AND TR.owner_base = 16 AND TR.owner_id = dp.[superkoryg]
				LEFT OUTER JOIN HM.TW ON DP.idtw = TW.id
				WHERE tblDP.[Id] IS NULL OR tblDP.[Id] = 0 AND dp.guid = tblDP.[Guid]

				-- Nowe rozliczenia w HM.RO dla korekt
				IF @correction <> 0
				BEGIN
					INSERT INTO [HM].[RO]
					(
						[flag],
						[typ],
						[id1],
						[id2],
						[ilosc],
						[wartosc],
						[data]
					)
					SELECT
						op.[flag] AS [flag],
						1 AS [typ],
						op2.[id] AS [id1],
						op.[id] AS [id2],
						CASE WHEN op.[flag] & 0x1800 = 0x1800 THEN op.[ilosc]
							 WHEN op.[flag] & 0x1000 = 0x1000 THEN -op.[ilosc]
							 ELSE 0 
							 END AS [ilosc],
						CASE WHEN op.[flag] & 0x1800 = 0x1800 THEN op.[wartosc]
							 WHEN op.[flag] & 0x1000 = 0x1000 THEN -op.[wartosc] 
							 ELSE 0 
							 END AS [wartosc],
						CONVERT(date, GETDATE()) AS [data]
					FROM @tblDocumentPositions tblDP
					JOIN [HM].[DP] dp ON dp.[guid] = tblDP.[guid]
					JOIN [HM].[OP] op ON op.[owner_id] = dp.[id] AND op.owner_base = 18
					LEFT JOIN [HM].[DP] dp2 ON dp2.[id] = dp.[idpozkoryg]
					JOIN [HM].[OP] op2 ON op2.[owner_id] = (ISNULL(dp2.[idpozkoryg], dp.[idpozkoryg])) AND op2.owner_base = 18
					WHERE tblDP.[Id] IS NULL OR tblDP.[Id] = 0
				END

				-- Aktualizacja pozycji
				UPDATE [HM].[DP]
				SET dp.lp = CASE WHEN @correction = 0 OR [IsNewCorrectPosition] = 'true' THEN tblDP.NodeId
				                 ELSE                      (SELECT DP.lp FROM HM.DP WHERE DP.id = tblDP.CorrectedPositionId)
							END,
				    dp.[idkh] = @ContractorId,
					dp.[idtw] = IIF(tblDP.[ProductId] = 0, NULL, tblDP.[ProductId]),
					dp.[kod] = (
						CASE
							WHEN (tblDP.[ProductId] = 0) THEN ''
							ELSE (Select [kod] from HM.TW where [id] = tblDP.[ProductId])
						END
					),	
					dp.[opis] = (
						CASE
							WHEN (LEN(tblDP.[Description]) <= @shortDescriptionLength) THEN tblDP.[Description]
							ELSE CONCAT(LEFT ([Description], @shortDescriptionLength-3), '...')
						END
					),
					dp.[jmwp] = tblDP.[UnitOfMeasurement],
					dp.[jm] = tblDP.[EvidenceUnitOfMeasurement],
					dp.[iloscwp] = tblDP.[Quantity],
					dp.[iloscjedn] = tblDP.[UnitQuantity],
					dp.[ilosc] = tblDP.[EvidenceQuantity],					
					dp.[schemat] = tblDP.[AccountingPattern],
					dp.[stvat] = IIF(@docType = 46,tblDP.[DomesticVatRateId],tblDP.[VatRateId]),
					dp.[cena] = CASE WHEN @IsNet = 1 THEN tblDP.[Price] ELSE tblDP.[PriceGross] END * @ExchangeRate, --celowo bez zaokrąglenia
					dp.[walNetto] = tblDP.[Value],						
					dp.[walBrutto] = tblDP.[ValueGross],
					dp.[wartNetto] = tblDP.[ValuePLN],
					dp.[wartVat] = tblDP.[ValueVatPLN],
					dp.[grupacen] = @IsNet,
					dp.[cenaBazaPl] = CASE WHEN @IsNet = 1 THEN tblDP.[PriceListPrice] ELSE tblDP.[PriceListPriceGross] END * @ExchangeRate, --celowo bez zaokrąglenia
					dp.[cenaBaza] = tblDP.[OriginalPriceListPrice],
					dp.[JPK_V7] = tblDP.[JPK_V7],
					dp.[subtyp] = 0,
					dp.[flag] = valuesForDP.[flag],
					dp.[typ] = valuesForDP.[typ],
					dp.[opisdod] = tblDP.[CodePKWIU],
					dp.[waluta] = tblDP.[OriginalPriceListPriceCurrency],
					dp.[wartTowaru] = valuesForDP.wartTowaru,
					dp.[cenabaztow] = valuesForDP.cenabaztow,
					dp.[walcenybaz] = valuesForDP.walcenybaz,
					dp.[wartstvat] = valuesForDP.wartstvat,
					dp.[zyskdod] = valuesForDP.zyskdod,
					dp.[cenawal] = CASE WHEN @IsNet = 1 THEN tblDP.[Price] ELSE tblDP.[PriceGross] END,
					dp.[bufor] = @isBufor,
					dp.[kompensata] = tblDP.[Compensation],
					dp.[typceny] = tblDP.[PriceTypeId],
					dp.[kosztmarzy] = 0,
					dp.[cn] = tblDP.[CN],
					dp.[rejestrVAT] = IIF(tblDP.[VatRegister] = 0, NULL, tblDP.[VatRegister]),
					dp.[magazyn] = @department,
					dp.[data] = @issueDate,
					dp.[wartPrzychod] = tblDP.[ValuePLN],
					dp.idpozkoryg = tblDP.CorrectedPositionId,
					dp.odwrotneObc = tblDP.OO,
					dp.[koszt] = valuesForDP.koszt,
					dp.[iloscRLKS] = valuesForDP.iloscRLKS
				FROM [HM].[DP] dp
				JOIN @tblDocumentPositions tblDP ON dp.[id] = tblDP.[Id]
				JOIN @valuesForDP valuesForDP ON valuesForDP.NodeId = tblDP.NodeId
				WHERE dp.[super] = @docId

				IF (@departmentId = 0 OR @departmentId IS NULL)
				BEGIN
					SELECT @departmentId = magazyn FROM [HM].[DK] WHERE id = @docId
				END				

				-- Aktualizacja operacji
				UPDATE [HM].[OP]
				SET
					[flag] = IIF(op.flag & 0x400 = 0x400, 0x400, 0) |
							 CASE WHEN (dp.[flag] & 0x1000 = 0x1000) THEN CASE WHEN (dp.[idpozkoryg] IS NOT NULL AND dp.kompensata = 0) THEN -28160
																			   WHEN (dp.[idpozkoryg] IS NOT NULL AND dp.kompensata = 1) THEN -26112
																			   ELSE -32256 END
								  WHEN (dp.[super] != dp.[superkoryg] and dp.[idpozkoryg] is not null and dp.[kompensata] = 1) THEN 0x1800
								  WHEN (dp.[super] != dp.[superkoryg] and dp.[idpozkoryg] is not null and dp.[kompensata] = 0) THEN 0x1000
								  ELSE IIF(ISNULL(tw.[subtypext], 1) = 1, 512, 0) END,
					[subtyp] = 1,
					[owner_id] = dp.[id],
					[kod] = dp.[kod],
					[id_co] = dp.[idtw],
					[ok] = CASE WHEN dp.[idpozkoryg] is not null THEN 1 
								WHEN (dp.[flag] & 0x1000 = 0x1000) THEN 1
								ELSE IIF((dp.[ilosc] = [ilosc_rozl] AND [ilosc_rozl] <> 0) OR dp.[idtw] IS NULL OR dp.[flag] = 0 OR dp.[flag] & 0x1000 = 0x1000, 1, 0) END,
					[ilosc] = Abs(dp.[ilosc]),
					[ilosc_rozl] = CASE WHEN dp.[idpozkoryg] is not null THEN Abs(dp.[ilosc]) ELSE [ilosc_rozl] END,
					[wartosc] = IIF(dp.[flag] & 0x1000 = 0x1000 AND dp.[idpozkoryg] IS NOT NULL, 0, Abs(dp.[ilosc]) * dp.[cenabaztow]),
					[wartosc_rozl] = CASE WHEN dp.[flag] & 0x1000 = 0x1000 AND dp.[idpozkoryg] IS NOT NULL THEN 0
										  WHEN dp.[idpozkoryg] is not null THEN Abs(dp.[ilosc]) * dp.[cenabaztow] 
										  ELSE [wartosc_rozl] END,
					[datarozl] = CASE WHEN dp.[idpozkoryg] is not null THEN CONVERT(date, GETDATE())
										ELSE 
											CASE WHEN (dp.[flag] & 0x1000 = 0x1000) THEN CONVERT(date, GETDATE()) ELSE IIF(dp.[idtw] IS NULL, CONVERT(date, GETDATE()), NULL ) END
										END
				FROM [HM].[OP] op
				JOIN [HM].[DP] dp ON op.[owner_id] = dp.[id] AND op.[owner_base] = 18
				LEFT OUTER JOIN [HM].[TW] tw ON DP.idtw = tw.id
				WHERE dp.super = @docId

				-- Aktualizacja rozliczeń w HM.RO dla korekt
				IF @correction <> 0
				BEGIN
					UPDATE [HM].[RO]
					SET
						[ilosc] = CASE WHEN dp.kompensata = 1 THEN op.[ilosc]
									   WHEN dp.kompensata = 0 THEN -op.[ilosc]
									   ELSE 0 
									   END,
						[wartosc] = CASE WHEN dp.kompensata = 1 THEN op.[wartosc]
										 WHEN dp.kompensata = 0 THEN -op.[wartosc] 
										 ELSE 0 
										 END,
						[data] = CONVERT(date, GETDATE())
					FROM [HM].[RO] ro
					JOIN [HM].[OP] op ON op.[id] = ro.[id2]
					JOIN [HM].[DP] dp ON op.[owner_id] = dp.[id] AND op.[owner_base] = 18
					WHERE dp.[super] = @docId AND (ro.[flag] & 0x1800 = 0x1800 OR ro.[flag] & 0x1000 = 0x1000)
										
					DECLARE @sum_ro TABLE(id1 int, quantitySum float, valueSum float);

					INSERT INTO @sum_ro
					SELECT id1, SUM(ilosc), SUM(wartosc)
					FROM [HM].[RO]
					WHERE id1 in (SELECT op.[id]
								  FROM [HM].[DP] dp
								  JOIN [HM].[OP] op ON op.[owner_id] = ISNULL(dp.[idpozkoryg], dp.id)
								  where dp.[super] IN (SELECT * FROM @correctedOrDocId) AND dp.[kompensata] = 0)  
					GROUP BY id1

					UPDATE [HM].[OP]
					SET
						[ilosc_rozl] = sum_ro.[quantitySum],
						[wartosc_rozl] = sum_ro.[valueSum],
						[ok] = CASE WHEN op.[flag] = -32256 OR op.[flag] = 512 THEN 1 
									ELSE IIF(sum_ro.[quantitySum] = op.[ilosc], 1, 0)									
									END
					FROM [HM].[OP] op
					JOIN @sum_ro sum_ro ON sum_ro.[id1] = op.[id]

				END
				
				DECLARE @incompletedOperationsOwners TABLE (Id INT);
				INSERT INTO @incompletedOperationsOwners
					SELECT dp.super
					FROM [HM].[OP] op
					JOIN [HM].[DP] dp ON op.owner_id = dp.id AND op.owner_base = 18 
					WHERE (dp.super IN (SELECT * FROM @correctedOrDocId) OR dp.super = @docId) AND ok = 0

				--Powiązane transakcje wydań
				DECLARE @transactionIds TABLE (id INT);
				INSERT INTO @transactionIds SELECT id from HM.TR where owner_id IN (SELECT * FROM @correctedOrDocId) AND owner_base = 16
				
				DECLARE @linkedTransactions TABLE(id int);
				
				INSERT INTO @linkedTransactions
				SELECT id2 FROM hm.po 
				WHERE id1 IN (SELECT * FROM @transactionIds);
				
				DECLARE @incompletedTransactions INT;
				SET @incompletedTransactions = (SELECT COUNT(1) 
												FROM HM.TR tr
												JOIN @linkedTransactions transactions ON transactions.id = tr.id
												where tr.owner_base = 33 AND tr.status <> 32);

				
				DECLARE @status SMALLINT;
				DECLARE @bufor bit;
				SET @bufor = (SELECT bufor FROM [HM].[DK] dk WHERE dk.id = @docId);
				
				IF @correction = 0
				BEGIN
					SET @status = CASE 
								WHEN @incompletedTransactions = 0 AND @bufor = 1 THEN 4
								WHEN (SELECT COUNT(Id) FROM @incompletedOperationsOwners) <> 0 THEN 8
								WHEN @incompletedTransactions <> 0 THEN 16
								ELSE 32
								END;
				END
				ELSE
				BEGIN

					DECLARE @anyTransactions INT;
					SET @anyTransactions = (SELECT COUNT(1) 
												FROM HM.TR tr
												JOIN @linkedTransactions transactions ON transactions.id = tr.id
												where tr.owner_base = 33);

					SET @status = CASE 
								WHEN @incompletedTransactions = 0 AND @anyTransactions = 0 THEN 4
								WHEN (SELECT COUNT(Id) FROM @incompletedOperationsOwners) <> 0 THEN 8
								WHEN @incompletedTransactions <> 0 OR @bufor = 1 THEN 16
								ELSE 32
								END;
				END;

				DECLARE @wartoscTransakcji FLOAT;
				SELECT @wartoscTransakcji = ISNULL(SUM(CASE WHEN ((32768 & OP.flag) = 32768) THEN 0 WHEN ((OP.flag & 6144) = 6144) THEN -OP.wartosc WHEN ((2048 & OP.flag) = 2048) THEN -OP.wartosc ELSE OP.wartosc END),0) FROM [HM].[TR] TR
				JOIN HM.OP ON OP.id_transakcji = TR.id 
				WHERE TR.owner_id IN (SELECT * FROM @correctedOrDocId) and TR.typ = 1 AND TR.owner_base = 16

				UPDATE [HM].[TR]
				SET
					id_kto = dk.khid,
					kod = dk.kod,
					wartosc = @wartoscTransakcji,
					nrozl_oper = (SELECT COUNT(Id) FROM @incompletedOperationsOwners WHERE Id = tr.owner_id),
					nrozlilosc = (SELECT COUNT(Id) FROM @incompletedOperationsOwners WHERE Id = tr.owner_id),
					status = @status,
					ok = IIF((SELECT COUNT(Id) FROM @incompletedOperationsOwners WHERE Id = tr.owner_id) = 0, 1, 0),
					datarozl = IIF((SELECT COUNT(Id) FROM @incompletedOperationsOwners WHERE Id = tr.owner_id) = 0, CONVERT(date, GETDATE()), NULL)
				FROM [HM].[TR] tr 
				JOIN [HM].[DK] dk ON dk.id = tr.owner_id AND tr.owner_base = 16
				WHERE DK.id IN (SELECT * FROM @correctedOrDocId)
				
				-- Aktualizacja w tabeli tymczasowej Id na potrzeby dodania rezerwacji
				UPDATE @tblDocumentPositions SET Id = DP.id
				FROM [HM].[DP] DP
				JOIN @tblDocumentPositions temp ON dp.super = @docId
				WHERE DP.super = @docId and (temp.[Id] IS NULL OR temp.[Id] = 0) AND temp.[Guid] = DP.guid

				-- Tymczasowe tabele pozycji na potrzeby zapisu rezerwacji
				DECLARE @tblDRP [HM].[DocumentReservationsPositionsType]

				INSERT INTO @tblDRP 
				SELECT tblDP.Id, tblDP.NodeId, tblDP.ProductId, tblDP.ReservationType
				FROM @tblDocumentPositions tblDP

				DECLARE @tblDP [HM].[DocumentPositionsType]

				INSERT INTO @tblDP
				SELECT DP.[Id], DP.[idtw], DP.[super], DP.[ilosc]
				FROM [HM].[DP] DP
				WHERE DP.[super] = @docId

				DECLARE @anyOrderRelatedDocuments BIT = ISNULL((SELECT TOP(1) 1 FROM @tblRelatedDocuments WHERE DocumentType = 'Zamówienia'), 0)

				-- Zapis rezerwacji
				EXEC [HM].[UpdateDocumentReservationsFromXML] @handle, @tblDRP, @tblDP, @DeletedSaleDocumentPositionsRZ, @docId, @IssueDate, @ContractorId, @correction, @anyOrderRelatedDocuments

				-- Aktualizacja notatki nowego dokumentu
				UPDATE [HM].[DocumentNotes] 
				SET [Text] = tblSD.[NoticeText]
				FROM [HM].[DocumentNotes] dn
				JOIN @tblSaleDocument tblSD ON dn.[DocumentId] = tblSD.[Id] 
				WHERE dn.[TableId] = 16		
												
				--aktualizacja statusu rozliczenia dokumentu gdy dokument jest już rozliczony lub częściowo rozliczony			
				UPDATE [HM].[DK] SET DK.rozlmg = case WHEN ((32 & DK.rozlmg) = 32) THEN ~32 & DK.rozlmg ELSE 32 | DK.rozlmg END 
				FROM HM.DK WHERE DK.id in 
				(SELECT DK.id 
					FROM  [HM].[DK] DK
					JOIN [HM].[TR] TR ON (TR.owner_id = DK.id OR TR.owner_id IN (SELECT * FROM @correctedDocsIds)) AND TR.owner_base = 16 AND TR.typ = 1 
					JOIN  [HM].[DK] DKO ON DKO.id = TR.owner_id
					WHERE (((TR.ok = 0 AND TR.nrozl_oper <> 0 AND ((32 & DK.rozlmg) = 32)) OR (TR.ok <> 0 AND TR.nrozl_oper = 0 AND ((32 & DK.rozlmg) <> 32))) AND (0x4000 & DKO.flag) = 0 AND DK.bufor = 0 AND DK.typ = 0) 
					AND DK.anulowany = 0 and DK.id IN (SELECT * FROM @correctedOrDocId))

				IF @correction <> 0
				BEGIN
					UPDATE [HM].[DK] 
						SET [rozlmg] = CASE WHEN tr.[status] = 32 OR tr.[status] = 16 THEN dk.[rozlmg] | 32
											 ELSE dk.[rozlmg]
											 END
					FROM [HM].[DK] dk
					JOIN [HM].[TR] tr ON tr.[owner_id] IN (SELECT * FROM @correctedDocsIds)
					WHERE dk.[id] = @docId
				END

				--naprawa wartości oraz wartości rozliczonej dokumentu gdy dokument jest już rozliczony lub częściowo rozliczony
				CREATE TABLE [#tempRozl] (idTR INT, wartosc FLOAT, wartosc_rozl FLOAT)

				INSERT #tempRozl
				SELECT TR.id as idTR, SUM(CASE WHEN ((32768 & OP.flag) = 32768) THEN 0 WHEN ((2048 & OP.flag) = 2048) THEN -OP.wartosc ELSE OP.wartosc END) as wartGood, SUM(CASE WHEN ((32768 & OP.flag) = 32768) THEN 0 WHEN ((2048 & OP.flag) = 2048) THEN -OP.wartosc_rozl ELSE OP.wartosc_rozl END) as wartRozlGood  
				FROM HM.TR TR
				JOIN HM.OP ON OP.id_transakcji = TR.id 
				WHERE TR.typ = '1' and (TR.owner_id = @docId and TR.owner_base = 16) 
				GROUP BY TR.id, TR.kod HAVING (ABS(ABS(SUM(CASE WHEN ((32768 & OP.flag) = 32768) THEN 0 WHEN ((2048 & OP.flag) = 2048) THEN -OP.wartosc_rozl ELSE OP.wartosc_rozl END)) - ABS(MIN(TR.wartosc_rozl))) > 0.000001) OR (ABS(ABS(SUM(CASE WHEN ((32768 & OP.flag) = 32768) THEN 0 WHEN ((2048 & OP.flag) = 2048) THEN -OP.wartosc ELSE OP.wartosc END)) - ABS(MIN(TR.wartosc))) > 0.000001)

				UPDATE HM.TR SET TR.wartosc = tmpRozl.wartosc, TR.wartosc_rozl = tmpRozl.wartosc_rozl FROM HM.TR JOIN #tempRozl tmpRozl ON tmpRozl.idTR = TR.id

				IF (OBJECT_ID('tempdb..[#tempRozl]') IS NOT NULL) DROP TABLE [#tempRozl]
												
			END					

			-- Aktualizacja długich opisów pozycji
			DECLARE @tblLongNames TABLE(
					[Id] [smallint] IDENTITY(1,1) NOT NULL,
					[Guid] UNIQUEIDENTIFIER,
					[Description] NVARCHAR(max),
					[DpId] INT,
					[TxId] INT,
					[IsLongName] BIT)	
			
			INSERT INTO @tblLongNames ([Guid], [Description], [DpId], [TxId], [IsLongName])
			SELECT tdp.[Guid], tdp.[Description], DP.[id], DP.[idlongname], IIF(LEN([Description]) > @shortDescriptionLength, 1, 0)
			FROM @tblDocumentPositions tdp
			JOIN HM.DP ON DP.[Guid] = tdp.[Guid]
			WHERE LEN (tdp.[Description]) > @shortDescriptionLength OR DP.[idlongname] is NOT NULL

			-- aktualizacja pozycji które były długie i już nie są
			UPDATE HM.DP
			SET idlongname = NULL
			WHERE id in (SELECT DpId FROM @tblLongNames where IsLongName = 0)

			-- usunięcie tych które były długie i już nie są
			DELETE FROM HM.TX
			WHERE id in (SELECT TxId FROM @tblLongNames where IsLongName = 0)

			-- dodanie nowych długich nazw, aby otrzymać id do DP
			INSERT INTO HM.TX (flag, subtyp, typ, opis)
			SELECT ln.[Id], 0, 16, ln.[Description]
			FROM @tblLongNames ln
			WHERE ln.[TxId] IS NULL
			
			-- aktualizacja pozycji dla nowych długich nazw
			UPDATE HM.DP
			SET idlongname = TX.id
			FROM @tblLongNames ln
			JOIN HM.TX ON ln.[Id] = TX.flag
			WHERE DP.super = @docId AND DP.Id = ln.DpId

			-- porządki w tx po tymczasowych zmianach
			UPDATE HM.TX
			SET flag = 0
			FROM HM.DP
			WHERE TX.flag != 0 AND DP.super = @docId AND DP.[idlongname] = TX.[Id]

			-- aktualizacja opisu dla długich nazw
			UPDATE HM.TX
			SET opis = ln.[Description]
			FROM @tblLongNames ln 
			WHERE TX.id = ln.TxId

			-- Koniec: Aktualizacja długich opisów pozycji

			IF(@foreignOrder = 'true')
			BEGIN
				
				-- Tabela pomocnicza powiązania operacji dokumentu i zamówienia
				DECLARE @temp_ro TABLE(id int, id_zp int, id_dp int, ilosc_ro float, ilosc_dp float, ilosc_zp float, 
										ilosc_rozl_zp float, ilosc_dp_other float, ilosc_ro_new float, ilosc_sum float);

				INSERT INTO @temp_ro
				SELECT ro.id, ro.id1, ro.id2, ro.ilosc, op_dp.ilosc, op_zp.ilosc, op_zp.ilosc_rozl, 0, 0, 0
				FROM HM.RO ro
				JOIN HM.OP op_dp ON ro.id2 = op_dp.id
				JOIN HM.OP op_zp ON ro.id1 = op_zp.id
				JOIN HM.DP dp ON dp.id = op_dp.owner_id
				WHERE dp.super = @docId AND op_dp.owner_base = 18 AND op_dp.flag & 0x400 = 0x400;

				-- Tabela pomocnicza sumy ilosci z innych powiazanych dokumentow, bez edytowanego dokumentu
				DECLARE @temp_ro_SUM TABLE(id int, ilosc_SUM float);
				
				INSERT INTO @temp_ro_SUM
				SELECT temp_ro.id, SUM(ro.ilosc) AS ilosc_SUM 
				FROM HM.RO ro
				JOIN @temp_ro temp_ro ON temp_ro.id_zp = ro.id1
				WHERE temp_ro.id != ro.id 
				GROUP BY temp_ro.id, temp_ro.ilosc_zp;

				-- Dopisanie do tabeli pomocniczej sumy ilosci na innych powiązanych dokumentach
				UPDATE @temp_ro
				SET ilosc_dp_other = temp_ro_SUM.ilosc_SUM
				from @temp_ro ro
				JOIN @temp_ro_SUM temp_ro_SUM ON temp_ro_SUM.id = ro.id

				-- Przeliczenie ilości do aktualizacji kolumny HM.RO
				DECLARE @id_dp_prev int;
				DECLARE @id_dp int;
				DECLARE @ilosc_dp float;
				DECLARE @ilosc_zp float;
				DECLARE @ilosc_dp_other float;
				DECLARE @ilosc_ro_new float;
				DECLARE @calculated_ilosc_ro float;
				DECLARE @ilosc_left float; -- pozostała ilość do przypisania (dla pozycji scalonych z wielu zamówień)
 
				DECLARE temp_cursor CURSOR FOR
				SELECT id_dp, ilosc_dp, ilosc_zp, ilosc_dp_other
				FROM @temp_ro
 
				OPEN temp_cursor;
				FETCH NEXT FROM temp_cursor INTO @id_dp, @ilosc_dp, @ilosc_zp, @ilosc_dp_other;
 
				WHILE @@FETCH_STATUS = 0
				BEGIN

					IF(@id_dp_prev = @id_dp)
					BEGIN
						
						SET @calculated_ilosc_ro = IIF(@ilosc_left > @ilosc_zp - @ilosc_dp_other, @ilosc_zp - @ilosc_dp_other, @ilosc_left);
						SET @ilosc_left = @ilosc_left - @calculated_ilosc_ro;

					END
					ELSE
					BEGIN
						SET @calculated_ilosc_ro = IIF(@ilosc_dp > @ilosc_zp - @ilosc_dp_other, @ilosc_zp - @ilosc_dp_other, @ilosc_dp);
						SET @ilosc_left = @ilosc_dp - @calculated_ilosc_ro;
					END

					UPDATE @temp_ro
					SET ilosc_ro_new = @calculated_ilosc_ro, ilosc_sum = @calculated_ilosc_ro + ilosc_dp_other
					WHERE CURRENT OF temp_cursor;

					SET @id_dp_prev = @id_dp;

					FETCH NEXT FROM temp_cursor INTO @id_dp, @ilosc_dp, @ilosc_zp, @ilosc_dp_other;
				END
 
				CLOSE temp_cursor;
				DEALLOCATE temp_cursor;

				-- Aktualizacja ilosci w tabeli powiązań operacji
				UPDATE HM.RO
				SET ilosc = temp_ro.ilosc_ro_new
				FROM HM.RO ro
				JOIN @temp_ro temp_ro ON ro.id = temp_ro.id

				-- Aktualizacja operacji zamówień
				UPDATE HM.OP SET
				ilosc_rozl = temp_ro.ilosc_SUM,
				ok = IIF(op.ilosc = temp_ro.ilosc_SUM OR op.flag & 0x2200 = 0x2200, 1, 0),
				datarozl = IIF(op.ilosc = temp_ro.ilosc_SUM OR op.flag & 0x2200 = 0x2200, CAST( GETDATE() AS Date ), NULL),
				wartosc_rozl = (wartosc / ilosc) * temp_ro.ilosc_ro_new
				FROM HM.OP op
				JOIN @temp_ro temp_ro ON temp_ro.id_zp = op.id;

				-- Aktualizacja operacji zamówieia po skasowaniu pozycji
				-- Tabela pomocnicza sumy wszystkich ilosci z powiazanych dokumentow
				DECLARE @deleted_dp_sum TABLE (id int, ilosc_SUM float);
				INSERT INTO @deleted_dp_sum
				SELECT deleted_operations.id, SUM(ro.ilosc) AS ilosc_SUMA 
				FROM HM.RO ro
				JOIN @deleted_operations deleted_operations ON deleted_operations.id = ro.id1
				GROUP BY deleted_operations.id;

				-- Aktualizacja operacji zamówienia po skasowaniu pozycji
				UPDATE HM.OP SET
				ilosc_rozl = deleted_dp_sum.ilosc_SUM,
				ok = IIF(op.ilosc=deleted_dp_sum.ilosc_SUM, 1, 0),
				datarozl = IIF(op.ilosc=deleted_dp_sum.ilosc_SUM, CAST( GETDATE() AS Date ), NULL),
				wartosc_rozl = (wartosc / ilosc) * deleted_dp_sum.ilosc_SUM
				FROM HM.OP op
				JOIN @deleted_dp_sum deleted_dp_sum ON deleted_dp_sum.id = op.id;

				-- Aktualizacja wartosci w tabeli powiązań operacji
				UPDATE HM.RO SET
				ro.wartosc = op.wartosc_rozl
				FROM HM.RO ro
				JOIN HM.OP op ON ro.id1 = op.id
				JOIN @temp_ro temp_ro on temp_ro.id = ro.id

				-- Id transakcji zamówienia powiązana z dokumentem
				DECLARE @tr_zm TABLE(id int);
				INSERT INTO @tr_zm SELECT id1 from hm.tr tr JOIN hm.po po ON po.id2 = tr.id
				WHERE tr.owner_id = @docId AND tr.owner_base = 16;
				
				-- Aktualizacja operacji zamówienia po usunięciu operacji w dokumencie
				UPDATE HM.OP SET
				op.ok = 0,
				op.ilosc_rozl = 0,
				op.wartosc_rozl = 0
				FROM HM.OP op
				LEFT JOIN HM.RO ON ro.id1 = op.id
				JOIN @tr_zm tr_zm ON op.id_transakcji = tr_zm.id
				WHERE ro.id IS NULL;

				-- Suma wartosci rozliczonych operacji zamowienia
				DECLARE @completedValue TABLE (id int, wartosc_rozl float);
				INSERT INTO @completedValue
				SELECT op.id_transakcji, SUM(op.wartosc_rozl) 
				FROM HM.OP op 
				JOIN @tr_zm tr_zm ON op.id_transakcji = tr_zm.id 
				GROUP BY op.id_transakcji;

				-- Ilość nierozliczonych operacji zamówienia
				DECLARE @incompletedOperations_zm TABLE (id int, nrozl int);
				INSERT INTO @incompletedOperations_zm
				SELECT op.id_transakcji, COUNT(*) 
				FROM HM.OP op 
				JOIN @tr_zm tr_zm ON op.id_transakcji = tr_zm.id 
				where ok = 0 
				GROUP BY op.id_transakcji;

				-- Aktualizacja transakcji zamówienia
				UPDATE HM.TR SET
				nrozl_oper = ISNULL(ico.nrozl, 0),
				nrozlilosc = ISNULL(ico.nrozl, 0),
				ok = IIF(ISNULL(ico.nrozl, 0) = 0, 1, 0),
				status = IIF(ISNULL(ico.nrozl, 0) = 0, 16, 8),
				datarozl = IIF(ISNULL(ico.nrozl, 0) = 0, CAST( GETDATE() AS Date ), NULL),
				wartosc_rozl = cv.wartosc_rozl
				FROM HM.TR tr 
				JOIN @tr_zm tr_zm ON tr.id = tr_zm.id
				JOIN @completedValue cv ON cv.id = tr_zm.id
				LEFT JOIN @incompletedOperations_zm ico ON ico.id = tr_zm.id
							   
				-- Aktualizacja stanu zamówienia w tabeli ZO			   
				UPDATE HM.ZO SET
				ok = IIF(ISNULL(ico.nrozl, 0) = 0, 1, 0),
				rozlmg = IIF(TR.status = 16, 0x21, 0x01)
				FROM HM.ZO ZO
				JOIN HM.TR TR ON TR.owner_id = ZO.id AND TR.owner_base = 45
				JOIN @tr_zm tr_zm ON tr_zm.id = TR.id
				LEFT JOIN @incompletedOperations_zm ico ON ico.id = tr_zm.id

			END

			-- Aktualizacja pól własnych dokumentu
			exec HM.UpdateCustomFieldsFromXML
				@docData = @docData,
				@moduleCode = @moduleCode, 
				@docId = @docId,
				@docType = 0
			
			EXEC sp_xml_removedocument @handle;

			EXEC [HM].[UpdateSaleDocumentRIFromXML] @docId, @docData , @userId , @moduleCode

			COMMIT TRANSACTION;
		
			-- odswiezamy powiazane zamowienia
			-- m.in. przyciski do tworzenia dokumentow realizujacych : 'Dokument sprzedazy' i 'Dokument wydania'
			INSERT LOG_BASE (baseName, rec_id, operation, term)
			SELECT 'ZO', TRzo.owner_id, 3, @@SPID
			  FROM HM.TR AS TRdk
			       INNER JOIN HM.PO ON TRdk.id = PO.id2
				   INNER JOIN HM.TR AS TRzo ON PO.id1 = TRzo.id
			 WHERE TRdk.owner_base = 16 AND TRdk.owner_id = @docId
			       AND TRzo.owner_base = 45

			EXEC [HM].[ReadSaleDocumentAsXML] @docId, @userId, @moduleCode
	END TRY
	BEGIN CATCH
		IF @@TRANCOUNT > 0
		BEGIN
			ROLLBACK TRANSACTION;

			THROW;
		END
	END CATCH
END