namespace CRMSalesDAL.DTO.Deal;
///
/// SalesMind AI "Pipeline & Lead Intelligence" slice — the pipeline entity (TDEAL). Every Deal
/// originates from a Marketing TLEAD row via (not optional — this is
/// the concrete Marketing→Sales handoff point described in the plan
/// (~/.claude/plans/in-entitlement-also-we-async-charm.md, "Marketing→SalesMind SQL handoff")).
///
public class DealDTO
{
#region Deal
public int DealId { get; set; }
public string DealCode { get; set; } = string.Empty;
public string DealName { get; set; } = string.Empty;
/// FK to TLEAD — required on every Deal, never a sentinel/optional value.
public int LeadId { get; set; }
public string? LeadCode { get; set; }
public string? LeadName { get; set; }
/// 1=Lead, 2=Discovery, 3=Proposal, 4=Negotiation, 5=ClosedWon, 6=ClosedLost — see CK_TDEAL_STAGE.
public byte Stage { get; set; }
public decimal DealValue { get; set; }
///
/// 1=Hot, 2=Warm, 3=Cold — DERIVED, not user-editable. Recomputed in DealBLL.ComputeTemperature
/// from // on every save:
/// all 3 = "Yes" -> Hot; exactly 2 = "Yes" -> Warm; 0 or 1 = "Yes" -> Cold. Stored so
/// reads never recompute it (same precedent as ICPBLL.ComputeABCDCategory / ProductBLL's
/// ComputeProductLabel).
///
public byte Temperature { get; set; }
/// MAN qualification — Money. 1=Yes, 2=Partial, 3=No.
public byte MANMoney { get; set; }
/// MAN qualification — Authority. 1=Yes, 2=Partial, 3=No.
public byte MANAuthority { get; set; }
/// MAN qualification — Need. 1=Yes, 2=Partial, 3=No.
public byte MANNeed { get; set; }
///
/// Updated by DealBLL whenever differs from the previously-persisted value.
/// Never set directly by the caller on Update — DealBLL loads the current row and compares.
///
public DateTime StageChangedOn { get; set; }
///
/// Read-only, computed at query time as DATEDIFF(day, StageChangedOn, GETUTCDATE()) in
/// DealQB.GET_DEAL — never persisted, so it can never go stale. 0 on an unsaved/new DTO.
///
public int DaysInStage { get; set; }
public string? NextAction { get; set; }
///
/// Free-text/JSON array of flag strings, e.g. ["No response in 7 days"]. No separate
/// RiskFlag master table for v1 — see this module's migration header for the rationale.
///
public string? RiskFlags { get; set; }
///
/// FK to PayRoll's MEMPLOYEE (cross-module-readable, same pattern Marketing already uses for
/// MCONTACT). NULLABLE — not the repo's usual "-1 sentinel + dummy row" convention, because
/// MEMPLOYEE carries numerous NOT NULL FK dependencies (WorkOUId, DepartmentId, DesignationId,
/// etc.) that make a physical "-1 = not applicable" dummy employee row impractical to seed
/// safely. Same reasoning/precedent as ContentRefDTO.SourceContentId's nullable-FK decision.
///
public int? RepId { get; set; }
public string? RepCode { get; set; }
public string? RepName { get; set; }
public string? Remarks { get; set; }
#endregion
#region Base
public int CreatedById { get; set; }
public DateTime CreatedOn { get; set; }
public string? CreatedByName { get; set; }
public int ModifiedById { get; set; }
public DateTime ModifiedOn { get; set; }
public string? ModifiedByName { get; set; }
#endregion
#region Standard
public short SortOrder { get; set; }
public byte Status { get; set; }
public short Version { get; set; }
public int TenantId { get; set; }
#endregion
}