Add timezone-conversion and dashboard-widget SQL functions; remove obsolete backup__ copies
Playwright Tests / test (push) Canceled after 0s

Add datetime_LocalToUTC / datetime_utcToLocal, and two widget query
functions (fds_wdg_MFRSync, fds_wgd_lastEmails). Remove the unreferenced
backup__fds__* function files superseded by their current counterparts,
and suppress SQL71501 (unresolved cross-database/composite references)
project-wide.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-09 12:10:24 +02:00
co-authored by Claude Sonnet 5
parent 076290cbeb
commit c1936a327e
11 changed files with 107 additions and 265 deletions
+5 -6
View File
@@ -22,6 +22,7 @@
<SqlServerVerification>False</SqlServerVerification> <SqlServerVerification>False</SqlServerVerification>
<IncludeCompositeObjects>True</IncludeCompositeObjects> <IncludeCompositeObjects>True</IncludeCompositeObjects>
<TargetDatabaseSet>True</TargetDatabaseSet> <TargetDatabaseSet>True</TargetDatabaseSet>
<SuppressTSqlWarnings>71501</SuppressTSqlWarnings>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>bin\Release\</OutputPath> <OutputPath>bin\Release\</OutputPath>
@@ -215,9 +216,6 @@
<Build Include="dbo\Functions\date_addcustom.sql" /> <Build Include="dbo\Functions\date_addcustom.sql" />
<Build Include="dbo\Functions\date_add.sql" /> <Build Include="dbo\Functions\date_add.sql" />
<Build Include="dbo\Functions\bo_val.sql" /> <Build Include="dbo\Functions\bo_val.sql" />
<Build Include="dbo\Functions\backup__fds__r_getBalanceThisMonth.sql" />
<Build Include="dbo\Functions\backup__fds__fn_InvoiceIdByName.sql" />
<Build Include="dbo\Functions\backup__fds__fn_invoice_customerid.sql" />
<Build Include="dbo\Functions\AddBusinessDays.sql" /> <Build Include="dbo\Functions\AddBusinessDays.sql" />
<Build Include="dbo\Functions\string_SplitString_ordered.sql" /> <Build Include="dbo\Functions\string_SplitString_ordered.sql" />
<Build Include="dbo\Functions\ott_20_randomStrings.sql" /> <Build Include="dbo\Functions\ott_20_randomStrings.sql" />
@@ -236,7 +234,6 @@
<Build Include="dbo\Functions\fds__getUpdateableRequests.sql" /> <Build Include="dbo\Functions\fds__getUpdateableRequests.sql" />
<Build Include="dbo\Functions\fds__fn_bankingtransactions_perInvoice.sql" /> <Build Include="dbo\Functions\fds__fn_bankingtransactions_perInvoice.sql" />
<Build Include="dbo\Functions\fds__fn_bankingtransactions.sql" /> <Build Include="dbo\Functions\fds__fn_bankingtransactions.sql" />
<Build Include="dbo\Functions\backup__fds__fn_bankingtransactions.sql" />
<Build Include="dbo\Functions\fis_getModuleAuthList.sql" /> <Build Include="dbo\Functions\fis_getModuleAuthList.sql" />
<Build Include="dbo\Functions\fds__getRequestTreeIds.sql" /> <Build Include="dbo\Functions\fds__getRequestTreeIds.sql" />
<Build Include="dbo\Functions\fds__getInvoiceTreeIds.sql" /> <Build Include="dbo\Functions\fds__getInvoiceTreeIds.sql" />
@@ -246,8 +243,6 @@
<Build Include="dbo\Functions\fds__fn_unpaidInvoices.sql" /> <Build Include="dbo\Functions\fds__fn_unpaidInvoices.sql" />
<Build Include="dbo\Functions\fds__fn_requestsforinvoice.sql" /> <Build Include="dbo\Functions\fds__fn_requestsforinvoice.sql" />
<Build Include="dbo\Functions\fds__admin_reminderSettings.sql" /> <Build Include="dbo\Functions\fds__admin_reminderSettings.sql" />
<Build Include="dbo\Functions\backup__fds__getInvoiceTreeIds.sql" />
<Build Include="dbo\Functions\backup__fds__fn_unpaidInvoices.sql" />
<Build Include="dbo\Stored Procedures\mfr__updt__users.sql" /> <Build Include="dbo\Stored Procedures\mfr__updt__users.sql" />
<Build Include="dbo\Stored Procedures\mfr__updt__timeevents.sql" /> <Build Include="dbo\Stored Procedures\mfr__updt__timeevents.sql" />
<Build Include="dbo\Stored Procedures\mfr__updt__tags.sql" /> <Build Include="dbo\Stored Procedures\mfr__updt__tags.sql" />
@@ -404,5 +399,9 @@
<Build Include="dbo\Stored Procedures\fds__setBankingtransaction_manual.sql" /> <Build Include="dbo\Stored Procedures\fds__setBankingtransaction_manual.sql" />
<Build Include="dbo\Stored Procedures\fds__getBankingtransaction_manual_1.sql" /> <Build Include="dbo\Stored Procedures\fds__getBankingtransaction_manual_1.sql" />
<Build Include="dbo\User Defined Types\fds__tt__mfr_items+.sql" /> <Build Include="dbo\User Defined Types\fds__tt__mfr_items+.sql" />
<Build Include="dbo\Functions\datetime_utcToLocal.sql" />
<Build Include="dbo\Functions\datetime_LocalToUTC.sql" />
<Build Include="dbo\Functions\fds_wgd_lastEmails.sql" />
<Build Include="dbo\Functions\fds_wdg_MFRSync.sql" />
</ItemGroup> </ItemGroup>
</Project> </Project>
@@ -1,27 +0,0 @@
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date, ,>
-- Description: <Description, ,>
-- =============================================
CREATE FUNCTION [dbo].[backup__fds__fn_InvoiceIdByName]
(
@nme varchar(255)
)
RETURNS varchar(20)
AS
BEGIN
DECLARE @Id varchar(20);
SET @nme = TRIM((SELECT TOP(1) [value] FROM string_split(@nme, '(')));
SET @Id = ISNULL(
(SELECT TOP(1) [Id] FROM (
SELECT TOP(1) [Id], [fds] = 1 FROM [dbo].[fds__invoices] WHERE [InvoiceId] = @nme
UNION
SELECT TOP(1) try_Cast([Id] as varchar(20)), [fds] = 0 FROM [dbo].[mfr__invoices] WHERE [InvoiceId] = @nme
)z ORDER BY [fds] DESC
),'');
RETURN @id;
END
@@ -1,83 +0,0 @@
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE FUNCTION [dbo].[backup__fds__fn_bankingtransactions]
(
@startdate date = NULL
,@enddate date = NULL
,@invoice_startdate date = NULL
,@invoice_enddate date = NULL
,@invoice_idlist [dbo].[fds__tt__idlist_vchar] READONLY
)
RETURNS @bankingtransactions TABLE
(
[uid] bigint
,[AccountIdentification] varchar(50)
,[ValueDate] date
,[Amount] numeric(9,2)
,[AccountNumberOfPayer] varchar(30)
,[NameOfPayer] nvarchar(60)
,[SepaRemittanceInformation] varchar(150)
,[EndToEndReference] varchar(50)
,[manu] bit
,[InvId] varchar(15)
,[done_manually] bit
,[fds] bit
)
AS
BEGIN
-- Fill the table variable with the rows for your result set
DECLARE @firstever date = '1900-01-01', @tomorrow date = DATEADD(dAy, 1, GETDATE());
SELECT @invoice_startdate = ISNULL(@invoice_startdate, @firstever), @invoice_enddate = ISNULL(@invoice_enddate, @tomorrow);
DECLARE @idlistempty bit = IIF(EXISTS (SELECT 0 FROM @invoice_idlist) ,0,1);
with bt as (
SELECT [uid],[AccountIdentification],[ValueDate],[Amount],AccountNumberOfPayer,NameOfPayer, SepaRemittanceInformation, EndToEndReference
FROM [dbo].[fds__bankingtransactions] as bt_
where (@startdate is null OR bt_.ValueDate >= @startdate)
AND (@enddate is null or bt_.ValueDate <= @enddate)
), bs0manu as (
SELECT bs.[banking_uid], [invid] = spl.[value], [manu] = cast(1 as bit)
FROM [dbo].[fds__bankingtransactions_settings] as bs
CROSS APPLY STRING_SPLIT(bs.assigned_invoice_id, ',') as spl
JOIN bt on bt.[uid] = bs.[banking_uid]
WHERE bs.assigned_invoice_id is not null
), bs1 as (
SELECT * FROM bs0manu
UNION
SELECT bs.[banking_uid], [invid] = spl.[value], [manu] = cast(0 as bit)
FROM [dbo].[fds__bankingtransactions_settings] as bs
CROSS APPLY STRING_SPLIT(bs.auto_invoice_id, ',') as spl
JOIN bt on bt.[uid] = bs.[banking_uid]
WHERE bs.auto_invoice_id is not null
and bt.[uid] NOT IN (SELECT [banking_uid] FROM bs0manu)
), bs as (
SELECT banking_uid, [invid], manu = CAST(MAX(CAST([manu] as int)) as bit)
from bs1
WHERE @idlistempty = 1 OR bs1.[invid] in (SELECT [id] FROM @invoice_idlist)
GROUP BY banking_uid, [invid]
)
INSERT INTO @bankingtransactions
SELECT
bt.[uid]
,[AccountIdentification]
, bt.[ValueDate]
, [Amount]
,bt.AccountNumberOfPayer
,bt.NameOfPayer
,bt.SepaRemittanceInformation
,bt.EndToEndReference
,[manu]
,[invid]
,[done_manually] = IIF(ISNULL(bs2.[done_manually],'') <> '', 1,0)
,[fds] = IIF(mi.id is null, 1, 0)
FROM bt
JOIN bs ON bt.[uid] = bs.[banking_uid]
LEFT JOIN [dbo].[fds__bankingtransactions_settings] as bs2 ON bt.[uid] = bs2.[banking_uid]
LEFT JOIN [dbo].[fds__invoices] as fi on bs.[invid] = fi.[id] AND fi.[DateFinalized] BETWEEN @invoice_startdate AND @invoice_enddate
LEFT JOIN [dbo].[mfr__invoices] as mi on try_cast(bs.[invid] as bigint) = mi.[id] AND mi.[DateOfCreation] BETWEEN @invoice_startdate AND @invoice_enddate;
RETURN
END
@@ -1,26 +0,0 @@
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date, ,>
-- Description: <Description, ,>
-- =============================================
CREATE FUNCTION [dbo].[backup__fds__fn_invoice_customerid]
(
@InvId varchar(15)
)
RETURNS bigint
AS
BEGIN
DECLARE @ret bigint;
SELECT TOP(1) @ret = [customerid] FROM dbo.[fds__invoices] WHERE [id] = @InvId;
IF @ret is null
SELECT TOP(1) @ret = [customerid] FROM (SELECT TOP(1) [invid] = p.[PartnerId], s.[CustomerId], cy.[supportmail], cy.[Name]
FROM dbo.[mfr__*PartnerSet] as p
JOIN [dbo].[mfr__servicerequests] as s on p.[EntityId] = s.[Id] AND p.[Property] = 'ServiceRequest:Invoices'
JOIN [dbo].[mfr__companies] as cy on s.[CustomerId] = cy.id
WHERE p.PartnerId = TRY_CAST(@invId as bigint))z;
RETURN @ret;
END
@@ -1,48 +0,0 @@
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE FUNCTION [dbo].[backup__fds__fn_unpaidInvoices]
(
)
RETURNS TABLE
AS
RETURN
(
WITH inv as (
SELECT [Id] = cast([id] as varchar(15))
,[Invoiceid]
,[DateFinalized]
,[InvoiceBalance]
,[DocumentName]
,[file]
,[InvoiceTitle]
,[customerid]
,[dateSent]
,[fds] = CAST(1 as bit)
FROM [dbo].[fds__invoices] as iv
WHERE [isfinal] = 1 and CAST(CASE WHEN ISNULL(iv.[IsCanceled],0) = 1 THEN 1 ELSE ISNULL([IsPayed],0) END as bit) = 0
and InvoiceBalance > 0
UNION
SELECT [Id] = cast([id] as varchar(15))
,[Invoiceid]
,[DateFinalized] = [DateOfCreation]
,[InvoiceBalance]
,[DocumentName]
,[file] = NULL
,[InvoiceTitle] = ''
,[customerid] = [dbo].[fds__fn_invoice_customerid](mfri.[id])
,[datesent] = NULL
,[fds] = CAST(0 as bit)
FROM [dbo].[mfr__invoices] as mfri
LEFT JOIN [dbo].[fds__custom_invoiceinfo] as ivi on mfri.[id] = ivi.[invid]
WHERE [invoicestate] in ('eIsSent','eIsOpen')
AND ISNULL(ivi.isPayed,0) = 0
AND not [invoiceId] like 'preview'
and InvoiceBalance > 0
)
SELECT * /*[Rechnung] = [invoiceId], [Name] = [InvoiceTitle] + CHAR(10) + ' (' + (SELECT TOP(1) c.[name] FROM [dbo].[mfr__companies] as c WHERE inv.[customerid] = c.[id]) + ')', [Betrag (net)] = FORMAT([invoicebalance], '#0.00€', 'de'), [Datum] = FORMAT([DateFinalized], 'dd.MM.yy' , 'de'), [Zahlungen] = FORMAT([dbo].[fds__fn_InvoicePaymentAmount]([id]), '#0.00€', 'de'), [order] = ROW_NUMBER() OVER (ORDER BY [DateFinalized], [DateSent]) */
FROM inv
)
@@ -1,33 +0,0 @@
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE FUNCTION [dbo].[backup__fds__getInvoiceTreeIds]
(
@invid varchar(20)
)
RETURNS TABLE
AS
RETURN
(
with mfr_inv as (
SELECT [type] = 'invoice', [id] = [id] FROM [dbo].[mfr__invoices] as _mfri where _mfri.[id] = TRY_CAST(@invid as bigint)
), mfr_srq as (
SELECT DISTINCT [type] = 'servicerequest', [id] = mfrs.[id] FROM mfr_inv
JOIN [dbo].[mfr__*PartnerSet] as ps on Property = 'Invoice:SourceServiceRequest' and ps.EntityId = mfr_inv.[id]
JOIN [dbo].[mfr__servicerequests] as mfrs on ps.[PartnerId] = mfrs.id
), fds_srq as (
SELECT distinct [type] = 'servicerequest', [id] = mfrs.[id]
FROM [dbo].[fds__invoices] as _fi
JOIN [dbo].[fds__invoice_servicerequests] as _fs on _fi.Id = _fs.[InvId] and _fs.[mfr__servicerequest] is not null
JOIN [dbo].[mfr__servicerequests] as mfrs on _fs.[mfr__servicerequest] = mfrs.id
WHERE _fi.[Id] = @invid
)
SELECT * FROM mfr_inv
union
SELECT * FROM mfr_srq
union
SELECT * FROM fds_srq
)
@@ -1,42 +0,0 @@
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE FUNCTION [dbo].[backup__fds__r_getBalanceThisMonth](
@authuser varchar(100)
)
RETURNS varchar(25)
BEGIN
DECLARE @today date = GETDATE();
DECLARE @tomorrow date = DATEADD(DAY,1,@today);
DECLARE @thismonthfirst date = [dbo].[date_monthfirst](@today);
DECLARE @ret varchar(25) = ''
IF [dbo].[fis_getModuleAuth]('fds_reports', @authuser) < 2
SET @ret = '';
ELSE
BEGIN
WITH inv as (
SELECT
i.[Dateofcreation]
,i.[InvoiceBalance]
,i.[InvoiceBalanceNetto]
FROM [dbo].[mfr__invoices] as i
where --i.[invoicestate] in('eIsSent','eIsPaid','eIsOpen') and
i.[FileType] in( 'PdfInvoice','PdfCancelInvoice','PdfPartialInvoice') and ISNULL(InvoiceId,'') not in ('Preview','')
AND [dbo].[date_monthfirst](i.[Dateofcreation]) = @thismonthfirst
UNION
SELECT
[Dateofcreation] = i.[DateFinalized]
,i.[InvoiceBalance]
,[InvoiceBalanceNetto] = i.[InvoiceBalance_net]
FROM [dbo].[fds__invoices] as i
WHERE i.[isFinal] = 1 AND [dbo].[date_monthfirst](i.[DateFinalized]) = @thismonthfirst
)
SELECT TOP(1) @ret = FORMAT( SUM( ISNULL(inv.[InvoiceBalanceNetto],0) ) * 0.001, '#,0 k€', 'de') FROM inv;
END
RETURN @ret;
END
@@ -0,0 +1,26 @@
-- =============================================
-- Author: Dr. Stefan Ott
-- Create date: <Create Date, ,>
-- Description: <Description, ,>
-- =============================================
CREATE FUNCTION [dbo].[datetime_LocalToUTC]
(
@datetime datetime
,@timezone varchar(50) = null
)
RETURNS datetime
AS
BEGIN
DECLARE @Ret datetime;
IF @datetime is null
SET @RET = null;
ELSE
SET @RET = @datetime AT TIME ZONE ISNULL(@timezone, 'Central European Standard Time') AT TIME ZONE 'UTC'
RETURN @RET;
END
@@ -0,0 +1,26 @@
-- =============================================
-- Author: Dr. Stefan Ott
-- Create date: <Create Date, ,>
-- Description: <Description, ,>
-- =============================================
CREATE FUNCTION [dbo].[datetime_utcToLocal]
(
@datetime datetime
,@timezone varchar(50) = null
)
RETURNS datetime
WITH SCHEMABINDING
AS
BEGIN
DECLARE @Ret datetime;
IF @datetime is null
SET @RET = null;
ELSE
SET @RET = @datetime AT TIME ZONE 'UTC' AT TIME ZONE ISNULL(@timezone, 'Central European Standard Time');
RETURN @RET;
END
@@ -0,0 +1,33 @@
CREATE FUNCTION dbo.fds_wdg_MFRSync ()
RETURNS TABLE
AS
RETURN
(
WITH LastPerTableAction AS
(
SELECT
[table],
[action],
[timestamp],
TRY_CAST(JSON_VALUE([info], '$.count') AS INT) AS ItemCount,
ROW_NUMBER() OVER (PARTITION BY [table], [action] ORDER BY [timestamp] DESC) AS rn
FROM [dbo].[fds__log]
WHERE --[action] IN (N'imdu_reset', N'imdu_short', N'update_reset', N'update_short')
[timestamp] > DATEADD(DAY, -3, GETUTCDATE())
),
Formatted AS
(
SELECT
[table],
[action],
CONCAT(FORMAT([dbo].[datetime_utcToLocal]([timestamp], null), 'dd.MM. HH:mm', 'de-DE'), 'Uhr - (', ISNULL(CONVERT(varchar(20), ItemCount), 'n/a'), ' Datensätze)') AS Cell
FROM LastPerTableAction
WHERE rn = 1
)
SELECT [Info] = SUBSTRING([table], 6, 100), [imdu_reset], [imdu_short], [update_reset], [update_short]
FROM Formatted
PIVOT
(
MAX(Cell) FOR [action] IN ([imdu_reset], [imdu_short], [update_reset], [update_short])
) AS pvt
);
@@ -0,0 +1,17 @@
create function [fds_wgd_lastEmails](@count int = 10)
returns table
as return
SELECT TOP (@count)
[Betreff] = oj.[subject],
[Empfänger] = (SELECT STRING_AGG(
CASE WHEN CHARINDEX('<', [value]) > 0
THEN SUBSTRING([value], CHARINDEX('<', [value]) + 1, CHARINDEX('>', [value]) - CHARINDEX('<', [value]) - 1)
ELSE [value]
END, ', ')
FROM OPENJSON(JSON_QUERY(el.[config], '$.to'))),
[attachments] = (SELECT STRING_AGG([value], ', ') FROM OPENJSON(JSON_QUERY(el.[config], '$.attachments'))),
[gesendet] = FORMAT(el.DateSent, 'dd.MM.yy', 'de-DE')
FROM [dbo].[fds__emaillog] as el
CROSS APPLY OPENJSON(el.[config], '$') WITH ( [subject] nvarchar(255) '$.subject' ) as oj
order by [DateSent] desc