Files
XRLib/Assets/Scripts/SHI/modal/ISOP/ISOPChartData.cs
2026-01-21 20:43:54 +09:00

174 lines
7.3 KiB
C#

using System;
using System.Collections.Generic;
namespace SHI.Modal.ISOP
{
/// <summary>
/// ISOP(조선소 공정 계획) 간트 차트의 개별 작업(Task) 데이터를 나타냅니다.
///
/// <para><b>개요:</b></para>
/// <para>
/// JSON 파일에서 역직렬화되어 ISOPChart에서 간트 차트를 렌더링하는 데 사용됩니다.
/// 각 작업은 계획 일정(파란색 막대)과 실적 일정(연두색 막대)을 가집니다.
/// L1~L8 필드는 작업의 계층 구조를 나타내며, 가장 하위의 유효한 값이 표시 이름으로 사용됩니다.
/// </para>
///
/// <para><b>주요 필드:</b></para>
/// <list type="bullet">
/// <item>PROJ_NO, BLK_NO - 프로젝트 및 블록 식별자</item>
/// <item>L1~L8 - 작업 계층 구조 (WBS: Work Breakdown Structure)</item>
/// <item>STDT21, FNDT21, DUR21 - 계획 시작일, 종료일, 기간</item>
/// <item>STDT23, FNDT23, DUR23 - 실적 시작일, 종료일, 기간</item>
/// </list>
///
/// <para><b>날짜 형식:</b></para>
/// <para>모든 날짜 필드는 "yyyyMMdd" 형식의 문자열입니다. (예: "20250115")</para>
/// </summary>
[Serializable]
public class ISOPChartDataTask
{
#region (Basic Information)
/// <summary>프로젝트 번호</summary>
public string PROJ_NO;
/// <summary>블록 번호 (선박 건조 블록 식별자)</summary>
public string BLK_NO;
/// <summary>선박 타입</summary>
public string SHIP_TYPE;
#endregion
#region (Work Breakdown Structure)
/// <summary>레벨 1 작업명 (최상위)</summary>
public string L1;
/// <summary>레벨 2 작업명</summary>
public string L2;
/// <summary>레벨 3 작업명</summary>
public string L3;
/// <summary>레벨 4 작업명</summary>
public string L4;
/// <summary>레벨 5 작업명</summary>
public string L5;
/// <summary>레벨 6 작업명</summary>
public string L6;
/// <summary>레벨 7 작업명</summary>
public string L7;
/// <summary>레벨 8 작업명 (최하위)</summary>
public string L8;
#endregion
#region - 21 (Plan Schedule)
/// <summary>계획 시작일 (yyyyMMdd 형식). 차트에서 파란색 막대로 표시됩니다.</summary>
public string STDT21;
/// <summary>계획 종료일 (yyyyMMdd 형식)</summary>
public string FNDT21;
/// <summary>계획 기간 (일 단위)</summary>
public int DUR21;
#endregion
#region - 23 (Actual Schedule)
/// <summary>실적 시작일 (yyyyMMdd 형식). 차트에서 연두색 막대로 표시됩니다.</summary>
public string STDT23;
/// <summary>실적 종료일 (yyyyMMdd 형식)</summary>
public string FNDT23;
/// <summary>실적 기간 (일 단위)</summary>
public int DUR23;
#endregion
#region (Additional Work Code Schedules)
/// <summary>작업 코드 43 일정</summary>
public string STDT43, FNDT43; public int DUR43;
/// <summary>작업 코드 44 일정</summary>
public string STDT44, FNDT44; public int DUR44;
/// <summary>작업 코드 46 일정</summary>
public string STDT46, FNDT46; public int DUR46;
/// <summary>작업 코드 49 일정</summary>
public string STDT49, FNDT49; public int DUR49;
/// <summary>작업 코드 4A 일정</summary>
public string STDT4A, FNDT4A; public int DUR4A;
/// <summary>작업 코드 4B 일정</summary>
public string STDT4B, FNDT4B; public int DUR4B;
/// <summary>작업 코드 62 일정</summary>
public string STDT62, FNDT62; public int DUR62;
#endregion
#region (Calculated Values)
/// <summary>
/// 런타임에 계산되는 진행률 (0~100).
/// JSON 직렬화에서 제외됩니다.
/// </summary>
[NonSerialized] public float CalculatedProgress;
#endregion
#region (Date Conversion Methods)
/// <summary>계획 시작일을 DateTime으로 반환합니다.</summary>
/// <returns>파싱된 DateTime 또는 null</returns>
public DateTime? GetPlanStart() => ParseDate(STDT21);
/// <summary>계획 종료일을 DateTime으로 반환합니다.</summary>
/// <returns>파싱된 DateTime 또는 null</returns>
public DateTime? GetPlanEnd() => ParseDate(FNDT21);
/// <summary>실적 시작일을 DateTime으로 반환합니다.</summary>
/// <returns>파싱된 DateTime 또는 null</returns>
public DateTime? GetActualStart() => ParseDate(STDT23);
/// <summary>실적 종료일을 DateTime으로 반환합니다.</summary>
/// <returns>파싱된 DateTime 또는 null</returns>
public DateTime? GetActualEnd() => ParseDate(FNDT23);
/// <summary>
/// yyyyMMdd 형식의 문자열을 DateTime으로 파싱합니다.
/// </summary>
/// <param name="dateStr">날짜 문자열 (예: "20250115")</param>
/// <returns>파싱된 DateTime 또는 null (빈 문자열이나 "null"인 경우)</returns>
private DateTime? ParseDate(string dateStr)
{
if (string.IsNullOrEmpty(dateStr) || dateStr == "null") return null;
if (DateTime.TryParseExact(dateStr, "yyyyMMdd", null, System.Globalization.DateTimeStyles.None, out DateTime date))
return date;
return null;
}
#endregion
#region (Display Methods)
/// <summary>
/// 작업의 표시 이름을 반환합니다.
/// L8부터 L1까지 역순으로 검사하여 첫 번째 유효한 값을 반환합니다.
/// 모든 레벨이 비어있으면 BLK_NO를 반환합니다.
/// </summary>
/// <returns>표시할 작업명</returns>
public string GetDisplayName()
{
// 가장 하위 레벨(L8)부터 검사하여 유효한 값 반환
if (!string.IsNullOrEmpty(L8)) return L8;
if (!string.IsNullOrEmpty(L7)) return L7;
if (!string.IsNullOrEmpty(L6)) return L6;
if (!string.IsNullOrEmpty(L5)) return L5;
if (!string.IsNullOrEmpty(L4)) return L4;
if (!string.IsNullOrEmpty(L3)) return L3;
if (!string.IsNullOrEmpty(L2)) return L2;
return L1 ?? BLK_NO;
}
#endregion
}
/// <summary>
/// ISOPChartDataTask 목록을 감싸는 래퍼 클래스입니다.
/// JSON 역직렬화 시 배열을 객체로 감싸기 위해 사용됩니다.
///
/// <para><b>사용 예시:</b></para>
/// <code>
/// var json = File.ReadAllText(path);
/// var wrapper = JsonUtility.FromJson<ISOPChartDataWrapper>("{\"items\":" + json + "}");
/// var tasks = wrapper.items;
/// </code>
/// </summary>
[Serializable]
public class ISOPChartDataWrapper
{
/// <summary>작업 데이터 목록</summary>
public List<ISOPChartDataTask> items;
}
}