1322 lines
54 KiB
Transact-SQL
1322 lines
54 KiB
Transact-SQL
/*
|
|
Customer-specific review draft for the lserp_AI compatibility-level-100 database.
|
|
|
|
This file is intentionally inert. SET NOEXEC ON prevents the definition from being
|
|
applied and @customer_dba_reviewed remains 0. purchase.open_sources contains a bounded
|
|
candidate query only so that its field, permission and allocation contract can be
|
|
compiled and reviewed without enabling it.
|
|
The customer DBA must create a separate approved deployment script after reviewing the
|
|
database, account-book, subsystem, permission, status, currency, row-scope, calendar and
|
|
source-allocation rules. Do not edit this evidence draft in place.
|
|
|
|
Payload parsing happens in the trusted ERP process. This procedure accepts only fixed,
|
|
typed scalar parameters and therefore does not depend on JSON functions unavailable at
|
|
database compatibility level 100.
|
|
*/
|
|
SET NOEXEC ON;
|
|
GO
|
|
|
|
CREATE PROCEDURE dbo.p_lserp_agent_workflow_read_compat100
|
|
@workflow VARCHAR(32),
|
|
@action VARCHAR(64),
|
|
@module_code NVARCHAR(64),
|
|
@account_book NVARCHAR(64),
|
|
@subsystem_id NVARCHAR(32),
|
|
@user_id NVARCHAR(64),
|
|
@reference NVARCHAR(500) = NULL,
|
|
@tax_id NVARCHAR(50) = NULL,
|
|
@line_id NVARCHAR(64) = NULL,
|
|
@specification NVARCHAR(200) = NULL,
|
|
@unit NVARCHAR(100) = NULL,
|
|
@supplier_code NVARCHAR(64) = NULL,
|
|
@currency_code NVARCHAR(64) = NULL,
|
|
@invoice_number NVARCHAR(128) = NULL,
|
|
@query NVARCHAR(500) = NULL,
|
|
@employee_id NVARCHAR(64) = NULL,
|
|
@local_date NVARCHAR(10) = NULL,
|
|
@day_part VARCHAR(16) = NULL,
|
|
@leave_type_code NVARCHAR(64) = NULL,
|
|
@flow_type_query NVARCHAR(500) = NULL,
|
|
@calculated_hours DECIMAL(18, 6) = NULL,
|
|
@flow_type_code NVARCHAR(64) = NULL,
|
|
@start_local DATETIME = NULL,
|
|
@end_local DATETIME = NULL,
|
|
@record_id NVARCHAR(128) = NULL
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
DECLARE @customer_dba_reviewed BIT;
|
|
SET @customer_dba_reviewed = 0;
|
|
|
|
IF DB_NAME() <> N'lserp_AI'
|
|
BEGIN
|
|
RAISERROR(N'workflow_database_not_allowed', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
IF NULLIF(LTRIM(RTRIM(@account_book)), N'') IS NULL
|
|
OR NULLIF(LTRIM(RTRIM(@user_id)), N'') IS NULL
|
|
BEGIN
|
|
RAISERROR(N'workflow_context_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
IF @workflow = 'purchase'
|
|
BEGIN
|
|
IF @module_code <> N'acc_1007' OR @subsystem_id <> N'5'
|
|
BEGIN
|
|
RAISERROR(N'purchase_scope_not_allowed', 16, 1);
|
|
RETURN;
|
|
END;
|
|
IF @action NOT IN
|
|
('resolve_supplier', 'resolve_currency', 'resolve_material',
|
|
'invoice_exists', 'open_sources')
|
|
BEGIN
|
|
RAISERROR(N'purchase_action_not_allowed', 16, 1);
|
|
RETURN;
|
|
END;
|
|
END
|
|
ELSE IF @workflow = 'leave'
|
|
BEGIN
|
|
IF @module_code <> N'hr_4011' OR @subsystem_id <> N'7'
|
|
BEGIN
|
|
RAISERROR(N'leave_scope_not_allowed', 16, 1);
|
|
RETURN;
|
|
END;
|
|
IF @action NOT IN
|
|
('context', 'resolve_type', 'resolve_flow_type',
|
|
'resolve_calendar_range', 'type_enabled', 'flow_type_enabled',
|
|
'calculate_hours', 'has_conflict', 'can_submit')
|
|
BEGIN
|
|
RAISERROR(N'leave_action_not_allowed', 16, 1);
|
|
RETURN;
|
|
END;
|
|
END
|
|
ELSE
|
|
BEGIN
|
|
RAISERROR(N'workflow_not_allowed', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
IF @customer_dba_reviewed <> 1
|
|
BEGIN
|
|
RAISERROR(N'customer_dba_review_required', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
IF LEN(@user_id) > 10 OR @user_id LIKE N'%[^0-9]%'
|
|
BEGIN
|
|
RAISERROR(N'erp_employee_context_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
DECLARE @user_number DECIMAL(10, 0);
|
|
SET @user_number = CONVERT(DECIMAL(10, 0), @user_id);
|
|
IF @user_number < 1 OR @user_number > 2147483647
|
|
BEGIN
|
|
RAISERROR(N'erp_employee_context_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
DECLARE @current_employee_id INT;
|
|
DECLARE @current_employee_name NVARCHAR(50);
|
|
DECLARE @current_department_id INT;
|
|
SET @current_employee_id = CONVERT(INT, @user_number);
|
|
|
|
SELECT
|
|
@current_employee_name = CONVERT(NVARCHAR(50), EmployeeName),
|
|
@current_department_id = Departmentid
|
|
FROM dbo.p_employeetab
|
|
WHERE employeeid = @current_employee_id
|
|
AND ISNULL(p_emp_status, '') <> N'离职';
|
|
|
|
IF @current_employee_name IS NULL
|
|
BEGIN
|
|
RAISERROR(N'erp_employee_context_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
DECLARE @permission_text NVARCHAR(MAX);
|
|
SET @permission_text = N',';
|
|
SELECT TOP (1)
|
|
@permission_text =
|
|
N',' + CONVERT(NVARCHAR(MAX), ISNULL(wmsPurview, '')) + N','
|
|
+ ISNULL(KcPurview, '') + N',' + ISNULL(crmPurview, '') + N','
|
|
+ ISNULL(bomPurview, '') + N',' + ISNULL(mpsPurview, '') + N','
|
|
+ ISNULL(mrpPurview, '') + N',' + ISNULL(scmPurview, '') + N','
|
|
+ ISNULL(sellPurview, '') + N',' + ISNULL(RdmPurview, '') + N','
|
|
+ ISNULL(hrPurview, '') + N',' + ISNULL(costPurview, '') + N','
|
|
+ ISNULL(eamPurview, '') + N',' + ISNULL(accPurview, '') + N','
|
|
+ ISNULL(oaPurview, '') + N',' + ISNULL(BiPurview, '') + N','
|
|
+ ISNULL(QmsPurview, '') + N',' + ISNULL(FmPurview, '') + N','
|
|
+ ISNULL(Ppurview, '') + N',' + ISNULL(EMApurview, '') + N','
|
|
+ ISNULL(GYSpurview, '') + N',' + ISNULL(PdaPurview, '') + N','
|
|
+ ISNULL(GFPTPurview, '') + N',' + ISNULL(scmtestPurview, '') + N','
|
|
+ ISNULL(CBpurview, '') + N',' + ISNULL(PMPurview, '') + N','
|
|
+ ISNULL(SMSPurview, '') + N',' + ISNULL(AMSPurview, '') + N','
|
|
+ ISNULL(cmspurview, '') + N',' + ISNULL(MEspurview, '') + N','
|
|
+ ISNULL(APSPurview, '') + N',' + ISNULL(KFpurview, '') + N','
|
|
+ ISNULL(qmcPurview, '') + N','
|
|
FROM dbo.p_SubsysPurviewTab
|
|
WHERE employeeid = @current_employee_id;
|
|
|
|
DECLARE @required_menu_id INT;
|
|
SET @required_menu_id =
|
|
CASE WHEN @workflow = 'purchase' THEN 18848 ELSE 16629 END;
|
|
|
|
IF (@current_employee_id <> 1 OR @current_employee_name <> N'管理员')
|
|
AND CHARINDEX(N',' + CONVERT(NVARCHAR(20), @required_menu_id) + N',',
|
|
@permission_text) = 0
|
|
AND CHARINDEX(N',' + CONVERT(NVARCHAR(20), @required_menu_id) + N'|,',
|
|
@permission_text) = 0
|
|
BEGIN
|
|
RAISERROR(N'workflow_module_permission_denied', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
IF @workflow = 'purchase' AND @action = 'resolve_supplier'
|
|
BEGIN
|
|
SET @reference = NULLIF(LTRIM(RTRIM(@reference)), N'');
|
|
SET @tax_id = NULLIF(LTRIM(RTRIM(@tax_id)), N'');
|
|
IF @reference IS NULL AND @tax_id IS NULL
|
|
BEGIN
|
|
RAISERROR(N'purchase_supplier_reference_required', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
IF
|
|
(
|
|
SELECT COUNT_BIG(*)
|
|
FROM dbo.p_providertab
|
|
WHERE ISNULL(IsDisabled, 0) = 0
|
|
AND ISNULL(ban, 0) = 0
|
|
AND ISNULL(cancelFlag, 0) = 0
|
|
AND
|
|
(
|
|
@reference IS NULL
|
|
OR CONVERT(NVARCHAR(32), id) = @reference
|
|
OR CONVERT(NVARCHAR(20), Coid) = @reference
|
|
OR CONVERT(NVARCHAR(100), CoCode) = @reference
|
|
OR CONVERT(NVARCHAR(500), CoName) = @reference
|
|
OR CONVERT(NVARCHAR(500), CoAlias) = @reference
|
|
)
|
|
AND (@tax_id IS NULL OR CONVERT(NVARCHAR(50), taxid) = @tax_id)
|
|
) > 20
|
|
BEGIN
|
|
RAISERROR(N'purchase_supplier_candidates_exceeded', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
SELECT
|
|
CONVERT(NVARCHAR(32), id) AS supplier_code,
|
|
CONVERT(NVARCHAR(500), CoName) AS supplier_name,
|
|
CONVERT(NVARCHAR(50), taxid) AS supplier_tax_id
|
|
FROM dbo.p_providertab
|
|
WHERE ISNULL(IsDisabled, 0) = 0
|
|
AND ISNULL(ban, 0) = 0
|
|
AND ISNULL(cancelFlag, 0) = 0
|
|
AND
|
|
(
|
|
@reference IS NULL
|
|
OR CONVERT(NVARCHAR(32), id) = @reference
|
|
OR CONVERT(NVARCHAR(20), Coid) = @reference
|
|
OR CONVERT(NVARCHAR(100), CoCode) = @reference
|
|
OR CONVERT(NVARCHAR(500), CoName) = @reference
|
|
OR CONVERT(NVARCHAR(500), CoAlias) = @reference
|
|
)
|
|
AND (@tax_id IS NULL OR CONVERT(NVARCHAR(50), taxid) = @tax_id)
|
|
ORDER BY id;
|
|
RETURN;
|
|
END;
|
|
|
|
IF @workflow = 'purchase' AND @action = 'resolve_currency'
|
|
BEGIN
|
|
SET @reference = NULLIF(LTRIM(RTRIM(@reference)), N'');
|
|
IF @reference IS NULL OR LEN(@reference) > 40
|
|
BEGIN
|
|
RAISERROR(N'purchase_currency_reference_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
/* Purchase orders and acc_1007 use different currency dictionaries. Never
|
|
expose a source currency to matching unless finance/DBA has approved its
|
|
exact target mapping. OCR may supply either dictionary's exact id, code or
|
|
name, but the result deliberately remains the source P_CurrencyType id used
|
|
by open_sources and by the signed write wrapper. */
|
|
IF OBJECT_ID(N'dbo.p_agent_purchase_currency_crosswalk', N'U') IS NULL
|
|
OR COL_LENGTH(N'dbo.p_agent_purchase_currency_crosswalk', N'source_currency_id') IS NULL
|
|
OR COL_LENGTH(N'dbo.p_agent_purchase_currency_crosswalk', N'target_currency_id') IS NULL
|
|
OR COL_LENGTH(N'dbo.p_agent_purchase_currency_crosswalk', N'is_active') IS NULL
|
|
OR COL_LENGTH(N'dbo.p_agent_purchase_currency_crosswalk', N'approval_evidence_sha256') IS NULL
|
|
OR NOT EXISTS
|
|
(
|
|
SELECT 1 FROM sys.indexes
|
|
WHERE object_id = OBJECT_ID(N'dbo.p_agent_purchase_currency_crosswalk')
|
|
AND name = N'UX_p_agent_purchase_currency_active'
|
|
AND is_unique = 1 AND has_filter = 1 AND is_disabled = 0
|
|
)
|
|
BEGIN
|
|
RAISERROR(N'purchase_agent_evidence_schema_missing', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
IF NOT EXISTS
|
|
(
|
|
SELECT 1
|
|
FROM dbo.P_CurrencyType AS known_source_currency
|
|
WHERE ISNULL(known_source_currency.is_active, 1) = 1
|
|
AND
|
|
(
|
|
CONVERT(NVARCHAR(32), known_source_currency.id) = @reference
|
|
OR CONVERT(NVARCHAR(3), known_source_currency.currency_code) = @reference
|
|
OR known_source_currency.currency_name = @reference
|
|
)
|
|
)
|
|
AND NOT EXISTS
|
|
(
|
|
SELECT 1
|
|
FROM dbo.P_BaseMixInfoTab AS known_target_currency
|
|
WHERE known_target_currency.Tag = 'L000101'
|
|
AND ISNULL(known_target_currency.Ban, 0) = 0
|
|
AND ISNULL(known_target_currency.Delid, 0) = 0
|
|
AND
|
|
(
|
|
CONVERT(NVARCHAR(32), known_target_currency.ID) = @reference
|
|
OR CONVERT(NVARCHAR(100), known_target_currency.Mix_NO) = @reference
|
|
OR CONVERT(NVARCHAR(500), known_target_currency.Mix_apellation) = @reference
|
|
)
|
|
)
|
|
BEGIN
|
|
/* Unknown references remain an empty candidate set so the trusted ERP
|
|
adapter can return purchase_currency_not_resolved without disclosing
|
|
dictionary contents. */
|
|
SELECT
|
|
CONVERT(NVARCHAR(32), NULL) AS currency_code,
|
|
CONVERT(NVARCHAR(40), NULL) AS currency_name
|
|
WHERE 1 = 0;
|
|
RETURN;
|
|
END;
|
|
|
|
IF NOT EXISTS
|
|
(
|
|
SELECT 1
|
|
FROM dbo.P_CurrencyType AS approved_source_currency
|
|
INNER JOIN dbo.p_agent_purchase_currency_crosswalk AS approved_mapping
|
|
ON approved_mapping.source_currency_id = approved_source_currency.id
|
|
INNER JOIN dbo.P_BaseMixInfoTab AS approved_target_currency
|
|
ON approved_target_currency.ID = approved_mapping.target_currency_id
|
|
AND approved_target_currency.Tag = 'L000101'
|
|
WHERE approved_mapping.is_active = 1
|
|
AND LEN(approved_mapping.approval_evidence_sha256) = 64
|
|
AND approved_mapping.approval_evidence_sha256
|
|
COLLATE Latin1_General_100_BIN2 NOT LIKE '%[^0-9a-f]%'
|
|
AND 1 =
|
|
(
|
|
SELECT COUNT_BIG(*)
|
|
FROM dbo.p_agent_purchase_currency_crosswalk AS source_mapping_count
|
|
WHERE source_mapping_count.source_currency_id = approved_source_currency.id
|
|
AND source_mapping_count.is_active = 1
|
|
AND LEN(source_mapping_count.approval_evidence_sha256) = 64
|
|
AND source_mapping_count.approval_evidence_sha256
|
|
COLLATE Latin1_General_100_BIN2 NOT LIKE '%[^0-9a-f]%'
|
|
)
|
|
AND ISNULL(approved_source_currency.is_active, 1) = 1
|
|
AND ISNULL(approved_target_currency.Ban, 0) = 0
|
|
AND ISNULL(approved_target_currency.Delid, 0) = 0
|
|
AND
|
|
(
|
|
CONVERT(NVARCHAR(32), approved_source_currency.id) = @reference
|
|
OR CONVERT(NVARCHAR(3), approved_source_currency.currency_code) = @reference
|
|
OR approved_source_currency.currency_name = @reference
|
|
OR CONVERT(NVARCHAR(32), approved_target_currency.ID) = @reference
|
|
OR CONVERT(NVARCHAR(100), approved_target_currency.Mix_NO) = @reference
|
|
OR CONVERT(NVARCHAR(500), approved_target_currency.Mix_apellation) = @reference
|
|
)
|
|
)
|
|
BEGIN
|
|
RAISERROR(N'purchase_currency_crosswalk_not_approved', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
IF
|
|
(
|
|
SELECT COUNT_BIG(*)
|
|
FROM
|
|
(
|
|
SELECT approved_source_currency.id
|
|
FROM dbo.P_CurrencyType AS approved_source_currency
|
|
INNER JOIN dbo.p_agent_purchase_currency_crosswalk AS approved_mapping
|
|
ON approved_mapping.source_currency_id = approved_source_currency.id
|
|
INNER JOIN dbo.P_BaseMixInfoTab AS approved_target_currency
|
|
ON approved_target_currency.ID = approved_mapping.target_currency_id
|
|
AND approved_target_currency.Tag = 'L000101'
|
|
WHERE approved_mapping.is_active = 1
|
|
AND LEN(approved_mapping.approval_evidence_sha256) = 64
|
|
AND approved_mapping.approval_evidence_sha256
|
|
COLLATE Latin1_General_100_BIN2 NOT LIKE '%[^0-9a-f]%'
|
|
AND 1 =
|
|
(
|
|
SELECT COUNT_BIG(*)
|
|
FROM dbo.p_agent_purchase_currency_crosswalk AS source_mapping_count
|
|
WHERE source_mapping_count.source_currency_id = approved_source_currency.id
|
|
AND source_mapping_count.is_active = 1
|
|
AND LEN(source_mapping_count.approval_evidence_sha256) = 64
|
|
AND source_mapping_count.approval_evidence_sha256
|
|
COLLATE Latin1_General_100_BIN2 NOT LIKE '%[^0-9a-f]%'
|
|
)
|
|
AND ISNULL(approved_source_currency.is_active, 1) = 1
|
|
AND ISNULL(approved_target_currency.Ban, 0) = 0
|
|
AND ISNULL(approved_target_currency.Delid, 0) = 0
|
|
AND
|
|
(
|
|
CONVERT(NVARCHAR(32), approved_source_currency.id) = @reference
|
|
OR CONVERT(NVARCHAR(3), approved_source_currency.currency_code) = @reference
|
|
OR approved_source_currency.currency_name = @reference
|
|
OR CONVERT(NVARCHAR(32), approved_target_currency.ID) = @reference
|
|
OR CONVERT(NVARCHAR(100), approved_target_currency.Mix_NO) = @reference
|
|
OR CONVERT(NVARCHAR(500), approved_target_currency.Mix_apellation) = @reference
|
|
)
|
|
GROUP BY approved_source_currency.id
|
|
) AS approved_currency_candidates
|
|
) > 20
|
|
BEGIN
|
|
RAISERROR(N'purchase_currency_candidates_exceeded', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
SELECT
|
|
CONVERT(NVARCHAR(32), approved_source_currency.id) AS currency_code,
|
|
CONVERT(NVARCHAR(40), approved_source_currency.currency_name) AS currency_name
|
|
FROM dbo.P_CurrencyType AS approved_source_currency
|
|
INNER JOIN dbo.p_agent_purchase_currency_crosswalk AS approved_mapping
|
|
ON approved_mapping.source_currency_id = approved_source_currency.id
|
|
INNER JOIN dbo.P_BaseMixInfoTab AS approved_target_currency
|
|
ON approved_target_currency.ID = approved_mapping.target_currency_id
|
|
AND approved_target_currency.Tag = 'L000101'
|
|
WHERE approved_mapping.is_active = 1
|
|
AND LEN(approved_mapping.approval_evidence_sha256) = 64
|
|
AND approved_mapping.approval_evidence_sha256
|
|
COLLATE Latin1_General_100_BIN2 NOT LIKE '%[^0-9a-f]%'
|
|
AND 1 =
|
|
(
|
|
SELECT COUNT_BIG(*)
|
|
FROM dbo.p_agent_purchase_currency_crosswalk AS source_mapping_count
|
|
WHERE source_mapping_count.source_currency_id = approved_source_currency.id
|
|
AND source_mapping_count.is_active = 1
|
|
AND LEN(source_mapping_count.approval_evidence_sha256) = 64
|
|
AND source_mapping_count.approval_evidence_sha256
|
|
COLLATE Latin1_General_100_BIN2 NOT LIKE '%[^0-9a-f]%'
|
|
)
|
|
AND ISNULL(approved_source_currency.is_active, 1) = 1
|
|
AND ISNULL(approved_target_currency.Ban, 0) = 0
|
|
AND ISNULL(approved_target_currency.Delid, 0) = 0
|
|
AND
|
|
(
|
|
CONVERT(NVARCHAR(32), approved_source_currency.id) = @reference
|
|
OR CONVERT(NVARCHAR(3), approved_source_currency.currency_code) = @reference
|
|
OR approved_source_currency.currency_name = @reference
|
|
OR CONVERT(NVARCHAR(32), approved_target_currency.ID) = @reference
|
|
OR CONVERT(NVARCHAR(100), approved_target_currency.Mix_NO) = @reference
|
|
OR CONVERT(NVARCHAR(500), approved_target_currency.Mix_apellation) = @reference
|
|
)
|
|
GROUP BY approved_source_currency.id, approved_source_currency.currency_name
|
|
ORDER BY approved_source_currency.id;
|
|
RETURN;
|
|
END;
|
|
|
|
IF @workflow = 'purchase' AND @action = 'resolve_material'
|
|
BEGIN
|
|
SET @reference = NULLIF(LTRIM(RTRIM(@reference)), N'');
|
|
SET @specification = NULLIF(LTRIM(RTRIM(@specification)), N'');
|
|
SET @unit = NULLIF(LTRIM(RTRIM(@unit)), N'');
|
|
SET @supplier_code = NULLIF(LTRIM(RTRIM(@supplier_code)), N'');
|
|
|
|
IF @reference IS NULL OR @supplier_code IS NULL
|
|
OR LEN(@supplier_code) > 10 OR @supplier_code LIKE N'%[^0-9]%'
|
|
BEGIN
|
|
RAISERROR(N'purchase_material_reference_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
DECLARE @material_supplier_number DECIMAL(10, 0);
|
|
DECLARE @material_supplier_id INT;
|
|
SET @material_supplier_number = CONVERT(DECIMAL(10, 0), @supplier_code);
|
|
IF @material_supplier_number < 1 OR @material_supplier_number > 2147483647
|
|
BEGIN
|
|
RAISERROR(N'purchase_material_reference_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
SET @material_supplier_id = CONVERT(INT, @material_supplier_number);
|
|
|
|
IF
|
|
(
|
|
SELECT COUNT_BIG(*)
|
|
FROM dbo.P_productTab
|
|
WHERE ISNULL(delid, 0) = 0
|
|
AND ISNULL(IsLocked, 0) = 0
|
|
AND ISNULL(IsDisabled, 0) = 0
|
|
AND ISNULL(ban, 0) = 0
|
|
AND ISNULL(cancelFlag, 0) = 0
|
|
AND
|
|
(
|
|
CONVERT(NVARCHAR(32), id) = @reference
|
|
OR CONVERT(NVARCHAR(200), productid) = @reference
|
|
OR CONVERT(NVARCHAR(500), appellation) = @reference
|
|
)
|
|
AND
|
|
(
|
|
@specification IS NULL
|
|
OR CONVERT(NVARCHAR(200), spec) = @specification
|
|
OR CONVERT(NVARCHAR(200), model) = @specification
|
|
)
|
|
AND
|
|
(
|
|
@unit IS NULL
|
|
OR CONVERT(NVARCHAR(20), productunitname) = @unit
|
|
OR CONVERT(NVARCHAR(100), pur_unit) = @unit
|
|
)
|
|
AND (pur_providerid IS NULL OR pur_providerid = @material_supplier_id)
|
|
) > 20
|
|
BEGIN
|
|
RAISERROR(N'purchase_material_candidates_exceeded', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
SELECT
|
|
CONVERT(NVARCHAR(200), productid) AS material_code,
|
|
CONVERT(NVARCHAR(500), appellation) AS material_name,
|
|
CONVERT(NVARCHAR(200), COALESCE(NULLIF(spec, ''), model, '')) AS specification,
|
|
CONVERT(NVARCHAR(100), COALESCE(NULLIF(productunitname, ''), pur_unit, '')) AS unit
|
|
FROM dbo.P_productTab
|
|
WHERE ISNULL(delid, 0) = 0
|
|
AND ISNULL(IsLocked, 0) = 0
|
|
AND ISNULL(IsDisabled, 0) = 0
|
|
AND ISNULL(ban, 0) = 0
|
|
AND ISNULL(cancelFlag, 0) = 0
|
|
AND
|
|
(
|
|
CONVERT(NVARCHAR(32), id) = @reference
|
|
OR CONVERT(NVARCHAR(200), productid) = @reference
|
|
OR CONVERT(NVARCHAR(500), appellation) = @reference
|
|
)
|
|
AND
|
|
(
|
|
@specification IS NULL
|
|
OR CONVERT(NVARCHAR(200), spec) = @specification
|
|
OR CONVERT(NVARCHAR(200), model) = @specification
|
|
)
|
|
AND
|
|
(
|
|
@unit IS NULL
|
|
OR CONVERT(NVARCHAR(20), productunitname) = @unit
|
|
OR CONVERT(NVARCHAR(100), pur_unit) = @unit
|
|
)
|
|
AND (pur_providerid IS NULL OR pur_providerid = @material_supplier_id)
|
|
ORDER BY productid;
|
|
RETURN;
|
|
END;
|
|
|
|
IF @workflow = 'purchase' AND @action = 'invoice_exists'
|
|
BEGIN
|
|
SET @supplier_code = NULLIF(LTRIM(RTRIM(@supplier_code)), N'');
|
|
SET @invoice_number = NULLIF(LTRIM(RTRIM(@invoice_number)), N'');
|
|
IF @supplier_code IS NULL OR @invoice_number IS NULL
|
|
OR LEN(@supplier_code) > 10 OR @supplier_code LIKE N'%[^0-9]%'
|
|
BEGIN
|
|
RAISERROR(N'purchase_invoice_identity_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
DECLARE @invoice_supplier_number DECIMAL(10, 0);
|
|
DECLARE @invoice_supplier_id INT;
|
|
SET @invoice_supplier_number = CONVERT(DECIMAL(10, 0), @supplier_code);
|
|
IF @invoice_supplier_number < 1 OR @invoice_supplier_number > 2147483647
|
|
BEGIN
|
|
RAISERROR(N'purchase_invoice_identity_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
SET @invoice_supplier_id = CONVERT(INT, @invoice_supplier_number);
|
|
|
|
SELECT CONVERT(BIT,
|
|
CASE WHEN EXISTS
|
|
(
|
|
SELECT 1
|
|
FROM dbo.ACC_billscmInvoicemainPIDHxtab
|
|
WHERE acc_mphhscm_Providerid = @invoice_supplier_id
|
|
AND CONVERT(NVARCHAR(MAX), acc_mphhscm_invoice) = @invoice_number
|
|
AND ISNULL(acc_mphhscm_cancelFlag, 0) = 0
|
|
AND ISNULL(acc_mphhscm_wasteoper, 0) = 0
|
|
)
|
|
OR EXISTS
|
|
(
|
|
SELECT 1
|
|
FROM dbo.ACC_billscminvoicemaintab
|
|
WHERE acc_mscmi_Providerid = @invoice_supplier_id
|
|
AND CONVERT(NVARCHAR(50), acc_mscmi_invoice) = @invoice_number
|
|
AND ISNULL(acc_mscmi_cancelFlag, 0) = 0
|
|
AND ISNULL(acc_mscmi_wasteoper, 0) = 0
|
|
)
|
|
THEN 1 ELSE 0 END) AS [exists];
|
|
RETURN;
|
|
END;
|
|
|
|
IF @workflow = 'purchase' AND @action = 'open_sources'
|
|
BEGIN
|
|
SET @supplier_code = NULLIF(LTRIM(RTRIM(@supplier_code)), N'');
|
|
SET @currency_code = NULLIF(LTRIM(RTRIM(@currency_code)), N'');
|
|
IF @supplier_code IS NULL OR @currency_code IS NULL
|
|
OR LEN(@supplier_code) > 10 OR @supplier_code LIKE N'%[^0-9]%'
|
|
OR LEN(@currency_code) > 10 OR @currency_code LIKE N'%[^0-9]%'
|
|
BEGIN
|
|
RAISERROR(N'purchase_source_identity_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
DECLARE @source_supplier_number DECIMAL(10, 0);
|
|
DECLARE @source_currency_number DECIMAL(10, 0);
|
|
DECLARE @source_supplier_id INT;
|
|
DECLARE @source_currency_id INT;
|
|
SET @source_supplier_number = CONVERT(DECIMAL(10, 0), @supplier_code);
|
|
SET @source_currency_number = CONVERT(DECIMAL(10, 0), @currency_code);
|
|
IF @source_supplier_number < 1 OR @source_supplier_number > 2147483647
|
|
OR @source_currency_number < 1 OR @source_currency_number > 2147483647
|
|
BEGIN
|
|
RAISERROR(N'purchase_source_identity_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
SET @source_supplier_id = CONVERT(INT, @source_supplier_number);
|
|
SET @source_currency_id = CONVERT(INT, @source_currency_number);
|
|
|
|
IF NOT EXISTS
|
|
(
|
|
SELECT 1 FROM dbo.P_CurrencyType
|
|
WHERE id = @source_currency_id
|
|
)
|
|
BEGIN
|
|
RAISERROR(N'purchase_source_currency_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
/* Reading purchase-order rows requires the PUR_5001 menu in addition to
|
|
the acc_1007 permission checked above. Every returned row must also match
|
|
one currently active, signed procurement scope tuple; administrators do
|
|
not bypass this data boundary. */
|
|
IF (@current_employee_id <> 1 OR @current_employee_name <> N'管理员')
|
|
AND CHARINDEX(N',187,', @permission_text) = 0
|
|
AND CHARINDEX(N',187|,', @permission_text) = 0
|
|
BEGIN
|
|
RAISERROR(N'purchase_source_permission_denied', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
IF OBJECT_ID(N'dbo.p_agent_purchase_row_scope', N'U') IS NULL
|
|
OR COL_LENGTH(N'dbo.p_agent_purchase_row_scope', N'account_book') IS NULL
|
|
OR COL_LENGTH(N'dbo.p_agent_purchase_row_scope', N'subsystem_id') IS NULL
|
|
OR COL_LENGTH(N'dbo.p_agent_purchase_row_scope', N'erp_user_id') IS NULL
|
|
OR COL_LENGTH(N'dbo.p_agent_purchase_row_scope', N'group_id') IS NULL
|
|
OR COL_LENGTH(N'dbo.p_agent_purchase_row_scope', N'department_id') IS NULL
|
|
OR COL_LENGTH(N'dbo.p_agent_purchase_row_scope', N'purchase_user_id') IS NULL
|
|
OR COL_LENGTH(N'dbo.p_agent_purchase_row_scope', N'is_active') IS NULL
|
|
OR COL_LENGTH(N'dbo.p_agent_purchase_row_scope', N'approval_evidence_sha256') IS NULL
|
|
OR COL_LENGTH(N'dbo.p_agent_purchase_row_scope', N'valid_from_utc') IS NULL
|
|
OR COL_LENGTH(N'dbo.p_agent_purchase_row_scope', N'valid_to_utc') IS NULL
|
|
OR NOT EXISTS
|
|
(
|
|
SELECT 1 FROM sys.indexes
|
|
WHERE object_id = OBJECT_ID(N'dbo.p_agent_purchase_row_scope')
|
|
AND name = N'UX_p_agent_purchase_row_scope_active'
|
|
AND is_unique = 1 AND has_filter = 1 AND is_disabled = 0
|
|
)
|
|
BEGIN
|
|
RAISERROR(N'purchase_agent_evidence_schema_missing', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
IF NOT EXISTS
|
|
(
|
|
SELECT 1
|
|
FROM dbo.p_agent_purchase_row_scope
|
|
WHERE account_book = @account_book
|
|
AND subsystem_id = @subsystem_id
|
|
AND erp_user_id = @user_id
|
|
AND is_active = 1
|
|
AND valid_from_utc <= SYSUTCDATETIME()
|
|
AND (valid_to_utc IS NULL OR valid_to_utc > SYSUTCDATETIME())
|
|
AND LEN(approval_evidence_sha256) = 64
|
|
AND approval_evidence_sha256 COLLATE Latin1_General_100_BIN2
|
|
NOT LIKE '%[^0-9a-f]%'
|
|
)
|
|
BEGIN
|
|
RAISERROR(N'purchase_row_scope_denied', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
;WITH active_invoice_quantity AS
|
|
(
|
|
SELECT
|
|
invoice_line.acc_lphhscm_ScmPoid AS source_line_id,
|
|
SUM(ISNULL(invoice_line.acc_lphhscm_amount, 0)) AS reserved_quantity
|
|
FROM dbo.ACC_billscmInvoicelistPIDHxtab AS invoice_line
|
|
INNER JOIN dbo.ACC_billscmInvoicemainPIDHxtab AS invoice_main
|
|
ON invoice_main.acc_mphhscm_billdocument_id =
|
|
invoice_line.acc_lphhscm_billdocument_id
|
|
WHERE invoice_line.acc_lphhscm_ScmPoid IS NOT NULL
|
|
AND ISNULL(invoice_main.acc_mphhscm_cancelFlag, 0) = 0
|
|
AND ISNULL(invoice_main.acc_mphhscm_wasteoper, 0) = 0
|
|
AND ISNULL(invoice_main.acc_mphhscm_delid, 0) = 0
|
|
GROUP BY invoice_line.acc_lphhscm_ScmPoid
|
|
),
|
|
source_candidates AS
|
|
(
|
|
SELECT
|
|
order_line.scm_lpo_Billdocument_id,
|
|
order_main.scm_mpo_handcraftId,
|
|
order_line.scm_lpo_id,
|
|
order_main.scm_mpo_Providerid,
|
|
order_main.scm_mpo_Currency,
|
|
order_line.scm_lpo_Productid,
|
|
order_line.scm_lpo_ProductUnitName,
|
|
CONVERT(DECIMAL(19, 8),
|
|
ISNULL(order_line.scm_lpo_Amount, 0)
|
|
- ISNULL(reserved.reserved_quantity, 0)) AS remaining_quantity,
|
|
CONVERT(DECIMAL(19, 12), ISNULL(order_line.scm_lpo_Fprice, 0)) AS unit_price,
|
|
CONVERT(DECIMAL(19, 8), ISNULL(order_line.scm_lpo_taxRate, 0)) AS tax_rate,
|
|
CONVERT(DECIMAL(19, 8), COALESCE(
|
|
NULLIF(order_line.scm_lpo_ExchangeRate, 0),
|
|
order_main.scm_mpo_ExchangeRate,
|
|
0)) AS exchange_rate
|
|
FROM dbo.scm_BillPolistTab AS order_line
|
|
INNER JOIN dbo.scm_BillPoMainTab AS order_main
|
|
ON order_main.scm_mpo_Billdocument_Id =
|
|
order_line.scm_lpo_Billdocument_id
|
|
LEFT JOIN active_invoice_quantity AS reserved
|
|
ON reserved.source_line_id = order_line.scm_lpo_id
|
|
WHERE order_main.scm_mpo_Providerid = @source_supplier_id
|
|
AND LTRIM(RTRIM(CONVERT(NVARCHAR(20), order_main.scm_mpo_Currency))) =
|
|
CONVERT(NVARCHAR(20), @source_currency_id)
|
|
AND ISNULL(order_main.scm_mpo_stepover, 0) = 1
|
|
AND ISNULL(order_main.scm_mpo_cancelFlag, 0) = 0
|
|
AND ISNULL(order_main.scm_mpo_wasteoper, 0) = 0
|
|
AND ISNULL(order_main.scm_mpo_ban, 0) = 0
|
|
AND EXISTS
|
|
(
|
|
SELECT 1
|
|
FROM dbo.p_agent_purchase_row_scope AS allowed_scope
|
|
WHERE allowed_scope.account_book = @account_book
|
|
AND allowed_scope.subsystem_id = @subsystem_id
|
|
AND allowed_scope.erp_user_id = @user_id
|
|
AND CONVERT(NVARCHAR(20), allowed_scope.group_id) =
|
|
LTRIM(RTRIM(CONVERT(NVARCHAR(20), order_main.scm_mpo_Groupid)))
|
|
AND CONVERT(NVARCHAR(20), allowed_scope.department_id) =
|
|
LTRIM(RTRIM(CONVERT(NVARCHAR(20), order_main.scm_mpo_Departmentid)))
|
|
AND CONVERT(NVARCHAR(20), allowed_scope.purchase_user_id) =
|
|
LTRIM(RTRIM(CONVERT(NVARCHAR(20), order_main.scm_mpo_PurchaseUserId)))
|
|
AND allowed_scope.is_active = 1
|
|
AND allowed_scope.valid_from_utc <= SYSUTCDATETIME()
|
|
AND (allowed_scope.valid_to_utc IS NULL
|
|
OR allowed_scope.valid_to_utc > SYSUTCDATETIME())
|
|
AND LEN(allowed_scope.approval_evidence_sha256) = 64
|
|
AND allowed_scope.approval_evidence_sha256
|
|
COLLATE Latin1_General_100_BIN2 NOT LIKE '%[^0-9a-f]%'
|
|
)
|
|
)
|
|
SELECT TOP (10001)
|
|
CONVERT(NVARCHAR(50), scm_lpo_Billdocument_id) AS source_order_id,
|
|
CONVERT(NVARCHAR(50), COALESCE(
|
|
NULLIF(LTRIM(RTRIM(scm_mpo_handcraftId)), ''),
|
|
scm_lpo_Billdocument_id)) AS source_order_number,
|
|
CONVERT(NVARCHAR(32), scm_lpo_id) AS source_line_id,
|
|
CONVERT(NVARCHAR(32), scm_mpo_Providerid) AS supplier_code,
|
|
CONVERT(NVARCHAR(32), @source_currency_id) AS currency_code,
|
|
CONVERT(NVARCHAR(200), scm_lpo_Productid) AS material_code,
|
|
CONVERT(NVARCHAR(100), scm_lpo_ProductUnitName) AS unit,
|
|
remaining_quantity,
|
|
unit_price,
|
|
tax_rate,
|
|
exchange_rate,
|
|
CONVERT(BIT, 0) AS closed
|
|
FROM source_candidates
|
|
WHERE remaining_quantity > 0
|
|
ORDER BY scm_lpo_Billdocument_id, scm_lpo_id;
|
|
RETURN;
|
|
END;
|
|
|
|
IF @workflow = 'leave' AND @action = 'context'
|
|
BEGIN
|
|
SELECT
|
|
CONVERT(NVARCHAR(32), @current_employee_id) AS current_employee_id,
|
|
CONVERT(BIT, 0) AS can_apply_for_others,
|
|
CONVERT(DATETIME, DATEADD(HOUR, 8, SYSUTCDATETIME())) AS now_local;
|
|
RETURN;
|
|
END;
|
|
|
|
IF @workflow = 'leave' AND @action = 'resolve_type'
|
|
BEGIN
|
|
SET @query = NULLIF(LTRIM(RTRIM(@query)), N'');
|
|
IF @query IS NULL
|
|
BEGIN
|
|
RAISERROR(N'leave_type_query_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
;WITH leave_types AS
|
|
(
|
|
SELECT
|
|
CONVERT(NVARCHAR(64), 1) AS leave_type_code,
|
|
CONVERT(NVARCHAR(128), CONVERT(NVARCHAR(4), YEAR(GETDATE()))
|
|
+ N'年假剩余' + CONVERT(NVARCHAR(30), ISNULL(p_emp_holidaybalance, 0))
|
|
+ N'小时') AS leave_type_name,
|
|
CONVERT(NVARCHAR(64), N'本年年假') AS alias_one,
|
|
CONVERT(NVARCHAR(64), N'年假') AS alias_two
|
|
FROM dbo.p_employeetab WHERE employeeid = @current_employee_id
|
|
UNION ALL
|
|
SELECT CONVERT(NVARCHAR(64), 2),
|
|
CONVERT(NVARCHAR(128), CONVERT(NVARCHAR(4), YEAR(GETDATE()) - 1)
|
|
+ N'年假剩余' + CONVERT(NVARCHAR(30), ISNULL(p_emp_lastholidaybalance, 0))
|
|
+ N'小时'),
|
|
CONVERT(NVARCHAR(64), N'上年年假'), CONVERT(NVARCHAR(64), N'年假')
|
|
FROM dbo.p_employeetab WHERE employeeid = @current_employee_id
|
|
UNION ALL
|
|
SELECT CONVERT(NVARCHAR(64), 3),
|
|
CONVERT(NVARCHAR(128), CONVERT(NVARCHAR(4), YEAR(GETDATE()))
|
|
+ N'年调休剩余' + CONVERT(NVARCHAR(30), ISNULL(p_emp_txholidaybalance, 0))
|
|
+ N'小时'),
|
|
CONVERT(NVARCHAR(64), N'本年调休'), CONVERT(NVARCHAR(64), N'调休')
|
|
FROM dbo.p_employeetab WHERE employeeid = @current_employee_id
|
|
UNION ALL
|
|
SELECT CONVERT(NVARCHAR(64), 4),
|
|
CONVERT(NVARCHAR(128), CONVERT(NVARCHAR(4), YEAR(GETDATE()) - 1)
|
|
+ N'年调休剩余' + CONVERT(NVARCHAR(30), ISNULL(p_emp_lasttxholidaybalance, 0))
|
|
+ N'小时'),
|
|
CONVERT(NVARCHAR(64), N'上年调休'), CONVERT(NVARCHAR(64), N'调休')
|
|
FROM dbo.p_employeetab WHERE employeeid = @current_employee_id
|
|
UNION ALL
|
|
SELECT CONVERT(NVARCHAR(64), ID),
|
|
CONVERT(NVARCHAR(128), Mix_apellation),
|
|
CONVERT(NVARCHAR(64), Mix_NO),
|
|
CONVERT(NVARCHAR(64), Mix_apellation)
|
|
FROM dbo.P_BaseMixInfoTab
|
|
WHERE Tag = '7001801' AND Ban = 0 AND ID NOT IN (1, 2, 3, 4)
|
|
)
|
|
SELECT leave_type_code, leave_type_name
|
|
FROM leave_types
|
|
WHERE @query IN (leave_type_code, leave_type_name, alias_one, alias_two)
|
|
ORDER BY CONVERT(INT, leave_type_code), leave_type_code;
|
|
RETURN;
|
|
END;
|
|
|
|
IF @workflow = 'leave' AND @action = 'type_enabled'
|
|
BEGIN
|
|
SET @leave_type_code = NULLIF(LTRIM(RTRIM(@leave_type_code)), N'');
|
|
IF @leave_type_code IS NULL OR LEN(@leave_type_code) > 10
|
|
OR @leave_type_code LIKE N'%[^0-9]%'
|
|
BEGIN
|
|
SELECT CONVERT(BIT, 0) AS enabled;
|
|
RETURN;
|
|
END;
|
|
|
|
DECLARE @leave_type_number DECIMAL(10, 0);
|
|
DECLARE @leave_type_id INT;
|
|
SET @leave_type_number = CONVERT(DECIMAL(10, 0), @leave_type_code);
|
|
IF @leave_type_number < 1 OR @leave_type_number > 2147483647
|
|
BEGIN
|
|
SELECT CONVERT(BIT, 0) AS enabled;
|
|
RETURN;
|
|
END;
|
|
SET @leave_type_id = CONVERT(INT, @leave_type_number);
|
|
|
|
SELECT CONVERT(BIT,
|
|
CASE WHEN @leave_type_id IN (1, 2, 3, 4)
|
|
OR EXISTS
|
|
(
|
|
SELECT 1 FROM dbo.P_BaseMixInfoTab
|
|
WHERE ID = @leave_type_id
|
|
AND Tag = '7001801' AND Ban = 0
|
|
)
|
|
THEN 1 ELSE 0 END) AS enabled;
|
|
RETURN;
|
|
END;
|
|
|
|
IF @workflow = 'leave' AND @action = 'resolve_flow_type'
|
|
BEGIN
|
|
SET @employee_id = NULLIF(LTRIM(RTRIM(@employee_id)), N'');
|
|
SET @flow_type_query = NULLIF(LTRIM(RTRIM(@flow_type_query)), N'');
|
|
IF @employee_id IS NULL OR LEN(@employee_id) > 10
|
|
OR @employee_id LIKE N'%[^0-9]%'
|
|
OR @calculated_hours IS NULL
|
|
OR @calculated_hours <= 0 OR @calculated_hours > 744
|
|
BEGIN
|
|
RAISERROR(N'leave_flow_type_request_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
DECLARE @flow_employee_number DECIMAL(10, 0);
|
|
SET @flow_employee_number = CONVERT(DECIMAL(10, 0), @employee_id);
|
|
IF @flow_employee_number <> @current_employee_id
|
|
BEGIN
|
|
RAISERROR(N'leave_flow_type_request_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
IF
|
|
(
|
|
SELECT COUNT_BIG(*)
|
|
FROM dbo.p_systemdlltabflowtype AS flow_type
|
|
WHERE flow_type.typeCode = 'hr_4011'
|
|
AND ISNULL(flow_type.billflowban, 0) = 0
|
|
AND EXISTS
|
|
(
|
|
SELECT 1
|
|
FROM dbo.p_systemdlltabflowtypestep AS flow_step
|
|
WHERE flow_step.typeCode = 'hr_4011'
|
|
AND flow_step.billType = CONVERT(VARCHAR(10), flow_type.id)
|
|
AND ISNULL(flow_step.stepClosed, 0) = 0
|
|
)
|
|
AND
|
|
(
|
|
@flow_type_query IS NULL
|
|
OR CONVERT(NVARCHAR(64), flow_type.id) = @flow_type_query
|
|
OR CONVERT(NVARCHAR(128), flow_type.billTypeName) = @flow_type_query
|
|
)
|
|
) > 20
|
|
BEGIN
|
|
RAISERROR(N'leave_flow_type_candidates_exceeded', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
/*
|
|
calculated_hours is deliberately not used to infer an approval route. The
|
|
customer has multiple rank/day categories but no reviewed deterministic
|
|
employee-rank mapping. An empty query therefore returns every enabled choice.
|
|
*/
|
|
SELECT
|
|
CONVERT(NVARCHAR(64), flow_type.id) AS flow_type_code,
|
|
CONVERT(NVARCHAR(128), flow_type.billTypeName) AS flow_type_name
|
|
FROM dbo.p_systemdlltabflowtype AS flow_type
|
|
WHERE flow_type.typeCode = 'hr_4011'
|
|
AND ISNULL(flow_type.billflowban, 0) = 0
|
|
AND EXISTS
|
|
(
|
|
SELECT 1
|
|
FROM dbo.p_systemdlltabflowtypestep AS flow_step
|
|
WHERE flow_step.typeCode = 'hr_4011'
|
|
AND flow_step.billType = CONVERT(VARCHAR(10), flow_type.id)
|
|
AND ISNULL(flow_step.stepClosed, 0) = 0
|
|
)
|
|
AND
|
|
(
|
|
@flow_type_query IS NULL
|
|
OR CONVERT(NVARCHAR(64), flow_type.id) = @flow_type_query
|
|
OR CONVERT(NVARCHAR(128), flow_type.billTypeName) = @flow_type_query
|
|
)
|
|
ORDER BY flow_type.id;
|
|
RETURN;
|
|
END;
|
|
|
|
IF @workflow = 'leave' AND @action = 'flow_type_enabled'
|
|
BEGIN
|
|
SET @flow_type_code = NULLIF(LTRIM(RTRIM(@flow_type_code)), N'');
|
|
IF @flow_type_code IS NULL OR LEN(@flow_type_code) > 10
|
|
OR @flow_type_code LIKE N'%[^0-9]%'
|
|
BEGIN
|
|
SELECT CONVERT(BIT, 0) AS enabled;
|
|
RETURN;
|
|
END;
|
|
|
|
SELECT CONVERT(BIT, CASE WHEN EXISTS
|
|
(
|
|
SELECT 1
|
|
FROM dbo.p_systemdlltabflowtype
|
|
WHERE CONVERT(NVARCHAR(64), id) = @flow_type_code
|
|
AND typeCode = 'hr_4011'
|
|
AND ISNULL(billflowban, 0) = 0
|
|
AND EXISTS
|
|
(
|
|
SELECT 1
|
|
FROM dbo.p_systemdlltabflowtypestep
|
|
WHERE typeCode = 'hr_4011'
|
|
AND billType = @flow_type_code
|
|
AND ISNULL(stepClosed, 0) = 0
|
|
)
|
|
) THEN 1 ELSE 0 END) AS enabled;
|
|
RETURN;
|
|
END;
|
|
|
|
IF @workflow = 'leave' AND @action = 'resolve_calendar_range'
|
|
BEGIN
|
|
SET @employee_id = NULLIF(LTRIM(RTRIM(@employee_id)), N'');
|
|
IF @employee_id IS NULL OR LEN(@employee_id) > 10
|
|
OR @employee_id LIKE N'%[^0-9]%'
|
|
OR @local_date IS NULL OR LEN(@local_date) <> 10
|
|
OR SUBSTRING(@local_date, 5, 1) <> N'-'
|
|
OR SUBSTRING(@local_date, 8, 1) <> N'-'
|
|
OR STUFF(STUFF(@local_date, 8, 1, N''), 5, 1, N'') LIKE N'%[^0-9]%'
|
|
OR ISDATE(@local_date) <> 1
|
|
OR @day_part NOT IN ('morning', 'afternoon', 'full_day')
|
|
BEGIN
|
|
RAISERROR(N'leave_calendar_request_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
DECLARE @calendar_employee_number DECIMAL(10, 0);
|
|
DECLARE @calendar_employee_id INT;
|
|
DECLARE @calendar_date DATE;
|
|
SET @calendar_employee_number = CONVERT(DECIMAL(10, 0), @employee_id);
|
|
IF @calendar_employee_number <> @current_employee_id
|
|
BEGIN
|
|
RAISERROR(N'leave_calendar_request_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
SET @calendar_employee_id = CONVERT(INT, @calendar_employee_number);
|
|
SET @calendar_date = CONVERT(DATE, @local_date, 23);
|
|
|
|
DECLARE @schedule_count BIGINT;
|
|
SELECT @schedule_count = COUNT_BIG(*) FROM dbo.HR_ScheduleTab
|
|
WHERE HR_Schedule_employeeid = @calendar_employee_id
|
|
AND HR_Schedule_Date = @calendar_date;
|
|
|
|
IF @schedule_count = 0
|
|
BEGIN
|
|
SELECT CONVERT(BIT, 0) AS available,
|
|
CONVERT(VARCHAR(64), 'schedule_missing') AS reason_code,
|
|
CONVERT(DATETIME, NULL) AS start_local,
|
|
CONVERT(DATETIME, NULL) AS end_local,
|
|
CONVERT(DECIMAL(18, 4), NULL) AS hours,
|
|
CONVERT(NVARCHAR(128), NULL) AS time_zone_id;
|
|
RETURN;
|
|
END;
|
|
IF @schedule_count <> 1
|
|
BEGIN
|
|
RAISERROR(N'leave_calendar_duplicate_schedule', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
DECLARE @is_workday INT;
|
|
DECLARE @am_start_raw DATETIME;
|
|
DECLARE @am_end_raw DATETIME;
|
|
DECLARE @pm_start_raw DATETIME;
|
|
DECLARE @pm_end_raw DATETIME;
|
|
SELECT
|
|
@is_workday = HR_Schedule_IsWorkday,
|
|
@am_start_raw = HR_Schedule_AMStartTime,
|
|
@am_end_raw = HR_Schedule_AMEndTime,
|
|
@pm_start_raw = HR_Schedule_PMStartTime,
|
|
@pm_end_raw = HR_Schedule_PMEndTime
|
|
FROM dbo.HR_ScheduleTab
|
|
WHERE HR_Schedule_employeeid = @calendar_employee_id
|
|
AND HR_Schedule_Date = @calendar_date;
|
|
|
|
IF ISNULL(@is_workday, 0) <> 1
|
|
BEGIN
|
|
SELECT CONVERT(BIT, 0) AS available,
|
|
CONVERT(VARCHAR(64), 'not_workday') AS reason_code,
|
|
CONVERT(DATETIME, NULL) AS start_local,
|
|
CONVERT(DATETIME, NULL) AS end_local,
|
|
CONVERT(DECIMAL(18, 4), NULL) AS hours,
|
|
CONVERT(NVARCHAR(128), NULL) AS time_zone_id;
|
|
RETURN;
|
|
END;
|
|
|
|
IF @am_start_raw IS NULL OR @am_end_raw IS NULL
|
|
OR @pm_start_raw IS NULL OR @pm_end_raw IS NULL
|
|
BEGIN
|
|
RAISERROR(N'leave_calendar_shift_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
DECLARE @am_start DATETIME;
|
|
DECLARE @am_end DATETIME;
|
|
DECLARE @pm_start DATETIME;
|
|
DECLARE @pm_end DATETIME;
|
|
SET @am_start = DATEADD(MILLISECOND,
|
|
DATEDIFF(MILLISECOND, CONVERT(DATE, @am_start_raw), @am_start_raw),
|
|
CONVERT(DATETIME, @calendar_date));
|
|
SET @am_end = DATEADD(MILLISECOND,
|
|
DATEDIFF(MILLISECOND, CONVERT(DATE, @am_end_raw), @am_end_raw),
|
|
CONVERT(DATETIME, @calendar_date));
|
|
SET @pm_start = DATEADD(MILLISECOND,
|
|
DATEDIFF(MILLISECOND, CONVERT(DATE, @pm_start_raw), @pm_start_raw),
|
|
CONVERT(DATETIME, @calendar_date));
|
|
SET @pm_end = DATEADD(MILLISECOND,
|
|
DATEDIFF(MILLISECOND, CONVERT(DATE, @pm_end_raw), @pm_end_raw),
|
|
CONVERT(DATETIME, @calendar_date));
|
|
|
|
IF @am_start >= @am_end OR @pm_start >= @pm_end OR @am_end > @pm_start
|
|
BEGIN
|
|
RAISERROR(N'leave_calendar_shift_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
DECLARE @range_start DATETIME;
|
|
DECLARE @range_end DATETIME;
|
|
DECLARE @range_seconds BIGINT;
|
|
SET @range_start =
|
|
CASE WHEN @day_part = 'afternoon' THEN @pm_start ELSE @am_start END;
|
|
SET @range_end =
|
|
CASE WHEN @day_part = 'morning' THEN @am_end ELSE @pm_end END;
|
|
SET @range_seconds =
|
|
CASE WHEN @day_part = 'morning'
|
|
THEN DATEDIFF(SECOND, @am_start, @am_end)
|
|
WHEN @day_part = 'afternoon'
|
|
THEN DATEDIFF(SECOND, @pm_start, @pm_end)
|
|
ELSE DATEDIFF(SECOND, @am_start, @am_end)
|
|
+ DATEDIFF(SECOND, @pm_start, @pm_end)
|
|
END;
|
|
|
|
SELECT CONVERT(BIT, 1) AS available,
|
|
CONVERT(VARCHAR(64), 'ok') AS reason_code,
|
|
@range_start AS start_local,
|
|
@range_end AS end_local,
|
|
CONVERT(DECIMAL(18, 4), @range_seconds / 3600.0) AS hours,
|
|
CONVERT(NVARCHAR(128), N'China Standard Time') AS time_zone_id;
|
|
RETURN;
|
|
END;
|
|
|
|
IF @workflow = 'leave' AND @action IN ('calculate_hours', 'has_conflict')
|
|
BEGIN
|
|
SET @employee_id = NULLIF(LTRIM(RTRIM(@employee_id)), N'');
|
|
IF @employee_id IS NULL OR LEN(@employee_id) > 10
|
|
OR @employee_id LIKE N'%[^0-9]%'
|
|
OR @start_local IS NULL OR @end_local IS NULL
|
|
OR @end_local <= @start_local
|
|
OR DATEDIFF(DAY, CONVERT(DATE, @start_local), CONVERT(DATE, @end_local)) > 366
|
|
BEGIN
|
|
RAISERROR(N'leave_time_range_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
DECLARE @time_employee_number DECIMAL(10, 0);
|
|
DECLARE @time_employee_id INT;
|
|
SET @time_employee_number = CONVERT(DECIMAL(10, 0), @employee_id);
|
|
IF @time_employee_number <> @current_employee_id
|
|
BEGIN
|
|
RAISERROR(N'leave_time_range_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
SET @time_employee_id = CONVERT(INT, @time_employee_number);
|
|
|
|
IF @action = 'has_conflict'
|
|
BEGIN
|
|
SELECT CONVERT(BIT, CASE WHEN EXISTS
|
|
(
|
|
SELECT 1
|
|
FROM dbo.HR_EmpLeaveAloneTab
|
|
WHERE hr_ela_empid = @time_employee_id
|
|
AND hr_ela_starttime < @end_local
|
|
AND hr_ela_finishtime > @start_local
|
|
AND ISNULL(hr_ela_cancelFlag, 0) = 0
|
|
) THEN 1 ELSE 0 END) AS has_conflict;
|
|
RETURN;
|
|
END;
|
|
|
|
IF EXISTS
|
|
(
|
|
SELECT 1
|
|
FROM
|
|
(
|
|
SELECT TOP (DATEDIFF(DAY, CONVERT(DATE, @start_local),
|
|
CONVERT(DATE, @end_local)) + 1)
|
|
DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1,
|
|
CONVERT(DATE, @start_local)) AS work_date
|
|
FROM sys.all_objects
|
|
) AS requested_dates
|
|
WHERE NOT EXISTS
|
|
(
|
|
SELECT 1 FROM dbo.HR_ScheduleTab
|
|
WHERE HR_Schedule_employeeid = @time_employee_id
|
|
AND HR_Schedule_Date = requested_dates.work_date
|
|
)
|
|
)
|
|
BEGIN
|
|
RAISERROR(N'leave_calendar_schedule_missing', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
IF EXISTS
|
|
(
|
|
SELECT HR_Schedule_Date
|
|
FROM dbo.HR_ScheduleTab
|
|
WHERE HR_Schedule_employeeid = @time_employee_id
|
|
AND HR_Schedule_Date BETWEEN CONVERT(DATE, @start_local)
|
|
AND CONVERT(DATE, @end_local)
|
|
GROUP BY HR_Schedule_Date
|
|
HAVING COUNT_BIG(*) <> 1
|
|
)
|
|
BEGIN
|
|
RAISERROR(N'leave_calendar_schedule_duplicate', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
IF EXISTS
|
|
(
|
|
SELECT 1 FROM dbo.HR_ScheduleTab
|
|
WHERE HR_Schedule_employeeid = @time_employee_id
|
|
AND HR_Schedule_Date BETWEEN CONVERT(DATE, @start_local)
|
|
AND CONVERT(DATE, @end_local)
|
|
AND ISNULL(HR_Schedule_IsWorkday, 0) = 1
|
|
AND
|
|
(
|
|
HR_Schedule_AMStartTime IS NULL OR HR_Schedule_AMEndTime IS NULL
|
|
OR HR_Schedule_PMStartTime IS NULL OR HR_Schedule_PMEndTime IS NULL
|
|
OR CONVERT(TIME, HR_Schedule_AMStartTime)
|
|
>= CONVERT(TIME, HR_Schedule_AMEndTime)
|
|
OR CONVERT(TIME, HR_Schedule_PMStartTime)
|
|
>= CONVERT(TIME, HR_Schedule_PMEndTime)
|
|
OR CONVERT(TIME, HR_Schedule_AMEndTime)
|
|
> CONVERT(TIME, HR_Schedule_PMStartTime)
|
|
)
|
|
)
|
|
BEGIN
|
|
RAISERROR(N'leave_calendar_shift_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
;WITH schedule_days AS
|
|
(
|
|
SELECT
|
|
HR_Schedule_Date AS work_date,
|
|
HR_Schedule_AMStartTime AS am_start_raw,
|
|
HR_Schedule_AMEndTime AS am_end_raw,
|
|
HR_Schedule_PMStartTime AS pm_start_raw,
|
|
HR_Schedule_PMEndTime AS pm_end_raw
|
|
FROM dbo.HR_ScheduleTab
|
|
WHERE HR_Schedule_employeeid = @time_employee_id
|
|
AND HR_Schedule_Date BETWEEN CONVERT(DATE, @start_local)
|
|
AND CONVERT(DATE, @end_local)
|
|
AND ISNULL(HR_Schedule_IsWorkday, 0) = 1
|
|
),
|
|
work_segments AS
|
|
(
|
|
SELECT
|
|
DATEADD(MILLISECOND,
|
|
DATEDIFF(MILLISECOND, CONVERT(DATE, am_start_raw), am_start_raw),
|
|
CONVERT(DATETIME, work_date)) AS segment_start,
|
|
DATEADD(MILLISECOND,
|
|
DATEDIFF(MILLISECOND, CONVERT(DATE, am_end_raw), am_end_raw),
|
|
CONVERT(DATETIME, work_date)) AS segment_end
|
|
FROM schedule_days
|
|
UNION ALL
|
|
SELECT
|
|
DATEADD(MILLISECOND,
|
|
DATEDIFF(MILLISECOND, CONVERT(DATE, pm_start_raw), pm_start_raw),
|
|
CONVERT(DATETIME, work_date)),
|
|
DATEADD(MILLISECOND,
|
|
DATEDIFF(MILLISECOND, CONVERT(DATE, pm_end_raw), pm_end_raw),
|
|
CONVERT(DATETIME, work_date))
|
|
FROM schedule_days
|
|
),
|
|
overlaps AS
|
|
(
|
|
SELECT
|
|
CASE WHEN @start_local > segment_start THEN @start_local
|
|
ELSE segment_start END AS overlap_start,
|
|
CASE WHEN @end_local < segment_end THEN @end_local
|
|
ELSE segment_end END AS overlap_end
|
|
FROM work_segments
|
|
WHERE segment_start < segment_end
|
|
AND @start_local < segment_end
|
|
AND @end_local > segment_start
|
|
)
|
|
SELECT CONVERT(DECIMAL(18, 4),
|
|
ISNULL(SUM(CASE WHEN overlap_start < overlap_end
|
|
THEN DATEDIFF(SECOND, overlap_start, overlap_end)
|
|
ELSE 0 END), 0) / 3600.0) AS hours
|
|
FROM overlaps;
|
|
RETURN;
|
|
END;
|
|
|
|
IF @workflow = 'leave' AND @action = 'can_submit'
|
|
BEGIN
|
|
SET @record_id = NULLIF(LTRIM(RTRIM(@record_id)), N'');
|
|
IF @record_id IS NULL
|
|
BEGIN
|
|
RAISERROR(N'leave_record_id_invalid', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
IF
|
|
(
|
|
SELECT COUNT_BIG(*) FROM dbo.HR_EmpLeaveAloneTab
|
|
WHERE CONVERT(NVARCHAR(32), hr_ela_id) = @record_id
|
|
OR CONVERT(NVARCHAR(50), hr_ela_no) = @record_id
|
|
) > 1
|
|
BEGIN
|
|
RAISERROR(N'leave_record_identity_ambiguous', 16, 1);
|
|
RETURN;
|
|
END;
|
|
|
|
DECLARE @record_employee_id INT;
|
|
DECLARE @record_operator_id INT;
|
|
DECLARE @record_affirmer INT;
|
|
DECLARE @record_ban INT;
|
|
DECLARE @record_stepover INT;
|
|
DECLARE @record_cancel INT;
|
|
DECLARE @record_stepdirection CHAR(1);
|
|
DECLARE @record_start DATETIME;
|
|
DECLARE @record_end DATETIME;
|
|
DECLARE @record_hours FLOAT;
|
|
|
|
SELECT
|
|
@record_employee_id = hr_ela_empid,
|
|
@record_operator_id = hr_ela_operatorid,
|
|
@record_affirmer = hr_ela_Affirmer,
|
|
@record_ban = hr_ela_ban,
|
|
@record_stepover = hr_ela_stepover,
|
|
@record_cancel = hr_ela_cancelFlag,
|
|
@record_stepdirection = hr_ela_stepdirection,
|
|
@record_start = hr_ela_starttime,
|
|
@record_end = hr_ela_finishtime,
|
|
@record_hours = hr_ela_totals
|
|
FROM dbo.HR_EmpLeaveAloneTab
|
|
WHERE CONVERT(NVARCHAR(32), hr_ela_id) = @record_id
|
|
OR CONVERT(NVARCHAR(50), hr_ela_no) = @record_id;
|
|
|
|
DECLARE @can_submit BIT;
|
|
DECLARE @submit_reason NVARCHAR(128);
|
|
SET @can_submit = 1;
|
|
SET @submit_reason = N'ok';
|
|
|
|
IF @record_employee_id IS NULL
|
|
BEGIN
|
|
SET @can_submit = 0;
|
|
SET @submit_reason = N'record_not_found';
|
|
END
|
|
ELSE IF @record_employee_id <> @current_employee_id
|
|
AND ISNULL(@record_operator_id, -1) <> @current_employee_id
|
|
AND (@current_employee_id <> 1
|
|
OR @current_employee_name <> N'管理员')
|
|
AND ISNULL(@current_department_id, -1) <> 1
|
|
BEGIN
|
|
SET @can_submit = 0;
|
|
SET @submit_reason = N'record_owner_mismatch';
|
|
END
|
|
ELSE IF ISNULL(@record_cancel, 0) <> 0
|
|
BEGIN
|
|
SET @can_submit = 0;
|
|
SET @submit_reason = N'record_cancelled';
|
|
END
|
|
ELSE IF ISNULL(@record_affirmer, 0) <> 0
|
|
OR ISNULL(@record_stepover, 0) <> 0
|
|
OR ISNULL(@record_ban, 0) <> 0
|
|
OR ISNULL(@record_stepdirection, '') <> ''
|
|
BEGIN
|
|
SET @can_submit = 0;
|
|
SET @submit_reason = N'record_workflow_locked';
|
|
END
|
|
ELSE IF @record_start IS NULL OR @record_end IS NULL
|
|
OR @record_end <= @record_start OR ISNULL(@record_hours, 0) <= 0
|
|
BEGIN
|
|
SET @can_submit = 0;
|
|
SET @submit_reason = N'record_content_invalid';
|
|
END;
|
|
|
|
SELECT @can_submit AS can_submit, @submit_reason AS reason;
|
|
RETURN;
|
|
END;
|
|
|
|
RAISERROR(N'workflow_action_not_implemented', 16, 1);
|
|
RETURN;
|
|
END;
|
|
GO
|