LogikalServer.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842
  1. using InABox.Integration.Logikal;
  2. using PRSLogikal.OpenXML;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Data;
  6. using System.Data.SQLite;
  7. using System.Diagnostics;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Threading.Tasks;
  11. using Ofcas.Lk.Api.Client.Core;
  12. using Ofcas.Lk.Api.Client.Ui;
  13. using Ofcas.Lk.Api.Shared;
  14. namespace PRSLogikal
  15. {
  16. public class LogikalLogArguments
  17. {
  18. public String Message { get; private set; }
  19. public LogikalLogArguments(string message)
  20. {
  21. Message = message;
  22. }
  23. }
  24. public delegate void LogikalLogEvent(object sender, LogikalLogArguments args);
  25. public class LogikalServer : IDisposable
  26. {
  27. public event LogikalLogEvent Log;
  28. private void DoLog(String message) => Log?.Invoke(this, new LogikalLogArguments(message));
  29. private IServiceProxyUiResult _proxy;
  30. private ICoreObjectResult<ILoginScopeUi> _login;
  31. public IntPtr WindowHandle { get; private set; }
  32. private static readonly LogikalErrorResponse NOTCONNECTED = new LogikalErrorResponse()
  33. {
  34. Status = LogikalStatus.Disconnected,
  35. Message = $"LogiKal is not connected"
  36. };
  37. private static readonly LogikalErrorResponse NOTLOGGEDIN = new LogikalErrorResponse()
  38. {
  39. Status = LogikalStatus.NotLoggedIn,
  40. Message = $"Not Logged In"
  41. };
  42. public LogikalServer(IntPtr windowHandle)
  43. {
  44. WindowHandle = windowHandle;
  45. }
  46. public LogikalResponse Connect(LogikalConnectRequest request)
  47. {
  48. if (_proxy != null)
  49. return new LogikalConnectResponse();
  50. // Check that LogiKal is actually running from the folder we have specified
  51. var _driveLetter = Path.GetPathRoot(request.Path)?.Split(':').FirstOrDefault()?.ToLower() ?? "c";
  52. var _processes = Process.GetProcessesByName("LogiKal");
  53. var _running = _processes.Any(x => x.MainModule?.FileName.ToLower().Contains($"{_driveLetter}\\common\\bin\\logikal.exe") == true);
  54. if (!_running)
  55. {
  56. return new LogikalErrorResponse()
  57. {
  58. Status = LogikalStatus.NotRunning,
  59. Message = $"LogiKal is not running at [{request.Path}]"
  60. };
  61. }
  62. var _p = ServiceProxyUiFactory.CreateServiceProxy(request.Path, "ERP");
  63. var _status = _p.ServiceProxyUi.Start();
  64. if (_status.OperationCode != OperationCode.Accepted)
  65. {
  66. return new LogikalErrorResponse()
  67. {
  68. Status = LogikalStatus.CannotConnect,
  69. Message = $"Unable to connect to LogiKal at [{request.Path}]: {_status}"
  70. };
  71. }
  72. _proxy = _p;
  73. return new LogikalConnectResponse();
  74. }
  75. public LogikalResponse Disconnect()
  76. {
  77. if (_login != null)
  78. Logout();
  79. if (_proxy != null)
  80. {
  81. _proxy.ServiceProxyUi.Stop();
  82. _proxy.Dispose();
  83. }
  84. _proxy = null;
  85. return new LogikalDisconnectResponse();
  86. }
  87. private void DoOnDisconnecting()
  88. {
  89. }
  90. public LogikalResponse Login(LogikalLoginRequest request)
  91. {
  92. Dictionary<string, object> _parameters = new Dictionary<string, object>()
  93. {
  94. { WellKnownParameterKey.Login.ProgramMode, "erp" },
  95. { WellKnownParameterKey.Login.ApplicationHandle, WindowHandle },
  96. //{ WellKnownParameterKey.Login.UserName, username },
  97. //{ WellKnownParameterKey.Login.Password, password },
  98. { WellKnownParameterKey.Login.EnableEventSynchronization, true },
  99. };
  100. if (_proxy == null)
  101. return NOTCONNECTED;
  102. if (_login != null)
  103. return new LogikalLoginResponse();
  104. var _check = _proxy.ServiceProxyUi.CanLogin(_parameters);
  105. if (!_check.CanExecute)
  106. {
  107. return new LogikalErrorResponse()
  108. {
  109. Status = LogikalStatus.Restricted,
  110. Message = $"Login not allowed: {_check}!"
  111. };
  112. }
  113. try
  114. {
  115. var _l = _proxy.ServiceProxyUi.Login(_parameters);
  116. if (_l.OperationCode != OperationCode.Accepted)
  117. {
  118. _login = null;
  119. return new LogikalErrorResponse()
  120. {
  121. Status = LogikalStatus.Failed,
  122. Message = $"Login failed: {_l}"
  123. };
  124. }
  125. else
  126. {
  127. _login = _l;
  128. return new LogikalLoginResponse();
  129. }
  130. }
  131. catch (Exception e)
  132. {
  133. return new LogikalErrorResponse()
  134. {
  135. Status = LogikalStatus.Error,
  136. Message = $"{e.Message}\n{e.StackTrace}"
  137. };
  138. }
  139. }
  140. public LogikalResponse Logout()
  141. {
  142. if (_login != null)
  143. _login.Dispose();
  144. _login = null;
  145. return new LogikalLogoutResponse();
  146. }
  147. public bool IsLoggedIn() => _login != null;
  148. private void GetProjectCentres(ICoreObjectResult<IProjectCenterUi> center, List<LogikalProjectCentre> results)
  149. {
  150. var _projectresults = new List<LogikalProject>();
  151. IList<IBaseProjectInfo> _projects = center.CoreObject.ChildrenInfos;
  152. foreach (var _project in _projects)
  153. {
  154. var _summary = new LogikalProject();
  155. PopulateProject(_project, _summary);
  156. _projectresults.Add(_summary);
  157. }
  158. var _result = new LogikalProjectCentre()
  159. {
  160. ID = center.CoreObject.ProjectCenterContainer.Id,
  161. Name = center.CoreObject.Parent != null ? center.CoreObject.Info.DirectoryName : "Project Center",
  162. ParentID = center.CoreObject.Parent != null
  163. ? center.CoreObject.Parent.ProjectCenterContainer.Id
  164. : Guid.Empty,
  165. Projects = _projectresults.ToArray()
  166. };
  167. results.Add(_result);
  168. var _children = center.CoreObject.ProjectCenterContainer.GetChildren().CoreObjectResults;
  169. foreach (var _child in _children)
  170. GetProjectCentres(_child, results);
  171. }
  172. private void PopulateProject(IBaseProjectInfo source, ILogikalProject target)
  173. {
  174. target.ID = source.Guid;
  175. target.Title = source.Name;
  176. target.PersonInCharge = source.PersonInCharge;
  177. target.Path = source.Path;
  178. target.LastUpdated = source.LastChangedDateTime;
  179. target.Created = source.CreatedDateTime;
  180. target.JobNumber = source.AsProjectInfo().JobNumber;
  181. target.OfferNumber = source.AsProjectInfo().OfferNumber;
  182. }
  183. private List<LogikalProjectCentre> GetProjectCentres()
  184. {
  185. var _results = new List<LogikalProjectCentre>();
  186. var _info = _login.CoreObject.ProjectCenterInfos.FirstOrDefault(x => x.Type.Id == 0);
  187. if (_info != null)
  188. {
  189. var _center = _login.CoreObject.GetProjectCenter(_info);
  190. GetProjectCentres(_center, _results);
  191. }
  192. return _results;
  193. }
  194. public LogikalResponse GetProjectCentres(LogikalProjectCentresRequest request)
  195. {
  196. if (_proxy == null)
  197. return NOTCONNECTED;
  198. if (_login == null)
  199. return NOTLOGGEDIN;
  200. var _results = GetProjectCentres();
  201. return new LogikalProjectCentresResponse<LogikalProjectCentre,LogikalProject>() { ProjectCentres = _results.ToArray() };
  202. }
  203. public LogikalResponse GetProjects(LogikalProjectsRequest request)
  204. {
  205. if (_proxy == null)
  206. return NOTCONNECTED;
  207. if (_login == null)
  208. return NOTLOGGEDIN;
  209. List<LogikalProject> _results = new List<LogikalProject>();
  210. var _centres = GetProjectCentres();
  211. foreach (var _centre in _centres)
  212. {
  213. var _projects = _centre.Projects.Where(x => string.IsNullOrWhiteSpace(request.JobNumber) || string.Equals(x.JobNumber, request.JobNumber));
  214. _results.AddRange(_projects);
  215. }
  216. return new LogikalProjectsResponse<LogikalProject>() { Projects = _results.ToArray() };
  217. }
  218. public LogikalResponse GetProject(LogikalProjectRequest request)
  219. {
  220. if (_proxy == null)
  221. return NOTCONNECTED;
  222. if (_login == null)
  223. return NOTLOGGEDIN;
  224. var _project = _login.CoreObject.GetProjectByGuid(request.ProjectID);
  225. if (_project == null)
  226. return new LogikalErrorResponse()
  227. {
  228. Status = LogikalStatus.InvalidProjectID,
  229. Message = $"Cannot Load Project {request.ProjectID}"
  230. };
  231. var response = new LogikalProjectResponse<LogikalProject>();
  232. PopulateProject(_project.CoreObject.Info, response.Project);
  233. return response;
  234. }
  235. public LogikalResponse GetPhases(LogikalPhasesRequest request)
  236. {
  237. if (_proxy == null)
  238. return NOTCONNECTED;
  239. if (_login == null)
  240. return NOTLOGGEDIN;
  241. var _project = _login.CoreObject.GetProjectByGuid(request.ProjectID);
  242. if (_project == null)
  243. return new LogikalErrorResponse()
  244. {
  245. Status = LogikalStatus.InvalidProjectID,
  246. Message = $"Cannot Load Project {request.ProjectID}"
  247. };
  248. List<LogikalPhase> _results = new List<LogikalPhase>();
  249. var _phases = _project.CoreObject.GetChildren().CoreObjectResults;
  250. foreach (ICoreObjectResult<IPhase> _phase in _phases)
  251. {
  252. var _result = new LogikalPhase()
  253. {
  254. ID = _phase.CoreObject.Info.Name,
  255. Title = string.IsNullOrWhiteSpace(_phase.CoreObject.Info.Name) ? "Default Phase" : _phase.CoreObject.Info.Name
  256. };
  257. _results.Add(_result);
  258. }
  259. return new LogikalPhasesResponse<LogikalPhase>() { Phases = _results.ToArray() };
  260. }
  261. public LogikalResponse GetElevationSummaries(LogikalElevationSummaryRequest request)
  262. {
  263. if (_proxy == null)
  264. return NOTCONNECTED;
  265. if (_login == null)
  266. return NOTLOGGEDIN;
  267. var _results = new List<LogikalElevationSummary>();
  268. var _project = _login.CoreObject.GetProjectByGuid(request.ProjectID);
  269. if (_project == null)
  270. return new LogikalErrorResponse()
  271. {
  272. Status = LogikalStatus.InvalidProjectID,
  273. Message = $"Cannot Load Project {request.ProjectID}"
  274. };
  275. var _phases = _project.CoreObject.GetChildren().CoreObjectResults;
  276. var _phase = _phases.FirstOrDefault(x => x.CoreObject.Info.Name == request.Phase);
  277. if (_phase == null)
  278. return new LogikalErrorResponse()
  279. {
  280. Status = LogikalStatus.InvalidPhaseID,
  281. Message = $"Cannot find phase [{request.Phase}] within project [{request.ProjectID}]"
  282. };
  283. var _elevations = _phase.CoreObject.GetChildren().CoreObjectResults;
  284. foreach (var _elevation in _elevations)
  285. {
  286. if (!_elevation.CoreObject.Info.IsInRecycleBin)
  287. {
  288. var _result = new LogikalElevationSummary();
  289. PopulateElevation(_elevation.CoreObject, _result);
  290. _results.Add(_result);
  291. }
  292. }
  293. return new LogikalElevationSummaryResponse<LogikalElevationSummary>() { Elevations = _results.ToArray() };
  294. }
  295. private void PopulateElevation(IElevation source, ILogikalElevationSummary target)
  296. {
  297. target.ID = source.Info.Guid;
  298. target.Name = source.Info.Name;
  299. target.Description = source.Info.SystemDescription;
  300. target.Size = source.Info.Size;
  301. using (var ms = new MemoryStream())
  302. {
  303. IStreamResult thumbnail =
  304. source.GetThumbnail(new Dictionary<string, object>() { });
  305. thumbnail.Stream.CopyTo(ms);
  306. target.Thumbnail = ms.GetBuffer();
  307. }
  308. }
  309. public LogikalResponse GetBillOfMaterials(LogikalBOMRequest request)
  310. {
  311. if (_proxy == null)
  312. return NOTCONNECTED;
  313. if (_login == null)
  314. return NOTLOGGEDIN;
  315. var _project = _login.CoreObject.GetProjectByGuid(request.ProjectID);
  316. if (_project == null)
  317. return new LogikalErrorResponse()
  318. {
  319. Status = LogikalStatus.InvalidProjectID,
  320. Message = $"Cannot Load Project [{request.ProjectID}]"
  321. };
  322. var _elevations = new List<IElevationInfo>();
  323. if (request.ElevationIDs?.Any() == true)
  324. {
  325. var _phases = _project.CoreObject.GetChildren();
  326. foreach (var _phase in _phases.CoreObjectResults)
  327. _elevations.AddRange(_phase.CoreObject.ChildrenInfos.Where(x => request.ElevationIDs.Contains(x.Guid)));
  328. }
  329. using (IReportItemsResult reportItemsResult = _project.CoreObject.GetReports())
  330. {
  331. if (reportItemsResult.OperationCode != OperationCode.Accepted)
  332. {
  333. return new LogikalErrorResponse()
  334. {
  335. Status = LogikalStatus.Error,
  336. Message = $"Cannot Get Reports for Project!"
  337. };
  338. }
  339. // Filter available reports for the erp export report item
  340. IReportItem reportItem = reportItemsResult.ReportItems.First(rep =>
  341. (rep.Id == WellKnownReports.Delivery.ErpExport) &&
  342. (rep.Category.Id == WellKnownReports.Delivery.CategoryId));
  343. // Create parameters for erp export, export format is required, but always sqlite
  344. var exportParameters = new Dictionary<string, object>
  345. {
  346. { WellKnownParameterKey.Project.Report.ExportFormat, "SQLite" },
  347. };
  348. // Check if report can be exported for the given parameters
  349. var operationInfo = _project.CoreObject.CanGetReport(reportItem, _elevations, exportParameters);
  350. if (!operationInfo.CanExecute)
  351. {
  352. return new LogikalErrorResponse()
  353. {
  354. Status = LogikalStatus.Error,
  355. Message = $"Cannot Get Erp Report for Project!"
  356. };
  357. }
  358. // Run report creation asynchronously - begin method starts the operation in background task
  359. using (ISynchronizedOperationResult synchronizedOperationResult =
  360. _project.CoreObject.BeginGetReport(reportItem, _elevations, exportParameters))
  361. {
  362. var response = new LogikalBOMResponse<LogikalBOM, LogikalFinish, LogikalProfile, LogikalGasket, LogikalComponent, LogikalGlass, LogikalLabour>();
  363. // End method waits for the background operation to complete in separate task
  364. using (IStreamResult streamResult = Task.Run<IStreamResult>(() =>
  365. _project.CoreObject.EndGetReport(synchronizedOperationResult.SynchronizedOperation)).Result)
  366. {
  367. PopulateParts(request, response.BOM, streamResult);
  368. }
  369. return response;
  370. }
  371. }
  372. }
  373. public LogikalResponse GetElevationDetails(LogikalElevationDetailRequest detailRequest)
  374. {
  375. var _project = _login.CoreObject.GetProjectByGuid(detailRequest.ProjectID);
  376. if (_project == null)
  377. return new LogikalErrorResponse()
  378. {
  379. Status = LogikalStatus.InvalidProjectID,
  380. Message = $"Cannot Load Project [{detailRequest.ProjectID}]"
  381. };
  382. Dictionary<Guid, ICoreObjectResult<IElevationUi>> elevations = new Dictionary<Guid, ICoreObjectResult<IElevationUi>>();
  383. var _phases = _project.CoreObject.GetChildren().CoreObjectResults;
  384. foreach (var id in detailRequest.IDs)
  385. {
  386. foreach (var _phase in _phases)
  387. {
  388. var ui = _phase.CoreObject.GetChildren().CoreObjectResults
  389. .FirstOrDefault(e => e.CoreObject.Info.Guid == id);
  390. if (ui != null)
  391. elevations[id] = ui;
  392. }
  393. if (!elevations.ContainsKey(id))
  394. {
  395. return new LogikalErrorResponse()
  396. {
  397. Status = LogikalStatus.ElevationNotFound,
  398. Message = $"Cannot find Elevation [{id}] within project [{detailRequest.ProjectID}]"
  399. };
  400. }
  401. }
  402. try
  403. {
  404. List<LogikalElevationDetail> results = new List<LogikalElevationDetail>();
  405. var response = new LogikalElevationDetailResponse<LogikalElevationDetail, LogikalFinish, LogikalProfile, LogikalGasket, LogikalComponent, LogikalGlass, LogikalLabour>();
  406. foreach (var id in elevations.Keys)
  407. {
  408. var _elevation = elevations[id];
  409. LogikalElevationDetail newel = new LogikalElevationDetail();
  410. PopulateElevation(_elevation.CoreObject, newel);
  411. var dxf = ElevationDetails(detailRequest, _elevation, id, newel, detailRequest.DrawingFormat, detailRequest.DrawingView, detailRequest.DrawingType);
  412. if (dxf != null)
  413. return dxf;
  414. results.Add(newel);
  415. }
  416. response.Elevations = results;
  417. return response;
  418. }
  419. catch (Exception e)
  420. {
  421. return new LogikalErrorResponse() { Status = LogikalStatus.Error, Message = $"{e.Message}\n\n{e.StackTrace}" };
  422. }
  423. }
  424. private LogikalResponse ElevationDetails(LogikalElevationDetailRequest detailRequest, ICoreObjectResult<IElevationUi> _elevation, Guid id,
  425. LogikalElevationDetail newel, LogikalDrawingFormat format, LogikalDrawingView view, LogikalDrawingType type)
  426. {
  427. // Setup parameters for export of the elevation drawing
  428. var sectionDrawingParameters = new Dictionary<string, object>
  429. {
  430. { WellKnownParameterKey.Elevation.Drawing.Format, format == LogikalDrawingFormat.DXF ? ElevationDrawingFormat.DXF : ElevationDrawingFormat.PNG },
  431. { WellKnownParameterKey.Elevation.Drawing.View, view == LogikalDrawingView.Exterior ? View.Exterior : View.Interior },
  432. { WellKnownParameterKey.Elevation.Drawing.Type, type == LogikalDrawingType.Explosion
  433. ? ElevationDrawingType.Explosion
  434. : type == LogikalDrawingType.Section
  435. ? ElevationDrawingType.Section
  436. : type == LogikalDrawingType.Elevation
  437. ? ElevationDrawingType.Elevation
  438. : type == LogikalDrawingType.ElevationWithSectionLines
  439. ? ElevationDrawingType.ElevationWithSectionLines
  440. : ElevationDrawingType.SectionLine
  441. },
  442. { WellKnownParameterKey.Elevation.Drawing.DxfVersion, DxfVersion.Acad2010 },
  443. { WellKnownParameterKey.Elevation.Drawing.ShowDescription, true },
  444. { WellKnownParameterKey.Elevation.Drawing.ShowDimensions, true },
  445. { WellKnownParameterKey.Elevation.Drawing.Scale, 1.0 },
  446. };
  447. // Check if the drawing can be exported for the elevation with the given parameters
  448. if (!_elevation.CoreObject.CanGetDrawing(sectionDrawingParameters).CanExecute)
  449. {
  450. return new LogikalErrorResponse()
  451. {
  452. Status = LogikalStatus.Error,
  453. Message = $"GetDrawing() not permitted for Elevation [{id}]"
  454. };
  455. }
  456. // Generate drawing for the elevation with the given parameters
  457. using (IDrawingResult drawingResult = _elevation.CoreObject.GetDrawing(sectionDrawingParameters))
  458. {
  459. Stream exportStream = drawingResult.Stream;
  460. using (var _ms = new MemoryStream())
  461. {
  462. exportStream.CopyTo(_ms);
  463. newel.Drawing = _ms.GetBuffer();
  464. }
  465. }
  466. using (IStreamResult streamResult = _elevation.CoreObject.GetPartsList())
  467. {
  468. try
  469. {
  470. PopulateParts(detailRequest, newel, streamResult);
  471. //return response;
  472. }
  473. catch (Exception e)
  474. {
  475. return new LogikalErrorResponse()
  476. { Status = LogikalStatus.Error, Message = $"{e.Message}\n{e.StackTrace}" };
  477. }
  478. }
  479. return null;
  480. }
  481. private T CheckValue<T>(object value)
  482. {
  483. if (value == null || value is DBNull || value.GetType() != typeof(T))
  484. return default(T);
  485. return (T)value;
  486. }
  487. private void PopulateParts<TRequest, TBOM>(TRequest request, TBOM bom, IStreamResult stream)
  488. where TRequest : AbstractLogikalPartsRequest
  489. where TBOM : ILogikalBOM<LogikalFinish, LogikalProfile, LogikalGasket, LogikalComponent,LogikalGlass,LogikalLabour>
  490. {
  491. var _excelData = new byte[] { };
  492. var sqLiteData = new byte[] { };
  493. var _finishes = new List<LogikalFinish>();
  494. var _profiles = new List<LogikalProfile>();
  495. var _gaskets = new List<LogikalGasket>();
  496. var _components = new List<LogikalComponent>();
  497. var _glass = new List<LogikalGlass>();
  498. var _labour = new List<LogikalLabour>();
  499. var file = Path.ChangeExtension(Path.Combine(Path.GetTempPath(), Path.GetTempFileName()), "sqlite3");
  500. using (var fs = new FileStream(file, FileMode.OpenOrCreate))
  501. stream.Stream.CopyTo(fs);
  502. if (request.IncludeSqliteData)
  503. sqLiteData = File.ReadAllBytes(file);
  504. var sb = new SQLiteConnectionStringBuilder();
  505. sb.DataSource = file;
  506. using (var _connection = new SQLiteConnection(sb.ToString()))
  507. {
  508. _connection.Open();
  509. // Get Finishes
  510. using (var _data = new SQLiteCommand(_connection))
  511. {
  512. _data.CommandText = request.FinishQuery.Replace('\n', ' ');
  513. try
  514. {
  515. using (var _reader = _data.ExecuteReader())
  516. {
  517. DataTable _dt = new DataTable();
  518. _dt.Load(_reader);
  519. foreach (DataRow row in _dt.Rows)
  520. {
  521. var _finish = new LogikalFinish();
  522. _finish.Code = CheckValue<string>(row[nameof(LogikalFinish.Code)]);
  523. _finish.Description = CheckValue<string>(row[nameof(LogikalFinish.Description)]);
  524. _finishes.Add(_finish);
  525. }
  526. }
  527. }
  528. catch (Exception e)
  529. {
  530. throw new Exception($"Error: {e.Message}\nQuery: {_data.CommandText}\nTrace: {e.StackTrace}");
  531. }
  532. }
  533. // Get Profiles
  534. using (var _data = new SQLiteCommand(_connection))
  535. {
  536. _data.CommandText = request.ProfileQuery.Replace('\n', ' ');
  537. try
  538. {
  539. using (var _reader = _data.ExecuteReader())
  540. {
  541. DataTable _dt = new DataTable();
  542. _dt.Load(_reader);
  543. foreach (DataRow row in _dt.Rows)
  544. {
  545. var _profile = new LogikalProfile();
  546. _profile.Code = CheckValue<string>(row[nameof(LogikalProfile.Code)]);
  547. _profile.Description = CheckValue<string>(row[nameof(LogikalProfile.Description)]);
  548. _profile.Quantity = CheckValue<Int64>(row[nameof(LogikalProfile.Quantity)]);
  549. _profile.Cost = CheckValue<double>(row[nameof(LogikalProfile.Cost)]);
  550. _profile.Finish = CheckValue<string>(row[nameof(LogikalProfile.Finish)]);
  551. _profile.Length = CheckValue<double>(row[nameof(LogikalProfile.Length)]);
  552. _profiles.Add(_profile);
  553. }
  554. }
  555. }
  556. catch (Exception e)
  557. {
  558. throw new Exception($"Error: {e.Message}\nQuery: {_data.CommandText}\nTrace: {e.StackTrace}");
  559. }
  560. }
  561. // Get Gaskets
  562. using (var _data = new SQLiteCommand(_connection))
  563. {
  564. _data.CommandText = request.GasketQuery.Replace('\n', ' ');
  565. try
  566. {
  567. using (var _reader = _data.ExecuteReader())
  568. {
  569. DataTable _dt = new DataTable();
  570. _dt.Load(_reader);
  571. foreach (DataRow row in _dt.Rows)
  572. {
  573. var _gasket = new LogikalGasket();
  574. _gasket.Code = CheckValue<string>(row[nameof(LogikalGasket.Code)]);
  575. _gasket.Description = CheckValue<string>(row[nameof(LogikalGasket.Description)]);
  576. _gasket.Quantity = CheckValue<Int64>(row[nameof(LogikalGasket.Quantity)]);
  577. _gasket.Cost = CheckValue<double>(row[nameof(LogikalGasket.Cost)]);
  578. _gasket.Length = CheckValue<double>(row[nameof(LogikalGasket.Length)]);
  579. _gaskets.Add(_gasket);
  580. }
  581. }
  582. }
  583. catch (Exception e)
  584. {
  585. throw new Exception($"Error: {e.Message}\nQuery: {_data.CommandText}\nTrace: {e.StackTrace}");
  586. }
  587. }
  588. // Get Components
  589. using (var _data = new SQLiteCommand(_connection))
  590. {
  591. _data.CommandText = request.ComponentQuery.Replace('\n', ' ');
  592. try
  593. {
  594. using (var _reader = _data.ExecuteReader())
  595. {
  596. DataTable _dt = new DataTable();
  597. _dt.Load(_reader);
  598. foreach (DataRow row in _dt.Rows)
  599. {
  600. var _component = new LogikalComponent();
  601. _component.Code = CheckValue<string>(row[nameof(LogikalComponent.Code)]);
  602. _component.Description = CheckValue<string>(row[nameof(LogikalComponent.Description)]);
  603. _component.Quantity = CheckValue<double>(row[nameof(LogikalComponent.Quantity)]);
  604. _component.Cost = CheckValue<double>(row[nameof(LogikalComponent.Cost)]);
  605. _component.PackSize = CheckValue<double>(row[nameof(LogikalComponent.PackSize)]);
  606. _components.Add(_component);
  607. }
  608. }
  609. }
  610. catch (Exception e)
  611. {
  612. throw new Exception($"Error: {e.Message}\nQuery: {_data.CommandText}\nTrace: {e.StackTrace}");
  613. }
  614. }
  615. // Get Glass
  616. using (var _data = new SQLiteCommand(_connection))
  617. {
  618. _data.CommandText = request.GlassQuery.Replace('\n', ' ');
  619. try
  620. {
  621. using (var _reader = _data.ExecuteReader())
  622. {
  623. DataTable _dt = new DataTable();
  624. _dt.Load(_reader);
  625. foreach (DataRow row in _dt.Rows)
  626. {
  627. var _glassitem = new LogikalGlass();
  628. _glassitem.Code = CheckValue<string>(row[nameof(LogikalGlass.Code)]);
  629. _glassitem.Description = CheckValue<string>(row[nameof(LogikalGlass.Description)]);
  630. _glassitem.Quantity = CheckValue<Int64>(row[nameof(LogikalGlass.Quantity)]);
  631. _glassitem.Cost = CheckValue<double>(row[nameof(LogikalGlass.Cost)]);
  632. _glassitem.Height = CheckValue<double>(row[nameof(LogikalGlass.Height)]);
  633. _glassitem.Width = CheckValue<double>(row[nameof(LogikalGlass.Width)]);
  634. _glassitem.Treatment = CheckValue<string>(row[nameof(LogikalGlass.Treatment)]);
  635. _glassitem.Location = CheckValue<string>(row[nameof(LogikalGlass.Location)]);
  636. _glass.Add(_glassitem);
  637. }
  638. }
  639. }
  640. catch (Exception e)
  641. {
  642. throw new Exception($"Error: {e.Message}\nQuery: {_data.CommandText}\nTrace: {e.StackTrace}");
  643. }
  644. }
  645. // Get Labour
  646. using (var _data = new SQLiteCommand(_connection))
  647. {
  648. _data.CommandText = request.LabourQuery.Replace('\n', ' ');
  649. try
  650. {
  651. using (var _reader = _data.ExecuteReader())
  652. {
  653. DataTable _dt = new DataTable();
  654. _dt.Load(_reader);
  655. foreach (DataRow row in _dt.Rows)
  656. {
  657. var _labouritem = new LogikalLabour();
  658. _labouritem.Code = CheckValue<string>(row[nameof(LogikalLabour.Code)]);
  659. _labouritem.Description = CheckValue<string>(row[nameof(LogikalLabour.Description)]);
  660. _labouritem.Quantity = CheckValue<double>(row[nameof(LogikalLabour.Quantity)]);
  661. _labouritem.Cost = CheckValue<double>(row[nameof(LogikalLabour.Cost)]);
  662. _labour.Add(_labouritem);
  663. }
  664. }
  665. }
  666. catch (Exception e)
  667. {
  668. throw new Exception($"Error: {e.Message}\nQuery: {_data.CommandText}\nTrace: {e.StackTrace}");
  669. }
  670. }
  671. if (request.IncludeExcelData)
  672. {
  673. List<string> _tables = new List<string>();
  674. using (var _master = new SQLiteCommand(_connection))
  675. {
  676. _master.CommandText = "select * from sqlite_master where type='table'";
  677. using (var _reader = _master.ExecuteReader())
  678. {
  679. if (_reader.HasRows)
  680. {
  681. while (_reader.Read())
  682. _tables.Add(_reader.GetString(1));
  683. }
  684. }
  685. }
  686. DataSet _ds = new DataSet();
  687. foreach (var _table in _tables)
  688. {
  689. using (var _data = new SQLiteCommand(_connection))
  690. {
  691. _data.CommandText = $"select * from {_table}";
  692. using (var _reader = _data.ExecuteReader())
  693. {
  694. DataTable _dt = new DataTable(_table);
  695. _ds.Tables.Add(_dt);
  696. _dt.Load(_reader);
  697. }
  698. }
  699. }
  700. var excelApp = OfficeOpenXML.GetInstance();
  701. using (var _buffer = excelApp.GetExcelStream(_ds, false))
  702. _excelData = _buffer.GetBuffer();
  703. _connection.Close();
  704. File.Delete(file);
  705. }
  706. bom.Finishes = _finishes.ToArray();
  707. bom.Profiles = _profiles.ToArray();
  708. bom.Gaskets = _gaskets.ToArray();
  709. bom.Components = _components.ToArray();
  710. bom.Glass = _glass.ToArray();
  711. bom.Labour = _labour.ToArray();
  712. bom.ExcelData = _excelData;
  713. bom.SQLiteData = sqLiteData;
  714. }
  715. }
  716. public void Dispose()
  717. {
  718. Disconnect();
  719. }
  720. }
  721. }