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.WebApi.DTO.AMES;
using AMESCoreStudio.CommonTools.Result;
using System.Data.Common;
using System.Data;
using System.Dynamic;
using Microsoft.Extensions.Configuration;
using Dapper;
using AMESCoreStudio.WebApi.Extensions;

namespace AMESCoreStudio.WebApi.Controllers.AMES
{
    /// <summary>
    /// 
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class WipInfosController : Controller
    {
        private readonly AMESContext _context;
        private readonly IConfiguration _config;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        public WipInfosController(AMESContext context)
        {
            _config = new ConfigurationBuilder().SetBasePath(Environment.CurrentDirectory).AddJsonFile("appsettings.json").Build();
            _context = context;
        }

        /// <summary>
        /// 查詢工單資料Info
        /// </summary>
        /// <returns></returns>
        // GET: api/SystemInfoes
        [HttpGet]
        public async Task<ActionResult<IEnumerable<WipInfo>>> GetWipInfo()
        {
            IQueryable<WipInfo> q = _context.WipInfos;

            q = q.OrderBy(p => p.WipNO);

            //q = q.OrderByDescending(p => p.SystemID);

            var WipInfo = await q.ToListAsync();

            //return await _context.SystemInfoes.ToListAsync();

            return WipInfo;
        }

        /// <summary>
        /// 查詢工單資料QRS008
        /// </summary>
        /// <param name="unitNo"></param>
        /// <param name="lineId"></param>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<dynamic>> GetWipInfo4QRS008(string unitNo, string lineId)
        {
            ResultModel<dynamic> result = new ResultModel<dynamic>();
            var q = from q1 in _context.WipInfos
                    join q2 in _context.WipAtts on q1.WipNO equals q2.WipNO
                    join q3 in _context.LineInfoes on q1.WipID equals q3.WipNo
                    join q4 in _context.FactoryUnits on q1.UnitNO equals q4.UnitNo
                    select new
                    {
                        q1.WipID,
                        q1.WipNO,
                        q1.PlanQTY,
                        q1.CompleteQTY,
                        q1.UnitNO,
                        q1.LineID,
                        q1.FlowRuleID,
                        q1.StatusNO,
                        q1.CreateDate,
                        q2.ItemNO,
                        q3.LineDesc,
                        q4.UnitName,
                        q1.WerksNO
                    };

            q = q.Where(w => w.StatusNO == "A");
            if (unitNo != null)
            {
                q = q.Where(w => w.UnitNO.Equals(unitNo));
            }

            if (lineId != null && lineId != "0")
            {
                q = q.Where(w => w.LineID.Equals(int.Parse(lineId)));
            }

            //紀錄筆數
            result.DataTotal = q.Count();

            result.Data = await q.ToListAsync();

            if (result == null)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }

        /// <summary>
        /// 查詢工單資料QRS009
        /// </summary>
        /// <param name="unitNo"></param>
        /// <param name="factoryNo"></param>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<dynamic>> GetWipInfo4QRS009(string unitNo, string factoryNo)
        {
            ResultModel<dynamic> result = new ResultModel<dynamic>();
            var q = from q1 in _context.WipInfos
                    join q2 in _context.WipAtts on q1.WipNO equals q2.WipNO
                    join q3 in _context.LineInfoes on q1.WipID equals q3.WipNo
                    join q4 in _context.FactoryUnits on q1.UnitNO equals q4.UnitNo
                    select new
                    {
                        q1.WipID,
                        q1.WipNO,
                        q1.PlanQTY,
                        q1.CompleteQTY,
                        q1.UnitNO,
                        q1.LineID,
                        q1.FlowRuleID,
                        q1.StatusNO,
                        q1.CreateDate,
                        q2.ItemNO,
                        q3.LineDesc,
                        q4.UnitName,
                        q1.WerksNO
                    };

            q = q.Where(w => w.StatusNO == "A");
            if (unitNo != null)
            {
                q = q.Where(w => w.UnitNO.Equals(unitNo));
            }
            if (factoryNo != null)
            {
                q = q.Where(w => w.WerksNO.Equals(factoryNo));
            }

            //紀錄筆數
            result.DataTotal = q.Count();

            result.Data = await q.ToListAsync();

            if (result == null)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }

        /// <summary>
        /// 查詢工單資料PDS003
        /// </summary>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<dynamic>> GetWipInfo4PDS003(string wipNO)
        {
            ResultModel<dynamic> result = new ResultModel<dynamic>();
            var q = from q1 in _context.WipInfos
                    join q2 in _context.WipAtts on q1.WipNO equals q2.WipNO into wip_att
                    from x in wip_att.DefaultIfEmpty()
                    join q3 in _context.LineInfoes on q1.LineID equals q3.LineID
                    join q4 in _context.FactoryUnits on q1.UnitNO equals q4.UnitNo
                    select new
                    {
                        q1.WipID,
                        q1.WipNO,
                        q1.PlanQTY,
                        q1.CompleteQTY,
                        q1.UnitNO,
                        q1.LineID,
                        q1.FlowRuleID,
                        q1.StatusNO,
                        q1.CreateDate,
                        x.ItemNO,
                        q3.LineDesc,
                        q4.UnitName
                    };

            if (wipNO != null && wipNO != "")
            {
                q = q.Where(w => w.WipNO == wipNO);
            }

            //紀錄筆數
            result.DataTotal = q.Count();

            result.Data = await q.ToListAsync();

            if (result == null)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }

        /// <summary>
        /// 根據安勤工單查詢工單資料
        /// </summary>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<dynamic>> GetWipInfo4Avalue(string relatedWoNo)
        {
            ResultModel<dynamic> result = new ResultModel<dynamic>();
            var q = from q1 in _context.WipInfos
                    join q2 in _context.WipAtts on q1.WipNO equals q2.WipNO into wip_att
                    from x in wip_att.DefaultIfEmpty()
                    join q3 in _context.LineInfoes on q1.LineID equals q3.LineID
                    join q4 in _context.FactoryUnits on q1.UnitNO equals q4.UnitNo
                    select new
                    {
                        q1.WipID,
                        q1.WipNO,
                        q1.RelatedWONO,
                        q1.PlanQTY,
                        q1.CompleteQTY,
                        q1.UnitNO,
                        q1.LineID,
                        q1.FlowRuleID,
                        q1.StatusNO,
                        q1.CreateDate,
                        x.ItemNO,
                        x.ModelNO,
                        q3.LineDesc,
                        q4.UnitName
                    };

            if (relatedWoNo != null && relatedWoNo != "")
            {
                q = q.Where(w => w.RelatedWONO == relatedWoNo);
            }

            //紀錄筆數
            result.DataTotal = q.Count();

            result.Data = await q.ToListAsync();

            if (result == null)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }

        /// <summary>
        /// 查詢工單資料QRS011
        /// </summary>
        /// <param name="unitNo">生產製程</param>
        /// <param name="itemNO">料號</param>
        /// <param name="wipNO">工單號碼</param>
        /// <param name="startDate">開工日期起</param>
        /// <param name="endDate">開工日期訖</param>
        /// <param name="wipStatus">工單狀態:N(未完工) E(已完工)</param>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<dynamic>> GetWipInfo4QRS011(string unitNo, string itemNO, string wipNO, string startDate, string endDate, string wipStatus = "A")
        {
            ResultModel<dynamic> result = new ResultModel<dynamic>();
            var q = from q1 in _context.WipInfos
                    join q2 in _context.WipAtts on q1.WipNO equals q2.WipNO
                    join q3 in _context.LineInfoes on q1.LineID equals q3.LineID
                    join q4 in _context.FactoryUnits on q1.UnitNO equals q4.UnitNo
                    select new
                    {
                        q1.WipID,
                        q1.WipNO,
                        q1.PlanQTY,
                        q1.CompleteQTY,
                        q1.UnitNO,
                        q1.LineID,
                        q1.FlowRuleID,
                        q1.StatusNO,
                        q1.CreateDate,
                        q2.ItemNO,
                        q3.LineDesc,
                        q4.UnitName
                    };

            if (wipStatus != "*")
            {
                q = q.Where(w => w.StatusNO == wipStatus);
            }

            if (unitNo != "*")
            {
                q = q.Where(w => w.UnitNO == unitNo);
            }
            if (itemNO != null && itemNO != "")
            {
                q = q.Where(w => w.ItemNO == itemNO);
            }
            if (wipNO != null && wipNO != "")
            {
                q = q.Where(w => w.WipNO == wipNO);
            }

            if (startDate != null && endDate != null)
            {
                if (startDate != "" && endDate != "")
                {
                    q = q.Where(w => w.CreateDate >= DateTime.Parse(startDate) && w.CreateDate <= DateTime.Parse(endDate).AddDays(1));
                }
            }

            //紀錄筆數
            result.DataTotal = q.Count();

            result.Data = await q.ToListAsync();

            if (result == null)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        public static DataTable DataReaderToDataTable(DbDataReader reader)
        {
            try
            {
                DataTable dt = new DataTable();
                int fieldCount = reader.FieldCount;
                for (int fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex)
                {
                    dt.Columns.Add(reader.GetName(fieldIndex), reader.GetFieldType(fieldIndex));
                }

                dt.BeginLoadData();

                object[] rowValues = new object[fieldCount];
                while (reader.Read())
                {
                    reader.GetValues(rowValues);
                    dt.LoadDataRow(rowValues, true);
                }
                reader.Close();
                dt.EndLoadData();

                return dt;

            }
            catch (Exception ex)
            {
                throw new Exception("DataReader Convert DataTable Error!", ex);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="barcodeNo"></param>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<dynamic>> ESUNConnectTest(string barcodeNo)
        {
            ResultModel<dynamic> result = new ResultModel<dynamic>();

            result.Msg = "OK";
            result.Success = true;

            ESUNContext _esun_context = new ESUNContext();

            try
            {
                //读取MAC
                DbConnection esun_conn = _esun_context.Database.GetDbConnection();
                if (esun_conn.State != System.Data.ConnectionState.Open)
                {
                    await esun_conn.OpenAsync();
                }

                /*
                string mac_sql = string.Format(@"select distinct a.工單編號 as mo_id,e.客戶工單編號 as customer_moid,a.工單序號 as product_sn,                        
                               case substring(f.avalue_kp_typeid, 1, 3) when 'MAC' then isnull(z.item_prefix,'')+b.SUB_ITEM_SN else b.SUB_ITEM_SN end as part_barcode,
                               f.avalue_kp_typeid as class,c.material_id,d.r_stn as routeid,'' as workerid,rtrim(g.sn_date) + ' ' + rtrim(g.sn_time) as create_date
                          from or_sn_story a
                        left join sub_item_db b on a.工單編號 = b.or_sn and a.工單序號 = b.or_sal
                        left join jh_sub_item c on a.工單編號 = c.mo_id and b.class = c.part_typeid
                        left join jh_sub_item_prefix z on c.mo_id = z.mo_id
                        left join or_sub_db d on a.工單編號 = d.or_sn and b.class = d.class
                             join or_list e on a.工單編號 = e.工單編號 and e.[客戶] = 'EV'
                        left join jh_sub_item_mapping f on b.class = f.eversun_kp_typeid
                             join jh_sn_list g on a.工單序號 = g.sn
                         where g.sn_result = 'OK'
       AND a.工單序號 = '{0}'
       AND c.material_id LIKE 'MAC%'", barcodeNo);
                */

                string mac_sql = string.Format(@"SELECT B.[ProductSN], B.[PartBarcode], B.[MFID], B.[MOID], B.[PartTypeID], B.[MaterialID], B.[IsActive]
FROM [SFIS].[dbo].[ZPDKeyPart]  B WHERE B.[IsActive] = 1  AND B.[ProductSN] = (SELECT A.[PartBarcode]  FROM [SFIS].[dbo].[ZPDKeyPart] A WHERE A.[IsActive] = 1 AND A.[PartTypeID] = 'MAC'  AND A.[PartBarcode] = '{0}')", barcodeNo);

                try
                {
                    using (var esun_cmd = esun_conn.CreateCommand())
                    {
                        esun_cmd.CommandText = mac_sql;

                        using (var esun_reader = await esun_cmd.ExecuteReaderAsync())
                        {
                            if (esun_reader.HasRows)
                            {
                                List<dynamic> esun_list = new List<dynamic>();
                                DataTable esun_table = new DataTable();

                                esun_table = DataReaderToDataTable(esun_reader);

                                if (esun_table.Rows.Count > 0)
                                {
                                    string mac_list = "";
                                    for (int k = 0; k < esun_table.Rows.Count; k++)
                                    {
                                        mac_list = mac_list + esun_table.Rows[k]["part_barcode"].ToString().Trim() + ",";
                                    }

                                    if (mac_list != "")
                                    {
                                        string mac = mac_list.Substring(0, mac_list.Length - 1);
                                        result.Msg = "OK:" + mac;
                                        result.Success = true;
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception e2)
                {
                    result.Msg = "NG:" + e2.Message;
                    result.Success = false;
                }
            }
            catch (Exception e1)
            {
                result.Msg = "NG:" + e1.Message;
                result.Success = false;

            }

            return result;
        }

        /// <summary>
        /// 查詢工單KeyParts資料QRS013
        /// </summary>
        /// <param name="wipNO"></param>
        /// <param name="factoryNo"></param>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<dynamic>> GetWipInfo4QRS013(string wipNO, string factoryNo, int page, int limit)
        {
            ResultModel<dynamic> result = new ResultModel<dynamic>();
            Helper helper = new Helper(_context);

            DbConnection conn = _context.Database.GetDbConnection();
            if (conn.State != ConnectionState.Open)
            {
                await conn.OpenAsync();
            }

            string kp_sql = "select kp_no, count(kp_seq) as kp_qty  from jhames.wip_kp where wip_no = '" + wipNO + "' group by kp_no";

            DataTable dtKp = new DataTable();

            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = kp_sql;

                using (var reader = await cmd.ExecuteReaderAsync())
                {
                    if (reader.HasRows)
                    {
                        dtKp = DataReaderToDataTable(reader);
                    }
                }
            }

            string sql = @" select c.wip_no as WipNo,b.barcode_no as BarcodeNo,b.extra_barcode_no as ExtraBarcodeNo,d.model_no as ModelNO,d.item_no as ItemNO";
            sql = sql + " from jhames.barcode_info b,jhames.wip_info c,jhames.wip_att d";
            sql = sql + " where b.wip_id = c.wip_id and c.wip_no = d.wip_no";
            sql = sql + " and c.wip_no = '" + wipNO + "'";

            using (var barcode_cmd = conn.CreateCommand())
            {
                barcode_cmd.CommandText = sql;

                using (var barcode_reader = await barcode_cmd.ExecuteReaderAsync())
                {
                    if (barcode_reader.HasRows)
                    {
                        List<dynamic> list = new List<dynamic>();
                        DataTable dtBarcode = new DataTable();

                        dtBarcode = DataReaderToDataTable(barcode_reader);

                        if (dtKp.Rows.Count > 0)
                        {
                            for (int i = 0; i < dtKp.Rows.Count; i++)
                            {
                                int kp_qty = int.Parse(dtKp.Rows[i]["KP_QTY"].ToString());
                                string kp_no = dtKp.Rows[i]["KP_NO"].ToString();
                                if (kp_qty > 1)
                                {
                                    try
                                    {
                                        dtBarcode.Columns.Add("KP_" + kp_no);
                                    }
                                    catch { }

                                    for (int j = 1; j < kp_qty; j++)
                                    {
                                        try
                                        {
                                            dtBarcode.Columns.Add("KP_" + kp_no + "_" + j.ToString());
                                        }
                                        catch { }
                                    }
                                }
                                else
                                {
                                    try
                                    {
                                        dtBarcode.Columns.Add("KP_" + kp_no);
                                    }
                                    catch { }
                                }
                            }
                            dtBarcode.AcceptChanges();

                            for (int i = 0; i < dtBarcode.Rows.Count; i++)
                            {
                                string barcode_no = dtBarcode.Rows[i]["BarcodeNo"].ToString();

                                //读取组件
                                for (int j = 0; j < dtKp.Rows.Count; j++)
                                {
                                    string kp_no = dtKp.Rows[j]["KP_NO"].ToString();

                                    string barcode_item_sql = string.Format(@"select part_no from jhames.barcode_info a,jhames.barcode_item b where a.barcode_id = b.barcode_id 
and b.item_no = '{0}' and a.barcode_no = '{1}'", kp_no, barcode_no);

                                    using (var item_cmd = conn.CreateCommand())
                                    {
                                        item_cmd.CommandText = barcode_item_sql;

                                        using (var item_reader = await item_cmd.ExecuteReaderAsync())
                                        {
                                            if (item_reader.HasRows)
                                            {
                                                DataTable dtItem = new DataTable();
                                                dtItem = DataReaderToDataTable(item_reader);

                                                for (int k = 0; k < dtItem.Rows.Count; k++)
                                                {
                                                    string part_no = dtItem.Rows[k]["PART_NO"].ToString();
                                                    try
                                                    {
                                                        dtBarcode.Rows[i]["KP_" + kp_no + "_" + k.ToString()] = part_no;
                                                    }
                                                    catch
                                                    {
                                                        try
                                                        {
                                                            dtBarcode.Rows[i]["KP_" + kp_no] = part_no;
                                                        }
                                                        catch { }
                                                    }

                                                    dtBarcode.AcceptChanges();

                                                    try
                                                    {
                                                        if (kp_no.StartsWith("MB") && !kp_no.StartsWith("MB_MAC"))
                                                        {
                                                            ESUNContext _esun_context = new ESUNContext();

                                                            //读取MAC
                                                            DbConnection esun_conn = _esun_context.Database.GetDbConnection();
                                                            if (esun_conn.State != ConnectionState.Open)
                                                            {
                                                                await esun_conn.OpenAsync();
                                                            }

                                                            bool createMacCol = true;


                                                            //part_no = "91000237320038";

                                                            string mac_sql = string.Format(@"select distinct a.工單編號 as mo_id,e.客戶工單編號 as customer_moid,a.工單序號 as product_sn,                        
                               case substring(f.avalue_kp_typeid, 1, 3) when 'MAC' then isnull(z.item_prefix,'')+b.SUB_ITEM_SN else b.SUB_ITEM_SN end as part_barcode,
                               f.avalue_kp_typeid as class,c.material_id,d.r_stn as routeid,'' as workerid,rtrim(g.sn_date) + ' ' + rtrim(g.sn_time) as create_date
                          from or_sn_story a
                        left join sub_item_db b on a.工單編號 = b.or_sn and a.工單序號 = b.or_sal
                        left join jh_sub_item c on a.工單編號 = c.mo_id and b.class = c.part_typeid
                        left join jh_sub_item_prefix z on c.mo_id = z.mo_id
                        left join or_sub_db d on a.工單編號 = d.or_sn and b.class = d.class
                             join or_list e on a.工單編號 = e.工單編號 and e.[客戶] = 'EV'
                        left join jh_sub_item_mapping f on b.class = f.eversun_kp_typeid
                             join jh_sn_list g on a.工單序號 = g.sn
                         where g.sn_result = 'OK'
       AND a.工單序號 = '{0}'
       AND c.material_id LIKE 'MAC%'", part_no);

                                                            using (var esun_cmd = esun_conn.CreateCommand())
                                                            {
                                                                esun_cmd.CommandText = mac_sql;
                                                                esun_cmd.CommandTimeout = 0;

                                                                using (var esun_reader = await esun_cmd.ExecuteReaderAsync())
                                                                {
                                                                    if (esun_reader.HasRows)
                                                                    {
                                                                        List<dynamic> esun_list = new List<dynamic>();
                                                                        DataTable esun_table = new DataTable();

                                                                        esun_table = DataReaderToDataTable(esun_reader);

                                                                        if (esun_table.Rows.Count > 0)
                                                                        {
                                                                            if (createMacCol)
                                                                            {
                                                                                for (int m = 0; m < esun_table.Rows.Count; m++)
                                                                                {
                                                                                    if (dtItem.Rows.Count == 1)
                                                                                    {
                                                                                        try
                                                                                        {
                                                                                            dtBarcode.Columns.Add("KP_" + kp_no + "_MAC" + (m + 1).ToString());
                                                                                        }
                                                                                        catch { }
                                                                                    }
                                                                                    else
                                                                                    {
                                                                                        try
                                                                                        {
                                                                                            dtBarcode.Columns.Add("KP_" + kp_no + "_" + (k + 1).ToString() + "_MAC" + (m + 1).ToString());
                                                                                        }
                                                                                        catch { }
                                                                                    }
                                                                                }
                                                                                dtBarcode.AcceptChanges();
                                                                                createMacCol = false;
                                                                            }

                                                                            string mac = "";
                                                                            for (int m = 0; m < esun_table.Rows.Count; m++)
                                                                            {
                                                                                mac = esun_table.Rows[m]["part_barcode"].ToString().Trim();
                                                                                if (dtItem.Rows.Count == 1)
                                                                                {
                                                                                    dtBarcode.Rows[i]["KP_" + kp_no + "_MAC" + (m + 1).ToString()] = mac;
                                                                                }
                                                                                else
                                                                                {
                                                                                    dtBarcode.Rows[i]["KP_" + kp_no + "_" + (k + 1).ToString() + "_MAC" + (m + 1).ToString()] = mac;
                                                                                }
                                                                                dtBarcode.AcceptChanges();
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }

                                                        }
                                                    }
                                                    catch (Exception e1)
                                                    {
                                                        string err = e1.Message;
                                                    }
                                                }
                                                dtBarcode.AcceptChanges();
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        foreach (DataRow row in dtBarcode.Rows)
                        {
                            dynamic dyn = new ExpandoObject();
                            list.Add(dyn);
                            foreach (DataColumn column in dtBarcode.Columns)
                            {
                                var dic = (IDictionary<string, object>)dyn;
                                dic[column.ColumnName] = row[column];
                            }
                        }

                        result.DataTotal = list.Count();
                        result.Data = list;
                    }
                }
            }

            if (result == null)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }

        /// <summary>
        /// 查詢工單KeyParts資料QRS017
        /// </summary>
        /// <param name="wipNO"></param>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<dynamic>> GetWipInfo4QRS017(string wipNO)
        {
            ResultModel<dynamic> result = new ResultModel<dynamic>();
            Helper helper = new Helper(_context);

            DbConnection conn = _context.Database.GetDbConnection();
            if (conn.State != ConnectionState.Open)
            {
                await conn.OpenAsync();
            }

            string kp_sql = "select kp_no, count(kp_seq) as kp_qty  from jhames.wip_kp where wip_no = '" + wipNO + "' group by kp_no";

            DataTable dtKp = new DataTable();

            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = kp_sql;

                using (var reader = await cmd.ExecuteReaderAsync())
                {
                    if (reader.HasRows)
                    {
                        dtKp = DataReaderToDataTable(reader);
                    }
                }
            }

            /*
            string sql = @" select c.wip_no as WipNo,b.barcode_no as BarcodeNo,b.extra_barcode_no as ExtraBarcodeNo,b.box_no as BoxNo,d.model_no as ModelNO,d.item_no as ItemNO";
            sql = sql + " from jhames.barcode_info b,jhames.wip_info c,jhames.wip_att d";
            sql = sql + " where b.wip_id = c.wip_id and c.wip_no = d.wip_no";
            sql = sql + " and c.wip_no = '" + wipNO + "'";
            */

            string sql = @" select c.wip_no as WipNo,b.barcode_no as BarcodeNo,b.extra_barcode_no as ExtraBarcodeNo,e.station_name as StationName,b.box_no as BoxNo,d.model_no as ModelNO,d.item_no as ItemNO";
            sql = sql + " from jhames.barcode_info b,jhames.wip_barcode c,jhames.wip_att d,jhames.stations e";
            sql = sql + " where b.barcode_no between c.start_no and c.end_no and c.wip_no = d.wip_no and b.station_id = e.station_id";
            sql = sql + " and c.wip_no = '" + wipNO + "'";
            sql = sql + " order by b.barcode_no ";

            using (var barcode_cmd = conn.CreateCommand())
            {
                barcode_cmd.CommandText = sql;

                using (var barcode_reader = await barcode_cmd.ExecuteReaderAsync())
                {
                    if (barcode_reader.HasRows)
                    {
                        List<dynamic> list = new List<dynamic>();
                        DataTable dtBarcode = new DataTable();

                        dtBarcode = DataReaderToDataTable(barcode_reader);

                        if (dtKp.Rows.Count > 0)
                        {
                            for (int i = 0; i < dtKp.Rows.Count; i++)
                            {
                                int kp_qty = int.Parse(dtKp.Rows[i]["KP_QTY"].ToString());
                                string kp_no = dtKp.Rows[i]["KP_NO"].ToString();
                                if (kp_qty > 1)
                                {
                                    try
                                    {
                                        dtBarcode.Columns.Add("KP_" + kp_no);
                                    }
                                    catch { }

                                    for (int j = 1; j < kp_qty; j++)
                                    {
                                        try
                                        {
                                            dtBarcode.Columns.Add("KP_" + kp_no + "#" + j.ToString());
                                        }
                                        catch { }
                                    }
                                }
                                else
                                {
                                    try
                                    {
                                        dtBarcode.Columns.Add("KP_" + kp_no);
                                    }
                                    catch { }
                                }
                            }
                            dtBarcode.AcceptChanges();

                            for (int i = 0; i < dtBarcode.Rows.Count; i++)
                            {
                                string barcode_no = dtBarcode.Rows[i]["BarcodeNo"].ToString();

                                //读取组件
                                for (int j = 0; j < dtKp.Rows.Count; j++)
                                {
                                    string kp_no = dtKp.Rows[j]["KP_NO"].ToString();

                                    string barcode_item_sql = string.Format(@"select part_no from jhames.barcode_info a,jhames.barcode_item b where a.barcode_id = b.barcode_id 
and b.item_no = '{0}' and a.barcode_no = '{1}'", kp_no, barcode_no);

                                    using (var item_cmd = conn.CreateCommand())
                                    {
                                        item_cmd.CommandText = barcode_item_sql;

                                        using (var item_reader = await item_cmd.ExecuteReaderAsync())
                                        {
                                            if (item_reader.HasRows)
                                            {
                                                DataTable dtItem = new DataTable();
                                                dtItem = DataReaderToDataTable(item_reader);

                                                for (int k = 0; k < dtItem.Rows.Count; k++)
                                                {
                                                    string part_no = dtItem.Rows[k]["PART_NO"].ToString();
                                                    try
                                                    {
                                                        dtBarcode.Rows[i]["KP_" + kp_no + "#" + k.ToString()] = part_no;
                                                    }
                                                    catch
                                                    {
                                                        try
                                                        {
                                                            dtBarcode.Rows[i]["KP_" + kp_no] = part_no;
                                                        }
                                                        catch { }
                                                    }

                                                    dtBarcode.AcceptChanges();

                                                    try
                                                    {
                                                        if (kp_no.StartsWith("MB") && !kp_no.StartsWith("MB_MAC"))
                                                        {
                                                            /*
                                                            ESUNContext _esun_context = new ESUNContext();

                                                            //读取MAC
                                                            DbConnection esun_conn = _esun_context.Database.GetDbConnection();
                                                            if (esun_conn.State != ConnectionState.Open)
                                                            {
                                                                await esun_conn.OpenAsync();
                                                            }
                                                            */

                                                            bool createMacCol = true;

                                                            //part_no = "91000237320038";

                                                            /*
                                                            string mac_sql = string.Format(@"select distinct a.工單編號 as mo_id,e.客戶工單編號 as customer_moid,a.工單序號 as product_sn,                        
                               case substring(f.avalue_kp_typeid, 1, 3) when 'MAC' then isnull(z.item_prefix,'')+b.SUB_ITEM_SN else b.SUB_ITEM_SN end as part_barcode,
                               f.avalue_kp_typeid as class,c.material_id,d.r_stn as routeid,'' as workerid,rtrim(g.sn_date) + ' ' + rtrim(g.sn_time) as create_date
                          from or_sn_story a
                        left join sub_item_db b on a.工單編號 = b.or_sn and a.工單序號 = b.or_sal
                        left join jh_sub_item c on a.工單編號 = c.mo_id and b.class = c.part_typeid
                        left join jh_sub_item_prefix z on c.mo_id = z.mo_id
                        left join or_sub_db d on a.工單編號 = d.or_sn and b.class = d.class
                             join or_list e on a.工單編號 = e.工單編號 and e.[客戶] = 'EV'
                        left join jh_sub_item_mapping f on b.class = f.eversun_kp_typeid
                             join jh_sn_list g on a.工單序號 = g.sn
                         where g.sn_result = 'OK'
       AND a.工單序號 = '{0}'
       AND c.material_id LIKE 'MAC%'", part_no);
                                                            */

                                                            /*
                                                            string mac_sql = string.Format(@"SELECT B.[ProductSN], B.[PartBarcode], B.[MFID], B.[MOID], B.[PartTypeID], B.[MaterialID], B.[IsActive]
FROM [SFIS].[dbo].[ZPDKeyPart]  B WHERE B.[IsActive] = 1  AND B.[ProductSN] = (SELECT A.[PartBarcode]  FROM [SFIS].[dbo].[ZPDKeyPart] A WHERE A.[IsActive] = 1 AND A.[PartTypeID] = 'MAC'  AND A.[PartBarcode] = '{0}')", part_no);


                                                            using (var esun_cmd = esun_conn.CreateCommand())
                                                            {
                                                                esun_cmd.CommandText = mac_sql;
                                                                esun_cmd.CommandTimeout = 0;

                                                                using (var esun_reader = await esun_cmd.ExecuteReaderAsync())
                                                                {
                                                                    if (esun_reader.HasRows)
                                                                    {
                                                                        List<dynamic> esun_list = new List<dynamic>();
                                                                        DataTable esun_table = new DataTable();

                                                                        esun_table = DataReaderToDataTable(esun_reader);

                                                                        if (esun_table.Rows.Count > 0)
                                                                        {
                                                                            if (createMacCol)
                                                                            {
                                                                                for (int m = 0; m < esun_table.Rows.Count; m++)
                                                                                {
                                                                                    if (dtItem.Rows.Count == 1)
                                                                                    {
                                                                                        try
                                                                                        {
                                                                                            dtBarcode.Columns.Add("KP_" + kp_no + "#MAC" + (m + 1).ToString());
                                                                                        }
                                                                                        catch { }
                                                                                    }
                                                                                    else
                                                                                    {
                                                                                        try
                                                                                        {
                                                                                            dtBarcode.Columns.Add("KP_" + kp_no + "#" + (k + 1).ToString() + "_MAC" + (m + 1).ToString());
                                                                                        }
                                                                                        catch { }
                                                                                    }
                                                                                }
                                                                                dtBarcode.AcceptChanges();
                                                                                createMacCol = false;
                                                                            }

                                                                            string mac = "";
                                                                            for (int m = 0; m < esun_table.Rows.Count; m++)
                                                                            {
                                                                                mac = esun_table.Rows[m]["part_barcode"].ToString().Trim();
                                                                                if (dtItem.Rows.Count == 1)
                                                                                {
                                                                                    dtBarcode.Rows[i]["KP_" + kp_no + "#MAC" + (m + 1).ToString()] = mac;
                                                                                }
                                                                                else
                                                                                {
                                                                                    dtBarcode.Rows[i]["KP_" + kp_no + "#" + (k + 1).ToString() + "_MAC" + (m + 1).ToString()] = mac;
                                                                                }
                                                                                dtBarcode.AcceptChanges();
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                            */

                                                            string mac_sql2 = string.Format("select a.part_no from jhames.barcode_item a,jhames.barcode_info b where a.barcode_id = b.barcode_id and b.barcode_no = '{0}' and item_no like 'MAC%'", part_no);

                                                            using (var esun_cmd = conn.CreateCommand())
                                                            {
                                                                esun_cmd.CommandText = mac_sql2;
                                                                esun_cmd.CommandTimeout = 0;

                                                                using (var esun_reader = await esun_cmd.ExecuteReaderAsync())
                                                                {
                                                                    if (esun_reader.HasRows)
                                                                    {
                                                                        List<dynamic> esun_list = new List<dynamic>();
                                                                        DataTable esun_table = new DataTable();

                                                                        esun_table = DataReaderToDataTable(esun_reader);

                                                                        if (esun_table.Rows.Count > 0)
                                                                        {
                                                                            if (createMacCol)
                                                                            {
                                                                                for (int m = 0; m < esun_table.Rows.Count; m++)
                                                                                {
                                                                                    if (dtItem.Rows.Count == 1)
                                                                                    {
                                                                                        try
                                                                                        {
                                                                                            dtBarcode.Columns.Add("KP_" + kp_no + "#MAC" + (m + 1).ToString());
                                                                                        }
                                                                                        catch { }
                                                                                    }
                                                                                    else
                                                                                    {
                                                                                        try
                                                                                        {
                                                                                            dtBarcode.Columns.Add("KP_" + kp_no + "#" + (k + 1).ToString() + "_MAC" + (m + 1).ToString());
                                                                                        }
                                                                                        catch { }
                                                                                    }
                                                                                }
                                                                                dtBarcode.AcceptChanges();
                                                                                createMacCol = false;
                                                                            }

                                                                            string mac = "";
                                                                            for (int m = 0; m < esun_table.Rows.Count; m++)
                                                                            {
                                                                                //mac = esun_table.Rows[m]["part_barcode"].ToString().Trim();
                                                                                mac = esun_table.Rows[m]["PART_NO"].ToString().Trim();
                                                                                if (dtItem.Rows.Count == 1)
                                                                                {
                                                                                    dtBarcode.Rows[i]["KP_" + kp_no + "#MAC" + (m + 1).ToString()] = mac;
                                                                                }
                                                                                else
                                                                                {
                                                                                    dtBarcode.Rows[i]["KP_" + kp_no + "#" + (k + 1).ToString() + "_MAC" + (m + 1).ToString()] = mac;
                                                                                }
                                                                                dtBarcode.AcceptChanges();
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                    catch (Exception e1)
                                                    {
                                                        string err = e1.Message;
                                                    }
                                                }
                                                dtBarcode.AcceptChanges();
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        foreach (DataRow row in dtBarcode.Rows)
                        {
                            dynamic dyn = new ExpandoObject();
                            list.Add(dyn);
                            foreach (DataColumn column in dtBarcode.Columns)
                            {
                                var dic = (IDictionary<string, object>)dyn;
                                dic[column.ColumnName] = row[column];
                            }
                        }

                        result.DataTotal = list.Count();
                        result.Data = list;
                    }
                }
            }

            if (result == null)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }

        /// <summary>
        /// 查詢工單KeyParts資料QRS013
        /// </summary>
        /// <param name="wipNO"></param>
        /// <param name="factoryNo"></param>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<dynamic>> GetWipInfo4QRS013V4(string wipNO, string factoryNo, int page, int limit)
        {
            ResultModel<dynamic> result = new ResultModel<dynamic>();
            Helper helper = new Helper(_context);

            var wip_kp = await _context.WipKps.FromSqlRaw("SELECT * FROM JHAMES.WIP_KP WHERE WIP_NO = '" + wipNO + "' ORDER BY KP_NO").ToListAsync();

            string sql = @" select c.wip_no as WipNo,b.barcode_no as BarcodeNo,b.extra_barcode_no as ExtraBarcodeNo,d.model_no as ModelNO,d.item_no as ItemNO";
            string sql1 = "", sql2 = "", sql3 = "";
            if (wip_kp.Count > 0)
            {
                for (int i = 0; i < wip_kp.Count; i++)
                {
                    sql1 = sql1 + ",k" + (i + 1).ToString() + ".part_no as KP_" + wip_kp[i].KpNo;
                    sql2 = sql2 + ",(select barcode_id,part_no from jhames.barcode_item where item_no = '" + wip_kp[i].KpNo + "') k" + (i + 1).ToString();
                    sql3 = sql3 + " and b.barcode_id = k" + (i + 1).ToString() + ".barcode_id(+)";
                }
            }

            sql = sql + sql1;
            sql = sql + " from jhames.barcode_info b,jhames.wip_info c,jhames.wip_att d";
            sql = sql + sql2;

            sql = sql + " where b.wip_id = c.wip_id and c.wip_no = d.wip_no";

            sql = sql + sql3;

            sql = sql + " and c.wip_no = '" + wipNO + "'";

            DbConnection conn = _context.Database.GetDbConnection();
            if (conn.State != System.Data.ConnectionState.Open)
            {
                await conn.OpenAsync();
            }

            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = sql;

                using (var reader = await cmd.ExecuteReaderAsync())
                {
                    if (reader.HasRows)
                    {
                        List<dynamic> list = new List<dynamic>();
                        DataTable table = new DataTable();

                        table = DataReaderToDataTable(reader);

                        //判断MB组件增加查询MAC
                        try
                        {
                            if (wip_kp.Count > 0)
                            {
                                bool mbFlag = false;
                                for (int i = 0; i < wip_kp.Count; i++)
                                {
                                    if (wip_kp[i].KpNo.StartsWith("MB"))
                                    {
                                        mbFlag = true;
                                        break;
                                    }
                                }

                                if (mbFlag)
                                {
                                    ESUNContext _esun_context = new ESUNContext();

                                    //读取MAC
                                    DbConnection esun_conn = _esun_context.Database.GetDbConnection();
                                    if (esun_conn.State != System.Data.ConnectionState.Open)
                                    {
                                        await esun_conn.OpenAsync();
                                    }

                                    bool createMacCol = true;

                                    for (int j = 0; j < table.Rows.Count; j++)
                                    {
                                        string barcode_no = "";

                                        try
                                        {
                                            barcode_no = table.Rows[j]["KP_MB"].ToString();
                                        }
                                        catch { }

                                        string mac_sql = string.Format(@"select distinct a.工單編號 as mo_id,e.客戶工單編號 as customer_moid,a.工單序號 as product_sn,                        
                               case substring(f.avalue_kp_typeid, 1, 3) when 'MAC' then isnull(z.item_prefix,'')+b.SUB_ITEM_SN else b.SUB_ITEM_SN end as part_barcode,
                               f.avalue_kp_typeid as class,c.material_id,d.r_stn as routeid,'' as workerid,rtrim(g.sn_date) + ' ' + rtrim(g.sn_time) as create_date
                          from or_sn_story a
                        left join sub_item_db b on a.工單編號 = b.or_sn and a.工單序號 = b.or_sal
                        left join jh_sub_item c on a.工單編號 = c.mo_id and b.class = c.part_typeid
                        left join jh_sub_item_prefix z on c.mo_id = z.mo_id
                        left join or_sub_db d on a.工單編號 = d.or_sn and b.class = d.class
                             join or_list e on a.工單編號 = e.工單編號 and e.[客戶] = 'EV'
                        left join jh_sub_item_mapping f on b.class = f.eversun_kp_typeid
                             join jh_sn_list g on a.工單序號 = g.sn
                         where g.sn_result = 'OK'
       AND a.工單序號 = '{0}'
       AND c.material_id LIKE 'MAC%'", barcode_no);

                                        using (var esun_cmd = esun_conn.CreateCommand())
                                        {
                                            esun_cmd.CommandText = mac_sql;

                                            using (var esun_reader = await esun_cmd.ExecuteReaderAsync())
                                            {
                                                if (esun_reader.HasRows)
                                                {
                                                    List<dynamic> esun_list = new List<dynamic>();
                                                    DataTable esun_table = new DataTable();

                                                    esun_table = DataReaderToDataTable(esun_reader);

                                                    if (esun_table.Rows.Count > 0)
                                                    {
                                                        if (createMacCol)
                                                        {
                                                            for (int k = 0; k < esun_table.Rows.Count; k++)
                                                            {
                                                                table.Columns.Add("KP_MAC" + (k + 1).ToString());
                                                            }
                                                            table.AcceptChanges();
                                                            createMacCol = false;
                                                        }

                                                        string mac = "";
                                                        for (int k = 0; k < esun_table.Rows.Count; k++)
                                                        {
                                                            mac = esun_table.Rows[k]["part_barcode"].ToString().Trim();
                                                            table.Rows[j]["KP_MAC" + (k + 1).ToString()] = mac;
                                                            table.AcceptChanges();
                                                        }
                                                    }
                                                }
                                            }
                                        }

                                    }
                                }
                            }
                        }
                        catch { }


                        foreach (DataRow row in table.Rows)
                        {
                            dynamic dyn = new ExpandoObject();
                            list.Add(dyn);
                            foreach (DataColumn column in table.Columns)
                            {
                                var dic = (IDictionary<string, object>)dyn;
                                dic[column.ColumnName] = row[column];
                            }
                        }

                        result.DataTotal = list.Count();
                        result.Data = list;
                    }
                }
            }

            if (result == null)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }

        /// <summary>
        /// 查詢工單KeyParts資料QRS013
        /// </summary>
        /// <param name="wipNO"></param>
        /// <param name="factoryNo"></param>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<dynamic>> GetWipInfo4QRS013V3(string wipNO, string factoryNo, int page, int limit)
        {
            ResultModel<dynamic> result = new ResultModel<dynamic>();
            Helper helper = new Helper(_context);

            var wip_kp = await _context.WipKps.FromSqlRaw("SELECT * FROM JHAMES.WIP_KP WHERE WIP_NO = '" + wipNO + "' ORDER BY KP_NO").ToListAsync();

            string sql = @" select c.wip_no as WipNo,b.barcode_no as BarcodeNo,b.extra_barcode_no as ExtraBarcodeNo,d.model_no as ModelNO,d.item_no as ItemNO";
            string sql1 = "", sql2 = "", sql3 = "";
            if (wip_kp.Count > 0)
            {
                for (int i = 0; i < wip_kp.Count; i++)
                {
                    sql1 = sql1 + ",k" + (i + 1).ToString() + ".part_no as KP_" + wip_kp[i].KpNo;
                    sql2 = sql2 + ",(select barcode_id,part_no from jhames.barcode_item where item_no = '" + wip_kp[i].KpNo + "') k" + (i + 1).ToString();
                    sql3 = sql3 + " and b.barcode_id = k" + (i + 1).ToString() + ".barcode_id(+)";
                }
            }

            sql = sql + sql1;
            sql = sql + " from jhames.barcode_info b,jhames.wip_info c,jhames.wip_att d";
            sql = sql + sql2;

            sql = sql + " where b.wip_id = c.wip_id and c.wip_no = d.wip_no";

            sql = sql + sql3;

            sql = sql + " and c.wip_no = '" + wipNO + "'";

            DbConnection conn = _context.Database.GetDbConnection();
            if (conn.State != System.Data.ConnectionState.Open)
            {
                await conn.OpenAsync();
            }

            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = sql;

                using (var reader = await cmd.ExecuteReaderAsync())
                {
                    if (reader.HasRows)
                    {
                        List<dynamic> list = new List<dynamic>();
                        DataTable table = new DataTable();

                        table = DataReaderToDataTable(reader);

                        //判断MB组件增加查询MAC
                        try
                        {
                            if (wip_kp.Count > 0)
                            {
                                /*
                                for (int i = 0; i < wip_kp.Count; i++)
                                {
                                    if (wip_kp[i].KpNo.StartsWith("MB"))
                                    {
                                        table.Columns.Add("MAC");
                                        table.AcceptChanges();
                                        break;
                                    }
                                }
                                */

                                ESUNContext _esun_context = new ESUNContext();

                                //读取MAC
                                DbConnection esun_conn = _esun_context.Database.GetDbConnection();
                                if (esun_conn.State != System.Data.ConnectionState.Open)
                                {
                                    await esun_conn.OpenAsync();
                                }

                                bool createMacCol = true;

                                for (int j = 0; j < table.Rows.Count; j++)
                                {
                                    string barcode_no = table.Rows[j]["BarcodeNo"].ToString();

                                    string mac_sql = string.Format(@"select distinct a.工單編號 as mo_id,e.客戶工單編號 as customer_moid,a.工單序號 as product_sn,                        
                               case substring(f.avalue_kp_typeid, 1, 3) when 'MAC' then isnull(z.item_prefix,'')+b.SUB_ITEM_SN else b.SUB_ITEM_SN end as part_barcode,
                               f.avalue_kp_typeid as class,c.material_id,d.r_stn as routeid,'' as workerid,rtrim(g.sn_date) + ' ' + rtrim(g.sn_time) as create_date
                          from or_sn_story a
                        left join sub_item_db b on a.工單編號 = b.or_sn and a.工單序號 = b.or_sal
                        left join jh_sub_item c on a.工單編號 = c.mo_id and b.class = c.part_typeid
                        left join jh_sub_item_prefix z on c.mo_id = z.mo_id
                        left join or_sub_db d on a.工單編號 = d.or_sn and b.class = d.class
                             join or_list e on a.工單編號 = e.工單編號 and e.[客戶] = 'EV'
                        left join jh_sub_item_mapping f on b.class = f.eversun_kp_typeid
                             join jh_sn_list g on a.工單序號 = g.sn
                         where g.sn_result = 'OK'
       AND a.工單序號 = '{0}'
       AND c.material_id LIKE 'MAC%'", barcode_no);

                                    using (var esun_cmd = esun_conn.CreateCommand())
                                    {
                                        esun_cmd.CommandText = mac_sql;

                                        using (var esun_reader = await esun_cmd.ExecuteReaderAsync())
                                        {
                                            if (esun_reader.HasRows)
                                            {
                                                List<dynamic> esun_list = new List<dynamic>();
                                                DataTable esun_table = new DataTable();

                                                esun_table = DataReaderToDataTable(esun_reader);

                                                if (esun_table.Rows.Count > 0)
                                                {
                                                    if (createMacCol)
                                                    {
                                                        for (int k = 0; k < esun_table.Rows.Count; k++)
                                                        {
                                                            table.Columns.Add("KP_MAC" + (k + 1).ToString());
                                                        }
                                                        table.AcceptChanges();
                                                        createMacCol = false;
                                                    }

                                                    string mac = "";
                                                    for (int k = 0; k < esun_table.Rows.Count; k++)
                                                    {
                                                        mac = esun_table.Rows[k]["part_barcode"].ToString().Trim();
                                                        table.Rows[j]["KP_MAC" + (k + 1).ToString()] = mac;
                                                        table.AcceptChanges();
                                                    }
                                                }
                                            }
                                        }
                                    }

                                }
                            }
                        }
                        catch { }


                        foreach (DataRow row in table.Rows)
                        {
                            dynamic dyn = new ExpandoObject();
                            list.Add(dyn);
                            foreach (DataColumn column in table.Columns)
                            {
                                var dic = (IDictionary<string, object>)dyn;
                                dic[column.ColumnName] = row[column];
                            }
                        }

                        result.DataTotal = list.Count();
                        result.Data = list;
                    }
                }
            }

            if (result == null)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }

        /// <summary>
        /// 查詢工單KeyParts資料QRS013
        /// </summary>
        /// <param name="wipNO"></param>
        /// <param name="factoryNo"></param>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<dynamic>> GetWipInfo4QRS013V2(string wipNO, string factoryNo, int page, int limit)
        {
            ResultModel<dynamic> result = new ResultModel<dynamic>();
            Helper helper = new Helper(_context);

            var wip_kp = await _context.WipKps.FromSqlRaw("SELECT * FROM JHAMES.WIP_KP WHERE WIP_NO = '" + wipNO + "' ORDER BY KP_NO").ToListAsync();

            string sql = @" select c.wip_no as WipNo,b.barcode_no as BarcodeNo,b.extra_barcode_no as ExtraBarcodeNo,d.model_no as ModelNO,d.item_no as ItemNO";
            string sql1 = "", sql2 = "", sql3 = "";
            if (wip_kp.Count > 0)
            {
                for (int i = 0; i < wip_kp.Count; i++)
                {
                    sql1 = sql1 + ",k" + (i + 1).ToString() + ".part_no as KP_" + wip_kp[i].KpNo;
                    sql2 = sql2 + ",(select barcode_id,part_no from jhames.barcode_item where item_no = '" + wip_kp[i].KpNo + "') k" + (i + 1).ToString();
                    sql3 = sql3 + " and b.barcode_id = k" + (i + 1).ToString() + ".barcode_id(+)";
                }
            }

            sql = sql + sql1;
            sql = sql + " from jhames.barcode_info b,jhames.wip_info c,jhames.wip_att d";
            sql = sql + sql2;

            sql = sql + " where b.wip_id = c.wip_id and c.wip_no = d.wip_no";

            sql = sql + sql3;

            sql = sql + " and c.wip_no = '" + wipNO + "'";

            DbConnection conn = _context.Database.GetDbConnection();
            if (conn.State != System.Data.ConnectionState.Open)
            {
                await conn.OpenAsync();
            }

            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = sql;

                using (var reader = await cmd.ExecuteReaderAsync())
                {
                    if (reader.HasRows)
                    {
                        List<dynamic> list = new List<dynamic>();
                        DataTable table = new DataTable();

                        table = DataReaderToDataTable(reader);

                        table.Columns.Add("KP_MAC");
                        table.AcceptChanges();

                        //判断MB组件增加查询MAC
                        try
                        {
                            if (wip_kp.Count > 0)
                            {
                                /*
                                for (int i = 0; i < wip_kp.Count; i++)
                                {
                                    if (wip_kp[i].KpNo.StartsWith("MB"))
                                    {
                                        table.Columns.Add("MAC");
                                        table.AcceptChanges();
                                        break;
                                    }
                                }
                                */

                                ESUNContext _esun_context = new ESUNContext();

                                //读取MAC
                                DbConnection esun_conn = _esun_context.Database.GetDbConnection();
                                if (esun_conn.State != System.Data.ConnectionState.Open)
                                {
                                    await esun_conn.OpenAsync();
                                }

                                for (int j = 0; j < table.Rows.Count; j++)
                                {
                                    string barcode_no = table.Rows[j]["BarcodeNo"].ToString();

                                    string mac_sql = string.Format(@"select distinct a.工單編號 as mo_id,e.客戶工單編號 as customer_moid,a.工單序號 as product_sn,                        
                               case substring(f.avalue_kp_typeid, 1, 3) when 'MAC' then isnull(z.item_prefix,'')+b.SUB_ITEM_SN else b.SUB_ITEM_SN end as part_barcode,
                               f.avalue_kp_typeid as class,c.material_id,d.r_stn as routeid,'' as workerid,rtrim(g.sn_date) + ' ' + rtrim(g.sn_time) as create_date
                          from or_sn_story a
                        left join sub_item_db b on a.工單編號 = b.or_sn and a.工單序號 = b.or_sal
                        left join jh_sub_item c on a.工單編號 = c.mo_id and b.class = c.part_typeid
                        left join jh_sub_item_prefix z on c.mo_id = z.mo_id
                        left join or_sub_db d on a.工單編號 = d.or_sn and b.class = d.class
                             join or_list e on a.工單編號 = e.工單編號 and e.[客戶] = 'EV'
                        left join jh_sub_item_mapping f on b.class = f.eversun_kp_typeid
                             join jh_sn_list g on a.工單序號 = g.sn
                         where g.sn_result = 'OK'
       AND a.工單序號 = '{0}'
       AND c.material_id LIKE 'MAC%'", barcode_no);

                                    using (var esun_cmd = esun_conn.CreateCommand())
                                    {
                                        esun_cmd.CommandText = mac_sql;

                                        using (var esun_reader = await esun_cmd.ExecuteReaderAsync())
                                        {
                                            if (esun_reader.HasRows)
                                            {
                                                List<dynamic> esun_list = new List<dynamic>();
                                                DataTable esun_table = new DataTable();

                                                esun_table = DataReaderToDataTable(esun_reader);

                                                if (esun_table.Rows.Count > 0)
                                                {
                                                    string mac_list = "";
                                                    for (int k = 0; k < esun_table.Rows.Count; k++)
                                                    {
                                                        mac_list = mac_list + esun_table.Rows[k]["part_barcode"].ToString().Trim() + ",";
                                                    }

                                                    if (mac_list != "")
                                                    {
                                                        string mac = mac_list.Substring(0, mac_list.Length - 1);
                                                        table.Rows[j]["KP_MAC"] = mac;
                                                        table.AcceptChanges();
                                                    }
                                                }
                                            }
                                        }
                                    }

                                }
                            }
                        }
                        catch { }


                        foreach (DataRow row in table.Rows)
                        {
                            dynamic dyn = new ExpandoObject();
                            list.Add(dyn);
                            foreach (DataColumn column in table.Columns)
                            {
                                var dic = (IDictionary<string, object>)dyn;
                                dic[column.ColumnName] = row[column];
                            }
                        }

                        result.DataTotal = list.Count();
                        result.Data = list;
                    }
                }
            }

            if (result == null)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }

        /// <summary>
        /// 查詢工單KeyParts資料QRS013
        /// </summary>
        /// <param name="wipNO"></param>
        /// <param name="factoryNo"></param>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<dynamic>> GetWipInfo4QRS013V1(string wipNO, string factoryNo, int page, int limit)
        {
            ResultModel<dynamic> result = new ResultModel<dynamic>();
            Helper helper = new Helper(_context);

            var q = from q1 in _context.WipInfos
                    join q2 in _context.BarcodeInfoes on q1.WipID equals q2.WipID
                    join q3 in _context.BarcodeItems on q2.BarcodeID equals q3.BarcodeID into item_data
                    from x in item_data.DefaultIfEmpty()
                    join q4 in _context.Items on x.ItemNo equals q4.ItemNo into item_base
                    from y in item_base.DefaultIfEmpty()
                    join q5 in _context.WipAtts on q1.WipNO equals q5.WipNO
                    select new
                    {
                        q1.WipID,
                        q1.WipNO,
                        q1.WerksNO,
                        q2.BarcodeNo,
                        q2.ExtraBarcodeNo,
                        q5.ModelNO,
                        q5.ItemNO,
                        KeyPartNo = x.ItemNo,
                        KeyPartItem = x.KpItemNo,
                        KeyPartSN = x.PartNo,
                        KeyPartUserNo = helper.GetUserNo(x.CreateUserID).Result,
                        KeyPartUserName = helper.GetUserName(x.CreateUserID).Result,
                        KeyPartDate = x.CreateDate
                    };

            if (wipNO != null && wipNO != "")
            {
                q = q.Where(w => w.WipNO == wipNO);
            }
            if (factoryNo != null && factoryNo != "")
            {
                q = q.Where(w => w.WerksNO == factoryNo);
            }
            //紀錄筆數
            result.DataTotal = q.Count();

            // Table 頁數
            if (page > 0)
            {
                q = q.Skip((page - 1) * limit).Take(limit);
            }

            result.Data = await q.ToListAsync();

            if (result == null)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }

        /// <summary>
        /// 查詢工單資料QRS014
        /// </summary>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<dynamic>> GetWipInfo4QRS014(string unitNo, string itemNO, string wipNO, string dateStart, string dateEnd, string modelNO, string custType, string pType)
        {
            string fpyStation = _config["FPYStation"].ToString();
            string[] fpy_station = fpyStation.Split(',');

            var s = from q1 in _context.Stationses.Where(y=>fpy_station.Contains(y.StationName))
                    select new {
                        q1.StationID,
                        q1.StationName
                    };

            var sdata = await s.ToListAsync();

            int[] slist = new int[sdata.Count];
            for (int i = 0; i < slist.Length; i++)
            {
                slist[i] = sdata[i].StationID;
            }

            ResultModel<dynamic> result = new ResultModel<dynamic>();
            var q = from q1 in _context.WipInfos
                    join q2 in _context.WipAtts on q1.WipNO equals q2.WipNO
                    join q3 in _context.LineInfoes on q1.LineID equals q3.LineID
                    join q4 in _context.FactoryUnits on q1.UnitNO equals q4.UnitNo
                    join q5 in _context.WipStations.Where(y=>slist.Contains(y.StationID)).GroupBy(x => new { x.WipID }).Select(x => new { WipID = x.Key.WipID, CreateDate = x.Min(o => o.CreateDate) }) on q1.WipID equals q5.WipID into wip_data
                    from x in wip_data.DefaultIfEmpty()
                    select new
                    {
                        q1.WipID,
                        q1.WipNO,
                        q1.PlanQTY,
                        q1.CompleteQTY,
                        q1.UnitNO,
                        q1.LineID,
                        q1.FlowRuleID,
                        q1.StatusNO,
                        CreateDate = (x.CreateDate == null ? DateTime.Now : x.CreateDate),
                        q2.ItemNO,
                        q2.ModelNO,
                        q3.LineDesc,
                        q4.UnitName,
                        q1.CustomerMedical,
                        q1.CustomerVIP
                    };

            q = q.Where(w => w.CompleteQTY > 0);

            if (pType != "*")
            {
                if (pType == "M")
                {
                    q = q.Where(w => w.CustomerMedical == "Y");
                }
                else
                {
                    q = q.Where(w => w.CustomerVIP == "Y");
                }

            }
            if (unitNo != "*")
            {
                q = q.Where(w => w.UnitNO == unitNo);
            }
            if (itemNO != null && itemNO != "")
            {
                q = q.Where(w => w.ItemNO == itemNO);
            }
            if (custType != null && custType != "")
            {
                q = q.Where(w => w.ItemNO.StartsWith(custType));
            }
            if (modelNO != null && modelNO != "")
            {
                q = q.Where(w => w.ModelNO == modelNO);
            }
            if (wipNO != null && wipNO != "")
            {
                q = q.Where(w => w.WipNO == wipNO);
            }
            if (dateStart != null && dateStart != "" && dateEnd != null && dateEnd != "")
            {
                q = q.Where(w => w.CreateDate >= DateTime.Parse(dateStart) && w.CreateDate <= DateTime.Parse(dateEnd).AddDays(1));
            }

            //紀錄筆數
            result.DataTotal = q.Distinct().ToList().Count();

            result.Data = await q.Distinct().ToListAsync();

            if (result == null)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }

        /// <summary>
        /// 查詢工單資料 by SelectParameter
        /// </summary>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<dynamic>> GetWipInfoSelectParameter([FromQuery] WipInfoDto value, int page = 0, int limit = 10)
        {
            ResultModel<dynamic> result = new ResultModel<dynamic>();
            var q = from q1 in _context.WipInfos
                    join q2 in _context.WipAtts on q1.WipNO equals q2.WipNO
                    join q3 in _context.LineInfoes on q1.LineID equals q3.LineID
                    join q4 in _context.FactoryUnits on q1.UnitNO equals q4.UnitNo
                    join q5 in _context.FactoryInfos on q1.Werks equals q5.FactoryID.ToString()
                    join q6 in _context.WipChecks on q1.WipNO equals q6.WipNo into j1
                    from q6 in j1.DefaultIfEmpty()
                    select new WipQueryDto
                    {
                        wipID = q1.WipID,
                        wipNo = q1.WipNO,
                        planQTY = q1.PlanQTY,
                        unitNo = q1.UnitNO,
                        lineID = q1.LineID,
                        statusNo = q1.StatusNO,
                        wipScheduleDate = q1.WipScheduleDate,
                        wipDueDate = q1.WipDueDate,
                        factoryNameCh = q5.FactoryNameCh,
                        description = q1.Description,
                        CreateDate = q1.CreateDate,
                        itemNo = q2.ItemNO,
                        lineDesc = q3.LineDesc,
                        unitName = q4.UnitName,
                        wipType = q1.WipType,
                        factoryNo = q1.WerksNO,
                        wipCheck = q6 == null ? "N" : q6.PEUserID == null ? "N" : "Y"
                    };


            if (!string.IsNullOrWhiteSpace(value.unitno))
            {
                q = q.Where(w => w.unitNo == value.unitno);
            }

            if (!string.IsNullOrWhiteSpace(value.wipno))
            {
                q = q.Where(w => w.wipNo.Contains(value.wipno.ToUpper().Trim()));
            }

            if (value.lineid != 0)
            {
                q = q.Where(w => w.lineID == value.lineid);
            }

            DateTime dateTime = DateTime.Now;
            if (DateTime.TryParse(value.date_str, out dateTime))
            {
                q = q.Where(w => w.CreateDate >= DateTime.Parse(value.date_str));
            }

            if (DateTime.TryParse(value.date_end, out dateTime))
            {
                q = q.Where(w => w.CreateDate <= DateTime.Parse(value.date_end));
            }

            if (value.itemno != null)
            {
                q = q.Where(w => w.itemNo == value.itemno);
            }

            if (!string.IsNullOrWhiteSpace(value.wipType))
            {
                q = q.Where(w => w.wipType == value.wipType);
            }

            if (!string.IsNullOrWhiteSpace(value.factoryno))
            {
                q = q.Where(w => w.factoryNo == value.factoryno);
            }

            if (!string.IsNullOrWhiteSpace(value.statusNo))
            {
                if (value.statusNo == "N")
                    q = q.Where(w => w.statusNo != "E" && w.statusNo != "C");
                else
                    q = q.Where(w => w.statusNo == value.statusNo);
            }

            q.Take(1000);
            // 紀錄筆數
            result.DataTotal = q.Count();

            // Table 頁數
            if (page > 0)
            {
                q = q.Skip((page - 1) * limit).Take(limit);
            }

            var qq = await q.ToListAsync();

            // 塞入開工日
            foreach (var item in qq)
            {
                var workDate = _context.WipStations.Where(w => w.WipID == item.wipID)
                                                    .OrderBy(s => s.CreateDate)
                                                    .FirstOrDefault();
                item.workDate = workDate == null ? "" : workDate.CreateDate.ToString("yyyy/MM/dd");
            }

            // 塞檢驗完成日期
            foreach (var item in qq)
            {
                var fqcDate = _context.FqcResultMasters.Where(w => w.WipNo == item.wipNo && w.QaResult != "A")
                                                    .OrderBy(s => s.EndTime)
                                                    .FirstOrDefault();
                item.fqcDate = fqcDate == null ? "" : fqcDate.EndTime.ToString("yyyy/MM/dd");
            }

            result.Data = qq;

            if (result == null)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }

        /// <summary>
        /// 查詢工單資料 未結工單查詢
        /// </summary>
        /// <returns></returns>
        [Route("[action]")]
        [HttpGet]
        public async Task<ResultModel<dynamic>> GetWipInfoPCS008([FromQuery] WipInfoDto value, string statusNo = null)
        {
            ResultModel<dynamic> result = new ResultModel<dynamic>();
            var q = from q1 in _context.WipInfos
                    where q1.CompleteQTY != 0
                    join q2 in _context.WipAtts on q1.WipNO equals q2.WipNO
                    join q3 in _context.LineInfoes on q1.LineID equals q3.LineID
                    join q4 in _context.FactoryUnits on q1.UnitNO equals q4.UnitNo
                    select new
                    {
                        q1.WipID,
                        q1.WipNO,
                        q1.PlanQTY,
                        q1.CompleteQTY,
                        q1.UnitNO,
                        q1.LineID,
                        q1.FlowRuleID,
                        q1.StatusNO,
                        q1.CreateDate,
                        q2.ItemNO,
                        q3.LineDesc,
                        q4.UnitName,
                        q1.WerksNO
                    };

            if (statusNo == null)
            {
                q = q.Where(w => w.StatusNO != "E");
            }

            if (value.wipno != null)
            {
                q = q.Where(w => w.WipNO.Equals(value.wipno));
            }

            if (value.itemno != null)
            {
                q = q.Where(w => w.ItemNO.Equals(value.itemno));
            }

            if (value.unitno != null)
            {
                q = q.Where(w => w.UnitNO.Equals(value.unitno));
            }
            if (value.factoryno != null)
            {
                q = q.Where(w => w.WerksNO.Equals(value.factoryno));
            }

            DateTime dateTime = DateTime.Now;
            if (DateTime.TryParse(value.date_str, out dateTime))
            {
                q = q.Where(w => w.CreateDate >= DateTime.Parse(value.date_str));
            }

            if (DateTime.TryParse(value.date_end, out dateTime))
            {
                q = q.Where(w => w.CreateDate <= DateTime.Parse(value.date_end));
            }

            //紀錄筆數
            result.DataTotal = q.Count();

            result.Data = await q.ToListAsync();

            if (result == null)
            {
                result.Msg = "查無資料";
                result.Success = false;
                return result;
            }

            result.Success = true;
            result.Msg = "OK";
            return result;
        }

        /// <summary>
        /// 查詢工單資料Info By WipID
        /// </summary>
        /// <param name="id">WipID</param>
        /// <returns></returns>
        // GET: api/RoleModules/Role/5
        [HttpGet("{id}")]
        public async Task<ActionResult<IEnumerable<WipInfo>>> GetWipInfo(int id)
        {
            IQueryable<WipInfo> q = _context.WipInfos.Where(w => w.WipID == id);

            var WipInfo = await q.ToListAsync();

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

            return WipInfo;
        }

        /// <summary>
        /// 查詢工單資料Info By WipNO
        /// </summary>
        /// <param name="wipno">工單號碼</param>
        /// <returns></returns>
        // GET: api/RoleModules/Role/5
        [HttpGet("WipInfoByWipNo/{wipno}")]
        public async Task<ActionResult<IEnumerable<WipInfo>>> GetWipInfoByWipNo(string wipno)
        {
            IQueryable<WipInfo> q = _context.WipInfos.Where(w => w.WipNO.ToUpper().Trim() == wipno.ToUpper().Trim());
            var WipInfo = await q.ToListAsync();
            return WipInfo;
        }

        /// <summary>
        /// 查詢工單是否投入
        /// </summary>
        /// <param name="wipno">工單號碼</param>
        /// <returns>Y:投入N:未投入</returns>
        [HttpGet("CheckStart/{wipno}")]
        public ActionResult<string> GetWipInfoCheckStart(string wipno)
        {
            // 判斷是否有投產紀錄
            var q = from q1 in _context.WipInfos
                    join q2 in _context.BarcodeInfoes on q1.WipID equals q2.WipID
                    where q1.WipNO == wipno
                    select q2;

            if (q.Count() != 0)
                return "Y";
            else
                return "N";
        }

        /// <summary>
        /// 查詢工單是否投入
        /// </summary>
        /// <param name="wipno">工單號碼</param>
        /// <param name="unit">生產製程</param>
        /// <returns>Y:投入N:未投入</returns>
        [HttpGet("CheckStart/{wipno}/{unit}")]
        public ActionResult<string> GetWipInfoCheckStart(string wipno, string unit)
        {
            // 判斷是否有投產紀錄
            var q = from q1 in _context.WipInfos
                    join q2 in _context.BarcodeInfoes on q1.WipID equals q2.WipID
                    where q1.WipNO == wipno && q1.UnitNO == unit
                    select q2;

            if (q.Count() != 0)
                return "Y";
            else
                return "N";
        }

        /// <summary>
        /// 查詢工單是否投入
        /// </summary>
        /// <param name="wipno">工單號碼</param>
        /// <param name="unit">生產製程</param>
        /// <param name="line">線別</param>
        /// <returns>Y:投入N:未投入</returns>
        [HttpGet("CheckStart/{wipno}/{unit}/{line}")]
        public ActionResult<string> GetWipInfoCheckStart(string wipno, string unit, int line)
        {
            // 判斷是否有投產紀錄
            var q = from q1 in _context.WipInfos
                    join q2 in _context.BarcodeInfoes on q1.WipID equals q2.WipID
                    where q1.WipNO == wipno && q1.UnitNO == unit && q1.LineID == line
                    select q2;

            if (q.Count() != 0)
                return "Y";
            else
                return "N";
        }

        /// <summary>
        /// 查詢工單是否開線
        /// </summary>
        /// <param name="wipno">工單號碼</param>
        /// <returns>Y:已開線N:未開線</returns>
        [HttpGet("CheckStartLine/{wipno}")]
        public ActionResult<string> GetWipInfoCheckStartLine(string wipno)
        {
            // 判斷是否已經開線
            var q = from q1 in _context.WipInfos
                    join q2 in _context.LineInfoes on q1.WipID equals q2.WipNo
                    where q1.WipNO == wipno
                    select q2;

            if (q.Count() != 0)
                return "Y";
            else
                return "N";
        }



        /// <summary>
        /// 條碼批次查詢
        /// </summary>
        /// <param name="wipNO"></param>
        /// <param name="unit"></param>
        /// <param name="lineID"></param>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <param name="wipNo">工單號碼</param>
        /// <returns></returns>
        [HttpGet("WipInfoByPCS038")]
        public async Task<ResultModel<dynamic>> GetWipInfoByPCS038(string wipNO,
          string unit, int lineID, int page = 0, int limit = 10)
        {

            ResultModel<dynamic> result = new ResultModel<dynamic>();
            try
            {
                var q = from q1 in _context.WipInfos
                        join q2 in _context.WipAtts on q1.WipNO equals q2.WipNO into wip_att
                        from x in wip_att.DefaultIfEmpty()
                        join q3 in _context.LineInfoes on q1.LineID equals q3.LineID
                        join q4 in _context.FactoryUnits on q1.UnitNO equals q4.UnitNo
                        select new
                        {
                            q1.WipID,
                            q1.WipNO,
                            WipQty = q1.PlanQTY,
                            q1.CompleteQTY,
                            q1.UnitNO,
                            q1.LineID,
                            q1.FlowRuleID,
                            q1.StatusNO,
                            q1.CreateDate,
                            x.ItemNO,
                            LineName = q3.LineDesc,
                            q4.UnitName,
                            q1.WipType

                        };

                if (wipNO != null && wipNO != "")
                {
                    q = q.Where(w => w.WipNO == wipNO);
                }
                if (unit != null && unit != "")
                {
                    q = q.Where(w => w.UnitNO == unit);
                }
                if (lineID != 0)
                {
                    q = q.Where(w => w.LineID == lineID);
                }

                //紀錄筆數
                result.DataTotal = q.Count();

                result.Data = await q.ToListAsync();

                result.DataTotal = q.Count();

                // Table 頁數
                if (page > 0)
                {
                    q = q.Skip((page - 1) * limit).Take(limit);
                }

                result.Data = q.ToList();
                result.Success = true;
                return result;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.Message;
                return result;
            }
        }


        /// <summary>
        /// 查詢工單是否開線
        /// </summary>
        /// <param name="wipno">工單號碼</param>
        /// <param name="unit">生產製程</param>
        /// <returns>Y:已開線N:未開線</returns>
        [HttpGet("CheckStartLine/{wipno}/{unit}")]
        public ActionResult<string> GetWipInfoCheckStartLine(string wipno, string unit)
        {
            // 判斷是否已經開線
            var q = from q1 in _context.WipInfos
                    join q2 in _context.LineInfoes on q1.WipID equals q2.WipNo
                    where q1.WipNO == wipno && q1.UnitNO == unit
                    select q2;

            if (q.Count() != 0)
                return "Y";
            else
                return "N";
        }

        /// <summary>
        /// 查詢工單是否開線
        /// </summary>
        /// <param name="wipno">工單號碼</param>
        /// <param name="unit">生產製程</param>
        /// <param name="line">線別ID</param>
        /// <returns>Y:已開線N:未開線</returns>
        [HttpGet("CheckStartLine/{wipno}/{unit}/{line}")]
        public ActionResult<string> GetWipInfoCheckStartLine(string wipno, string unit, int line)
        {
            // 判斷是否已經開線
            var q = from q1 in _context.WipInfos
                    join q2 in _context.LineInfoes on q1.WipID equals q2.WipNo
                    where q1.WipNO == wipno && q1.UnitNO == unit && q1.LineID == line
                    select q2;

            if (q.Count() != 0)
                return "Y";
            else
                return "N";
        }

        /// <summary>
        /// 查詢工單資料Info By RelatedWONO
        /// </summary>
        /// <param name="RelatedWoNo">關聯工單號碼</param>
        /// <returns></returns>
        // GET: api/RoleModules/Role/5
        [HttpGet("WipInfoByRelatedWoNo/{RelatedWoNo}")]
        public async Task<ActionResult<IEnumerable<WipInfo>>> GetWipInfoByRelatedWoNo(string RelatedWoNo)
        {
            IQueryable<WipInfo> q = _context.WipInfos.Where(w => w.RelatedWONO.ToUpper().Trim() == RelatedWoNo.ToUpper().Trim());
            var WipInfo = await q.ToListAsync();
            return WipInfo;
        }


        /// <summary>
        /// 新增工單資料
        /// </summary>
        /// <param name="WipInfo"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResultModel<WipInfo>> PostWipInfo([FromBody] WipInfo WipInfo)
        {
            ResultModel<WipInfo> result = new ResultModel<WipInfo>();
            Helper helper = new Helper(_context);
            WipInfo.WipID = helper.GetIDKey("WIP_ID").Result;

            // 工單號碼去空白
            WipInfo.WipNO = WipInfo.WipNO.Trim().ToUpper();

            // 委外廠編號抓WERKS廠別代碼
            var q = _context.FactoryInfos.Where(w => w.FactoryID.ToString() == WipInfo.Werks).ToList();
            if (q.Count() != 0)
            {
                WipInfo.WerksNO = q.FirstOrDefault().FactoryNo;
            }

            _context.WipInfos.Add(WipInfo);
            try
            {
                await _context.SaveChangesAsync();
                result.Success = true;
                result.Msg = WipInfo.WipID.ToString();
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.InnerException.Message;
            }
            return result;

            //return CreatedAtAction("GetWipInfo", new { id = WipInfo.WipID }, WipInfo);
        }

        /// <summary>
        /// 更新工單資本資料-狀態
        /// </summary>
        /// <param name="id">工單ID</param>
        /// <param name="statusno">狀態</param>
        /// <returns></returns>
        [HttpPut("{id}/{statusno}")]
        public async Task<ResultModel<WipInfo>> PutWipinfoToStatusNO(int id = 0, string statusno = null)
        {
            ResultModel<WipInfo> result = new ResultModel<WipInfo>();
            try
            {
                await _context.Database.ExecuteSqlInterpolatedAsync
                ($"UPDATE JHAMES.WIP_INFO SET STATUS_NO={statusno} , UPDATE_DATE={DateTime.Now} WHERE WIP_ID={id}");

                //WipInfo wipinfo = new WipInfo
                //{
                //    WipID = id,
                //    StatusNO = statusno,
                //    UpdateDate = DateTime.Now
                //};
                //_context.WipInfos.Attach(wipinfo);
                //// 指定更新某個欄位
                //_context.Entry(wipinfo).Property(p => p.StatusNO).IsModified = true;
                //_context.Entry(wipinfo).Property(p => p.UpdateDate).IsModified = true;

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


        /// <summary>
        /// 更新工單資本資料
        /// </summary>
        /// <returns></returns>
        [HttpPut]
        public async Task<ResultModel<WipInfo>> PutWipinfo([FromBody] WipInfo wipInfo)
        {
            ResultModel<WipInfo> result = new ResultModel<WipInfo>();
            // 工單號碼去空白
            wipInfo.WipNO = wipInfo.WipNO.Trim().ToUpper();

            // 委外廠編號抓WERKS廠別代碼
            var q = _context.FactoryInfos.Where(w => w.FactoryID.ToString() == wipInfo.Werks).ToList();
            if (q.Count() != 0)
            {
                wipInfo.WerksNO = q.FirstOrDefault().FactoryNo;
            }

            _context.Entry(wipInfo).State = EntityState.Modified;
            _context.Entry<WipInfo>(wipInfo).Property("CompleteQTY").IsModified = false;
            _context.Entry<WipInfo>(wipInfo).Property("StatusNO").IsModified = false;
            _context.Entry<WipInfo>(wipInfo).Property("CreateDate").IsModified = false;
            _context.Entry<WipInfo>(wipInfo).Property("CreateUserID").IsModified = false;
            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("UpdateCompleteQty/ById/{id}")]
        public async Task<ResultModel<WipInfo>> PutWipinfoByCompleteQTY(int id)
        {
            ResultModel<WipInfo> result = new ResultModel<WipInfo>();
            result.Success = true;
            var wipInfo = await _context.WipInfos.FindAsync(id);

            if (wipInfo != null)
            {
                wipInfo.CompleteQTY += 1;
                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="wipInfo"></param>
        /// <returns></returns>
        [HttpPut("UpdateLineId")]
        public async Task<ResultModel<WipInfo>> PutWipInfoUpdateByLineId([FromBody] WipInfo wipInfo)
        {
            ResultModel<WipInfo> result = new ResultModel<WipInfo>();
            wipInfo.UpdateDate = DateTime.Now;
            _context.Attach(wipInfo);
            // 指定更新某個欄位
            _context.Entry(wipInfo).Property(p => p.LineID).IsModified = true;
            _context.Entry(wipInfo).Property(p => p.UpdateDate).IsModified = true;

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


        /// <summary>
        /// 更新 By工單號碼 統一更新指定欄位
        /// </summary>
        /// <param name="wipInfo"></param>
        /// <returns></returns>
        [HttpPut("UpdateDesignate")]
        public async Task<ResultModel<WipInfo>> PutWipInfoDesignateByWipNo([FromBody] WipInfo wipInfo)
        {
            ResultModel<WipInfo> result = new ResultModel<WipInfo>();
            try
            {
                var query = @"  UPDATE JHAMES.WIP_INFO SET PLAN_QTY =:PlanQTY  ,-- 計劃數量
                                CUSTOMER_MEDICAL =:CustomerMedical  , --客戶類別醫療
                                CUSTOMER_VIP =:CustomerVIP , --客戶類別VIP
                                CUSTOMER_NO =:CustomerNO , --客戶名稱
                                CUSTOMER_ITEM_NO =:CustomerItemNO , --成品料號
                                CUSTOMER_WIPNO =:CustomerWipNo , --客戶工單
                                RELATED_WO_NO =:RelatedWONO , --關聯工單
                                ORDER_NO =:OrderNO , --客戶訂單
                                REMARKS =:Remarks ,-- 工單備註
                                FLOW_REMARK =:FlowRemark -- 流程備註
                                WHERE WIP_NO = :WipNO";
                await _context.Database.DapperExecuteAsync(query, wipInfo);
                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<WipInfo>> DeleteWipinfo(int id)
        {
            ResultModel<WipInfo> result = new ResultModel<WipInfo>();

            var wipinfos = await _context.WipInfos.Where(w => w.WipID == id).FirstOrDefaultAsync();
            var WiwipinfoByWipNo = await _context.WipInfos.Where(w => w.WipNO == wipinfos.WipNO).ToListAsync();
            _context.WipInfos.RemoveRange(wipinfos);

            var wipBarcode = await _context.WipBarcodes.Where(w => w.WipNO == wipinfos.WipNO && w.UnitNO == wipinfos.UnitNO).ToListAsync();
            _context.WipBarcodes.RemoveRange(wipBarcode);

            if (WiwipinfoByWipNo.Count() == 1)
            {
                var WipNo = WiwipinfoByWipNo.FirstOrDefault().WipNO;
                var wipAtt = await _context.WipAtts.Where(w => w.WipNO == WipNo).ToListAsync();
                _context.WipAtts.RemoveRange(wipAtt);

                var wipKp = await _context.WipKps.Where(w => w.WipNo == WipNo).ToListAsync();
                _context.WipKps.RemoveRange(wipKp);

                var wipSop = await _context.WipSops.Where(w => w.WipNo == WipNo).ToListAsync();
                _context.WipSops.RemoveRange(wipSop);

                var wipOutfit = await _context.WipOutfits.Where(w => w.WipNo == WipNo).ToListAsync();
                _context.WipOutfits.RemoveRange(wipOutfit);

                var wipLabel = await _context.WipLabels.Where(w => w.WipNO == WipNo).ToListAsync();
                _context.WipLabels.RemoveRange(wipLabel);

                var wipBarcodeOther = await _context.WipBarcodeOthers.Where(w => w.WipNO == WipNo).ToListAsync();
                _context.WipBarcodeOthers.RemoveRange(wipBarcodeOther);

                var wipBoard = await _context.WipBoards.Where(w => w.WipNo == WipNo).ToListAsync();
                _context.WipBoards.RemoveRange(wipBoard);

                var wipSystem = await _context.WipSystems.Where(w => w.WipNo == WipNo).ToListAsync();
                _context.WipSystems.RemoveRange(wipSystem);

                var wipChecks = await _context.WipChecks.Where(w => w.WipNo == WipNo).ToListAsync();
                _context.WipChecks.RemoveRange(wipChecks);

                var wipInfoBlob = await _context.WipInfoBlobs.Where(w => w.WipNo == WipNo).ToListAsync();
                _context.WipInfoBlobs.RemoveRange(wipInfoBlob);
            }
            try
            {
                await _context.SaveChangesAsync();
                result.Success = true;
                result.Msg = "OK";
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Msg = ex.InnerException.Message;
            }
            return result;

        }

    }
}