Pārlūkot izejas kodu

Separated Logikal BOM and Elevation Requests

Frank van den Bos 10 mēneši atpakaļ
vecāks
revīzija
6d7efa331c

+ 17 - 1
prs.classes/Entities/Logikal/LogikalComponent.cs

@@ -14,7 +14,7 @@ namespace Comal.Classes
             ValidateField(sql, nameof(PackSize), errors);
         }
 
-        public static String SQL =
+        public static String ElevationSQL =
             "select \n" +
             $"  a.[ArticleCode_BaseNumber] as {nameof(Code)}, \n" +
             $"  a.[description] as {nameof(Description)}, \n" +
@@ -29,6 +29,22 @@ namespace Comal.Classes
             "  elevations e on i.[elevationid] = e.[elevationid] \n" +
             "where \n" +
             "  1=1";
+
+        public static String BillOfMaterialsSQL =
+            "select \n" +
+            $"  a.[ArticleCode_BaseNumber] as {nameof(Code)}, \n" +
+            $"  a.[description] as {nameof(Description)}, \n" +
+            $"  1.0 as {nameof(PackSize)}, \n" +
+            $"  a.[units] as {nameof(Quantity)}, \n" +
+            $"  0.0 as {nameof(Cost)} \n" +
+            "from \n" +
+            "  allarticles a \n" +
+            "left outer join \n" +
+            "  insertions i on a.[insertionid] = i.[insertionid] \n" +
+            "left outer join \n" +
+            "  elevations e on i.[elevationid] = e.[elevationid] \n" +
+            "where \n" +
+            "  1=1";
     }
 
 }

+ 20 - 1
prs.classes/Entities/Logikal/LogikalGlass.cs

@@ -19,7 +19,26 @@ namespace Comal.Classes
             ValidateField(sql, nameof(Location), errors);
         }
 
-        public static string SQL =
+        public static string ElevationSQL =
+            "select \n" +
+            $"  g.[Name] as {nameof(Code)}, \n" +
+            $"  g.[Description] as {nameof(Description)}, \n" +
+            $"  g.[width_output] as {nameof(Height)}, \n" +
+            $"  g.[height_output] as {nameof(Width)}, \n" +
+            $"  g.[Configuration] as {nameof(Treatment)}, \n" +
+            $"  '' as {nameof(Location)}, \n" +
+            $"  1.0 as {nameof(Quantity)}, \n" +
+            $"  g.[Price] as {nameof(Cost)} \n" +
+            "from \n" +
+            "  glass g \n" +
+            "left outer join \n" +
+            "  insertions i on g.[insertionid] = i.[insertionid] \n" +
+            "left outer join \n" +
+            "  elevations e on i.[elevationid] = e.[elevationid] \n" +
+            "where \n" +
+            "  1=1";
+
+        public static string BillOfMaterialsSQL =
             "select \n" +
             $"  g.[Name] as {nameof(Code)}, \n" +
             $"  g.[Description] as {nameof(Description)}, \n" +

+ 2 - 2
prs.classes/Entities/Logikal/LogikalLabour.cs

@@ -21,9 +21,9 @@ namespace Comal.Classes
             "from \n" +
             "  labourtimes t \n" +
             "join \n" +
-            "  labourcosts c  on t.[labourtimeid] = c.[labourtimeid] \n" +
+            "  labourcosts c  on t.[timetype] = c.[type] \n" +
             "left outer join \n" +
-            "  elevations e on t.[elevationid] = e.[insertionid] \n" +
+            "  elevations e on t.[elevationid] = e.[elevationid] \n" +
             "where \n" +
             "  1=1";
 

+ 20 - 1
prs.classes/Entities/Logikal/LogikalProfile.cs

@@ -18,7 +18,7 @@ namespace Comal.Classes
             ValidateField(sql, nameof(Finish), errors);
         }
 
-        public static String SQL =
+        public static String ElevationSQL =
             "select \n" +
             $"  p.[ArticleCode_BaseNumber] as {nameof(Code)}, \n" +
             $"  p.[description] as {nameof(Description)}, \n" +
@@ -37,6 +37,25 @@ namespace Comal.Classes
             "where \n" +
             "  1=1";
 
+        public static String BillOfMaterialsSQL =
+            "select \n" +
+            $"  b.[ArticleCode_BaseNumber] as {nameof(Code)}, \n" +
+            $"  b.[description] as {nameof(Description)}, \n" +
+            $"  b.[length_output] as {nameof(Length)}, \n" +
+            $"  c.[ColorName] as {nameof(Finish)}, \n" +
+            $" 1.0 as {nameof(Quantity)}, \n" +
+            $"  0.0 as {nameof(Cost)} \n" +
+            "from \n" +
+            "  profilebars b \n" +
+            "left outer join \n" +
+            "  insertions i on b.[insertionid] = i.[insertionid] \n" +
+            "left outer join \n" +
+            "  elevations e on i.[elevationid] = e.[elevationid] \n" +
+            "left outer join \n" +
+            "  colors c on b.[lk_colorid] = c.[colorid] \n" +
+            "where \n" +
+            "  1=1";
+
     }
 
 

+ 79 - 19
prs.classes/Entities/Logikal/LogikalSettings.cs

@@ -3,6 +3,13 @@ using InABox.Core;
 
 namespace Comal.Classes
 {
+
+    public enum LogikalDesignType
+    {
+        Approved,
+        NotApproved
+    }
+
     public class LogikalSettings : Entity, IRemotable, IPersistent, ILicense<LogikalLicense>
     {
         [FileNameEditor]
@@ -17,40 +24,93 @@ namespace Comal.Classes
         [EditorSequence(3)]
         public string Password { get; set; }
 
-        [MemoEditor]
-        [EditorSequence("1. Profiles",1)]
-        public String ProfileSQL { get; set; }
+        [CheckBoxEditor]
+        [EditorSequence(4)]
+        public bool ImportJobs { get; set; }
+
+        [CheckBoxEditor]
+        [EditorSequence(5)]
+        [Caption("Import BOMs")]
+        public bool ImportBillOfMaterials { get; set; }
+
+        [CheckBoxEditor]
+        [EditorSequence(6)]
+        [Caption("Import Requis")]
+        public bool ImportRequisitions { get; set; }
 
-        [CodeEditor(Visible=Visible.Default, Editable=Editable.Enabled)]
-        [EditorSequence("1. Profiles", 2)]
+        [EnumLookupEditor(typeof(LogikalDesignType))]
+        [EditorSequence(7)]
+        [Caption("Import Designs")]
+        public LogikalDesignType ImportDesigns { get; set; }
+
+        [CodeEditor(Visible = Visible.Default, Editable = Editable.Enabled)]
+        [EditorSequence(8)]
+        public string JobStatus { get; set; }
+
+        [CodeEditor(Visible = Visible.Default, Editable = Editable.Enabled)]
+        [EditorSequence(9)]
+        public string TaxCode { get; set; }
+
+        [CodeEditor(Visible = Visible.Default, Editable = Editable.Enabled)]
+        [EditorSequence(10)]
         public string ProfileUom { get; set; }
 
+        [CodeEditor(Visible = Visible.Default, Editable = Editable.Enabled)]
+        [EditorSequence(11)]
+        public string ComponentUom { get; set; }
+
+        [CodeEditor(Visible = Visible.Default, Editable = Editable.Enabled)]
+        [EditorSequence(12)]
+        public string GlassUom { get; set; }
+
         [MemoEditor]
-        [EditorSequence("2. Components", 1)]
-        public String ComponentSQL { get; set; }
+        [EditorSequence("1. BOM Queries",1)]
+        [Caption("Profiles")]
+        public String BillOfMaterialsProfileSQL { get; set; }
 
-        [CodeEditor(Visible=Visible.Default, Editable=Editable.Enabled)]
-        [EditorSequence("2. Components", 2)]
-        public string ComponentUom { get; set; }
+        [MemoEditor]
+        [EditorSequence("1. BOM Queries", 2)]
+        [Caption("Components")]
+        public String BillOfMaterialsComponentSQL { get; set; }
 
         [MemoEditor]
-        [EditorSequence("3. Glass", 1)]
-        public String GlassSQL { get; set; }
+        [EditorSequence("1. BOM Queries", 3)]
+        [Caption("Glass")]
+        public String BillOfMaterialsGlassSQL { get; set; }
 
-        [CodeEditor(Visible=Visible.Default, Editable=Editable.Enabled)]
-        [EditorSequence("3. Glass", 2)]
-        public string GlassUom { get; set; }
+        [MemoEditor]
+        [EditorSequence("2. Elevation Queries", 1)]
+        [Caption("Profiles")]
+        public String ElevationProfileSQL { get; set; }
+
+        [MemoEditor]
+        [EditorSequence("2. Elevation Queries", 2)]
+        [Caption("Components")]
+        public String ElevationComponentSQL { get; set; }
+
+        [MemoEditor]
+        [EditorSequence("2. Elevation Queries", 3)]
+        [Caption("Glass")]
+        public String ElevationGlassSQL { get; set; }
 
         [MemoEditor]
-        [EditorSequence("4. Labour", 1)]
+        [EditorSequence("3. Labour Queries", 1)]
+        [Caption("Query")]
         public String LabourSQL { get; set; }
 
+
         public void CheckSQL()
         {
-            ProfileSQL = string.IsNullOrWhiteSpace(ProfileSQL) ? LogikalProfile.SQL : ProfileSQL;
-            ComponentSQL = string.IsNullOrWhiteSpace(ComponentSQL) ? LogikalComponent.SQL : ComponentSQL;
-            GlassSQL = string.IsNullOrWhiteSpace(GlassSQL) ? LogikalGlass.SQL : GlassSQL;
+            BillOfMaterialsProfileSQL = string.IsNullOrWhiteSpace(BillOfMaterialsProfileSQL) ? LogikalProfile.BillOfMaterialsSQL : BillOfMaterialsProfileSQL;
+            BillOfMaterialsComponentSQL = string.IsNullOrWhiteSpace(BillOfMaterialsComponentSQL) ? LogikalComponent.BillOfMaterialsSQL : BillOfMaterialsComponentSQL;
+            BillOfMaterialsGlassSQL = string.IsNullOrWhiteSpace(BillOfMaterialsGlassSQL) ? LogikalGlass.BillOfMaterialsSQL : BillOfMaterialsGlassSQL;
+
+            ElevationProfileSQL = string.IsNullOrWhiteSpace(ElevationProfileSQL) ? LogikalProfile.ElevationSQL : ElevationProfileSQL;
+            ElevationComponentSQL = string.IsNullOrWhiteSpace(ElevationComponentSQL) ? LogikalComponent.ElevationSQL : ElevationComponentSQL;
+            ElevationGlassSQL = string.IsNullOrWhiteSpace(ElevationGlassSQL) ? LogikalGlass.ElevationSQL : ElevationGlassSQL;
+
             LabourSQL = string.IsNullOrWhiteSpace(LabourSQL) ? LogikalLabour.SQL : LabourSQL;
+        
         }
 
     }

+ 10 - 6
prs.desktop/Panels/Jobs/BillOfMaterials/JobBillOfMaterialsGrid.cs

@@ -107,13 +107,17 @@ namespace PRSDesktop
 
             if (Security.CanView<LogikalSettings>())
             {
-                menu ??= new ContextMenu();
-                var item = new MenuItem()
+                var _c = new LogikalClient();
+                if (_c.Settings.ImportBillOfMaterials)
                 {
-                    Header = "Import from Logikal"
-                };
-                item.Click += ImportFromLogikal;
-                menu.Items.Add(item);
+                    menu ??= new ContextMenu();
+                    var item = new MenuItem()
+                    {
+                        Header = "Import from Logikal"
+                    };
+                    item.Click += ImportFromLogikal;
+                    menu.Items.Add(item);
+                }
             }
 
             if (menu != null)

+ 14 - 9
prs.desktop/Panels/Jobs/ProjectsGrid.cs

@@ -224,6 +224,8 @@ public class ProjectsGrid : DynamicDataGrid<Job>
         return pages;
     }
 
+    private LogikalSettings? _logikalSettings;
+
     protected override void DoAdd(bool openEditorOnDirectEdit = false)
     {
         ContextMenu? menu = null;
@@ -240,13 +242,17 @@ public class ProjectsGrid : DynamicDataGrid<Job>
 
         if (Security.CanView<LogikalSettings>())
         {
-            menu ??= new ContextMenu();
-            var item = new MenuItem()
+            var _c = new LogikalClient();
+            if (_c.Settings.ImportJobs)
             {
-                Header = "Import from Logikal"
-            };
-            item.Click += ImportFromLogikal;
-            menu.Items.Add(item);
+                menu ??= new ContextMenu();
+                var item = new MenuItem()
+                {
+                    Header = "Import from Logikal"
+                };
+                item.Click += ImportFromLogikal;
+                menu.Items.Add(item);
+            }
         }
 
         if (menu != null)
@@ -266,9 +272,8 @@ public class ProjectsGrid : DynamicDataGrid<Job>
 
     private void ImportFromLogikal(object sender, RoutedEventArgs e)
     {
-        if (SelectedRows?.Length != 1)
-            return;
-        var import = new LogikalProjectImport(SelectedRows[0].ToObject<Job>());
+
+        var import = new LogikalProjectImport();
         if (import.ShowDialog() == true)
             Refresh(false,true);
     }

+ 7 - 3
prs.desktop/Setups/SystemSetupActions.cs

@@ -172,10 +172,14 @@ public static class SystemSetupActions
             //}
 
             _item.CheckSQL();
-            Validate<LogikalProfile>(_item.ProfileSQL, errors);
-            Validate<LogikalComponent>(_item.ComponentSQL, errors);
+            Validate<LogikalProfile>(_item.BillOfMaterialsProfileSQL, errors);
+            Validate<LogikalComponent>(_item.BillOfMaterialsComponentSQL, errors);
+            Validate<LogikalGlass>(_item.BillOfMaterialsGlassSQL, errors);
+            Validate<LogikalProfile>(_item.ElevationProfileSQL, errors);
+            Validate<LogikalComponent>(_item.ElevationComponentSQL, errors);
+            Validate<LogikalGlass>(_item.ElevationGlassSQL, errors);
             Validate<LogikalLabour>(_item.LabourSQL, errors);
-            Validate<LogikalGlass>(_item.GlassSQL, errors);
+
         }
 
     }

+ 33 - 30
prs.desktop/Utils/LogikalUtils/Grids/LogikalElevationGrid.cs

@@ -22,45 +22,48 @@ public class LogikalElevationGrid : LogikalGrid<LogikalElevation>
     public Guid ProjectID { get; set; }
     public string Phase { get; set; }
 
-    private BitmapImage excel = PRSDesktop.Resources.doc_xls.AsBitmapImage();
 
     protected override void Init()
     {
         base.Init();
+        Options.MultiSelect = true;
         HiddenColumns.Add(x => x.ID);
-        ActionColumns.Add(new DynamicImageColumn(r => excel, GetBOM));
+        //ActionColumns.Add(new DynamicMenuColumn(BuildMenu) {  Position = DynamicActionColumnPosition.Start });
     }
 
-    private bool GetBOM(CoreRow? r)
-    {
-        if (r != null && Client != null)
-        {
-            var id = r.Get<LogikalElevation, Guid>(x => x.ID);
+    //private void BuildMenu(DynamicMenuColumn column, CoreRow? row)
+    //{
+    //    column.AddItem("Download Parts List", PRSDesktop.Resources.doc_xls, GetBOM);
+    //}
 
-            Client.GetBOM(ProjectID, id, true)
-                .Error(e =>
-                {
-                    Dispatcher.BeginInvoke(() =>
-                    {
-                        MessageWindow.ShowError("Unable to retrieve parts", e.Message, e.Status.ToString());
-                    });
-                })
-                .Success<LogikalBOMResponse<LogikalProfile,LogikalComponent,LogikalGlass,LogikalLabour>>(p =>
-                {
-                    var sfd = new SaveFileDialog();
-                    sfd.Filter = "Excel Files (*.xlsx)|*.xlsx";
-                    sfd.FileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "LogikalParts.xlsx");
-                    if (sfd.ShowDialog() == true)
-                    {
-                        File.WriteAllBytes(sfd.FileName, p.ExcelData);
-                        var pInfo = new ProcessStartInfo(sfd.FileName) { UseShellExecute = true };
-                        Process.Start(pInfo);
-                    }
-                });
-        }
+    //private void GetBOM(CoreRow? r)
+    //{
+    //    if (r != null && Client != null)
+    //    {
+    //        var id = r.Get<LogikalElevation, Guid>(x => x.ID);
 
-        return false;
-    }
+    //        Client.GetBillOfMaterials(ProjectID, id, true)
+    //            .Error(e =>
+    //            {
+    //                Dispatcher.BeginInvoke(() =>
+    //                {
+    //                    MessageWindow.ShowError("Unable to retrieve parts", e.Message, e.Status.ToString());
+    //                });
+    //            })
+    //            .Success<LogikalBOMResponse<LogikalProfile,LogikalComponent,LogikalGlass,LogikalLabour>>(p =>
+    //            {
+    //                var sfd = new SaveFileDialog();
+    //                sfd.Filter = "Excel Files (*.xlsx)|*.xlsx";
+    //                sfd.FileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "ElevationPartsList.xlsx");
+    //                if (sfd.ShowDialog() == true)
+    //                {
+    //                    File.WriteAllBytes(sfd.FileName, p.ExcelData);
+    //                    var pInfo = new ProcessStartInfo(sfd.FileName) { UseShellExecute = true };
+    //                    Process.Start(pInfo);
+    //                }
+    //            });
+    //    }
+    //}
 
     protected override void DoGet(LogikalClient client, IProgress<string> progress)
 

+ 1 - 1
prs.desktop/Utils/LogikalUtils/Grids/LogikalProjectGrid.cs

@@ -31,7 +31,7 @@ public class LogikalProjectGrid : LogikalGrid<LogikalProject>
             return base.GenerateColumns();
         var result = new DynamicGridColumns();
         result.Add<LogikalProject, string>(x => x.Name, 0, "Projects", "", Alignment.MiddleLeft);
-        result.Add<LogikalProject, string>(x => x.PersonInCharge, 100, "Manager", "", Alignment.MiddleLeft);
+        //result.Add<LogikalProject, string>(x => x.PersonInCharge, 100, "Manager", "", Alignment.MiddleLeft);
         return result;
     }
 

+ 4 - 4
prs.desktop/Utils/LogikalUtils/LogikalBillOfMaterialsImport.xaml

@@ -7,8 +7,8 @@
         xmlns:dynamicGrid="clr-namespace:InABox.DynamicGrid;assembly=InABox.Wpf"
         mc:Ignorable="d"
         Title="Import From Logikal" 
-        Height="600" 
-        Width="1200" 
+        Height="800" 
+        Width="1400" 
         Loaded="Window_Loaded"
         WindowStartupLocation="CenterScreen">
     <Grid Margin="5">
@@ -30,7 +30,7 @@
             <local:LogikalProjectGrid 
                 x:Name="Projects"
                 DockPanel.Dock="Left"
-                Width="350"
+                Width="250"
                 Margin="0,0,5,0"
                 Visibility="Collapsed"
                 ClientRequired="GetClient"
@@ -41,7 +41,7 @@
             <local:LogikalPhasesGrid 
                 x:Name="Phases"
                 DockPanel.Dock="Left"
-                Width="350"
+                Width="200"
                 Visibility="Collapsed"
                 ClientRequired="GetClient"
                 ResponseReceived="UpdateStatus"

+ 19 - 8
prs.desktop/Utils/LogikalUtils/LogikalBillOfMaterialsImport.xaml.cs

@@ -5,6 +5,7 @@ using System.Threading.Tasks;
 using System.Windows;
 using Comal.Classes;
 using InABox.Clients;
+using InABox.Configuration;
 using InABox.Core;
 using InABox.DynamicGrid;
 using InABox.Logikal;
@@ -28,8 +29,18 @@ public partial class LogikalBillOfMaterialsImport : Window
     public LogikalBillOfMaterialsImport(Job job)
     {
         InitializeComponent();
-        
-        Projects.JobNumber = job.JobNumber;
+
+        if (client.Settings.ImportJobs)
+        {
+            Guid.TryParse(job.SourceRef, out Guid _projectid);
+            Phases.ProjectID = _projectid;
+            Elevations.ProjectID = _projectid;
+        }
+        else
+        {
+            Projects.JobNumber = job.JobNumber;
+        }
+
         Projects.Refresh(true, false);
 
         Phases.Refresh(true, false);
@@ -49,14 +60,16 @@ public partial class LogikalBillOfMaterialsImport : Window
 
     private void Window_Loaded(object sender, RoutedEventArgs e)
     {
-        Projects.Get();
+        if (client.Settings.ImportJobs)
+            Phases.Get();
+        else
+            Projects.Get();
     }
 
     private void Projects_OnSelectItem(object sender, DynamicGridSelectionEventArgs e)
     {
         var id = e.Rows?.FirstOrDefault()?.Get<LogikalProject, Guid>(x => x.ID) ?? Guid.Empty;
         GetPhases(id);
-        
     }
 
     private void GetPhases(Guid id)
@@ -89,8 +102,7 @@ public partial class LogikalBillOfMaterialsImport : Window
         Projects.Visibility = Projects.Items.Count > 1
             ? Visibility.Visible
             : Visibility.Collapsed;
-        if (Projects.Items.Count <= 1)
-            GetPhases(Projects.Items.FirstOrDefault()?.ID ?? Guid.Empty);
+        GetPhases(Projects.Items.FirstOrDefault()?.ID ?? Guid.Empty);
     }
 
     private void Phases_AfterRefresh(object sender, AfterRefreshEventArgs args)
@@ -98,8 +110,7 @@ public partial class LogikalBillOfMaterialsImport : Window
         Phases.Visibility = Phases.Items.Count > 1
             ? Visibility.Visible
             : Visibility.Collapsed;
-        if (Phases.Items.Count <= 1)
-            GetElevations(Phases.Items.FirstOrDefault()?.ID ?? "");
+        GetElevations(Phases.Items.FirstOrDefault()?.ID ?? "");
     }
 
     

+ 45 - 6
prs.desktop/Utils/LogikalUtils/LogikalClient.cs

@@ -217,7 +217,10 @@ public class LogikalClient : IDisposable
         Ready = false;
         var _request = new LogikalLoginRequest();
         var _result = Send(_request)
-            .Success<LogikalLoginResponse>(r => Ready = true );
+            .Success<LogikalLoginResponse>(r => 
+            {
+                Ready = true;
+            });
         return _result;
     }
 
@@ -248,7 +251,17 @@ public class LogikalClient : IDisposable
         var _result = Send(_request);
         return _result;
     }
-        
+
+    public LogikalResponse GetProject(Guid projectid)
+    {
+        if (!Ready)
+            return NOTLOGGEDIN;
+
+        var _request = new LogikalProjectRequest(projectid);
+        var _result = Send(_request);
+        return _result;
+    }
+
     public LogikalResponse GetPhases(Guid projectid)
     {
         if (!Ready)
@@ -269,15 +282,41 @@ public class LogikalClient : IDisposable
         return _result; 
     }
     
-    public LogikalResponse GetBOM(Guid projectid, Guid elevationid, bool excel)
+    public LogikalResponse GetBillOfMaterials(Guid projectid, Guid[] elevationids, bool excel)
     {
         if (!Ready)
             return NOTLOGGEDIN;
 
-        var _request = new LogikalBOMRequest(projectid, elevationid, Settings.ProfileSQL, Settings.ComponentSQL, Settings.GlassSQL, Settings.LabourSQL, excel);
+        var _request = new LogikalBOMRequest(
+            projectid, 
+            elevationids, 
+            Settings.BillOfMaterialsProfileSQL, 
+            Settings.BillOfMaterialsComponentSQL, 
+            Settings.BillOfMaterialsGlassSQL, 
+            Settings.LabourSQL, 
+            excel);
+
         var _result = Send(_request);
         return _result;
     }
-    
-    
+
+    public LogikalResponse GetElevation(Guid projectid, Guid elevationid, bool excel)
+    {
+        if (!Ready)
+            return NOTLOGGEDIN;
+
+        var _request = new LogikalElevationRequest(
+            projectid, 
+            elevationid,
+            Settings.ElevationProfileSQL, 
+            Settings.ElevationComponentSQL, 
+            Settings.ElevationGlassSQL,
+            Settings.LabourSQL, 
+            excel);
+
+        var _result = Send(_request);
+        return _result;
+    }
+
+
 }

+ 13 - 10
prs.desktop/Utils/LogikalUtils/LogikalProjectImport.xaml.cs

@@ -1,5 +1,7 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
 using System.Linq;
 using System.Threading.Tasks;
 using System.Windows;
@@ -8,7 +10,10 @@ using InABox.Clients;
 using InABox.Core;
 using InABox.DynamicGrid;
 using InABox.Logikal;
+using InABox.Wpf;
 using InABox.WPF;
+using Microsoft.Win32;
+using sun.rmi.server;
 
 namespace PRSDesktop;
 
@@ -24,13 +29,11 @@ public partial class LogikalProjectImport : Window
         return client;
     }
 
-    private Job? _job = null;
-
+   
     private LogikalClient client = new LogikalClient();
     
-    public LogikalProjectImport(Job? job = null)
+    public LogikalProjectImport()
     {
-        _job = job;
         InitializeComponent();
         ProjectCentres.Refresh(true, false);
         Projects.Refresh(true, false);
@@ -41,11 +44,12 @@ public partial class LogikalProjectImport : Window
         var project = Projects.SelectedRows.FirstOrDefault()?.ToObject<LogikalProject>();
         if (project == null)
             return;
-        if (_job != null)
-        {
-            _job.SourceRef = project.ID.ToString();
-            Client.Save<Job>(_job, "Linked to Logikal Project");
-        }
+
+        Job job = new Job();
+        job.Name = project.Name?? "Unknown Project";
+        job.SourceRef = project.ID.ToString();
+        Client.Save<Job>(job, "Created from Logikal Logikal Project");
+        
         DialogResult = true;
     }
 
@@ -74,5 +78,4 @@ public partial class LogikalProjectImport : Window
         OK.IsEnabled = id != Guid.Empty;
     }
 
-
 }

+ 18 - 3
prs.logikal/LogikalListener.cs

@@ -34,6 +34,7 @@ namespace PRSLogikal
                 { LogikalMethod.Projects, new LogikalMethodInfo<LogikalProjectsRequest>(GetProjects) },
                 { LogikalMethod.Phases, new LogikalMethodInfo<LogikalPhasesRequest>(GetPhases) },
                 { LogikalMethod.Elevations, new LogikalMethodInfo<LogikalElevationsRequest>(GetElevations) },
+                { LogikalMethod.Elevation, new LogikalMethodInfo<LogikalElevationRequest>(GetElevation) },
                 { LogikalMethod.BOM, new LogikalMethodInfo<LogikalBOMRequest>(GetBOM) },
             };
             
@@ -160,7 +161,14 @@ namespace PRSLogikal
             DoLog($"Server replies: {_response.ToString()}");
             _server.WriteAsync(_response.ToMessage(messageID));
         }
-        
+
+        private void GetProject(LogikalProjectRequest request, Guid messageID)
+        {
+            var _response = Server.GetProject(request);
+            DoLog($"Server replies: {_response.ToString()}");
+            _server.WriteAsync(_response.ToMessage(messageID));
+        }
+
         private void GetPhases(LogikalPhasesRequest request, Guid messageID)
         {
             var _response = Server.GetPhases(request);
@@ -178,11 +186,18 @@ namespace PRSLogikal
         
         private void GetBOM(LogikalBOMRequest request, Guid messageID)
         {
-            var _response = Server.GetBOM(request);
+            var _response = Server.GetBillOfMaterials(request);
             DoLog($"Server replies: {_response.ToString()}");
             _server.WriteAsync(_response.ToMessage(messageID));
         }
-        
+
+        private void GetElevation(LogikalElevationRequest request, Guid messageID)
+        {
+            var _response = Server.GetElevation(request);
+            DoLog($"Server replies: {_response.ToString()}");
+            _server.WriteAsync(_response.ToMessage(messageID));
+        }
+
         public void Dispose()
         {
             if (_server != null)

+ 313 - 169
prs.logikal/LogikalServer.cs

@@ -1,3 +1,5 @@
+using DocumentFormat.OpenXml.Office2010.Excel;
+using DocumentFormat.OpenXml.Wordprocessing;
 using InABox.Logikal;
 using Ofcas.Lk.Api.Client.Core;
 using Ofcas.Lk.Api.Client.Ui;
@@ -12,8 +14,10 @@ using System.Data.SQLite;
 using System.Diagnostics;
 using System.IO;
 using System.Linq;
+using System.Linq.Expressions;
 using System.Threading.Tasks;
 using System.Windows;
+using System.Windows.Navigation;
 
 namespace PRSLogikal
 {
@@ -185,17 +189,8 @@ namespace PRSLogikal
             IList<IBaseProjectInfo> _projects = center.CoreObject.ChildrenInfos;
             foreach (var _project in _projects)
             {
-                var _summary = new LogikalProject()
-                {
-                    ID = _project.Guid,
-                    Name = _project.Name,
-                    PersonInCharge = _project.PersonInCharge,
-                    Path = _project.Path,
-                    LastUpdated = _project.LastChangedDateTime,
-                    Created = _project.CreatedDateTime,
-                    JobNumber = _project.AsProjectInfo().JobNumber,
-                    OfferNumber = _project.AsProjectInfo().OfferNumber
-                };
+                var _summary = new LogikalProject();
+                PopulateProject(_project, _summary);
                 _projectresults.Add(_summary);
             }
 
@@ -216,6 +211,18 @@ namespace PRSLogikal
                 GetProjectCentres(_child, results); 
         }
 
+        private void PopulateProject(IBaseProjectInfo source, ILogikalProject target)
+        {
+            target.ID = source.Guid;
+            target.Name = source.Name;
+            target.PersonInCharge = source.PersonInCharge;
+            target.Path = source.Path;
+            target.LastUpdated = source.LastChangedDateTime;
+            target.Created = source.CreatedDateTime;
+            target.JobNumber = source.AsProjectInfo().JobNumber;
+            target.OfferNumber = source.AsProjectInfo().OfferNumber;
+        }
+
         private List<LogikalProjectCentre> GetProjectCentres()
         {
             var _results = new List<LogikalProjectCentre>();
@@ -262,6 +269,28 @@ namespace PRSLogikal
             
         }
 
+        public LogikalResponse GetProject(LogikalProjectRequest request)
+        {
+            if (_proxy == null)
+                return NOTCONNECTED;
+
+            if (_login == null)
+                return NOTLOGGEDIN;
+
+            var _project = _login.CoreObject.GetProjectByGuid(request.ProjectID);
+            if (_project == null)
+                return new LogikalErrorResponse()
+                {
+                    Status = LogikalStatus.InvalidProjectID,
+                    Message = $"Cannot Load Project {request.ProjectID}"
+                };
+
+            var response = new LogikalProjectResponse();
+            PopulateProject(_project.CoreObject.Info, response);
+            return response;
+           
+        }
+
         public LogikalResponse GetPhases(LogikalPhasesRequest request)
         {
             if (_proxy == null)
@@ -322,26 +351,29 @@ namespace PRSLogikal
             var _elevations = _phase.CoreObject.GetChildren().CoreObjectResults;
             foreach (var _elevation in _elevations)
             {
-                var _result = new LogikalElevation()
-                {
-                    ID = _elevation.CoreObject.Info.Guid,
-                    Name = _elevation.CoreObject.Info.Name,
-                    Description = _elevation.CoreObject.Info.SystemDescription,
-                    Size = _elevation.CoreObject.Info.Size
-                };
-                using (var ms = new MemoryStream())
-                {
-                    IStreamResult thumbnail =
-                        _elevation.CoreObject.GetThumbnail(new Dictionary<string, object>() { });
-                    thumbnail.Stream.CopyTo(ms);
-                    _result.Thumbnail = ms.GetBuffer();
-                }
+                var _result = new LogikalElevation();
+                PopulateElevation(_elevation.CoreObject, _result);  
                 _results.Add(_result);
             }
             return new LogikalElevationsResponse<LogikalElevation>() { Elevations = _results.ToArray() };
         }
 
-        public LogikalResponse GetBOM(LogikalBOMRequest request)
+        private void PopulateElevation(IElevation source, ILogikalElevation target)
+        {
+            target.ID = source.Info.Guid;
+            target.Name = source.Info.Name;
+            target.Description = source.Info.SystemDescription;
+            target.Size = source.Info.Size;
+            using (var ms = new MemoryStream())
+            {
+                IStreamResult thumbnail =
+                   source.GetThumbnail(new Dictionary<string, object>() { });
+                thumbnail.Stream.CopyTo(ms);
+                target.Thumbnail = ms.GetBuffer();
+            }
+        }
+
+        public LogikalResponse GetBillOfMaterials(LogikalBOMRequest request)
         {
 
             if (_proxy == null)
@@ -349,6 +381,81 @@ namespace PRSLogikal
 
             if (_login == null)
                 return NOTLOGGEDIN;
+
+            var _project = _login.CoreObject.GetProjectByGuid(request.ProjectID);
+            if (_project == null)
+                return new LogikalErrorResponse()
+                {
+                    Status = LogikalStatus.InvalidProjectID,
+                    Message = $"Cannot Load Project [{request.ProjectID}]"
+                };
+
+            var _elevations = new List<IElevationInfo>();
+
+           
+            if (request.ElevationIDs?.Any() == true)
+            {
+                var _phases = _project.CoreObject.GetChildren();
+                foreach (var _phase in _phases.CoreObjectResults)
+                    _elevations.AddRange(_phase.CoreObject.ChildrenInfos.Where(x => request.ElevationIDs.Contains(x.Guid)));
+            }
+
+            using (IReportItemsResult reportItemsResult = _project.CoreObject.GetReports())
+            {
+                if (reportItemsResult.OperationCode != OperationCode.Accepted)
+                {
+                    return new LogikalErrorResponse()
+                    {
+                        Status = LogikalStatus.Error,
+                        Message = $"Cannot Get Reports for Project!"
+                    };
+                }
+
+                // Filter available reports for the erp export report item
+                IReportItem reportItem = reportItemsResult.ReportItems.First(rep =>
+                    (rep.Id == WellKnownReports.Delivery.ErpExport) &&
+                    (rep.Category.Id == WellKnownReports.Delivery.CategoryId));
+
+                // Create parameters for erp export, export format is required, but always sqlite
+                var exportParameters = new Dictionary<string, object>
+                {
+                    { WellKnownParameterKey.Project.Report.ExportFormat, "SQLite" },
+                };
+
+
+                // Check if report can be exported for the given parameters
+                var operationInfo = _project.CoreObject.CanGetReport(reportItem, _elevations, exportParameters);
+                if (!operationInfo.CanExecute)
+                {
+                    return new LogikalErrorResponse()
+                    {
+                        Status = LogikalStatus.Error,
+                        Message = $"Cannot Get Erp Report for Project!"
+                    };
+                }
+
+                // Run report creation asynchronously - begin method starts the operation in background task
+                using (ISynchronizedOperationResult synchronizedOperationResult =
+                    _project.CoreObject.BeginGetReport(reportItem, _elevations, exportParameters))
+                {
+
+                    var response = new LogikalBOMResponse<LogikalProfile, LogikalComponent, LogikalGlass, LogikalLabour>();
+                    // End method waits for the background operation to complete in separate task
+                    using (IStreamResult streamResult = Task.Run<IStreamResult>(() =>
+                        _project.CoreObject.EndGetReport(synchronizedOperationResult.SynchronizedOperation)).Result)
+                    {
+                        PopulateParts(request, response, streamResult);
+                    }
+                    return response;
+
+                }
+            }
+
+
+        }
+
+        public LogikalResponse GetElevation(LogikalElevationRequest request)
+        {
             
             var _project = _login.CoreObject.GetProjectByGuid(request.ProjectID);
             if (_project == null)
@@ -357,193 +464,230 @@ namespace PRSLogikal
                     Status = LogikalStatus.InvalidProjectID,
                     Message = $"Cannot Load Project [{request.ProjectID}]"
                 };
-             
+
             var _phases = _project.CoreObject.GetChildren().CoreObjectResults;
             var _phase = _phases.FirstOrDefault(p => p.CoreObject.GetChildren().CoreObjectResults.Any(e => e.CoreObject.Info.Guid == request.ElevationID));
             if (_phase == null)
                 return new LogikalErrorResponse()
                 {
                     Status = LogikalStatus.ElevationNotFound,
-                    Message = $"Elevation [{request.ElevationID}] within project [{request.ProjectID}]"
+                    Message = $"Cannot find Elevation [{request.ElevationID}] within project [{request.ProjectID}]"
                 };
-            
+
+
             var _elevation = _phase.CoreObject.GetChildren().CoreObjectResults.FirstOrDefault(x => x.CoreObject.Info.Guid == request.ElevationID);
             if (_elevation == null)
+            {
                 return new LogikalErrorResponse()
                 {
                     Status = LogikalStatus.InvalidElevationID,
                     Message = $"Cannot find elevation [{request.ElevationID}] within phase [{_phase.CoreObject.Info.Name}]"
                 };
+            }
+
+            try
+            {
+
+                var response = new LogikalElevationResponse<LogikalProfile, LogikalComponent, LogikalGlass, LogikalLabour>();
+
+                PopulateElevation(_elevation.CoreObject, response);
+
+                // Setup parameters for export of the elevation drawing
+                var sectionDrawingParameters = new Dictionary<string, object>
+                {
+                    { WellKnownParameterKey.Elevation.Drawing.Format, ElevationDrawingFormat.DXF },
+                    { WellKnownParameterKey.Elevation.Drawing.View, Ofcas.Lk.Api.Shared.View.Interior },
+                    { WellKnownParameterKey.Elevation.Drawing.Type, ElevationDrawingType.Elevation },
+                    { WellKnownParameterKey.Elevation.Drawing.DxfVersion, DxfVersion.R12 },
+                    { WellKnownParameterKey.Elevation.Drawing.ShowDescription, true },
+                    { WellKnownParameterKey.Elevation.Drawing.ShowDimensions, true },
+                    { WellKnownParameterKey.Elevation.Drawing.Scale, 1.0 },
+                };
+
+                // Check if the drawing can be exported for the elevation with the given parameters
+                if (!_elevation.CoreObject.CanGetDrawing(sectionDrawingParameters).CanExecute)
+                {
+                    return new LogikalErrorResponse()
+                    {
+                        Status = LogikalStatus.Error,
+                        Message = $"GetDrawing() not permitted for [{request.ElevationID}]"
+                    };
+                }
+
+                // Generate drawing for the elevation with the given parameters
+                using (IDrawingResult drawingResult = _elevation.CoreObject.GetDrawing(sectionDrawingParameters))
+                {
+                    Stream exportStream = drawingResult.Stream;
+                    using (var _ms = new MemoryStream())
+                    {
+                        exportStream.CopyTo(_ms);
+                        response.Drawing = _ms.GetBuffer();
+                    }
+                }
+
+                using (IStreamResult streamResult = _elevation.CoreObject.GetPartsList())
+                    PopulateParts(request, response, streamResult);
+                return response;
+
+            }
+            catch (Exception e)
+            {
+                return new LogikalErrorResponse() { Status = LogikalStatus.Error, Message = $"{e.Message}\n\n{e.StackTrace}" };
+            }
+        }
 
+        private void PopulateParts<TRequest, TResponse>(TRequest request, TResponse response, IStreamResult stream)
+            where TRequest : AbstractLogikalPartsRequest
+            where TResponse : AbstractLogikalPartsResponse<LogikalProfile,LogikalComponent,LogikalGlass,LogikalLabour>
+        {
             var _excelData = new byte[] { };
             var _profiles = new List<LogikalProfile>();
             var _components = new List<LogikalComponent>();
             var _glass = new List<LogikalGlass>();
             var _labour = new List<LogikalLabour>();
-
-            try
+ 
+            var file = Path.ChangeExtension(Path.Combine(Path.GetTempPath(), Path.GetTempFileName()), "sqlite3");
+            using (var fs = new FileStream(file, FileMode.OpenOrCreate))
+                stream.Stream.CopyTo(fs);
+
+            var sb = new SQLiteConnectionStringBuilder();
+            sb.DataSource = file;
+            var _connection = new SQLiteConnection(sb.ToString());
+            _connection.Open();
+
+            // Get Profiles
+            using (var _data = new SQLiteCommand(_connection))
             {
-                using (IStreamResult parts = _elevation.CoreObject.GetPartsList())
+                _data.CommandText = request.ProfileQuery;
+                using (var _reader = _data.ExecuteReader())
                 {
-                    var file = Path.ChangeExtension(Path.Combine(Path.GetTempPath(), Path.GetTempFileName()), "sqlite3");
-                    using (var fs = new FileStream(file, FileMode.OpenOrCreate))
-                        parts.Stream.CopyTo(fs);
+                    DataTable _dt = new DataTable();
+                    _dt.Load(_reader);
+                    foreach (DataRow row in _dt.Rows)
+                    {
+                        var _profile = new LogikalProfile();
+                        _profile.Code = (string)row[nameof(LogikalProfile.Code)];
+                        _profile.Description = (string)row[nameof(LogikalProfile.Description)];
+                        _profile.Quantity = (double)row[nameof(LogikalProfile.Quantity)];
+                        _profile.Cost = (double)row[nameof(LogikalProfile.Cost)];
+                        _profile.Finish = (string)row[nameof(LogikalProfile.Finish)];
+                        _profile.Length = (double)row[nameof(LogikalProfile.Length)];
+                        _profiles.Add(_profile);
 
-                    var sb = new SQLiteConnectionStringBuilder();
-                    sb.DataSource = file;
-                    var _connection = new SQLiteConnection(sb.ToString());
-                    _connection.Open();
+                    }
+                }
+            }
 
-                    // Get Profiles
-                    using (var _data = new SQLiteCommand(_connection))
+            // Get Components
+            using (var _data = new SQLiteCommand(_connection))
+            {
+                _data.CommandText = request.ComponentQuery;
+                using (var _reader = _data.ExecuteReader())
+                {
+                    DataTable _dt = new DataTable();
+                    _dt.Load(_reader);
+                    foreach (DataRow row in _dt.Rows)
                     {
-                        _data.CommandText = request.ProfileQuery.Replace("1=1", "where e.[xGuid]='{request.ElevationID}'");
-                        using (var _reader = _data.ExecuteReader())
-                        {
-                            DataTable _dt = new DataTable();
-                            _dt.Load(_reader);
-                            foreach (DataRow row in _dt.Rows)
-                            {
-                                _profiles.Add(new LogikalProfile()
-                                {
-                                    Code = (string)row[nameof(LogikalProfile.Code)],
-                                    Description = (string)row[nameof(LogikalProfile.Description)],
-                                    Quantity = (double)row[nameof(LogikalProfile.Quantity)],
-                                    Cost = (double)row[nameof(LogikalProfile.Cost)],
-                                    Finish = (string)row[nameof(LogikalProfile.Finish)],
-                                    Length = (double)row[nameof(LogikalProfile.Length)],
-                                });
-                            }
-                        }
+                        var _component = new LogikalComponent();
+                        _component.Code = (string)row[nameof(LogikalComponent.Code)];
+                        _component.Description = (string)row[nameof(LogikalComponent.Description)];
+                        _component.Quantity = (double)row[nameof(LogikalComponent.Quantity)];
+                        _component.Cost = (double)row[nameof(LogikalComponent.Cost)];
+                        _component.PackSize = (double)row[nameof(LogikalComponent.PackSize)];
+                        _components.Add(_component);
                     }
+                }
+            }
 
-                    // Get Components
-                    using (var _data = new SQLiteCommand(_connection))
+            // Get Glass
+            using (var _data = new SQLiteCommand(_connection))
+            {
+                _data.CommandText = request.GlassQuery;
+                using (var _reader = _data.ExecuteReader())
+                {
+                    DataTable _dt = new DataTable();
+                    _dt.Load(_reader);
+                    foreach (DataRow row in _dt.Rows)
                     {
-                        _data.CommandText = request.ComponentQuery.Replace("1=1", "where e.[xGuid]='{request.ElevationID}'");
-                        using (var _reader = _data.ExecuteReader())
-                        {
-                            DataTable _dt = new DataTable();
-                            _dt.Load(_reader);
-                            foreach (DataRow row in _dt.Rows)
-                            {
-                                _components.Add(new LogikalComponent()
-                                {
-                                    Code = (string)row[nameof(LogikalComponent.Code)],
-                                    Description = (string)row[nameof(LogikalComponent.Description)],
-                                    Quantity = (double)row[nameof(LogikalComponent.Quantity)],
-                                    Cost = (double)row[nameof(LogikalComponent.Cost)],
-                                    PackSize = (double)row[nameof(LogikalComponent.PackSize)],
-                                });
-                            }
-                        }
+                        var _glassitem = new LogikalGlass();
+                        _glassitem.Code = (string)row[nameof(LogikalGlass.Code)];
+                        _glassitem.Description = (string)row[nameof(LogikalGlass.Description)];
+                        _glassitem.Quantity = (double)row[nameof(LogikalGlass.Quantity)];
+                        _glassitem.Cost = (double)row[nameof(LogikalGlass.Cost)];
+                        _glassitem.Height = (double)row[nameof(LogikalGlass.Height)];
+                        _glassitem.Width = (double)row[nameof(LogikalGlass.Width)];
+                        _glassitem.Treatment = (string)row[nameof(LogikalGlass.Treatment)];
+                        _glassitem.Location = (string)row[nameof(LogikalGlass.Location)];
+                        _glass.Add(_glassitem);
                     }
+                }
+            }
 
-                    // Get Glass
-                    using (var _data = new SQLiteCommand(_connection))
+            // Get Labour
+            using (var _data = new SQLiteCommand(_connection))
+            {
+                _data.CommandText = request.LabourQuery; 
+                using (var _reader = _data.ExecuteReader())
+                {
+                    DataTable _dt = new DataTable();
+                    _dt.Load(_reader);
+                    foreach (DataRow row in _dt.Rows)
                     {
-                        _data.CommandText = request.GlassQuery.Replace("1=1", "where e.[xGuid]='{request.ElevationID}'");
-                        using (var _reader = _data.ExecuteReader())
-                        {
-                            DataTable _dt = new DataTable();
-                            _dt.Load(_reader);
-                            foreach (DataRow row in _dt.Rows)
-                            {
-                                _glass.Add(new LogikalGlass()
-                                {
-                                    Code = (string)row[nameof(LogikalGlass.Code)],
-                                    Description = (string)row[nameof(LogikalGlass.Description)],
-                                    Quantity = (double)row[nameof(LogikalGlass.Quantity)],
-                                    Cost = (double)row[nameof(LogikalGlass.Cost)],
-                                    Height = (double)row[nameof(LogikalGlass.Height)],
-                                    Width = (double)row[nameof(LogikalGlass.Width)],
-                                    Treatment = (string)row[nameof(LogikalGlass.Treatment)],
-                                    Location = (string)row[nameof(LogikalGlass.Location)],
-                                });
-                            }
-                        }
+                        var _labouritem = new LogikalLabour();
+
+                        _labouritem.Code = row[nameof(LogikalLabour.Code)].ToString();
+                        _labouritem.Description = (string)row[nameof(LogikalLabour.Description)];
+                        _labouritem.Quantity = (double)row[nameof(LogikalLabour.Quantity)];
+                        _labouritem.Cost = (double)row[nameof(LogikalLabour.Cost)];
+                        _labour.Add(_labouritem);
                     }
-                    // Get Labour
-                    using (var _data = new SQLiteCommand(_connection))
+                }
+            }
+
+            if (request.IncludeExcelData)
+            {
+                List<string> _tables = new List<string>();
+                using (var _master = new SQLiteCommand(_connection))
+                {
+                    _master.CommandText = "select * from sqlite_master where type='table'";
+                    using (var _reader = _master.ExecuteReader())
                     {
-                        _data.CommandText = request.LabourQuery.Replace("1=1", "where e.[xGuid]='{request.ElevationID}'");
-                        using (var _reader = _data.ExecuteReader())
+                        if (_reader.HasRows)
                         {
-                            DataTable _dt = new DataTable();
-                            _dt.Load(_reader);
-                            foreach (DataRow row in _dt.Rows)
-                            {
-                                _labour.Add(new LogikalLabour()
-                                {
-                                    Code = (string)row[nameof(LogikalLabour.Code)],
-                                    Description = (string)row[nameof(LogikalLabour.Description)],
-                                    Quantity = (double)row[nameof(LogikalLabour.Quantity)],
-                                    Cost = (double)row[nameof(LogikalLabour.Cost)],                                  
-                                });
-                            }
+                            while (_reader.Read())
+                                _tables.Add(_reader.GetString(1));
                         }
                     }
+                }
 
-                    // Labour
-                    // select TimeType, Name, TotalMinutes from labourtimes
-                    // where elevationid='{request.ElevationID}'
-
-                    if (request.IncludeExcelData)
+                DataSet _ds = new DataSet();
+                foreach (var _table in _tables)
+                {
+                    using (var _data = new SQLiteCommand(_connection))
                     {
-                        List<string> _tables = new List<string>();
-                        using (var _master = new SQLiteCommand(_connection))
-                        {
-                            _master.CommandText = "select * from sqlite_master where type='table'";
-                            using (var _reader = _master.ExecuteReader())
-                            {
-                                if (_reader.HasRows)
-                                {
-                                    while (_reader.Read())
-                                        _tables.Add(_reader.GetString(1));
-                                }
-                            }
-                        }
-
-                        DataSet _ds = new DataSet();
-                        foreach (var _table in _tables)
-                        {
-                            using (var _data = new SQLiteCommand(_connection))
-                            {
-                                _data.CommandText = $"select * from {_table}";
-                                using (var _reader = _data.ExecuteReader())
-                                {
-                                    DataTable _dt = new DataTable(_table);
-                                    _ds.Tables.Add(_dt);
-                                    _dt.Load(_reader);
-                                }
-                            }
-                        }
-                        var excelApp = OfficeOpenXML.GetInstance();
-
-                        using (var stream = excelApp.GetExcelStream(_ds, false))
+                        _data.CommandText = $"select * from {_table}";
+                        using (var _reader = _data.ExecuteReader())
                         {
-                            _excelData = stream.GetBuffer();
+                            DataTable _dt = new DataTable(_table);
+                            _ds.Tables.Add(_dt);
+                            _dt.Load(_reader);
                         }
-
-                        _connection.Close();
-                        File.Delete(file);
                     }
                 }
-            }
-            catch (Exception e)
-            {
-                return new LogikalErrorResponse() { Status = LogikalStatus.Error, Message = $"{e.Message}\n\n{e.StackTrace}" };
+                var excelApp = OfficeOpenXML.GetInstance();
+                using (var _buffer = excelApp.GetExcelStream(_ds, false)) 
+                    _excelData = _buffer.GetBuffer();
+                   
+                _connection.Close();
+                File.Delete(file);
             }
 
-            return new LogikalBOMResponse<LogikalProfile, LogikalComponent, LogikalGlass, LogikalLabour>()
-            {
-                Profiles = _profiles.ToArray(),
-                Components = _components.ToArray(),
-                Glass = _glass.ToArray(),
-                Labour = _labour.ToArray(),
-                ExcelData = _excelData
-            };
-                
+
+            response.Profiles = _profiles.ToArray();
+            response.Components = _components.ToArray();
+            response.Glass = _glass.ToArray();
+            response.Labour = _labour.ToArray();
+            response.ExcelData = _excelData;
         }
 
         public void Dispose()