feat: Implement mfr truncation fix and enhance invoice handling
Playwright Tests / test (push) Canceled after 0s
Playwright Tests / test (push) Canceled after 0s
- Added a new SQL script to address the "String or binary data would be truncated" error in mfr sync by widening the Note fields in service objects and companies to NVARCHAR(MAX). - Updated the table types and associated stored procedures to accommodate the changes, ensuring compatibility with existing data. - Queued a re-sync for previously rejected rows due to truncation issues. - Created application logins for fuchs_fds and fuchs_web with placeholder passwords for initial setup. - Introduced functions for invoice backdating and invoice date retrieval to streamline invoice processing. - Developed a password generation function with customizable parameters for length and character types. - Added a random number generation function to support password creation.
This commit is contained in:
@@ -12,9 +12,13 @@ CREATE FUNCTION [dbo].[fds__fn_IntermediateIsAllocatedToOther]
|
||||
RETURNS bit
|
||||
AS
|
||||
BEGIN
|
||||
DECLARE @IsA bit = CASE WHEN EXISTS (SELECT * FROM [dbo].[fds__invoices] as intermediates JOIN [dbo].[fds__invoice_details] as id on intermediates.[Id] = id.[InvId] and id.[AllocatedTo_InvId] is not null
|
||||
-- An allocation only counts while the crediting invoice is alive: once that invoice is cancelled
|
||||
-- (storno) its credit line is void and the Abschlagsrechnung must be offered again (ADR 0034).
|
||||
DECLARE @IsA bit = CASE WHEN EXISTS (SELECT 1 FROM [dbo].[fds__invoices] as intermediates JOIN [dbo].[fds__invoice_details] as id on intermediates.[Id] = id.[InvId] and id.[AllocatedTo_InvId] is not null
|
||||
JOIN [dbo].[fds__invoices] as non_intermediates ON id.[AllocatedTo_InvId] = non_intermediates.[Id] and id.[AllocatedTo_InvId] is not null
|
||||
WHERE intermediates.[Id] = @Intermediate_InvID and (@Target_InvID is null or non_intermediates.[Id] <> @Target_InvID))
|
||||
WHERE intermediates.[Id] = @Intermediate_InvID
|
||||
and ISNULL(non_intermediates.[IsCanceled], 0) = 0
|
||||
and (@Target_InvID is null or non_intermediates.[Id] <> @Target_InvID))
|
||||
THEN 1 ELSE 0 END;
|
||||
|
||||
RETURN @isA;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
-- =============================================
|
||||
-- Description: Invoice backdating (ADR 0032). Returns the date an invoice may be backdated to
|
||||
-- (the last working day Mon-Fri of the previous month, Europe/Berlin), or NULL when
|
||||
-- backdating is not allowed:
|
||||
-- * @authuser needs fds_inv > 2, and
|
||||
-- * no invoice may have been finalized after that date yet (invoice numbers are
|
||||
-- issued in date order; DateFinalized is stored in UTC, hence the 2h margin).
|
||||
-- Single source for fds__setInvoiceFinal (@backdate = 1) and the preview dialog.
|
||||
-- The check is only race-free inside fds__setInvoiceFinal, which serializes all
|
||||
-- finalizations with a transaction-owned app lock; the preview call is advisory.
|
||||
-- =============================================
|
||||
CREATE FUNCTION [dbo].[fds__fn_invoiceBackdate]
|
||||
(
|
||||
@authuser varchar(25)
|
||||
)
|
||||
RETURNS date
|
||||
AS
|
||||
BEGIN
|
||||
IF [dbo].[fis_getModuleAuth]('fds_inv', @authuser) <= 2
|
||||
RETURN NULL;
|
||||
|
||||
DECLARE @today date = CAST(SYSDATETIMEOFFSET() AT TIME ZONE 'W. Europe Standard Time' AS date);
|
||||
DECLARE @eom date = EOMONTH(@today, -1);
|
||||
-- DATEFIRST-independent weekday: 0 = Monday ... 5 = Saturday, 6 = Sunday
|
||||
DECLARE @bd date = DATEADD(day, CASE DATEDIFF(day, '19000101', @eom) % 7 WHEN 5 THEN -1 WHEN 6 THEN -2 ELSE 0 END, @eom);
|
||||
|
||||
IF EXISTS (SELECT 0 FROM [dbo].[fds__invoices]
|
||||
WHERE [DateFinalized] IS NOT NULL
|
||||
AND [DateFinalized] >= DATEADD(HOUR, -2, CAST(DATEADD(DAY, 1, @bd) AS datetime)))
|
||||
RETURN NULL;
|
||||
|
||||
RETURN @bd;
|
||||
END
|
||||
@@ -0,0 +1,18 @@
|
||||
-- =============================================
|
||||
-- Description: The invoice date ("Rechnungsdatum", ADR 0032) as a German calendar day:
|
||||
-- DateFinalized (the finalisation - or, when backdated, the backdated - moment),
|
||||
-- falling back to DateCreated for drafts. Both columns are stored in UTC.
|
||||
-- SQL twin of Fuchs/code/InvoiceDates.IssueDate. Every list, report, export and
|
||||
-- reminder that shows or groups by an invoice date uses this function (ADR 0035).
|
||||
-- Also used for reminders (fds__reminder has the same DateFinalized/DateCreated pair).
|
||||
-- =============================================
|
||||
CREATE FUNCTION [dbo].[fds__fn_invoiceDate]
|
||||
(
|
||||
@DateFinalized datetime,
|
||||
@DateCreated datetime
|
||||
)
|
||||
RETURNS date
|
||||
AS
|
||||
BEGIN
|
||||
RETURN CAST(ISNULL(@DateFinalized, @DateCreated) AT TIME ZONE 'UTC' AT TIME ZONE 'W. Europe Standard Time' AS date);
|
||||
END
|
||||
@@ -20,11 +20,11 @@ BEGIN
|
||||
|
||||
WITH inv as (
|
||||
SELECT
|
||||
[Dateofcreation] = i.[DateFinalized]
|
||||
[Dateofcreation] = [dbo].[fds__fn_invoiceDate](i.[DateFinalized], i.[DateCreated])
|
||||
,i.[InvoiceBalance]
|
||||
,[InvoiceBalanceNetto] = i.[InvoiceBalance_net]
|
||||
FROM [dbo].[fds__invoices] as i
|
||||
WHERE i.[isFinal] = 1 AND [dbo].[date_monthfirst](i.[DateFinalized]) = @thismonthfirst
|
||||
WHERE i.[isFinal] = 1 AND [dbo].[date_monthfirst]([dbo].[fds__fn_invoiceDate](i.[DateFinalized], i.[DateCreated])) = @thismonthfirst
|
||||
)
|
||||
SELECT TOP(1) @ret = FORMAT( SUM( ISNULL(inv.[InvoiceBalanceNetto],0) ) * 0.001, '#,0 k€', 'de') FROM inv;
|
||||
END
|
||||
|
||||
@@ -14,7 +14,7 @@ BEGIN
|
||||
DECLARE @groups TABLE([usergroup_id] varchar(5));
|
||||
INSERT INTO @groups SELECT * from STRING_SPLIT(@usergroup_id,',');
|
||||
|
||||
DECLARE @isMember bit = CASE WHEN EXISTS (SELECT * FROM [dbo].[fis_usergroups] as g
|
||||
DECLARE @isMember bit = CASE WHEN EXISTS (SELECT 1 FROM [dbo].[fis_usergroups] as g
|
||||
JOIN @groups as groupstotest On groupstotest.[usergroup_id] = g.[usergroup_id]
|
||||
JOIN [dbo].[fis_usergroups_members] as gm on g.[usergroup_id] = gm.[usergroup_id] and gm.[DateDeleted] is null AND g.[DateDeleted] is null
|
||||
JOIN [dbo].[fis_useraccounts] as u on gm.[useraccount_id] = u.[useraccount_id]
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
|
||||
|
||||
CREATE FUNCTION [dbo].[ocms_fn_generatePassword] (
|
||||
@length int
|
||||
, @specialChars bit = 1
|
||||
, @nums bit = 1
|
||||
, @lowerCase bit = 1
|
||||
)
|
||||
RETURNS varchar(255)
|
||||
AS
|
||||
BEGIN
|
||||
DECLARE @randInt int;
|
||||
DECLARE @NewCharacter varchar(1);
|
||||
DECLARE @NewPassword TABLE([typ] char(1), [char] char(1), [order] int);
|
||||
|
||||
SET @length = CASE WHEN @length > 255 THEN 255 ELSE @length END;
|
||||
|
||||
DECLARE @cnt int = 0, @position as int;
|
||||
--random characters
|
||||
WHILE (@cnt < @length)
|
||||
BEGIN
|
||||
SELECT @randInt = [dbo].[ocms_fn_randbetween](33,122)
|
||||
|
||||
IF (CASE WHEN (@randInt>=33 AND @randInt<=47) AND @specialChars = 1 THEN 1
|
||||
WHEN (@randInt>=48 AND @randInt<=57) AND @nums = 1 THEN 1
|
||||
WHEN (@randInt>=58 AND @randInt<=64) AND @specialChars = 1 THEN 1
|
||||
WHEN (@randInt>=65 AND @randInt<=90) THEN 1
|
||||
WHEN (@randInt>=91 AND @randInt<=93) AND @specialChars = 1 THEN 1
|
||||
WHEN (@randInt>=97 AND @randInt<=122) AND @lowerCase = 1 THEN 1
|
||||
ELSE 0
|
||||
END) = 1
|
||||
BEGIN
|
||||
SET @cnt = @cnt + 1;
|
||||
|
||||
INSERT INTO @NewPassword
|
||||
VALUES (CASE WHEN (@randInt>=33 AND @randInt<=47) THEN 's'
|
||||
WHEN (@randInt>=48 AND @randInt<=57) THEN 'n'
|
||||
WHEN (@randInt>=58 AND @randInt<=64) THEN 's'
|
||||
WHEN (@randInt>=65 AND @randInt<=90) THEN 'u'
|
||||
WHEN (@randInt>=91 AND @randInt<=93) THEN 's'
|
||||
WHEN (@randInt>=97 AND @randInt<=122) THEN 'l'
|
||||
END,
|
||||
CHAR(@randInt), @cnt);
|
||||
END
|
||||
END
|
||||
|
||||
DECLARE @min_n int = CASE WHEN @length > 4 AND @length < 11 THEN 1 ELSE FLOOR(@length * 0.1) END;
|
||||
DECLARE @min_s int = FLOOR(@length * 0.1);
|
||||
DECLARE @min_l int = FLOOR(@length * 0.4);
|
||||
DECLARE @min_u int = FLOOR(@length * 0.4);
|
||||
|
||||
WHILE (SELECT COUNT(*) FROM @NewPassword WHERE [typ] = 'n') < @min_n AND @length > 0 AND @nums = 1
|
||||
BEGIN
|
||||
SET @position = [dbo].[ocms_fn_randbetween](1,@length);
|
||||
UPDATE @NewPassword SET [char] = CHAR([dbo].[ocms_fn_randbetween](48,57)), [typ] = 'n' WHERE [order] = @position;
|
||||
END
|
||||
|
||||
WHILE (SELECT COUNT(*) FROM @NewPassword WHERE [typ] = 'l') < @min_l AND @length > 0 AND @lowerCase = 1
|
||||
BEGIN
|
||||
SET @position = [dbo].[ocms_fn_randbetween](1,@length);
|
||||
UPDATE @NewPassword SET [char] = CHAR([dbo].[ocms_fn_randbetween](97,122)), [typ] = 'l' WHERE [order] = @position;
|
||||
END
|
||||
|
||||
WHILE (SELECT COUNT(*) FROM @NewPassword WHERE [typ] = 'u') < @min_n AND @length > 0
|
||||
BEGIN
|
||||
SET @position = [dbo].[ocms_fn_randbetween](1,@length);
|
||||
UPDATE @NewPassword SET [char] = CHAR([dbo].[ocms_fn_randbetween](65,90)), [typ] = 'u' WHERE [order] = @position;
|
||||
END
|
||||
|
||||
WHILE (SELECT COUNT(*) FROM @NewPassword WHERE [typ] = 's') < @min_s AND @length > 0 AND @specialChars = 1
|
||||
BEGIN
|
||||
SET @position = [dbo].[ocms_fn_randbetween](1,@length);
|
||||
DECLARE @nc char(1), @nt char(1);
|
||||
select @randInt=[dbo].[ocms_fn_randbetween](33,122)
|
||||
|
||||
UPDATE @NewPassword SET [char] = CHAR(@randint), [typ] = 's' WHERE [order] = @position AND (CASE WHEN (@randInt>=33 AND @randInt<=47) THEN 's'
|
||||
WHEN (@randInt>=48 AND @randInt<=57) THEN 'n'
|
||||
WHEN (@randInt>=58 AND @randInt<=64) THEN 's'
|
||||
WHEN (@randInt>=65 AND @randInt<=90) THEN 'u'
|
||||
WHEN (@randInt>=91 AND @randInt<=93) THEN 's'
|
||||
WHEN (@randInt>=97 AND @randInt<=122) THEN 'l'
|
||||
END) = 's';
|
||||
END
|
||||
|
||||
|
||||
|
||||
RETURN (Cast((SELECT [CHAR] as [text()] FROM @NewPassword FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)') as varchar(255)));
|
||||
END;
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
CREATE FUNCTION [dbo].[ocms_fn_randbetween](@bottom integer, @top integer)
|
||||
RETURNS integer
|
||||
AS
|
||||
BEGIN
|
||||
RETURN (select cast(round((@top-@bottom) * [rn] +@bottom,0) as integer) from [dbo].[ocms_fn_rand])
|
||||
END
|
||||
@@ -96,7 +96,7 @@ BEGIN
|
||||
SELECT TOP(1)
|
||||
o.*
|
||||
, [InvoiceId] = inv.[InvoiceId]
|
||||
, [InvoiceDate] = inv.[DateFinalized]
|
||||
, [InvoiceDate] = [dbo].[fds__fn_invoiceDate](inv.[DateFinalized], inv.[DateCreated])
|
||||
, [hasFile] = CAST ( CASE WHEN o.[file] is null THEN 0 ELSE 1 END as bit)
|
||||
, [UserNameFinalized] = [dbo].[fis_admin_getUserName_byID](o.[UserFinalized])
|
||||
, [UserEmailFinalized] = [dbo].[fis_admin_getUserEmail_byID](o.[UserFinalized])
|
||||
|
||||
@@ -43,11 +43,16 @@ BEGIN
|
||||
;
|
||||
|
||||
|
||||
-- The invoice date (fds__fn_invoiceDate: DateFinalized as German day, ADR 0035) drives both the export
|
||||
-- period and the Belegdatum; DateCreated is only the draft's creation and may lie in a later month for
|
||||
-- a backdated invoice.
|
||||
-- [DateOfCreation] keeps its name for the callers (HandleDatev / FdsMfr.GetDatevZip) but carries that day.
|
||||
DECLARE @inv TABLE([Id] varchar(20), [InvoiceID] varchar(255), [DocumentName] nvarchar(255), [DateOfCreation] date, [fds] bit, [file_guid] varchar(36));
|
||||
INSERT INTO @inv
|
||||
SELECT [Id],[invoiceid],[DocumentName],[DateOfCreation] = [DateCreated],[fds] = IIF([isExternal] = 0,1,0), [file_guid]
|
||||
SELECT [Id],[invoiceid],[DocumentName],[DateOfCreation] = d.[InvoiceDate],[fds] = IIF([isExternal] = 0,1,0), [file_guid]
|
||||
FROM [dbo].[fds__invoices]
|
||||
where CAST([DateCreated] as date) between @startdate AND @enddate and [isfinal] = 1;
|
||||
CROSS APPLY (SELECT [InvoiceDate] = [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated])) as d
|
||||
where [isfinal] = 1 and d.[InvoiceDate] between @startdate AND @enddate;
|
||||
|
||||
SELECT
|
||||
inv.[Id],inv.[InvoiceID],inv.[DocumentName],inv.[fds]
|
||||
@@ -78,15 +83,15 @@ BEGIN
|
||||
,[deb_cred] = CASE WHEN [invoiceBalance] >= 0 THEN 'S' ELSE 'H' END
|
||||
,[customer] = (SELECT TOP(1) [ExternalId] FROM [dbo].[mfr__companies] as c WHERE c.[Id] = iv.[CustomerId])
|
||||
,[contra_account] = ca.[account]
|
||||
,[Belegdatum] = iv.[DateCreated]
|
||||
,[Belegdatum] = i.[DateOfCreation] -- the invoice date (DateFinalized as German day), see @inv
|
||||
,[Buchungstext] = (SELECT TOP(1) SReq.[name] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id])
|
||||
,[DateOfCreation] = iv.[DateCreated]
|
||||
,[file_guid]
|
||||
from [dbo].[fds__invoices] as iv
|
||||
,[DateOfCreation] = i.[DateOfCreation]
|
||||
,[file_guid] = iv.[file_guid]
|
||||
from [dbo].[fds__invoices] as iv
|
||||
JOIN @inv as i on iv.[Id] = i.[Id]
|
||||
LEFT JOIN [dbo].[fds__invoice_details] as d on iv.[Id] = d.[InvId]
|
||||
LEFT JOIN sc on iv.[id] = sc.[invoice.Id]
|
||||
LEFT JOIN @contraaccounts as ca ON (CASE WHEN d.InvoiceOptions like '%§13b%' and RIGHT(ca.[name], 3) = '13b' then 1 WHEN d.InvoiceOptions like '%§13b%' THEN 0 when ISNULL(iv.[InvoiceVAT_1], 19.0) = ca.[vat] THEN 1 ELSE 0 END) = 1
|
||||
where iv.Id in (SELECT [Id] FROM @inv)
|
||||
)
|
||||
select
|
||||
[Umsatz (ohne Soll/Haben-Kz)] = ABS([balance])--CAST(FORMAT(ABS([balance]), '0.00', 'de') as varchar(13))
|
||||
|
||||
@@ -16,15 +16,15 @@ BEGIN
|
||||
IF @type = 'invoice'
|
||||
BEGIN
|
||||
SELECT TOP(1)
|
||||
[Id] = CAST([Id] as varchar(20)),[type] = @type, [InvoiceID],[DocumentName],[DateOfCreation] = [DateCreated],[fds] = CAST( 1 as bit), [file]
|
||||
,[order] = ROW_NUMBER() OVER (ORDER BY [DateCreated] ASC)
|
||||
[Id] = CAST([Id] as varchar(20)),[type] = @type, [InvoiceID],[DocumentName],[DateOfCreation] = [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated]),[fds] = CAST( 1 as bit), [file]
|
||||
,[order] = ROW_NUMBER() OVER (ORDER BY [DateFinalized] ASC)
|
||||
FROM [dbo].[fds__invoices] WHERE [id] = @reportid AND [isFinal] = 1;
|
||||
END
|
||||
ELSE IF @type = 'reminder'
|
||||
BEGIN
|
||||
SELECT TOP(1)
|
||||
[Id] = CAST([Id] as varchar(20)),[type] = @type, [ReminderID] = '',[DocumentName],[isInvoice] = 1,[DateOfCreation] = [DateCreated],[fds] = CAST( 1 as bit), [file]
|
||||
,[order] = ROW_NUMBER() OVER (ORDER BY [DateCreated] ASC)
|
||||
[Id] = CAST([Id] as varchar(20)),[type] = @type, [ReminderID] = '',[DocumentName],[isInvoice] = 1,[DateOfCreation] = [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated]),[fds] = CAST( 1 as bit), [file]
|
||||
,[order] = ROW_NUMBER() OVER (ORDER BY [DateFinalized] ASC)
|
||||
FROM [dbo].[fds__reminder] WHERE [id] = @reportid AND [isFinal] = 1;
|
||||
END
|
||||
|
||||
|
||||
@@ -46,9 +46,9 @@ BEGIN
|
||||
|
||||
|
||||
DECLARE @inv TABLE([Id] varchar(15), [InvoiceID] varchar(255), [URI] nvarchar(255), [DocumentName] nvarchar(255), [DateOfCreation] date, [fds] bit);
|
||||
SELECT [Id],[invoiceid],[DocumentName],[DateOfCreation] = [DateCreated],[fds] = IIF([isExternal] = 0,1,0)
|
||||
SELECT [Id],[invoiceid],[DocumentName],[DateOfCreation] = [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated]),[fds] = IIF([isExternal] = 0,1,0)
|
||||
FROM [dbo].[fds__invoices]
|
||||
where CAST([DateCreated] as date) between @startdate AND @enddate and (ISNULL(@include_drafts,0) = 1 OR [isfinal] = 1);
|
||||
where [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated]) between @startdate AND @enddate and (ISNULL(@include_drafts,0) = 1 OR [isfinal] = 1);
|
||||
|
||||
DECLARE @SReq TABLE ([id] bigint, [DateOfCreation] datetime, [name] nvarchar(255), [invoice.Id] varchar(15), [customer.ExternalId] bigint, [customer.Id] bigint, [ExternalId] nvarchar(255), [fds] bit);
|
||||
INSERT INTO @SReq
|
||||
@@ -87,9 +87,9 @@ BEGIN
|
||||
,[deb_cred] = CASE WHEN [invoiceBalance] >= 0 THEN 'S' ELSE 'H' END
|
||||
,[customer] = (SELECT TOP(1) [customer.ExternalId] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id] and [customer.ExternalId] is not null ORDER BY SReq.DateOfCreation ASC)
|
||||
,[contra_account] = ca.[account]
|
||||
,[Belegdatum] = FORMAT(iv.[DateCreated], 'dd.MM.yy')
|
||||
,[Belegdatum] = FORMAT([dbo].[fds__fn_invoiceDate](iv.[DateFinalized], iv.[DateCreated]), 'dd.MM.yy')
|
||||
,[Buchungstext] = (SELECT TOP(1) SReq.[name] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id])
|
||||
,[DateOfCreation] = iv.[DateCreated]
|
||||
,[DateOfCreation] = [dbo].[fds__fn_invoiceDate](iv.[DateFinalized], iv.[DateCreated])
|
||||
,[DueDate]
|
||||
,[PaymentTerm] = ISNULL([PaymentTerm], @stage1)
|
||||
,[PaymentStatus]
|
||||
|
||||
@@ -69,23 +69,23 @@ BEGIN
|
||||
IF @searchmode = 'i'
|
||||
BEGIN
|
||||
insert into @inv
|
||||
SELECT [Id],[invoiceid],[DocumentName],[DateOfCreation] = [DateCreated],[fds] = IIF([isExternal] = 0,1,0)
|
||||
SELECT [Id],[invoiceid],[DocumentName],[DateOfCreation] = [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated]),[fds] = IIF([isExternal] = 0,1,0)
|
||||
FROM [dbo].[fds__invoices]
|
||||
where [InvoiceID] = @search OR [InvoiceID] like ('R20[0-9][0-9][-]' + @search);
|
||||
END
|
||||
ELSE IF @searchmode = 'c'
|
||||
BEGIN
|
||||
insert into @inv
|
||||
SELECT [Id],[invoiceid],[DocumentName],[DateOfCreation] = [DateCreated],[fds] = IIF([isExternal] = 0,1,0)
|
||||
SELECT [Id],[invoiceid],[DocumentName],[DateOfCreation] = [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated]),[fds] = IIF([isExternal] = 0,1,0)
|
||||
FROM [dbo].[fds__invoices]
|
||||
WHERE [CustomerId] IN (SELECT [CustomerId] fROM @customerfilter);
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
insert into @inv
|
||||
SELECT [Id],[invoiceid],[DocumentName],[DateOfCreation] = [DateCreated],[fds] = IIF([isExternal] = 0,1,0)
|
||||
SELECT [Id],[invoiceid],[DocumentName],[DateOfCreation] = [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated]),[fds] = IIF([isExternal] = 0,1,0)
|
||||
FROM [dbo].[fds__invoices]
|
||||
WHERE CAST([DateCreated] as date) between @startdate AND @enddate and (ISNULL(@include_drafts,0) = 1 OR [isfinal] = 1);
|
||||
WHERE [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated]) between @startdate AND @enddate and (ISNULL(@include_drafts,0) = 1 OR [isfinal] = 1);
|
||||
END;
|
||||
|
||||
|
||||
@@ -126,9 +126,9 @@ BEGIN
|
||||
,[deb_cred] = CASE WHEN [invoiceBalance] >= 0 THEN 'S' ELSE 'H' END
|
||||
--,[customer] = (SELECT TOP(1) [customer.ExternalId] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id] and [customer.ExternalId] is not null ORDER BY SReq.DateOfCreation ASC)
|
||||
,[contra_account] = ca.[account]
|
||||
,[Belegdatum] = FORMAT(iv.[DateCreated], 'dd.MM.yy')
|
||||
,[Belegdatum] = FORMAT([dbo].[fds__fn_invoiceDate](iv.[DateFinalized], iv.[DateCreated]), 'dd.MM.yy')
|
||||
,[Buchungstext] = (SELECT TOP(1) SReq.[name] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id])
|
||||
,[DateOfCreation] = iv.[DateCreated]
|
||||
,[DateOfCreation] = [dbo].[fds__fn_invoiceDate](iv.[DateFinalized], iv.[DateCreated])
|
||||
,[DueDate]
|
||||
,[PaymentTerm] = ISNULL([PaymentTerm], @stage1)
|
||||
,[PaymentStatus]
|
||||
|
||||
@@ -74,9 +74,9 @@ BEGIN
|
||||
|
||||
DECLARE @inv TABLE([Id] varchar(15), [InvoiceID] varchar(255), [DocumentName] nvarchar(255), [DateOfCreation] date, [fds] bit);
|
||||
INSERT INTO @inv
|
||||
SELECT [Id],[invoiceid],[DocumentName],[DateOfCreation] = [DateCreated],[fds] = IIF([isExternal] = 0,1,0)
|
||||
SELECT [Id],[invoiceid],[DocumentName],[DateOfCreation] = [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated]),[fds] = IIF([isExternal] = 0,1,0)
|
||||
FROM [dbo].[fds__invoices]
|
||||
where CAST([DateCreated] as date) between @startdate AND @enddate
|
||||
where [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated]) between @startdate AND @enddate
|
||||
and (ISNULL(@include_drafts,0) = 1 OR [isfinal] = 1)
|
||||
and (@only_drafts = 0 OR [isfinal] = 0)
|
||||
and (@only_akonto = 0 OR [InvoiceType] = 'i')
|
||||
@@ -120,9 +120,9 @@ BEGIN
|
||||
,[deb_cred] = CASE WHEN [invoiceBalance] >= 0 THEN 'S' ELSE 'H' END
|
||||
,[customer] = (SELECT TOP(1) [customer.ExternalId] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id] and [customer.ExternalId] is not null ORDER BY SReq.DateOfCreation ASC)
|
||||
,[contra_account] = ca.[account]
|
||||
,[Belegdatum] = FORMAT(iv.[DateCreated], 'dd.MM.yy')
|
||||
,[Belegdatum] = FORMAT([dbo].[fds__fn_invoiceDate](iv.[DateFinalized], iv.[DateCreated]), 'dd.MM.yy')
|
||||
,[Buchungstext] = (SELECT TOP(1) SReq.[name] FROM @SReq as sreq WHERE iv.[Id] = sreq.[invoice.Id])
|
||||
,[DateOfCreation] = iv.[DateCreated]
|
||||
,[DateOfCreation] = [dbo].[fds__fn_invoiceDate](iv.[DateFinalized], iv.[DateCreated])
|
||||
,[DueDate]
|
||||
,[PaymentTerm] = ISNULL([PaymentTerm], @stage1)
|
||||
,[PaymentStatus]
|
||||
|
||||
@@ -68,7 +68,7 @@ BEGIN
|
||||
)
|
||||
SELECT TOP(1) o.*
|
||||
,inv.[InvoiceId]
|
||||
,[InvoiceDate] = inv.[DateFinalized]
|
||||
,[InvoiceDate] = [dbo].[fds__fn_invoiceDate](inv.[DateFinalized], inv.[DateCreated])
|
||||
,[InvoiceFileName] = inv.[DocumentName]
|
||||
,[InvoiceFile] = CASE WHEN ISNULL(@includefile,0) = 1 THEN inv.[file] else NULL END -- do not return file if not explicitly requested
|
||||
,[hasFile] = CAST ( CASE WHEN o.[file] is null THEN 0 ELSE 1 END as bit)
|
||||
|
||||
@@ -13,9 +13,9 @@ BEGIN
|
||||
DECLARE @idbigint bigint = TRY_CAST(@reportid as bigint);
|
||||
|
||||
SELECT TOP(1)
|
||||
[Id] = CAST([Id] as varchar(20)),[InvoiceID],[URI] = '',[DocumentName],[isInvoice] = 1,[DateOfCreation] = [DateCreated],[fds] = CAST( 1 as bit)
|
||||
[Id] = CAST([Id] as varchar(20)),[InvoiceID],[URI] = '',[DocumentName],[isInvoice] = 1,[DateOfCreation] = [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated]),[fds] = CAST( 1 as bit)
|
||||
, [file] = ISNULL(iv.[file], (SELECT TOP(1) mfrf.[file] FROM [dbo].[fds__mfr_invoicefiles] as mfrf where iv.[IsExternal] = 1 and mfrf.[id] = iv.[externalid]))
|
||||
, [order] = ROW_NUMBER() OVER (ORDER BY [DateCreated] ASC)
|
||||
, [order] = ROW_NUMBER() OVER (ORDER BY [DateFinalized] ASC)
|
||||
FROM [dbo].[fds__invoices] as iv
|
||||
WHERE [id] = @reportid AND [isFinal] = 1;
|
||||
;
|
||||
|
||||
@@ -216,14 +216,14 @@ BEGIN
|
||||
[MappingId] [nvarchar](255) NULL,
|
||||
[ExternalId] [nvarchar](255) NULL,
|
||||
[Name] [nvarchar](255) NULL,
|
||||
[Note] [nvarchar](255) NULL,
|
||||
[Note] [nvarchar](max) NULL,
|
||||
[SupportTelephone] [nvarchar](255) NULL,
|
||||
[SupportFax] [nvarchar](255) NULL,
|
||||
[SupportMail] [nvarchar](255) NULL,
|
||||
[QuickSearch] [nvarchar](255) NULL,
|
||||
[DateModified] [datetime] NOT NULL,
|
||||
[CustomValues] [nvarchar](max) NOT NULL,
|
||||
[MainContactId] [bigint] NOT NULL,
|
||||
[CustomValues] [nvarchar](max) NULL,
|
||||
[MainContactId] [bigint] NULL,
|
||||
[address] nvarchar(1000) null
|
||||
);
|
||||
INSERT INTO @company SELECT DISTINCT cy.*, [address] = [dbo].[fds__getCompanyAddress](cy.[id]) FROM [mfr__companies] as cy JOIN @SReq as s on cy.id = s.[CustomerId];
|
||||
@@ -377,6 +377,7 @@ BEGIN
|
||||
)
|
||||
SELECT [Id] = CAST(i.[Id] as varchar(20))
|
||||
,i.[DateCreated]
|
||||
,[InvoiceDate] = [dbo].[fds__fn_invoiceDate](i.[DateFinalized], i.[DateCreated])
|
||||
,[isFinal]
|
||||
,[isSent]
|
||||
,i.[DocumentName]
|
||||
@@ -387,10 +388,10 @@ BEGIN
|
||||
WHEN [DueDate] is null THEN 'op'
|
||||
WHEN [invoiceBalance] < 0 THEN ''
|
||||
WHEN @today >= [DueDate] THEN 'due'
|
||||
WHEN @stage1 <> '' AND ISNULL(rem.[#],0) = 0 AND @today > [dbo].[date_addcustom](ISNULL(DueDate, i.[DateCreated]), @stage1) THEN 'ovd'
|
||||
WHEN @stage1 <> '' AND ISNULL(rem.[#],0) = 0 AND @today > [dbo].[date_addcustom](ISNULL(DueDate, [dbo].[fds__fn_invoiceDate](i.[DateFinalized], i.[DateCreated])), @stage1) THEN 'ovd'
|
||||
WHEN ISNULL(rem.[#],0) > 0 THEN 'rem'
|
||||
END
|
||||
,[order] = ROW_NUMBER() OVER ( ORDER BY inv.[isChild], inv.[baseorder], i.[isFinal] DESC, i.[datecreated] ASC )
|
||||
,[order] = ROW_NUMBER() OVER ( ORDER BY inv.[isChild], inv.[baseorder], i.[isFinal] DESC, [dbo].[fds__fn_invoiceDate](i.[DateFinalized], i.[DateCreated]) ASC )
|
||||
FROM [dbo].[fds__invoices] as i
|
||||
JOIN inv on i.[Id] = inv.[Id]
|
||||
LEFT JOIN reminder as rem on inv.id = rem.[InvId]
|
||||
|
||||
@@ -189,14 +189,14 @@ BEGIN
|
||||
[MappingId] [nvarchar](255) NULL,
|
||||
[ExternalId] [nvarchar](255) NULL,
|
||||
[Name] [nvarchar](255) NULL,
|
||||
[Note] [nvarchar](255) NULL,
|
||||
[Note] [nvarchar](max) NULL,
|
||||
[SupportTelephone] [nvarchar](255) NULL,
|
||||
[SupportFax] [nvarchar](255) NULL,
|
||||
[SupportMail] [nvarchar](255) NULL,
|
||||
[QuickSearch] [nvarchar](255) NULL,
|
||||
[DateModified] [datetime] NOT NULL,
|
||||
[CustomValues] [nvarchar](max) NOT NULL,
|
||||
[MainContactId] [bigint] NOT NULL,
|
||||
[CustomValues] [nvarchar](max) NULL,
|
||||
[MainContactId] [bigint] NULL,
|
||||
[address] nvarchar(1000) null
|
||||
);
|
||||
INSERT INTO @company SELECT DISTINCT cy.*, [address] = [dbo].[fds__getCompanyAddress](cy.[id]) FROM [mfr__companies] as cy JOIN @SReq as s on cy.id = s.[CustomerId];
|
||||
@@ -228,6 +228,7 @@ BEGIN
|
||||
-- Add virtual items for intermediate invoices
|
||||
With associated_interims as (
|
||||
SELECT inv.InvoiceVAT_1
|
||||
,[InvId] = inv.[Id] --carried as reference_InvId so fds__setInvoiceFinal can record the allocation
|
||||
,inv.InvoiceBalance_net
|
||||
,inv.DocumentName
|
||||
,inv.DateCreated
|
||||
@@ -259,7 +260,7 @@ BEGIN
|
||||
,[NameOrNumber] = REPLACE(ai.DocumentName, '.pdf','')
|
||||
,[CustomValues] = NULL
|
||||
,[Note] = '<p>' + 'Anrechnung der ' + REPLACE(ai.DocumentName, '.pdf','') + ' vom ' + FORMAT(ai.[dateFinalized], 'dd.MM.yyyy', 'de-de') + '</p>'
|
||||
,[ExternalId] = NULL
|
||||
,[ExternalId] = ai.[InvId] --referenced intermediate invoice (-> reference_InvId)
|
||||
,[Discount] = NULL
|
||||
,[VAT] = ai.InvoiceVAT_1
|
||||
,[IsManual] = 1
|
||||
@@ -289,7 +290,7 @@ BEGIN
|
||||
,[NameOrNumber] = 'offener Betrag aus ' + REPLACE(ai.DocumentName, '.pdf','')
|
||||
,[CustomValues] = NULL
|
||||
,[Note] = '<p>' + 'Berechnung des offenen Betrags aus ' + REPLACE(ai.DocumentName, '.pdf','') + ' vom ' + FORMAT(ai.[dateFinalized], 'dd.MM.yyyy', 'de-de') + '</p><p>bereits gezahlt (brutto): ' + FORMAT([payed], '0.00', 'de') + '€.</p>'
|
||||
,[ExternalId] = NULL
|
||||
,[ExternalId] = ai.[InvId] --referenced intermediate invoice (-> reference_InvId)
|
||||
,[Discount] = NULL
|
||||
,[VAT] = ai.InvoiceVAT_1
|
||||
,[IsManual] = 1
|
||||
@@ -393,6 +394,7 @@ BEGIN
|
||||
, [Note] = IIF(ISNULL([Discount], 0) > 0, '<b>Rabatt '+ FORMAT([discount]*0.01,'#.0%','de-de') + '</b>', '') + ISNULL(itm.[Note],'')
|
||||
, [order] = (itm.[baseorder] * 100) + itm.[order]
|
||||
, [SetItmId]
|
||||
, [reference_InvId] = CASE WHEN itm.[Type] IN ('IntInvoiceAllocation', 'IntInvoiceAllocationDiff') THEN CAST(itm.[ExternalId] as varchar(20)) ELSE NULL END
|
||||
FROM @itm as itm
|
||||
LEFT JOIN [dbo].[fds__custom_vat] as vat ON itm.[Id] = vat.[EntityId] and vat.[EntityType] = 'item';
|
||||
END
|
||||
|
||||
@@ -49,7 +49,7 @@ BEGIN
|
||||
END
|
||||
, [type] = @type
|
||||
, [invoiceid] = inv.[Invoiceid]
|
||||
, [invoicedate] = inv.[DateFinalized]
|
||||
, [invoicedate] = [dbo].[fds__fn_invoiceDate](inv.[DateFinalized], inv.[DateCreated])
|
||||
, [amount] = inv.[InvoiceBalance]
|
||||
, [amount_payed] = CAST( ISNULL([dbo].[fds__fn_InvoicePaymentAmount_full](inv.[Id]),0.0) as numeric(10,2))
|
||||
FROM inv;
|
||||
|
||||
@@ -188,14 +188,14 @@ BEGIN
|
||||
[MappingId] [nvarchar](255) NULL,
|
||||
[ExternalId] [nvarchar](255) NULL,
|
||||
[Name] [nvarchar](255) NULL,
|
||||
[Note] [nvarchar](255) NULL,
|
||||
[Note] [nvarchar](max) NULL,
|
||||
[SupportTelephone] [nvarchar](255) NULL,
|
||||
[SupportFax] [nvarchar](255) NULL,
|
||||
[SupportMail] [nvarchar](255) NULL,
|
||||
[QuickSearch] [nvarchar](255) NULL,
|
||||
[DateModified] [datetime] NOT NULL,
|
||||
[CustomValues] [nvarchar](max) NOT NULL,
|
||||
[MainContactId] [bigint] NOT NULL,
|
||||
[CustomValues] [nvarchar](max) NULL,
|
||||
[MainContactId] [bigint] NULL,
|
||||
[address] nvarchar(1000) null
|
||||
);
|
||||
INSERT INTO @company SELECT DISTINCT cy.*, [address] = [dbo].[fds__getCompanyAddress](cy.[id]) FROM [mfr__companies] as cy JOIN @SReq as s on cy.id = s.[CustomerId];
|
||||
@@ -236,12 +236,12 @@ BEGIN
|
||||
,[NameOrNumber] = REPLACE(inv.DocumentName, '.pdf','')
|
||||
,[CustomValues] = NULL
|
||||
,[Note] = '<p>' + 'Anrechnung der ' + REPLACE(inv.DocumentName, '.pdf','') + ' vom ' + FORMAT(inv.[dateFinalized], 'dd.MM.yyyy', 'de-de') + '</p>'
|
||||
,[ExternalId] = NULL
|
||||
,[ExternalId] = inv.[Id] --referenced intermediate invoice (-> reference_InvId)
|
||||
,[Discount] = NULL
|
||||
,[VAT] = inv.InvoiceVAT_1
|
||||
,[IsManual] = 1
|
||||
,[SortOrder] = ROW_NUMBER() OVER (PARTITION BY srq.[mfr__servicerequest] ORDER BY inv.[dateFinalized], inv.DateCreated)
|
||||
,[Type] = 'PartialInvoice'
|
||||
,[Type] = 'IntInvoiceAllocation' -- same line type as fds__prepInvoice: only this type is taken over as an allocation by fds__setInvoiceFinal
|
||||
,[ServiceRequestId] = -2 --s.[id]
|
||||
,[ServiceObjectId] = Null
|
||||
,[CreatorId] = NULL
|
||||
@@ -292,7 +292,7 @@ BEGIN
|
||||
,[NameOrNumber] = REPLACE(inv.DocumentName, '.pdf','')
|
||||
,[CustomValues] = NULL
|
||||
,[Note] = '<p>' + 'Storno der ' + REPLACE(inv.DocumentName, '.pdf','') + ' vom ' + FORMAT(inv.[dateFinalized], 'dd.MM.yyyy', 'de-de') + '</p>'
|
||||
,[ExternalId] = NULL
|
||||
,[ExternalId] = inv.[Id] --replaced invoice (-> reference_InvId; fds__setInvoiceFinal builds Replaces_InvId from it)
|
||||
,[Discount] = NULL
|
||||
,[VAT] = inv.InvoiceVAT_1
|
||||
,[IsManual] = 1
|
||||
@@ -387,6 +387,7 @@ BEGIN
|
||||
, itm.[Note]
|
||||
, [order] = (itm.[baseorder] * 100) + itm.[order]
|
||||
, [SetItmId]
|
||||
, [reference_InvId] = CASE WHEN itm.[Type] IN ('IntInvoiceAllocation', 'CanceledInvoice') THEN CAST(itm.[ExternalId] as varchar(20)) ELSE NULL END
|
||||
FROM @itm as itm
|
||||
LEFT JOIN [dbo].[fds__custom_vat] as vat ON itm.[Id] = vat.[EntityId] and vat.[EntityType] = 'item';
|
||||
END
|
||||
|
||||
@@ -35,7 +35,7 @@ BEGIN
|
||||
|
||||
WITH inv as (
|
||||
SELECT
|
||||
[Dateofcreation] = i.[DateCreatEd]
|
||||
[Dateofcreation] = [dbo].[fds__fn_invoiceDate](i.[DateFinalized], i.[DateCreated])
|
||||
,i.[InvoiceBalance]
|
||||
,[InvoiceBalanceNetto] = i.[InvoiceBalance_net]
|
||||
FROM [dbo].[fds__invoices] as i
|
||||
|
||||
@@ -39,21 +39,21 @@ BEGIN
|
||||
WITH inv as(
|
||||
select
|
||||
[InvoiceBalance] = SUM( ISNULL(_i.[InvoiceBalance],0) )
|
||||
,[Dateofcreation] = CAST(_i.[DateCreated] as date)
|
||||
,[Dateofcreation] = [dbo].[fds__fn_invoiceDate](_i.[DateFinalized], _i.[DateCreated])
|
||||
,_i.CustomerId
|
||||
,[customerName] = cy.Name
|
||||
,[seq] = ROW_NUMBER() OVER (ORDER BY CAST(_i.[DateCreated] as date))
|
||||
,[seq] = ROW_NUMBER() OVER (ORDER BY [dbo].[fds__fn_invoiceDate](_i.[DateFinalized], _i.[DateCreated]))
|
||||
FROM [dbo].[fds__invoices] as _i
|
||||
JOIN [dbo].[mfr__companies] as cy on _i.CustomerId = cy.id
|
||||
where YEAR(_i.[DateCreated]) = @year and _i.[isfinal] = 1
|
||||
GROUP BY CAST(_i.[DateCreated] as date), CustomerId, cy.name
|
||||
where YEAR([dbo].[fds__fn_invoiceDate](_i.[DateFinalized], _i.[DateCreated])) = @year and _i.[isfinal] = 1
|
||||
GROUP BY [dbo].[fds__fn_invoiceDate](_i.[DateFinalized], _i.[DateCreated]), CustomerId, cy.name
|
||||
), yr1 as (
|
||||
SELECT
|
||||
[year] = YEAR( _i.[DateCreated] )
|
||||
[year] = YEAR([dbo].[fds__fn_invoiceDate](_i.[DateFinalized], _i.[DateCreated]))
|
||||
, [total] = SUM( ISNULL(_i.[InvoiceBalance],0) )
|
||||
FROM [dbo].[fds__invoices] as _i
|
||||
WHERE _i.[isfinal] = 1
|
||||
GROUP BY YEAR( _i.[DateCreated])
|
||||
GROUP BY YEAR([dbo].[fds__fn_invoiceDate](_i.[DateFinalized], _i.[DateCreated]))
|
||||
), yr as (
|
||||
SELECT [year], [total] = SUM([total])
|
||||
from yr1 GROUP BY [year]
|
||||
|
||||
@@ -40,20 +40,20 @@ BEGIN
|
||||
WITH inv as(
|
||||
SELECT
|
||||
[itmPrice] = SUM( ISNULL(itm.[value_total],0) )
|
||||
,[Dateofcreation] = CAST(_i.[DateCreated] as date)
|
||||
,[Dateofcreation] = [dbo].[fds__fn_invoiceDate](_i.[DateFinalized], _i.[DateCreated])
|
||||
,[material] = itm.[text]
|
||||
,[seq] = ROW_NUMBER() OVER (ORDER BY CAST(_i.[DateCreated] as date))
|
||||
,[seq] = ROW_NUMBER() OVER (ORDER BY [dbo].[fds__fn_invoiceDate](_i.[DateFinalized], _i.[DateCreated]))
|
||||
FROM [dbo].[fds__invoices] as _i
|
||||
JOIN [fds__invoice_items] as itm on itm.[invid] = _i.[id] AND itm.[Type] like 'Material'
|
||||
where YEAR(_i.[DateCreated]) = @year and _i.[isfinal] = 1
|
||||
GROUP BY CAST(_i.[DateCreated] as date), itm.[text]
|
||||
where YEAR([dbo].[fds__fn_invoiceDate](_i.[DateFinalized], _i.[DateCreated])) = @year and _i.[isfinal] = 1
|
||||
GROUP BY [dbo].[fds__fn_invoiceDate](_i.[DateFinalized], _i.[DateCreated]), itm.[text]
|
||||
), yr1 as (
|
||||
SELECT
|
||||
[year] = YEAR( _i.[DateCreated] )
|
||||
[year] = YEAR([dbo].[fds__fn_invoiceDate](_i.[DateFinalized], _i.[DateCreated]))
|
||||
, [total] = SUM( ISNULL(_i.[InvoiceBalance],0) )
|
||||
FROM [dbo].[fds__invoices] as _i
|
||||
WHERE _i.[isfinal] = 1
|
||||
GROUP BY YEAR( _i.[DateCreated])
|
||||
GROUP BY YEAR([dbo].[fds__fn_invoiceDate](_i.[DateFinalized], _i.[DateCreated]))
|
||||
), yr as (
|
||||
SELECT [year], [total] = SUM([total])
|
||||
from yr1 GROUP BY [year]
|
||||
|
||||
@@ -47,10 +47,10 @@ BEGIN
|
||||
with inv as(
|
||||
select
|
||||
[InvoiceBalance] = SUM( ISNULL(_i.[InvoiceBalance],0) )
|
||||
,[Dateofcreation] = CAST([Datecreated] as date)
|
||||
,[seq] = ROW_NUMBER() OVER (ORDER BY CAST([Datecreated] as date))
|
||||
FROM [dbo].[fds__invoices] as _i where _i.IsFinal = 1 and month([Datecreated]) = @Month and YEAR([Datecreated]) = @year
|
||||
GROUP BY CAST([Datecreated] as date)
|
||||
,[Dateofcreation] = [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated])
|
||||
,[seq] = ROW_NUMBER() OVER (ORDER BY [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated]))
|
||||
FROM [dbo].[fds__invoices] as _i where _i.IsFinal = 1 and MONTH([dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated])) = @Month and YEAR([dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated])) = @year
|
||||
GROUP BY [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated])
|
||||
)
|
||||
SELECT
|
||||
--[Monat] = FORMAT( inv.[Dateofcreation], 'yyyy - MM', 'de')
|
||||
|
||||
@@ -46,10 +46,10 @@ BEGIN
|
||||
with inv as(
|
||||
select
|
||||
[InvoiceBalance] = SUM( ISNULL(_i.[InvoiceBalance],0) )
|
||||
,[Dateofcreation] = CAST([Datecreated] as date)
|
||||
,[seq] = ROW_NUMBER() OVER (ORDER BY CAST([Datecreated] as date))
|
||||
FROM [dbo].[fds__invoices] as _i where _i.IsFinal = 1 and YEAR([Datecreated]) = @year
|
||||
GROUP BY CAST([Datecreated] as date)
|
||||
,[Dateofcreation] = [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated])
|
||||
,[seq] = ROW_NUMBER() OVER (ORDER BY [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated]))
|
||||
FROM [dbo].[fds__invoices] as _i where _i.IsFinal = 1 and YEAR([dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated])) = @year
|
||||
GROUP BY [dbo].[fds__fn_invoiceDate]([DateFinalized], [DateCreated])
|
||||
)
|
||||
SELECT
|
||||
--[Monat] = FORMAT( inv.[Dateofcreation], 'yyyy - MM', 'de')
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
-- =============================================
|
||||
CREATE PROCEDURE [dbo].[fds__setInvoiceFinal]
|
||||
@Id varchar(8),
|
||||
@authuser varchar(25)
|
||||
@authuser varchar(25),
|
||||
@backdate bit = 0 -- 1: date the invoice to the last working day of the previous month (ADR 0032)
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
@@ -13,10 +14,33 @@ BEGIN
|
||||
THROW 60000, N'not authorized', 1;
|
||||
|
||||
INSERT INTO [dbo].[fds__admin_activity] ([activity] ,[authuser] ,[info])
|
||||
VALUES ('fds__setInvoiceFinal' ,@authuser , (SELECT * FROM (VALUES(@Id, @authuser)) as z ([id],[authuser]) FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER));
|
||||
VALUES ('fds__setInvoiceFinal' ,@authuser , (SELECT * FROM (VALUES(@Id, @authuser, @backdate)) as z ([id],[authuser],[backdate]) FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER));
|
||||
|
||||
DECLARE @now datetime = GETUTCDATE();
|
||||
|
||||
-- Finalizations are serialized: the "no later invoice" check of fds__fn_invoiceBackdate and the
|
||||
-- numbering UPDATE below must not interleave with a concurrent finalization, or a higher invoice
|
||||
-- number could end up with an earlier DateFinalized (ADR 0032). The app lock is transaction-owned
|
||||
-- and released at COMMIT/ROLLBACK; every finalization (backdated or not) takes it.
|
||||
SET XACT_ABORT ON;
|
||||
BEGIN TRY
|
||||
BEGIN TRANSACTION;
|
||||
DECLARE @lock int;
|
||||
EXEC @lock = sp_getapplock @Resource = N'fds__setInvoiceFinal', @LockMode = N'Exclusive', @LockOwner = N'Transaction', @LockTimeout = 15000;
|
||||
IF @lock < 0
|
||||
THROW 60002, N'invoice finalization lock not acquired', 1;
|
||||
|
||||
-- Invoice date: now, or (admins, fds_inv > 2) the last working day of the previous month as long as
|
||||
-- no invoice has been finalized after it. Noon keeps the UTC-stored value on the same calendar day.
|
||||
DECLARE @finalized datetime = @now, @backdateDay date = NULL;
|
||||
IF ISNULL(@backdate, 0) = 1
|
||||
BEGIN
|
||||
SET @backdateDay = [dbo].[fds__fn_invoiceBackdate](@authuser);
|
||||
IF @backdateDay IS NULL
|
||||
THROW 60001, N'backdating not allowed', 1;
|
||||
SET @finalized = DATEADD(HOUR, 12, CAST(@backdateDay AS datetime));
|
||||
END
|
||||
|
||||
DECLARE @ids as TABLE([Id] varchar(10));
|
||||
|
||||
DECLARE @Replaces TABLE([RefInvID] varchar(10));
|
||||
@@ -24,7 +48,9 @@ BEGIN
|
||||
DECLARE @Replaces_InvId varchar(50) = CASE WHEN EXISTS(SELECT * FROM @Replaces) THEN STUFF( (SELECT ',' + [refinvid] as [Text] FROM @replaces FOR XML PATH, TYPE).value('.', 'nvarchar(max)'), 1, 1, '') ELSE NULL END;
|
||||
|
||||
|
||||
UPDATE [dbo].[fds__invoices] SET [DateFinalized] = @now, [UserFinalized] = @authuser, [DateModified] = @now, [UserModified] = @authuser, [invoiceid] = [dbo].[fds__newInvoiceId](Year(@now)), [version] = (ISNULL([version],0) + 1), [Replaces_InvId] = @Replaces_InvId
|
||||
UPDATE [dbo].[fds__invoices] SET [DateFinalized] = @finalized, [UserFinalized] = @authuser, [DateModified] = @now, [UserModified] = @authuser, [invoiceid] = [dbo].[fds__newInvoiceId](Year(@finalized)),
|
||||
[DueDate] = CASE WHEN @backdateDay IS NULL THEN [DueDate] -- same term arithmetic as fds__setInvoice, anchored on the backdated invoice date
|
||||
ELSE DATEADD(DAY, ISNULL(TRY_PARSE(REPLACE(REPLACE(ISNULL([PaymentTerm], '10wd'), 'w', ''), 'd', '') AS tinyint), 10), @backdateDay) END, [version] = (ISNULL([version],0) + 1), [Replaces_InvId] = @Replaces_InvId
|
||||
OUTPUT inserted.[id]
|
||||
INTO @ids
|
||||
WHERE [Id] = @Id AND @Id is not null and [isFinal] = 0 and [isSent] = 0;
|
||||
@@ -32,35 +58,54 @@ BEGIN
|
||||
SELECT iv.* FROM [dbo].[fds__invoices] as iv JOIN @ids as ids on iv.[id] = ids.Id; --this is necessary to get calculated fields also
|
||||
|
||||
|
||||
-- update references of intermediate invoices
|
||||
-- update references of intermediate invoices (ADR 0034)
|
||||
WITH IntInvoiceAllocs as(
|
||||
SELECT [tgtInvId] = @Id, [reference_InvId] FROM [dbo].[fds__invoice_items] where [Type] = 'IntInvoiceAllocation' AND [InvId] = @Id
|
||||
SELECT DISTINCT [tgtInvId] = @Id, [reference_InvId] FROM [dbo].[fds__invoice_items] where [Type] = 'IntInvoiceAllocation' AND [InvId] = @Id
|
||||
AND ISNULL([reference_InvId], '') <> '' -- a NULL reference used to abort this MERGE (515 on fds__invoice_details.InvId)
|
||||
-- a Stornorechnung (copy) mirrors the cancelled invoice's credit lines but consumes no Abschlagsrechnung
|
||||
AND EXISTS (SELECT * FROM [dbo].[fds__invoices] as me WHERE me.[Id] = @Id AND me.[InvoiceType] <> 'c')
|
||||
), existing as (
|
||||
SELECT intermediates.Id
|
||||
FROM [dbo].[fds__invoice_details] as id
|
||||
JOIN [dbo].[fds__invoices] as intermediates on id.[InvId] = intermediates.[id]
|
||||
-- intermediates already credited on ANOTHER *live* invoice: a credit on a cancelled invoice, or on the
|
||||
-- invoice this one replaces (storno + recreate), is void and may be taken over
|
||||
SELECT intermediates.Id
|
||||
FROM [dbo].[fds__invoice_details] as id
|
||||
JOIN [dbo].[fds__invoices] as intermediates on id.[InvId] = intermediates.[id]
|
||||
JOIN IntInvoiceAllocs as iia on iia.[reference_InvId] = intermediates.[Id]
|
||||
JOIN [dbo].[fds__invoices] as tgt on tgt.[Id] = id.[AllocatedTo_InvId] -- (a dangling AllocatedTo_InvId counts as free)
|
||||
WHERE ISNULL(intermediates.[iscanceled], 0) = 0 AND isnull(intermediates.[isfinal],0) = 1 -- reallocation is allowed for cancelled inv.
|
||||
and ISNULL(id.[AllocatedTo_InvId], '6AA609E8-1') <> @id
|
||||
and tgt.[Id] <> @Id -- (an unallocated one used to count as taken, so nothing was ever allocated)
|
||||
and ISNULL(tgt.[IsCanceled], 0) = 0
|
||||
and NOT EXISTS (SELECT * FROM @Replaces as r WHERE r.[RefInvID] = tgt.[Id])
|
||||
)
|
||||
MERGE [dbo].[fds__invoice_details] as TARGET
|
||||
USING IntInvoiceAllocs as iia ON TARGET.[InvID] = iia.[reference_InvId]
|
||||
WHEN NOT MATCHED BY TARGET
|
||||
AND NOT EXISTS (SELECT * FROM existing WHERE existing.[id] = iia.[reference_InvId]) THEN
|
||||
WHEN NOT MATCHED BY TARGET
|
||||
AND NOT EXISTS (SELECT * FROM existing WHERE existing.[id] = iia.[reference_InvId]) THEN
|
||||
INSERT ([InvId] ,[AllocatedTo_InvId])
|
||||
VALUES (iia.[reference_InvId], iia.[tgtInvId])
|
||||
WHEN NOT MATCHED BY SOURCE THEN
|
||||
UPDATE
|
||||
SET [AllocatedTo_InvId] = NULL
|
||||
WHEN MATCHED -- free, ours already, or held by a cancelled/replaced invoice -> (re)allocate to this one
|
||||
AND NOT EXISTS (SELECT * FROM existing WHERE existing.[id] = iia.[reference_InvId]) THEN
|
||||
UPDATE
|
||||
SET [AllocatedTo_InvId] = iia.[tgtInvId]
|
||||
WHEN NOT MATCHED BY SOURCE AND TARGET.[AllocatedTo_InvId] = @Id THEN -- only this invoice's own stale allocations (was: every row of the table)
|
||||
UPDATE
|
||||
SET [AllocatedTo_InvId] = NULL
|
||||
;
|
||||
|
||||
--updated replaced invoices
|
||||
UPDATE refinv
|
||||
SET [DateCancelled] = @now, [UserCancelled] = @authuser, [version] = (ISNULL([version],0) + 1)
|
||||
SET [DateCancelled] = @finalized, [UserCancelled] = @authuser, [version] = (ISNULL([version],0) + 1)
|
||||
FROM [dbo].[fds__invoices] as refinv JOIN @Replaces as r on refinv.Id = r.[RefInvID]
|
||||
WHERE refinv.[isFinal] = 1 and refinv.[IsCanceled] = 0;
|
||||
|
||||
|
||||
--update replaced invoices (by stornos)
|
||||
EXECUTE [dbo].[fds__maint__updateCancelledStatus];
|
||||
|
||||
COMMIT TRANSACTION;
|
||||
END TRY
|
||||
BEGIN CATCH
|
||||
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
|
||||
THROW; -- keeps the original number (60001 = backdating not allowed) for the caller
|
||||
END CATCH;
|
||||
END
|
||||
@@ -9,7 +9,7 @@
|
||||
[MappingId] NVARCHAR (255) NULL,
|
||||
[ExternalId] NVARCHAR (255) NULL,
|
||||
[Name] NVARCHAR (255) NULL,
|
||||
[Note] NVARCHAR (255) NULL,
|
||||
[Note] NVARCHAR (MAX) NULL,
|
||||
[SupportTelephone] NVARCHAR (255) NULL,
|
||||
[SupportFax] NVARCHAR (255) NULL,
|
||||
[SupportMail] NVARCHAR (255) NULL,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
[Id] BIGINT NOT NULL,
|
||||
[Location#ID] BIGINT NULL,
|
||||
[Name] NVARCHAR (255) NULL,
|
||||
[Note] NVARCHAR (255) NULL,
|
||||
[Note] NVARCHAR (MAX) NULL,
|
||||
[CustomValues] NVARCHAR (MAX) NOT NULL,
|
||||
[DateModified] DATETIME NOT NULL,
|
||||
[ExternalId] NVARCHAR (255) NULL,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
[MappingId] NVARCHAR (255) NULL,
|
||||
[ExternalId] NVARCHAR (255) NULL,
|
||||
[Name] NVARCHAR (255) NULL,
|
||||
[Note] NVARCHAR (255) NULL,
|
||||
[Note] NVARCHAR (MAX) NULL,
|
||||
[SupportTelephone] NVARCHAR (255) NULL,
|
||||
[SupportFax] NVARCHAR (255) NULL,
|
||||
[SupportMail] NVARCHAR (255) NULL,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[Id] BIGINT NOT NULL,
|
||||
[Location#ID] BIGINT NULL,
|
||||
[Name] NVARCHAR (255) NULL,
|
||||
[Note] NVARCHAR (255) NULL,
|
||||
[Note] NVARCHAR (MAX) NULL,
|
||||
[CustomValues] NVARCHAR (MAX) NOT NULL,
|
||||
[DateModified] DATETIME NOT NULL,
|
||||
[ExternalId] NVARCHAR (255) NULL,
|
||||
|
||||
Reference in New Issue
Block a user