using ButcherFactory.BO.Utils;
using Forks.EnterpriseServices.DomainObjects2;
using Forks.EnterpriseServices.DomainObjects2.DQuery;
using Forks.EnterpriseServices.SqlDoms;
using Forks.JsonRpc.Client;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ButcherFactory.BO.LocalBL
{
  public static class SegmentProductionBL
  {
    const string RpcPath = @"/MainSystem/B3ClientService/Rpcs/SegmentProductionRpc/";
    const string ProductTaskRpc = @"/MainSystem/B3Sale/Rpcs/SaleOutStoreRpc/GetSaleOutStoreNumber";
    const string BatchProductTaskRpc = @"/MainSystem/B3Sale/Rpcs/SaleOutStoreRpc/BatchGetSaleOutStoreNumber";

    public static BindingList<SegmentProduction> GetListByState(bool submited)
    {
      var query = new DQueryDom(new JoinAlias(typeof(SegmentProduction)));
      query.Columns.Add(DQSelectColumn.Field("ID"));
      query.Columns.Add(DQSelectColumn.Field("RowIndex"));
      query.Columns.Add(DQSelectColumn.Field("BarCode"));
      query.Columns.Add(DQSelectColumn.Field("Weight"));
      query.Columns.Add(DQSelectColumn.Field("Goods_Name"));
      query.Columns.Add(DQSelectColumn.Field("GroupID"));
      query.Columns.Add(DQSelectColumn.Field("TrunOutID"));
      query.Columns.Add(DQSelectColumn.Field("Goods_Spec"));
      query.Columns.Add(DQSelectColumn.Field("StandardPic"));
      query.Columns.Add(DQSelectColumn.Field("Goods_ID"));
      query.Columns.Add(DQSelectColumn.Field("Goods_Code"));
      query.Columns.Add(DQSelectColumn.Field("ShotPrintName"));
      query.Columns.Add(DQSelectColumn.Field("MainUnit"));
      query.Columns.Add(DQSelectColumn.Field("TotalCode_ID"));
      query.Columns.Add(DQSelectColumn.Field("TotalCode_Code"));
      query.Columns.Add(DQSelectColumn.Field("CreateTime"));
      query.Columns.Add(DQSelectColumn.Field("GoodsType"));
      query.Columns.Add(DQSelectColumn.Field("NoTotalCode"));
      query.Columns.Add(DQSelectColumn.Field("Identify"));
      query.Columns.Add(DQSelectColumn.Field("Goods_CustomerDefine"));
      query.Where.Conditions.Add(DQCondition.And(DQCondition.EQ("InStored", false), DQCondition.EQ("Delete", false), DQCondition.EQ("Submited", submited)));
      query.OrderBy.Expressions.Add(DQOrderByExpression.Create("ID", true));
      if (submited)
      {
        query.Where.Conditions.Add(DQCondition.GreaterThanOrEqual("CreateTime", DateTime.Today));
        //query.Range = SelectRange.Top(50);
      }
      var list = new BindingList<SegmentProduction>();
      using (var session = DmoSession.New())
      {
        using (var reader = session.ExecuteReader(query))
        {
          while (reader.Read())
          {
            var entity = new SegmentProduction();
            entity.ID = (long)reader[0];
            entity.RowIndex = (int?)reader[1];
            entity.BarCode = (string)reader[2];
            entity.Weight = (decimal)reader[3];
            entity.Goods_Name = (string)reader[4];
            entity.GroupID = (long?)reader[5];
            entity.TrunOutID = (long?)reader[6];
            entity.Goods_Spec = (string)reader[7];
            entity.StandardPic = (bool)reader[8];
            entity.Goods_ID = (long)reader[9];
            entity.Goods_Code = (string)reader[10];
            entity.ShotPrintName = (string)reader[11];
            entity.Submited = submited;
            entity.MainUnit = (string)reader[12];
            entity.TotalCode_ID = (long)reader[13];
            entity.TotalCode_Code = (string)reader[14];
            entity.CreateTime = (DateTime)reader[15];
            entity.GoodsType = (short?)reader[16];
            entity.NoTotalCode = (bool)reader[17];
            entity.Identify = (string)reader[18];
            entity.Goods_CustomerDefine = (string)reader[19];
            list.Add(entity);
          }
        }
      }

      return list;
    }

    public static TotalCode InitStayTotalCode()
    {
      TotalCode entity = null;
      var date = DateTime.Now;
      using (var session = DmoSession.New())
      {
        var tuple = GetStayTotalCode(date, session);
        if (tuple == null)
        {
          entity = new TotalCode();
          entity.UserID = BO.Utils.AppContext.Worker.ID;
          entity.GoodsType = 1;
          entity.NoTotalCode = true;
          entity.RowIndex = 1;
          //  年月日+2位机器号 
          entity.BarCode = string.Format("{0:yyyyMMdd}{1}", date, BO.Utils.AppContext.ConnectInfo.ClientCode);
          session.Insert(entity);
          session.Commit();
        }
        else
        {
          entity = new TotalCode();
          entity.ID = tuple.Item1;
          entity.BarCode = tuple.Item2;
          entity.GoodsType = 1;
          entity.NoTotalCode = true;
        }

      }
      return entity;
    }

    static Tuple<long, string> GetStayTotalCode(DateTime date, IDmoSession session)
    {
      var query = new DQueryDom(new JoinAlias("_main", typeof(TotalCode)));
      query.Columns.Add(DQSelectColumn.Field("ID"));
      query.Columns.Add(DQSelectColumn.Field("BarCode"));
      query.Where.Conditions.Add(DQCondition.EQ("GoodsType", 1));
      query.Where.Conditions.Add(DQCondition.EQ("NoTotalCode", 1));
      query.Where.Conditions.Add(DQCondition.GreaterThanOrEqual("CreateTime", date.Date));
      query.Where.Conditions.Add(DQCondition.LessThan("CreateTime", date.Date.AddDays(1)));
      return query.EExecuteScalar<long, string>(session);
    }

    public static BindingList<long?> GetInStoreList()
    {
      var query = new DQueryDom(new JoinAlias(typeof(SegmentProduction)));
     
      query.Columns.Add(DQSelectColumn.Field("TotalCode_ID")); 
      query.Where.Conditions.Add(DQCondition.And(DQCondition.EQ("InStored", true) ));
      query.GroupBy.Expressions.Add(DQExpression.Field("TotalCode_ID"));
      query.Where.Conditions.Add(DQCondition.GreaterThanOrEqual("CreateTime", DateTime.Today));
       
      var list = new BindingList<long?>();
      using (var session = DmoSession.New())
      {
        using (var reader = session.ExecuteReader(query))
        {
          while (reader.Read())
          { 
            list.Add((long)reader[0] );
          }
        }
      }

      return list;
    }


    public static BindingList<TotalCode> GetTotalCode( DateTime date)
    {
      var query = new DQueryDom(new JoinAlias(typeof(TotalCode)));
      query.Columns.Add(DQSelectColumn.Field("ID"));
      query.Columns.Add(DQSelectColumn.Field("RowIndex"));
      query.Columns.Add(DQSelectColumn.Field("BarCode"));
      query.Columns.Add(DQSelectColumn.Field("GoodsType"));
      query.Columns.Add(DQSelectColumn.Field("NoTotalCode"));
      query.Where.Conditions.Add(DQCondition.GreaterThanOrEqual("CreateTime", date.Date));
      query.Where.Conditions.Add(DQCondition.LessThan("CreateTime", date.Date.AddDays(1)));
      query.Where.Conditions.Add(DQCondition.And(DQCondition.EQ("Delete", false) ));
      query.OrderBy.Expressions.Add(DQOrderByExpression.Create("GoodsType"));
      query.OrderBy.Expressions.Add(DQOrderByExpression.Create("NoTotalCode", true));
      query.OrderBy.Expressions.Add(DQOrderByExpression.Create("ID",true));
      var list = new BindingList<TotalCode>();
      using (var session = DmoSession.New())
      {
        using (var reader = session.ExecuteReader(query))
        {
          while (reader.Read())
          {
              var entity = new TotalCode();
            entity.ID = (long)reader[0];
            entity.RowIndex = (int?)reader[1];
            entity.BarCode = (string)reader[2];
            entity.GoodsType = (short)reader[3];
            entity.NoTotalCode = (bool)reader[4];
            list.Add(entity);
          }
        }
      }

      return list;
    }

    public static Tuple<short?,string> GetGoodsInfo(long goodsID)
    {
      var query = new DQueryDom(new JoinAlias(typeof(Goods)));
      query.Where.Conditions.Add(DQCondition.EQ("ID", goodsID));
      query.Columns.Add(DQSelectColumn.Field("GoodsType"));
      query.Columns.Add(DQSelectColumn.Field("CustomerDefine"));
      return query.EExecuteScalar<short?,string>();
    }

    public static SegmentProduction Insert(long goodsID, decimal weight, long? workUnitID, long productBatchID, DateTime batchDate)
    {
      using (var session = DmoSession.New())
      {
        var entity = new SegmentProduction();
        entity.Goods_ID = goodsID;
        entity.Weight = weight;
        entity.UserID = BO.Utils.AppContext.Worker.ID;
        entity.WorkUnit_ID = workUnitID;
        entity.ProductBatch_ID = productBatchID;
        entity.RowIndex = GenerateRowIndex(productBatchID, session);
        entity.BarCode = string.Format("260912011{0:yyyyMMdd}{1}{2:00000}", batchDate, BO.Utils.AppContext.ConnectInfo.ClientCode, entity.RowIndex);
        session.Insert(entity);
        FillMsgID(session, entity);
        session.Commit();
        return entity;
      }
    }

    static void FillMsgID(IDmoSession session, SegmentProduction item)
    {
      var update = new DQUpdateDom(typeof(SegmentProduction));
      update.Where.Conditions.Add(DQCondition.EQ("ID", item.ID));
      update.Columns.Add(new DQUpdateColumn("MsgID", string.Format("{0}_{1}", BO.Utils.AppContext.ConnectInfo.ClientCode, item.ID)));
      session.ExecuteNonQuery(update);
    }

    public static SegmentProduction InsertAndSetGroupID(SegmentProduction entity, DateTime batchDate)
    {
      using (var session = DmoSession.New())
      {
        entity.UserID = BO.Utils.AppContext.Worker.ID;
        entity.RowIndex = GenerateRowIndex(entity.ProductBatch_ID, session);
        entity.BarCode = string.Format("260912011{0:yyyyMMdd}{1}{2:00000}", batchDate, BO.Utils.AppContext.ConnectInfo.ClientCode, entity.RowIndex);
        entity.Submited = true;
        session.Insert(entity);
        FillGroupIDAsID(session, entity.ID);
        session.Commit();
        return entity;
      }
    }

    public static TotalCode InsertTotalCode(TotalCode entity)
    {
        return InsertTotalCode(entity, DateTime.Now);
    }

    public static TotalCode InsertTotalCode(TotalCode entity,DateTime date )
    {
      using (var session = DmoSession.New())
      {
        entity.UserID = BO.Utils.AppContext.Worker.ID;
     
        entity.RowIndex = TotalCodeRowIndex(date, session);
        //  年月日+2位机器号+4位顺序号 
        entity.BarCode = string.Format("{0:yyyyMMdd}{1}{2:0000}", date, BO.Utils.AppContext.ConnectInfo.ClientCode, entity.RowIndex);
       
        session.Insert(entity); 
        session.Commit();
        return entity;
      }
    }

    public static TotalCode InitFreshTotalCode()
    {
        TotalCode entity = null;
        var date = DateTime.Now;
        using (var session = DmoSession.New())
        {
            var tuple = GetFreshTotalCode(date, session);
            if (tuple == null)
            {
                entity = new TotalCode();
                entity.UserID = BO.Utils.AppContext.Worker.ID;
                entity.GoodsType = 0;
                entity.RowIndex = 1;
                //  年月日+2位机器号 
                entity.BarCode = string.Format("{0:yyyyMMdd}{1}", date, BO.Utils.AppContext.ConnectInfo.ClientCode); 
                session.Insert(entity);
                session.Commit();
            }
            else
            {
                entity = new TotalCode();
                entity.ID = tuple.Item1;
                entity.BarCode = tuple.Item2;
                entity.GoodsType = 0;
            }

        } return entity;
    }

    static Tuple<long, string> GetFreshTotalCode(DateTime date, IDmoSession session)
    {
      var query = new DQueryDom(new JoinAlias("_main", typeof(TotalCode)));
      query.Columns.Add(DQSelectColumn.Field("ID"));
      query.Columns.Add(DQSelectColumn.Field("BarCode"));
      query.Where.Conditions.Add(DQCondition.EQ("GoodsType", 0));
      query.Where.Conditions.Add(DQCondition.GreaterThanOrEqual("CreateTime", date.Date));
      query.Where.Conditions.Add(DQCondition.LessThan("CreateTime", date.Date.AddDays(1)));
      return query.EExecuteScalar<long,string>(session) ;
    }

    static int TotalCodeRowIndex( DateTime date, IDmoSession session,short type=1)
    {
      var query = new DQueryDom(new JoinAlias("_main", typeof(TotalCode)));
      query.Columns.Add(DQSelectColumn.Max("RowIndex"));
      query.Where.Conditions.Add(DQCondition.EQ("GoodsType", type));
      query.Where.Conditions.Add(DQCondition.GreaterThanOrEqual("CreateTime", date.Date));
      query.Where.Conditions.Add(DQCondition.LessThan("CreateTime", date.Date.AddDays(1)));
      return (query.EExecuteScalar<int?>(session) ?? 0) + 1;
    }

    static void FillGroupIDAsID(IDmoSession session, long id)
    {
      var update = new DQUpdateDom(typeof(SegmentProduction));
      update.Where.Conditions.Add(DQCondition.EQ("ID", id));
      update.Columns.Add(new DQUpdateColumn("MsgID", string.Format("{0}_{1}", BO.Utils.AppContext.ConnectInfo.ClientCode, id)));
      update.Columns.Add(new DQUpdateColumn("GroupID", id));
      session.ExecuteNonQuery(update);
    }

    static int GenerateRowIndex(long productBatchID, IDmoSession session)
    {
      var query = new DQueryDom(new JoinAlias("_main", typeof(SegmentProduction)));
      query.Columns.Add(DQSelectColumn.Max("RowIndex"));
      query.Where.Conditions.Add(DQCondition.EQ("ProductBatch_ID", productBatchID));
      return (query.EExecuteScalar<int?>(session) ?? 0) + 1;
    }

    public static long SetListGroupID(IEnumerable<long> ids)
    {
      using (var session = DmoSession.New())
      {
        var groupID = ids.Max();
        BatchUpdate(ids, session, new Tuple<string, object>("GroupID", groupID));
        session.Commit();
        return groupID;
      }
    }

    static void BatchUpdate(IEnumerable<long> ids, IDmoSession session, params Tuple<string, object>[] keyValues)
    {
      var update = new DQUpdateDom(typeof(SegmentProduction));
      update.Where.Conditions.Add(DQCondition.InList(DQExpression.Field("ID"), ids.Select(x => DQExpression.Value(x)).ToArray()));
      foreach (var item in keyValues)
        update.Columns.Add(new DQUpdateColumn(item.Item1, item.Item2));
      update.Columns.Add(new DQUpdateColumn("Sync", false));
      update.Columns.Add(new DQUpdateColumn("RowVersion", DQExpression.Add(DQExpression.Field("RowVersion"), DQExpression.Value(1))));
      session.ExecuteNonQuery(update);
    }

    public static void BatchUpdate(IEnumerable<long> ids, params Tuple<string, object>[] keyValues)
    {
      using (var session = DmoSession.New())
      {
        BatchUpdate(ids, session, keyValues);
        session.Commit();
      }
    }

    public static void TrunBack(IEnumerable<long> ids)
    {
      using (var session = DmoSession.New())
      {
        BatchUpdate(ids, session, new Tuple<string, object>("TrunOutID", null));
        session.Commit();
      }
    }

    public static List<string> GetInStoreState(List<string> codeArr)
    {
      try
      {
        var json = RpcFacade.Call<string>(RpcPath + "CheckInStored", JsonConvert.SerializeObject(codeArr));
        return JsonConvert.DeserializeObject<List<string>>(json);
      }
      catch
      {
#if DEBUG
        throw;
#endif
        return new List<string>();
      }
    }

    public static void SetInStored(List<long> ids)
    {
      var update = new DQUpdateDom(typeof(SegmentProduction));
      update.Columns.Add(new DQUpdateColumn("InStored", true));
      update.Where.Conditions.Add(DQCondition.InList(DQExpression.Field("ID"), ids.Select(x => DQExpression.Value(x)).ToArray()));
      update.EExecute();
    }

    public static List<ProductTask> GetProductTask(DateTime date, SegmentProduction detail)
    {
      TaskTemp task = null;
      try
      {
        var json = ButcherFactoryUtil.SecondUrlCall<string>(ProductTaskRpc, date, detail.Goods_Code);
        task = JsonConvert.DeserializeObject<TaskTemp>(json);
      }
      catch
      {
#if DEBUG
        throw;
#endif
        task = new TaskTemp();
      }

      var local = GetLocalProducted(detail);

      var list = new List<ProductTask>();
      list.Add(new ProductTask { Item = "重量", Need = task.Weight, Done = local.Weight });
      list.Add(new ProductTask { Item = "数量", Need = task.Number, Done = local.Number });
      return list;
    }

    private static TaskTemp GetLocalProducted(SegmentProduction detail)
    {
      var local = new TaskTemp();
      var query = new DQueryDom(new JoinAlias(typeof(SegmentProduction)));
      query.Columns.Add(DQSelectColumn.Sum("Weight"));
      query.Columns.Add(DQSelectColumn.Count());
      query.Where.Conditions.Add(DQCondition.And(DQCondition.EQ("Delete", false), DQCondition.EQ("ProductBatch_ID", detail.ProductBatch_ID), DQCondition.EQ("Goods_ID", detail.Goods_ID)));
      using (var session = DmoSession.New())
      {
        using (var reader = session.ExecuteReader(query))
        {
          while (reader.Read())
          {
            local.Weight = (decimal?)reader[0];
            local.Number = Convert.ToDecimal(reader[1]);
          }
        }
      }
      return local;
    }

    public static List<ProductTaskFull> GetProductTaskFull(DateTime date,long batchId, IEnumerable<Goods> goods)
    {
      var code = goods.Select(x => x.Code);
      var json = ButcherFactoryUtil.SecondUrlCall<string>(BatchProductTaskRpc, date, code);
      var list = JsonConvert.DeserializeObject<List<ProductTaskFull>>(json);
      var local = BatchGetLocalProducted(batchId, goods.Select(x => x.ID));
      foreach (var item in list)
      {
        var g=goods.First(x=>x.Code==item.Goods_Code);
        item.Goods_Name=g.Name;
        var first = local.FirstOrDefault(x => x.Item1 == g.ID);
        if (first != null)
        {
          item.FinishWeight = first.Item2;
          item.FinishNumber = first.Item3;
        }
      }
      return list;
    }

    private static List<Tuple<long, decimal,decimal>> BatchGetLocalProducted(long batchId, IEnumerable<long> goodsIds)
    {
      var list = new List<Tuple<long, decimal, decimal>>();
      var query = new DQueryDom(new JoinAlias(typeof(SegmentProduction)));
      query.Columns.Add(DQSelectColumn.Field("Goods_ID"));
      query.Columns.Add(DQSelectColumn.Sum("Weight"));
      query.Columns.Add(DQSelectColumn.Count());
      query.GroupBy.Expressions.Add(DQExpression.Field("Goods_ID"));
      query.Where.Conditions.Add(DQCondition.And(DQCondition.EQ("Delete", false), DQCondition.EQ("ProductBatch_ID", batchId), DQCondition.InList(DQExpression.Field("Goods_ID"), goodsIds.Select(x => DQExpression.Value(x)).ToArray())));
      using (var session = DmoSession.New())
      {
        using (var reader = session.ExecuteReader(query))
        {
          while (reader.Read())
          {
            list.Add(new Tuple<long,decimal,decimal>((long)reader[0],(decimal)reader[1],Convert.ToDecimal(reader[2])));
          }
        }
      }
      return list;
    }

    public static string UploadSegmentInfo(bool throwEx = false)
    {
      try
      {
        using (var session = DmoSession.New())
        {
          var needUpload = GetUnSyncData(session);
          if (needUpload.Count == 0)
            return "";

          var json = JsonConvert.SerializeObject(needUpload);
          RpcFacade.Call<int>(RpcPath + "Insert", json);
          foreach (var item in needUpload)
            SetLocalAsSyncd(item, session);
          session.Commit();
        }
      }
      catch (Exception ex)
      {
#if DEBUG
        throw;
#endif
          if (throwEx)
          {
              return ex.Message;
          }

          return "";
      }
      return "";
    }

    static List<SegmentProductionMin> GetUnSyncData(IDmoSession session)
    {
      var query = new DQueryDom(new JoinAlias("_main", typeof(SegmentProduction)));
      query.Columns.Add(DQSelectColumn.Field("ID"));
      query.Columns.Add(DQSelectColumn.Field("RowVersion"));
      query.Columns.Add(DQSelectColumn.Field("BarCode"));
      query.Columns.Add(DQSelectColumn.Field("UserID"));
      query.Columns.Add(DQSelectColumn.Field("WorkUnit_ID"));
      query.Columns.Add(DQSelectColumn.Field("ProductBatch_ID"));
      query.Columns.Add(DQSelectColumn.Field("Goods_ID"));
      query.Columns.Add(DQSelectColumn.Field("Weight"));
      query.Columns.Add(DQSelectColumn.Field("CreateTime"));
      query.Columns.Add(DQSelectColumn.Field("Delete"));
      query.Columns.Add(DQSelectColumn.Field("StandardPic"));
      query.Columns.Add(DQSelectColumn.Field("MsgID"));
      query.Columns.Add(DQSelectColumn.Field("StatisticNumber"));
      query.Columns.Add(DQSelectColumn.Field("TotalCode_Code"));
      query.Columns.Add(DQSelectColumn.Field("NoTotalCode"));
      query.Columns.Add(DQSelectColumn.Field("Identify"));
      query.Columns.Add(DQSelectColumn.Field("IdentifyRemark"));
      query.Columns.Add(DQSelectColumn.Field("ButcherDate"));
      query.Where.Conditions.Add(DQCondition.And(DQCondition.EQ("Submited", true), DQCondition.EQ("Sync", false), DQCondition.EQ("Delete", false)));
      query.Where.Conditions.Add(DQCondition.LessThan("CreateTime", DateTime.Now.AddMinutes(-1)));
      query.Range = SelectRange.Top(10);
      query.OrderBy.Expressions.Add(DQOrderByExpression.Create("ID"));

      var upload = new List<SegmentProductionMin>();
      using (var reader = session.ExecuteReader(query))
      {
        while (reader.Read())
        {
          var obj = new SegmentProductionMin();
          obj.ID = (long)reader[0];
          obj.RowVersion = (int)reader[1];
          obj.BarCode = (string)reader[2];
          obj.Worker_ID = (long)reader[3];
          obj.WorkUnit_ID = (long?)reader[4];
          obj.ProductBatch_ID = (long?)reader[5];
          obj.Goods_ID = (long)reader[6];
          obj.Weight = (decimal)reader[7];
          obj.ProductTime = (DateTime)reader[8];
          obj.Delete = (bool)reader[9];
          obj.StandardPic = (bool)reader[10];
          obj.MsgID = (string)reader[11];
          obj.StatisticNumber = (decimal?)reader[12];
          obj.TotalCode_Code = (string)reader[13];
          obj.NoTotalCode = (bool)reader[14];
          obj.Identify = (string)reader[15];
          obj.IdentifyRemark = (string)reader[16];
          obj.ButcherDate = ((DateTime?)reader[17] ?? DateTime.Today);
          upload.Add(obj);
        }
      }
      return upload;
    }

    static void SetLocalAsSyncd(SegmentProductionMin obj, IDmoSession session)
    {
      var update = new DQUpdateDom(typeof(SegmentProduction));
      update.Where.Conditions.Add(DQCondition.And(DQCondition.EQ("ID", obj.ID), DQCondition.EQ("RowVersion", obj.RowVersion)));
      update.Columns.Add(new DQUpdateColumn("Sync", true));
      session.ExecuteNonQuery(update);
    }

    public static void SetAsDelete(long id, string barCode)
    {
      var canDelete = CheckCanDelete(barCode);
      if (canDelete == null)
        throw new Exception("网络中断，请稍后再试！");
      else if (canDelete == false)
        throw new Exception("已入库，不允许删除！");

      var update = new DQUpdateDom(typeof(SegmentProduction));
      update.Where.Conditions.Add(DQCondition.EQ("ID", id));
      update.Columns.Add(new DQUpdateColumn("Sync", true));
      update.Columns.Add(new DQUpdateColumn("Delete", true));
      update.Columns.Add(new DQUpdateColumn("RowVersion", DQExpression.Add(DQExpression.Field("RowVersion"), DQExpression.Value(1))));
      update.EExecute();
    }

    public static void Delete(SegmentProduction entity)
    {
      var update = new DQUpdateDom(typeof(SegmentProduction));
      update.Where.Conditions.Add(DQCondition.EQ("ID", entity.ID));
      update.Columns.Add(new DQUpdateColumn("Sync", true));
      update.Columns.Add(new DQUpdateColumn("Delete", true));
      update.Columns.Add(new DQUpdateColumn("RowVersion", DQExpression.Add(DQExpression.Field("RowVersion"), DQExpression.Value(1))));
      update.EExecute();

      var log = new SegmentLog(entity.BarCode, "删除");
      log.Message = string.Format("存货名称：{0} 重量：{1:#0.###}", entity.Goods_Name, entity.Weight);
      InsertLog(log);
    }

    public static void DeleteTotalCode(TotalCode entity)
    {
        var update = new DQUpdateDom(typeof(TotalCode));
        update.Where.Conditions.Add(DQCondition.EQ("ID", entity.ID));
        update.Columns.Add(new DQUpdateColumn("Delete", true));
        update.Columns.Add(new DQUpdateColumn("RowVersion", DQExpression.Add(DQExpression.Field("RowVersion"), DQExpression.Value(1))));
        update.EExecute();

        var update1 = new DQUpdateDom(typeof(SegmentProduction));
        update1.Where.Conditions.Add(DQCondition.EQ("TotalCode_ID", entity.ID));
        update1.Columns.Add(new DQUpdateColumn("Sync", true));
        update1.Columns.Add(new DQUpdateColumn("Delete", true));
        update1.Columns.Add(new DQUpdateColumn("RowVersion", DQExpression.Add(DQExpression.Field("RowVersion"), DQExpression.Value(1))));
        update1.EExecute();

        var log = new SegmentLog(entity.BarCode, "删除");
        log.Message = string.Format("总码：删除");
        InsertLog(log);
    }

    static bool? CheckCanDelete(string barCode)
    {
      try
      {
        var rst = RpcFacade.Call<string>(RpcPath + "CheckInStored", JsonConvert.SerializeObject(new List<string> { barCode }));
        return JsonConvert.DeserializeObject<List<string>>(rst).Count == 0;
      }
      catch
      {
        return null;
      }
    }

    public static void DeleteBefore()
    {
      var delete = new DQDeleteDom(typeof(SegmentProduction));
      delete.Where.Conditions.Add(DQCondition.LessThan("CreateTime", new DateTime(2018, 10, 15)));
      delete.EExecute();

      var delete2 = new DQDeleteDom(typeof(SegmentLog));
      delete2.Where.Conditions.Add(DQCondition.LessThan("Time", DateTime.Today.AddDays(-30)));
      delete2.EExecute();
    }

    public static int GetUnSyncCount()
    {
      var query = new DQueryDom(new JoinAlias("_main", typeof(SegmentProduction)));
      query.Columns.Add(DQSelectColumn.Count());
      query.Where.Conditions.Add(DQCondition.And(DQCondition.EQ("Submited", true), DQCondition.EQ("Sync", false)));
      return Convert.ToInt32(query.EExecuteScalar());
    }

    public static void InsertLog(SegmentLog log)
    {
      using (var session = DmoSession.New())
      {
        session.Insert(log);
        session.Commit();
      }
    }

    public static IEnumerable<SegmentLog> GetLog(string type)
    {
      var query = new DmoQuery(typeof(SegmentLog));
      query.Where.Conditions.Add(DQCondition.GreaterThan("Time", DateTime.Today.AddDays(-2)));
      query.OrderBy.Expressions.Add(DQOrderByExpression.Create("ID", true));
      if (!string.IsNullOrEmpty(type))
        query.Where.Conditions.Add(DQCondition.EQ("Action", type));
      return query.EExecuteList().Cast<SegmentLog>();
    }

    public static List<GoodsIdentify> GetGoodsIdentify()
    {
      var query = new DmoQuery(typeof(GoodsIdentify));
      return query.EExecuteList().Cast<GoodsIdentify>().ToList();
    }

    public static void InsertProductNumLog(SegmentGoodsProductNumLog log)
    {
      using (var session = DmoSession.New())
      {
        session.Insert(log);
        session.Commit();
      }
    }
  }

  class SegmentProductionMin
  {
    [JsonIgnore]
    public long ID { get; set; }
    [JsonIgnore]
    public long RowVersion { get; set; }
    public string BarCode { get; set; }
    public DateTime? ProductTime { get; set; }
    public long? Worker_ID { get; set; }
    public long? WorkUnit_ID { get; set; }
    public long? ProductBatch_ID { get; set; }
    public long? Goods_ID { get; set; }
    public decimal? Weight { get; set; }
    public DateTime? InStoreTime { get; set; }
    public bool Delete { get; set; }
    public bool StandardPic { get; set; }
    public string MsgID { get; set; }
    public decimal? StatisticNumber { get; set; }
    public string TotalCode_Code { get; set; }
    public bool NoTotalCode { get; set; }
    public string Identify { get; set; }
    public string IdentifyRemark { get; set; }
    public DateTime ButcherDate { get; set; }
  }

  class TaskTemp
  {
    public decimal? Weight { get; set; }
    public decimal? Number { get; set; }
  }
}
