LogikalServer.cs 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824
  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. // Setup parameters for export of the elevation drawing
  412. var sectionDrawingParameters = new Dictionary<string, object>
  413. {
  414. { WellKnownParameterKey.Elevation.Drawing.Format, ElevationDrawingFormat.DXF },
  415. { WellKnownParameterKey.Elevation.Drawing.View, View.Interior },
  416. {
  417. WellKnownParameterKey.Elevation.Drawing.Type, ElevationDrawingType.Elevation
  418. },
  419. { WellKnownParameterKey.Elevation.Drawing.DxfVersion, DxfVersion.Acad2010 },
  420. { WellKnownParameterKey.Elevation.Drawing.ShowDescription, true },
  421. { WellKnownParameterKey.Elevation.Drawing.ShowDimensions, true },
  422. { WellKnownParameterKey.Elevation.Drawing.Scale, 1.0 },
  423. };
  424. // Check if the drawing can be exported for the elevation with the given parameters
  425. if (!_elevation.CoreObject.CanGetDrawing(sectionDrawingParameters).CanExecute)
  426. {
  427. return new LogikalErrorResponse()
  428. {
  429. Status = LogikalStatus.Error,
  430. Message = $"GetDrawing() not permitted for Elevation [{id}]"
  431. };
  432. }
  433. // Generate drawing for the elevation with the given parameters
  434. using (IDrawingResult drawingResult = _elevation.CoreObject.GetDrawing(sectionDrawingParameters))
  435. {
  436. Stream exportStream = drawingResult.Stream;
  437. using (var _ms = new MemoryStream())
  438. {
  439. exportStream.CopyTo(_ms);
  440. newel.Drawing = _ms.GetBuffer();
  441. }
  442. }
  443. using (IStreamResult streamResult = _elevation.CoreObject.GetPartsList())
  444. {
  445. try
  446. {
  447. PopulateParts(detailRequest, newel, streamResult);
  448. //return response;
  449. }
  450. catch (Exception e)
  451. {
  452. return new LogikalErrorResponse()
  453. { Status = LogikalStatus.Error, Message = $"{e.Message}\n{e.StackTrace}" };
  454. }
  455. }
  456. results.Add(newel);
  457. }
  458. response.Elevations = results;
  459. return response;
  460. }
  461. catch (Exception e)
  462. {
  463. return new LogikalErrorResponse() { Status = LogikalStatus.Error, Message = $"{e.Message}\n\n{e.StackTrace}" };
  464. }
  465. }
  466. private T CheckValue<T>(object value)
  467. {
  468. if (value == null || value is DBNull || value.GetType() != typeof(T))
  469. return default(T);
  470. return (T)value;
  471. }
  472. private void PopulateParts<TRequest, TBOM>(TRequest request, TBOM bom, IStreamResult stream)
  473. where TRequest : AbstractLogikalPartsRequest
  474. where TBOM : ILogikalBOM<LogikalFinish, LogikalProfile, LogikalGasket, LogikalComponent,LogikalGlass,LogikalLabour>
  475. {
  476. var _excelData = new byte[] { };
  477. var sqLiteData = new byte[] { };
  478. var _finishes = new List<LogikalFinish>();
  479. var _profiles = new List<LogikalProfile>();
  480. var _gaskets = new List<LogikalGasket>();
  481. var _components = new List<LogikalComponent>();
  482. var _glass = new List<LogikalGlass>();
  483. var _labour = new List<LogikalLabour>();
  484. var file = Path.ChangeExtension(Path.Combine(Path.GetTempPath(), Path.GetTempFileName()), "sqlite3");
  485. using (var fs = new FileStream(file, FileMode.OpenOrCreate))
  486. stream.Stream.CopyTo(fs);
  487. if (request.IncludeSqliteData)
  488. sqLiteData = File.ReadAllBytes(file);
  489. var sb = new SQLiteConnectionStringBuilder();
  490. sb.DataSource = file;
  491. using (var _connection = new SQLiteConnection(sb.ToString()))
  492. {
  493. _connection.Open();
  494. // Get Finishes
  495. using (var _data = new SQLiteCommand(_connection))
  496. {
  497. _data.CommandText = request.FinishQuery.Replace('\n', ' ');
  498. try
  499. {
  500. using (var _reader = _data.ExecuteReader())
  501. {
  502. DataTable _dt = new DataTable();
  503. _dt.Load(_reader);
  504. foreach (DataRow row in _dt.Rows)
  505. {
  506. var _finish = new LogikalFinish();
  507. _finish.Code = CheckValue<string>(row[nameof(LogikalFinish.Code)]);
  508. _finish.Description = CheckValue<string>(row[nameof(LogikalFinish.Description)]);
  509. _finishes.Add(_finish);
  510. }
  511. }
  512. }
  513. catch (Exception e)
  514. {
  515. throw new Exception($"Error: {e.Message}\nQuery: {_data.CommandText}\nTrace: {e.StackTrace}");
  516. }
  517. }
  518. // Get Profiles
  519. using (var _data = new SQLiteCommand(_connection))
  520. {
  521. _data.CommandText = request.ProfileQuery.Replace('\n', ' ');
  522. try
  523. {
  524. using (var _reader = _data.ExecuteReader())
  525. {
  526. DataTable _dt = new DataTable();
  527. _dt.Load(_reader);
  528. foreach (DataRow row in _dt.Rows)
  529. {
  530. var _profile = new LogikalProfile();
  531. _profile.Code = CheckValue<string>(row[nameof(LogikalProfile.Code)]);
  532. _profile.Description = CheckValue<string>(row[nameof(LogikalProfile.Description)]);
  533. _profile.Quantity = CheckValue<Int64>(row[nameof(LogikalProfile.Quantity)]);
  534. _profile.Cost = CheckValue<double>(row[nameof(LogikalProfile.Cost)]);
  535. _profile.Finish = CheckValue<string>(row[nameof(LogikalProfile.Finish)]);
  536. _profile.Length = CheckValue<double>(row[nameof(LogikalProfile.Length)]);
  537. _profiles.Add(_profile);
  538. }
  539. }
  540. }
  541. catch (Exception e)
  542. {
  543. throw new Exception($"Error: {e.Message}\nQuery: {_data.CommandText}\nTrace: {e.StackTrace}");
  544. }
  545. }
  546. // Get Gaskets
  547. using (var _data = new SQLiteCommand(_connection))
  548. {
  549. _data.CommandText = request.GasketQuery.Replace('\n', ' ');
  550. try
  551. {
  552. using (var _reader = _data.ExecuteReader())
  553. {
  554. DataTable _dt = new DataTable();
  555. _dt.Load(_reader);
  556. foreach (DataRow row in _dt.Rows)
  557. {
  558. var _gasket = new LogikalGasket();
  559. _gasket.Code = CheckValue<string>(row[nameof(LogikalGasket.Code)]);
  560. _gasket.Description = CheckValue<string>(row[nameof(LogikalGasket.Description)]);
  561. _gasket.Quantity = CheckValue<Int64>(row[nameof(LogikalGasket.Quantity)]);
  562. _gasket.Cost = CheckValue<double>(row[nameof(LogikalGasket.Cost)]);
  563. _gasket.Length = CheckValue<double>(row[nameof(LogikalGasket.Length)]);
  564. _gaskets.Add(_gasket);
  565. }
  566. }
  567. }
  568. catch (Exception e)
  569. {
  570. throw new Exception($"Error: {e.Message}\nQuery: {_data.CommandText}\nTrace: {e.StackTrace}");
  571. }
  572. }
  573. // Get Components
  574. using (var _data = new SQLiteCommand(_connection))
  575. {
  576. _data.CommandText = request.ComponentQuery.Replace('\n', ' ');
  577. try
  578. {
  579. using (var _reader = _data.ExecuteReader())
  580. {
  581. DataTable _dt = new DataTable();
  582. _dt.Load(_reader);
  583. foreach (DataRow row in _dt.Rows)
  584. {
  585. var _component = new LogikalComponent();
  586. _component.Code = CheckValue<string>(row[nameof(LogikalComponent.Code)]);
  587. _component.Description = CheckValue<string>(row[nameof(LogikalComponent.Description)]);
  588. _component.Quantity = CheckValue<double>(row[nameof(LogikalComponent.Quantity)]);
  589. _component.Cost = CheckValue<double>(row[nameof(LogikalComponent.Cost)]);
  590. _component.PackSize = CheckValue<double>(row[nameof(LogikalComponent.PackSize)]);
  591. _components.Add(_component);
  592. }
  593. }
  594. }
  595. catch (Exception e)
  596. {
  597. throw new Exception($"Error: {e.Message}\nQuery: {_data.CommandText}\nTrace: {e.StackTrace}");
  598. }
  599. }
  600. // Get Glass
  601. using (var _data = new SQLiteCommand(_connection))
  602. {
  603. _data.CommandText = request.GlassQuery.Replace('\n', ' ');
  604. try
  605. {
  606. using (var _reader = _data.ExecuteReader())
  607. {
  608. DataTable _dt = new DataTable();
  609. _dt.Load(_reader);
  610. foreach (DataRow row in _dt.Rows)
  611. {
  612. var _glassitem = new LogikalGlass();
  613. _glassitem.Code = CheckValue<string>(row[nameof(LogikalGlass.Code)]);
  614. _glassitem.Description = CheckValue<string>(row[nameof(LogikalGlass.Description)]);
  615. _glassitem.Quantity = CheckValue<Int64>(row[nameof(LogikalGlass.Quantity)]);
  616. _glassitem.Cost = CheckValue<double>(row[nameof(LogikalGlass.Cost)]);
  617. _glassitem.Height = CheckValue<double>(row[nameof(LogikalGlass.Height)]);
  618. _glassitem.Width = CheckValue<double>(row[nameof(LogikalGlass.Width)]);
  619. _glassitem.Treatment = CheckValue<string>(row[nameof(LogikalGlass.Treatment)]);
  620. _glassitem.Location = CheckValue<string>(row[nameof(LogikalGlass.Location)]);
  621. _glass.Add(_glassitem);
  622. }
  623. }
  624. }
  625. catch (Exception e)
  626. {
  627. throw new Exception($"Error: {e.Message}\nQuery: {_data.CommandText}\nTrace: {e.StackTrace}");
  628. }
  629. }
  630. // Get Labour
  631. using (var _data = new SQLiteCommand(_connection))
  632. {
  633. _data.CommandText = request.LabourQuery.Replace('\n', ' ');
  634. try
  635. {
  636. using (var _reader = _data.ExecuteReader())
  637. {
  638. DataTable _dt = new DataTable();
  639. _dt.Load(_reader);
  640. foreach (DataRow row in _dt.Rows)
  641. {
  642. var _labouritem = new LogikalLabour();
  643. _labouritem.Code = CheckValue<string>(row[nameof(LogikalLabour.Code)]);
  644. _labouritem.Description = CheckValue<string>(row[nameof(LogikalLabour.Description)]);
  645. _labouritem.Quantity = CheckValue<double>(row[nameof(LogikalLabour.Quantity)]);
  646. _labouritem.Cost = CheckValue<double>(row[nameof(LogikalLabour.Cost)]);
  647. _labour.Add(_labouritem);
  648. }
  649. }
  650. }
  651. catch (Exception e)
  652. {
  653. throw new Exception($"Error: {e.Message}\nQuery: {_data.CommandText}\nTrace: {e.StackTrace}");
  654. }
  655. }
  656. if (request.IncludeExcelData)
  657. {
  658. List<string> _tables = new List<string>();
  659. using (var _master = new SQLiteCommand(_connection))
  660. {
  661. _master.CommandText = "select * from sqlite_master where type='table'";
  662. using (var _reader = _master.ExecuteReader())
  663. {
  664. if (_reader.HasRows)
  665. {
  666. while (_reader.Read())
  667. _tables.Add(_reader.GetString(1));
  668. }
  669. }
  670. }
  671. DataSet _ds = new DataSet();
  672. foreach (var _table in _tables)
  673. {
  674. using (var _data = new SQLiteCommand(_connection))
  675. {
  676. _data.CommandText = $"select * from {_table}";
  677. using (var _reader = _data.ExecuteReader())
  678. {
  679. DataTable _dt = new DataTable(_table);
  680. _ds.Tables.Add(_dt);
  681. _dt.Load(_reader);
  682. }
  683. }
  684. }
  685. var excelApp = OfficeOpenXML.GetInstance();
  686. using (var _buffer = excelApp.GetExcelStream(_ds, false))
  687. _excelData = _buffer.GetBuffer();
  688. _connection.Close();
  689. File.Delete(file);
  690. }
  691. bom.Finishes = _finishes.ToArray();
  692. bom.Profiles = _profiles.ToArray();
  693. bom.Gaskets = _gaskets.ToArray();
  694. bom.Components = _components.ToArray();
  695. bom.Glass = _glass.ToArray();
  696. bom.Labour = _labour.ToArray();
  697. bom.ExcelData = _excelData;
  698. bom.SQLiteData = sqLiteData;
  699. }
  700. }
  701. public void Dispose()
  702. {
  703. Disconnect();
  704. }
  705. }
  706. }