397 lines
15 KiB
C#
397 lines
15 KiB
C#
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> bed_order { get; set; }
|
||
[JsonIgnore]
|
||
public virtual ICollection<pro_order_detail> 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> 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> pro_order_record { get; set; }
|
||
[JsonIgnore]
|
||
public virtual ICollection<accounting> accountings { get; set; }
|
||
[JsonIgnore]
|
||
public virtual ICollection<transfer_register> transfer_register { get; set; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成序列化ID(print_id)的方法,處理父項目和子項目的編號生成
|
||
/// </summary>
|
||
/// <returns>生成的序列化ID</returns>
|
||
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
|
||
{
|
||
/// <summary>
|
||
/// 主鍵,付款記錄編號
|
||
/// </summary>
|
||
[Display(Name = "付款記錄編號")]
|
||
public int num { get; set; }
|
||
|
||
/// <summary>
|
||
/// 關聯到報名明細編號 (pro_order_detail.num)
|
||
/// </summary>
|
||
[Display(Name = "報名明細編號")]
|
||
[Required(ErrorMessage = "報名明細編號為必填欄位")]
|
||
public Nullable<int> detail_num { get; set; }
|
||
|
||
/// <summary>
|
||
/// 付款金額
|
||
/// </summary>
|
||
[Display(Name = "付款金額")]
|
||
[Required(ErrorMessage = "付款金額為必填欄位")]
|
||
[Range(0.01, double.MaxValue, ErrorMessage = "付款金額必須大於0")]
|
||
public Nullable<float> price { get; set; }
|
||
|
||
/// <summary>
|
||
/// 付款方式 (1=現金, 2=匯款, 3=支票)
|
||
/// </summary>
|
||
[Display(Name = "付款方式")]
|
||
[Required(ErrorMessage = "付款方式為必填欄位")]
|
||
public Nullable<int> payment { get; set; }
|
||
|
||
/// <summary>
|
||
/// 登記時間 (系統自動產生)
|
||
/// </summary>
|
||
[Display(Name = "登記時間")]
|
||
public Nullable<System.DateTime> reg_time { get; set; }
|
||
|
||
/// <summary>
|
||
/// 付款日期
|
||
/// </summary>
|
||
[Display(Name = "付款日期")]
|
||
[Required(ErrorMessage = "付款日期為必填欄位")]
|
||
public Nullable<System.DateTime> pay_date { get; set; }
|
||
|
||
/// <summary>
|
||
/// 付款機構 (銀行名稱等)
|
||
/// </summary>
|
||
[Display(Name = "付款機構")]
|
||
[StringLength(100, ErrorMessage = "付款機構長度不能超過100個字元")]
|
||
public string organization { get; set; }
|
||
|
||
/// <summary>
|
||
/// 銀行代碼或帳號後5碼
|
||
/// </summary>
|
||
[Display(Name = "帳號後5碼")]
|
||
[StringLength(10, ErrorMessage = "帳號後5碼長度不能超過10個字元")]
|
||
public string bank_code { get; set; }
|
||
|
||
/// <summary>
|
||
/// 關聯到匯款登記編號 (transfer_register.num)
|
||
/// </summary>
|
||
[Display(Name = "匯款登記編號")]
|
||
public Nullable<int> transfer_id { get; set; }
|
||
|
||
/// <summary>
|
||
/// 關聯到會計科目分類
|
||
/// </summary>
|
||
[JsonIgnore]
|
||
public virtual accounting_kind2 accounting_kind2 { get; set; }
|
||
|
||
/// <summary>
|
||
/// 關聯到報名明細
|
||
/// </summary>
|
||
[JsonIgnore]
|
||
public virtual pro_order_detail pro_order_detail { get; set; }
|
||
|
||
/// <summary>
|
||
/// 關聯到匯款登記資料
|
||
/// </summary>
|
||
[JsonIgnore]
|
||
public virtual transfer_register transfer_register { get; set; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 付款方式列舉
|
||
/// </summary>
|
||
public enum pay_kind : int
|
||
{
|
||
/// <summary>
|
||
/// 現金付款
|
||
/// </summary>
|
||
[Description("現金")]
|
||
Cash = 1,
|
||
|
||
/// <summary>
|
||
/// 匯款付款
|
||
/// </summary>
|
||
[Description("匯款")]
|
||
ATM = 2,
|
||
|
||
/// <summary>
|
||
/// 支票付款
|
||
/// </summary>
|
||
[Description("支票")]
|
||
Check = 3
|
||
}
|
||
|
||
/// <summary>
|
||
/// 取得付款方式的中文描述
|
||
/// </summary>
|
||
/// <param name="paymentType">付款方式代碼</param>
|
||
/// <returns>付款方式中文描述</returns>
|
||
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 "未知";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 取得付款方式的完整資訊
|
||
/// </summary>
|
||
/// <returns>包含付款方式、機構、帳號的完整資訊</returns>
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
|