using AMESCoreStudio.CommonTools.Result;
using AMESCoreStudio.WebApi.Models.BAS;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;
using System;
using System.Net.Mail;
using Microsoft.Extensions.Configuration;
using System.Net;
using System.Linq;
using System.Text.RegularExpressions;
using System.IO;
using AMESCoreStudio.WebApi.Controllers.AMES;
using AMESCoreStudio.WebApi.DTO.AMES;
using System.Data;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using AMESCoreStudio.WebApi.Controllers.SYS;
using System.Data.Common;
using System.Collections.Generic;

namespace AMESCoreStudio.WebApi.Controllers.BLL
{
    /// <summary>
    /// 報表資料
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class RPTController : Controller
    {
        private readonly AMESContext _context;
        private readonly SMSContext _SMS_context;
        private readonly IConfiguration _config;

        /// <summary>
        /// 建構式
        /// </summary>
        /// <param name="context"></param>
        public RPTController(AMESContext context, IConfiguration config)
        {
            _config = config;
            _context = context;
        }

        /// <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="sDate">開始日期</param>
        /// <param name="eDate">結束日期</param>
        /// <returns></returns>
        [HttpGet("GetRPT001View")]
        public async Task<RPT001ViewDto> GetRPT001View(string sDate, string eDate)
        {
            if (string.IsNullOrWhiteSpace(sDate) || string.IsNullOrWhiteSpace(eDate))
            {
                sDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).ToString("yyyy/MM/dd");
                eDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month)).ToString("yyyy/MM/dd");
            }

            var result = new RPT001ViewDto();
            // 未結工單數
            var a = await new WipInfosController(_context).GetWipInfoPCS008(new DTO.AMES.WipInfoDto
            {
                date_str = sDate,
                date_end = eDate
            });
            result.openOrderWipQty = a.DataTotal;

            // 完工入庫數:GetFqcInhouseMasterMultiQuery
            var b = await new FqcInhouseMasterController(_context).GetFqcInhouseMasteMultiQuery("", "", "", "", date_str: sDate, date_end: eDate, "");
            result.finishedProducts = b.DataTotal;

            //異常工時:GetExceptionWorktime4RPT001
            var c = await new ExceptionWorktimesController(_context).GetExceptionWorktime4RPT001(sDate, eDate);
            decimal errorTime = 0;
            double errTime = 0.00;
            if (c.DataTotal > 0)
            {
                foreach (var item in c.Data)
                {
                    string str = item.ToString();
                    string[] str2 = str.Replace("{", "").Replace("}", "").Split(',');
                    string str3 = "";
                    for (int i = 0; i < str2.Length; i++)
                    {
                        string[] str21 = str2[i].Split("=");
                        str3 = str3 + str21[0].Trim() + ":" + "'" + str21[1].Trim() + "',";
                    }
                    JObject j1 = JObject.Parse("{" + str3.Substring(0, str3.Length - 1) + "}");
                    decimal time = decimal.Parse(j1["Time"].ToString());
                    errorTime = errorTime + time;
                }
                errTime = double.Parse(errorTime.ToString()) / 60.0;
            }
            result.abnormalTime = double.Parse(errTime.ToString("0.00"));

            //直通率:GetWipStation4QRS014GroupALL
            //2023-07-11 BB.Wang Modify 安勤 Jason反映只要查安勤產線即可
            //var d = await new WipStationController(_context).GetWipStation4QRS014GroupALL(null, sDate, eDate, null, null, null);
            var d = await new WipStationController(_context).GetWipStation4QRS014GroupALL(null, sDate, eDate, null, "YS00", null);
            if (d.DataTotal > 0)
            {
                double sum_rate = 100.0;
                int sum_idx = 1;

                DataTable dtRate = new DataTable();
                dtRate.Columns.Add("STATION_ID");
                dtRate.Columns.Add("OK_QTY");
                dtRate.Columns.Add("NG_QTY");
                dtRate.PrimaryKey = new DataColumn[] { dtRate.Columns[0] };
                dtRate.AcceptChanges();

                foreach (var data in d.Data)
                {
                    string str = data.ToString();
                    string[] str2 = str.Replace("{", "").Replace("}", "").Split(',');
                    string str3 = "";
                    for (int i = 0; i < str2.Length; i++)
                    {
                        string[] str21 = str2[i].Split("=");
                        str3 = str3 + str21[0].Trim() + ":" + "'" + str21[1].Trim() + "',";
                    }
                    JObject j0 = JObject.Parse("{" + str3.Substring(0, str3.Length - 1) + "}");
                    int stationID = int.Parse(j0["StationID"].ToString());

                    bool existFlag = false;
                    int idx = 0;

                    for (int i = 0; i < dtRate.Rows.Count; i++)
                    {
                        if (dtRate.Rows[i]["STATION_ID"].ToString() == stationID.ToString())
                        {
                            idx = i;
                            existFlag = true;
                            break;
                        }
                    }

                    int okQty = 0, ngQty = 0;

                    if (j0["RuleStatus"].ToString() == "P")
                    {
                        okQty = int.Parse(j0["FirstCnt"].ToString());
                    }
                    else
                    {
                        ngQty = int.Parse(j0["FirstCnt"].ToString());
                    }

                    if (existFlag)
                    {
                        if (okQty > 0)
                        {
                            dtRate.Rows[idx][1] = okQty;
                        }
                        if (ngQty > 0)
                        {
                            dtRate.Rows[idx][2] = ngQty;
                        }

                        dtRate.AcceptChanges();
                    }
                    else
                    {
                        DataRow dr = dtRate.NewRow();
                        dr[0] = stationID;
                        dr[1] = okQty;
                        dr[2] = ngQty;

                        dtRate.Rows.Add(dr);
                        dtRate.AcceptChanges();
                    }
                }

                if (dtRate.Rows.Count > 0)
                {
                    for (int j = 0; j < dtRate.Rows.Count; j++)
                    {
                        int okQty = int.Parse(dtRate.Rows[j][1].ToString());
                        int ngQty = int.Parse(dtRate.Rows[j][2].ToString());

                        int inputQty = okQty + ngQty;

                        double rate = 0;
                        if (okQty > 0)
                        {
                            rate = (okQty * 1.0 / inputQty) * 100;
                        }

                        if (rate > 0)
                        {
                            //sum_rate = sum_rate * (rate / 100.0);
                            sum_idx = sum_idx + 1;
                            sum_rate = sum_rate + rate;
                        }
                    }
                }
                result.test = double.Parse((sum_rate / sum_idx).ToString("0.00"));
            }
            else
            {
                result.test = 0.00;
            }

            //IPQC
            var e = await new InspectionResultMastersController(_context).GetIPQCHeaderData4QRS015(null, null, null, sDate, eDate);

            int sumIpqcCnt = 0, sumPassCnt = 0, sumFailCnt = 0;
            foreach (var item in e.Data)
            {
                string str = item.ToString();
                JObject jo = JObject.Parse(str.Replace("=", ":"));

                string ipqc_week = jo["IPQCWeek"].ToString();
                int ipqc_cnt = int.Parse(jo["IPQCCnt"].ToString());
                int pass_cnt = int.Parse(jo["PassCnt"].ToString());
                int fail_cnt = int.Parse(jo["FailCnt"].ToString());
                double ipqc_rate = pass_cnt * 100.0 / ipqc_cnt;
                sumIpqcCnt = sumIpqcCnt + ipqc_cnt;
                sumPassCnt = sumPassCnt + pass_cnt;
                sumFailCnt = sumFailCnt + fail_cnt;
            }
            double sum_ipqc_rate = 0.00;
            if (sumIpqcCnt > 0)
            {
                sum_ipqc_rate = sumPassCnt * 100.0 / sumIpqcCnt;
            }

            result.ipqc = double.Parse(sum_ipqc_rate.ToString("0.00"));


            //FQC
            //2023-07-11 BB.Wang Modify 安勤 Jason反映只要查安勤產線即可
            //var f = await new FqcResultMasterController(_context).GetFQCHeaderData4QRS016(null, null, null, sDate, eDate, null);
            var f = await new FqcResultMasterController(_context).GetFQCHeaderData4QRS016(null, null, null, sDate, eDate, "1001");
            if (f.DataTotal > 0)
            {
                int sumFqcCnt = 0, sumFqcPassCnt = 0, sumFqcFailCnt = 0;
                foreach (var item in f.Data)
                {
                    string str = item.ToString();
                    JObject jo = JObject.Parse(str.Replace("=", ":"));

                    string fqc_week = jo["FQCWeek"].ToString();
                    int fqc_cnt = int.Parse(jo["FQCCnt"].ToString());
                    int pass_cnt = int.Parse(jo["PassCnt"].ToString());
                    int fail_cnt = int.Parse(jo["FailCnt"].ToString());
                    double fqc_rate = pass_cnt * 100.0 / fqc_cnt;

                    sumFqcCnt = sumFqcCnt + fqc_cnt;
                    sumFqcPassCnt = sumFqcPassCnt + pass_cnt;
                }
                double sum_fqc_rate = 0.00;
                if (sumFqcCnt > 0)
                {
                    sum_fqc_rate = sumFqcPassCnt * 100.0 / sumFqcCnt;
                }
                result.fqc = double.Parse(sum_fqc_rate.ToString("0.00"));
            }

            #region
            /*
            //应出勤人数
            var ea = await new UserInfoesController(_context).GetUserData4EA();
            int eaTime = ea.DataTotal * 8;

            var g = await new WorkManPowersController(_context).GetWorkManPower4RPT001(sDate, eDate);
            double sumAATime = 0.00, sumOverTime = 0.00;
            double aaRate = 0.00;

            if (g.DataTotal > 0)
            {
                foreach (var item in g.Data)
                {
                    //string str = item.ToString();
                    //JObject jo = JObject.Parse(str.Replace("=", ":"));

                    string str = item.ToString();
                    string[] str2 = str.Replace("{", "").Replace("}", "").Split(',');
                    string str3 = "";
                    for (int i = 0; i < str2.Length; i++)
                    {
                        string[] str21 = str2[i].Split("=");
                        str3 = str3 + str21[0].Trim() + ":" + "'" + str21[1].Trim() + "',";
                    }
                    JObject jo = JObject.Parse("{" + str3.Substring(0, str3.Length - 1) + "}");

                    double aa_time = double.Parse(jo["FactWorkH"].ToString());
                    double over_time = double.Parse(jo["OvarH"].ToString());

                    sumAATime = sumAATime + aa_time;
                    sumOverTime = sumOverTime + over_time;

                }

                if (eaTime > 0)
                {
                    aaRate = sumAATime * 100.0 / (eaTime * g.DataTotal);
                }
            }

            //出勤率
            result.attendance = double.Parse(aaRate.ToString("0.00"));
            //加班工时
            result.overtime = double.Parse(sumOverTime.ToString("0.00"));

            //异常工时
            var h = await new ExceptionWorktimesController(_context).GetExceptionWorktime4RPT001(sDate, eDate);
            double sumExceptionTime = 0.00;
            if (h.DataTotal > 0)
            {
                foreach (var item in h.Data)
                {
                    string str = item.ToString();
                    string[] str2 = str.Replace("{", "").Replace("}", "").Split(',');
                    string str3 = "";
                    for (int i = 0; i < str2.Length; i++)
                    {
                        string[] str21 = str2[i].Split("=");
                        str3 = str3 + str21[0].Trim() + ":" + "'" + str21[1].Trim() + "',";
                    }
                    JObject jo = JObject.Parse("{" + str3.Substring(0, str3.Length - 1) + "}");

                    double exception_time = double.Parse(jo["Time"].ToString());

                    sumExceptionTime = sumExceptionTime + exception_time;
                }
            }

            result.abnormalTime = double.Parse((sumExceptionTime / 60.0).ToString("0.00"));
            */
            #endregion

            var pi = await new ProductionIndexesController(_context).GetProductionIndex4RPT001(sDate, eDate);

            int sumPI_EA = 0;
            double sumPI_EATime = 0.00, sumPI_AATime = 0.00, sumPI_InvalidTIme = 0.00, sumPI_OverTime = 0.00, sumPI_ActualTime = 0.00;
            double PI_Attendance = 0.00, PI_Efficiency = 0.00, PI_Productivity = 0.00;
            double attendance = 0.00, efficiency = 0.00, productivity = 0.00;

            if (pi.DataTotal > 0)
            {
                foreach (var item in pi.Data)
                {
                    string str = item.ToString();
                    string[] str2 = str.Replace("{", "").Replace("}", "").Split(',');
                    string str3 = "";

                    for (int i = 0; i < str2.Length; i++)
                    {
                        string[] str21 = str2[i].Split("=");
                        str3 = str3 + str21[0].Trim() + ":" + "'" + str21[1].Trim() + "',";
                    }
                    JObject jo = JObject.Parse("{" + str3.Substring(0, str3.Length - 1) + "}");

                    int pi_ea = int.Parse(jo["EA"].ToString());
                    double pi_eatime = double.Parse(jo["EATime"].ToString());
                    double pi_aatime = double.Parse(jo["AATime"].ToString());
                    double pi_overtime = double.Parse(jo["OverTime"].ToString());
                    double pi_invalidtime = double.Parse(jo["InvalidTime"].ToString());
                    double pi_actualtime = double.Parse(jo["ActualTime"].ToString());
                    double pi_efficiency = double.Parse(jo["Efficiency"].ToString());
                    double pi_productivity = double.Parse(jo["Productivity"].ToString());
                    double pi_attendance = double.Parse(jo["Attendance"].ToString());

                    sumPI_EA = sumPI_EA + pi_ea;
                    sumPI_EATime = sumPI_EATime + pi_eatime;
                    sumPI_AATime = sumPI_AATime + pi_aatime;
                    sumPI_InvalidTIme = sumPI_InvalidTIme + pi_invalidtime;
                    sumPI_OverTime = sumPI_OverTime + pi_overtime;
                    sumPI_ActualTime = sumPI_ActualTime + pi_actualtime;

                    PI_Attendance = PI_Attendance + pi_attendance;
                    PI_Efficiency = PI_Efficiency + pi_efficiency;
                    PI_Productivity = PI_Productivity + pi_productivity;
                }

                if (PI_Attendance > 0)
                {
                    attendance = PI_Attendance / (pi.DataTotal * 1.0);
                }
                if (PI_Efficiency > 0)
                {
                    efficiency = PI_Efficiency / (pi.DataTotal * 1.0);
                }
                if (PI_Productivity > 0)
                {
                    productivity = PI_Productivity / (pi.DataTotal * 1.0);
                }
            }

            result.productivity = double.Parse(efficiency.ToString("0.00"));
            result.attendance = double.Parse(attendance.ToString("0.00"));
            result.productiveForces = double.Parse(productivity.ToString("0.00"));

            result.overtime = double.Parse(sumPI_OverTime.ToString("0.00"));
            result.invalidHours = double.Parse(sumPI_InvalidTIme.ToString("0.00"));

            return result;
        }

        private (int iIPQC_Fail_Total,int iIPQC_Fail) Get_IPQC_Rate(string sDate, string eDate)
        {
            var e = new InspectionResultMastersController(_context).GetIPQCHeaderData4QRS015(null, null, null, sDate, eDate);

            int sumIpqcCnt = 0, sumPassCnt = 0, sumFailCnt = 0;
            foreach (var item in e.Result.Data)
            {
                string str = item.ToString();
                JObject jo = JObject.Parse(str.Replace("=", ":"));

                string ipqc_week = jo["IPQCWeek"].ToString();
                int ipqc_cnt = int.Parse(jo["IPQCCnt"].ToString());
                int pass_cnt = int.Parse(jo["PassCnt"].ToString());
                int fail_cnt = int.Parse(jo["FailCnt"].ToString());
                double ipqc_rate = pass_cnt * 100.0 / ipqc_cnt;
                sumIpqcCnt = sumIpqcCnt + ipqc_cnt;
                sumPassCnt = sumPassCnt + pass_cnt;
                sumFailCnt = sumFailCnt + fail_cnt;
            }

            return (sumFailCnt, sumFailCnt);
        }

        private async Task<string> Get_QC_Rate(string C_YEAR, string C_MONTH, string sQC_RATE_TYPE)
        {
            DbConnection conn = _context.Database.GetDbConnection();
            if (conn.State != ConnectionState.Open)
            {
                await conn.OpenAsync();
            }

            string sMS_SQL = @" SELECT YRER, MONTH, QC_RATE_TYPE, PRODUCT_TYPE, QC_RATE, CREATE_DATE, CREATE_USERID, UPDATE_DATE, UPDATE_USERID";
            sMS_SQL = sMS_SQL + " FROM JHAMES.QC_RATE";
            sMS_SQL = sMS_SQL + " WHERE YRER = '" + C_YEAR + "'";
            sMS_SQL = sMS_SQL + " AND MONTH = '" + C_MONTH + "'";
            sMS_SQL = sMS_SQL + " AND QC_RATE_TYPE = '" + sQC_RATE_TYPE + "'";

            using (var AMES_cmd = conn.CreateCommand())
            {
                AMES_cmd.CommandText = sMS_SQL;
                AMES_cmd.CommandTimeout = 0;

                using (var AMES_reader = await AMES_cmd.ExecuteReaderAsync())
                {
                    if (AMES_reader.HasRows)
                    {
                        List<dynamic> list = new List<dynamic>();
                        DataTable dtAMES_TB = new DataTable();

                        dtAMES_TB = DataReaderToDataTable(AMES_reader);

                        if (dtAMES_TB.Rows.Count > 0)
                        {
                            var dRate_P = dtAMES_TB.Select("PRODUCT_TYPE = 'BOARD'")[0]["QC_RATE"].ToString();
                            var dRate_S = dtAMES_TB.Select("PRODUCT_TYPE = 'SYSTEM'")[0]["QC_RATE"].ToString();
                            var dRate_M = dtAMES_TB.Select("PRODUCT_TYPE = 'MEDICAL'")[0]["QC_RATE"].ToString();

                            if (dRate_P.ToString().Equals(""))
                            { return "0|0|0"; }
                            else
                            { return dRate_P + "|" + dRate_S + "|" + dRate_M; }

                        }
                    }
                    return "0|0|0"; ;
                }
            }
        }

        /// <summary>
        /// IOQ進料檢驗
        /// </summary>
        /// <param name="MEDICAL">醫療產品""、Y、N</param>
        /// <param name="C_YEAR">年</param>
        /// <param name="C_MONTH">月</param>
        /// <param name="PARTTYPE">電子或機構</param>
        /// <returns></returns>
        private async Task<double> Get_IQC_Rate(string MEDICAL, string C_YEAR,string C_MONTH, string PARTTYPE)
        {
            #region IQC進料批退       
            SMSContext _SMS_context = new SMSContext();

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

            string sMS_SQL = @" SELECT N1.THE_YEAR C_YEAR,N1.MONTH_OF_YEAR C_MONTH,M1.MEDICAL,M1.PARTTYPE,M1.NG_QTY,M1.TOTAL_QTY,M1.NG_RATE";
            sMS_SQL = sMS_SQL + " FROM (SELECT DISTINCT THE_YEAR,MONTH_OF_YEAR FROM  Calendar WHERE the_year= '" + C_YEAR + "') N1 ";
            sMS_SQL = sMS_SQL + " LEFT JOIN";
            sMS_SQL = sMS_SQL + " (";
            sMS_SQL = sMS_SQL + " SELECT M.C_YEAR,M.C_MONTH,'" + MEDICAL + "' MEDICAL,'" + PARTTYPE + "' PARTTYPE,SUM(M.NG_LOT) NG_QTY,SUM(M.TOTAL_LOT) TOTAL_QTY";
            sMS_SQL = sMS_SQL + " ,round((SUM(convert(float,M.NG_LOT))/SUM(convert(float,M.TOTAL_LOT))) *100,2) NG_RATE";
            sMS_SQL = sMS_SQL + " FROM (";
            sMS_SQL = sMS_SQL + " SELECT  PARTTYPE,MEDICAL,C_YEAR,C_MONTH,POSTDATE";
            sMS_SQL = sMS_SQL + " ,(CASE WHEN VD_CODE='R' THEN 1 ELSE 0 END) NG_LOT";
            sMS_SQL = sMS_SQL + " ,(CASE WHEN VD_CODE<>'' THEN 1 ELSE 0 END) TOTAL_LOT";
            sMS_SQL = sMS_SQL + " FROM  [dbo].[INSLOT]";
            sMS_SQL = sMS_SQL + " WHERE POSTDATE IS NOT NULL";
            sMS_SQL = sMS_SQL + " AND PARTTYPE = " + "'" + PARTTYPE + "'";
            //sMS_SQL = sMS_SQL + " AND POSTDATE BETWEEN '" + sDate + "' AND '" + eDate + "'";
            sMS_SQL = sMS_SQL + " AND C_YEAR = '" + C_YEAR + "'";
            sMS_SQL = sMS_SQL + " ) M";
            sMS_SQL = sMS_SQL + " GROUP BY M.C_YEAR,M.C_MONTH";
            sMS_SQL = sMS_SQL + " )M1";
            sMS_SQL = sMS_SQL + " ON N1.THE_YEAR = M1.C_YEAR AND N1.MONTH_OF_YEAR=M1.C_MONTH";

            using (var SMS_cmd = conn.CreateCommand())
            {
                SMS_cmd.CommandText = sMS_SQL;
                SMS_cmd.CommandTimeout = 0;

                using (var SMS_reader = await SMS_cmd.ExecuteReaderAsync())
                {
                    if (SMS_reader.HasRows)
                    {
                        List<dynamic> list = new List<dynamic>();
                        DataTable dtSMS_TB = new DataTable();

                        dtSMS_TB = DataReaderToDataTable(SMS_reader);

                        if (dtSMS_TB.Rows.Count > 0)
                        {
                            var dRate = dtSMS_TB.Select("C_MONTH='" + C_MONTH + "'")[0]["NG_RATE"];

                            if (dRate.ToString().Equals(""))
                            { return 0.0; }
                            else
                            { return double.Parse(dRate.ToString()); }

                        }
                    }
                    return 0.0;
                }
            }
            #endregion
        }

        private async Task<string> Get_QRC_Rate(int nCarTypeID, string C_YEAR, string C_MONTH, string PRODUCT_TYPE_ID)
        {
            #region QRC單       
            SMSContext _SMS_context = new SMSContext();

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

            string sMS_SQL = @" SELECT M1.THE_YEAR,M1.THE_MONTH,M1.MONTH_OF_YEAR,ISNULL(M2.QTY, 0) FLAG_3,ISNULL(M3.QTY, 0) FLAG_4";
            sMS_SQL += " FROM";
            sMS_SQL += " (";
            sMS_SQL += " SELECT DISTINCT A.THE_YEAR, A.THE_MONTH, A.MONTH_OF_YEAR";
            sMS_SQL += " FROM CALENDAR A";
            sMS_SQL += " WHERE A.THE_YEAR = '" + C_YEAR + "'";
            sMS_SQL += " )M1 LEFT JOIN";  //開單總數:狀態為OPEN、TBC、TBC - C、TBC - R、CLOSE(NA不算),開單日為當月ISSUE_DATE,且立案否為Y)
            sMS_SQL += " (SELECT B.THE_YEAR,B.MONTH_OF_YEAR,'' GROUPNAME,'開單總數' CATEGORY,3 SEQ_FLAG,COUNT(A.CAR_NUMBER) QTY";
            sMS_SQL += " FROM  CORRECTIVE_ACTION_REPORT A, CALENDAR B,CAR_TYPE C";
            sMS_SQL += " WHERE CONVERT(VARCHAR(20),A.ISSUE_DATE,23)= CONVERT(VARCHAR(20), B.THE_DATE, 23)";
            sMS_SQL += " AND A.CAR_TYPE_ID = C.CAR_TYPE_ID";
            sMS_SQL += " AND C.CAR_CLASS = 'SCAR'";
            sMS_SQL += " AND A.CAR_TYPE_ID = 102";
            sMS_SQL += " AND A.ESTABLISHED = 'Y'";
            if (!PRODUCT_TYPE_ID.Equals(""))
            {
                sMS_SQL += " AND A.PRODUCT_TYPE_ID IN(" + PRODUCT_TYPE_ID + ")";
            }
            sMS_SQL += " AND A.STATUS IN ('OPEN', 'TBC', 'TBC-C', 'TBC-R', 'CLOSE')";
            sMS_SQL += " AND DATEPART(YYYY, A.ISSUE_DATE) = '" + C_YEAR + "'";
            sMS_SQL += " GROUP BY  B.THE_YEAR,B.MONTH_OF_YEAR";
            sMS_SQL += " )M2 ON M1.THE_YEAR = M2.THE_YEAR AND M1.MONTH_OF_YEAR = M2.MONTH_OF_YEAR";
            sMS_SQL += " LEFT JOIN";  //未結件數:狀態為OPEN、TBC - C、TBC - R,開單日為當月ISSUE_DATE,且立案否為Y
            sMS_SQL += " (SELECT B.THE_YEAR, B.MONTH_OF_YEAR, '' GROUPNAME, '未結件數' CATEGORY, 4 SEQ_FLAG, COUNT(A.CAR_NUMBER) QTY";
            sMS_SQL += " FROM CORRECTIVE_ACTION_REPORT A, CALENDAR B, CAR_TYPE C";
            sMS_SQL += " WHERE CONVERT(VARCHAR(20), A.ISSUE_DATE, 23) = CONVERT(VARCHAR(20), B.THE_DATE, 23)";
            sMS_SQL += " AND A.CAR_TYPE_ID = C.CAR_TYPE_ID";
            sMS_SQL += " AND C.CAR_CLASS = 'SCAR'";
            sMS_SQL += " AND A.CAR_TYPE_ID = 102";
            sMS_SQL += " AND A.ESTABLISHED = 'Y'";
            sMS_SQL += " AND A.STATUS IN ('OPEN', 'TBC-C', 'TBC-R')";
            if (!PRODUCT_TYPE_ID.Equals(""))
            {
                sMS_SQL += " AND A.PRODUCT_TYPE_ID IN(" + PRODUCT_TYPE_ID + ")";
            }
            sMS_SQL += " AND DATEPART(YYYY, A.ISSUE_DATE) = '" + C_YEAR + "'";
            sMS_SQL += " GROUP BY  B.THE_YEAR,B.MONTH_OF_YEAR";
            sMS_SQL += " )M3 ON  M1.THE_YEAR = M3.THE_YEAR AND M1.MONTH_OF_YEAR = M3.MONTH_OF_YEAR";

            using (var SMS_cmd = conn.CreateCommand())
            {
                SMS_cmd.CommandText = sMS_SQL;
                SMS_cmd.CommandTimeout = 0;

                using (var SMS_reader = await SMS_cmd.ExecuteReaderAsync())
                {
                    if (SMS_reader.HasRows)
                    {
                        List<dynamic> list = new List<dynamic>();
                        DataTable dtSMS_TB = new DataTable();

                        dtSMS_TB = DataReaderToDataTable(SMS_reader);

                        if (dtSMS_TB.Rows.Count > 0)
                        {
                            var dRate1 = dtSMS_TB.Select("MONTH_OF_YEAR='" + C_MONTH + "'")[0]["FLAG_3"];
                            var dRate2 = dtSMS_TB.Select("MONTH_OF_YEAR='" + C_MONTH + "'")[0]["FLAG_4"];

                            int iTotal = 0;
                            for(int i= 1; i<=12; i++)
                            {
                                iTotal = iTotal + int.Parse(dtSMS_TB.Select("MONTH_OF_YEAR='" + i.ToString() + "'")[0]["FLAG_3"].ToString());
                            }

                            var dRate = dRate1 + "|" + dRate2 + "|" + iTotal.ToString();

                            if (dRate.ToString().Equals(""))
                            { return "0|0|0"; }
                            else
                            { return dRate.ToString(); }

                        }
                    }
                    return "0|0|0";
                }
            }
            #endregion
        }

        private async Task<string> Get_CFQR_Rate(string sCarTypeID, string C_YEAR, string C_MONTH, string PRODUCT_TYPE_ID)
        {
            #region CFQR單       
            SMSContext _SMS_context = new SMSContext();

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

            string sMS_SQL = @" SELECT N1.C_YEAR,N1.C_MONTH,N1.FLAG_DESC,N1.FLAG_SEQ,ISNULL(N2.QTY,0) QTY";
            sMS_SQL += " FROM";
            sMS_SQL += " (";
            sMS_SQL += " SELECT DISTINCT THE_YEAR C_YEAR,MONTH_OF_YEAR C_MONTH,CAST(A.THE_YEAR AS VARCHAR(4)) +' ' + C.FLAG_DESC FLAG_DESC,C.FLAG_SEQ";
            sMS_SQL += " FROM  CALENDAR A,";
            sMS_SQL += " ( SELECT '立案單總數' FLAG_DESC ,3 FLAG_SEQ";
            sMS_SQL += " UNION SELECT '總開單數' FLAG_DESC ,3.1 FLAG_SEQ";
            sMS_SQL += " UNION SELECT 'ONTIMECLOSERATE %' FLAG_DESC, 4 FLAG_SEQ) C";
            sMS_SQL += " WHERE A.THE_YEAR = " + C_YEAR;
            sMS_SQL += " )N1";
            sMS_SQL += " LEFT JOIN";
            sMS_SQL += " (";
            sMS_SQL += " SELECT M.C_YEAR,M.C_MONTH,'立案單總數' FLAG_DESC,3 FLAG_SEQ,COUNT(M.CAR_NUMBER) QTY";
            sMS_SQL += " FROM (";
            sMS_SQL += " SELECT DATEPART(YYYY, A.ISSUE_DATE) C_YEAR,DATEPART(MM, A.ISSUE_DATE) C_MONTH,A.CAR_NUMBER,A.STATUS";
            sMS_SQL += " from  CORRECTIVE_ACTION_REPORT A";
            sMS_SQL += " where A.CAR_TYPE_ID = " + sCarTypeID;  //--CFQR
            sMS_SQL += " AND A.PRODUCT_TYPE_ID IN (" + PRODUCT_TYPE_ID + ")";  // --103:PCBA 104:System 101:Medical	
            sMS_SQL += " AND A.ESTABLISHED='Y'";  //--已经立案
            sMS_SQL += " AND DATEPART(YYYY, A.ISSUE_DATE) = " + C_YEAR;
            sMS_SQL += "  ) M";
            sMS_SQL += " GROUP BY M.C_YEAR,M.C_MONTH";
            sMS_SQL += " UNION ";
            sMS_SQL += " SELECT M.C_YEAR,M.C_MONTH,'總開單數' FLAG_DESC,3.1 FLAG_SEQ,COUNT(M.CAR_NUMBER) QTY";  //總開單數
            sMS_SQL += " FROM (";
            sMS_SQL += " SELECT DATEPART(YYYY, A.ISSUE_DATE) C_YEAR,DATEPART(MM, A.ISSUE_DATE) C_MONTH,A.CAR_NUMBER,A.STATUS";
            sMS_SQL += " from  CORRECTIVE_ACTION_REPORT A";
            sMS_SQL += " where A.CAR_TYPE_ID = " + sCarTypeID;  //--CFQR
            sMS_SQL += " AND A.PRODUCT_TYPE_ID IN (" + PRODUCT_TYPE_ID + ")";  // --103:PCBA 104:System 101:Medical	       
            sMS_SQL += " AND DATEPART(YYYY, A.ISSUE_DATE) = " + C_YEAR;
            sMS_SQL += "  ) M";
            sMS_SQL += " GROUP BY M.C_YEAR,M.C_MONTH";
            sMS_SQL += " UNION ";
            sMS_SQL += " SELECT M1.C_YEAR,M1.C_MONTH,'OnTimeCloseRate' FLAG_DESC, 4 FLAG_SEQ ";            
            sMS_SQL += " ,(CASE WHEN M1.Sub_Total_Qty >0 THEN  cast(round(ISNULL(M2.Less_Days_Qty,0)*100.0/M1.Sub_Total_Qty,0) as int) ELSE 0 END) Rate"; //四舍五入取整           
            sMS_SQL += " FROM ";
            sMS_SQL += " ( SELECT M.C_YEAR,M.C_MONTH,COUNT(M.CAR_NUMBER) Sub_Total_Qty";
            sMS_SQL += " FROM (";
            sMS_SQL += " SELECT A.PRODUCT_TYPE_ID,DATEPART(YYYY, A.ISSUE_DATE) C_YEAR,DATEPART(MM, A.ISSUE_DATE) C_MONTH,A.CAR_NUMBER,A.STATUS";
            sMS_SQL += " from  CORRECTIVE_ACTION_REPORT A";
            sMS_SQL += " where A.CAR_TYPE_ID = " + sCarTypeID; // --CFQR
            sMS_SQL += " AND A.PRODUCT_TYPE_ID IN (" + PRODUCT_TYPE_ID + ")";  // --103:PCBA 104:System 101:Medical
            sMS_SQL += " AND A.ESTABLISHED='Y'";  //--已经立案
            sMS_SQL += " AND DATEPART(YYYY, A.ISSUE_DATE) = " + C_YEAR;
            sMS_SQL += " ) M";
            sMS_SQL += " GROUP BY M.C_YEAR,M.C_MONTH";
            sMS_SQL += " ) M1 LEFT JOIN ";
            sMS_SQL += " (";
            sMS_SQL += " SELECT M.C_YEAR,M.C_MONTH,COUNT(CAR_NUMBER) Less_Days_Qty";
            sMS_SQL += " FROM ";
            sMS_SQL += " (select A.CAR_NUMBER,DATEPART(YYYY, A.ISSUE_DATE) C_YEAR,DATEPART(MM, A.ISSUE_DATE) C_MONTH ,A.ISSUE_DATE,A.TRACK_DATETIME,";
            sMS_SQL += " (CASE WHEN A.OPEN_DATETIME IS NOT NULL THEN (CASE WHEN TRACK_DATETIME IS NOT NULL THEN datediff(day,A.OPEN_DATETIME,A.TRACK_DATETIME) ELSE datediff(day,A.OPEN_DATETIME,getdate()) END) ELSE 0 END)  ISSUE_DAYS";
            sMS_SQL += " from  CORRECTIVE_ACTION_REPORT A,PRODUCT_TYPE B";
            sMS_SQL += " where A.PRODUCT_TYPE_ID=B.PRODUCT_TYPE_ID";
            sMS_SQL += " AND A.CAR_TYPE_ID = " + sCarTypeID;  //--CFQR
            sMS_SQL += " AND A.PRODUCT_TYPE_ID IN (" + PRODUCT_TYPE_ID + ") ";  //--103:PCBA 104:System 101:Medical
            sMS_SQL += " AND A.OPEN_DATETIME IS NOT NULL ";  // --TRACK_DATETIME表示已经定案
            sMS_SQL += " AND DATEPART(YYYY, A.ISSUE_DATE) = " + C_YEAR;
            sMS_SQL += "  )M";
            sMS_SQL += " WHERE M.ISSUE_DAYS <=21";
            sMS_SQL += " GROUP BY M.C_YEAR,M.C_MONTH";
            sMS_SQL += " )M2  ON  M1.C_YEAR=M2.C_YEAR  AND M1.C_MONTH=M2.C_MONTH ";
            sMS_SQL += " )N2";
            sMS_SQL += " ON N1.C_YEAR = N2.C_YEAR AND N1.C_MONTH=N2.C_MONTH AND N1.FLAG_SEQ = N2.FLAG_SEQ";
            sMS_SQL += " WHERE N1.FLAG_DESC = '" + C_YEAR + " 總開單數'";

            using (var SMS_cmd = conn.CreateCommand())
            {
                SMS_cmd.CommandText = sMS_SQL;
                SMS_cmd.CommandTimeout = 0;

                using (var SMS_reader = await SMS_cmd.ExecuteReaderAsync())
                {
                    if (SMS_reader.HasRows)
                    {
                        List<dynamic> list = new List<dynamic>();
                        DataTable dtSMS_TB = new DataTable();

                        dtSMS_TB = DataReaderToDataTable(SMS_reader);

                        if (dtSMS_TB.Rows.Count > 0)
                        {
                            var dRate1 = dtSMS_TB.Select("C_MONTH='" + C_MONTH + "'")[0]["QTY"];
                            var dRate2 = await Get_CFQR_UnFinished_Rate(sCarTypeID, C_YEAR, C_MONTH, PRODUCT_TYPE_ID);

                            int iTotal = 0;
                            for (int i = 1; i <= 12; i++)
                            {
                                iTotal = iTotal + int.Parse(dtSMS_TB.Select("C_MONTH='" + i.ToString() + "'")[0]["QTY"].ToString());
                            }

                            var dRate = dRate1 + "|" + dRate2 + "|" + iTotal.ToString();

                            if (dRate.ToString().Equals(""))
                            { return "0|0|0"; }
                            else
                            { return dRate.ToString(); }

                        }
                    }
                    return "0|0|0";
                }
            }
            #endregion
        }

        private async Task<string> Get_CFQR_UnFinished_Rate(string sCarTypeID, string C_YEAR, string C_MONTH, string PRODUCT_TYPE_ID)
        {
            #region CFQR 未結單       
            SMSContext _SMS_context = new SMSContext();

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

            string sMS_SQL = @" with t as (";
            sMS_SQL = sMS_SQL + " select m1.the_year,m1.month_of_year,m1.Category,m1.FLAG_SEQ,sum(ISNULL(m2.qty,0)) total_qty";
            sMS_SQL = sMS_SQL + " from ";
            sMS_SQL = sMS_SQL + " (";
            sMS_SQL = sMS_SQL + " select distinct a.the_year, a.month_of_year,'總未結件數' Category,4 FLAG_SEQ";
            sMS_SQL = sMS_SQL + " from Calendar a,PRODUCT_TYPE b";
            sMS_SQL = sMS_SQL + " where a.the_date BETWEEN  '" + C_YEAR + "0101' AND '" + C_YEAR + "1231'";
            sMS_SQL = sMS_SQL + " and b.PRODUCT_TYPE_ID IN (" + PRODUCT_TYPE_ID + ") ";
            sMS_SQL = sMS_SQL + " ) m1 left join ";
            sMS_SQL = sMS_SQL + " (";
            sMS_SQL = sMS_SQL + " select b.the_year,b.month_of_year,'總未結件數' Category,count(a.CAR_NUMBER) qty, 4 FLAG_SEQ";
            sMS_SQL = sMS_SQL + " from  CORRECTIVE_ACTION_REPORT a,Calendar b,PRODUCT_TYPE c";
            sMS_SQL = sMS_SQL + " WHERE convert(varchar(20),a.issue_date,23)=convert(varchar(20),b.the_date,23)";
            sMS_SQL = sMS_SQL + " AND A.PRODUCT_TYPE_ID=C.PRODUCT_TYPE_ID";
            sMS_SQL = sMS_SQL + " AND A.CAR_TYPE_ID = " + sCarTypeID;
            sMS_SQL = sMS_SQL + " AND A.PRODUCT_TYPE_ID IN (" + PRODUCT_TYPE_ID + ") ";
            sMS_SQL = sMS_SQL + " AND ESTABLISHED = 'Y' ";
            sMS_SQL = sMS_SQL + " AND STATUS in ('OPEN','TBC','TBC-R') ";
            sMS_SQL = sMS_SQL + " AND ISSUE_DATE BETWEEN  '" + C_YEAR + "0101' AND '" + C_YEAR + "1231'";
            sMS_SQL = sMS_SQL + " group by  b.the_year,b.month_of_year,c.PRODUCT_ST";
            sMS_SQL = sMS_SQL + " )m2 on  m1.the_year= m2.the_year and m1.month_of_year=m2.month_of_year and m1.FLAG_SEQ=m2.FLAG_SEQ";
            sMS_SQL = sMS_SQL + " group by m1.the_year,m1.month_of_year,m1.Category, m1.FLAG_SEQ";
            sMS_SQL = sMS_SQL + " )";
            sMS_SQL = sMS_SQL + " select t1.the_year,t1.month_of_year,t1.Category, t1.FLAG_SEQ,sum(t2.total_qty) total_qty";
            sMS_SQL = sMS_SQL + " from t as t1, t  as t2";
            sMS_SQL = sMS_SQL + " where t1.the_year = t2.the_year";
            sMS_SQL = sMS_SQL + " and t1.FLAG_SEQ = t2.FLAG_SEQ";
            sMS_SQL = sMS_SQL + " and t2.month_of_year<=t1.month_of_year";
            sMS_SQL = sMS_SQL + " and t1.THE_YEAR = '" + C_YEAR + "'";
            sMS_SQL = sMS_SQL + " GROUP BY t1.the_year,t1.Category,t1.FLAG_SEQ,t1.month_of_year";

            using (var SMS_cmd = conn.CreateCommand())
            {
                SMS_cmd.CommandText = sMS_SQL;
                SMS_cmd.CommandTimeout = 0;

                using (var SMS_reader = await SMS_cmd.ExecuteReaderAsync())
                {
                    if (SMS_reader.HasRows)
                    {
                        List<dynamic> list = new List<dynamic>();
                        DataTable dtSMS_TB = new DataTable();

                        dtSMS_TB = DataReaderToDataTable(SMS_reader);

                        if (dtSMS_TB.Rows.Count > 0)
                        {
                            var dRate = dtSMS_TB.Select("month_of_year='" + C_MONTH + "'")[0]["total_qty"];

                            if (dRate.ToString().Equals(""))
                            { return "0"; }
                            else
                            { return dRate.ToString(); }

                        }
                    }
                    return "0";
                }
            }
            #endregion
        }

        /// <summary>
        /// 品質看板
        /// </summary>
        /// <param name="sDate">開始日期</param>
        /// <param name="eDate">結束日期</param>
        /// <returns></returns>
        [HttpGet("GetRPT002View")]
        public async Task<RPT002ViewDto> GetRPT002View(string sDate, string eDate)
        {
            if (string.IsNullOrWhiteSpace(sDate) || string.IsNullOrWhiteSpace(eDate))
            {
                sDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).ToString("yyyy/MM/dd");
                eDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month)).ToString("yyyy/MM/dd");
            }

            var result = new RPT002ViewDto();

            var vYear = DateTime.Parse(sDate).Year;
            var vMonth = DateTime.Parse(sDate).Month;

            // 進料批退率 電子
            //result.IQLRR_EE = 0.84;
            #region
            result.IQLRR_EE = await Get_IQC_Rate("", vYear.ToString(), vMonth.ToString(), "E");
            #endregion

            // 進料批退率 機構
            //result.IQLRR_ME = 0.06;
            #region
            result.IQLRR_ME = await Get_IQC_Rate("", vYear.ToString(), vMonth.ToString(), "M");
            #endregion

            // 線上材料品質
            result.LQC = 0.00;

            // QRC件數 新增筆數
            //result.QRCNew = 4;
            #region
            string sReturn_Data = await Get_QRC_Rate(102, vYear.ToString(), vMonth.ToString(), "");
            string[] sData_Ary = sReturn_Data.Split("|");
            result.QRCNew = int.Parse(sData_Ary[0].ToString());
            #endregion

            // QRC件數 結案筆數
            //result.QRCClose = 2;
            result.QRCClose = int.Parse(sData_Ary[1].ToString());

            // QRC件數 總筆數
            //result.QRCTotal = 6;
            result.QRCTotal = int.Parse(sData_Ary[2].ToString());

            //IPQC異常件數 新增筆數
            //result.IPQCNew = 10;
            var vIPQCNew = Get_IPQC_Rate(sDate, eDate);
            result.IPQCNew = vIPQCNew.iIPQC_Fail;

            // IPQC異常件數 結案筆數
            result.IPQCClose = 0;

            // IPQC異常件數 總筆數
            //result.IPQCTotal = 12;
            var vIPQCTotal = Get_IPQC_Rate(vYear.ToString() + "/01/01", vYear.ToString() + "/12/31");
            result.IPQCTotal = vIPQCTotal.iIPQC_Fail_Total;

            // FQC批退率 Board
            #region 批退率 Board
            //result.FQCRRBoard = 5.08;
            var f_FQCRRBoard = await new FqcResultMasterController(_context).GetFQCHeaderData4QRS016ByDetail(null, null, null, sDate, eDate, "1001");
            if (f_FQCRRBoard.DataTotal > 0)
            {
                foreach (var item in f_FQCRRBoard.Data.Where(W => W.type == "單板"))
                {
                    result.FQCRRBoard = item.rejectRate;
                }
            }
            #endregion

            // FQC批退率 System
            #region 批退率 System
            //result.FQCRRSystem = 12.12;
            var f_FQCRRSystem = await new FqcResultMasterController(_context).GetFQCHeaderData4QRS016ByDetail(null, null, null, sDate, eDate, "1001");
            if (f_FQCRRSystem.DataTotal > 0)
            {
                foreach (var item in f_FQCRRSystem.Data.Where(W => W.type == "系統組裝"))
                {
                    result.FQCRRSystem = item.rejectRate;
                }
            }
            #endregion

            // FQC批退率 Medical
            #region 批退率 Medical
            //result.FQCRRMedical = 11.11;
            var f_FQCRRMedical = await new FqcResultMasterController(_context).GetFQCHeaderData4QRS016ByDetail(null, null, null, sDate, eDate, "1001");
            if (f_FQCRRSystem.DataTotal > 0)
            {
                foreach (var item in f_FQCRRMedical.Data.Where(W => W.type == "醫療"))
                {
                    result.FQCRRMedical = item.rejectRate;
                }
            }
            #endregion

            // DOA Board
            //result.DOABoard = 0.04;
            sReturn_Data = await Get_QC_Rate(vYear.ToString(), vMonth.ToString(),"DOA");
            sData_Ary = sReturn_Data.Split("|");
            result.DOABoard = double.Parse(sData_Ary[0].ToString());

            // DOA System
            //result.DOASystem = 0.12;
            result.DOASystem = double.Parse(sData_Ary[1].ToString());

            // DOA Medical
            //result.DOAMedical = 0.00;
            result.DOAMedical = double.Parse(sData_Ary[2].ToString());

            // FPY 立德 Board
            #region 立德 Board
            //result.FPYBoard_LEI = 99.15;
            var f_FPYBoard_LEI = await new WipStationController(_context).GetWipStation4QRS014GroupB(null, sDate, eDate, null, "YS00", null);
            if (f_FPYBoard_LEI.DataTotal > 0)
            {
                double sum_rate = 100.0;
                int sum_idx = 1;

                DataTable dtRate = new DataTable();
                dtRate.Columns.Add("STATION_ID");
                dtRate.Columns.Add("OK_QTY");
                dtRate.Columns.Add("NG_QTY");
                dtRate.PrimaryKey = new DataColumn[] { dtRate.Columns[0] };
                dtRate.AcceptChanges();

                foreach (var data in f_FPYBoard_LEI.Data)
                {
                    string str = data.ToString();
                    string[] str2 = str.Replace("{", "").Replace("}", "").Split(',');
                    string str3 = "";
                    for (int i = 0; i < str2.Length; i++)
                    {
                        string[] str21 = str2[i].Split("=");
                        str3 = str3 + str21[0].Trim() + ":" + "'" + str21[1].Trim() + "',";
                    }
                    JObject j0 = JObject.Parse("{" + str3.Substring(0, str3.Length - 1) + "}");
                    int stationID = int.Parse(j0["StationID"].ToString());

                    bool existFlag = false;
                    int idx = 0;

                    for (int i = 0; i < dtRate.Rows.Count; i++)
                    {
                        if (dtRate.Rows[i]["STATION_ID"].ToString() == stationID.ToString())
                        {
                            idx = i;
                            existFlag = true;
                            break;
                        }
                    }

                    int okQty = 0, ngQty = 0;

                    if (j0["RuleStatus"].ToString() == "P")
                    {
                        okQty = int.Parse(j0["FirstCnt"].ToString());
                    }
                    else
                    {
                        ngQty = int.Parse(j0["FirstCnt"].ToString());
                    }

                    if (existFlag)
                    {
                        if (okQty > 0)
                        {
                            dtRate.Rows[idx][1] = okQty;
                        }
                        if (ngQty > 0)
                        {
                            dtRate.Rows[idx][2] = ngQty;
                        }

                        dtRate.AcceptChanges();
                    }
                    else
                    {
                        DataRow dr = dtRate.NewRow();
                        dr[0] = stationID;
                        dr[1] = okQty;
                        dr[2] = ngQty;

                        dtRate.Rows.Add(dr);
                        dtRate.AcceptChanges();
                    }
                }

                if (dtRate.Rows.Count > 0)
                {
                    for (int j = 0; j < dtRate.Rows.Count; j++)
                    {
                        int okQty = int.Parse(dtRate.Rows[j][1].ToString());
                        int ngQty = int.Parse(dtRate.Rows[j][2].ToString());

                        int inputQty = okQty + ngQty;

                        double rate = 0;
                        if (okQty > 0)
                        {
                            rate = (okQty * 1.0 / inputQty) * 100;
                        }

                        if (rate > 0)
                        {
                            //sum_rate = sum_rate * (rate / 100.0);
                            sum_idx = sum_idx + 1;
                            sum_rate = sum_rate + rate;
                        }
                    }
                }
                result.FPYBoard_LEI = double.Parse((sum_rate / sum_idx).ToString("0.00"));
            }
            #endregion

            // FPY 立德 System
            #region  立德 System
            //result.FPYSystem_LEI = 92.12;
            var f_FPYSystem_LEI = await new WipStationController(_context).GetWipStation4QRS014GroupS(null, sDate, eDate, null, "YS00", null);
            if (f_FPYSystem_LEI.DataTotal > 0)
            {
                double sum_rate = 100.0;
                int sum_idx = 1;

                DataTable dtRate = new DataTable();
                dtRate.Columns.Add("STATION_ID");
                dtRate.Columns.Add("OK_QTY");
                dtRate.Columns.Add("NG_QTY");
                dtRate.PrimaryKey = new DataColumn[] { dtRate.Columns[0] };
                dtRate.AcceptChanges();

                foreach (var data in f_FPYSystem_LEI.Data)
                {
                    string str = data.ToString();
                    string[] str2 = str.Replace("{", "").Replace("}", "").Split(',');
                    string str3 = "";
                    for (int i = 0; i < str2.Length; i++)
                    {
                        string[] str21 = str2[i].Split("=");
                        str3 = str3 + str21[0].Trim() + ":" + "'" + str21[1].Trim() + "',";
                    }
                    JObject j0 = JObject.Parse("{" + str3.Substring(0, str3.Length - 1) + "}");
                    int stationID = int.Parse(j0["StationID"].ToString());

                    bool existFlag = false;
                    int idx = 0;

                    for (int i = 0; i < dtRate.Rows.Count; i++)
                    {
                        if (dtRate.Rows[i]["STATION_ID"].ToString() == stationID.ToString())
                        {
                            idx = i;
                            existFlag = true;
                            break;
                        }
                    }

                    int okQty = 0, ngQty = 0;

                    if (j0["RuleStatus"].ToString() == "P")
                    {
                        okQty = int.Parse(j0["FirstCnt"].ToString());
                    }
                    else
                    {
                        ngQty = int.Parse(j0["FirstCnt"].ToString());
                    }

                    if (existFlag)
                    {
                        if (okQty > 0)
                        {
                            dtRate.Rows[idx][1] = okQty;
                        }
                        if (ngQty > 0)
                        {
                            dtRate.Rows[idx][2] = ngQty;
                        }

                        dtRate.AcceptChanges();
                    }
                    else
                    {
                        DataRow dr = dtRate.NewRow();
                        dr[0] = stationID;
                        dr[1] = okQty;
                        dr[2] = ngQty;

                        dtRate.Rows.Add(dr);
                        dtRate.AcceptChanges();
                    }
                }

                if (dtRate.Rows.Count > 0)
                {
                    for (int j = 0; j < dtRate.Rows.Count; j++)
                    {
                        int okQty = int.Parse(dtRate.Rows[j][1].ToString());
                        int ngQty = int.Parse(dtRate.Rows[j][2].ToString());

                        int inputQty = okQty + ngQty;

                        double rate = 0;
                        if (okQty > 0)
                        {
                            rate = (okQty * 1.0 / inputQty) * 100;
                        }

                        if (rate > 0)
                        {
                            //sum_rate = sum_rate * (rate / 100.0);
                            sum_idx = sum_idx + 1;
                            sum_rate = sum_rate + rate;
                        }
                    }
                }
                result.FPYSystem_LEI = double.Parse((sum_rate / sum_idx).ToString("0.00"));
            }
            #endregion

            // FPY 立德 Medical
            #region 立德 Medical
            //result.FPYMedical_LEI = 90.11;
            var f_FPYMedical_LEI = await new WipStationController(_context).GetWipStation4QRS014GroupS(null, sDate, eDate, null, "YS00", null);
            if (f_FPYMedical_LEI.DataTotal > 0)
            {
                double sum_rate = 100.0;
                int sum_idx = 1;

                DataTable dtRate = new DataTable();
                dtRate.Columns.Add("STATION_ID");
                dtRate.Columns.Add("OK_QTY");
                dtRate.Columns.Add("NG_QTY");
                dtRate.PrimaryKey = new DataColumn[] { dtRate.Columns[0] };
                dtRate.AcceptChanges();

                foreach (var data in f_FPYMedical_LEI.Data)
                {
                    string str = data.ToString();
                    string[] str2 = str.Replace("{", "").Replace("}", "").Split(',');
                    string str3 = "";
                    for (int i = 0; i < str2.Length; i++)
                    {
                        string[] str21 = str2[i].Split("=");
                        str3 = str3 + str21[0].Trim() + ":" + "'" + str21[1].Trim() + "',";
                    }
                    JObject j0 = JObject.Parse("{" + str3.Substring(0, str3.Length - 1) + "}");
                    int stationID = int.Parse(j0["StationID"].ToString());

                    bool existFlag = false;
                    int idx = 0;

                    for (int i = 0; i < dtRate.Rows.Count; i++)
                    {
                        if (dtRate.Rows[i]["STATION_ID"].ToString() == stationID.ToString())
                        {
                            idx = i;
                            existFlag = true;
                            break;
                        }
                    }

                    int okQty = 0, ngQty = 0;

                    if (j0["RuleStatus"].ToString() == "P")
                    {
                        okQty = int.Parse(j0["FirstCnt"].ToString());
                    }
                    else
                    {
                        ngQty = int.Parse(j0["FirstCnt"].ToString());
                    }

                    if (existFlag)
                    {
                        if (okQty > 0)
                        {
                            dtRate.Rows[idx][1] = okQty;
                        }
                        if (ngQty > 0)
                        {
                            dtRate.Rows[idx][2] = ngQty;
                        }

                        dtRate.AcceptChanges();
                    }
                    else
                    {
                        DataRow dr = dtRate.NewRow();
                        dr[0] = stationID;
                        dr[1] = okQty;
                        dr[2] = ngQty;

                        dtRate.Rows.Add(dr);
                        dtRate.AcceptChanges();
                    }
                }

                if (dtRate.Rows.Count > 0)
                {
                    for (int j = 0; j < dtRate.Rows.Count; j++)
                    {
                        int okQty = int.Parse(dtRate.Rows[j][1].ToString());
                        int ngQty = int.Parse(dtRate.Rows[j][2].ToString());

                        int inputQty = okQty + ngQty;

                        double rate = 0;
                        if (okQty > 0)
                        {
                            rate = (okQty * 1.0 / inputQty) * 100;
                        }

                        if (rate > 0)
                        {
                            //sum_rate = sum_rate * (rate / 100.0);
                            sum_idx = sum_idx + 1;
                            sum_rate = sum_rate + rate;
                        }
                    }
                }
                result.FPYMedical_LEI = double.Parse((sum_rate / sum_idx).ToString("0.00"));
            }
            #endregion

            // FPY Board
            #region 立德 委外 Board
            //result.FPYBoard = 100.00;
            var f_FPYBoard = await new WipStationController(_context).GetWipStation4QRS014GroupB(null, sDate, eDate, null, "YS31", null);
            if (f_FPYBoard.DataTotal > 0)
            {
                double sum_rate = 100.0;
                int sum_idx = 1;

                DataTable dtRate = new DataTable();
                dtRate.Columns.Add("STATION_ID");
                dtRate.Columns.Add("OK_QTY");
                dtRate.Columns.Add("NG_QTY");
                dtRate.PrimaryKey = new DataColumn[] { dtRate.Columns[0] };
                dtRate.AcceptChanges();

                foreach (var data in f_FPYBoard.Data)
                {
                    string str = data.ToString();
                    string[] str2 = str.Replace("{", "").Replace("}", "").Split(',');
                    string str3 = "";
                    for (int i = 0; i < str2.Length; i++)
                    {
                        string[] str21 = str2[i].Split("=");
                        str3 = str3 + str21[0].Trim() + ":" + "'" + str21[1].Trim() + "',";
                    }
                    JObject j0 = JObject.Parse("{" + str3.Substring(0, str3.Length - 1) + "}");
                    int stationID = int.Parse(j0["StationID"].ToString());

                    bool existFlag = false;
                    int idx = 0;

                    for (int i = 0; i < dtRate.Rows.Count; i++)
                    {
                        if (dtRate.Rows[i]["STATION_ID"].ToString() == stationID.ToString())
                        {
                            idx = i;
                            existFlag = true;
                            break;
                        }
                    }

                    int okQty = 0, ngQty = 0;

                    if (j0["RuleStatus"].ToString() == "P")
                    {
                        okQty = int.Parse(j0["FirstCnt"].ToString());
                    }
                    else
                    {
                        ngQty = int.Parse(j0["FirstCnt"].ToString());
                    }

                    if (existFlag)
                    {
                        if (okQty > 0)
                        {
                            dtRate.Rows[idx][1] = okQty;
                        }
                        if (ngQty > 0)
                        {
                            dtRate.Rows[idx][2] = ngQty;
                        }

                        dtRate.AcceptChanges();
                    }
                    else
                    {
                        DataRow dr = dtRate.NewRow();
                        dr[0] = stationID;
                        dr[1] = okQty;
                        dr[2] = ngQty;

                        dtRate.Rows.Add(dr);
                        dtRate.AcceptChanges();
                    }
                }

                if (dtRate.Rows.Count > 0)
                {
                    for (int j = 0; j < dtRate.Rows.Count; j++)
                    {
                        int okQty = int.Parse(dtRate.Rows[j][1].ToString());
                        int ngQty = int.Parse(dtRate.Rows[j][2].ToString());

                        int inputQty = okQty + ngQty;

                        double rate = 0;
                        if (okQty > 0)
                        {
                            rate = (okQty * 1.0 / inputQty) * 100;
                        }

                        if (rate > 0)
                        {
                            //sum_rate = sum_rate * (rate / 100.0);
                            sum_idx = sum_idx + 1;
                            sum_rate = sum_rate + rate;
                        }
                    }
                }
                result.FPYBoard = double.Parse((sum_rate / sum_idx).ToString("0.00"));
            }
            #endregion

            // FPY System            
            #region  立德 委外 System
            //result.FPYSystem = 99.12;
            var f_FPYSystem = await new WipStationController(_context).GetWipStation4QRS014GroupS(null, sDate, eDate, null, "YS31", null);
            if (f_FPYSystem.DataTotal > 0)
            {
                double sum_rate = 100.0;
                int sum_idx = 1;

                DataTable dtRate = new DataTable();
                dtRate.Columns.Add("STATION_ID");
                dtRate.Columns.Add("OK_QTY");
                dtRate.Columns.Add("NG_QTY");
                dtRate.PrimaryKey = new DataColumn[] { dtRate.Columns[0] };
                dtRate.AcceptChanges();

                foreach (var data in f_FPYSystem.Data)
                {
                    string str = data.ToString();
                    string[] str2 = str.Replace("{", "").Replace("}", "").Split(',');
                    string str3 = "";
                    for (int i = 0; i < str2.Length; i++)
                    {
                        string[] str21 = str2[i].Split("=");
                        str3 = str3 + str21[0].Trim() + ":" + "'" + str21[1].Trim() + "',";
                    }
                    JObject j0 = JObject.Parse("{" + str3.Substring(0, str3.Length - 1) + "}");
                    int stationID = int.Parse(j0["StationID"].ToString());

                    bool existFlag = false;
                    int idx = 0;

                    for (int i = 0; i < dtRate.Rows.Count; i++)
                    {
                        if (dtRate.Rows[i]["STATION_ID"].ToString() == stationID.ToString())
                        {
                            idx = i;
                            existFlag = true;
                            break;
                        }
                    }

                    int okQty = 0, ngQty = 0;

                    if (j0["RuleStatus"].ToString() == "P")
                    {
                        okQty = int.Parse(j0["FirstCnt"].ToString());
                    }
                    else
                    {
                        ngQty = int.Parse(j0["FirstCnt"].ToString());
                    }

                    if (existFlag)
                    {
                        if (okQty > 0)
                        {
                            dtRate.Rows[idx][1] = okQty;
                        }
                        if (ngQty > 0)
                        {
                            dtRate.Rows[idx][2] = ngQty;
                        }

                        dtRate.AcceptChanges();
                    }
                    else
                    {
                        DataRow dr = dtRate.NewRow();
                        dr[0] = stationID;
                        dr[1] = okQty;
                        dr[2] = ngQty;

                        dtRate.Rows.Add(dr);
                        dtRate.AcceptChanges();
                    }
                }

                if (dtRate.Rows.Count > 0)
                {
                    for (int j = 0; j < dtRate.Rows.Count; j++)
                    {
                        int okQty = int.Parse(dtRate.Rows[j][1].ToString());
                        int ngQty = int.Parse(dtRate.Rows[j][2].ToString());

                        int inputQty = okQty + ngQty;

                        double rate = 0;
                        if (okQty > 0)
                        {
                            rate = (okQty * 1.0 / inputQty) * 100;
                        }

                        if (rate > 0)
                        {
                            //sum_rate = sum_rate * (rate / 100.0);
                            sum_idx = sum_idx + 1;
                            sum_rate = sum_rate + rate;
                        }
                    }
                }
                result.FPYSystem = double.Parse((sum_rate / sum_idx).ToString("0.00"));
            }
            #endregion

            // FPY Medical            
            #region 立德 委外 Medical
            //result.FPYMedical = 12.12;
            var f_FPYMedical = await new WipStationController(_context).GetWipStation4QRS014GroupS(null, sDate, eDate, null, "YS31", null);
            if (f_FPYMedical.DataTotal > 0)
            {
                double sum_rate = 100.0;
                int sum_idx = 1;

                DataTable dtRate = new DataTable();
                dtRate.Columns.Add("STATION_ID");
                dtRate.Columns.Add("OK_QTY");
                dtRate.Columns.Add("NG_QTY");
                dtRate.PrimaryKey = new DataColumn[] { dtRate.Columns[0] };
                dtRate.AcceptChanges();

                foreach (var data in f_FPYMedical.Data)
                {
                    string str = data.ToString();
                    string[] str2 = str.Replace("{", "").Replace("}", "").Split(',');
                    string str3 = "";
                    for (int i = 0; i < str2.Length; i++)
                    {
                        string[] str21 = str2[i].Split("=");
                        str3 = str3 + str21[0].Trim() + ":" + "'" + str21[1].Trim() + "',";
                    }
                    JObject j0 = JObject.Parse("{" + str3.Substring(0, str3.Length - 1) + "}");
                    int stationID = int.Parse(j0["StationID"].ToString());

                    bool existFlag = false;
                    int idx = 0;

                    for (int i = 0; i < dtRate.Rows.Count; i++)
                    {
                        if (dtRate.Rows[i]["STATION_ID"].ToString() == stationID.ToString())
                        {
                            idx = i;
                            existFlag = true;
                            break;
                        }
                    }

                    int okQty = 0, ngQty = 0;

                    if (j0["RuleStatus"].ToString() == "P")
                    {
                        okQty = int.Parse(j0["FirstCnt"].ToString());
                    }
                    else
                    {
                        ngQty = int.Parse(j0["FirstCnt"].ToString());
                    }

                    if (existFlag)
                    {
                        if (okQty > 0)
                        {
                            dtRate.Rows[idx][1] = okQty;
                        }
                        if (ngQty > 0)
                        {
                            dtRate.Rows[idx][2] = ngQty;
                        }

                        dtRate.AcceptChanges();
                    }
                    else
                    {
                        DataRow dr = dtRate.NewRow();
                        dr[0] = stationID;
                        dr[1] = okQty;
                        dr[2] = ngQty;

                        dtRate.Rows.Add(dr);
                        dtRate.AcceptChanges();
                    }
                }

                if (dtRate.Rows.Count > 0)
                {
                    for (int j = 0; j < dtRate.Rows.Count; j++)
                    {
                        int okQty = int.Parse(dtRate.Rows[j][1].ToString());
                        int ngQty = int.Parse(dtRate.Rows[j][2].ToString());

                        int inputQty = okQty + ngQty;

                        double rate = 0;
                        if (okQty > 0)
                        {
                            rate = (okQty * 1.0 / inputQty) * 100;
                        }

                        if (rate > 0)
                        {
                            //sum_rate = sum_rate * (rate / 100.0);
                            sum_idx = sum_idx + 1;
                            sum_rate = sum_rate + rate;
                        }
                    }
                }
                result.FPYMedical = double.Parse((sum_rate / sum_idx).ToString("0.00"));
            }
            #endregion

            // RMA Board
            //result.RMABoard = 0.01;
            sReturn_Data = await Get_QC_Rate(vYear.ToString(), vMonth.ToString(), "RMA");
            sData_Ary = sReturn_Data.Split("|");
            result.RMABoard = double.Parse(sData_Ary[0].ToString());

            // RMA System
            //result.RMASystem = 0.02;
            result.RMASystem = double.Parse(sData_Ary[1].ToString());

            // RMA Medical
            //result.RMAMedical = 0.03;
            result.RMAMedical = double.Parse(sData_Ary[2].ToString());

            // CFQR件數 新增筆數
            //result.CFQRNew = 100;
            #region
            sReturn_Data = await Get_CFQR_Rate("104", vYear.ToString(), vMonth.ToString(), "103,104,101");
            sData_Ary = sReturn_Data.Split("|");
            result.CFQRNew = int.Parse(sData_Ary[0].ToString());
            #endregion

            // CFQR件數 結案筆數
            //result.CFQRClose = 50;
            result.CFQRClose = int.Parse(sData_Ary[1].ToString());

            // CFQR件數 總筆數
            //result.CFQRTotal = 250;
            result.CFQRTotal = int.Parse(sData_Ary[2].ToString());

            return result;
        }
    }
}