/// 
///LOGIC CLASS FOR TABLE t_wmslocation
///By wm with codesmith. 
///on 05/02/2017
/// 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DeiNiu.wms.Data.Model;
using System.Data;
using System.Transactions;
using DeiNiu.Utils;
using DeiNiu.Data.BaseObject;
 
 
namespace DeiNiu.wms.Logical
{
    [Serializable]
    public class lWmslocation:lbase
    {
        WmsLocation _obj;
        public lWmslocation()
        {
            initialize();
        }
        public lWmslocation(int operId) :base(operId)
        {
            initialize();
        }
        public WmsLocation getWmslocation
        {
            get
            {
                return _obj;
            }
        }
        /// 
        /// get all data
        /// 
        public DataSet getAllData()
        {
            return _obj.Query();
        }
        /// 
        /// get all data
        /// 
        public DataSet getAllActiveData()
        {
            return _obj.QueryActived();
        }
        /// 
        /// get a record by id
        /// 
        public void initialize(int id)
        {
            _obj = id != 0 ? new WmsLocation(id) : new WmsLocation();
        }
        /// 
        /// get a record by id 0
        /// 
        public void initialize()
        {
            initialize(0);
        }
        /// 
        /// get a record by id
        /// 
        public void initialize(DataRow dr)
        {
            _obj = new WmsLocation(dr);
        }
        //begin cust db operation, query, excute sql etc.
        /*
        /// 
        ///  query with like, return talbe and record cnt.
        /// 
        public DataSet Query(string querystr, int rownumStart, int rownumEnd)
        {
            if (rownumEnd > rownumStart && rownumStart > 0)
            {
                _obj.rownumStart = rownumStart;
                _obj.rownumEnd = rownumEnd;
            }
          //  DataSet ds = string.IsNullOrEmpty(querystr) ? _obj.Query() : _obj.Query(querystr);
            if (string.IsNullOrEmpty(querystr))
            {
                return _obj.Query();
            }
            string condition = "";
            string[] parameters = querystr.Split(";".ToCharArray());
            foreach (string value in parameters)
            {
                if (string.IsNullOrEmpty(value))
                {
                    continue;
                }
                string[] par = value.Split("#".ToCharArray());
                condition += par.Length == 0 ? "" :" and ";
                foreach (string p in par)
                {
                    condition += p;
                }
            }
          return  _obj.Query(condition);
             
        }
        */
        public DataSet Query(DataTable dic,string query ,int rownumStart, int rownumEnd)
        {
            DataSet ds = Query(query, rownumStart, rownumEnd);
            if (dic != null)
            {// build new columns from dic.
                DataTable dt = ds.Tables[0];
                string warehouseGoodsType = WmsLocation.fields.whGoodsType.ToString();
                string WarehouseType = WmsLocation.fields.whType.ToString() ;
            //    string warehouseVolume = Wmslocation.fields.whVolType.ToString() ;
               // string goodsType = Wmslocation.fields.goodsType.ToString()+"_" ;
                string parts = WmsLocation.fields.part.ToString()  ;
                string ABC = WmsLocation.fields.ABC.ToString();
                string[] fieds = { warehouseGoodsType, WarehouseType,/* goodsType, parts,*/ WmsLocation.fields.transLine.ToString(),ABC };
                foreach (string field in fieds)
                {
                    dt.Columns.Add(field + "Name");
                }
                 
                foreach (DataRow dr in dt.Rows){
                    foreach (string field in fieds)
                    {
                        if (string.IsNullOrEmpty(dr[field].ToString()))
                        {
                            continue;
                        }
                        string filter = "id = " + dr[field].ToString();
                        DataRow[] drs = dic.Select(filter);
                        if (drs.Length > 0)
                        {
                            string v = drs[0]["name"].ToString();
                            dr[field + "Name"] = v;
                        }
                    }
                    
                }
            }
            return ds;
        }
        /// 
        /// update in a transaction scrop
        /// 
        public void update()
        {
            if (valid())
            {
                using (TransactionScope scope = new TransactionScope())
                {
                    //Node tmp = new Node();
                    //tmp.parentid = 1;
                    //tmp.name = "test trans" + DateTime.Now;
                    //tmp.description = "this is for transTest";
                    //tmp.Add();
                    _obj.Update();
                    scope.Complete();
                }
            }
         }
        internal int updateLocJobCross(int[] ids, bool isCross)
        {
            return  _obj.updateLocJobCross(getWhereIds(ids), isCross, operId);
        }
        public void addLocations(Structs locs)
        {
            //    System.Data.SqlClient.SqlConnection conn = new DeiNiu.Data.DataAccess.Connection().getSqlCon();
            // Wmslocation loc = new Wmslocation(conn);
            log.Debug("start to create locations....");
            WmsLocation loc = new WmsLocation();
            loc.bigPart = locs.bigPart + "";
            loc.part = locs.part  ;
            loc.port = locs.port;
          //  loc.operater = locs.operater;
            loc.length = locs.length;
            loc.height = locs.height;
            loc.weight = locs.weight;
            loc.width = locs.width; 
          //  loc.whGoodsType = loc.whGoodsType;
            loc.whType = locs.whType;
            loc.whVolType = locs.whVoltype;
            loc.volType = locs.volType;
            loc.state = (int)enumStockLocationStatus.正常;//locs.state;//default 1
            loc.tranState = locs.tranState;
            loc.warehouse = locs.warehouse;
            loc.goodsType = locs.goodsType;
            loc.transLine = locs.transLine;
            loc.ABC = locs.ABC;
            if (!String.IsNullOrEmpty(locs.ownerCode))
            loc.ownerCode = locs.ownerCode;
            loc.storeType = locs.storeType;
            try
            {
                using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions()
                {
                    IsolationLevel = System.Transactions.IsolationLevel.Serializable,Timeout = new TimeSpan( 0,10,0)
                }
                    ))
                {
                    for (int channel = locs.channel1; channel <= locs.channel2; channel++)
                    {
                        for (int shelf = locs.shelf1; shelf <= locs.shelf2; shelf++)
                        {
                            for (int layer = locs.layer1; layer <= locs.layer2; layer++)
                            {
                                for (int column = locs.col1; column <= locs.col2; column++)
                                {
                                    // loc = new Wmslocation();
                                    // locs.warehouseName = "AA";
                                    //loc.channel = string.Format("{0:D2}", channel);
                                    //loc.shelf = string.Format("{0:D2}", shelf);
                                    loc.channel =   channel ;
                                    loc.shelf =  shelf ;
                                    loc.layer = layer;
                                    loc.col = column;
                                    loc.operater = operId;
                                    //loc.bigPart = locs.bigPart + "";
                                    //loc.part = locs.part + "";
                                    //loc.port = locs.port + "";
                                    loc.locationId = string.Format(WmsConstants.LOC_NAME_FORMAT, locs.warehouseName+locs.partCode, channel, shelf, layer, column);
                                    if (locs.eleid1 > 0 && locs.elelayer > 0 && locs.elecol > 0)
                                    {
                                        loc.elabId = getLabId(locs, channel, shelf, layer, column);
                                        loc.elabAddress = layer * 10 + column;
                                    }
                                    DateTime timestamp = DateTime.Now; 
                                    loc.Add(); 
                                  //  Console.WriteLine(string.Format("{0},locid:{1}",DateTime.Now - timestamp ,loc.locationId));
                           
                                }
                            }
                        }
                    }
                    scope.Complete();
                }
            }
            catch (Exception er)
            {
                log.Error(er);
                throw er;
            }
            finally
            {
              //  conn.Close();
            }
             
        }
        internal bool updateLocScale(int[] ids, Structs locs)
        {
            return _obj.updateLocScale(getWhereIds(ids), locs, operId);
        }
        private Int32 getLabId( Structs locs,int channel,int shelf,int layer, int column)
        {
            int ele_layer_count;
            int ele_column_count;
            ele_layer_count = locs.layer2 / locs.elelayer;//单个标签管理的层数
            ele_column_count = locs.col2 / locs.elecol;//单个标签管理的列数
            int ele_id_layer;
            int ele_id_column;
            ele_id_layer = ( layer - 1) / ele_layer_count + 1;    //电子标签的坐标值 层
            ele_id_column = ( column - 1) / ele_column_count + 1; //电子标签的坐标值 列
            
            int channel_count = channel - locs.channel1 + 1;
            int shelves_count = shelf - locs.shelf1 + 1;
            int single_shelves = locs.elelayer * locs.elecol;
            int single_channel = single_shelves * (locs.shelf2 - locs.shelf1 + 1);
            int total_id = (channel_count - 1) * single_channel + (shelves_count - 1) * single_shelves; 
           
            int ele_id = (ele_id_layer - 1) * locs.elecol + ele_id_column;
            ele_id = total_id + ele_id;
            int id = locs.eleid1 - 1 + ele_id;
            return id;
        }
        private Int32 get_id(int channel_begain, int channel,//int channel_end,
                         int shelves_begain, int shelves, int shelves_end,
                         int layer_begin, int layer, int layer_end,
                         int columns_begin, int column, int columns_end,
                         int ele_begain,//int ele_end,
                         int ele_layer, int ele_column)
        {
            int ele_layer_count;
            int ele_column_count;
            ele_layer_count = layer_end / ele_layer;//单个标签管理的层数
            ele_column_count = columns_end / ele_column;//单个标签管理的列数
            int ele_id_layer;
            int ele_id_column;
            ele_id_layer = (layer - 1) / ele_layer_count + 1;    //电子标签的坐标值 层
            ele_id_column = (column - 1) / ele_column_count + 1; //电子标签的坐标值 列
            int ele_id;
            int channel_count = channel - channel_begain + 1;
            int shelves_count = shelves - shelves_begain + 1;
            int single_shelves = ele_layer * ele_column;
            int single_channel = single_shelves * (shelves_end - shelves_begain + 1);
            int total_id = (channel_count - 1) * single_channel + (shelves_count - 1) * single_shelves;
            //ele_id = ele_id_layer * ele_id_column;
            ele_id = 0;
            ele_id = (ele_id_layer - 1) * ele_column + ele_id_column;
            int base_count;
            ele_id = total_id + ele_id;
            base_count = ele_begain - 1 + ele_id;
            return base_count;
             
        }
        private bool valid()
        {
            return true;
        }
        //public void printLocations(DataTable dt)
        //{
        //    string reportName =   "wmsLocationCode.rdlc";           
        //    BillPrint.Run(dt, reportName, PrinterType.code);
        //    // new printUtils().print_report(dt, reportName, null, "code");wmsLocationCode.rdlc 
        //}
        protected override BaseModel getModel()
        {
            return _obj;
        }
        internal string  getWhereIds(int[] ids )
        {
            
             string wids = "";
            foreach (int id in ids)
            {
                wids +=  id + ",";
            }
            wids = wids.Substring(0, wids.Length - 1);
            return "(" + wids + ")";
        }
        public bool updateWhLocations(int[] ids, Structs locs)
        {
            return _obj.updateWhLocations(getWhereIds(ids), locs,operId);
        }
        internal bool updateSizeLocations(int[] ids, Structs locs)
        {
            return _obj.updateSizeLocations(getWhereIds(ids), locs, operId);
        }
 
        public bool updateLocationStatus(int[] ids, int status)
        {
            return _obj.updateLocationStatus(getWhereIds(ids), status, operId);
        }
        internal bool updateLocationTranLines(int[] ids, Structs locs)
        {
            return _obj.updateLocationTranLines(getWhereIds(ids), locs, operId);  
        }
        public bool updateLocationLabelId(int[] ids, Structs locs )
        {
            return _obj.updateLocationLabelId(getWhereIds(ids), locs, operId);  
        }
        public int deleteLocations(int[] ids)
        { 
            return    _obj.deleteLocations(getWhereIds(ids));
        }
        internal bool updateLocationABC(int[] ids, Structs locs)
        {
            return _obj.updateLocationABC(getWhereIds(ids), locs, operId);
        }
        internal bool updateLocationOwner(int[] ids, Structs locs)
        {
            return _obj.updateLocationOwner(getWhereIds(ids), locs, operId);
        }
        internal DataTable getLocationsUsedPercent()
        {
            return _obj.getLocationsUsedPercent();
        }
        internal bool updateLocationStoreType(int[] ids, Structs locs)
        {
            return _obj.updateLocationStoreType(getWhereIds(ids), locs, operId);
        }
        internal int locationEleIdCombine(string locId, int eleId)
        {
            WmsLocation loc = new WmsLocation(locId);
            int shelf = loc.shelf;
            int channel = loc.channel;
           return  loc.locationEleIdCombine(shelf, channel, eleId);
             
        }
 
    }
}