using ICSSoft.Common;
using ICSSoft.Entity;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ICSSoft.DataProject
{
    /// <summary>
    /// 销售出库红字
    /// </summary>
    public class SalesShipmentDocNegative
    {
        private static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private static string connString = System.Configuration.ConfigurationManager.AppSettings["ERPConnStr"];
        private static string ERPDB = System.Configuration.ConfigurationManager.AppSettings["ERPDB"];
        private static string Type = System.Configuration.ConfigurationManager.AppSettings["Type"];
        string bustype = string.Empty;
        /// <summary>
        ///获取销售出库单红字
        /// </summary>
        /// <param name="infos"></param>
        /// <returns></returns>
        public string Get(List<ICSSalesShipmentDocNegative> infos)
        {

            List<ICSSalesShipmentDocNegative> szJson = new List<ICSSalesShipmentDocNegative>();
            DataTable dt = null;
            string json = "";
            if (infos.Count <= 0)
            {
                throw new Exception("传送数据为空!");
            }
            string res = string.Empty;
            SqlConnection conn = new System.Data.SqlClient.SqlConnection(connString);
            conn.Open();
            SqlTransaction sqlTran = conn.BeginTransaction();
            SqlCommand cmd = new SqlCommand();
            cmd.Transaction = sqlTran;
            cmd.Connection = conn;
            try
            {
                string sql = string.Empty;
                foreach (ICSSalesShipmentDocNegative info in infos)
                {
                    if (info.MTime < new DateTime(2000, 01, 01))
                        throw new Exception("请输入正确的操作时间:" + info.MTime);
                    sql = @"select a.ID,a.cCode,a.cCusCode,c.cCusName,a.cWhCode,d.cWhName,e.cordercode ,a.cMaker ,a.dnmaketime ,a.cHandler ,a.dnverifytime ,
                             b.AutoID,b.iRSRowNO ,b.cInvCode ,b.iQuantity ,b.iNum,e.AutoID    
                             from rdrecord32 a 
                             inner join rdrecords32 b on a.ID=b.ID
							 left join DispatchLists e on a.cDLCode=e.DLID 
                             left join Customer  c on a.cCusCode=c.cCusCode
                             left join Warehouse d on a.cWhCode=d.cWhCode WHERE 1=1 and b.iquantity<0 ";
                    if (!string.IsNullOrWhiteSpace(info.SDNNEGCode))
                    {
                        sql += " and a.cCode='{0}'";
                    }
                    if (!string.IsNullOrWhiteSpace(info.MTime.ToString()))
                    {
                        sql += " and ISNULL(a.dnmodifytime ,ISNULL(a.dnverifytime , ISNULL(a.dnmodifytime , a.dnmaketime )))>='{1}'";
                    }
                    if (!string.IsNullOrWhiteSpace(info.User))
                    {
                        sql += "and a.CMAKER='{2}'";
                    }
                    sql = string.Format(sql, info.SDNNEGCode, info.MTime, info.User);
                    dt = DBHelper.SQlReturnData(sql, cmd);
                    if (dt.Rows.Count <= 0 || dt == null)
                        throw new Exception("红字销售出库单号:" + info.SDNNEGCode + ",无信息!");
                    json = JsonConvert.SerializeObject(dt);
                }
                cmd.Transaction.Commit();
                return json;
            }
            catch (Exception ex)
            {
                cmd.Transaction.Rollback();
                log.Error(ex.Message);
                throw new Exception(ex.Message);
            }
            finally
            {
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                }
                conn.Dispose();
            }
        }
        /// <summary>
        ///  创建销售出库单红字
        /// </summary>
        /// <param name="Bills"></param>
        /// <returns></returns>
        public string CreateSalesShipmentDocNegative(List<ICSSalesShipmentDocNegative> Bills)
        {
            string sql = "";
            string msg = "";
            DataTable dt = null;
            int iFatherId = 0;
            int iChildId = 0;
            string iFatherIdTwo = "";
            int num = 0;
            //bool ResultFlag = false;
            SqlConnection conn = new System.Data.SqlClient.SqlConnection(connString);
            conn.Open();
            SqlTransaction sqlTran = conn.BeginTransaction();
            SqlCommand cmd = new SqlCommand();
            cmd.Transaction = sqlTran;
            cmd.Connection = conn;
            VouchKey key = new VouchKey();
            try
            {
                if (Bills.Count <= 0)
                {
                    throw new Exception("传送数据为空!");
                }
                LogInfo(Bills);
                foreach (ICSSalesShipmentDocNegative head in Bills)
                {
                    #region 检查 发货单状态
                    sql = @"SELECT a.DLID,a.cBusType,c.cRdCode,a.cSTCode,b.AutoID,b.irowno,a.cPersonCode,a.cCusCode,b.iDLsID,
                a.cMemo,a.cShipAddress,a.cDepCode,cCusInvName,b.cBatch,a.caddcode,a.cCloser,a.cVerifier FROM dbo.DispatchList a INNER JOIN 
                            dbo.DispatchLists b ON a.DLID=b.DLID 
							LEFT JOIN dbo.SaleType c ON c.cSTCode=a.cSTCode
							WHERE a.cDLCode ='" + head.SDNRTCode + "'";
                    cmd.CommandText = sql;
                    DataTable dtDisCheck = DBHelper.SQlReturnData(sql, cmd);
                    if (dtDisCheck != null && dtDisCheck.Rows.Count > 0)
                    {
                        foreach (DataRow item in dtDisCheck.Rows)
                        {
                            if (!string.IsNullOrEmpty(item["cCloser"].ToString()))
                            {
                                log.Info("DLID:" + head.ID);
                                throw new Exception("ERP发货单已关闭,无法发货!发货单号:" + head.SDNNEGCode);
                            }
                        }
                        bustype = dtDisCheck.Rows[0]["cBusType"].ToString();
                    }
                    else
                    {
                        throw new Exception("销售发货单单号:" + head.ID + "在ERP内不存在!");
                    }
                    #endregion

                    #region 检验发货单数量

                    foreach (ICSSalesShipmentDocNegatives body in head.details)
                    {
                        sql = "SELECT isnull(fOutQuantity,0) as fOutQuantity,ABS(iQuantity) as iQuantity FROM dbo.DispatchLists WHERE AutoID='" + body.SDNRTDetailID + "'";
                        DataTable dtfOutQty = DBHelper.SQlReturnData(sql, cmd);
                        if (dtfOutQty != null && dtfOutQty.Rows.Count > 0)
                        {
                            decimal fOutQty = Convert.ToDecimal(dtfOutQty.Rows[0]["fOutQuantity"]);
                            decimal iQuantity = Convert.ToDecimal(dtfOutQty.Rows[0]["iQuantity"]);
                            if (fOutQty + body.Quantity > iQuantity)
                            {
                                throw new Exception("可出库数量超过发货单表体出库数量!");
                            }
                        }
                        else
                        {
                            throw new Exception("发货单表体不存在!");
                        }
                    }

                    #endregion

                    #region 红字销售出库单表头
                
                    num = head.details.Count();
              
                    DateTime time = DateTime.Now;
                    Dictionary<string, int> dic = DBHelper.GetAllCode("" + ERPDB + "", "ShipmentDoc", "" + num + "");
                    iFatherId = Convert.ToInt32(dic["iFatherId"].ToString());
                    iChildId = Convert.ToInt32(dic["iChildId"].ToString());
                    DateTime date = DateTime.Now;
                    string iBaseCodeLen = DBHelper.GetAllRDCode("0303", "" + time + "", "admin");

                    sql = @"INSERT INTO dbo.rdrecord32
                                    ( ID ,bRdFlag ,cVouchType ,cBusType ,cSource ,cBusCode ,cWhCode ,
                                      dDate ,cCode ,cRdCode ,cDepCode ,cPersonCode ,cSTCode ,cCusCode ,
                                      cDLCode ,cHandler ,cMemo ,bTransFlag ,cMaker ,cDefine1 ,cDefine2 ,
                                      cDefine3 ,cDefine4 ,cDefine5 ,cDefine6 ,cDefine7 ,cDefine8 ,cDefine9 ,
                                      cDefine10 ,dVeriDate ,bpufirst ,biafirst ,VT_ID ,bIsSTQc ,cDefine11 ,
                                      cDefine12 ,cDefine13 ,cDefine14 ,cDefine15 ,cDefine16 ,cShipAddress ,
                                      caddcode ,bOMFirst ,bFromPreYear ,bIsComplement ,iDiscountTaxType ,
                                      ireturncount ,iverifystate ,iswfcontrolled ,dnmaketime ,dnverifytime ,
                                      iPrintCount ,cinvoicecompany)
                            SELECT @ID,0,32,a.cBusType,'发货单',a.cDLCode,@cWhCode,
                            		CONVERT(NVARCHAR(15),GETDATE(),23),@cCode,'21',a.cDepCode,a.cPersonCode,a.cSTCode,a.cCusCode,
                            		a.DLID,@cHandler,a.cMemo,0,@cMaker,a.cDefine1,a.cDefine2,
                            		a.cDefine3,a.cDefine4,a.cDefine5,a.cDefine6,a.cDefine7,a.cDefine8,a.cDefine9,
                            		a.cDefine10,CONVERT(NVARCHAR(15),GETDATE(),23),0,0,@VT_ID,0,a.cDefine11,
                             		a.cDefine12,a.cDefine13,a.cDefine14,a.cDefine15,a.cDefine16,a.cShipAddress,
                            		a.caddcode,null,0,0,0,
                            		0,0,0,GETDATE(),GETDATE(),
                            		0,a.cinvoicecompany
                                  FROM dbo.DispatchList a WHERE a.cDLCode ='" + head.SDNRTCode + "'";
                    cmd.Parameters.Clear();
                    cmd.Parameters.Add(new SqlParameter("@ID", iFatherId));
                    cmd.Parameters.Add(new SqlParameter("@cWhCode", head.WHCode));
                    cmd.Parameters.Add(new SqlParameter("@cCode", iBaseCodeLen));
                    cmd.Parameters.Add(new SqlParameter("@cDepCode", ""));
                    cmd.Parameters.Add(new SqlParameter("@cHandler", head.User));
                    cmd.Parameters.Add(new SqlParameter("@cMaker", head.User));
                    cmd.Parameters.Add(new SqlParameter("@VT_ID", iChildId));
                    //cmd.Parameters.Add(new SqlParameter("@dDate", data.dMate));
                    cmd.CommandText = sql;
                    try
                    {
                        int count = cmd.ExecuteNonQuery();
                        if (count <= 0)
                        {
                            log.Error("生成红字销售出库单表头失败,受影响行数<=0;");
                            throw new Exception("生成红字销售出库单表头失败,受影响行数<=0;");
                        }
                    }
                    catch (Exception ex)
                    {
                        log.Error("生成红字销售出库单表头失败!销售出库单号:" + head.SDNNEGCode + ";异常:" + ex.Message + ";SQL:\r\n" + sql, ex);
                        throw new Exception("生成红字销售出库单表头失败!销售出库单号:" + head.SDNNEGCode + ";异常:" + ex.Message + ";SQL:\r\n" + sql, ex);
                    }
                    #endregion

                    #region 红字销售出库单表体
                    foreach (ICSSalesShipmentDocNegatives body in head.details)
                    {
                        //iChildId -= 1;

                        ////if (head.IsReturn == "1")
                        ////{
                        //body.Quantity = -body.Quantity;
                        //}
                        //else
                        //{
                        //判断物料批号与现存量表批号是否一致、数量不能超过现存量物料数量
                        //sql = @"SELECT cBatch,iQuantity from CurrentStock WHERE cInvCode='" + body.InvCode + "'AND cBatch='" + "" + "'and cWhCode='" + head.WHCode + "'";
                        //DataTable dtItem = DBHelper.SQlReturnData(sql, cmd);
                        //if (dtItem != null && dtItem.Rows.Count > 0)
                        //{
                        //    //if (!dtItem.Rows[0]["cBatch"].ToString().Equals(body.cBatch))
                        //    //{
                        //    //    throw new Exception("物料条码的批号与U8现存量物料批号不一致,物料:" + body.cInvCode);
                        //    //}
                        //    if (Convert.ToDecimal(dtItem.Rows[0]["iQuantity"].ToString()) < body.Quantity)
                        //    {
                        //        throw new Exception("物料条码的数量大于U8现存量物料数量,物料:" + body.InvCode);
                        //    }

                        //}
                        //else
                        //{
                        //    throw new Exception("物料:" + body.InvCode + "在现存量表中不存在!");
                        //}
                        //}
                        sql = @"INSERT INTO dbo.rdrecords32
                                        ( AutoID ,ID ,cInvCode ,iQuantity ,cBatch ,iFlag ,
                                          cDefine22 ,cDefine23 ,cDefine24 ,cDefine25 ,cDefine26 ,
                                          cDefine27 ,cItem_class ,cItemCode ,iDLsID ,iNQuantity ,
                                          cDefine28 ,cDefine29 ,cDefine30 ,cDefine31 ,cDefine32 ,
                                          cDefine33 ,cDefine34 ,cDefine35 ,cDefine36 ,cDefine37 ,
                                          bLPUseFree ,iRSRowNO ,iOriTrackID ,ccusinvcode,ccusinvname,bCosting ,bVMIUsed ,
                                          cbdlcode ,iExpiratDateCalcu ,iorderdid ,iordertype ,
                                          iordercode ,iorderseq ,ipesodid ,ipesotype ,cpesocode ,
                                          ipesoseq ,isodid ,isotype ,csocode ,isoseq ,irowno ,
                                          bIAcreatebill ,bsaleoutcreatebill ,isaleoutid ,bneedbill,iposflag )
                                SELECT @AutoID,@ID,@cInvCode,@iQuantity,@cBatch,0,
                                		a.cDefine22,a.cDefine23,a.cDefine24,a.cDefine25,a.cDefine26,
                                		a.cDefine27,a.cItem_class,a.cItemCode,a.AutoID,a.iQuantity,
                                		a.cDefine28,a.cDefine29,a.cDefine30,a.cDefine31,a.cDefine32,
                                		a.cDefine33,a.cDefine34,a.cDefine35,a.cDefine36,a.cDefine37,
                                		0,0,0,a.cCusInvCode,a.cCusInvName,1,0,
                                		b.cDLCode,0,a.iSOsID,1,
                                		d.cSOCode,c.iRowNo,a.iSOsID,1,d.cSOCode,
                                		1,a.iSOsID,1,d.cSOCode,c.iRowNo,@irowno,
                                		1,1,@AutoID,1,null
                                FROM dbo.DispatchLists a
                                INNER JOIN dbo.DispatchList b ON a.DLID=b.DLID
                                LEFT JOIN dbo.SO_SODetails c ON a.iSOsID=c.iSOsID
                                LEFT JOIN dbo.SO_SOMain d ON c.ID=d.ID WHERE a.AutoID='" + body.SDNRTDetailID + "'";
                        cmd.Parameters.Clear();
                        cmd.Parameters.Add(new SqlParameter("@AutoID", iChildId));
                        cmd.Parameters.Add(new SqlParameter("@ID", iFatherId));
                        cmd.Parameters.Add(new SqlParameter("@cInvCode", body.InvCode));
                        cmd.Parameters.Add(new SqlParameter("@iQuantity", -body.Quantity));
                        cmd.Parameters.Add(new SqlParameter("@cBatch", ""));
                        cmd.Parameters.Add(new SqlParameter("@irowno", body.Sequence));
                        cmd.CommandText = sql;
                        try
                        {
                            int count = cmd.ExecuteNonQuery();
                            if (count <= 0)
                            {
                                log.Error("生成红字销售出库单表体失败,受影响行数<=0;");
                                throw new Exception("生成红字销售出库单表体失败,受影响行数<=0;");
                            }
                        }
                        catch (Exception ex)
                        {
                            log.Error("生成红字销售出库单表体失败!销售出库单号:" + head.SDNNEGCode + ";异常:" + ex.Message + ";SQL:\r\n" + sql, ex);
                            throw new Exception("生成红字销售出库单表体失败!销售出库单号:" + head.SDNNEGCode + ";异常:" + ex.Message + ";SQL:\r\n" + sql, ex);
                        }

                        #region 更新现存量 现存量表待出库数量增加
                        key.cBustypeUN = bustype;
                        key.cVouchTypeUN = "32";
                        key.TableName = "IA_ST_UnAccountVouch32";
                        DBHelper.UpdateCurrentStock(cmd, body.InvCode, head.WHCode, "", body.Quantity, key);
                        #endregion
                        log.Debug(sql);
                        #region 回写销售订单累计发货数量,回写销售发货单累计出库数量
                        sql = @"UPDATE a SET a.foutquantity=ISNULL(a.foutquantity,0)+" + -body.Quantity + @"
                                FROM dbo.SO_SODetails a LEFT JOIN dbo.DispatchLists b ON a.iSOsID=b.iSOsID
                                WHERE b.AutoID='" + body.SDNRTDetailID + "'";
                        DBHelper.CmdExecuteNonQuery(sql, cmd, "回写销售订单累计发货数量失败!");

                        sql = "Update DispatchLists set fOutQuantity=isnull(fOutQuantity,0)+" + -body.Quantity + " where AutoID='" + body.SDNRTDetailID + "' ";
                        DBHelper.CmdExecuteNonQuery(sql, cmd, "回写销售发货单累计出库数量失败!");
                        iChildId--;
                        #endregion
                    }
                    #endregion
                    iFatherIdTwo += "'" + iFatherId + "',"; 
                }
                #region 查询
                sql = @"  
                           select distinct a.ID as ID, a.ID as IDs,a.cCode as SDNNEGCode,a.cCusCode as CusCode,
                            c.cCusName as CusName,a.cWhCode as WHCode,d.cWhName as WHName,e.cordercode ,
                        a.cMaker as CreateUser ,a.dnmaketime as CreateDateTime ,a.cHandler as Checker ,
                    a.dnverifytime as CheckDateTime 
                             from rdrecord32 a 
							 left join DispatchLists e on a.cDLCode=e.DLID 
                             left join Customer  c on a.cCusCode=c.cCusCode
                             left join Warehouse d on a.cWhCode=d.cWhCode WHERE 1=1 and a.ID in({0})

                           select distinct a.ID as IDs,b.AutoID as DetailID,b.irowno as Sequence,b.cInvCode as InvCode ,b.iQuantity as Quantity ,
                           b.iNum as Amount,b.iDLsID  as  SDNRTDetailID    
                             from rdrecord32 a 
                             inner join rdrecords32 b on a.ID=b.ID
                             left join Customer  c on a.cCusCode=c.cCusCode
                             left join Warehouse d on a.cWhCode=d.cWhCode WHERE 1=1 and a.ID in({0})";
                sql = string.Format(sql, iFatherIdTwo.TrimEnd(','));
                DataSet ds = DBHelper.SQlReturnDataSet(sql, cmd);
                string RelationName = "details";
                DataRelation dr = new DataRelation(RelationName, ds.Tables[0].Columns["IDs"], ds.Tables[1].Columns["IDs"]);
                ds.Relations.Add(dr);

                #endregion
                msg = DBHelper.DataSetToJson(ds, RelationName);
                cmd.Transaction.Commit();
                //ResultFlag = true;
                return msg;
            }
            catch (Exception ex)
            {
                cmd.Transaction.Rollback();
                log.Error(ex.Message);
                throw new Exception(ex.Message);
            }
            finally
            {
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                }
                conn.Dispose();
            }
        }
        /// <summary>
        /// 删除销售出库单红字
        /// </summary>
        /// <param name="infos"></param>
        /// <returns></returns>
        public string Delete(List<ICSSalesShipmentDocNegative> infos)
        {
            List<ICSSalesShipmentDocNegative> szJson = new List<ICSSalesShipmentDocNegative>();
            if (infos.Count <= 0)
            {
                throw new Exception("传送数据为空!");
            }
            string res = string.Empty;
            SqlConnection conn = new System.Data.SqlClient.SqlConnection(connString);
            conn.Open();
            SqlTransaction sqlTran = conn.BeginTransaction();
            SqlCommand cmd = new SqlCommand();
            cmd.Transaction = sqlTran;
            cmd.Connection = conn;
            try
            {
                string sql = string.Empty;
                foreach (ICSSalesShipmentDocNegative info in infos)
                {
                    if (info.MTime < new DateTime(2000, 01, 01))
                        throw new Exception("请输入正确的操作时间:" + info.MTime);
                    sql = @"delete  rdrecord11  where  rdrecord32.ID='" + info.ID + "'";
                    sql += @"delete  rdrecords11  where  rdrecords32.ID='" + info.ID + "'";
                    //UPDATE dbo.rdrecord11 a SET cHandler='" + info.User + @"' ,
                    //                            dVeriDate=CONVERT(VARCHAR(50),GETDATE(),112),dnverifytime=GETDATE() 
                    //                            WHERE a.ID='" + info.ID + "'";
                    DBHelper.CmdExecuteNonQuery(sql, cmd, "删除红字销售出单失败!");
                }
                cmd.Transaction.Commit();
                return res;
            }
            catch (Exception ex)
            {
                cmd.Transaction.Rollback();
                log.Error(ex.Message);
                throw new Exception(ex.Message);
            }
            finally
            {
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                }
                conn.Dispose();
            }
        }
        /// <summary>
        /// 审核销售出库单
        /// </summary>
        /// <param name="infos"></param>
        /// <returns></returns>
        public string Approve(List<ICSSalesShipmentDocNegative> infos)
        {
            List<ICSSalesShipmentDocNegative> szJson = new List<ICSSalesShipmentDocNegative>();
            DataTable dt = null;
            string json = "";
            if (infos.Count <= 0)
            {
                throw new Exception("传送数据为空!");
            }
            string res = string.Empty;
            SqlConnection conn = new System.Data.SqlClient.SqlConnection(connString);
            conn.Open();
            SqlTransaction sqlTran = conn.BeginTransaction();
            SqlCommand cmd = new SqlCommand();
            cmd.Transaction = sqlTran;
            cmd.Connection = conn;
            try
            {
                string sql = string.Empty;
                foreach (ICSSalesShipmentDocNegative info in infos)
                {
                    if (info.MTime < new DateTime(2000, 01, 01))
                        throw new Exception("请输入正确的操作时间:" + info.MTime);
                    sql = @"UPDATE  rdrecord32 SET cHandler ='" + info.User + @"' ,
                            dnverifytime=CONVERT(VARCHAR(50),GETDATE(),112),dVeriDate=GETDATE() WHERE ID='{0}'";
                    sql = string.Format(sql, info.ID);
                    DBHelper.CmdExecuteNonQuery(sql, cmd, "审核红字销售出单失败!");
                }
                cmd.Transaction.Commit();
                return json;
            }
            catch (Exception ex)
            {
                cmd.Transaction.Rollback();
                log.Error(ex.Message);
                throw new Exception(ex.Message);
            }
            finally
            {
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                }
                conn.Dispose();
            }
        }
        /// <summary>
        /// 
        /// 记录日志
        /// </summary>
        /// <param name="Bills"></param>
        private void LogInfo(List<ICSSalesShipmentDocNegative> Bills)
        {
            string HeadList = string.Empty;
            string BodyList = string.Empty;
            foreach (ICSSalesShipmentDocNegative head in Bills)
            {
                HeadList += "\r\n 表头主键ID:" + head.ID + ",仓库:" + head.WHCode + ",用户:" + head.User;
                foreach (ICSSalesShipmentDocNegatives body in head.details)
                {
                    BodyList += "\r\n 表体主键ID: " + body.SDNRTDetailID + ",数量:" + body.Quantity;
                }
            }
            log.Info(HeadList);
            log.Info(BodyList);
        }
    }
}