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
|
||||
Reference in New Issue
Block a user