using System;
using System.Collections.Generic;
using static GB5Shared.GB5Constant.Constant;
namespace GB5Shared.DTO.WorkFlow
{
public static class ContractsDTO
{
// ── Pre-check result ──────────────────────────────────────────────────
///
/// Returned by CheckWorkFlowApplicability.
/// Tells the caller whether a workflow is applicable and which one.
///
public class WorkflowPreCheckResult
{
/// True when a workflow is configured and all conditions match.
public bool IsEnabled { get; set; }
///
/// 0 = None, 1 = Regular, 2 = WIP (form-based approval).
///
public int WorkFlowMode { get; set; }
/// PK of the resolved MWORKFLOW row.
public int WorkFlowId { get; set; }
/// PK of the matched MWORKFLOWCONFIG row (0 when no config found).
public int WorkflowConfigId { get; set; }
/// Whether the matched config has ISFORMBASEDAPPROVAL = 0 (0=Yes/Form-based).
public bool IsFormBasedApproval { get; set; }
///
/// Full URL of the entity save API used for the WIP approval callback.
/// Populated from MWORKFLOWCONFIG.CALLBACKENDPOINT when IsFormBasedApproval = true.
///
public string? CallbackEndpoint { get; set; }
}
// ── Workflow start result ─────────────────────────────────────────────
///
/// Returned by StartWorkflowAsync.
///
public class WorkflowStartResult
{
public bool IsStarted { get; set; }
public bool IsWip { get; set; }
public int WipId { get; set; }
public int WorkflowInstanceId { get; set; }
///
/// Tasks created at the first approval level.
/// BLL publishes one TOUTBOX event per entry (EventTypeCode = WORKFLOW_TASK_ASSIGNED)
/// AFTER the workflow transaction is committed.
///
public List PendingNotifications { get; set; } = new();
///
/// Populated when the first approval level has no applicable steps and the WIP
/// workflow finalises immediately at submission time (edge case).
/// EventHandler dispatches this AFTER committing the transaction.
///
public WipDispatchInfo? PendingDispatch { get; set; }
}
// ── Task notification ─────────────────────────────────────────────────
///
/// Carries the data needed to publish a WORKFLOW_TASK_ASSIGNED outbox event.
/// One instance is created per TWORKFLOWTASK row inserted by the engine.
///
public class WorkflowTaskNotificationRequest
{
public int TaskId { get; set; }
public int AssigneeUserId { get; set; }
public int WorkflowInstanceId { get; set; }
public int WorkflowId { get; set; }
public object? DataJson { get; set; }
///
/// JSON-serialized scalar facts from TWORKFLOWINSTANCE.FACTSJSON (DB_ENRICH bag:
/// ReportingToEmployeeId, MailId, DepartmentId, etc.).
/// Wrapped as {"Bag":...} and stored in OutboxDTO.ContextJson so
/// EmailActionHandler can resolve recipients via DeliveryType=12 without
/// an extra DB round-trip.
///
public string? FactsJson { get; set; }
}
// ── Action result ─────────────────────────────────────────────────────
///
/// Returned by HandleActionsAsync.
/// PendingDispatches is populated when a WIP instance reaches final approval.
/// Outcomes is populated for every terminal action (Approve-final, Reject, Return)
/// so the BLL can publish outcome events after the transaction commits.
/// The caller must dispatch WIP callbacks and publish outcome events AFTER committing.
///
public class WorkflowActionResult
{
public List PendingDispatches { get; set; } = new();
public List Outcomes { get; set; } = new();
///
/// One entry per action processed by HandleActionsAsync, regardless of whether it
/// was terminal for the workflow (unlike Outcomes, which only covers Approve-final /
/// Reject / Return). Lets the BLL build a per-item response message (e.g. "Leave
/// Request Approved Successfully") for every task the caller just acted on.
///
public List ProcessedItems { get; set; } = new();
}
// ── Per-item action context (for response message building) ───────────
///
/// Snapshot of the entity a single workflow task belongs to, captured for every
/// action processed — used by the BLL to resolve entity type / sub-type display
/// names for the caller's success message, independent of Outcomes' terminal-only
/// scope.
///
public class WorkflowActionItemInfo
{
public int TaskId { get; set; }
public int WorkflowInstanceId { get; set; }
/// MENTITY.ENTITYID of the document under workflow.
public int EntityId { get; set; }
/// PK of the document record (e.g. TaskId, LeaveId).
public int ObjectId { get; set; }
/// Action code taken by the caller — see .
public int Action { get; set; }
///
/// Serialised snapshot of the entity DTO as stored in TWORKFLOWINSTANCE.DATAJSON.
/// May be a raw JSON string or a boxed object — callers must handle both.
///
public object? DataJson { get; set; }
}
// ── Workflow outcome (Approve-final / Reject / Return) ────────────────
///
/// Carries the data needed to publish a WORKFLOW_APPROVED / WORKFLOW_REJECTED /
/// WORKFLOW_RETURNED outbox event. One instance is created per terminal action
/// processed by the engine (i.e. actions that change the overall workflow status
/// rather than just advancing an intermediate level).
///
/// For WIP workflows on Approve the WIP dispatcher already replays the entity save,
/// so no outcome is emitted —
/// covers that path.
///
///
public class WorkflowOutcomeInfo
{
/// PK of the TWORKFLOWINSTANCE row.
public int WorkflowInstanceId { get; set; }
/// PK of the MWORKFLOW definition.
public int WorkflowId { get; set; }
/// MENTITY.ENTITYID of the document under workflow.
public int EntityId { get; set; }
/// PK of the document record (e.g. TaskId, LeaveId).
public int ObjectId { get; set; }
///
/// Action code — .
/// 1 = Approve (final level), 2 = Reject, 3 = Return.
///
public int Action { get; set; }
/// UserId of the approver who took the action.
public int ActionByUserId { get; set; }
/// Optional comment left by the approver.
public string? Comment { get; set; }
///
/// Serialised snapshot of the entity DTO as stored in TWORKFLOWINSTANCE.DATAJSON.
/// May be a raw JSON string or a boxed object — callers must handle both.
///
public object? DataJson { get; set; }
///
/// JSON-serialized scalar facts from TWORKFLOWINSTANCE.FACTSJSON.
/// Written at workflow start from WorkflowStartRequest.Facts (DB_ENRICH bag values
/// such as ReportingToEmployeeId, DepartmentId).
/// Carried into the published Bag so
/// EmailActionHandler can resolve recipients via EnrichQualifier (DeliveryType=12)
/// without an extra DB round-trip.
///
public string? FactsJson { get; set; }
}
// ── Context for applicability check ──────────────────────────────────
///
/// Input to CheckWorkFlowApplicability.
/// Combines all dimensions used to resolve MWORKFLOWCONFIG.
///
public class WorkflowCheckContext
{
/// MENTITY.ENTITYID of the document being saved.
public int EntityId { get; set; }
///
/// OUId of the current session. Use -1 when not relevant.
/// Populated from LoginDTO.WorkOUId.
///
public int OUId { get; set; } = -1;
/// MBIZTRANSACTIONCLASS.BIZTRANSACTIONCLASSID. Use -1 when not relevant.
public int BizTransactionClassId { get; set; } = -1;
/// MBIZTRANSACTION.BIZTRANSACTIONID. Use -1 when not relevant.
public int BizTransactionId { get; set; } = -1;
///
/// Key/value pairs extracted from the DTO being saved.
/// These are evaluated against the EVALCONDITION of MWORKFLOWCONFIG
/// and each MWORKFLOWDETAIL step.
/// Example: { "TaskDetailType", 2 }
///
public IReadOnlyDictionary Facts { get; set; }
= new Dictionary();
}
// ── Context for starting a workflow ──────────────────────────────────
///
/// Full context required to start a new workflow instance.
/// Combines the resolution context with the document payload.
///
public class WorkflowStartRequest
{
// -- Config resolution fields (same as WorkflowCheckContext) --------
/// Entity ID of the document.
public int EntityId { get; set; }
/// OUId from the session. Defaults to -1 (any OU).
public int OUId { get; set; } = -1;
/// BizTransactionClassId. Defaults to -1 (any).
public int BizTransactionClassId { get; set; } = -1;
/// BizTransactionId. Defaults to -1 (any).
public int BizTransactionId { get; set; } = -1;
// -- Document fields ------------------------------------------------
/// PK of the document record (e.g. TaskId).
public int ObjectId { get; set; }
/// Serialised snapshot of the document for audit trail.
public object? DataJson { get; set; }
/// Optional submitter comment.
public string Comment { get; set; } = string.Empty;
///
/// Runtime facts extracted from the DTO.
/// Used both for config resolution and per-step condition evaluation.
///
public IReadOnlyDictionary Facts { get; set; }
= new Dictionary();
}
// ── Action context ────────────────────────────────────────────────────
///
/// Describes a single approver action (Approve / Reject / Return / Escalate).
///
public class WorkflowActionContext
{
/// PK of the TWORKFLOWTASK being acted on.
public int TaskId { get; set; }
/// UserId of the person taking the action.
public int UserId { get; set; }
///
/// Action code — see .
/// 0=Submit 1=Approve 2=Reject 3=Return 4=Escalate
///
public int Action { get; set; }
/// Optional comment left by the approver.
public string? Comment { get; set; }
///
/// Runtime facts forwarded from the client (used for next-step condition evaluation).
///
public IReadOnlyDictionary Facts { get; set; }
= new Dictionary();
}
// ── Simulation / graph ────────────────────────────────────────────────
public class WorkflowSimulationResult
{
public bool WorkflowExists { get; set; }
public bool Applicable { get; set; }
public string? DefinitionName { get; set; }
public IList StepKeys { get; set; } = new List();
public IList Actions { get; set; } = new List();
}
public class WorkflowGraph
{
public int EntityId { get; set; }
public string EntityName { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public IList Nodes { get; set; } = new List();
public IList Edges { get; set; } = new List();
}
public class WorkflowGraphNode
{
public long StepId { get; set; }
public string StepKey { get; set; } = string.Empty;
public int StepType { get; set; }
public bool IsInitial { get; set; }
public bool IsFinal { get; set; }
}
public class WorkflowGraphEdge
{
public long FromStepId { get; set; }
public long ToStepId { get; set; }
public string Trigger { get; set; } = string.Empty;
}
}
}