| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568 | using InABox.Integration.Logikal;using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Threading.Tasks;using Ofcas.Lk.Api.Client.Core;using Ofcas.Lk.Api.Client.Ui;using Ofcas.Lk.Api.Shared;namespace PRSLogikal{    public class LogikalLogArguments    {        public String Message { get; private set; }        public LogikalLogArguments(string message)        {            Message = message;        }            }    public delegate void LogikalLogEvent(object sender, LogikalLogArguments args);        public class LogikalServer : IDisposable    {        public event LogikalLogEvent Log;        private void DoLog(String message) => Log?.Invoke(this, new LogikalLogArguments(message));                private IServiceProxyUiResult _proxy;        private ICoreObjectResult<ILoginScopeUi> _login;        public IntPtr WindowHandle { get; private set; }        private static readonly LogikalErrorResponse NOTCONNECTED = new LogikalErrorResponse()        {            Status = LogikalStatus.Disconnected,            Message = $"LogiKal is not connected"        };                private static readonly LogikalErrorResponse NOTLOGGEDIN = new LogikalErrorResponse()        {            Status = LogikalStatus.NotLoggedIn,            Message = $"Not Logged In"        };                public LogikalServer(IntPtr windowHandle)        {            WindowHandle = windowHandle;        }                        public LogikalResponse Connect(LogikalConnectRequest request)        {            if (_proxy != null)                return new LogikalConnectResponse();                        var _p = ServiceProxyUiFactory.CreateServiceProxy(request.Path, "ERP");            var _status = _p.ServiceProxyUi.Start();            if (_status.OperationCode != OperationCode.Accepted)            {               return new LogikalErrorResponse()               {                   Status = LogikalStatus.CannotConnect,                   Message = $"Unable to connect to LogiKal at [{request.Path}]: {_status}"               };            }            _proxy = _p;            return new LogikalConnectResponse();        }        public LogikalResponse Disconnect()        {            if (_login != null)                Logout();            if (_proxy != null)            {                _proxy.ServiceProxyUi.Stop();                _proxy.Dispose();            }            _proxy = null;            return new LogikalDisconnectResponse();        }        private void DoOnDisconnecting()        {                    }        public LogikalResponse Login(LogikalLoginRequest request)        {            Dictionary<string, object> _parameters = new Dictionary<string, object>()            {                { WellKnownParameterKey.Login.ProgramMode, "erp" },                { WellKnownParameterKey.Login.ApplicationHandle, WindowHandle },                //{ WellKnownParameterKey.Login.UserName, username },                //{ WellKnownParameterKey.Login.Password, password },                { WellKnownParameterKey.Login.EnableEventSynchronization, true },            };            if (_proxy == null)                return NOTCONNECTED;            if (_login != null)                return new LogikalLoginResponse();            var _check = _proxy.ServiceProxyUi.CanLogin(_parameters);            if (!_check.CanExecute)            {                return new LogikalErrorResponse()                {                    Status = LogikalStatus.Restricted,                    Message = $"Login not allowed: {_check}!"                };            }            try            {                var _l = _proxy.ServiceProxyUi.Login(_parameters);                if (_l.OperationCode != OperationCode.Accepted)                {                    _login = null;                    return new LogikalErrorResponse()                    {                        Status = LogikalStatus.Failed,                        Message = $"Login failed: {_l}"                    };                }                else                {                    _login = _l;                    return new LogikalLoginResponse();                }            }            catch (Exception e)            {                return new LogikalErrorResponse()                {                    Status = LogikalStatus.Error,                    Message = $"{e.Message}\n{e.StackTrace}"                };            }                    }        public LogikalResponse Logout()        {            if (_login != null)                _login.Dispose();            _login = null;            return new LogikalLogoutResponse();        }        public bool IsLoggedIn() => _login != null;        private void GetProjectCentres(ICoreObjectResult<IProjectCenterUi> center, List<LogikalProjectCentre> results)        {            var _projectresults = new List<LogikalProject>();            IList<IBaseProjectInfo> _projects = center.CoreObject.ChildrenInfos;            foreach (var _project in _projects)            {                var _summary = new LogikalProject();                PopulateProject(_project, _summary);                _projectresults.Add(_summary);            }            var _result = new LogikalProjectCentre()            {                ID = center.CoreObject.ProjectCenterContainer.Id,                Name = center.CoreObject.Parent != null ? center.CoreObject.Info.DirectoryName : "Project Center",                ParentID = center.CoreObject.Parent != null                    ? center.CoreObject.Parent.ProjectCenterContainer.Id                    : Guid.Empty,                Projects = _projectresults.ToArray()            };            results.Add(_result);            var _children = center.CoreObject.ProjectCenterContainer.GetChildren().CoreObjectResults;            foreach (var _child in _children)                          GetProjectCentres(_child, results);         }        private void PopulateProject(IBaseProjectInfo source, ILogikalProject target)        {            target.ID = source.Guid;            target.Title = source.Name;            target.PersonInCharge = source.PersonInCharge;            target.Path = source.Path;            target.LastUpdated = source.LastChangedDateTime;            target.Created = source.CreatedDateTime;            target.JobNumber = source.AsProjectInfo().JobNumber;            target.OfferNumber = source.AsProjectInfo().OfferNumber;        }        private List<LogikalProjectCentre> GetProjectCentres()        {            var _results = new List<LogikalProjectCentre>();            var _info = _login.CoreObject.ProjectCenterInfos.FirstOrDefault(x => x.Type.Id == 0);            if (_info != null)            {                var _center = _login.CoreObject.GetProjectCenter(_info);                GetProjectCentres(_center, _results);            }            return _results;        }        public LogikalResponse GetProjectCentres(LogikalProjectCentresRequest request)        {            if (_proxy == null)                return NOTCONNECTED;            if (_login == null)                return NOTLOGGEDIN;            var _results = GetProjectCentres();            return new LogikalProjectCentresResponse<LogikalProjectCentre,LogikalProject>() { ProjectCentres = _results.ToArray() };        }        public LogikalResponse GetProjects(LogikalProjectsRequest request)        {            if (_proxy == null)                return NOTCONNECTED;            if (_login == null)                return NOTLOGGEDIN;            List<LogikalProject> _results = new List<LogikalProject>();            var _centres = GetProjectCentres();            foreach (var _centre in _centres)            {                var _projects = _centre.Projects.Where(x => string.IsNullOrWhiteSpace(request.JobNumber) || string.Equals(x.JobNumber, request.JobNumber));                _results.AddRange(_projects);            }                       return new LogikalProjectsResponse<LogikalProject>() { Projects = _results.ToArray() };                    }        public LogikalResponse GetProject(LogikalProjectRequest request)        {            if (_proxy == null)                return NOTCONNECTED;            if (_login == null)                return NOTLOGGEDIN;            var _project = _login.CoreObject.GetProjectByGuid(request.ProjectID);            if (_project == null)                return new LogikalErrorResponse()                {                    Status = LogikalStatus.InvalidProjectID,                    Message = $"Cannot Load Project {request.ProjectID}"                };            var response = new LogikalProjectResponse<LogikalProject>();            PopulateProject(_project.CoreObject.Info, response.Project);            return response;                   }        public LogikalResponse GetPhases(LogikalPhasesRequest request)        {            if (_proxy == null)                return NOTCONNECTED;            if (_login == null)                return NOTLOGGEDIN;            var _project = _login.CoreObject.GetProjectByGuid(request.ProjectID);            if (_project == null)                return new LogikalErrorResponse()                {                    Status = LogikalStatus.InvalidProjectID,                    Message = $"Cannot Load Project {request.ProjectID}"                };            List<LogikalPhase> _results = new List<LogikalPhase>();            var _phases = _project.CoreObject.GetChildren().CoreObjectResults;            foreach (ICoreObjectResult<IPhase> _phase in _phases)            {                var _result = new LogikalPhase()                {                    ID = _phase.CoreObject.Info.Name,                    Title = string.IsNullOrWhiteSpace(_phase.CoreObject.Info.Name) ? "Default Phase" : _phase.CoreObject.Info.Name                };                _results.Add(_result);            }            return new LogikalPhasesResponse<LogikalPhase>() { Phases = _results.ToArray() };        }        public LogikalResponse GetElevationSummaries(LogikalElevationSummaryRequest request)        {            if (_proxy == null)                return NOTCONNECTED;            if (_login == null)                return NOTLOGGEDIN;            var _results = new List<LogikalElevationSummary>();            var _project = _login.CoreObject.GetProjectByGuid(request.ProjectID);            if (_project == null)                return new LogikalErrorResponse()                {                    Status = LogikalStatus.InvalidProjectID,                    Message = $"Cannot Load Project {request.ProjectID}"                };            var _phases = _project.CoreObject.GetChildren().CoreObjectResults;            var _phase = _phases.FirstOrDefault(x => x.CoreObject.Info.Name == request.Phase);            if (_phase == null)                return new LogikalErrorResponse()                {                    Status = LogikalStatus.InvalidPhaseID,                    Message = $"Cannot find phase [{request.Phase}] within project [{request.ProjectID}]"                };                        var _elevations = _phase.CoreObject.GetChildren().CoreObjectResults;            foreach (var _elevation in _elevations)            {                if (!_elevation.CoreObject.Info.IsInRecycleBin)                {                    var _result = new LogikalElevationSummary();                    PopulateElevation(_elevation.CoreObject, _result);                    _results.Add(_result);                }            }            return new LogikalElevationSummaryResponse<LogikalElevationSummary>() { Elevations = _results.ToArray() };        }        private void PopulateElevation(IElevation source, ILogikalElevationSummary target)        {            target.ID = source.Info.Guid;            target.Name = source.Info.Name;            target.Description = source.Info.SystemDescription;            target.Size = source.Info.Size;            using (var ms = new MemoryStream())            {                IStreamResult thumbnail =                   source.GetThumbnail(new Dictionary<string, object>() { });                thumbnail.Stream.CopyTo(ms);                target.Thumbnail = ms.GetBuffer();            }        }        public LogikalResponse GetBillOfMaterials(LogikalBOMRequest request)        {            if (_proxy == null)                return NOTCONNECTED;            if (_login == null)                return NOTLOGGEDIN;            var _project = _login.CoreObject.GetProjectByGuid(request.ProjectID);            if (_project == null)                return new LogikalErrorResponse()                {                    Status = LogikalStatus.InvalidProjectID,                    Message = $"Cannot Load Project [{request.ProjectID}]"                };            var _elevations = new List<IElevationInfo>();                       if (request.ElevationIDs?.Any() == true)            {                var _phases = _project.CoreObject.GetChildren();                foreach (var _phase in _phases.CoreObjectResults)                    _elevations.AddRange(_phase.CoreObject.ChildrenInfos.Where(x => request.ElevationIDs.Contains(x.Guid)));            }            using (IReportItemsResult reportItemsResult = _project.CoreObject.GetReports())            {                if (reportItemsResult.OperationCode != OperationCode.Accepted)                {                    return new LogikalErrorResponse()                    {                        Status = LogikalStatus.Error,                        Message = $"Cannot Get Reports for Project!"                    };                }                // Filter available reports for the erp export report item                IReportItem reportItem = reportItemsResult.ReportItems.First(rep =>                    (rep.Id == WellKnownReports.Delivery.ErpExport) &&                    (rep.Category.Id == WellKnownReports.Delivery.CategoryId));                // Create parameters for erp export, export format is required, but always sqlite                var exportParameters = new Dictionary<string, object>                {                    { WellKnownParameterKey.Project.Report.ExportFormat, "SQLite" },                };                // Check if report can be exported for the given parameters                var operationInfo = _project.CoreObject.CanGetReport(reportItem, _elevations, exportParameters);                if (!operationInfo.CanExecute)                {                    return new LogikalErrorResponse()                    {                        Status = LogikalStatus.Error,                        Message = $"Cannot Get Erp Report for Project!"                    };                }                // Run report creation asynchronously - begin method starts the operation in background task                using (ISynchronizedOperationResult synchronizedOperationResult =                    _project.CoreObject.BeginGetReport(reportItem, _elevations, exportParameters))                {                    var response = new LogikalBOMResponse<LogikalBOM, LogikalFinish, LogikalProfile, LogikalGasket, LogikalComponent, LogikalGlass, LogikalLabour>();                    // End method waits for the background operation to complete in separate task                    using (IStreamResult partsResult = Task.Run<IStreamResult>(() =>                        _project.CoreObject.EndGetReport(synchronizedOperationResult.SynchronizedOperation)).Result)                    {                        Stream exportStream = partsResult.Stream;                        using (var _ms = new MemoryStream())                        {                            exportStream.CopyTo(_ms);                            response.BOM.SQLiteData = _ms.GetBuffer();                        }                    }                    return response;                }            }        }        public LogikalResponse GetElevationDetails(LogikalElevationDetailRequest detailRequest)        {                        var _project = _login.CoreObject.GetProjectByGuid(detailRequest.ProjectID);            if (_project == null)                return new LogikalErrorResponse()                {                    Status = LogikalStatus.InvalidProjectID,                    Message = $"Cannot Load Project [{detailRequest.ProjectID}]"                };            Dictionary<Guid, ICoreObjectResult<IElevationUi>> elevations = new Dictionary<Guid, ICoreObjectResult<IElevationUi>>();            var _phases = _project.CoreObject.GetChildren().CoreObjectResults;            foreach (var id in detailRequest.IDs)            {                foreach (var _phase in _phases)                {                    var ui = _phase.CoreObject.GetChildren().CoreObjectResults                        .FirstOrDefault(e => e.CoreObject.Info.Guid == id);                    if (ui != null)                        elevations[id] = ui;                }                if (!elevations.ContainsKey(id))                {                    return new LogikalErrorResponse()                    {                        Status = LogikalStatus.ElevationNotFound,                        Message = $"Cannot find Elevation [{id}] within project [{detailRequest.ProjectID}]"                    };                }            }                        try            {                List<LogikalElevationDetail> results = new List<LogikalElevationDetail>();                var response = new LogikalElevationDetailResponse<LogikalElevationDetail, LogikalFinish, LogikalProfile, LogikalGasket, LogikalComponent, LogikalGlass, LogikalLabour>();                foreach (var id in elevations.Keys)                {                    var _elevation = elevations[id];                    LogikalElevationDetail newel = new LogikalElevationDetail();                                        PopulateElevation(_elevation.CoreObject, newel);                                        var dxf = ElevationDetails(detailRequest, _elevation, id, newel, detailRequest.DrawingFormat, detailRequest.DrawingView, detailRequest.DrawingType);                    if (dxf != null)                        return dxf;                                        results.Add(newel);                }                response.Elevations = results;                return response;            }            catch (Exception e)            {                return new LogikalErrorResponse() { Status = LogikalStatus.Error, Message = $"{e.Message}\n\n{e.StackTrace}" };            }        }        private LogikalResponse ElevationDetails(LogikalElevationDetailRequest detailRequest, ICoreObjectResult<IElevationUi> _elevation, Guid id,            LogikalElevationDetail newel, LogikalDrawingFormat format, LogikalDrawingView view, LogikalDrawingType type)        {            // Setup parameters for export of the elevation drawing            var sectionDrawingParameters = new Dictionary<string, object>            {                { WellKnownParameterKey.Elevation.Drawing.Format, format == LogikalDrawingFormat.DXF ? ElevationDrawingFormat.DXF : ElevationDrawingFormat.PNG },                { WellKnownParameterKey.Elevation.Drawing.View, view == LogikalDrawingView.Exterior ? View.Exterior : View.Interior },                { WellKnownParameterKey.Elevation.Drawing.Type, type == LogikalDrawingType.Explosion                    ? ElevationDrawingType.Explosion                    : type == LogikalDrawingType.Section                        ? ElevationDrawingType.Section                        : type == LogikalDrawingType.Elevation                            ? ElevationDrawingType.Elevation                            : type == LogikalDrawingType.ElevationWithSectionLines                                ? ElevationDrawingType.ElevationWithSectionLines                                : ElevationDrawingType.SectionLine                 },                { WellKnownParameterKey.Elevation.Drawing.DxfVersion, DxfVersion.Acad2013 },                { WellKnownParameterKey.Elevation.Drawing.ShowDescription, true },                { WellKnownParameterKey.Elevation.Drawing.ShowDimensions, true },                { WellKnownParameterKey.Elevation.Drawing.Scale, 1.0 },            };            // Check if the drawing can be exported for the elevation with the given parameters            if (!_elevation.CoreObject.CanGetDrawing(sectionDrawingParameters).CanExecute)            {                return new LogikalErrorResponse()                {                    Status = LogikalStatus.Error,                    Message = $"GetDrawing() not permitted for Elevation [{id}]"                };            }                                // Generate drawing for the elevation with the given parameters            using (IDrawingResult drawingResult = _elevation.CoreObject.GetDrawing(sectionDrawingParameters))            {                Stream exportStream = drawingResult.Stream;                using (var _ms = new MemoryStream())                {                    exportStream.CopyTo(_ms);                    newel.Drawing = _ms.GetBuffer();                }            }            using (IStreamResult partsResult = _elevation.CoreObject.GetPartsList())            {                Stream exportStream = partsResult.Stream;                using (var _ms = new MemoryStream())                {                    exportStream.CopyTo(_ms);                    newel.SQLiteData = _ms.GetBuffer();                }            }            return null;        }                public void Dispose()        {            Disconnect();        }    }}
 |