using AutoMapper;
using Kean.Application.Query.Interfaces;
using Kean.Application.Query.ViewModels;
using Kean.Infrastructure.Database;
using Kean.Infrastructure.Database.Repository.Default;
using Kean.Infrastructure.Database.Repository.Default.Entities;
//using Kean.Infrastructure.Database.Repository.Record;
//using Kean.Infrastructure.Database.Repository.Record.Entities;
using Kean.Infrastructure.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Transactions;

namespace Kean.Application.Query.Implements
{
    /// <summary>
    /// 库存信息查询服务实现
    /// </summary>
    public sealed class RecordService : IRecordService
    {
        private readonly IMapper _mapper; // 模型映射
        //private readonly IRecordDb _recordDb;
        private readonly IDefaultDb _database; // 默认数据库

        /// <summary>
        /// 依赖注入
        /// </summary>
        public RecordService(
            IMapper mapper,
            //IRecordDb recordDb
            IDefaultDb database)
        {
            _mapper = mapper;
            //_recordDb = recordDb;
            _database = database;
        }

        /*
         * 实现 Kean.Application.Query.Interfaces.IRecordService.GetInterfaceRecordCount 方法
         */
        public async Task<int> GetInterfaceRecordCount(
            string direction,
            string method,
            string requestNo,
            string barcode,
            string result,
            DateTime? beginTimeFrom,
            DateTime? beginTimeTo,
            DateTime? endTimeFrom,
            DateTime? endTimeTo)
        {
            return (await GetInterfaceRecordSchema(direction, method, requestNo, barcode, result, beginTimeFrom, beginTimeTo, endTimeFrom, endTimeTo)
                .Single(r => new { Count = Function.Count(r.ID) }))
                .Count;
        }

        /*
         * 实现 Kean.Application.Query.Interfaces.IRecordService.GetInterfaceRecordList 方法
         */
        public async Task<IEnumerable<InterfaceRecord>> GetInterfaceRecordList(
            string direction,
            string method,
            string requestNo,
            string barcode,
            string result,
            DateTime? beginTimeFrom,
            DateTime? beginTimeTo,
            DateTime? endTimeFrom,
            DateTime? endTimeTo,
            string sort,
            int? offset,
            int? limit)
        {
            var properties = new Dictionary<string, string>();
            return _mapper.Map<IEnumerable<InterfaceRecord>>(await GetInterfaceRecordSchema(direction, method, requestNo, barcode, result, beginTimeFrom, beginTimeTo, endTimeFrom, endTimeTo)
                .Sort<T_INTERFACE_RECORD, InterfaceRecord>(sort, _mapper)
                .OrderBy(r => r.START_TIME, Infrastructure.Database.Order.Descending)
                .OrderBy(r => r.ID, Infrastructure.Database.Order.Descending)
                .Page(offset, limit)
                .Select());
        }

        /*
         * 组织 GetInterfaceRecord 相关方法的条件
         */
        private ISchema<T_INTERFACE_RECORD> GetInterfaceRecordSchema(
            string direction,
            string method,
            string requestNo,
            string barcode,
            string result,
            DateTime? beginTimeFrom,
            DateTime? beginTimeTo,
            DateTime? endTimeFrom,
            DateTime? endTimeTo)
        {
            //var schema = _recordDb.From<T_INTERFACE_RECORD>();
            var schema = _database.From<T_INTERFACE_RECORD>();
            if (direction != null)
            {
                schema = schema.Where(r => r.DIRECTION.Contains(direction));
            }
            if (method != null)
            {
                schema = schema.Where(r => r.METHOD.Contains(method));
            }
            if (requestNo != null)
            {
                schema = schema.Where(r => r.REQUEST_NO.Contains(requestNo));
            }
            if (barcode != null)
            {
                schema = schema.Where(r => r.BARCODE.Contains(barcode));
            }
            if (result != null)
            {
                schema = schema.Where(r => r.RESULT == result);
            }
           
            if (beginTimeFrom.HasValue)
            {
                schema = schema.Where(r => r.START_TIME >= beginTimeFrom.Value);
            }
            if (beginTimeTo.HasValue)
            {
                schema = schema.Where(r => r.START_TIME <= beginTimeTo.Value.AddDays(1));
            }
            if (endTimeFrom.HasValue)
            {
                schema = schema.Where(r => r.END_TIME >= endTimeFrom.Value);
            }
            if (endTimeTo.HasValue)
            {
                schema = schema.Where(r => r.END_TIME <= endTimeTo.Value.AddDays(1));
            }
            return schema;
        }

        /*
         * 实现 Kean.Application.Query.Interfaces.IRecordService.GetApiRecordCount 方法
         */
        public async Task<int> GetApiRecordCount(
            string userName,
            string method,
            string controlerName,
            DateTime? requestTimeFrom,
            DateTime? requestTimeTo)
        {
            return (await GetApiRecordSchema(userName, method, controlerName, requestTimeFrom, requestTimeTo)
                .Single(r => new { Count = Function.Count(r.ID) }))
                .Count;
        }

        /*
         * 实现 Kean.Application.Query.Interfaces.IRecordService.GetApiRecordList 方法
         */
        public async Task<IEnumerable<ApiRecord>> GetApiRecordList(
             string userName,
            string method,
            string controlerName,
            DateTime? requestTimeFrom,
            DateTime? requestTimeTo,
            string sort,
            int? offset,
            int? limit)
        {
            var properties = new Dictionary<string, string>();
            return _mapper.Map<IEnumerable<ApiRecord>>(await GetApiRecordSchema(userName, method, controlerName, requestTimeFrom, requestTimeTo)
                .Sort<V_API_RECORD, ApiRecord>(sort, _mapper)
                .OrderBy(r => r.ID, Infrastructure.Database.Order.Descending)
                .Page(offset, limit)
                .Select());
        }

        /*
         * 组织 GetApiRecord 相关方法的条件
         */
        private ISchema<V_API_RECORD> GetApiRecordSchema(
            string userName,
            string method,
            string controlerName,
            DateTime? requestTimeFrom,
            DateTime? requestTimeTo)
        {
            var schema = _database.From<V_API_RECORD>();
            if (!string.IsNullOrEmpty(userName))
            {
                schema = schema.Where(r => r.USER_NAME.Contains(userName));
            }
            if (!string.IsNullOrEmpty(method))
            {
                schema = schema.Where(r => r.METHOD.Contains(method));
            }
            if (!string.IsNullOrEmpty(controlerName))
            {
                schema = schema.Where(r => r.CONTROLLER_NAME.Contains(controlerName));
            }
            if (requestTimeFrom.HasValue)
            {
                schema = schema.Where(r => r.REQUEST_TIME >= requestTimeFrom.Value);
            }
            if (requestTimeTo.HasValue)
            {
                schema = schema.Where(r => r.REQUEST_TIME <= requestTimeTo.Value.AddDays(1));
            }
            return schema;
        }

        /*
        * 实现 Kean.Application.Query.Interfaces.IRecordService.RecordStatistics 方法
        */
        public async Task<object> RecordStatistics(
            DateTime startTimeFrom,
            DateTime endTimeTo,
            string statisticsType,
            bool bAC,
            string statisticsType2)
        {
            List<string> xDates = new List<string>();
            List<RecordStatisticsData> inDataList = new List<RecordStatisticsData>();
            List<RecordStatisticsData> outDataList = new List<RecordStatisticsData>();

            //时段
            //DateTime requestTimeFrom = Convert.ToDateTime(startTimeFrom.ToString("yyyy-MM-dd"));
            //DateTime requestTimeTo = Convert.ToDateTime(endTimeTo.ToString("yyyy-MM-dd"));
            TimeSpan pickTimeFrom = new TimeSpan(startTimeFrom.Hour, startTimeFrom.Minute, startTimeFrom.Second);
            TimeSpan pickTimeTo = new TimeSpan(endTimeTo.Hour, endTimeTo.Minute, (endTimeTo.Hour == 23 && endTimeTo.Minute == 59) ? 59 : 0);

            DateTime requestTimeFrom = startTimeFrom;
            DateTime requestTimeTo = endTimeTo;


            switch (statisticsType)
            {
                case "day":
                    //x轴 日期
                    for (DateTime temp = requestTimeFrom; temp <= requestTimeTo; temp = temp.AddDays(1))
                    {
                        xDates.Add(temp.ToString("yyyy-MM-dd"));
                    }

                    if (statisticsType2 == "EA")
                    {
                        inDataList.AddRange((List<RecordStatisticsData>)await this.GetInRecordStatistics(requestTimeFrom, requestTimeTo, xDates, bAC, statisticsType, pickTimeFrom, pickTimeTo));

                        outDataList.AddRange((List<RecordStatisticsData>)await this.GetOutRecordStatistics(requestTimeFrom, requestTimeTo, xDates, bAC, statisticsType, pickTimeFrom, pickTimeTo));
                    }
                    else
                    {
                        inDataList.AddRange((List<RecordStatisticsData>)await this.GetInRecordStatisticsByStock(requestTimeFrom, requestTimeTo, xDates, bAC, statisticsType, pickTimeFrom, pickTimeTo));

                        outDataList.AddRange((List<RecordStatisticsData>)await this.GetOutRecordStatisticsByStock(requestTimeFrom, requestTimeTo, xDates, bAC, statisticsType, pickTimeFrom, pickTimeTo));
                    }


                    break;
                case "week":

                    //起始日期的周一
                    DateTime timeFrom = requestTimeFrom.AddDays(1 - Convert.ToInt16(requestTimeFrom.DayOfWeek));
                    //终止日期的周日
                    DateTime timeTo = requestTimeTo.AddDays(0 - Convert.ToInt16(requestTimeTo.DayOfWeek) + 7);

                    //x轴 日期
                    for (DateTime temp = timeFrom; temp <= timeTo; temp = temp.AddDays(7))
                    {
                        xDates.Add(temp.ToString("yyyy-MM-dd"));
                    }

                    if (statisticsType2 == "EA")
                    {
                        inDataList.AddRange((List<RecordStatisticsData>)await this.GetInRecordStatistics(timeFrom, timeTo, xDates, bAC, statisticsType, pickTimeFrom, pickTimeTo));

                        outDataList.AddRange((List<RecordStatisticsData>)await this.GetOutRecordStatistics(timeFrom, timeTo, xDates, bAC, statisticsType, pickTimeFrom, pickTimeTo));
                    }
                    else
                    {
                        inDataList.AddRange((List<RecordStatisticsData>)await this.GetInRecordStatisticsByStock(timeFrom, timeTo, xDates, bAC, statisticsType, pickTimeFrom, pickTimeTo));

                        outDataList.AddRange((List<RecordStatisticsData>)await this.GetOutRecordStatisticsByStock(timeFrom, timeTo, xDates, bAC, statisticsType, pickTimeFrom, pickTimeTo));
                    }

                    break;
                case "month":
                    //起始日期的月一
                    DateTime monthTimeFrom = requestTimeFrom.AddDays(1 - requestTimeFrom.Day);
                    //终止日期的月最后
                    DateTime monthTimeTo = requestTimeTo.AddDays(1 - requestTimeTo.Day).AddMonths(1).AddDays(-1);

                    for (DateTime temp = monthTimeFrom; temp <= monthTimeTo; temp = temp.AddMonths(1))
                    {
                        xDates.Add(temp.ToString("yyyy-MM"));
                    }

                    if (statisticsType2 == "EA")
                    {
                        inDataList.AddRange((List<RecordStatisticsData>)await this.GetInRecordStatistics(monthTimeFrom, monthTimeTo, xDates, bAC, statisticsType, pickTimeFrom, pickTimeTo));

                        outDataList.AddRange((List<RecordStatisticsData>)await this.GetOutRecordStatistics(monthTimeFrom, monthTimeTo, xDates, bAC, statisticsType, pickTimeFrom, pickTimeTo));
                    }
                    else
                    {
                        inDataList.AddRange((List<RecordStatisticsData>)await this.GetInRecordStatisticsByStock(monthTimeFrom, monthTimeTo, xDates, bAC, statisticsType, pickTimeFrom, pickTimeTo));

                        outDataList.AddRange((List<RecordStatisticsData>)await this.GetOutRecordStatisticsByStock(monthTimeFrom, monthTimeTo, xDates, bAC, statisticsType, pickTimeFrom, pickTimeTo));
                    }

                    break;
                default:
                    break;
            }

            return new
            {
                xDates = xDates.ToArray(),
                inDataList,
                outDataList
            };
        }

        public async Task<object> GetInRecordStatistics(
            DateTime requestTimeFrom,
            DateTime requestTimeTo,
            List<string> xDates,
            bool bAC,
            string statisticsType,
            TimeSpan pickTimeFrom,
            TimeSpan pickTimeTo)
        {
            //requestTimeTo = requestTimeTo.AddDays(1);
            //入库数据
            var recordInSchema = _database.From<V_RECORD_LIST>().Lock(Lock.Nolock)
                .Where(r => r.BEGIN_TIME >= requestTimeFrom && r.BEGIN_TIME <= requestTimeTo)
                .Where(r => r.RECORD_TYPE == "Infeed")
                .Where(r => r.GOODS_ID != 5 && r.GOODS_ID != 9);


            //if (pickTimeFrom < pickTimeTo)
            //{
            //    recordInSchema = recordInSchema.Where(r => r.PICK_TIME >= pickTimeFrom && r.PICK_TIME < pickTimeTo);
            //}
            //else
            //{
            //    recordInSchema = recordInSchema.Where(r => (r.PICK_TIME >= pickTimeFrom || r.PICK_TIME < pickTimeTo));
            //}

            if (statisticsType == "day")
            {
                recordInSchema = recordInSchema.GroupBy(r => r.BEGIN_DATE);
            }
            else if (statisticsType == "week")
            {
                recordInSchema = recordInSchema.GroupBy(r => r.BEGIN_WEEK);
            }
            else if (statisticsType == "month")
            {
                recordInSchema = recordInSchema.GroupBy(r => r.BEGIN_MONTH);
            }

            if (bAC)
            {
                recordInSchema = recordInSchema.GroupBy(r => r.GOODS_NAME);
            }


            object recordInData = null;
            if (!bAC)
            {
                switch (statisticsType)
                {
                    case "day":

                        recordInData = (await recordInSchema.Select(r => new
                        {
                            name = r.BEGIN_DATE,
                            value = Function.Sum(r.QTY)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = "入库EA",
                            value = r.value
                        });

                        break;
                    case "week":

                        recordInData = (await recordInSchema.Select(r => new
                        {
                            name = r.BEGIN_WEEK,
                            value = Function.Sum(r.QTY)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = "入库EA",
                            value = r.value
                        });

                        break;
                    case "month":

                        recordInData = (await recordInSchema.Select(r => new
                        {
                            name = r.BEGIN_MONTH,
                            value = Function.Sum(r.QTY)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = "入库EA",
                            value = r.value
                        });

                        break;
                    default:
                        break;
                }


            }
            else
            {
                switch (statisticsType)
                {
                    case "day":

                        recordInData = (await recordInSchema.Select(r => new
                        {
                            name = r.BEGIN_DATE,
                            r.GOODS_NAME,
                            value = Function.Sum(r.QTY)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = $"{r.GOODS_NAME}入库EA",
                            value = r.value
                        });

                        break;
                    case "week":

                        recordInData = (await recordInSchema.Select(r => new
                        {
                            name = r.BEGIN_WEEK,
                            r.GOODS_NAME,
                            value = Function.Sum(r.QTY)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = $"{r.GOODS_NAME}入库EA",
                            value = r.value
                        });

                        break;
                    case "month":

                        recordInData = (await recordInSchema.Select(r => new
                        {
                            name = r.BEGIN_MONTH,
                            r.GOODS_NAME,
                            value = Function.Sum(r.QTY)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = $"{r.GOODS_NAME}入库EA",
                            value = r.value
                        });

                        break;
                    default:
                        break;

                }
               
            }

            List<RecordStatisticsData> inDataList = new List<RecordStatisticsData>();

            foreach (var n in (IEnumerable<dynamic>)recordInData)
            {
                if (inDataList.Where(r => r.Name == n.type).Count() == 0)
                {
                    RecordStatisticsData inData = new RecordStatisticsData();
                    inData.Name = n.type;
                    inData.Data = new int[xDates.Count];
                    for (int i = 0; i < xDates.Count; i++)
                    {
                        var tempIn = ((IEnumerable<dynamic>)recordInData).Where(m => m.name == xDates[i] && m.type == n.type);
                        if (tempIn.Count() > 0)
                        {
                            if (tempIn.First().value != null)
                            {
                                inData.Data[i] = Convert.ToInt32(tempIn.First().value);
                            }

                        }
                    }
                    inDataList.Add(inData);
                }

            }

            return inDataList;
        }

        public async Task<object> GetInRecordStatisticsByStock(
    DateTime requestTimeFrom,
    DateTime requestTimeTo,
    List<string> xDates,
    bool bAC,
    string statisticsType,
    TimeSpan pickTimeFrom,
    TimeSpan pickTimeTo)
        {
            //requestTimeTo = requestTimeTo.AddDays(1);
            //入库数据
            var recordInSchema = _database.From<V_RECORD>().Lock(Lock.Nolock)
                .Where(r => r.BEGIN_TIME >= requestTimeFrom && r.BEGIN_TIME <= requestTimeTo)
                .Where(r => r.RECORD_TYPE == "Infeed");

            //if (pickTimeFrom < pickTimeTo)
            //{
            //    recordInSchema = recordInSchema.Where(r => r.PICK_TIME >= pickTimeFrom && r.PICK_TIME < pickTimeTo);
            //}
            //else
            //{
            //    recordInSchema = recordInSchema.Where(r => (r.PICK_TIME >= pickTimeFrom || r.PICK_TIME < pickTimeTo));
            //}

            if (statisticsType == "day")
            {
                recordInSchema = recordInSchema.GroupBy(r => r.BEGIN_DATE);
            }
            else if (statisticsType == "week")
            {
                recordInSchema = recordInSchema.GroupBy(r => r.BEGIN_WEEK);
            }
            else if (statisticsType == "month")
            {
                recordInSchema = recordInSchema.GroupBy(r => r.BEGIN_MONTH);
            }

            if (bAC)
            {
                recordInSchema = recordInSchema.GroupBy(r => r.GOODS_NAME);
            }


            object recordInData = null;
            if (!bAC)
            {
                switch (statisticsType)
                {
                    case "day":

                        recordInData = (await recordInSchema.Select(r => new
                        {
                            name = r.BEGIN_DATE,
                            value = Function.Count(r.BEGIN_DATE)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = "入库托盘数",
                            value = r.value
                        });

                        break;
                    case "week":

                        recordInData = (await recordInSchema.Select(r => new
                        {
                            name = r.BEGIN_WEEK,
                            value = Function.Count(r.BEGIN_WEEK)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = "入库托盘数",
                            value = r.value
                        });

                        break;
                    case "month":

                        recordInData = (await recordInSchema.Select(r => new
                        {
                            name = r.BEGIN_MONTH,
                            value = Function.Count(r.BEGIN_MONTH)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = "入库托盘数",
                            value = r.value
                        });

                        break;
                    default:
                        break;
                }


            }
            else
            {
                switch (statisticsType)
                {
                    case "day":

                        recordInData = (await recordInSchema.Select(r => new
                        {
                            name = r.BEGIN_DATE,
                            r.GOODS_NAME,
                            value = Function.Count(r.BEGIN_DATE)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = $"{r.GOODS_NAME}入库托盘数",
                            value = r.value
                        });

                        break;
                    case "week":

                        recordInData = (await recordInSchema.Select(r => new
                        {
                            name = r.BEGIN_WEEK,
                            r.GOODS_NAME,
                            value = Function.Count(r.BEGIN_WEEK)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = $"{r.GOODS_NAME}入库托盘数",
                            value = r.value
                        });

                        break;
                    case "month":

                        recordInData = (await recordInSchema.Select(r => new
                        {
                            name = r.BEGIN_MONTH,
                            r.GOODS_NAME,
                            value = Function.Count(r.BEGIN_MONTH)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = $"{r.GOODS_NAME}入库托盘数",
                            value = r.value
                        });

                        break;
                    default:
                        break;

                }

            }

            List<RecordStatisticsData> inDataList = new List<RecordStatisticsData>();

            foreach (var n in (IEnumerable<dynamic>)recordInData)
            {
                if (inDataList.Where(r => r.Name == n.type).Count() == 0)
                {
                    RecordStatisticsData inData = new RecordStatisticsData();
                    inData.Name = n.type;
                    inData.Data = new int[xDates.Count];
                    for (int i = 0; i < xDates.Count; i++)
                    {
                        var tempIn = ((IEnumerable<dynamic>)recordInData).Where(m => m.name == xDates[i] && m.type == n.type);
                        if (tempIn.Count() > 0)
                        {
                            if (tempIn.First().value != null)
                            {
                                inData.Data[i] = Convert.ToInt32(tempIn.First().value);
                            }

                        }
                    }
                    inDataList.Add(inData);
                }

            }

            return inDataList;
        }

        public async Task<object> GetOutRecordStatistics(
            DateTime requestTimeFrom,
            DateTime requestTimeTo,
            List<string> xDates,
            bool bAC,
            string statisticsType,
            TimeSpan pickTimeFrom,
            TimeSpan pickTimeTo)
        {
            //requestTimeTo = requestTimeTo.AddDays(1);
            //出库数据
            var recordOutSchema = _database.From<V_RECORD_LIST>().Lock(Lock.Nolock)
             .Where(r => r.BEGIN_TIME >= requestTimeFrom && r.BEGIN_TIME <= requestTimeTo)
             .Where(r => r.RECORD_TYPE == "ApplyOut" || r.RECORD_TYPE == "PalletOut")
             .Where(r => r.GOODS_ID != 5 && r.GOODS_ID != 9);

            //if (pickTimeFrom < pickTimeTo)
            //{
            //    recordOutSchema = recordOutSchema.Where(r => r.PICK_TIME >= pickTimeFrom && r.PICK_TIME < pickTimeTo);
            //}
            //else
            //{
            //    recordOutSchema = recordOutSchema.Where(r => (r.PICK_TIME >= pickTimeFrom || r.PICK_TIME < pickTimeTo));
            //}

            if (statisticsType == "day")
            {
                recordOutSchema = recordOutSchema.GroupBy(r => r.BEGIN_DATE);
            }
            else if (statisticsType == "week")
            {
                recordOutSchema = recordOutSchema.GroupBy(r => r.BEGIN_WEEK);
            }
            else if (statisticsType == "month")
            {
                recordOutSchema = recordOutSchema.GroupBy(r => r.BEGIN_MONTH);
            }

            if (bAC)
            {
                recordOutSchema = recordOutSchema.GroupBy(r => r.GOODS_NAME);
            }

            object recordOutData = null;
            if (!bAC)
            {
                switch (statisticsType)
                {
                    case "day":

                        recordOutData = (await recordOutSchema.Select(r => new
                        {
                            name = r.BEGIN_DATE,
                            value = Function.Sum(r.QTY)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = "出库EA",
                            value = r.value
                        });

                        break;
                    case "week":

                        recordOutData = (await recordOutSchema.Select(r => new
                        {
                            name = r.BEGIN_WEEK,
                            value = Function.Sum(r.QTY)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = "出库EA",
                            value = r.value
                        });

                        break;
                    case "month":

                        recordOutData = (await recordOutSchema.Select(r => new
                        {
                            name = r.BEGIN_MONTH,
                            value = Function.Sum(r.QTY)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = "出库EA",
                            value = r.value
                        });

                        break;
                }

            }
            else
            {
                switch (statisticsType)
                {
                    case "day":

                        recordOutData = (await recordOutSchema.Select(r => new
                        {
                            name = r.BEGIN_DATE,
                            r.GOODS_NAME,
                            value = Function.Sum(r.QTY)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = $"{r.GOODS_NAME}出库EA",
                            value = r.value
                        });

                        break;
                    case "week":

                        recordOutData = (await recordOutSchema.Select(r => new
                        {
                            name = r.BEGIN_WEEK,
                            r.GOODS_NAME,
                            value = Function.Sum(r.QTY)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = $"{r.GOODS_NAME}出库EA",
                            value = r.value
                        });

                        break;
                    case "month":

                        recordOutData = (await recordOutSchema.Select(r => new
                        {
                            name = r.BEGIN_MONTH,
                            r.GOODS_NAME,
                            value = Function.Sum(r.QTY)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = $"{r.GOODS_NAME}出库EA",
                            value = r.value
                        });

                        break;
                }


            }

            List<RecordStatisticsData> outDataList = new List<RecordStatisticsData>();

            foreach (var n in ((IEnumerable<dynamic>)recordOutData))
            {
                if (outDataList.Where(r => r.Name == n.type).Count() == 0)
                {
                    RecordStatisticsData outData = new RecordStatisticsData();
                    outData.Name = n.type;
                    outData.Data = new int[xDates.Count];
                    for (int i = 0; i < xDates.Count; i++)
                    {
                        var tempOut = ((IEnumerable<dynamic>)recordOutData).Where(m => m.name == xDates[i] && m.type == n.type);
                        if (tempOut.Count() > 0)
                        {
                            if (tempOut.First().value != null)
                            {
                                outData.Data[i] = Convert.ToInt32(tempOut.First().value);
                            }

                        }
                    }
                    outDataList.Add(outData);
                }
            }

            return outDataList;
        }

        public async Task<object> GetOutRecordStatisticsByStock(
    DateTime requestTimeFrom,
    DateTime requestTimeTo,
    List<string> xDates,
    bool bAC,
    string statisticsType,
    TimeSpan pickTimeFrom,
    TimeSpan pickTimeTo)
        {
            //requestTimeTo = requestTimeTo.AddDays(1);
            //出库数据
            var recordOutSchema = _database.From<V_RECORD>().Lock(Lock.Nolock)
             .Where(r => r.BEGIN_TIME >= requestTimeFrom && r.BEGIN_TIME <= requestTimeTo)
             .Where(r => r.RECORD_TYPE == "ApplyOut" || r.RECORD_TYPE == "PalletOut");

            //if (pickTimeFrom < pickTimeTo)
            //{
            //    recordOutSchema = recordOutSchema.Where(r => r.PICK_TIME >= pickTimeFrom && r.PICK_TIME < pickTimeTo);
            //}
            //else
            //{
            //    recordOutSchema = recordOutSchema.Where(r => (r.PICK_TIME >= pickTimeFrom || r.PICK_TIME < pickTimeTo));
            //}

            if (statisticsType == "day")
            {
                recordOutSchema = recordOutSchema.GroupBy(r => r.BEGIN_DATE);
            }
            else if (statisticsType == "week")
            {
                recordOutSchema = recordOutSchema.GroupBy(r => r.BEGIN_WEEK);
            }
            else if (statisticsType == "month")
            {
                recordOutSchema = recordOutSchema.GroupBy(r => r.BEGIN_MONTH);
            }

            if (bAC)
            {
                recordOutSchema = recordOutSchema.GroupBy(r => r.GOODS_NAME);
            }

            object recordOutData = null;
            if (!bAC)
            {
                switch (statisticsType)
                {
                    case "day":

                        recordOutData = (await recordOutSchema.Select(r => new
                        {
                            name = r.BEGIN_DATE,
                            value = Function.Count(r.BEGIN_DATE)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = "出库托盘数",
                            value = r.value
                        });

                        break;
                    case "week":

                        recordOutData = (await recordOutSchema.Select(r => new
                        {
                            name = r.BEGIN_WEEK,
                            value = Function.Count(r.BEGIN_WEEK)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = "出库托盘数",
                            value = r.value
                        });

                        break;
                    case "month":

                        recordOutData = (await recordOutSchema.Select(r => new
                        {
                            name = r.BEGIN_MONTH,
                            value = Function.Count(r.BEGIN_MONTH)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = "出库托盘数",
                            value = r.value
                        });

                        break;
                }

            }
            else
            {
                switch (statisticsType)
                {
                    case "day":

                        recordOutData = (await recordOutSchema.Select(r => new
                        {
                            name = r.BEGIN_DATE,
                            r.GOODS_NAME,
                            value = Function.Count(r.BEGIN_DATE)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = $"{r.GOODS_NAME}出库托盘数",
                            value = r.value
                        });

                        break;
                    case "week":

                        recordOutData = (await recordOutSchema.Select(r => new
                        {
                            name = r.BEGIN_WEEK,
                            r.GOODS_NAME,
                            value = Function.Count(r.BEGIN_WEEK)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = $"{r.GOODS_NAME}出库托盘数",
                            value = r.value
                        });

                        break;
                    case "month":

                        recordOutData = (await recordOutSchema.Select(r => new
                        {
                            name = r.BEGIN_MONTH,
                            r.GOODS_NAME,
                            value = Function.Count(r.BEGIN_MONTH)
                        })).Select(r => new
                        {
                            name = r.name,
                            type = $"{r.GOODS_NAME}出库托盘数",
                            value = r.value
                        });

                        break;
                }


            }

            List<RecordStatisticsData> outDataList = new List<RecordStatisticsData>();

            foreach (var n in ((IEnumerable<dynamic>)recordOutData))
            {
                if (outDataList.Where(r => r.Name == n.type).Count() == 0)
                {
                    RecordStatisticsData outData = new RecordStatisticsData();
                    outData.Name = n.type;
                    outData.Data = new int[xDates.Count];
                    for (int i = 0; i < xDates.Count; i++)
                    {
                        var tempOut = ((IEnumerable<dynamic>)recordOutData).Where(m => m.name == xDates[i] && m.type == n.type);
                        if (tempOut.Count() > 0)
                        {
                            if (tempOut.First().value != null)
                            {
                                outData.Data[i] = Convert.ToInt32(tempOut.First().value);
                            }

                        }
                    }
                    outDataList.Add(outData);
                }
            }

            return outDataList;
        }

        private class RecordStatisticsData
        {
            public string Name { get; set; }
            public int[] Data { get; set; }
        }

        /*
         * 实现 Kean.Application.Query.Interfaces.IRecordService.GetErrfeedbackList 方法
         */
        public async Task<IEnumerable<ErrFeedback>> GetErrfeedbackList(
            string method,
            string requestNo,
            string barcode,
            string[] result,
            DateTime? beginTimeFrom,
            DateTime? beginTimeTo,
            DateTime? endTimeFrom,
            DateTime? endTimeTo,
            string sort,
            int? offset,
            int? limit)
        {
            var properties = new Dictionary<string, string>();
            return _mapper.Map<IEnumerable<ErrFeedback>>(await GetErrFeedbackSchema(method, requestNo, barcode, result, beginTimeFrom, beginTimeTo, endTimeFrom, endTimeTo)
                .Sort<T_ERROR_FEEDBACK, ErrFeedback>(sort, _mapper)
                .OrderBy(r => r.START_TIME, Infrastructure.Database.Order.Ascending)
                .OrderBy(r => r.ID, Infrastructure.Database.Order.Ascending)
                .Page(offset, limit)
                .Select());
        }

        /*
        * 实现 Kean.Application.Query.Interfaces.IRecordService.GetErrfeedbackCount 方法
        */
        public async Task<int> GetErrfeedbackCount(
            string method,
            string requestNo,
            string barcode,
            string[] result,
            DateTime? beginTimeFrom,
            DateTime? beginTimeTo,
            DateTime? endTimeFrom,
            DateTime? endTimeTo)
        {
            return (await GetErrFeedbackSchema(method, requestNo, barcode, result, beginTimeFrom, beginTimeTo, endTimeFrom, endTimeTo)
                .Single(r => new { Count = Function.Count(r.ID) }))
                .Count;
        }

        /*
        * 组织 GetErrFeedback 相关方法的条件
        */
        private ISchema<T_ERROR_FEEDBACK> GetErrFeedbackSchema(
            string method,
            string requestNo,
            string barcode,
            string[] result,
            DateTime? beginTimeFrom,
            DateTime? beginTimeTo,
            DateTime? endTimeFrom,
            DateTime? endTimeTo)
        {
            var schema = _database.From<T_ERROR_FEEDBACK>();
            if (method != null)
            {
                schema = schema.Where(r => r.METHOD.Contains(method));
            }
            if (requestNo != null)
            {
                schema = schema.Where(r => r.REQUEST_NO.Contains(requestNo));
            }
            if (barcode != null)
            {
                schema = schema.Where(r => r.BARCODE.Contains(barcode));
            }
            if (result != null)
            {

                schema = schema.Where(r => result.Contains(r.RESULT));
            }
            if (beginTimeFrom.HasValue)
            {
                schema = schema.Where(r => r.START_TIME >= beginTimeFrom.Value);
            }
            if (beginTimeTo.HasValue)
            {
                schema = schema.Where(r => r.START_TIME <= beginTimeTo.Value.AddDays(1));
            }
            if (endTimeFrom.HasValue)
            {
                schema = schema.Where(r => r.LAST_END_TIME >= endTimeFrom.Value);
            }
            if (endTimeTo.HasValue)
            {
                schema = schema.Where(r => r.LAST_END_TIME <= endTimeTo.Value.AddDays(1));
            }
            return schema;
        }

    }
}