using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using Foresight.Data;
using Foresight.ServiceModel;
using IronIntel.Contractor.Maintenance;
using Foresight.Fleet.Services.Asset;

namespace IronIntel.Contractor.Machines
{
    public class MachineManagement
    {
        private static List<AssetMake> _Makes = new List<AssetMake>();
        private static object _sycmakes = new object();

        private static List<AssetType> _MachineTypes = new List<AssetType>();
        private static object _syctypes = new object();

        private static List<AssetModel> _MachineModels = new List<AssetModel>();
        private static object _sycmodels = new object();

        private const string MachineFields = "{0}MACHINEID,{0}MACHINENAME,{0}MAKEID,{0}MODELID,{0}TYPEID,{0}MACHINEICONID,{0}DEVICEID,{0}VIN,{0}MAKEYEAR,{0}NOTES,{0}STATUS,{0}CONTRACTORID,{0}DEALERID,{0}UID,{0}ADDEDON,{0}CUR_LONGITUDE,{0}CUR_LATITUDE,{0}LOCDATE_UTC,{0}ENGINEHOURS,{0}HOURSDATE_UTC,{0}DATASOURCE,{0}HIDE,{0}FUEL_CONSUMED,{0}FUEL_UNITS,{0}FUEL_DATE,{0}ODOMETER,{0}ODODATE_UTC,{0}ODOMETERUOM,{0}FUELCOST,{0}FUELCOSTUOM,{0}MACHINERATE,{0}WORKTYPE,{0}RETIREMENTHOURS,{0}RETIREMENTODO,{0}ALTITUDE,{0}ALTITUDEUNITS,{0}IDLEHOURSUTC,{0}IDLEHOURS,{0}LOADCOUNTUTC,{0}LOADCOUNT,{0}PAYLOADTOTALUTC,{0}PAYLOADTOTAL,{0}PAYLOADTOTALUNITS,{0}DEFREMAININGUTC,{0}DEFREMAINING,{0}FUELREMAININGUTC,{0}FUELREMAININGPERCENT,{0}MACHINENAME2,{0}ONROAD,{0}LEASESTART,{0}LEASEEND,{0}LEASEHOURS,{0}UNDERCARRIAGEHOURS,{0}ODOSTART2,{0}ISDELETED,{0}DELETEDDATE,{0}ODOSTART2DATASOURCE,{0}LOCDATASOURCE,{0}HOURSDATASOURCE,{0}FUELDATASOURCE,{0}AQUISITIONTYPE,{0}ICONFILENAME,{0}STARTINGENGINEHOURS,{0}DISTANCECALCBY,{0}TELEMATICSENABLED,{0}COSTCENTER,{0}EQCLASS,{0}DESCRIPTION,{0}ADDEDBY";

        static MachineManagement()
        {
            RefreshBaseData();
        }

        public static void RefreshBaseData()
        {
            RefreshMakes();
            RefreshModels();
            RefreshMachineTypes();
        }

        public static void RefreshMakes()
        {
            AssetMake[] mks = null;
            var acp = FleetServiceClientHelper.CreateClient<AssetClassProvider>();
            try
            {
                mks = acp.GetAssetMakes(string.Empty);
            }
            catch
            {
            }
            if (mks != null)
            {
                lock (_sycmakes)
                {
                    _Makes.Clear();
                    _Makes.AddRange(mks);
                }
            }
        }

        public static void RefreshMachineTypes()
        {
            AssetType[] mks = null;

            var acp = FleetServiceClientHelper.CreateClient<AssetClassProvider>();
            try
            {
                mks = acp.GetAssetTypes(string.Empty);
            }
            catch
            {
            }
            if (mks != null)
            {
                lock (_syctypes)
                {
                    _MachineTypes.Clear();
                    _MachineTypes.AddRange(mks);
                }
            }
        }

        public static void RefreshModels()
        {
            AssetModel[] mks = null;
            var acp = FleetServiceClientHelper.CreateClient<AssetClassProvider>();
            try
            {
                mks = acp.GetAssetModels(-1, string.Empty);
            }
            catch
            {
            }
            if (mks != null)
            {
                lock (_sycmodels)
                {
                    _MachineModels.Clear();
                    _MachineModels.AddRange(mks);
                }
            }
        }

        public static AssetMake[] GetMachineMakes()
        {
            lock (_sycmakes)
            {
                return _Makes.ToArray();
            }
        }

        public static AssetType[] GetMachineTypes()
        {
            lock (_syctypes)
            {
                return _MachineTypes.ToArray();
            }
        }

        public static AssetModel[] GetMachineModels()
        {
            lock (_sycmodels)
            {
                return _MachineModels.ToArray();
            }
        }

        public static AssetMake GetMachineMake(int makeid)
        {
            var makes = GetMachineMakes();
            foreach (var make in makes)
            {
                if (makeid == make.ID)
                {
                    return make;
                }
            }
            RefreshMakes();
            var makes2 = GetMachineMakes();
            foreach (var make in makes2)
            {
                if (makeid == make.ID)
                {
                    return make;
                }
            }
            return null;
        }

        public static string GetMachineMakeName(int makeid)
        {
            var make = GetMachineMake(makeid);
            return make == null ? string.Empty : make.Name;
        }

        public static AssetModel GetMachineModel(int modelid)
        {
            var models = GetMachineModels();
            foreach (var model in models)
            {
                if (model.ID == modelid)
                {
                    return model;
                }
            }
            RefreshModels();
            var models2 = GetMachineModels();
            foreach (var model in models2)
            {
                if (model.ID == modelid)
                {
                    return model;
                }
            }
            return null;
        }

        public static string GetMachineModelName(int modelid)
        {
            var model = GetMachineModel(modelid);
            return model == null ? string.Empty : model.Name;
        }

        public static AssetType GetMachineType(int typeid)
        {
            var types = GetMachineTypes();
            foreach (var mtype in types)
            {
                if (mtype.ID == typeid)
                {
                    return mtype;
                }
            }
            RefreshMachineTypes();
            var types2 = GetMachineTypes();
            foreach (var mtype in types2)
            {
                if (mtype.ID == typeid)
                {
                    return mtype;
                }
            }
            return null;
        }

        public static string GetMachineTypeName(int typeid)
        {
            var mtype = GetMachineType(typeid);
            return mtype == null ? string.Empty : mtype.Name;
        }

        public static AssetMake GetMachineMake(IEnumerable<AssetMake> makes, int id)
        {
            foreach (AssetMake mk in makes)
            {
                if (id == mk.ID)
                {
                    return mk;
                }
            }
            return null;
        }

        public static AssetType GetMachineType(IEnumerable<AssetType> types, int id)
        {
            foreach (AssetType mk in types)
            {
                if (id == mk.ID)
                {
                    return mk;
                }
            }
            return null;
        }

        public static AssetModel GetMachineModel(IEnumerable<AssetModel> models, int id)
        {
            foreach (AssetModel mk in models)
            {
                if (id == mk.ID)
                {
                    return mk;
                }
            }
            return null;
        }



        private static string _DefaultMachineTypeIconUrl = string.Empty;

        public static string DefaultMachineTypeIconUrl
        {
            get
            {
                if (string.IsNullOrWhiteSpace(_DefaultMachineTypeIconUrl))
                {
                    try
                    {
                        var acp = FleetServiceClientHelper.CreateClient<AssetClassProvider>();
                        _DefaultMachineTypeIconUrl = acp.GetDefaultMachineTypeIconUrl();
                    }
                    catch
                    { }
                }
                return _DefaultMachineTypeIconUrl;
            }
        }

        public static bool Contains(string text, string val)
        {
            if (!string.IsNullOrWhiteSpace(text))
            {
                return text.IndexOf(val, StringComparison.OrdinalIgnoreCase) >= 0;
            }
            else
            {
                return false;
            }
        }


        public static MachineItem[] GetSelectMachinesByRental(string sessionid, string useriid, string searchtxt, string companyid = null)
        {
            string SQL = "select " + string.Format(MachineFields, "") + " from MACHINES where AQUISITIONTYPE in ('Rental','Rerent','RPO') order by MACHINENAME";

            FIDbAccess db = null;
            if (string.IsNullOrEmpty(companyid))
            {
                companyid = SystemParams.CompanyID;
                db = SystemParams.GetDbInstance();
            }
            else
            {
                string connetionstring = SystemParams.GetDbStringByCompany(companyid);
                db = new FISqlConnection(connetionstring);
            }

            DataTable tb = db.GetDataTableBySQL(SQL);
            if (tb.Rows.Count == 0)
            {
                return new MachineItem[0];
            }

            long[] availableAssetsids = null;
            var user = Users.UserManagement.GetUserByIID(useriid);
            if (user.UserType < Users.UserTypes.Admin)
                availableAssetsids = FleetServiceClientHelper.CreateClient<AssetQueryClient>(companyid, sessionid).GetAvailableAssetsForUsers(companyid, useriid);

            RefreshBaseData();
            AssetMake[] makes = GetMachineMakes();
            AssetModel[] models = GetMachineModels();
            AssetType[] types = GetMachineTypes();

            List<MachineItem> ls = new List<MachineItem>();
            if (tb.Rows.Count > 0)
            {
                foreach (DataRow dr in tb.Rows)
                {
                    long mid = FIDbAccess.GetFieldInt64(dr["MACHINEID"], 0);
                    if (user.UserType < Users.UserTypes.Admin && !availableAssetsids.Contains(mid))
                        continue;
                    MachineItem mi = ConvertToMachineItem(dr, makes, models, types);
                    if (!string.IsNullOrWhiteSpace(searchtxt))
                    {
                        if (Helper.Contains(mi.VIN, searchtxt)
                            || Helper.Contains(mi.MachineID.ToString(), searchtxt)
                            || Helper.Contains(mi.Name, searchtxt)
                            || Helper.Contains(mi.Name2, searchtxt)
                            || Helper.Contains(mi.Make, searchtxt)
                            || Helper.Contains(mi.MachineType, searchtxt)
                            || Helper.Contains(mi.Model, searchtxt))
                        {
                            ls.Add(mi);
                        }
                    }
                    else
                    {
                        ls.Add(mi);
                    }
                }
            }
            return ls.ToArray();
        }

        private static MachineItem ConvertToMachineItem(DataRow dr, AssetMake[] makes, AssetModel[] models, AssetType[] types)
        {
            MachineItem mi = new MachineItem();
            mi.MachineID = FIDbAccess.GetFieldInt(dr["MACHINEID"], 0);
            mi.Name = FIDbAccess.GetFieldString(dr["MACHINENAME"], string.Empty);
            mi.Name2 = FIDbAccess.GetFieldString(dr["MACHINENAME2"], string.Empty);
            mi.VIN = FIDbAccess.GetFieldString(dr["VIN"], string.Empty);
            mi.Notes = FIDbAccess.GetFieldString(dr["NOTES"], string.Empty);
            mi.MakeYear = FIDbAccess.GetFieldInt(dr["MAKEYEAR"], 0);
            mi.ContractorID = FIDbAccess.GetFieldString(dr["CONTRACTORID"], string.Empty);
            mi.DealerID = FIDbAccess.GetFieldString(dr["DEALERID"], string.Empty);
            mi.Status = FIDbAccess.GetFieldInt(dr["STATUS"], 0);
            mi.StartingEngineHours = FIDbAccess.GetFieldDouble(dr["STARTINGENGINEHOURS"], 0);
            mi.EngineHours = FIDbAccess.GetFieldDouble(dr["ENGINEHOURS"], 0);
            mi.EngineHoursDate = FIDbAccess.GetFieldDateTime(dr["HOURSDATE_UTC"], DateTime.MinValue);
            mi.Hide = FIDbAccess.GetFieldInt(dr["HIDE"], 0) == 1;
            mi.ODOStart2 = FIDbAccess.GetFieldDouble(dr["ODOSTART2"], 0);
            mi.ODOMeter = FIDbAccess.GetFieldDouble(dr["ODOMETER"], 0);
            mi.ODOMeterDate = FIDbAccess.GetFieldDateTime(dr["ODODATE_UTC"], DateTime.MinValue);
            mi.ODOMeterUom = FIDbAccess.GetFieldString(dr["ODOMETERUOM"], string.Empty);
            mi.FuelCost = FIDbAccess.GetFieldDouble(dr["FUELCOST"], 0);
            mi.FuelCostUom = FIDbAccess.GetFieldString(dr["FUELCOSTUOM"], string.Empty);
            mi.MachineRate = FIDbAccess.GetFieldDouble(dr["MACHINERATE"], 0);
            mi.WorkType = FIDbAccess.GetFieldString(dr["WORKTYPE"], string.Empty);
            mi.RetirementHours = FIDbAccess.GetFieldDouble(dr["RETIREMENTHOURS"], 0);
            mi.RetirementOdo = FIDbAccess.GetFieldDouble(dr["RETIREMENTODO"], 0);

            mi.MakeID = FIDbAccess.GetFieldInt(dr["MAKEID"], 0);
            AssetMake make = GetMachineMake(makes, mi.MakeID);
            mi.Make = make == null ? string.Empty : make.Name;

            mi.ModelID = FIDbAccess.GetFieldInt(dr["MODELID"], 0);
            AssetModel model = GetMachineModel(models, mi.ModelID);
            mi.Model = model == null ? string.Empty : model.Name;

            mi.TypeID = FIDbAccess.GetFieldInt(dr["TYPEID"], 0);
            AssetType mtype = GetMachineType(types, mi.TypeID);
            mi.MachineType = mtype == null ? string.Empty : mtype.Name;
            mi.OnRoad = FIDbAccess.GetFieldInt(dr["ONROAD"], 0) == 1;
            mi.LeaseStart = FIDbAccess.GetFieldDateTime(dr["LEASESTART"], DateTime.MinValue);
            mi.LeaseEnd = FIDbAccess.GetFieldDateTime(dr["LEASEEND"], DateTime.MinValue);
            mi.LeaseTerm = FIDbAccess.GetFieldDouble(dr["LEASEHOURS"], 0);
            mi.UndercarriageHours = FIDbAccess.GetFieldDouble(dr["UNDERCARRIAGEHOURS"], 0);
            mi.AquisitionType = FIDbAccess.GetFieldString(dr["AQUISITIONTYPE"], "");

            mi.GpsDeviceID = FIDbAccess.GetFieldInt(dr["DEVICEID"], -1);
            mi.MachineIconFileName = FIDbAccess.GetFieldString(dr["ICONFILENAME"], "");
            mi.DistanceCalcBy = FIDbAccess.GetFieldString(dr["DISTANCECALCBY"], "");

            mi.TelematicsEnabled = FIDbAccess.GetFieldInt(dr["TELEMATICSENABLED"], 0) == 1;
            mi.CostCenter = FIDbAccess.GetFieldString(dr["COSTCENTER"], "");
            mi.EqClass = FIDbAccess.GetFieldString(dr["EQCLASS"], "");
            mi.Description = FIDbAccess.GetFieldString(dr["DESCRIPTION"], "");

            return mi;
        }

        public static int SaveMachineGroup(MachineGroup mg)
        {
            const string SQL_Insert = "insert into MACHINEGROUPS (GROUPID,GROUPNAME,DESCRIPTION,CODE) values ({0},{1},{2},{3})";
            const string SQL_Update = "update MACHINEGROUPS set GROUPNAME={1},DESCRIPTION={2},CODE={3} where GROUPID={0} ";
            const string SQL_Exists = "select Count(1) from MACHINEGROUPS where GROUPNAME={0} and GROUPID<>{1}";
            const string SQL_DeleteDetail = "delete MACHINEGROUPMAP where GROUPID={0}";
            const string SQL_InsertDetail = "insert MACHINEGROUPMAP(MACHINEID,GROUPID) values({0},{1})";
            FISqlConnection db = SystemParams.GetDbInstance();

            int count = FIDbAccess.GetFieldInt(db.GetRC1BySQL(SQL_Exists, mg.GroupName, mg.GroupID ?? ""), 0);
            if (count > 0)
                return -1;

            if (string.IsNullOrWhiteSpace(mg.GroupID))
            {
                mg.GroupID = Guid.NewGuid().ToString();
                db.ExecSQL(SQL_Insert, mg.GroupID, mg.GroupName, mg.Description, mg.Code);
                if (mg.MachineIDs != null && mg.MachineIDs.Length > 0)
                {
                    foreach (long mid in mg.MachineIDs)
                        db.ExecSQL(SQL_InsertDetail, mid, mg.GroupID);
                }
            }
            else
            {
                db.ExecSQL(SQL_Update, mg.GroupID, mg.GroupName, mg.Description, mg.Code);
                db.ExecSQL(SQL_DeleteDetail, mg.GroupID);
                if (mg.MachineIDs != null && mg.MachineIDs.Length > 0)
                {
                    foreach (long mid in mg.MachineIDs)
                        db.ExecSQL(SQL_InsertDetail, mid, mg.GroupID);
                }
            }
            return 0;
        }

        public static int DeleteMachineGroup(string groupID)
        {
            const string SQL_Delete = "delete from MACHINEGROUPS where GROUPID={0} delete from MACHINEGROUPMAP where GROUPID={0} ";
            const string SQL_Exists = "select Count(1) from USERMACHINEGROUPMAP where GROUPID={0}";

            FISqlConnection db = SystemParams.GetDbInstance();
            int count = FIDbAccess.GetFieldInt(db.GetRC1BySQL(SQL_Exists, groupID ?? ""), 0);
            if (count > 0)
                return -1;

            db.ExecSQL(SQL_Delete, groupID);
            return 0;
        }

        public static MachineGroup[] GetMachineGroups(string searchtext, FISqlConnection db = null)
        {
            string SQL = "select GROUPID,GROUPNAME,DESCRIPTION,CODE from MACHINEGROUPS ";
            if (!string.IsNullOrEmpty(searchtext))
                SQL += " where GROUPNAME like {0} or DESCRIPTION like {0} or CODE like {0}";

            if (db == null)
                db = SystemParams.GetDbInstance();
            DataTable dt = db.GetDataTableBySQL(SQL, "%" + searchtext + "%");

            List<MachineGroup> result = new List<MachineGroup>();
            foreach (DataRow dr in dt.Rows)
            {
                MachineGroup mg = new MachineGroup();
                mg.GroupID = FIDbAccess.GetFieldString(dr["GROUPID"], "");
                mg.GroupName = FIDbAccess.GetFieldString(dr["GROUPNAME"], "");
                mg.Description = FIDbAccess.GetFieldString(dr["DESCRIPTION"], "");
                mg.Code = FIDbAccess.GetFieldString(dr["CODE"], "");
                result.Add(mg);
            }
            return result.ToArray();
        }

        public static MachineGroup[] GetMachineGroupsByUser(string useriid, FISqlConnection db = null)
        {
            string SQL = @"select GROUPID,GROUPNAME,DESCRIPTION from MACHINEGROUPS mg where (select case when not exists(select 1 from USERMACHINEGROUPMAP where USERIID={0}) then 1
            when exists(select 1 from USERMACHINEGROUPMAP g where USERIID={0} and mg.GROUPID=g.GROUPID) then 1 else 0 end) = 1";

            if (db == null)
                db = SystemParams.GetDbInstance();
            DataTable dt = db.GetDataTableBySQL(SQL, useriid);

            List<MachineGroup> result = new List<MachineGroup>();
            foreach (DataRow dr in dt.Rows)
            {
                MachineGroup mg = new MachineGroup();
                mg.GroupID = FIDbAccess.GetFieldString(dr["GROUPID"], "");
                mg.GroupName = FIDbAccess.GetFieldString(dr["GROUPNAME"], "");
                mg.Description = FIDbAccess.GetFieldString(dr["DESCRIPTION"], "");
                result.Add(mg);
            }
            return result.ToArray();
        }

        public static MachineItem[] GetMachineByGroup(string groupid)
        {
            string SQL = "select " + string.Format(MachineFields, "b.") + " from MACHINEGROUPMAP a with(nolock) left join MACHINES b with(nolock) on a.MACHINEID=b.MACHINEID where a.GROUPID={0} order by MACHINENAME";

            FIDbAccess db = SystemParams.GetDbInstance();
            if (db == null)
            {
                return new MachineItem[0];
            }

            DataTable tb = db.GetDataTableBySQL(SQL, groupid);
            if (tb.Rows.Count == 0)
            {
                return new MachineItem[0];
            }

            RefreshBaseData();
            AssetMake[] makes = GetMachineMakes();
            AssetModel[] models = GetMachineModels();
            AssetType[] types = GetMachineTypes();

            List<MachineItem> ls = new List<MachineItem>();
            if (tb.Rows.Count > 0)
            {
                foreach (DataRow dr in tb.Rows)
                {
                    MachineItem mi = ConvertToMachineItem(dr, makes, models, types);
                    ls.Add(mi);
                }
            }
            return ls.ToArray();
        }

        public static MachineGroup[] GetMachineGroupByUser(string useriid, FISqlConnection db = null)
        {
            const string SQL = "select b.* from USERMACHINEGROUPMAP a with(nolock) left join MACHINEGROUPS b with(nolock) on a.GROUPID=b.GROUPID where a.USERIID={0} order by GROUPNAME";

            if (db == null)
                db = SystemParams.GetDbInstance();
            DataTable dt = db.GetDataTableBySQL(SQL, useriid);

            List<MachineGroup> result = new List<MachineGroup>();
            foreach (DataRow dr in dt.Rows)
            {
                MachineGroup mg = new MachineGroup();
                mg.GroupID = FIDbAccess.GetFieldString(dr["GROUPID"], "");
                mg.GroupName = FIDbAccess.GetFieldString(dr["GROUPNAME"], "");
                mg.Description = FIDbAccess.GetFieldString(dr["DESCRIPTION"], "");
                result.Add(mg);
            }
            return result.ToArray();
        }

        public static AssetType[] GetMachineTypesByUser(string useriid, FISqlConnection db = null)
        {
            const string SQL = "select b.* from USERMACHINETYPEMAP a with(nolock) left join MACHINE_TYPE b with(nolock) on a.TYPEID=b.TYPEID where a.USERIID={0} order by TYPENAME";

            if (db == null)
                db = SystemParams.GetDbInstance();
            DataTable dt = db.GetDataTableBySQL(SQL, useriid);

            List<AssetType> result = new List<AssetType>();
            foreach (DataRow dr in dt.Rows)
            {
                AssetType mg = new AssetType();
                mg.ID = FIDbAccess.GetFieldInt(dr["TYPEID"], 0);
                mg.Name = FIDbAccess.GetFieldString(dr["TYPENAME"], "");
                result.Add(mg);
            }
            return result.ToArray();
        }

        /// <summary>
        /// 获取机器组和机器的对应关系
        /// </summary>
        /// <returns></returns>
        public static long[] GetGroupMachines(string[] groupids, FISqlConnection db = null)
        {
            const string SQL_C = "select distinct MACHINEID from MACHINEGROUPMAP with(nolock) where GROUPID in ({0})";

            List<long> result = new List<long>();
            if (db == null)
                db = SystemParams.GetDbInstance();
            DataTable tb = db.GetDataTableBySQL(string.Format(SQL_C, "'" + string.Join("','", groupids) + "'"));

            foreach (DataRow dr in tb.Rows)
            {
                int machineid = FIDbAccess.GetFieldInt(dr["MACHINEID"], -1);
                result.Add(machineid);
            }
            return result.ToArray();
        }

        public static void ChangeMachineIconFile(long machineid, string filename, byte[] filebyte, FISqlConnection db = null)
        {
            const string SQL_NULL = "update MACHINES set ICONFILENAME=null,ICONDATA=null where MACHINEID={0}";
            const string SQL_ICON = "update MACHINES set ICONFILENAME={1},ICONDATA={2} where MACHINEID={0}";

            if (db == null)
                db = SystemParams.GetDbInstance();
            if (filebyte == null)
                db.ExecSQL(SQL_NULL, machineid);
            else
                db.ExecSQL(SQL_ICON, machineid, filename, filebyte);
        }


        public static string GetMachineIDByVIN(string vin)
        {
            const string SQL = "select MACHINEID from MACHINES with(nolock) where VIN={0} and (HIDE is null or HIDE=0)";
            FISqlConnection db = SystemParams.GetDbInstance();

            object obj = db.GetRC1BySQL(SQL, vin);
            return FIDbAccess.GetFieldString(obj, string.Empty);
        }

        public static MaintenanceMachineInfo[] GetContactMachinesByID(string contactid)
        {
            const string SQL = @"select a.MACHINEID,b.MACHINENAME,b.MACHINENAME2,b.VIN,b.MAKEID,b.MODELID,b.TYPEID,b.HIDE,ISNULL(b.ENGINEHOURS,0) as ENGINEHOURS,
                    ISNULL(b.ODOMETER,0) as ODOMETER,ISNULL(b.ODOMETERUOM,'Mile') AS ODOMETERUOM from USERMACHINEMAP a with(nolock),MACHINES b with(nolock) 
                    where a.MACHINEID=b.MACHINEID and a.USERIID={0}";

            FISqlConnection db = SystemParams.GetDbInstance();
            DataTable tb = db.GetDataTableBySQL(SQL, contactid);
            if (tb.Rows.Count == 0)
            {
                return new MaintenanceMachineInfo[0];
            }
            RefreshBaseData();
            AssetMake[] makes = GetMachineMakes();
            AssetModel[] models = GetMachineModels();
            AssetType[] types = GetMachineTypes();
            List<MaintenanceMachineInfo> ls = new List<MaintenanceMachineInfo>();
            foreach (DataRow dr in tb.Rows)
            {
                MaintenanceMachineInfo mi = MaintenanceManagement.ConvertToMaintenanceMachineInfo(dr, makes, models, types);
                ls.Add(mi);
            }
            return ls.ToArray();

        }
    }
}
