using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using AMESCoreStudio.WebApi.Models.AMES;
using AMESCoreStudio.CommonTools.Result;
using AMESCoreStudio.WebApi.DTO.AMES;

namespace AMESCoreStudio.WebApi.Controllers.AMES
{
    /// <summary>
    /// 出貨序號編碼規則基本資料檔Controller
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class SerialRulesController : ControllerBase
    {
        private readonly AMESContext _context;

        /// <summary>
        /// 建構式
        /// </summary>
        /// <param name="context"></param>
        public SerialRulesController(AMESContext context)
        {
            _context = context;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ActionResult<IEnumerable<SerialRule>>> GetSerialRule(int page = 0, int limit = 10)
        {
            IQueryable<SerialRule> q = _context.SerialRules;
            if (page > 0)
            {
                q = q.OrderBy(p => p.SerialRuleID).Skip((page - 1) * limit).Take(limit);
            }
            else
            {
                q = q.OrderBy(p => p.SerialRuleID);
            }
            //q = q.OrderBy(p => p.SerialRuleID);
            var SerialRule = await q.ToListAsync();
            return SerialRule;
        }

        /// <summary>
        /// 出貨序號編碼規則基本資料檔 to SerialRuleID
        /// </summary>
        /// <param name="id">SerialRuleID</param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<ActionResult<IEnumerable<SerialRule>>> GetSerialRule(int id)
        {
            IQueryable<SerialRule> q = _context.SerialRules;

            var SerialRule = await q.Where(p => p.SerialRuleID == id).ToListAsync();
            return SerialRule;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [HttpGet("ItemNo/{id}")]
        public async Task<ActionResult<IEnumerable<SerialRule>>> GetSerialRuleByItemNo(string id, int page = 0, int limit = 10)
        {
            IQueryable<SerialRule> q = _context.SerialRules;

            q = q.Where(p => p.ItemNo == id);
            if (page > 0)
            {
                q = q.OrderBy(p => p.SerialRuleID).Skip((page - 1) * limit).Take(limit);
            }
            else
            {
                q = q.OrderBy(p => p.SerialRuleID);
            }
            var SerialRule = await q.ToListAsync();

            if (SerialRule == null)
            {
                return NotFound();
            }

            return SerialRule;

        }

        /// <summary>
        /// 取得出貨序號(單個)
        /// </summary>
        /// <param name="itemNo">料號</param>
        /// <param name="lotNo">生產序號</param>
        /// <returns></returns>
        [HttpGet("ByQurey/{itemNo}/{lotNo}")]
        public async Task<ResultModel<string>> GetSerialRuleByQurey(string itemNo, string lotNo)
        {
            IQueryable<SerialRule> q = _context.SerialRules;
            ResultModel<string> result = new ResultModel<string>();
            var serialRule = await q.Where(p => p.ItemNo == itemNo).FirstOrDefaultAsync();
            var serialRuleNew = serialRule;
            if (serialRule == null)
            {
                result.Success = false;
                result.Msg = "無料號對應出貨序號規則";
                return result;
            }
            if (serialRule.LotLen != 0)
            {
                if (lotNo == null)
                {


                    result.Success = false;
                    result.Msg = "所輸入LOT字數與規則不符合";
                    return result;


                }
                if (serialRule.LotLen != lotNo.Length)
                {
                    result.Success = false;
                    result.Msg = "所輸入LOT字數與規則不符合";
                    return result;
                }

            }



            var strRule = serialRule.Rule.ToUpper();
            var serial = serialRule.Rule;
            if (strRule.Contains("[YYYY]")) //年份
            {
                serial = serial.Replace("[YYYY]", System.DateTime.Now.ToString("yyyy"));
                if (serialRule.YNum != System.DateTime.Now.Year)
                {
                    serialRuleNew.YNum = System.DateTime.Now.Year;
                    if (serialRule.SnNum > 0)
                        serialRuleNew.SnNum = 0;
                }
            }
            if (strRule.Contains("[YY]"))//年份後兩碼
            {
                serial = serial.Replace("[YY]", System.DateTime.Now.ToString("yy"));
                if (serialRule.YNum.ToString() != System.DateTime.Now.ToString("yy"))
                {
                    serialRuleNew.YNum = int.Parse(System.DateTime.Now.ToString("yy"));
                    if (serialRule.SnNum > 0)
                        serialRuleNew.SnNum = 0;
                }
            }
            if (strRule.Contains("[MM]"))//月份
            {
                serial = serial.Replace("[MM]", System.DateTime.Now.ToString("MM"));

                if (serialRule.MNum != System.DateTime.Now.Month)
                {
                    serialRuleNew.MNum = System.DateTime.Now.Month;
                    if (serialRule.SnNum > 0)
                        serialRuleNew.SnNum = 0;
                }
            }
            //if (strRule.Contains("[MM1]"))//月份縮寫
            //{
            //    serial = strRule.Replace("[MM]", System.DateTime.Now.ToString("MMM"));
            //}
            if (strRule.Contains("[WW]"))
            {
                System.Globalization.GregorianCalendar gc = new System.Globalization.GregorianCalendar();
                DateTime datetime = DateTime.Now;
                int week = gc.GetWeekOfYear(datetime, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
                serial = serial.Replace("[WW]", week.ToString().Length == 1 ? week.ToString().PadLeft(2, '0') : week.ToString());

                if (serialRule.WNum != week)
                {
                    serialRuleNew.WNum = week;
                    if (serialRule.SnNum > 0)
                        serialRuleNew.SnNum = 0;
                }
            }
            if (strRule.Contains("[LOT3]"))
            {
                serial = serial.Replace("[LOT3]", lotNo);
            }
            if (strRule.Contains("[LOT4]"))
            {
                serial = serial.Replace("[LOT4]", lotNo);
            }
            if (strRule.Contains("[SN3]"))
            {
                serialRuleNew.SnNum++;
                serial = serial.Replace("[SN3]", serialRuleNew.SnNum.ToString("000"));
            }
            if (strRule.Contains("[SN4]"))
            {
                serialRuleNew.SnNum++;
                serial = serial.Replace("[SN4]", serialRuleNew.SnNum.ToString("0000"));
            }
            if (strRule.Contains("[SN5]"))
            {
                serialRuleNew.SnNum++;
                serial = serial.Replace("[SN5]", serialRuleNew.SnNum.ToString("00000"));
            }
            if (strRule.Contains("[SN6]"))
            {
                serialRuleNew.SnNum++;
                serial = serial.Replace("[SN6]", serialRuleNew.SnNum.ToString("000000"));
            }

            if (string.IsNullOrWhiteSpace(serial))
            {
                result.Success = false;
                result.Msg = "該筆料號設定出貨序號規則有錯誤,請在確認!";
                return result;
            }

            _context.Entry(serialRuleNew).State = EntityState.Modified;
            try
            {
                await _context.SaveChangesAsync();
                result.Success = true;
                result.Msg = serial;

            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.InnerException.Message;
            }
            return result;
        }

        /// <summary>
        /// 取得出貨序號(多個)
        /// </summary>
        /// <param name="itemNo">料號</param>
        /// <param name="lotNo">生產序號</param>
        /// <param name="num">生產數量</param>
        /// <returns></returns>
        [HttpGet("ByQurey/{itemNo}/{lotNo}/{num}")]
        public async Task<ResultModel<string>> GetSerialRuleByQurey(string itemNo, string lotNo, int num)
        {
            IQueryable<SerialRule> q = _context.SerialRules;
            ResultModel<string> result = new ResultModel<string>();
            var serialRule = await q.Where(p => p.ItemNo == itemNo).FirstOrDefaultAsync();
            var serialRuleNew = serialRule;
            var strRule = "";
            var serial = "";
            var minSerial = "";
            var maxSerial = "";
            if (num <= 0)
            {
                result.Success = false;
                result.Msg = "請輸入出貨數量!!";
                return result;
            }
            if (serialRule == null || itemNo.ToUpper() == "OTHER")
            {
                itemNo = "OTHER";
                if (lotNo.Length != 2)
                {
                    result.Success = false;
                    result.Msg = "前置碼長度為2";
                    //result.Msg = "無料號對應出貨序號規則";
                    return result;
                }
                else
                {
                    serialRule = await q.Where(p => p.ItemNo == "OTHER").FirstOrDefaultAsync();
                    serialRuleNew = serialRule;
                    strRule = serialRule.Rule.ToUpper();
                    serial = serialRule.Rule;

                    if (strRule.Contains("[SS]"))
                    {
                        serial = serial.Replace("[SS]", lotNo);
                    }
                    if (strRule.Contains("[WW]"))
                    {
                        System.Globalization.GregorianCalendar gc = new System.Globalization.GregorianCalendar();
                        DateTime datetime = DateTime.Now;
                        int week = gc.GetWeekOfYear(datetime, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
                        serial = serial.Replace("[WW]", week.ToString().Length == 1 ? week.ToString().PadLeft(2, '0') : week.ToString());

                        if (serialRule.WNum != week)
                        {
                            serialRuleNew.WNum = week;
                            if (serialRule.SnNum > 0)
                                serialRuleNew.SnNum = 0;
                        }
                    }
                    if (strRule.Contains("[YY]"))//年份後兩碼
                    {
                        var strYY = System.DateTime.Now.ToString("yy");
                        if (serialRule.YNum.ToString() != System.DateTime.Now.ToString("yy"))
                        {
                            serialRuleNew.YNum = int.Parse(System.DateTime.Now.ToString("yy"));
                            if (serialRule.SnNum > 0)
                                serialRuleNew.SnNum = 0;
                        }
                        strYY = strYY.Replace("0", "Z");
                        strYY = strYY.Replace("1", "A");
                        strYY = strYY.Replace("2", "B");
                        strYY = strYY.Replace("3", "C");
                        strYY = strYY.Replace("4", "D");
                        strYY = strYY.Replace("5", "E");
                        strYY = strYY.Replace("6", "F");
                        strYY = strYY.Replace("7", "G");
                        strYY = strYY.Replace("8", "H");
                        strYY = strYY.Replace("9", "J");

                        serial = serial.Replace("[YY]", strYY);
                    }
                    if (strRule.Contains("[SN5]"))
                    {
                        serialRuleNew.SnNum++;
                        if (num > 1)
                        {
                            minSerial = serial;
                            maxSerial = serial;
                            minSerial = minSerial.Replace("[SN5]", serialRuleNew.SnNum.ToString("00000"));
                            serialRuleNew.SnNum = serialRuleNew.SnNum + num - 1;
                            maxSerial = maxSerial.Replace("[SN5]", serialRuleNew.SnNum.ToString("00000"));
                            serial = minSerial + "~" + maxSerial;
                        }
                        else
                        {
                            serial = serial.Replace("[SN5]", serialRuleNew.SnNum.ToString("00000"));
                        }
                    }
                }
            }
            else
            {
                if (serialRule.LotLen != 0)
                {
                    if (lotNo == null)
                    {
                        result.Success = false;
                        result.Msg = "所輸入LOT字數與規則不符合";
                        return result;
                    }
                    if (serialRule.LotLen != lotNo.Length)
                    {
                        result.Success = false;
                        result.Msg = "所輸入LOT字數與規則不符合";
                        return result;
                    }
                }

                strRule = serialRule.Rule.ToUpper();
                serial = serialRule.Rule;
                if (strRule.Contains("[YYYY]")) //年份
                {
                    serial = serial.Replace("[YYYY]", System.DateTime.Now.ToString("yyyy"));
                    if (serialRule.YNum != System.DateTime.Now.Year)
                    {
                        serialRuleNew.YNum = System.DateTime.Now.Year;
                        if (serialRule.SnNum > 0)
                            serialRuleNew.SnNum = 0;
                    }
                }
                if (strRule.Contains("[YY]"))//年份後兩碼
                {
                    serial = serial.Replace("[YY]", System.DateTime.Now.ToString("yy"));
                    if (serialRule.YNum.ToString() != System.DateTime.Now.ToString("yy"))
                    {
                        serialRuleNew.YNum = int.Parse(System.DateTime.Now.ToString("yy"));
                        if (serialRule.SnNum > 0)
                            serialRuleNew.SnNum = 0;
                    }
                }
                if (strRule.Contains("[MM]"))//月份
                {
                    serial = serial.Replace("[MM]", System.DateTime.Now.ToString("MM"));

                    if (serialRule.MNum != System.DateTime.Now.Month)
                    {
                        serialRuleNew.MNum = System.DateTime.Now.Month;
                        if (serialRule.SnNum > 0)
                            serialRuleNew.SnNum = 0;
                    }
                }
                if (strRule.Contains("[WW]"))
                {
                    System.Globalization.GregorianCalendar gc = new System.Globalization.GregorianCalendar();
                    DateTime datetime = DateTime.Now;
                    int week = gc.GetWeekOfYear(datetime, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
                    serial = serial.Replace("[WW]", week.ToString().Length == 1 ? week.ToString().PadLeft(2, '0') : week.ToString());

                    if (serialRule.WNum != week)
                    {
                        serialRuleNew.WNum = week;
                        if (serialRule.SnNum > 0)
                            serialRuleNew.SnNum = 0;
                    }
                }
                if (strRule.Contains("[LOT3]"))
                {
                    serial = serial.Replace("[LOT3]", lotNo);
                }
                if (strRule.Contains("[LOT4]"))
                {
                    serial = serial.Replace("[LOT4]", lotNo);
                }
                if (strRule.Contains("[SN3]"))
                {
                    serialRuleNew.SnNum++;
                    if (num > 1)
                    {
                        minSerial = serial;
                        maxSerial = serial;
                        minSerial = minSerial.Replace("[SN3]", serialRuleNew.SnNum.ToString("000"));
                        serialRuleNew.SnNum = serialRuleNew.SnNum + num - 1;
                        maxSerial = maxSerial.Replace("[SN3]", serialRuleNew.SnNum.ToString("000"));
                        serial = minSerial + "~" + maxSerial;
                    }
                    else
                    {
                        serial = serial.Replace("[SN3]", serialRuleNew.SnNum.ToString("000"));
                    }
                }
                if (strRule.Contains("[SN4]"))
                {
                    serialRuleNew.SnNum++;
                    if (num > 1)
                    {
                        minSerial = serial;
                        maxSerial = serial;
                        minSerial = minSerial.Replace("[SN4]", serialRuleNew.SnNum.ToString("0000"));
                        serialRuleNew.SnNum = serialRuleNew.SnNum + num - 1;
                        maxSerial = maxSerial.Replace("[SN4]", serialRuleNew.SnNum.ToString("0000"));
                        serial = minSerial + "~" + maxSerial;
                    }
                    else
                    {
                        serial = serial.Replace("[SN4]", serialRuleNew.SnNum.ToString("0000"));
                    }
                }
                if (strRule.Contains("[SN5]"))
                {
                    serialRuleNew.SnNum++;
                    if (num > 1)
                    {
                        minSerial = serial;
                        maxSerial = serial;
                        minSerial = minSerial.Replace("[SN5]", serialRuleNew.SnNum.ToString("00000"));
                        serialRuleNew.SnNum = serialRuleNew.SnNum + num - 1;
                        maxSerial = maxSerial.Replace("[SN5]", serialRuleNew.SnNum.ToString("00000"));
                        serial = minSerial + "~" + maxSerial;
                    }
                    else
                    {
                        serial = serial.Replace("[SN5]", serialRuleNew.SnNum.ToString("00000"));
                    }
                }
                if (strRule.Contains("[SN6]"))
                {
                    serialRuleNew.SnNum++;
                    if (num > 1)
                    {
                        minSerial = serial;
                        maxSerial = serial;
                        minSerial = minSerial.Replace("[SN6]", serialRuleNew.SnNum.ToString("000000"));
                        serialRuleNew.SnNum = serialRuleNew.SnNum + num - 1;
                        maxSerial = maxSerial.Replace("[SN6]", serialRuleNew.SnNum.ToString("000000"));
                        serial = minSerial + "~" + maxSerial;
                    }
                    else
                    {
                        serial = serial.Replace("[SN6]", serialRuleNew.SnNum.ToString("000000"));
                    }
                }

                if (string.IsNullOrWhiteSpace(serial))
                {
                    result.Success = false;
                    result.Msg = "該筆料號設定出貨序號規則有錯誤,請在確認!";
                    return result;
                }
            }
            _context.Entry(serialRuleNew).State = EntityState.Modified;
            try
            {
                await _context.SaveChangesAsync();
                result.Success = true;
                result.Msg = serial;

            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.InnerException.Message;
            }
            return result;


        }


        /// <summary>
        /// 取得出貨序號(多個)
        /// </summary>
        /// <param name="itemNo">料號</param>
        /// <param name="lotNo">生產批 或 生產廠別(當批號為空白時,傳入廠別後2碼)</param>
        /// <param name="num">生產數量</param>
        /// <param name="wipShcDate">工單預計開工日</param>
        /// <returns></returns>
        [HttpGet("ByQurey/{itemNo}/{lotNo}/{num}/{wipShcDate}")]
        public async Task<ResultModel<string>> GetSerialRuleByQurey(string itemNo, string lotNo, int num, DateTime wipShcDate)
        {
            /* 非標準品的取號規則(不同ITEM 相同規則時)
             1、使用item_no 找到規則
             2、使用規則+Y+M+W+Lot 找Detail 相同之所有資料,取之中之SN_Num的最大值
             3、以最大值 +1 去產生取號工單的區間值
             4、更新Detail 相同規則+Y+M+W+Lot的所有資料最大值 
             
             */



            IQueryable<SerialRule> q = _context.SerialRules;
            IQueryable<SerialRuleDetail> q_Detail = _context.SerialRuleDetails;

            ResultModel<string> result = new ResultModel<string>();
            var serialRule = await q.Where(p => p.ItemNo == itemNo).FirstOrDefaultAsync();
           // var serialRuleNew = serialRule;
            var strRule = "";
            var serial = "";
            var minSerial = "";
            var maxSerial = "";
            #region  1.判斷OTHER + 廠別的序號規則

            if (num <= 0)
            {
                result.Success = false;
                result.Msg = "請輸入出貨數量!!";
                return result;
            }
            if (serialRule == null || itemNo.ToUpper() == "OTHER")
            {
                itemNo = "OTHER";
                if (lotNo.Length != 2)
                {
                    result.Success = false;
                    result.Msg = "前置碼長度為2";
                    //result.Msg = "無料號對應出貨序號規則";
                    return result;
                }
                else
                {
                    //若為OTHER 且查無廠別,則自動新增
                    itemNo = itemNo + "-" + lotNo;
                    serialRule = await q.Where(p => p.ItemNo == itemNo).FirstOrDefaultAsync();
                    if (serialRule == null)
                    {
                        var serialRule_Sample = await q.Where(p => p.ItemNo == "OTHER").FirstOrDefaultAsync();
                        SerialRule serialRule_OTHER = new SerialRule
                        {

                            ItemNo = itemNo,
                            // CreateDate = System.DateTime.Now,
                            CreateUserID = 0,
                            // UpdateDate = System.DateTime.Now,
                            UpdateUserID = 0,
                            Rule = serialRule_Sample.Rule,
                            YNum = serialRule_Sample.YNum,
                            YLen = serialRule_Sample.YLen,
                            MNum = serialRule_Sample.MNum,
                            MLen = serialRule_Sample.MNum,
                            WNum = serialRule_Sample.WNum,
                            WLen = serialRule_Sample.WLen,
                            LotNum = serialRule_Sample.LotNum,
                            LotLen = serialRule_Sample.LotLen,
                            SnNum = 0,
                            SnLen = serialRule_Sample.SnLen
                        };


                        await PostSerialRule(serialRule_OTHER);

                        q = _context.SerialRules;
                        serialRule = await q.Where(p => p.ItemNo == itemNo).FirstOrDefaultAsync();
                    }

                }
            }
            else
            {

                if (serialRule.LotLen != 0)
                {
                    if (lotNo == null)
                    {
                        result.Success = false;
                        result.Msg = "所輸入LOT字數與規則不符合";
                        return result;
                    }
                    if (serialRule.LotLen != lotNo.Length)
                    {
                        result.Success = false;
                        result.Msg = "所輸入LOT字數與規則不符合";
                        return result;
                    }
                  
                    if (!int.TryParse(lotNo, out int n))
                    {
                        result.Success = false;
                        result.Msg = "所輸入LOT需為數字";
                        return result;
                    }
                                 
                }

            }
            
            #endregion

            #region 2.針對各年月周判斷新增Detail表
            serialRule = await q.Where(p => p.ItemNo == itemNo).FirstOrDefaultAsync();
            strRule = serialRule.Rule.ToUpper();

            SerialRuleDetail serialRuleDetail_NEW = new SerialRuleDetail
            {
                ItemNo = itemNo,
                Rule = serialRule.Rule
            };

            if (strRule.Contains("[YYYY]")) //年份
            {
                serialRuleDetail_NEW.YNum = wipShcDate.Year;
                serialRuleDetail_NEW.SnNum = 0;
            }
            if (strRule.Contains("[YY]"))//年份後兩碼
            {
                serialRuleDetail_NEW.YNum = int.Parse(wipShcDate.ToString("yy"));
                serialRuleDetail_NEW.SnNum = 0;
              
            }
            if (strRule.Contains("[MM]"))//月份
            {
                serialRuleDetail_NEW.MNum = wipShcDate.Month;
                serialRuleDetail_NEW.SnNum = 0;

            }
            if (strRule.Contains("[WW]"))
            {
                //當年第一天為第1周,且每周的開始為星期一
                System.Globalization.GregorianCalendar gc = new System.Globalization.GregorianCalendar();
                int week = gc.GetWeekOfYear(wipShcDate, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Monday);
                serialRuleDetail_NEW.WNum = week;

            }

            if (strRule.Contains("[LOT3]") || strRule.Contains("[LOT4]"))
            {
                serialRuleDetail_NEW.LotNum = int.Parse(lotNo);
            }

            var q_detail_tmp = q_Detail.Where(w => w.ItemNo == itemNo && w.YNum == serialRuleDetail_NEW.YNum && w.MNum == serialRuleDetail_NEW.MNum && w.WNum == serialRuleDetail_NEW.WNum && w.LotNum == serialRuleDetail_NEW.LotNum).ToList();
            if (q_detail_tmp.Count == 0)
            {
                SerialRuleDetailsController serialRuleDetailsController = new SerialRuleDetailsController(_context);
                await serialRuleDetailsController.PostSerialRuleDetail(serialRuleDetail_NEW);
               
            }
            q_Detail = _context.SerialRuleDetails;
            var SerialRuleDetail =  q_Detail.Where(w => w.ItemNo == itemNo && w.YNum == serialRuleDetail_NEW.YNum && w.MNum == serialRuleDetail_NEW.MNum && w.WNum == serialRuleDetail_NEW.WNum && w.LotNum == serialRuleDetail_NEW.LotNum).FirstOrDefault();
          
            SerialRuleDetail.UpdateDate = System.DateTime.Now;


            var SerialRuleDetail_All = q_Detail.Where(w => w.Rule == serialRuleDetail_NEW.Rule && w.YNum == serialRuleDetail_NEW.YNum && w.MNum == serialRuleDetail_NEW.MNum && w.WNum == serialRuleDetail_NEW.WNum && w.LotNum == serialRuleDetail_NEW.LotNum);

            if (! itemNo.StartsWith("OTHER"))
            {
                //抓取所有相同參數的值
                int Max_SnNum = SerialRuleDetail_All.Max(s => s.SnNum); //抓取相同參數的SN_Num 最大數值取值,避免有不一致一情況
                SerialRuleDetail.SnNum = Max_SnNum;
            }

            #endregion


            #region 3.產生序號
            strRule = serialRule.Rule.ToUpper();
            serial = serialRule.Rule;

            if (itemNo.StartsWith("OTHER"))
            {

                if (strRule.Contains("[SS]"))
                {
                    serial = serial.Replace("[SS]", lotNo);
                }
                if (strRule.Contains("[WW]"))
                {
                    //  serial = serial.Replace("[WW]", SerialRuleDetail.WNum.ToString().Length == 1 ? SerialRuleDetail.WNum.ToString().PadLeft(2, '0') : SerialRuleDetail.WNum.ToString());
                    serial = serial.Replace("[WW]", SerialRuleDetail.WNum.ToString("00"));
                }
                if (strRule.Contains("[YY]"))//年份後兩碼
                {
                    var strYY = SerialRuleDetail.YNum.ToString();
                    strYY = strYY.Replace("0", "Z");
                    strYY = strYY.Replace("1", "A");
                    strYY = strYY.Replace("2", "B");
                    strYY = strYY.Replace("3", "C");
                    strYY = strYY.Replace("4", "D");
                    strYY = strYY.Replace("5", "E");
                    strYY = strYY.Replace("6", "F");
                    strYY = strYY.Replace("7", "G");
                    strYY = strYY.Replace("8", "H");
                    strYY = strYY.Replace("9", "J");
                    serial = serial.Replace("[YY]", strYY);
                }
                if (strRule.Contains("[SN5]"))
                {
                   
                    SerialRuleDetail.SnNum++;
                    if (num > 1)
                    {
                        minSerial = serial;
                        maxSerial = serial;
                        minSerial = minSerial.Replace("[SN5]", SerialRuleDetail.SnNum.ToString("00000"));
                        SerialRuleDetail.SnNum = SerialRuleDetail.SnNum + num - 1;
                        maxSerial = maxSerial.Replace("[SN5]", SerialRuleDetail.SnNum.ToString("00000"));
                        serial = minSerial + "~" + maxSerial;
                    }
                    else
                    {
                        serial = serial.Replace("[SN5]", SerialRuleDetail.SnNum.ToString("00000"));
                    }
                }

            }
            else
            {
               
                if (strRule.Contains("[YYYY]")) //年份
                {
                    serial = serial.Replace("[YYYY]", SerialRuleDetail.YNum.ToString("0000"));
                }
                if (strRule.Contains("[YY]"))//年份後兩碼
                {
                    serial = serial.Replace("[YY]", SerialRuleDetail.YNum.ToString("00"));
                }
                if (strRule.Contains("[MM]"))//月份
                {
                    serial = serial.Replace("[MM]", SerialRuleDetail.MNum.ToString("00"));

                }
                if (strRule.Contains("[WW]"))
                {
                    //  serial = serial.Replace("[WW]", SerialRuleDetail.WNum.ToString().Length == 1 ? SerialRuleDetail.WNum.ToString().PadLeft(2, '0') : SerialRuleDetail.WNum.ToString());
                    serial = serial.Replace("[WW]", SerialRuleDetail.WNum.ToString("00"));
                }
                if (strRule.Contains("[LOT3]"))
                {
                     serial = serial.Replace("[LOT3]", lotNo);

                }
                if (strRule.Contains("[LOT4]"))
                {
                      serial = serial.Replace("[LOT4]", lotNo);
                }
                if (strRule.Contains("[SN3]"))
                {
                    SerialRuleDetail.SnNum++;
                    if (num > 1)
                    {
                        minSerial = serial;
                        maxSerial = serial;
                        minSerial = minSerial.Replace("[SN3]", SerialRuleDetail.SnNum.ToString("000"));
                        SerialRuleDetail.SnNum = SerialRuleDetail.SnNum + num - 1;
                        maxSerial = maxSerial.Replace("[SN3]", SerialRuleDetail.SnNum.ToString("000"));
                        serial = minSerial + "~" + maxSerial;
                    }
                    else
                    {
                        serial = serial.Replace("[SN3]", SerialRuleDetail.SnNum.ToString("000"));
                    }
                }
                if (strRule.Contains("[SN4]"))
                {
                    SerialRuleDetail.SnNum++;
                    if (num > 1)
                    {
                        minSerial = serial;
                        maxSerial = serial;
                        minSerial = minSerial.Replace("[SN4]", SerialRuleDetail.SnNum.ToString("0000"));
                        SerialRuleDetail.SnNum = SerialRuleDetail.SnNum + num - 1;
                        maxSerial = maxSerial.Replace("[SN4]", SerialRuleDetail.SnNum.ToString("0000"));
                        serial = minSerial + "~" + maxSerial;
                    }
                    else
                    {
                        serial = serial.Replace("[SN4]", SerialRuleDetail.SnNum.ToString("0000"));
                    }
                }
                if (strRule.Contains("[SN5]"))
                {
                    SerialRuleDetail.SnNum++;
                    if (num > 1)
                    {
                        minSerial = serial;
                        maxSerial = serial;
                        minSerial = minSerial.Replace("[SN5]", SerialRuleDetail.SnNum.ToString("00000"));
                        SerialRuleDetail.SnNum = SerialRuleDetail.SnNum + num - 1;
                        maxSerial = maxSerial.Replace("[SN5]", SerialRuleDetail.SnNum.ToString("00000"));
                        serial = minSerial + "~" + maxSerial;
                    }
                    else
                    {
                        serial = serial.Replace("[SN5]", SerialRuleDetail.SnNum.ToString("00000"));
                    }
                }
                if (strRule.Contains("[SN6]"))
                {
                    SerialRuleDetail.SnNum++;
                    if (num > 1)
                    {
                        minSerial = serial;
                        maxSerial = serial;
                        minSerial = minSerial.Replace("[SN6]", SerialRuleDetail.SnNum.ToString("000000"));
                        SerialRuleDetail.SnNum = SerialRuleDetail.SnNum + num - 1;
                        maxSerial = maxSerial.Replace("[SN6]", SerialRuleDetail.SnNum.ToString("000000"));
                        serial = minSerial + "~" + maxSerial;
                    }
                    else
                    {
                        serial = serial.Replace("[SN6]", SerialRuleDetail.SnNum.ToString("000000"));
                    }
                }

                if (string.IsNullOrWhiteSpace(serial))
                {
                    result.Success = false;
                    result.Msg = "該筆料號設定出貨序號規則有錯誤,請在確認!";
                    return result;
                }
            }


            #endregion

            #region  修改serial_rule_detail 的記錄

            if (itemNo.StartsWith("OTHER"))
            {
                _context.Entry(SerialRuleDetail).State = EntityState.Modified;
            }
            else
            {
                #region 同步更改其他相同Rule、YY、MM、WW、Lot 的最大值流水號SN_Num (不同item會有相同rule,且流水號為累加)
                foreach (var item in SerialRuleDetail_All)
                {
                    item.SnNum = SerialRuleDetail.SnNum;
                    item.UpdateDate = SerialRuleDetail.UpdateDate;
                    _context.Entry(item).State = EntityState.Modified;
                }
            }

            #endregion
            #endregion


            //修改Serial_Rule_Detail

            try
            {
                await _context.SaveChangesAsync();
                result.Success = true;
                result.Msg = serial;

            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.InnerException.Message;
            }
            return result;


        }


        /// <summary>
        /// 取得樣本序號(單個)
        /// </summary>
        /// <param name="itemNo">料號</param>
        /// <returns></returns>
        [HttpGet("Sample/{itemNo}")]
        public async Task<ResultModel<string>> GetSampleSerialRule(string itemNo)
        {
            IQueryable<SerialRule> q = _context.SerialRules;
            ResultModel<string> result = new ResultModel<string>();
            if (string.IsNullOrWhiteSpace(itemNo))
            {
                itemNo = "Sample";
                itemNo = itemNo.ToUpper();

            }
            var serialRule = await q.Where(p => p.ItemNo == itemNo).FirstOrDefaultAsync();
            var serialRuleNew = serialRule;
            if (serialRule == null)
            {
                result.Success = false;
                result.Msg = "無料號對應出貨序號規則";
                return result;
            }
            var strRule = serialRule.Rule.ToUpper();
            var serial = serialRule.Rule;
            if (strRule.Contains("[WW]"))
            {
                System.Globalization.GregorianCalendar gc = new System.Globalization.GregorianCalendar();
                DateTime datetime = DateTime.Now;
                int week = gc.GetWeekOfYear(datetime, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
                serial = serial.Replace("[WW]", week.ToString().Length == 1 ? week.ToString().PadLeft(2, '0') : week.ToString());

                if (serialRule.WNum != week)
                {
                    serialRuleNew.WNum = week;
                    if (serialRule.SnNum > 0)
                        serialRuleNew.SnNum = 0;
                }
            }
            if (strRule.Contains("[YY]"))//年份後兩碼
            {
                var strYY = System.DateTime.Now.ToString("yy");
                if (serialRule.YNum.ToString() != System.DateTime.Now.ToString("yy"))
                {
                    serialRuleNew.YNum = int.Parse(System.DateTime.Now.ToString("yy"));
                    if (serialRule.SnNum > 0)
                        serialRuleNew.SnNum = 0;
                }
                strYY = strYY.Replace("0", "Z");
                strYY = strYY.Replace("1", "A");
                strYY = strYY.Replace("2", "B");
                strYY = strYY.Replace("3", "C");
                strYY = strYY.Replace("4", "D");
                strYY = strYY.Replace("5", "E");
                strYY = strYY.Replace("6", "F");
                strYY = strYY.Replace("7", "G");
                strYY = strYY.Replace("8", "H");
                strYY = strYY.Replace("9", "J");

                serial = serial.Replace("[YY]", strYY);
            }
            if (strRule.Contains("[SN5]"))
            {
                serialRuleNew.SnNum++;
                serial = serial.Replace("[SN5]", serialRuleNew.SnNum.ToString("00000"));
            }

            _context.Entry(serialRuleNew).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
                result.Success = true;
                result.Msg = serial;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.InnerException.Message;
            }
            return result;


        }

        /// <summary>
        /// 取得樣本序號(多個)
        /// </summary>
        /// <param name="num">數量</param>
        /// <returns></returns>
        [HttpGet("Sample/num/{num}")]
        public async Task<ResultModel<string>> GetSampleSerialRules(int num)
        {
            IQueryable<SerialRule> q = _context.SerialRules;
            ResultModel<string> result = new ResultModel<string>();

            var itemNo = "Sample";
            itemNo = itemNo.ToUpper();

            var serialRule = await q.Where(p => p.ItemNo == itemNo).FirstOrDefaultAsync();
            var serialRuleNew = serialRule;

            var strRule = serialRule.Rule.ToUpper();
            var serial = serialRule.Rule;
            var maxSerial = "";
            var minSerial = "";

            if (strRule.Contains("[WW]"))
            {
                System.Globalization.GregorianCalendar gc = new System.Globalization.GregorianCalendar();
                DateTime datetime = DateTime.Now;
                int week = gc.GetWeekOfYear(datetime, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
                serial = serial.Replace("[WW]", week.ToString().Length == 1 ? week.ToString().PadLeft(2, '0') : week.ToString());

                if (serialRule.WNum != week)
                {
                    serialRuleNew.WNum = week;
                    if (serialRule.SnNum > 0)
                        serialRuleNew.SnNum = 0;
                }
            }
            if (strRule.Contains("[YY]"))//年份後兩碼
            {
                var strYY = System.DateTime.Now.ToString("yy");
                if (serialRule.YNum.ToString() != System.DateTime.Now.ToString("yy"))
                {
                    serialRuleNew.YNum = int.Parse(System.DateTime.Now.ToString("yy"));
                    if (serialRule.SnNum > 0)
                        serialRuleNew.SnNum = 0;
                }
                strYY = strYY.Replace("0", "Z");
                strYY = strYY.Replace("1", "A");
                strYY = strYY.Replace("2", "B");
                strYY = strYY.Replace("3", "C");
                strYY = strYY.Replace("4", "D");
                strYY = strYY.Replace("5", "E");
                strYY = strYY.Replace("6", "F");
                strYY = strYY.Replace("7", "G");
                strYY = strYY.Replace("8", "H");
                strYY = strYY.Replace("9", "J");

                serial = serial.Replace("[YY]", strYY);
            }
            if (strRule.Contains("[SN5]"))
            {
                serialRuleNew.SnNum++;
                maxSerial = serial;
                minSerial = serial.Replace("[SN5]", serialRuleNew.SnNum.ToString("00000"));
                serialRuleNew.SnNum = serialRuleNew.SnNum + num - 1;
                maxSerial = serial.Replace("[SN5]", serialRuleNew.SnNum.ToString("00000"));
                serial = minSerial + "-" + maxSerial;
            }

            _context.Entry(serialRuleNew).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
                result.Success = true;
                result.Msg = serial;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.InnerException.Message;
            }
            return result;


        }


        /// <summary>
        /// 取得樣本序號,寫入Serial_Rule_Detail(多個)
        /// </summary>
        /// <param name="num">數量</param>
        /// <returns></returns>
        [HttpGet("Sample/num_new/{num}")]
        public async Task<ResultModel<string>> GetSampleSerialRulesNEW(int num)
        {
            IQueryable<SerialRule> q = _context.SerialRules;
            IQueryable<SerialRuleDetail> q_Detail = _context.SerialRuleDetails;
            ResultModel<string> result = new ResultModel<string>();

            var itemNo = "Sample";
            itemNo = itemNo.ToUpper();

            var serialRule = await q.Where(p => p.ItemNo == itemNo).FirstOrDefaultAsync();
         

            SerialRuleDetail serialRuleDetail_NEW = new SerialRuleDetail
            {
                ItemNo = itemNo,
                Rule = serialRule.Rule
            };

            var strRule = serialRule.Rule.ToUpper();
            var serial = serialRule.Rule;
            var maxSerial = "";
            var minSerial = "";

            if (strRule.Contains("[WW]"))
            {
                System.Globalization.GregorianCalendar gc = new System.Globalization.GregorianCalendar();
                DateTime datetime = System.DateTime.Now;
                int week = gc.GetWeekOfYear(datetime, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Monday);
                serial = serial.Replace("[WW]", week.ToString().Length == 1 ? week.ToString().PadLeft(2, '0') : week.ToString());


                serialRuleDetail_NEW.WNum = week;
                   
                
            }
            if (strRule.Contains("[YY]"))//年份後兩碼
            {
                var strYY = System.DateTime.Now.ToString("yy");
                
                    serialRuleDetail_NEW.YNum = int.Parse(System.DateTime.Now.ToString("yy"));
           
                
                strYY = strYY.Replace("0", "Z");
                strYY = strYY.Replace("1", "A");
                strYY = strYY.Replace("2", "B");
                strYY = strYY.Replace("3", "C");
                strYY = strYY.Replace("4", "D");
                strYY = strYY.Replace("5", "E");
                strYY = strYY.Replace("6", "F");
                strYY = strYY.Replace("7", "G");
                strYY = strYY.Replace("8", "H");
                strYY = strYY.Replace("9", "J");

                serial = serial.Replace("[YY]", strYY);
            }


            var q_detail_tmp = q_Detail.Where(w => w.ItemNo == itemNo && w.YNum == serialRuleDetail_NEW.YNum && w.MNum == serialRuleDetail_NEW.MNum && w.WNum == serialRuleDetail_NEW.WNum && w.LotNum == serialRuleDetail_NEW.LotNum).ToList();
            if (q_detail_tmp.Count == 0)
            {
                SerialRuleDetailsController serialRuleDetailsController = new SerialRuleDetailsController(_context);
                await serialRuleDetailsController.PostSerialRuleDetail(serialRuleDetail_NEW);

            }
            q_Detail = _context.SerialRuleDetails;
            var SerialRuleDetail = await q_Detail.Where(w => w.ItemNo == itemNo && w.YNum == serialRuleDetail_NEW.YNum && w.MNum == serialRuleDetail_NEW.MNum && w.WNum == serialRuleDetail_NEW.WNum && w.LotNum == serialRuleDetail_NEW.LotNum).FirstOrDefaultAsync();
            SerialRuleDetail.UpdateDate = System.DateTime.Now;



            if (strRule.Contains("[SN5]"))
            {
                SerialRuleDetail.SnNum++;
                maxSerial = serial;
                minSerial = serial.Replace("[SN5]", SerialRuleDetail.SnNum.ToString("00000"));
                SerialRuleDetail.SnNum = SerialRuleDetail.SnNum + num - 1;
                maxSerial = serial.Replace("[SN5]", SerialRuleDetail.SnNum.ToString("00000"));
                serial = minSerial + "-" + maxSerial;
            }


            _context.Entry(SerialRuleDetail).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
                result.Success = true;
                result.Msg = serial;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.InnerException.Message;
            }
            return result;


        }


        /// <summary>
        /// 新增料號基本資料檔
        /// </summary>
        /// <param name="SerialRule"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResultModel<SerialRule>> PostSerialRule([FromBody] SerialRule SerialRule)
        {
            ResultModel<SerialRule> result = new ResultModel<SerialRule>();
            Helper helper = new Helper(_context);
            SerialRule.SerialRuleID = helper.GetIDKey("SERIALRULE_ID").Result;
            _context.SerialRules.Add(SerialRule);
            try
            {
                await _context.SaveChangesAsync();
                result.Success = true;
                result.Msg = "OK";
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.InnerException.Message;
            }
            return result;
        }


        /// <summary>
        /// 修改料號基本資料檔
        /// </summary>
        /// <returns></returns>
        [HttpPut("{id}")]
        public async Task<ResultModel<SerialRule>> PutSerialRule(int id, [FromBody] SerialRule SerialRule)
        {
            ResultModel<SerialRule> result = new ResultModel<SerialRule>();
            //_context.Attach(SerialRule);
            // 指定更新某個欄位
            //_context.Entry(SerialRule).Property(p => p.SerialRuleID).IsModified = true;
            _context.Entry(SerialRule).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
                result.Success = true;
                result.Msg = "OK";
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.InnerException.Message;
            }
            return result;
        }


        /// <summary>
        /// 删除料號基本資料檔
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete("{id}")]
        public async Task<ResultModel<SerialRule>> DeleteSerialRule(int id)
        {
            ResultModel<SerialRule> result = new ResultModel<SerialRule>();
            var serialRule = await _context.SerialRules.FindAsync(id);
            if (serialRule == null)
            {
                result.Success = false;
                result.Msg = "出貨序號編碼編號錯誤";
                return result;
            }

            _context.SerialRules.Remove(serialRule);

            try
            {
                await _context.SaveChangesAsync();
                result.Success = true;
                result.Msg = "OK";
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.InnerException.Message;
            }

            return result;
        }

        
    }
}