LogikalServer.cs 31 KB

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