Add entity customer numbers and scope APIs via selected company.

Entity gets an optional unique-per-company number with allocate/peek/isNumberFree helpers. Company-scoped store methods no longer take companyId and resolve google_auth.selected_company instead.
This commit is contained in:
seb
2026-08-07 04:29:35 +02:00
parent 1e89e19863
commit 70e0a9ddc4
78 changed files with 940 additions and 772 deletions

View File

@@ -158,6 +158,7 @@ BEGIN
customergroup_id INT NOT NULL,
first_name NVARCHAR(255) NULL,
name NVARCHAR(255) NOT NULL,
[number] NVARCHAR(100) NULL,
created_at DATETIME2 NOT NULL CONSTRAINT DF_entity_created_at DEFAULT SYSUTCDATETIME(),
updated_at DATETIME2 NOT NULL CONSTRAINT DF_entity_updated_at DEFAULT SYSUTCDATETIME(),
CONSTRAINT FK_entity_customergroup FOREIGN KEY (customergroup_id) REFERENCES customergroup(id) ON DELETE CASCADE
@@ -165,6 +166,35 @@ BEGIN
END
`;
/** Unique (company_id, number) for non-null entity numbers via customergroup. */
export const INIT_ENTITY_COMPANY_NUMBER_UQ = `
IF OBJECT_ID(N'dbo.v_entity_company_number', N'V') IS NULL
BEGIN
EXEC('
CREATE VIEW dbo.v_entity_company_number
WITH SCHEMABINDING
AS
SELECT
e.id AS entity_id,
cg.company_id,
e.[number]
FROM dbo.entity AS e
INNER JOIN dbo.customergroup AS cg ON cg.id = e.customergroup_id
WHERE e.[number] IS NOT NULL
');
END
IF NOT EXISTS (
SELECT 1 FROM sys.indexes
WHERE name = N'UQ_entity_company_number'
AND object_id = OBJECT_ID(N'dbo.v_entity_company_number')
)
BEGIN
CREATE UNIQUE CLUSTERED INDEX UQ_entity_company_number
ON dbo.v_entity_company_number (company_id, [number]);
END
`;
export const INIT_ENTITYADDRESS = `
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'entityaddress')
BEGIN
@@ -601,6 +631,43 @@ END
');
`;
// EXEC dbo.peeknextnumberwithprefixandpadding
// @company_id = 1, @type = N'entity', @value = @n OUTPUT;
export const INIT_PEEK_NEXT_NUMBER_WITH_PREFIX_AND_PADDING = `
IF OBJECT_ID(N'dbo.peeknextnumberwithprefixandpadding', N'P') IS NOT NULL
DROP PROCEDURE dbo.peeknextnumberwithprefixandpadding;
EXEC('
CREATE PROCEDURE dbo.peeknextnumberwithprefixandpadding
@company_id INT,
@type NVARCHAR(100),
@value NVARCHAR(100) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @prefix NVARCHAR(50);
DECLARE @padding INT;
DECLARE @num INT;
SELECT
@prefix = n.prefix,
@padding = n.padding,
@num = n.[next]
FROM numbers n WITH (UPDLOCK, ROWLOCK)
WHERE n.company_id = @company_id AND n.[type] = @type;
IF @@ROWCOUNT = 0
THROW 50000, ''Number type not found for company'', 1;
SET @value = @prefix + CASE
WHEN @padding > 0 THEN RIGHT(REPLICATE(''0'', @padding) + CAST(@num AS NVARCHAR(20)), @padding)
ELSE CAST(@num AS NVARCHAR(20))
END;
END
');
`;
export const INIT_COMPANYUSER = `
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'companyuser')
BEGIN
@@ -686,6 +753,7 @@ export const SCHEMA_SCRIPTS = [
INIT_CUSTOMERGROUP,
INIT_COMPANY_POS_CUSTOMERGROUP_FK,
INIT_ENTITY,
INIT_ENTITY_COMPANY_NUMBER_UQ,
INIT_ENTITYADDRESS,
INIT_ENTITYCONTACT,
INIT_UNIT,
@@ -709,6 +777,7 @@ export const SCHEMA_SCRIPTS = [
INIT_LEDGER,
INIT_NUMBERS,
INIT_GET_NEXT_NUMBER_WITH_PREFIX_AND_PADDING,
INIT_PEEK_NEXT_NUMBER_WITH_PREFIX_AND_PADDING,
INIT_COMPANYUSER,
INIT_ARTICLEHISTORY,
INIT_ENTITYHISTORY,