Forráskód Böngészése

Preliminary RFI Implementation

Frank van den Bos 2 éve
szülő
commit
39b38543d1

+ 39 - 0
prs.classes/Entities/Job/JobRFI.cs

@@ -0,0 +1,39 @@
+using System;
+using System.Linq.Expressions;
+using InABox.Core;
+
+namespace Comal.Classes
+{
+    
+    public class JobRFI : Entity, IRemotable, IPersistent, INumericAutoIncrement<JobRFI>, ILicense<ProjectManagementLicense>
+    {
+
+        [NullEditor]
+        [EntityRelationship(DeleteAction.Cascade)]
+        public JobLink Job { get; set; }
+        public Expression<Func<JobRFI, int>> AutoIncrementField() => x => x.Number;
+        public Filter<JobRFI> AutoIncrementFilter() => new Filter<JobRFI>(x => x.Job.ID).IsEqualTo(Job.ID);
+        
+        [IntegerEditor( Editable = Editable.Disabled)]
+        [EditorSequence(1)]
+        public int Number { get; set; }
+        
+        [TextBoxEditor]
+        [EditorSequence(2)]
+        public String Subject { get; set; }
+        
+        [NotesEditor]
+        [EditorSequence(3)]
+        public String[] Notes { get; set; }
+
+        [TimestampEditor]
+        [EditorSequence(4)]
+        public DateTime Closed { get; set; }
+        
+        protected override void Init()
+        {
+            base.Init();
+            Job = new JobLink();
+        }
+    }
+}

+ 1 - 0
prs.desktop/Panels/Jobs/JobPanel.xaml

@@ -32,6 +32,7 @@
                 <dynamicgrid:DynamicTabItem Header="Details" Name="Details" />
                 <dynamicgrid:DynamicTabItem Header="Financials" Name="Financials" />
                 <dynamicgrid:DynamicTabItem Header="Documents" Name="Documents" />
+                <dynamicgrid:DynamicTabItem Header="RFIs" Name="RFIs" />
                 <dynamicgrid:DynamicTabItem Header="Planning" Name="Stages" />
                 <dynamicgrid:DynamicTabItem Header="ITP Areas" Name="ITPs" />
                 <dynamicgrid:DynamicTabItem Header="BOM" Name="BOM" />

+ 12 - 3
prs.desktop/Panels/Jobs/JobPanel.xaml.cs

@@ -26,8 +26,8 @@ namespace PRSDesktop
         {
             Details = 00,
             Financials,
-            
             Documents,
+            RFIs,
             Stages,
             ITPs,
             BOM,
@@ -55,6 +55,7 @@ namespace PRSDesktop
         private JobDetails JobDetailsPage;
         private JobFinancialGrid JobFinancialPage;
         private JobDocumentSetPanel JobDocumentsPage;
+        private JobRFIPanel JobRFIPage;
         private JobStagesPanel JobPlanningPage;
         private JobITPGrid JobITPPage;
         private JobBillOfMaterialsPanel JobBillOfMaterialsPage; 
@@ -102,6 +103,8 @@ namespace PRSDesktop
                 
                 PageIndex.Documents => JobDocumentsPage.Selected(),
                 
+                PageIndex.RFIs => JobRFIPage.Selected(),
+                
                 PageIndex.Stages => JobPlanningPage.Selected(),
                 
                 PageIndex.ITPs => new Dictionary<string, object[]> { { typeof(JobITP).EntityName(), JobITPPage.SelectedRows } },
@@ -176,6 +179,7 @@ namespace PRSDesktop
 
             Financials.Visibility = Security.CanView<JobFinancial>() ? Visibility.Visible : Visibility.Collapsed;
             Documents.Visibility = Security.CanView<JobDocumentSet>() ? Visibility.Visible : Visibility.Collapsed;
+            RFIs.Visibility = Security.CanView<JobRFI>() ? Visibility.Visible : Visibility.Collapsed;
             Stages.Visibility = ClientFactory.IsSupported<JobStage>() ? Visibility.Visible : Visibility.Collapsed;
             ITPs.Visibility = ClientFactory.IsSupported<JobITP>() ? Visibility.Visible : Visibility.Collapsed;
             BOM.Visibility = ClientFactory.IsSupported<JobBillOfMaterials>() ? Visibility.Visible : Visibility.Collapsed;
@@ -215,10 +219,13 @@ namespace PRSDesktop
             JobDetailsPage = null;
 
             Financials.Content = null;
-            Financials = null;
+            JobFinancialPage = null;
 
             Documents.Content = null;
-            Documents = null;
+            JobDocumentsPage = null;            
+            
+            RFIs.Content = null;
+            JobRFIPage = null;
 
             Stages.Content = null;
             JobPlanningPage = null;
@@ -349,6 +356,8 @@ namespace PRSDesktop
                     case PageIndex.Financials : RefreshGrid(Financials, ref JobFinancialPage, jobid, row != null);
                         break;
                     case PageIndex.Documents : RefreshPanel(Documents, ref JobDocumentsPage, jobid, row != null);
+                        break;                    
+                    case PageIndex.RFIs : RefreshPanel(RFIs, ref JobRFIPage, jobid, row != null);
                         break;
                     case PageIndex.Stages : RefreshPanel(Stages, ref JobPlanningPage, jobid, row != null);
                         break;

+ 31 - 0
prs.desktop/Panels/Jobs/JobRFIPanel.xaml

@@ -0,0 +1,31 @@
+<UserControl x:Class="PRSDesktop.JobRFIPanel"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+             xmlns:local="clr-namespace:PRSDesktop"
+             xmlns:dynamicGrid="clr-namespace:InABox.DynamicGrid;assembly=InABox.Wpf"
+             mc:Ignorable="d"
+             d:DesignHeight="300" d:DesignWidth="1000">
+    <dynamicGrid:DynamicSplitPanel Anchor="Master" AnchorWidth="500" View="Combined" AllowableViews="Combined, Master" OnChanged="DynamicSplitPanel_OnOnChanged">
+        <dynamicGrid:DynamicSplitPanel.Header>
+            <Border DockPanel.Dock="Top" BorderBrush="Gray" BorderThickness="0.75" Background="Gainsboro" Height="30">
+                <Label Content="Requests for Information" HorizontalContentAlignment="Center" FontWeight="Bold" FontSize="12"/>
+            </Border>
+        </dynamicGrid:DynamicSplitPanel.Header>
+        
+        <dynamicGrid:DynamicSplitPanel.Master>
+            <local:JobRFIGrid x:Name="RFIs" OnSelectItem="RFIs_OnOnSelectItem"></local:JobRFIGrid>    
+        </dynamicGrid:DynamicSplitPanel.Master>
+        
+        <dynamicGrid:DynamicSplitPanel.Detail>
+            <DockPanel>
+                <Border DockPanel.Dock="Top" BorderBrush="Gray" BorderThickness="0.75" Background="Gainsboro" Height="30">
+                    <Label Content="RFI Details" HorizontalContentAlignment="Center" FontWeight="Bold" FontSize="12"/>
+                </Border>
+                <dynamicGrid:EmbeddedDynamicEditorForm x:Name="RFIEditor" DockPanel.Dock="Bottom" OnOK="RFI_OnOnOK" OnCancel="RFI_OnOnCancel" Margin="-5"/>
+            </DockPanel>
+        </dynamicGrid:DynamicSplitPanel.Detail>
+        
+    </dynamicGrid:DynamicSplitPanel>
+</UserControl>

+ 151 - 0
prs.desktop/Panels/Jobs/JobRFIPanel.xaml.cs

@@ -0,0 +1,151 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using Comal.Classes;
+using InABox.Core;
+using InABox.DynamicGrid;
+using InABox.WPF;
+
+namespace PRSDesktop
+{
+
+    public class JobRFIGrid : DynamicDataGrid<JobRFI>
+    {
+        public Guid ParentID { get; set; }
+
+        public JobRFIGrid()
+        {
+            Options
+                .BeginUpdate()
+                .Clear()
+                .Add(DynamicGridOption.AddRows)
+                .Add(DynamicGridOption.EditRows)
+                .Add(DynamicGridOption.DeleteRows)
+                .Add(DynamicGridOption.FilterRows)
+                .Add(DynamicGridOption.SelectColumns)
+                .Add(DynamicGridOption.AddRows)
+                .EndUpdate();
+        }
+        
+        protected override void Reload(Filters<JobRFI> criteria, Columns<JobRFI> columns, ref SortOrder<JobRFI>? sort, Action<CoreTable?, Exception?> action)
+        {
+            criteria.Add(new Filter<JobRFI>(c => c.Job.ID).IsEqualTo(ParentID));
+            base.Reload(criteria, columns, ref sort, action);
+        }
+
+        protected override JobRFI CreateItem()
+        {
+            var result = base.CreateItem();
+            result.Job.ID = ParentID;
+            return result;
+        }
+        
+        public JobRFI[] LoadRFIs(CoreRow[]? rows)
+        {
+            return LoadItems(rows);
+        }
+    }
+
+    public partial class JobRFIPanel : UserControl, IPanel<JobRFI>, IJobControl
+    {
+
+        public Guid ParentID { get; set; }
+
+        public JobRFIPanel()
+        {
+            InitializeComponent();
+        }
+
+        private void DynamicSplitPanel_OnOnChanged(object sender, DynamicSplitPanelSettings e)
+        {
+            if (e.View == DynamicSplitPanelView.Master)
+                RFIs.Options.Add(DynamicGridOption.MultiSelect);
+            else
+                RFIs.Options.Remove(DynamicGridOption.MultiSelect);
+        }
+
+        private JobRFI[]? _rfis = null;
+
+        private void RFIs_OnOnSelectItem(object sender, DynamicGridSelectionEventArgs e)
+        {
+            ReloadRFIs();
+        }
+
+        private void ReloadRFIs()
+        {
+            if (RFIs.SelectedRows?.Any() == true)
+            {
+                _rfis = RFIs.LoadRFIs(RFIs.SelectedRows);
+                RFIs.InitialiseEditorForm(RFIEditor, _rfis);
+                RFIEditor.Visibility = Visibility.Visible;
+            }
+            else
+            {
+                _rfis = null;
+                RFIEditor.Visibility = Visibility.Hidden;
+            }
+        }
+
+        private void RFI_OnOnOK()
+        {
+            using (new WaitCursor())
+            {
+                var cancel = new System.ComponentModel.CancelEventArgs();
+                RFIEditor.SaveItem(cancel);
+                if (!cancel.Cancel)
+                    ReloadRFIs();
+            }
+        }
+
+        private void RFI_OnOnCancel()
+        {
+            ReloadRFIs();
+        }
+
+        #region IPanel Stuff
+
+        public void Setup()
+        {
+            RFIs.Refresh(true, false);
+        }
+
+        public void Shutdown()
+        {
+            
+        }
+
+        public void Refresh()
+        {
+            RFIs.Refresh(false, true);
+        }
+
+        public string SectionName => "Job RFIs";
+
+        public DataModel DataModel(Selection selection)
+        {
+            return new BaseDataModel<JobRFI>(new Filter<JobRFI>(x => x.Job.ID).IsEqualTo(ParentID));
+        }
+
+        public event DataModelUpdateEvent? OnUpdateDataModel;
+        public bool IsReady { get; set; }
+
+        public void CreateToolbarButtons(IPanelHost host)
+        {
+            
+        }
+
+        public Dictionary<string, object[]> Selected()
+        {
+            return new Dictionary<string, object[]>();
+        }
+
+        public void Heartbeat(TimeSpan time)
+        {
+            
+        }
+        
+        #endregion
+}
+}