LogikalServer.cs 31 KB

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