forlogic-core 2.5.1 → 2.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/services/TokenManager.d.ts +3 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1 -1
- package/docs/sql/import/00_infra.sql +210 -0
- package/docs/sql/import/validate_criteria.sql +209 -0
- package/docs/sql/import/validate_occurrences.sql +295 -0
- package/docs/sql/import/validate_occurrences_categories.sql +129 -105
- package/docs/sql/import/validate_occurrences_causes_classification.sql +112 -0
- package/docs/sql/import/validate_occurrences_types.sql +113 -0
- package/docs/sql/import/validate_risks.sql +112 -140
- package/docs/sql/import/validate_risks_categories.sql +104 -94
- package/docs/sql/import/validate_risks_groups.sql +98 -120
- package/docs/sql/import/validate_suppliers.sql +131 -52
- package/docs/sql/import/validate_suppliers_categories.sql +150 -0
- package/docs/sql/import/validate_supply_types.sql +76 -130
- package/package.json +1 -1
- package/docs/sql/import/validate_supplier_categories.sql +0 -173
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Infraestrutura compartilhada do fluxo de importação (staging).
|
|
3
|
+
Executar UMA ÚNICA VEZ por base, antes das procedures validate_*.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
USE [qualiex_common]
|
|
7
|
+
GO
|
|
8
|
+
|
|
9
|
+
IF NOT EXISTS (SELECT 1 FROM [dbo].[imports_types] WHERE [id] = N'5')
|
|
10
|
+
BEGIN
|
|
11
|
+
INSERT INTO [dbo].[imports_types] ([id], [name])
|
|
12
|
+
VALUES (N'5', N'Staging')
|
|
13
|
+
END
|
|
14
|
+
GO
|
|
15
|
+
|
|
16
|
+
IF SCHEMA_ID('import') IS NULL
|
|
17
|
+
EXEC('CREATE SCHEMA import')
|
|
18
|
+
GO
|
|
19
|
+
|
|
20
|
+
IF OBJECT_ID(N'import.batches', N'U') IS NULL
|
|
21
|
+
BEGIN
|
|
22
|
+
CREATE TABLE import.batches
|
|
23
|
+
(
|
|
24
|
+
id UNIQUEIDENTIFIER PRIMARY KEY DEFAULT NEWSEQUENTIALID(),
|
|
25
|
+
entity_name VARCHAR(100) NOT NULL,
|
|
26
|
+
status VARCHAR(30) NOT NULL DEFAULT 'PENDING',
|
|
27
|
+
total_rows INT NULL,
|
|
28
|
+
valid_rows INT NULL,
|
|
29
|
+
error_rows INT NULL,
|
|
30
|
+
created_at DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME(),
|
|
31
|
+
started_at DATETIME2 NULL,
|
|
32
|
+
finished_at DATETIME2 NULL,
|
|
33
|
+
|
|
34
|
+
CONSTRAINT chk_import_batches_status
|
|
35
|
+
CHECK
|
|
36
|
+
(
|
|
37
|
+
status IN
|
|
38
|
+
(
|
|
39
|
+
'PENDING',
|
|
40
|
+
'PROCESSING',
|
|
41
|
+
'PROCESSED',
|
|
42
|
+
'PROCESSED_WITH_ERRORS',
|
|
43
|
+
'FAILED'
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
)
|
|
47
|
+
END
|
|
48
|
+
GO
|
|
49
|
+
|
|
50
|
+
IF OBJECT_ID(N'import.errors', N'U') IS NULL
|
|
51
|
+
BEGIN
|
|
52
|
+
CREATE TABLE import.errors
|
|
53
|
+
(
|
|
54
|
+
id INT IDENTITY PRIMARY KEY,
|
|
55
|
+
id_batch UNIQUEIDENTIFIER NOT NULL,
|
|
56
|
+
row_num INT NOT NULL,
|
|
57
|
+
error_msg NVARCHAR(2000) NOT NULL,
|
|
58
|
+
created_at DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME()
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
ALTER TABLE import.errors
|
|
62
|
+
ADD CONSTRAINT FK_import_errors_batch
|
|
63
|
+
FOREIGN KEY (id_batch) REFERENCES import.batches(id)
|
|
64
|
+
END
|
|
65
|
+
GO
|
|
66
|
+
|
|
67
|
+
CREATE OR ALTER PROCEDURE import.process_batch
|
|
68
|
+
(
|
|
69
|
+
@id_batch UNIQUEIDENTIFIER,
|
|
70
|
+
@tablename SYSNAME
|
|
71
|
+
)
|
|
72
|
+
AS
|
|
73
|
+
BEGIN
|
|
74
|
+
|
|
75
|
+
SET NOCOUNT ON;
|
|
76
|
+
SET XACT_ABORT ON;
|
|
77
|
+
|
|
78
|
+
DECLARE
|
|
79
|
+
@sql NVARCHAR(MAX),
|
|
80
|
+
@lock_result INT,
|
|
81
|
+
@validation_procedure SYSNAME,
|
|
82
|
+
@staging_table SYSNAME,
|
|
83
|
+
@total INT,
|
|
84
|
+
@errors INT;
|
|
85
|
+
|
|
86
|
+
-- DEFINIÇÕES DINÂMICAS
|
|
87
|
+
SET @validation_procedure = 'validate_' + @tablename;
|
|
88
|
+
SET @staging_table = @tablename + '_staging';
|
|
89
|
+
|
|
90
|
+
IF NOT EXISTS
|
|
91
|
+
(
|
|
92
|
+
SELECT 1
|
|
93
|
+
FROM sys.procedures
|
|
94
|
+
WHERE name = @validation_procedure
|
|
95
|
+
AND schema_id = SCHEMA_ID('import')
|
|
96
|
+
)
|
|
97
|
+
THROW 50003, 'Procedure de validação não encontrada.', 1;
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
BEGIN TRY
|
|
101
|
+
|
|
102
|
+
-- LOCK DE CONCORRÊNCIA
|
|
103
|
+
EXEC @lock_result = sp_getapplock
|
|
104
|
+
@Resource = @id_batch,
|
|
105
|
+
@LockMode = 'Exclusive',
|
|
106
|
+
@LockOwner = 'Session',
|
|
107
|
+
@LockTimeout = 10000;
|
|
108
|
+
|
|
109
|
+
IF @lock_result < 0
|
|
110
|
+
THROW 50001, 'Não foi possível obter lock do batch.', 1;
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
-- MARCAR PROCESSANDO
|
|
114
|
+
UPDATE import.batches WITH (UPDLOCK, ROWLOCK)
|
|
115
|
+
SET
|
|
116
|
+
status = 'PROCESSING',
|
|
117
|
+
started_at = SYSUTCDATETIME()
|
|
118
|
+
WHERE id = @id_batch
|
|
119
|
+
AND status = 'PENDING';
|
|
120
|
+
|
|
121
|
+
IF @@ROWCOUNT = 0
|
|
122
|
+
THROW 50002, 'Batch inválido ou não está PENDING.', 1;
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
BEGIN TRAN;
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
-- LIMPAR ERROS
|
|
129
|
+
DELETE FROM import.errors WHERE id_batch = @id_batch;
|
|
130
|
+
|
|
131
|
+
-- EXECUTAR VALIDAÇÃO
|
|
132
|
+
SET @sql =
|
|
133
|
+
'EXEC [import].'
|
|
134
|
+
+ QUOTENAME(@validation_procedure)
|
|
135
|
+
+ ' @id_batch=@id_batch';
|
|
136
|
+
|
|
137
|
+
EXEC sp_executesql
|
|
138
|
+
@sql,
|
|
139
|
+
N'@id_batch UNIQUEIDENTIFIER',
|
|
140
|
+
@id_batch;
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
-- CONTAR TOTAL DE LINHAS
|
|
144
|
+
SET @sql =
|
|
145
|
+
'
|
|
146
|
+
SELECT
|
|
147
|
+
@total_out = COUNT(*)
|
|
148
|
+
FROM [import].' + QUOTENAME(@staging_table) + '
|
|
149
|
+
WHERE id_batch = @id_batch
|
|
150
|
+
';
|
|
151
|
+
|
|
152
|
+
EXEC sp_executesql
|
|
153
|
+
@sql,
|
|
154
|
+
N'@id_batch UNIQUEIDENTIFIER, @total_out INT OUTPUT',
|
|
155
|
+
@id_batch,
|
|
156
|
+
@total OUTPUT;
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
-- CONTAR LINHAS COM ERRO
|
|
160
|
+
SELECT
|
|
161
|
+
@errors = COUNT(DISTINCT row_num)
|
|
162
|
+
FROM import.errors
|
|
163
|
+
WHERE id_batch = @id_batch;
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
-- FINALIZAR BATCH
|
|
167
|
+
UPDATE import.batches
|
|
168
|
+
SET
|
|
169
|
+
total_rows = @total,
|
|
170
|
+
error_rows = @errors,
|
|
171
|
+
valid_rows = @total - @errors,
|
|
172
|
+
|
|
173
|
+
status =
|
|
174
|
+
CASE
|
|
175
|
+
WHEN @errors > 0
|
|
176
|
+
THEN 'PROCESSED_WITH_ERRORS'
|
|
177
|
+
ELSE 'PROCESSED'
|
|
178
|
+
END,
|
|
179
|
+
|
|
180
|
+
finished_at = SYSUTCDATETIME()
|
|
181
|
+
WHERE id = @id_batch;
|
|
182
|
+
|
|
183
|
+
COMMIT;
|
|
184
|
+
|
|
185
|
+
EXEC sp_releaseapplock
|
|
186
|
+
@Resource = @id_batch,
|
|
187
|
+
@LockOwner = 'Session';
|
|
188
|
+
|
|
189
|
+
END TRY
|
|
190
|
+
BEGIN CATCH
|
|
191
|
+
|
|
192
|
+
IF @@TRANCOUNT > 0
|
|
193
|
+
ROLLBACK;
|
|
194
|
+
|
|
195
|
+
UPDATE import.batches
|
|
196
|
+
SET
|
|
197
|
+
status = 'FAILED',
|
|
198
|
+
finished_at = SYSUTCDATETIME()
|
|
199
|
+
WHERE id = @id_batch;
|
|
200
|
+
|
|
201
|
+
EXEC sp_releaseapplock
|
|
202
|
+
@Resource = @id_batch,
|
|
203
|
+
@LockOwner = 'Session';
|
|
204
|
+
|
|
205
|
+
THROW;
|
|
206
|
+
|
|
207
|
+
END CATCH
|
|
208
|
+
|
|
209
|
+
END
|
|
210
|
+
GO
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
-- =============================================================
|
|
2
|
+
-- Procedures de importação — Fornecedores | Parâmetros | Critérios
|
|
3
|
+
-- Banco: qualiex_common (SQL Server)
|
|
4
|
+
-- Dispatch dinâmico: import.process_batch resolve pelo table_name
|
|
5
|
+
-- (@tablename = 'criteria').
|
|
6
|
+
--
|
|
7
|
+
-- Colunas esperadas no CSV (ordem do template):
|
|
8
|
+
-- 1) Título -> title (obrigatório)
|
|
9
|
+
-- 2) Etapa de seleção -> selection_stage (Sim/Não)
|
|
10
|
+
-- 3) Etapa de aquisição -> acquisition_stage (Sim/Não)
|
|
11
|
+
-- 4) Tipo de resposta -> id_answer_type (obrigatório, int)
|
|
12
|
+
-- 5) Critério -> type (obrigatório, 1 Mérito / 2 Demérito)
|
|
13
|
+
-- 6) Valor do demérito -> demerit_value (decimal, aceita vírgula)
|
|
14
|
+
-- 7) Critério obrigatório -> required (Sim/Não)
|
|
15
|
+
-- 8) Ocorrências -> is_occurrences (Sim/Não)
|
|
16
|
+
-- 9) Como avaliar -> how_to_evaluate (opcional)
|
|
17
|
+
-- 10) Situação -> is_active (Ativo/Inativo, default Ativo)
|
|
18
|
+
-- 11) Emissor -> id_creation_user (obrigatório, lookup users)
|
|
19
|
+
--
|
|
20
|
+
-- id_company é resolvido pelo backend a partir do contexto da unidade.
|
|
21
|
+
--
|
|
22
|
+
-- Nota de collation:
|
|
23
|
+
-- Colunas texto/ID usam Latin1_General_CS_AS explicitamente para
|
|
24
|
+
-- evitar conflito de collation com a base de produção.
|
|
25
|
+
-- =============================================================
|
|
26
|
+
|
|
27
|
+
USE [qualiex_common]
|
|
28
|
+
GO
|
|
29
|
+
|
|
30
|
+
IF EXISTS (SELECT * FROM sys.objects
|
|
31
|
+
WHERE object_id = OBJECT_ID(N'[import].[criteria_staging]')
|
|
32
|
+
AND type IN (N'U'))
|
|
33
|
+
DROP TABLE [import].[criteria_staging]
|
|
34
|
+
GO
|
|
35
|
+
|
|
36
|
+
CREATE TABLE [import].[criteria_staging](
|
|
37
|
+
[id_batch] [uniqueidentifier] NOT NULL,
|
|
38
|
+
[row_num] [int] NOT NULL,
|
|
39
|
+
[title] [varchar](500) COLLATE Latin1_General_CS_AS NOT NULL,
|
|
40
|
+
[selection_stage] [varchar](20) COLLATE Latin1_General_CS_AS NULL,
|
|
41
|
+
[acquisition_stage] [varchar](20) COLLATE Latin1_General_CS_AS NULL,
|
|
42
|
+
[id_answer_type] [int] NULL,
|
|
43
|
+
[how_to_evaluate] [nvarchar](max) COLLATE Latin1_General_CS_AS NULL,
|
|
44
|
+
[required] [varchar](20) COLLATE Latin1_General_CS_AS NULL,
|
|
45
|
+
[type] [int] NULL,
|
|
46
|
+
[demerit_value] [varchar](20) COLLATE Latin1_General_CS_AS NULL,
|
|
47
|
+
[is_active] [varchar](20) COLLATE Latin1_General_CS_AS NULL,
|
|
48
|
+
[is_occurrences] [varchar](20) COLLATE Latin1_General_CS_AS NULL,
|
|
49
|
+
[id_creation_user] [char](8) COLLATE Latin1_General_CS_AS NOT NULL,
|
|
50
|
+
[id_company] [char](8) COLLATE Latin1_General_CS_AS NOT NULL,
|
|
51
|
+
CONSTRAINT [pk_criteria_staging] PRIMARY KEY CLUSTERED
|
|
52
|
+
(
|
|
53
|
+
[id_batch] ASC,
|
|
54
|
+
[row_num] ASC
|
|
55
|
+
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
|
|
56
|
+
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON,
|
|
57
|
+
OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
|
|
58
|
+
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
|
|
59
|
+
GO
|
|
60
|
+
|
|
61
|
+
USE [qualiex_common]
|
|
62
|
+
GO
|
|
63
|
+
|
|
64
|
+
CREATE OR ALTER PROCEDURE [import].[validate_criteria]
|
|
65
|
+
@id_batch UNIQUEIDENTIFIER
|
|
66
|
+
AS
|
|
67
|
+
BEGIN
|
|
68
|
+
SET NOCOUNT ON;
|
|
69
|
+
|
|
70
|
+
-- Validação 1: Título duplicado dentro do próprio lote
|
|
71
|
+
INSERT INTO import.errors (id_batch, row_num, error_msg)
|
|
72
|
+
SELECT @id_batch, sub.row_num, 'Título duplicado no arquivo'
|
|
73
|
+
FROM (
|
|
74
|
+
SELECT *, COUNT(*) OVER (PARTITION BY title) AS cnt
|
|
75
|
+
FROM import.criteria_staging WITH (NOLOCK)
|
|
76
|
+
WHERE id_batch = @id_batch
|
|
77
|
+
) sub
|
|
78
|
+
WHERE sub.cnt > 1;
|
|
79
|
+
|
|
80
|
+
-- Validação 2: Título já existente na produção (mesma unidade)
|
|
81
|
+
INSERT INTO import.errors (id_batch, row_num, error_msg)
|
|
82
|
+
SELECT @id_batch, cs.row_num, 'Critério já existe na base para esta unidade'
|
|
83
|
+
FROM import.criteria_staging cs WITH (NOLOCK)
|
|
84
|
+
INNER JOIN suppliers.criteria c WITH (NOLOCK)
|
|
85
|
+
ON c.title COLLATE Latin1_General_CS_AS = cs.title
|
|
86
|
+
AND c.removed = 0
|
|
87
|
+
AND c.id_company COLLATE Latin1_General_CS_AS = cs.id_company
|
|
88
|
+
WHERE cs.id_batch = @id_batch;
|
|
89
|
+
|
|
90
|
+
-- Validação 3: Validação de Situação (Ativo / Inativo)
|
|
91
|
+
INSERT INTO import.errors (id_batch, row_num, error_msg)
|
|
92
|
+
SELECT @id_batch, cs.row_num, 'Situação inválida (selecione Ativo ou Inativo na planilha)'
|
|
93
|
+
FROM import.criteria_staging cs WITH (NOLOCK)
|
|
94
|
+
WHERE cs.id_batch = @id_batch
|
|
95
|
+
AND ISNULL(cs.is_active, '') NOT IN ('Ativo', 'Inativo', '');
|
|
96
|
+
|
|
97
|
+
-- Validação 4: Validação de booleanos genéricos (Sim / Não)
|
|
98
|
+
INSERT INTO import.errors (id_batch, row_num, error_msg)
|
|
99
|
+
SELECT @id_batch, cs.row_num, 'Valor inválido para campos de Sim/Não (Certifique-se de escolher Sim ou Não na planilha)'
|
|
100
|
+
FROM import.criteria_staging cs WITH (NOLOCK)
|
|
101
|
+
WHERE cs.id_batch = @id_batch
|
|
102
|
+
AND (
|
|
103
|
+
ISNULL(cs.selection_stage, '') NOT IN ('Sim', 'Não', '')
|
|
104
|
+
OR ISNULL(cs.acquisition_stage, '') NOT IN ('Sim', 'Não', '')
|
|
105
|
+
OR ISNULL(cs.required, '') NOT IN ('Sim', 'Não', '')
|
|
106
|
+
OR ISNULL(cs.is_occurrences, '') NOT IN ('Sim', 'Não', '')
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
-- Validação 5: Validação de número Decimal (demerit_value)
|
|
110
|
+
INSERT INTO import.errors (id_batch, row_num, error_msg)
|
|
111
|
+
SELECT @id_batch, cs.row_num, 'Valor de demérito inválido. Insira um número válido.'
|
|
112
|
+
FROM import.criteria_staging cs WITH (NOLOCK)
|
|
113
|
+
WHERE cs.id_batch = @id_batch
|
|
114
|
+
AND cs.demerit_value IS NOT NULL
|
|
115
|
+
AND TRY_CAST(REPLACE(cs.demerit_value, ',', '.') AS DECIMAL(6,2)) IS NULL;
|
|
116
|
+
|
|
117
|
+
-- INSERÇÃO DOS DADOS VÁLIDOS
|
|
118
|
+
INSERT INTO suppliers.criteria
|
|
119
|
+
(
|
|
120
|
+
id_company,
|
|
121
|
+
title,
|
|
122
|
+
selection_stage,
|
|
123
|
+
acquisition_stage,
|
|
124
|
+
id_answer_type,
|
|
125
|
+
how_to_evaluate,
|
|
126
|
+
how_to_evaluate_text,
|
|
127
|
+
required,
|
|
128
|
+
id_creation_user,
|
|
129
|
+
id_last_modified_user,
|
|
130
|
+
creation_date,
|
|
131
|
+
last_modified,
|
|
132
|
+
is_active,
|
|
133
|
+
removed,
|
|
134
|
+
type,
|
|
135
|
+
demerit_value,
|
|
136
|
+
is_occurrences
|
|
137
|
+
)
|
|
138
|
+
SELECT
|
|
139
|
+
cs.id_company,
|
|
140
|
+
cs.title,
|
|
141
|
+
|
|
142
|
+
CASE WHEN cs.selection_stage = 'Sim' THEN 1 ELSE 0 END AS selection_stage,
|
|
143
|
+
CASE WHEN cs.acquisition_stage = 'Sim' THEN 1 ELSE 0 END AS acquisition_stage,
|
|
144
|
+
|
|
145
|
+
ISNULL(cs.id_answer_type, 0) AS id_answer_type,
|
|
146
|
+
|
|
147
|
+
NULLIF(cs.how_to_evaluate, '') AS how_to_evaluate,
|
|
148
|
+
NULLIF(cs.how_to_evaluate, '') AS how_to_evaluate_text,
|
|
149
|
+
|
|
150
|
+
CASE WHEN cs.required = 'Sim' THEN 1 ELSE 0 END AS required,
|
|
151
|
+
|
|
152
|
+
cs.id_creation_user,
|
|
153
|
+
cs.id_creation_user AS id_last_modified_user,
|
|
154
|
+
SYSDATETIMEOFFSET() AS creation_date,
|
|
155
|
+
SYSDATETIMEOFFSET() AS last_modified,
|
|
156
|
+
|
|
157
|
+
CASE WHEN cs.is_active = 'Inativo' THEN 0 ELSE 1 END AS is_active,
|
|
158
|
+
0 AS removed,
|
|
159
|
+
|
|
160
|
+
ISNULL(cs.type, 0) AS type,
|
|
161
|
+
ISNULL(TRY_CAST(REPLACE(cs.demerit_value, ',', '.') AS DECIMAL(6,2)), 0.00) AS demerit_value,
|
|
162
|
+
|
|
163
|
+
CASE WHEN cs.is_occurrences = 'Sim' THEN 1 ELSE 0 END AS is_occurrences
|
|
164
|
+
|
|
165
|
+
FROM import.criteria_staging cs WITH (NOLOCK)
|
|
166
|
+
WHERE cs.id_batch = @id_batch
|
|
167
|
+
AND NOT EXISTS (
|
|
168
|
+
SELECT 1
|
|
169
|
+
FROM import.errors e
|
|
170
|
+
WHERE e.id_batch = cs.id_batch
|
|
171
|
+
AND e.row_num = cs.row_num
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
END
|
|
175
|
+
GO
|
|
176
|
+
|
|
177
|
+
USE [qualiex_common]
|
|
178
|
+
GO
|
|
179
|
+
|
|
180
|
+
CREATE OR ALTER PROCEDURE [import].[get_errors_criteria]
|
|
181
|
+
(
|
|
182
|
+
@id_batch UNIQUEIDENTIFIER
|
|
183
|
+
)
|
|
184
|
+
AS
|
|
185
|
+
BEGIN
|
|
186
|
+
SET NOCOUNT ON;
|
|
187
|
+
|
|
188
|
+
SELECT
|
|
189
|
+
STRING_AGG(
|
|
190
|
+
CAST(e.error_msg AS NVARCHAR(MAX)),
|
|
191
|
+
'; '
|
|
192
|
+
) WITHIN GROUP (ORDER BY e.error_msg) AS error_msg,
|
|
193
|
+
|
|
194
|
+
e.row_num,
|
|
195
|
+
cs.title,
|
|
196
|
+
cs.id_creation_user
|
|
197
|
+
|
|
198
|
+
FROM import.errors e WITH (NOLOCK)
|
|
199
|
+
JOIN import.criteria_staging cs WITH (NOLOCK)
|
|
200
|
+
ON cs.row_num = e.row_num
|
|
201
|
+
AND cs.id_batch = e.id_batch
|
|
202
|
+
WHERE e.id_batch = @id_batch
|
|
203
|
+
GROUP BY
|
|
204
|
+
e.row_num,
|
|
205
|
+
cs.title,
|
|
206
|
+
cs.id_creation_user
|
|
207
|
+
ORDER BY e.row_num;
|
|
208
|
+
END
|
|
209
|
+
GO
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
use [qualiex_common]
|
|
2
|
+
go
|
|
3
|
+
|
|
4
|
+
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[import].[occurrences_staging]') AND type IN (N'U'))
|
|
5
|
+
DROP TABLE [import].[occurrences_staging]
|
|
6
|
+
GO
|
|
7
|
+
|
|
8
|
+
CREATE TABLE import.occurrences_staging
|
|
9
|
+
(
|
|
10
|
+
id_batch UNIQUEIDENTIFIER,
|
|
11
|
+
row_num INT NOT NULL,
|
|
12
|
+
code NVARCHAR(8) COLLATE Latin1_General_CS_AS NOT NULL,
|
|
13
|
+
name NVARCHAR(500) COLLATE Latin1_General_CS_AS NULL,
|
|
14
|
+
id_type CHAR(8) COLLATE Latin1_General_CS_AS NULL,
|
|
15
|
+
id_category CHAR(8) COLLATE Latin1_General_CS_AS NULL,
|
|
16
|
+
description NVARCHAR(MAX) COLLATE Latin1_General_CS_AS NULL,
|
|
17
|
+
id_creation_user CHAR(8) COLLATE Latin1_General_CS_AS NULL,
|
|
18
|
+
id_responsible CHAR(8) COLLATE Latin1_General_CS_AS NULL,
|
|
19
|
+
start_date DATETIMEOFFSET(7) NULL,
|
|
20
|
+
end_date DATETIMEOFFSET(7) NULL,
|
|
21
|
+
id_status INT NOT NULL,
|
|
22
|
+
id_company CHAR(8) COLLATE Latin1_General_CS_AS NOT NULL,
|
|
23
|
+
CONSTRAINT pk_occurrences_staging PRIMARY KEY CLUSTERED (id_batch, row_num)
|
|
24
|
+
)
|
|
25
|
+
GO
|
|
26
|
+
|
|
27
|
+
USE [qualiex_common]
|
|
28
|
+
GO
|
|
29
|
+
|
|
30
|
+
CREATE OR ALTER PROCEDURE import.validate_occurrences
|
|
31
|
+
@id_batch UNIQUEIDENTIFIER
|
|
32
|
+
AS
|
|
33
|
+
BEGIN
|
|
34
|
+
SET NOCOUNT ON;
|
|
35
|
+
|
|
36
|
+
-- VALIDAÇÃO 1: Duplicado dentro do próprio lote
|
|
37
|
+
INSERT INTO import.errors
|
|
38
|
+
(id_batch, row_num, error_msg)
|
|
39
|
+
SELECT @id_batch, sub.row_num, 'Código duplicado no arquivo'
|
|
40
|
+
FROM (
|
|
41
|
+
SELECT *, COUNT(*) OVER (PARTITION BY code) AS cnt
|
|
42
|
+
FROM import.occurrences_staging WITH (NOLOCK)
|
|
43
|
+
WHERE id_batch = @id_batch
|
|
44
|
+
) sub
|
|
45
|
+
WHERE sub.cnt > 1;
|
|
46
|
+
|
|
47
|
+
-- VALIDAÇÃO 2: Código já existente na produção
|
|
48
|
+
INSERT INTO import.errors
|
|
49
|
+
(id_batch, row_num, error_msg)
|
|
50
|
+
SELECT @id_batch, os.row_num, 'Código já existe na base'
|
|
51
|
+
FROM import.occurrences_staging os WITH (NOLOCK)
|
|
52
|
+
INNER JOIN occurrences.occurrences o WITH (NOLOCK)
|
|
53
|
+
ON o.code COLLATE Latin1_General_CS_AS = os.code
|
|
54
|
+
AND o.id_company COLLATE Latin1_General_CS_AS = os.id_company
|
|
55
|
+
AND o.removed = 0
|
|
56
|
+
WHERE os.id_batch = @id_batch;
|
|
57
|
+
|
|
58
|
+
-- INSERÇÃO: Apenas registros válidos
|
|
59
|
+
INSERT INTO occurrences.occurrences
|
|
60
|
+
(
|
|
61
|
+
code,
|
|
62
|
+
name,
|
|
63
|
+
id_type,
|
|
64
|
+
id_category,
|
|
65
|
+
description,
|
|
66
|
+
id_creation_user,
|
|
67
|
+
id_responsible,
|
|
68
|
+
start_date,
|
|
69
|
+
end_date,
|
|
70
|
+
id_status,
|
|
71
|
+
id_company,
|
|
72
|
+
root_cause_identification_required,
|
|
73
|
+
checker_responsible_equals_in_occurrences,
|
|
74
|
+
creation_date,
|
|
75
|
+
last_modified,
|
|
76
|
+
removed
|
|
77
|
+
)
|
|
78
|
+
SELECT
|
|
79
|
+
os.code,
|
|
80
|
+
os.name,
|
|
81
|
+
os.id_type,
|
|
82
|
+
os.id_category,
|
|
83
|
+
os.description,
|
|
84
|
+
os.id_creation_user,
|
|
85
|
+
os.id_responsible,
|
|
86
|
+
os.start_date,
|
|
87
|
+
os.end_date,
|
|
88
|
+
os.id_status,
|
|
89
|
+
os.id_company,
|
|
90
|
+
1,
|
|
91
|
+
0,
|
|
92
|
+
SYSDATETIMEOFFSET(),
|
|
93
|
+
SYSDATETIMEOFFSET(),
|
|
94
|
+
0
|
|
95
|
+
FROM import.occurrences_staging os WITH (NOLOCK)
|
|
96
|
+
WHERE os.id_batch = @id_batch
|
|
97
|
+
AND NOT EXISTS (
|
|
98
|
+
SELECT 1
|
|
99
|
+
FROM import.errors e
|
|
100
|
+
WHERE e.id_batch = os.id_batch
|
|
101
|
+
AND e.row_num = os.row_num
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
CREATE TABLE #occurrence_phases (
|
|
105
|
+
id UNIQUEIDENTIFIER,
|
|
106
|
+
id_company CHAR(8),
|
|
107
|
+
id_occurrence CHAR(8),
|
|
108
|
+
id_responsible CHAR(8),
|
|
109
|
+
start_date DATETIME2,
|
|
110
|
+
id_days_work INT,
|
|
111
|
+
days_evaluation INT,
|
|
112
|
+
days_causes_analysis INT,
|
|
113
|
+
days_action_plan_elaboration INT,
|
|
114
|
+
days_action_plan_execution INT,
|
|
115
|
+
days_effectiveness_check INT,
|
|
116
|
+
days_standardization INT
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
INSERT INTO #occurrence_phases (
|
|
120
|
+
id,
|
|
121
|
+
id_company,
|
|
122
|
+
id_occurrence,
|
|
123
|
+
id_responsible,
|
|
124
|
+
start_date,
|
|
125
|
+
id_days_work,
|
|
126
|
+
days_evaluation,
|
|
127
|
+
days_causes_analysis,
|
|
128
|
+
days_action_plan_elaboration,
|
|
129
|
+
days_action_plan_execution,
|
|
130
|
+
days_effectiveness_check,
|
|
131
|
+
days_standardization
|
|
132
|
+
)
|
|
133
|
+
SELECT
|
|
134
|
+
NEWID() AS id,
|
|
135
|
+
o.id_company,
|
|
136
|
+
o.id AS id_occurrence,
|
|
137
|
+
o.id_responsible,
|
|
138
|
+
COALESCE(o.start_date, o.creation_date) AS start_date,
|
|
139
|
+
c.id_days_work,
|
|
140
|
+
cat.days_evaluation,
|
|
141
|
+
cat.days_causes_analysis,
|
|
142
|
+
cat.days_action_plan_elaboration,
|
|
143
|
+
cat.days_action_plan_execution,
|
|
144
|
+
cat.days_effectiveness_check,
|
|
145
|
+
cat.days_standardization
|
|
146
|
+
FROM import.occurrences_staging os WITH (NOLOCK)
|
|
147
|
+
INNER JOIN occurrences.occurrences o WITH (NOLOCK)
|
|
148
|
+
ON o.id_company COLLATE Latin1_General_CS_AS = os.id_company
|
|
149
|
+
AND o.code COLLATE Latin1_General_CS_AS = os.code
|
|
150
|
+
AND o.removed = 0
|
|
151
|
+
INNER JOIN occurrences.configurations c WITH (NOLOCK)
|
|
152
|
+
ON c.id_company = o.id_company
|
|
153
|
+
INNER JOIN occurrences.categories cat WITH (NOLOCK)
|
|
154
|
+
ON cat.id = o.id_category
|
|
155
|
+
WHERE os.id_batch = @id_batch
|
|
156
|
+
AND o.id_category IS NOT NULL;
|
|
157
|
+
|
|
158
|
+
-- create a record table that will hold one row per phase, calculated sequentially
|
|
159
|
+
CREATE TABLE #phase_records (
|
|
160
|
+
id_company CHAR(8),
|
|
161
|
+
id_occurrence CHAR(8),
|
|
162
|
+
id_responsible CHAR(8),
|
|
163
|
+
phase_status INT,
|
|
164
|
+
phase_duration INT,
|
|
165
|
+
phase_end_date DATETIME2
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
-- evaluation
|
|
169
|
+
INSERT INTO #phase_records
|
|
170
|
+
SELECT
|
|
171
|
+
id_company,
|
|
172
|
+
id_occurrence,
|
|
173
|
+
id_responsible,
|
|
174
|
+
2,
|
|
175
|
+
days_evaluation,
|
|
176
|
+
dbo.AddDays(days_evaluation, start_date, id_days_work, 0)
|
|
177
|
+
FROM #occurrence_phases;
|
|
178
|
+
|
|
179
|
+
-- cause analysis (cumulative)
|
|
180
|
+
INSERT INTO #phase_records
|
|
181
|
+
SELECT
|
|
182
|
+
id_company,
|
|
183
|
+
id_occurrence,
|
|
184
|
+
id_responsible,
|
|
185
|
+
3,
|
|
186
|
+
days_causes_analysis,
|
|
187
|
+
dbo.AddDays(days_evaluation + days_causes_analysis, start_date, id_days_work, 0)
|
|
188
|
+
FROM #occurrence_phases;
|
|
189
|
+
|
|
190
|
+
-- action plan elaboration (cumulative)
|
|
191
|
+
INSERT INTO #phase_records
|
|
192
|
+
SELECT
|
|
193
|
+
id_company,
|
|
194
|
+
id_occurrence,
|
|
195
|
+
id_responsible,
|
|
196
|
+
4,
|
|
197
|
+
days_action_plan_elaboration,
|
|
198
|
+
dbo.AddDays(days_evaluation + days_causes_analysis + days_action_plan_elaboration, start_date, id_days_work, 0)
|
|
199
|
+
FROM #occurrence_phases;
|
|
200
|
+
|
|
201
|
+
-- action plan execution (cumulative)
|
|
202
|
+
INSERT INTO #phase_records
|
|
203
|
+
SELECT
|
|
204
|
+
id_company,
|
|
205
|
+
id_occurrence,
|
|
206
|
+
id_responsible,
|
|
207
|
+
5,
|
|
208
|
+
days_action_plan_execution,
|
|
209
|
+
dbo.AddDays(days_evaluation + days_causes_analysis + days_action_plan_elaboration + days_action_plan_execution, start_date, id_days_work, 0)
|
|
210
|
+
FROM #occurrence_phases;
|
|
211
|
+
|
|
212
|
+
-- effectiveness check (cumulative)
|
|
213
|
+
INSERT INTO #phase_records
|
|
214
|
+
SELECT
|
|
215
|
+
id_company,
|
|
216
|
+
id_occurrence,
|
|
217
|
+
id_responsible,
|
|
218
|
+
6,
|
|
219
|
+
days_effectiveness_check,
|
|
220
|
+
dbo.AddDays(days_evaluation + days_causes_analysis + days_action_plan_elaboration + days_action_plan_execution + days_effectiveness_check, start_date, id_days_work, 0)
|
|
221
|
+
FROM #occurrence_phases;
|
|
222
|
+
|
|
223
|
+
-- standardization (cumulative)
|
|
224
|
+
INSERT INTO #phase_records
|
|
225
|
+
SELECT
|
|
226
|
+
id_company,
|
|
227
|
+
id_occurrence,
|
|
228
|
+
id_responsible,
|
|
229
|
+
7,
|
|
230
|
+
days_standardization,
|
|
231
|
+
dbo.AddDays(days_evaluation + days_causes_analysis + days_action_plan_elaboration + days_action_plan_execution + days_effectiveness_check + days_standardization, start_date, id_days_work, 0)
|
|
232
|
+
FROM #occurrence_phases;
|
|
233
|
+
|
|
234
|
+
-- finally insert all records into production at once
|
|
235
|
+
INSERT INTO occurrences.phase_associations
|
|
236
|
+
(id_company, id_occurrence, id_responsible, id_status, duration_days, end_date)
|
|
237
|
+
SELECT
|
|
238
|
+
id_company,
|
|
239
|
+
id_occurrence,
|
|
240
|
+
id_responsible,
|
|
241
|
+
phase_status,
|
|
242
|
+
phase_duration,
|
|
243
|
+
phase_end_date
|
|
244
|
+
FROM #phase_records;
|
|
245
|
+
|
|
246
|
+
DROP TABLE #occurrence_phases;
|
|
247
|
+
DROP TABLE #phase_records;
|
|
248
|
+
|
|
249
|
+
END
|
|
250
|
+
GO
|
|
251
|
+
|
|
252
|
+
use [qualiex_common]
|
|
253
|
+
go
|
|
254
|
+
|
|
255
|
+
CREATE OR ALTER PROCEDURE import.get_errors_occurrences
|
|
256
|
+
(
|
|
257
|
+
@id_batch UNIQUEIDENTIFIER
|
|
258
|
+
)
|
|
259
|
+
AS
|
|
260
|
+
BEGIN
|
|
261
|
+
SET NOCOUNT ON;
|
|
262
|
+
|
|
263
|
+
SELECT
|
|
264
|
+
STRING_AGG(CAST(e.error_msg AS NVARCHAR(MAX)), '; ') WITHIN GROUP (ORDER BY e.error_msg) AS error_msg,
|
|
265
|
+
e.row_num,
|
|
266
|
+
os.code,
|
|
267
|
+
os.name,
|
|
268
|
+
os.id_type,
|
|
269
|
+
os.id_category,
|
|
270
|
+
os.description,
|
|
271
|
+
os.id_creation_user,
|
|
272
|
+
os.id_responsible,
|
|
273
|
+
os.start_date,
|
|
274
|
+
os.end_date,
|
|
275
|
+
os.id_status
|
|
276
|
+
FROM import.errors e WITH (NOLOCK)
|
|
277
|
+
JOIN import.occurrences_staging os WITH (NOLOCK)
|
|
278
|
+
ON os.row_num = e.row_num
|
|
279
|
+
AND os.id_batch = e.id_batch
|
|
280
|
+
WHERE e.id_batch = @id_batch
|
|
281
|
+
GROUP BY
|
|
282
|
+
e.row_num,
|
|
283
|
+
os.code,
|
|
284
|
+
os.name,
|
|
285
|
+
os.id_type,
|
|
286
|
+
os.id_category,
|
|
287
|
+
os.description,
|
|
288
|
+
os.id_creation_user,
|
|
289
|
+
os.id_responsible,
|
|
290
|
+
os.start_date,
|
|
291
|
+
os.end_date,
|
|
292
|
+
os.id_status
|
|
293
|
+
ORDER BY e.row_num;
|
|
294
|
+
END
|
|
295
|
+
GO
|