using CK.SCP.Models;
using CK.SCP.Models.Enums;
using CK.SCP.Models.ScpEntity;
using CK.SCP.Models.ScpEntity.ExcelExportEnttity;
using CK.SCP.Utils;
using System;
using System.Collections.Generic;
using System.Data.Entity.Core;
using System.Data.Entity.Migrations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CK.SCP.Controller
{
    public class SCP_FORECAST_CONTROLLER
    {
        /// <summary>
        /// 获取数据
        /// </summary>
        /// <param name="p_entity"></param>
        /// <param name="p_action"></param>
        public static void Get_V_TB_FORECAST_List(V_TB_FORECAST p_entity, Action<ResultObject<IQueryable<V_TB_FORECAST>>> p_action)
        {
            ResultObject<IQueryable<V_TB_FORECAST>> _ret = new ResultObject<IQueryable<V_TB_FORECAST>>();
            try
            {
                using (Models.ScpEntities db = EntitiesFactory.CreateScpInstance())
                {
                    IQueryable<V_TB_FORECAST> q = db.V_TB_FORECAST;

                    if (!string.IsNullOrEmpty(p_entity.PartCode))
                    {
                        q = q.Where(p => p.PartCode.Contains(p_entity.PartCode));
                    }
                    if (!string.IsNullOrEmpty(p_entity.VendId))
                    {
                        q = q.Where(p => p.VendId == p_entity.VendId);
                    }
                    if (p_entity.BillStateList != null && p_entity.BillStateList.Count > 0)
                    {
                        q = q.Where(p => p_entity.BillStateList.Contains((int)p.State));
                    }
                    if (!string.IsNullOrEmpty(p_entity.State_DESC))
                    {
                        q = q.Where(p => p.State_DESC.Contains(p_entity.State_DESC));
                    }
                    if (!string.IsNullOrEmpty(p_entity.Month))
                    {
                        q = q.Where(p => p.Month == p_entity.Month);
                    }
                    q = q.Where(p => p.IsDeleted == p_entity.IsDeleted);
                    if (p_entity.UserInAddress != null && p_entity.UserInAddress.Count > 0)
                    {
                        q = q.Where(p => p_entity.UserInAddress.Contains(p.Site));
                    }
                    if (!string.IsNullOrEmpty(p_entity.CreateUser))
                    {
                        q = q.Where(p => p.CreateUser == p_entity.CreateUser);
                    }
                    if (p_entity.UserInVendIds != null && p_entity.UserInVendIds.Count > 0)
                    {
                        q = q.Where(p => p_entity.UserInVendIds.Contains(p.VendId));
                    }
                    _ret.State = ReturnStatus.Succeed;
                    _ret.Result = q;
                    p_action(_ret);
                }
            }
            catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)//捕获实体验证异常
            {
                var sb = new StringBuilder();
                foreach (var error in dbEx.EntityValidationErrors.ToList())
                {
                    error.ValidationErrors.ToList().ForEach(i =>
                    {
                        sb.AppendFormat("表:{0},字段:{1},信息:{2}\r\n", error.Entry.Entity.GetType().Name, i.PropertyName, i.ErrorMessage);
                    });
                }
                _ret.State = ReturnStatus.Failed;
                _ret.ErrorList.Add(dbEx);
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(SCP_FORECAST_CONTROLLER), "Get_V_TB_FORECAST_List", sb.ToString());
                throw new ScpException(ResultCode.DbEntityValidationException, sb.ToString(), "字段验证失败" + sb.ToString());
            }
            catch (OptimisticConcurrencyException ex)//并发冲突异常
            {

                _ret.State = ReturnStatus.Failed;
                _ret.ErrorList.Add(ex);
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(SCP_FORECAST_CONTROLLER), "Get_V_TB_FORECAST_List", ex.ToString());
                throw new ScpException(ResultCode.Exception, "9999", ex.ToString());
            }
            catch (ScpException ex)
            {
                _ret.State = ReturnStatus.Failed;
                _ret.ErrorList.Add(ex);
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(SCP_FORECAST_CONTROLLER), "Get_V_TB_FORECAST_List", ex.ToString());

                if (ex.InnerException != null && ex.InnerException.GetType() == typeof(UpdateException))
                {
                    var inner = (UpdateException)ex.InnerException;


                    throw new ScpException(ResultCode.Exception, "0000", ex.ToString());
                }
                else
                {
                    if (ex.InnerException != null) throw ex.InnerException;
                }
            }
            catch (Exception e)
            {
                _ret.State = ReturnStatus.Failed;
                _ret.ErrorList.Add(e);
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(SCP_FORECAST_CONTROLLER), "Get_V_TB_FORECAST_List", e.Message);
                throw e;
            }
        }
        /// <summary>
        /// EXCEL导入
        /// </summary>
        /// <param name="p_order_list"></param>
        /// <param name="p_creator"></param>
        /// <returns></returns>
        public static ResultObject<bool> EXCEL_FORECAST_MOD(List<SCP_FORECAST_EXPORT> p_order_list, string p_creator, string site)
        {
            ResultObject<bool> _ret = new ResultObject<bool>();
            try
            {
                using (ScpEntities db = EntitiesFactory.CreateScpInstance())
                {
                    int number = 1;
                    List<string> lineError = new List<string>();
                    List<string> ErrorList = new List<string>();
                    var _lst = p_order_list;
                    _lst.ForEach
                    (p =>
                    {
                        var _ls = CheckExcelMode_Forecast(db, p);
                        if (_ls.Count > 0)
                        {
                            lineError.Add(number.ToString());
                            ErrorList.Add(string.Join("<br>", _ls.ToArray()));
                        }
                        number++;
                    });
                    if (lineError.Count > 0)
                    {
                        _ret.State = ReturnStatus.Failed;
                        _ret.MessageList.AddRange(ErrorList);
                        _ret.Result = false;
                    }
                    else
                    {
                        _lst.ForEach(p =>
                        {
                            // var _item = db.TB_FORECAST.SingleOrDefault(t => t.PartCode == p.零件编号.ToUpper() && t.VendId == p.供应商编码 && t.Month == p.月份) ??
                            //         new TB_FORECAST { PartCode = p.零件编号.ToUpper(), VendId = p.供应商编码, Month = p.月份, GUID = System.Guid.NewGuid() };
                            var _item = new TB_FORECAST();
                            _item.PoType = p.订单;
                            _item.VendId = p.供应商编码;
                            _item.GUID = System.Guid.NewGuid();
                            _item.PartCode = p.零件编号;
                            _item.PoLine =Int32.Parse(p.图号);
                            _item.ShippdedPlace = p.规格;
                            _item.Unit = p.单位;
                            _item.Qty = decimal.Parse(p.当次订单数量);
                            _item.ProductStatus = p.产品状态;
                            _item.IsUrgent = p.紧急;
                            _item.ShippdedTime = DateTime.Parse(p.要求到货日期);
                            _item.ShippdedPlace = p.到货地;
                            _item.MonthQty = decimal.Parse(p.当月);
                            _item.MonthQty1 = decimal.Parse(p.预测1);
                            _item.MonthQty2 = decimal.Parse(p.预测2);
                            _item.MonthQty3 = decimal.Parse(p.预测3);
                            _item.Ontime = p.是否按期交货;
                            _item.Datetime = p.不能按期交付日期;
                            _item.Remark = p.备注;
                            _item.IsDeleted = false;
                            _item.CreateUser = p_creator;
                            _item.CreateTime = DateTime.Now;
                            _item.State = (int)ForecastState.New;
                            _item.UpdateInfo = "";
                            _item.Site = site;
                            db.TB_FORECAST.AddOrUpdate(_item);
                        });
                        if (_ret.MessageList.Count == 0)
                        {
                            int state = db.SaveChanges();
                            if (state != -1)
                            {
                                _ret.State = ReturnStatus.Succeed;
                                _ret.Result = true;
                            }
                            else
                            {
                                _ret.State = ReturnStatus.Failed;
                                _ret.Result = false;
                            }
                        }
                        else
                        {
                            _ret.State = ReturnStatus.Failed;
                            _ret.Result = false;
                        }
                    }
                }
            }
            catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)//捕获实体验证异常
            {
                var sb = new StringBuilder();

                foreach (var error in dbEx.EntityValidationErrors.ToList())
                {

                    error.ValidationErrors.ToList().ForEach(i =>
                    {
                        sb.AppendFormat("表:{0},字段:{1},信息:{2}\r\n", error.Entry.Entity.GetType().Name, i.PropertyName, i.ErrorMessage);
                    });
                }
                _ret.State = ReturnStatus.Failed;
                _ret.Result = false;
                _ret.ErrorList.Add(dbEx);
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(SCP_FORECAST_CONTROLLER), "EXCEL_FORECAST_MOD", sb.ToString());
                throw new ScpException(ResultCode.DbEntityValidationException, sb.ToString(), "字段验证失败" + sb.ToString());
            }
            catch (OptimisticConcurrencyException ex)//并发冲突异常
            {

                _ret.State = ReturnStatus.Failed;
                _ret.Result = false;
                _ret.ErrorList.Add(ex);
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(SCP_FORECAST_CONTROLLER), "EXCEL_FORECAST_MOD", ex.ToString());
                throw new ScpException(ResultCode.Exception, "9999", ex.ToString());
            }
            catch (ScpException ex)
            {


                _ret.State = ReturnStatus.Failed;
                _ret.Result = false;
                _ret.ErrorList.Add(ex);
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(SCP_FORECAST_CONTROLLER), "EXCEL_FORECAST_MOD", ex.ToString());

                if (ex.InnerException != null && ex.InnerException.GetType() == typeof(UpdateException))
                {
                    var inner = (UpdateException)ex.InnerException;


                    throw new ScpException(ResultCode.Exception, "0000", ex.ToString());
                }
                else
                {
                    if (ex.InnerException != null) throw ex.InnerException;
                }
            }
            catch (Exception e)
            {
                _ret.State = ReturnStatus.Failed;
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(SCP_FORECAST_CONTROLLER), "EXCEL_FORECAST_MOD", e.Message);
                _ret.Result = false;
                _ret.ErrorList.Add(e);
                throw e;
            }
            return _ret;
        }
        /// <summary>
        /// 导入验证
        /// </summary>
        /// <param name="db"></param>
        /// <param name="p_excel"></param>
        /// <returns></returns>
        private static List<string> CheckExcelMode_Forecast(ScpEntities db, SCP_FORECAST_EXPORT p_excel)
        {
            List<string> ErrorList = new List<string>();
            if (
         string.IsNullOrEmpty(p_excel.零件编号) ||
         string.IsNullOrEmpty(p_excel.供应商编码) ||
         string.IsNullOrEmpty(p_excel.图号) ||
         string.IsNullOrEmpty(p_excel.当次订单数量) ||
         string.IsNullOrEmpty(p_excel.要求到货日期) ||
          string.IsNullOrEmpty(p_excel.当月) ||
         string.IsNullOrEmpty(p_excel.预测1) ||
         string.IsNullOrEmpty(p_excel.预测2) ||
         string.IsNullOrEmpty(p_excel.预测3))
            {
                ErrorList.Add(string.Format("零件编号【{0}】有填写为空!", p_excel.零件编号));
            }
            return ErrorList;
        }
		 /// <summary>
        /// EXCEL导入(沈阳金杯)
        /// </summary>
        /// <param name="p_order_list"></param>
        /// <param name="p_creator"></param>
        /// <returns></returns>
        public static ResultObject<bool> EXCEL_FORECAST_MOD_SYJB(List<SCP_FORECAST_EXPORT_SYJB> p_order_list, string p_creator, string site)
        {
            ResultObject<bool> _ret = new ResultObject<bool>();
            try
            {
                using (ScpEntities db = EntitiesFactory.CreateScpInstance())
                {
                    int number = 1;
                    List<string> lineError = new List<string>();
                    List<string> ErrorList = new List<string>();
                    var _lst = p_order_list;
                    _lst.ForEach
                    (p =>
                    {
                        var _ls = CheckExcelMode_Forecast_SYJB(db, p);
                        if (_ls.Count > 0)
                        {
                            lineError.Add(number.ToString());
                            ErrorList.Add(string.Join("<br>", _ls.ToArray()));
                        }
                        number++;
                    });
                    if (lineError.Count > 0)
                    {
                        _ret.State = ReturnStatus.Failed;
                        _ret.MessageList.AddRange(ErrorList);
                        _ret.Result = false;
                    }
                    else
                    {
                        _lst.ForEach(p =>
                        {
                            var _item = db.TB_FORECAST.SingleOrDefault(t => t.PartCode == p.零件编号.ToUpper() && t.VendId == p.供应商编码 && t.Month == p.月份&&t.State!=(int)ForecastState.Reject) ??
                                      new TB_FORECAST { PartCode = p.零件编号.ToUpper(), VendId = p.供应商编码, Month = p.月份, GUID = System.Guid.NewGuid() };
                            _item.MonthQty1 = decimal.Parse(p.预测1);
                            _item.MonthQty2 = decimal.Parse(p.预测2);
                            _item.MonthQty3 = decimal.Parse(p.预测3);
                            _item.IsDeleted = false;
                            _item.CreateUser = p_creator;
                            _item.CreateTime = DateTime.Now;
                            _item.State = (int)ForecastState.New;
                            _item.UpdateInfo = "";
                            _item.Site = site;
                            db.TB_FORECAST.AddOrUpdate(_item);
                        });
                        if (_ret.MessageList.Count == 0)
                        {
                            int state = db.SaveChanges();
                            if (state != -1)
                            {
                                _ret.State = ReturnStatus.Succeed;
                                _ret.Result = true;
                            }
                            else
                            {
                                _ret.State = ReturnStatus.Failed;
                                _ret.Result = false;
                            }
                        }
                        else
                        {
                            _ret.State = ReturnStatus.Failed;
                            _ret.Result = false;
                        }
                    }
                }
            }
            catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)//捕获实体验证异常
            {
                var sb = new StringBuilder();

                foreach (var error in dbEx.EntityValidationErrors.ToList())
                {

                    error.ValidationErrors.ToList().ForEach(i =>
                    {
                        sb.AppendFormat("表:{0},字段:{1},信息:{2}\r\n", error.Entry.Entity.GetType().Name, i.PropertyName, i.ErrorMessage);
                    });
                }
                _ret.State = ReturnStatus.Failed;
                _ret.Result = false;
                _ret.ErrorList.Add(dbEx);
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(SCP_FORECAST_CONTROLLER), "EXCEL_FORECAST_MOD", sb.ToString());
                throw new ScpException(ResultCode.DbEntityValidationException, sb.ToString(), "字段验证失败" + sb.ToString());
            }
            catch (OptimisticConcurrencyException ex)//并发冲突异常
            {

                _ret.State = ReturnStatus.Failed;
                _ret.Result = false;
                _ret.ErrorList.Add(ex);
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(SCP_FORECAST_CONTROLLER), "EXCEL_FORECAST_MOD", ex.ToString());
                throw new ScpException(ResultCode.Exception, "9999", ex.ToString());
            }
            catch (ScpException ex)
            {


                _ret.State = ReturnStatus.Failed;
                _ret.Result = false;
                _ret.ErrorList.Add(ex);
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(SCP_FORECAST_CONTROLLER), "EXCEL_FORECAST_MOD", ex.ToString());

                if (ex.InnerException != null && ex.InnerException.GetType() == typeof(UpdateException))
                {
                    var inner = (UpdateException)ex.InnerException;


                    throw new ScpException(ResultCode.Exception, "0000", ex.ToString());
                }
                else
                {
                    if (ex.InnerException != null) throw ex.InnerException;
                }
            }
            catch (Exception e)
            {
                _ret.State = ReturnStatus.Failed;
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(SCP_FORECAST_CONTROLLER), "EXCEL_FORECAST_MOD", e.Message);
                _ret.Result = false;
                _ret.ErrorList.Add(e);
                throw e;
            }
            return _ret;
        }
        /// <summary>
        /// 导入验证(沈阳金杯)
        /// </summary>
        /// <param name="db"></param>
        /// <param name="p_excel"></param>
        /// <returns></returns>
        private static List<string> CheckExcelMode_Forecast_SYJB(ScpEntities db, SCP_FORECAST_EXPORT_SYJB p_excel)
        {
            List<string> ErrorList = new List<string>();
            var _item = db.TB_FORECAST.SingleOrDefault(t => t.PartCode == p_excel.零件编号.ToUpper() && t.VendId == p_excel.供应商编码 && t.Month == p_excel.月份 && t.State == (int)ForecastState.Confirm);
            if (_item != null)
            {
                ErrorList.Add(string.Format("零件编号【{0}】,月份【{1}】,供应商【{2}】的数据供应商已确认无法修改", p_excel.零件编号, p_excel.月份, p_excel.供应商编码));
            }
            if (
         string.IsNullOrEmpty(p_excel.零件编号) ||
         string.IsNullOrEmpty(p_excel.供应商编码) ||
         string.IsNullOrEmpty((p_excel.月份).ToString()) ||
         string.IsNullOrEmpty(p_excel.预测1) ||
         string.IsNullOrEmpty(p_excel.预测2) ||
         string.IsNullOrEmpty(p_excel.预测3))
            {
                ErrorList.Add(string.Format("零件编号【{0}】有填写为空!", p_excel.零件编号));
            }
            return ErrorList;
        }
        public static ResultObject<bool> Save_TB_FORECAST_STATE(List<long> p_list, string p_user, ForecastState State)
        {
            ResultObject<bool> _ret = new ResultObject<bool>();
            try
            {
                using (ScpEntities db = EntitiesFactory.CreateScpInstance())
                {
                    if (State == ForecastState.Confirm)
                    {
                        var _ls = db.TB_FORECAST.Where(p => p_list.Contains(p.UID)).ToList();
                        int count = _ls.Count(p => p.State == (int)ForecastState.New);
                        if (count == _ls.Count && _ls.Count > 0)
                        {
                            _ls.ForEach(p =>
                            {
                                p.State = (int)ForecastState.Confirm;
                                p.UpdateTime = DateTime.Now;
                                p.UpdateUser = p_user;
                                p.UpdateInfo = "供应商确认";
                            }
                            );
                            db.TB_FORECAST.AddOrUpdate(p => p.UID, _ls.ToArray());
                        }
                        else
                        {
                            _ret.State = ReturnStatus.Failed;
                            _ret.Result = false;
                            _ret.Message = "选择的记录,有已经确认的数据!";
                        }
                    }
                    if (State == ForecastState.Reject)
                    {
                        var _ls = db.TB_FORECAST.Where(p => p_list.Contains(p.UID)).ToList();
                        int count = _ls.Count(p => p.State == (int)ForecastState.New);
                        if (count == _ls.Count && _ls.Count > 0)
                        {
                            _ls.ForEach(p =>
                            {
                                p.State = (int)ForecastState.Reject;
                                p.UpdateTime = DateTime.Now;
                                p.UpdateUser = p_user;
                                p.UpdateInfo = "作废";
                                p.IsDeleted = true ;
                            }
                            );
                            db.TB_FORECAST.AddOrUpdate(p => p.UID, _ls.ToArray());
                        }
                        else
                        {
                            _ret.State = ReturnStatus.Failed;
                            _ret.Result = false;
                            _ret.Message = "选择的记录,有已经确认的数据!";
                        }
                    }
                    if (State == ForecastState.New)
                    {
                        var _ls = db.TB_FORECAST.Where(p => p_list.Contains(p.UID)).ToList();
                        int count = _ls.Count(p => p.State == (int)ForecastState.Confirm);
                        if (count == _ls.Count && _ls.Count > 0)
                        {
                            _ls.ForEach(p =>
                            {
                                p.State = (int)ForecastState.New;
                                p.UpdateTime = DateTime.Now;
                                p.UpdateUser = p_user;
                                p.UpdateInfo = "取消确认";
                            }
                            );
                            db.TB_FORECAST.AddOrUpdate(p => p.UID, _ls.ToArray());
                        }
                        else
                        {
                            _ret.State = ReturnStatus.Failed;
                            _ret.Result = false;
                            _ret.Message = "选择的记录,有不是确认的数据!";
                        }
                    }
                    if (string.IsNullOrEmpty(_ret.Message))
                    {
                        if (db.SaveChanges() != -1)
                        {
                            _ret.State = ReturnStatus.Succeed;
                            _ret.Result = true;
                        }
                        else
                        {
                            _ret.State = ReturnStatus.Failed;
                            _ret.Result = false;
                            _ret.Message = "数据更新失败!";
                        }
                    }
                }
            }
            catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)//捕获实体验证异常
            {
                var sb = new StringBuilder();

                foreach (var error in dbEx.EntityValidationErrors.ToList())
                {

                    error.ValidationErrors.ToList().ForEach(i =>
                    {
                        sb.AppendFormat("表:{0},字段:{1},信息:{2}\r\n", error.Entry.Entity.GetType().Name, i.PropertyName, i.ErrorMessage);
                    });
                }
                _ret.State = ReturnStatus.Failed;
                _ret.Result = false;
                _ret.ErrorList.Add(dbEx);
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(SCP_FORECAST_CONTROLLER), "Save_TB_FORECAST_STATE", sb.ToString());
                throw new ScpException(ResultCode.DbEntityValidationException, sb.ToString(), "字段验证失败" + sb.ToString());
            }
            catch (OptimisticConcurrencyException ex)//并发冲突异常
            {

                _ret.State = ReturnStatus.Failed;
                _ret.Result = false;
                _ret.ErrorList.Add(ex);
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(SCP_FORECAST_CONTROLLER), "Save_TB_FORECAST_STATE", ex.ToString());
                throw new ScpException(ResultCode.Exception, "9999", ex.ToString());
            }
            catch (ScpException ex)
            {


                _ret.State = ReturnStatus.Failed;
                _ret.Result = false;
                _ret.ErrorList.Add(ex);
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(SCP_FORECAST_CONTROLLER), "Save_TB_FORECAST_STATE", ex.ToString());

                if (ex.InnerException != null && ex.InnerException.GetType() == typeof(UpdateException))
                {
                    var inner = (UpdateException)ex.InnerException;


                    throw new ScpException(ResultCode.Exception, "0000", ex.ToString());
                }
                else
                {
                    if (ex.InnerException != null) throw ex.InnerException;
                }
            }
            catch (Exception e)
            {
                _ret.State = ReturnStatus.Failed;
                LogHelper.Writlog(LogHelper.LogType.Error, typeof(SCP_FORECAST_CONTROLLER), "Save_TB_FORECAST_STATE", e.Message);
                _ret.Result = false;
                _ret.ErrorList.Add(e);
                throw e;
            }

            return _ret;
        }
    }
}