using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Globalization; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.Serialization; using System.Web.Http; using System.Collections; using System.Text.RegularExpressions; namespace Model { // 為對應資料表MODEL宣告額外參數類別(Metadata) // [JsonIgnore] 避免WEBAPI自動抓關聯資料 [MetadataType(typeof(pro_orderMetadata))] public partial class pro_order { private class pro_orderMetadata { [JsonIgnore] public virtual activity activity { get; set; } [JsonIgnore] public virtual follower follower { get; set; } [JsonIgnore] public virtual follower follower1 { get; set; } [JsonIgnore] public virtual ICollection bed_order { get; set; } [JsonIgnore] public virtual ICollection pro_order_detail { get; set; } } public string log; #region 單據狀態 public struct keyin { public string Text; public string Value; public string Color; } public ArrayList keyin1_list() { ArrayList options = new ArrayList(); keyin keyin; keyin.Value = "A01"; keyin.Text = "報名中"; keyin.Color = "#990000"; options.Add(keyin); keyin.Value = "A02"; keyin.Text = "已報名"; keyin.Color = "black"; options.Add(keyin); keyin.Value = "A05"; keyin.Text = "取消報名"; keyin.Color = "green"; options.Add(keyin); return options; } public static string keyin1_value_to_text(string v) { string tmp = ""; ArrayList keyin1 = new pro_order(). keyin1_list(); foreach (keyin k in keyin1) { if (k.Value == v) { tmp = k.Text; break; } } return tmp; } #endregion public enum detailKeyin1 : int //報名狀態 { [Description("未收款")] Unconfirmed = 1, [Description("分期​")] Collection = 2, [Description("已收款")] Paied = 3, [Description("呆帳")] Finish = 4 } } [MetadataType(typeof(pro_order_detailMetadata))] public partial class pro_order_detail { private class pro_order_detailMetadata { [JsonIgnore] public virtual actItem actItem { get; set; } [JsonIgnore] public virtual ICollection bed_order { get; set; } [JsonIgnore] public virtual follower follower { get; set; } [JsonIgnore] public virtual follower follower1 { get; set; } [JsonIgnore] public virtual pro_order pro_order { get; set; } [JsonIgnore] public virtual ICollection pro_order_record { get; set; } [JsonIgnore] public virtual ICollection accountings { get; set; } [JsonIgnore] public virtual ICollection transfer_register { get; set; } } /// /// 生成序列化ID(print_id)的方法,處理父項目和子項目的編號生成 /// /// 生成的序列化ID public string GenerateSequentialId() { Model.ezEntities _db = new Model.ezEntities(); string r = this.print_id; try { bool chk = true; actItem actitem = null; int? actitem_id = null; // 處理子項目的ID生成 if (!(this.parent_num == null || this.parent_num == 0)) { // 1. 查找父項目的資料 var parent_order_item = _db.pro_order_detail.Where( q => q.num == this.parent_num).FirstOrDefault(); // 2. 確認父項目存在且當前項目還沒有 print_id if (parent_order_item != null && string.IsNullOrEmpty(this.print_id)) { actitem_id = parent_order_item.actItem_num; string parent_print_id = parent_order_item.print_id; // 1. 獲取當前子項目的品項前綴 var currentActItem = _db.actItems .Where(q => q.num == this.actItem_num) .FirstOrDefault(); if (currentActItem != null && !string.IsNullOrEmpty(currentActItem.print_init)) { var itemPrefix = currentActItem.print_init.Trim(); // 2. 獲取同父項目且同品項的子項目編號 var siblings = _db.pro_order_detail .Where(q => q.parent_num == this.parent_num) // 找出同一個父項目的子項目 .Where(q => q.actItem_num == this.actItem_num) // 同品項 .Where(q => q.print_id != null) // Ensure print_id is not null .Select(q => q.print_id) // Just select the print_id .AsEnumerable() // Switch to in-memory operations .Where(q => q.StartsWith(parent_print_id)) // Now do string operations in memory .Where(q => q.Contains(itemPrefix)) .Select(q => q.Trim().Replace("\t", "")) .Select(q => q.Replace($"{parent_print_id}-{itemPrefix}", "")) .ToList(); // 3. 將所有序號轉換為數字陣列並過濾無效值 int[] intArray = siblings .Select(s => { int result; return int.TryParse(s, out result) ? (int?)result : null; }) .Where(i => i.HasValue && i.Value != 0) .Select(i => i.Value) .ToArray(); // 4. 生成新的序號(最大序號+1,並格式化為兩位數) int maxNum = 1 + (intArray.Any() ? intArray.Max() : 0); string formattedNum = maxNum < 10 ? "0" + maxNum : maxNum.ToString(); // 5. 組合新的 print_id(父項目ID-品項前綴序號) r = $"{parent_print_id}-{itemPrefix}{formattedNum}"; } } } // 處理主項目的ID生成 else { actitem_id = this.actItem_num; actitem = _db.actItems .Where(q => q.num == actitem_id).FirstOrDefault(); var proorder = _db.pro_order.Where(q => q.order_no == this.order_no).FirstOrDefault(); // 檢查是否需要生成新的 print_id chk = String.IsNullOrEmpty(r) && actitem != null && proorder != null && !string.IsNullOrEmpty(actitem.print_init); if (chk) { // 1. 組合活動和品項的前綴 var print_init = string.IsNullOrEmpty(proorder?.activity?.print_init) ? "" : proorder?.activity?.print_init.Trim(); var actitem_print_init = actitem.print_init.Trim(); var combinedPrintInit = print_init + actitem_print_init; // 2. 查找相同活動和品項的已存在編號 var actitems = _db.pro_order_detail .Where(q => q.pro_order.activity_num == proorder.activity_num) .Where(q => q.actItem_num == this.actItem_num) .Where(q => !string.IsNullOrEmpty(q.print_id)) .Where(q => q.print_id.StartsWith(combinedPrintInit)) .Where(q => q.parent_num == 0 || q.parent_num == null) .Select(q => q.print_id) .ToList(); // 3. 獲取最大序號 var maxNum = actitems .Select(item => { var match = Regex.Match(item, @"\d+"); return match.Success ? (int?)int.Parse(match.Value.TrimStart('0')) : null; }) .Where(num => num.HasValue) .DefaultIfEmpty(0) .Max() ?? 0; // 4. 生成新的序號(四位數格式) int newNum = maxNum + 1; string formattedNum = newNum.ToString().PadLeft(4, '0'); // 5. 組合最終的 print_id r = $"{combinedPrintInit}{formattedNum}"; } } } catch (Exception ex) { // 異常處理:記錄錯誤並返回原始 print_id Console.WriteLine($"Error generating sequential ID: {ex.Message}"); r = this.print_id; } return r; } } [MetadataType(typeof(pro_order_recordMetadata))] public partial class pro_order_record { private class pro_order_recordMetadata { /// /// 主鍵,付款記錄編號 /// [Display(Name = "付款記錄編號")] public int num { get; set; } /// /// 關聯到報名明細編號 (pro_order_detail.num) /// [Display(Name = "報名明細編號")] [Required(ErrorMessage = "報名明細編號為必填欄位")] public Nullable detail_num { get; set; } /// /// 付款金額 /// [Display(Name = "付款金額")] [Required(ErrorMessage = "付款金額為必填欄位")] [Range(0.01, double.MaxValue, ErrorMessage = "付款金額必須大於0")] public Nullable price { get; set; } /// /// 付款方式 (1=現金, 2=匯款, 3=支票) /// [Display(Name = "付款方式")] [Required(ErrorMessage = "付款方式為必填欄位")] public Nullable payment { get; set; } /// /// 登記時間 (系統自動產生) /// [Display(Name = "登記時間")] public Nullable reg_time { get; set; } /// /// 付款日期 /// [Display(Name = "付款日期")] [Required(ErrorMessage = "付款日期為必填欄位")] public Nullable pay_date { get; set; } /// /// 付款機構 (銀行名稱等) /// [Display(Name = "付款機構")] [StringLength(100, ErrorMessage = "付款機構長度不能超過100個字元")] public string organization { get; set; } /// /// 銀行代碼或帳號後5碼 /// [Display(Name = "帳號後5碼")] [StringLength(10, ErrorMessage = "帳號後5碼長度不能超過10個字元")] public string bank_code { get; set; } /// /// 關聯到匯款登記編號 (transfer_register.num) /// [Display(Name = "匯款登記編號")] public Nullable transfer_id { get; set; } /// /// 關聯到會計科目分類 /// [JsonIgnore] public virtual accounting_kind2 accounting_kind2 { get; set; } /// /// 關聯到報名明細 /// [JsonIgnore] public virtual pro_order_detail pro_order_detail { get; set; } /// /// 關聯到匯款登記資料 /// [JsonIgnore] public virtual transfer_register transfer_register { get; set; } } /// /// 付款方式列舉 /// public enum pay_kind : int { /// /// 現金付款 /// [Description("現金")] Cash = 1, /// /// 匯款付款 /// [Description("匯款")] ATM = 2, /// /// 支票付款 /// [Description("支票")] Check = 3 } /// /// 取得付款方式的中文描述 /// /// 付款方式代碼 /// 付款方式中文描述 public static string GetPaymentDescription(int? paymentType) { if (!paymentType.HasValue) return "未指定"; switch (paymentType.Value) { case (int)pay_kind.Cash: return "現金"; case (int)pay_kind.ATM: return "匯款"; case (int)pay_kind.Check: return "支票"; default: return "未知"; } } /// /// 取得付款方式的完整資訊 /// /// 包含付款方式、機構、帳號的完整資訊 public string GetPaymentFullInfo() { string paymentDesc = GetPaymentDescription(this.payment); string fullInfo = paymentDesc; if (!string.IsNullOrEmpty(this.organization)) { fullInfo += $" - {this.organization}"; } if (!string.IsNullOrEmpty(this.bank_code)) { fullInfo += $" ({this.bank_code})"; } return fullInfo; } } }