using System;
using System.Linq;
using Infrastructure;
using WebRepository;

namespace WebApp
{
    /// <summary>
    /// 入库单下发接口App
    /// </summary>

    public partial class IReceiptApp : ApiApp
    {
        public IRepository<ReceiptHeader> _app;
        public IReceiptApp(IUnitWork unitWork, IAuth auth, BaseDBContext context, IRepository<ReceiptHeader> repository) : base(unitWork, auth, context)
        {
            _app = repository;
        }

        public string InsertReceipt(IReceiptModel receipts)
        {
            Response Response = new Response();

            if (!CheckLogin())
            {
                Response.Code = 500;
                Response.Status = false;
                Response.Message = "请先登录!";
                return JsonHelper.Instance.Serialize(Response);
            }

            try
            {
                #region 保存入库单接口主表
                IreceiptHeader headdata = _unitWork.FindSingle<IreceiptHeader>(u => u.SourceCode.Equals(receipts.receiptHeader.SourceCode));
                receipts.receiptHeader.ReceiveTime = DateTime.Now;
                receipts.receiptHeader.Id = (headdata?.Id);
                if (receipts.receiptHeader.Id == null)
                {
                    if (receipts.receiptHeader.CreateBy == null)
                    {
                        receipts.receiptHeader.CreateBy = "wms";
                        receipts.receiptHeader.CreateTime = DateTime.Now;
                    }
                    _unitWork.Add(receipts.receiptHeader);
                }
                else
                {
                    if (receipts.receiptHeader.UpdateBy == null)
                    {
                        receipts.receiptHeader.UpdateBy = "wms";
                        receipts.receiptHeader.UpdateTime = DateTime.Now;
                    }
                    _unitWork.Update(receipts.receiptHeader);
                }
                #endregion

                #region 保存入库单主表
                ReceiptHeader receiptHeader = _unitWork.FindSingle<ReceiptHeader>(u => u.SourceCode.Equals(receipts.receiptHeader.SourceCode));
                if (receiptHeader != null)
                {
                    if (receiptHeader.FirstStatus != ReceiptHeaderStatus.新建)
                    {
                        throw new Exception("单据进入订单池后,不允许修改!");
                    }
                }
                else
                {
                    receiptHeader = new ReceiptHeader();
                }

                receiptHeader.Type = receipts.receiptHeader.Type;
                receiptHeader.SourceCode = receipts.receiptHeader.SourceCode;
                receiptHeader.Station = receipts.receiptHeader.Station ?? "";
                receiptHeader.WarehouseType = receipts.receiptHeader.WarehouseType;
                receiptHeader.SupplierId = receipts.receiptHeader.SupplierId;
                receiptHeader.SupplierCode = receipts.receiptHeader.SupplierCode;
                receiptHeader.SupplierName = receipts.receiptHeader.SupplierName;
                receiptHeader.CreateTime = receipts.receiptHeader.CreateTime;
                receiptHeader.CreateBy = receipts.receiptHeader.CreateBy;
                receiptHeader.UpdateTime = receipts.receiptHeader.UpdateTime;
                receiptHeader.UpdateBy = receipts.receiptHeader.UpdateBy;

                receiptHeader.Code = string.IsNullOrEmpty(receiptHeader.Code) ? _unitWork.GetTaskNo(receipts.receiptHeader.Type) : receiptHeader.Code;
                receiptHeader.UploadStatus = 0;
                receiptHeader.FirstStatus = ReceiptHeaderStatus.新建;
                receiptHeader.LastStatus = ReceiptHeaderStatus.新建;
                receiptHeader.TotalLines = 0;
                receiptHeader.TotalQty = 0;

                if (receiptHeader.Id == null)
                {
                    if (receiptHeader.CreateBy == null)
                    {
                        receiptHeader.CreateBy = "wms";
                        receiptHeader.CreateTime = DateTime.Now;
                    }
                    _unitWork.Add(receiptHeader);
                }
                else
                {
                    if (receiptHeader.UpdateBy == null)
                    {
                        receiptHeader.UpdateBy = "wms";
                        receiptHeader.UpdateTime = DateTime.Now;
                    }
                    _unitWork.Update(receiptHeader);
                }
                #endregion

                short? totalLines = 0;
                decimal? qty = 0;

                foreach (var item in receipts.receiptDetails)
                {
                    try
                    {
                        #region 保存入库单接口子表
                        IreceiptDetail data = _context.Set<IreceiptDetail>().AsQueryable().Where(u => u.SourceCode.Equals(item.SourceCode) && u.MaterialCode.Equals(item.MaterialCode)).SingleOrDefault();
                        item.ReceiveTime = DateTime.Now;
                        item.Id = (data?.Id);

                        if (item.Id == null)
                        {
                            if (item.CreateBy == null)
                            {
                                item.CreateBy = "wms";
                                item.CreateTime = DateTime.Now;
                            }
                            _unitWork.Add(item);
                        }
                        else
                        {
                            if (item.UpdateBy == null)
                            {
                                item.UpdateBy = "wms";
                                item.UpdateTime = DateTime.Now;
                            }
                            _unitWork.Update(item);
                        }
                        #endregion

                        #region 保存入库单子表
                        ReceiptDetail receiptDetail = _context.Set<ReceiptDetail>().AsQueryable().Where(u => u.SourceCode.Equals(item.SourceCode) && u.MaterialCode.Equals(item.MaterialCode)).SingleOrDefault();
                        if (receiptDetail == null)
                        {
                            receiptDetail = new ReceiptDetail();
                        }

                        receiptDetail.SourceCode = item.SourceCode;
                        receiptDetail.Station = item.Station ?? "";
                        receiptDetail.MaterialCode = item.MaterialCode;
                        receiptDetail.Lot = item.Lot;
                        receiptDetail.InventoryStatus = item.InventoryStatus;
                        receiptDetail.Qty = item.Qty;
                        receiptDetail.CreateTime = item.CreateTime;
                        receiptDetail.CreateBy = item.CreateBy;
                        receiptDetail.UpdateTime = item.UpdateTime;
                        receiptDetail.UpdateBy = item.UpdateBy;

                        receiptDetail.ReceiptId = receiptHeader.Id;
                        receiptDetail.ReceiptCode = receiptHeader.Code;
                        receiptDetail.QtyDivided = 0;
                        receiptDetail.QtyCompleted = 0;
                        receiptDetail.Price = 0;
                        receiptDetail.Status = ReceiptHeaderStatus.新建;

                        if (receiptDetail.Id == null)
                        {
                            if (receiptDetail.CreateBy == null)
                            {
                                receiptDetail.CreateBy = "wms";
                                receiptDetail.CreateTime = DateTime.Now;
                            }
                            _unitWork.Add(receiptDetail);
                        }
                        else
                        {
                            if (receiptDetail.UpdateBy == null)
                            {
                                receiptDetail.UpdateBy = "wms";
                                receiptDetail.UpdateTime = DateTime.Now;
                            }
                            _unitWork.Update(receiptDetail);
                        }
                        #endregion

                        totalLines += 1;
                        qty += item.Qty;
                    }
                    catch (Exception ex)
                    {
                        #region 记录入库单接口子表错误信息
                        IreceiptDetail data = _context.Set<IreceiptDetail>().AsQueryable().Where(u => u.SourceCode.Equals(item.SourceCode) && u.MaterialCode.Equals(item.MaterialCode)).SingleOrDefault();
                        if (data != null)
                        {
                            data.ErrorMessage = ex.Message;
                            if (data.UpdateBy == null)
                            {
                                data.UpdateBy = "wms";
                                data.UpdateTime = DateTime.Now;
                            }
                            _unitWork.Update(data);
                        }
                        #endregion

                        Response.Code = 500;
                        Response.Status = false;
                        Response.Message = (Response.Message == "操作成功" ? "" : Response.Message) + "\r\n" + "SourceCode:" + item.SourceCode + ",MaterialCode:" + item.MaterialCode + "同步失败:" + ex.Message;
                    }
                }

                #region 更新入库单主表汇总信息
                receiptHeader.TotalLines += (short)_unitWork.Find<ReceiptDetail>(n => n.ReceiptCode == receiptHeader.Code).ToList().Count;
                receiptHeader.TotalQty += _unitWork.Find<ReceiptDetail>(n => n.ReceiptCode == receiptHeader.Code).Sum(x => x.Qty);
                if (receiptHeader.UpdateBy == null)
                {
                    receiptHeader.UpdateBy = "wms";
                    receiptHeader.UpdateTime = DateTime.Now;
                }
                _unitWork.Update(receiptHeader);
                #endregion
            }
            catch (Exception ex)
            {
                #region 记录入库单接口主表错误信息
                try
                {
                    IreceiptHeader data = _context.Set<IreceiptHeader>().AsQueryable().Where(u => u.SourceCode.Equals(receipts.receiptHeader.SourceCode)).SingleOrDefault();
                    if (data != null)
                    {
                        data.ErrorMessage = ex.Message;
                        if (data.UpdateBy == null)
                        {
                            data.UpdateBy = "wms";
                            data.UpdateTime = DateTime.Now;
                        }
                        _unitWork.Update(data);
                    }
                }
                catch (Exception)
                {
                }
                #endregion

                Response.Code = 500;
                Response.Status = false;
                Response.Message = (Response.Message == "操作成功" ? "" : Response.Message) + "\r\n" + "同步失败:" + ex.Message;
            }

            return JsonHelper.Instance.Serialize(Response);
        }

        public Response InsertReceiptOut(IReceiptModel receipts)
        {
            Response Response = new Response();
            using (var tran = _context.Database.BeginTransaction())
            {

                if (!CheckLogin())
                {
                    Response.Code = 500;
                    Response.Status = false;
                    Response.Message = "请先登录!";
                    return Response;
                }

                try
                {
                    #region 保存入库单接口主表
                    IreceiptHeader headdata = _unitWork.FindSingle<IreceiptHeader>(u => u.SourceCode.Equals(receipts.receiptHeader.SourceCode));
                    receipts.receiptHeader.ReceiveTime = DateTime.Now;
                    receipts.receiptHeader.Id = (headdata?.Id);
                    if (receipts.receiptHeader.Id == null)
                    {
                        if (receipts.receiptHeader.CreateBy == null)
                        {
                            receipts.receiptHeader.CreateBy = "wms";
                            receipts.receiptHeader.CreateTime = DateTime.Now;
                        }
                        _unitWork.Add(receipts.receiptHeader);
                    }
                    else
                    {
                        if (receipts.receiptHeader.UpdateBy == null)
                        {
                            receipts.receiptHeader.UpdateBy = "wms";
                            receipts.receiptHeader.UpdateTime = DateTime.Now;
                        }
                        _unitWork.Update(receipts.receiptHeader);
                    }
                    #endregion

                    #region 保存入库单主表
                    ReceiptHeader receiptHeader = _unitWork.FindSingle<ReceiptHeader>(u => u.SourceCode.Equals(receipts.receiptHeader.SourceCode));
                    if (receiptHeader != null)
                    {
                        if (receiptHeader.FirstStatus != ReceiptHeaderStatus.新建)
                        {
                            throw new Exception("单据进入订单池后,不允许修改!");
                        }
                    }
                    else
                    {
                        receiptHeader = new ReceiptHeader();
                    }

                    receiptHeader.Type = receipts.receiptHeader.Type;
                    receiptHeader.SourceCode = receipts.receiptHeader.SourceCode;
                    receiptHeader.Station = receipts.receiptHeader.Station ?? "";
                    receiptHeader.WarehouseType = receipts.receiptHeader.WarehouseType;
                    receiptHeader.SupplierId = receipts.receiptHeader.SupplierId;
                    receiptHeader.SupplierCode = receipts.receiptHeader.SupplierCode;
                    receiptHeader.SupplierName = receipts.receiptHeader.SupplierName;
                    receiptHeader.CreateTime = receipts.receiptHeader.CreateTime;
                    receiptHeader.CreateBy = receipts.receiptHeader.CreateBy;
                    receiptHeader.UpdateTime = receipts.receiptHeader.UpdateTime;
                    receiptHeader.UpdateBy = receipts.receiptHeader.UpdateBy;

                    receiptHeader.Code = string.IsNullOrEmpty(receiptHeader.Code) ? _unitWork.GetTaskNo(receipts.receiptHeader.Type) : receiptHeader.Code;
                    receiptHeader.UploadStatus = 0;
                    receiptHeader.FirstStatus = ReceiptHeaderStatus.回传;
                    receiptHeader.LastStatus = ReceiptHeaderStatus.回传;
                    receiptHeader.TotalLines = 0;
                    receiptHeader.TotalQty = 0;

                    if (receiptHeader.Id == null)
                    {
                        if (receiptHeader.CreateBy == null)
                        {
                            receiptHeader.CreateBy = "wms";
                            receiptHeader.CreateTime = DateTime.Now;
                        }
                        _unitWork.Add(receiptHeader);
                    }
                    else
                    {
                        if (receiptHeader.UpdateBy == null)
                        {
                            receiptHeader.UpdateBy = "wms";
                            receiptHeader.UpdateTime = DateTime.Now;
                        }
                        _unitWork.Update(receiptHeader);
                    }
                    #endregion

                    //验证站台提前获取仓位
                    StationRoadway stationRoadway = _unitWork.Find<StationRoadway>(n => n.StationCode == receiptHeader.Station).FirstOrDefault();
                    if (stationRoadway == null)
                    {
                        throw new Exception(receiptHeader.Station + "无此站台");
                    }
                    Location location = _unitWork.Find<Location>(n => n.Status == LocationStatus.空仓位 && n.Roadway == stationRoadway.RoadWay && n.IsStop == false).FirstOrDefault();
                    location.Status = LocationStatus.任务锁定中;
                    _unitWork.Update(location);
                    //插入对应物料和容器信息
                    Container container = _unitWork.Find<Container>(n => n.Code == receiptHeader.ContainerCode).FirstOrDefault();
                    if (container != null)
                    {
                        throw new Exception("库内有该托盘号" + receiptHeader.ContainerCode);
                    }
                    else if (string.IsNullOrEmpty(receiptHeader.ContainerCode))
                    {
                        throw new Exception("请填写容器");
                    }
                    Container c = new Container();
                    c.Code = receiptHeader.ContainerCode;
                    c.LocationCode = location.Code;
                    c.Status = ContainerStatus.有;
                    c.IsLock = 1;
                    c.Type = receiptHeader.ContainerType;
                    c.PrintCount = 0;
                    _unitWork.Add(c);

                    foreach (var item in receipts.receiptDetails)
                    {
                        try
                        {
                            #region 保存入库单接口子表
                            IreceiptDetail data = _context.Set<IreceiptDetail>().AsQueryable().Where(u => u.SourceCode.Equals(item.SourceCode) && u.MaterialCode.Equals(item.MaterialCode)).SingleOrDefault();
                            item.ReceiveTime = DateTime.Now;
                            item.Id = (data?.Id);

                            if (item.Id == null)
                            {
                                if (item.CreateBy == null)
                                {
                                    item.CreateBy = "wms";
                                    item.CreateTime = DateTime.Now;
                                }
                                _unitWork.Add(item);
                            }
                            else
                            {
                                if (item.UpdateBy == null)
                                {
                                    item.UpdateBy = "wms";
                                    item.UpdateTime = DateTime.Now;
                                }
                                _unitWork.Update(item);
                            }
                            #endregion

                            #region 保存入库单子表
                            ReceiptDetail receiptDetail = _context.Set<ReceiptDetail>().AsQueryable().Where(u => u.SourceCode.Equals(item.SourceCode) && u.MaterialCode.Equals(item.MaterialCode)).SingleOrDefault();
                            if (receiptDetail == null)
                            {
                                receiptDetail = new ReceiptDetail();
                            }

                            receiptDetail.SourceCode = item.SourceCode;
                            receiptDetail.Station = item.Station ?? "";
                            receiptDetail.MaterialCode = item.MaterialCode;
                            receiptDetail.Lot = item.Lot;
                            receiptDetail.InventoryStatus = item.InventoryStatus;
                            receiptDetail.Qty = item.Qty;
                            receiptDetail.CreateTime = item.CreateTime;
                            receiptDetail.CreateBy = item.CreateBy;
                            receiptDetail.UpdateTime = item.UpdateTime;
                            receiptDetail.UpdateBy = item.UpdateBy;

                            receiptDetail.ReceiptId = receiptHeader.Id;
                            receiptDetail.ReceiptCode = receiptHeader.Code;
                            receiptDetail.QtyDivided = 0;
                            receiptDetail.QtyCompleted = 0;
                            receiptDetail.Price = 0;
                            receiptDetail.Status = ReceiptHeaderStatus.回传;

                            if (receiptDetail.Id == null)
                            {
                                if (receiptDetail.CreateBy == null)
                                {
                                    receiptDetail.CreateBy = "wms";
                                    receiptDetail.CreateTime = DateTime.Now;
                                }
                                _unitWork.Add(receiptDetail);
                            }
                            else
                            {
                                if (receiptDetail.UpdateBy == null)
                                {
                                    receiptDetail.UpdateBy = "wms";
                                    receiptDetail.UpdateTime = DateTime.Now;
                                }
                                _unitWork.Update(receiptDetail);
                            }
                            #endregion

                            #region 库存添加
                            Inventory inventory = new Inventory();
                            inventory.Lot = receiptDetail.Lot;
                            inventory.WarehouseType = receiptHeader.WarehouseType;
                            inventory.LocationCode = location.Code;
                            inventory.Batch = receiptDetail.Batch;
                            inventory.ReceiptId = receiptHeader.Id;
                            inventory.ReceiptCode = receiptHeader.Code;
                            inventory.SourceLine = receiptDetail.SourceLine;
                            inventory.ReceiptDetailId = receiptDetail.Id;
                            inventory.Project = receiptDetail.Project;
                            inventory.ContainerCode = receiptHeader.ContainerCode;
                            inventory.SourceCode = receiptDetail.SourceCode;
                            inventory.MaterialCode = receiptDetail.MaterialCode;
                            inventory.MaterialId = receiptDetail.MaterialId;
                            inventory.SourceCode = receiptDetail.SourceCode;
                            inventory.Status = receiptDetail.InventoryStatus;
                            inventory.ContainerStatus = ContainerStatus.有;
                            inventory.Qty = receiptDetail.Qty;
                            inventory.TaskStatus = InventoryTaskType.无盘点任务;
                            _unitWork.Add(inventory);

                            InventoryTransaction inventoryTransaction = new InventoryTransaction();
                            inventoryTransaction.WarehouseType = inventory.WarehouseType;
                            inventoryTransaction.SourceCode = receiptHeader.SourceCode;
                            inventoryTransaction.BillCode = receiptDetail.ReceiptCode;
                            inventoryTransaction.Type = TransactionType.入库;
                            inventoryTransaction.ContainerCode = inventory.ContainerCode;
                            inventoryTransaction.MaterialCode = inventory.MaterialCode;
                            inventoryTransaction.MaterialName = _unitWork.Find<Material>(n => n.Code == inventory.ContainerCode).Select(a => a.Name).FirstOrDefault();
                            inventoryTransaction.Batch = inventory.Batch;
                            inventoryTransaction.Lot = inventory.Lot;
                            inventoryTransaction.LocationCode = inventory.LocationCode;
                            inventoryTransaction.Qty = receiptDetail.Qty;
                            inventoryTransaction.TaskQty = receiptDetail.Qty;
                            inventoryTransaction.Status = inventory.Status;
                            _unitWork.Add(inventoryTransaction);
                            #endregion
                        }
                        catch (Exception ex)
                        {
                            #region 记录入库单接口子表错误信息
                            IreceiptDetail data = _context.Set<IreceiptDetail>().AsQueryable().Where(u => u.SourceCode.Equals(item.SourceCode) && u.MaterialCode.Equals(item.MaterialCode)).SingleOrDefault();
                            if (data != null)
                            {
                                data.ErrorMessage = ex.Message;
                                if (data.UpdateBy == null)
                                {
                                    data.UpdateBy = "wms";
                                    data.UpdateTime = DateTime.Now;
                                }
                                _unitWork.Update(data);
                            }
                            #endregion

                            Response.Code = 500;
                            Response.Status = false;
                            Response.Message = (Response.Message == "操作成功" ? "" : Response.Message) + "\r\n" + "SourceCode:" + item.SourceCode + ",MaterialCode:" + item.MaterialCode + "同步失败:" + ex.Message;
                        }
                    }

                    #region 建立回库任务
                    Task task = new Task();
                    TaskDetail taskDetail = new TaskDetail();
                    var taskNo = _app.GetTaskNo(TaskNo.查看容器回库);
                    task.TaskNo = taskNo;
                    task.OrderCode = taskNo;
                    task.BusinessType = BusinessType.入库_其他入库单;
                    task.FirstStatus = TaskStatus.待下发任务;
                    task.LastStatus = TaskStatus.待下发任务;
                    _unitWork.Add(task);

                    taskDetail.TaskNo = taskNo;
                    taskDetail.OrderCode = taskNo;
                    taskDetail.TaskType = TaskType.容器回库;
                    taskDetail.ContainerCode = receiptHeader.ContainerCode;
                    taskDetail.SourceLocation = receiptHeader.Station;
                    taskDetail.DestinationLocation = location.Code;
                    taskDetail.OderQty = 0;
                    taskDetail.ContainerQty = 0;
                    taskDetail.HadQty = 0;
                    taskDetail.Roadway = stationRoadway.RoadWay;
                    taskDetail.Station = receiptHeader.Station;
                    taskDetail.Status = TaskStatus.待下发任务;
                    taskDetail.Priority = 99;
                    _unitWork.Add(taskDetail);
                    #endregion
                    #region 更新入库单主表汇总信息
                    receiptHeader.TotalLines += (short)_unitWork.Find<ReceiptDetail>(n => n.ReceiptCode == receiptHeader.Code).ToList().Count;
                    receiptHeader.TotalQty += _unitWork.Find<ReceiptDetail>(n => n.ReceiptCode == receiptHeader.Code).Sum(x => x.Qty);
                    if (receiptHeader.UpdateBy == null)
                    {
                        receiptHeader.UpdateBy = "wms";
                        receiptHeader.UpdateTime = DateTime.Now;
                    }
                    _unitWork.Update(receiptHeader);
                    #endregion
                    tran.Commit();
                    //如果都成功则给erp回传数据
                }
                catch (Exception ex)
                {
                    #region 记录入库单接口主表错误信息
                    try
                    {
                        tran.Rollback();
                        IreceiptHeader data = _context.Set<IreceiptHeader>().AsQueryable().Where(u => u.SourceCode.Equals(receipts.receiptHeader.SourceCode)).SingleOrDefault();
                        if (data != null)
                        {
                            data.ErrorMessage = ex.Message;
                            if (data.UpdateBy == null)
                            {
                                data.UpdateBy = "wms";
                                data.UpdateTime = DateTime.Now;
                            }
                            _unitWork.Update(data);
                        }
                    }
                    catch (Exception)
                    {
                    }
                    #endregion

                    Response.Code = 500;
                    Response.Status = false;
                    Response.Message = (Response.Message == "操作成功" ? "" : Response.Message) + "\r\n" + "同步失败:" + ex.Message;
                }
            }
                return Response;
        }
    }
}