LogikalServer.cs 31 KB

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