Files
lserp_cs_6.0/插件库/Lskj.AgentBridge/Deployment/customer-profiles/lserp-ai.workflow-read.compat100.draft.sql
T
2026-08-14 14:28:28 +08:00

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