瀏覽代碼

Setout form improvements; when adding new form, attaches document to a variable if it exists.

Kenric Nugteren 13 小時之前
父節點
當前提交
37e5d8ce40

+ 1 - 1
PRS.Avalonia/PRS.Avalonia/Components/FormsEditor/DigitalFormsHostViewModel.cs

@@ -379,7 +379,7 @@ public partial class DigitalFormsHostViewModel<TModel, TShell, TParent, TParentL
             await MessageDialog.ShowError(e);
             return;
         }
-        DigitalForm.SerializeFormData(Form, Variables, values);
+        DigitalForm.SerializeFormData(Form, values);
 
         await Task.Run(() =>
         {

+ 43 - 80
prs.classes/Entities/Staging/Setout/StagingSetout.cs

@@ -6,80 +6,6 @@ using System.Text;
 
 namespace Comal.Classes
 {
-    
-    public class StagingSetoutFormsAggregate : CoreAggregate<StagingSetout, StagingSetoutForm, Guid>
-    {
-        public override Expression<Func<StagingSetoutForm, Guid>> Aggregate => x => x.ID;
-
-        public override AggregateCalculation Calculation => AggregateCalculation.Count;
-
-        public override Dictionary<Expression<Func<StagingSetoutForm, object>>, Expression<Func<StagingSetout, object>>> Links =>
-            new Dictionary<Expression<Func<StagingSetoutForm, object>>, Expression<Func<StagingSetout, object>>>()
-            {
-                { form => form.Parent.ID, setout => setout.ID }
-            };
-    }
-    
-    public class StagingSetoutOpenFormsAggregate : CoreAggregate<StagingSetout, StagingSetoutForm, Guid>
-    {
-        public override Expression<Func<StagingSetoutForm, Guid>> Aggregate => x => x.ID;
-
-        public override AggregateCalculation Calculation => AggregateCalculation.Count;
-        
-        public override Filter<StagingSetoutForm>? Filter => 
-            Filter<StagingSetoutForm>.Where(x => x.FormCompleted).IsEqualTo(DateTime.MinValue);
-
-        public override Dictionary<Expression<Func<StagingSetoutForm, object>>, Expression<Func<StagingSetout, object>>> Links =>
-            new Dictionary<Expression<Func<StagingSetoutForm, object>>, Expression<Func<StagingSetout, object>>>()
-            {
-                { form => form.Parent.ID, setout => setout.ID }
-            };
-    }
-    
-    public class StagingSetoutPacketsAggregate : CoreAggregate<StagingSetout, StagingManufacturingPacket, Guid>
-    {
-        public override Expression<Func<StagingManufacturingPacket, Guid>> Aggregate => x => x.ID;
-
-        public override AggregateCalculation Calculation => AggregateCalculation.Count;
-
-        public override Dictionary<Expression<Func<StagingManufacturingPacket, object>>, Expression<Func<StagingSetout, object>>> Links =>
-            new Dictionary<Expression<Func<StagingManufacturingPacket, object>>, Expression<Func<StagingSetout, object>>>()
-            {
-                { packet => packet.StagingSetout.ID, setout => setout.ID }
-            };
-    }
-    
-    public class StagingSetoutUnprocessedPacketsAggregate : CoreAggregate<StagingSetout, StagingManufacturingPacket, Guid>
-    {
-        public override Expression<Func<StagingManufacturingPacket, Guid>> Aggregate => x => x.ID;
-
-        public override AggregateCalculation Calculation => AggregateCalculation.Count;
-        
-        public override Filter<StagingManufacturingPacket>? Filter => 
-            Filter<StagingManufacturingPacket>.Where(x => x.ManufacturingPacket.ID).IsEqualTo(Guid.Empty);
-
-        public override Dictionary<Expression<Func<StagingManufacturingPacket, object>>, Expression<Func<StagingSetout, object>>> Links =>
-            new Dictionary<Expression<Func<StagingManufacturingPacket, object>>, Expression<Func<StagingSetout, object>>>()
-            {
-                { packet => packet.StagingSetout.ID, setout => setout.ID }
-            };
-    }
-    
-    public class StagingUnapprovedDocumentsAggregate : CoreAggregate<StagingSetout, StagingSetoutDocument, Guid>
-    {
-        public override Expression<Func<StagingSetoutDocument, Guid>> Aggregate => x => x.ID;
-
-        public override AggregateCalculation Calculation => AggregateCalculation.Count;
-
-        public override Filter<StagingSetoutDocument>? Filter => Filter<StagingSetoutDocument>.Where(x => x.Approved).IsEqualTo(false);
-
-        public override Dictionary<Expression<Func<StagingSetoutDocument, object>>, Expression<Func<StagingSetout, object>>> Links =>
-            new Dictionary<Expression<Func<StagingSetoutDocument, object>>, Expression<Func<StagingSetout, object>>>()
-            {
-                { doc => doc.EntityLink.ID, setout => setout.ID }
-            };
-    }
-
     public class StagingSetout : Entity, IPersistent, IRemotable, ILicense<ManufacturingLicense>, IJobScopedItem
     {
         [EditorSequence(1)]
@@ -118,16 +44,39 @@ namespace Comal.Classes
         [NullEditor]
         public EmployeeLink LockedBy { get; set; }
 
+        private class PacketsAggregate : ComplexFormulaGenerator<StagingSetout, int>
+        {
+            public override IComplexFormulaNode<StagingSetout, int> GetFormula() =>
+                Count<StagingManufacturingPacket, Guid>(
+                    x => x.Property(x => x.ID))
+                .WithLink(x => x.StagingSetout.ID, x => x.ID);
+        }
         [NullEditor]
-        [Aggregate(typeof(StagingSetoutPacketsAggregate))]
+        [ComplexFormula(typeof(PacketsAggregate))]
         public int Packets { get; set; }
         
+        private class UnprocessedPacketsAggregate : ComplexFormulaGenerator<StagingSetout, int>
+        {
+            public override IComplexFormulaNode<StagingSetout, int> GetFormula() =>
+                Count<StagingManufacturingPacket, Guid>(
+                    x => x.Property(x => x.ID),
+                    Filter<StagingManufacturingPacket>.Where(x => x.ManufacturingPacket.ID).IsEqualTo(Guid.Empty))
+                .WithLink(x => x.StagingSetout.ID, x => x.ID);
+        }
         [NullEditor]
-        [Aggregate(typeof(StagingSetoutUnprocessedPacketsAggregate))]
+        [ComplexFormula(typeof(UnprocessedPacketsAggregate))]
         public int UnprocessedPackets { get; set; }
 
+        private class UnapprovedDocumentsAggregate : ComplexFormulaGenerator<StagingSetout, int>
+        {
+            public override IComplexFormulaNode<StagingSetout, int> GetFormula() =>
+                Count<StagingSetoutDocument, Guid>(
+                    x => x.Property(x => x.ID),
+                    Filter<StagingSetoutDocument>.Where(x => x.Approved).IsEqualTo(false))
+                .WithLink(x => x.EntityLink.ID, x => x.ID);
+        }
         [NullEditor]
-        [Aggregate(typeof(StagingUnapprovedDocumentsAggregate))]
+        [ComplexFormula(typeof(UnapprovedDocumentsAggregate))]
         public int UnapprovedDocuments { get; set; }
 
         [NullEditor]
@@ -136,13 +85,27 @@ namespace Comal.Classes
         [NullEditor]
         public KanbanLink Task { get; set; }
         
-        
+        private class FormsAggregate : ComplexFormulaGenerator<StagingSetout, int>
+        {
+            public override IComplexFormulaNode<StagingSetout, int> GetFormula() =>
+                Count<StagingSetoutForm, Guid>(
+                    x => x.Property(x => x.ID))
+                .WithLink(x => x.Parent.ID, x => x.ID);
+        }
         [NullEditor]
-        [Aggregate(typeof(StagingSetoutFormsAggregate))]
+        [ComplexFormula(typeof(FormsAggregate))]
         public int Forms { get; set; }
         
+        private class OpenFormsAggregate : ComplexFormulaGenerator<StagingSetout, int>
+        {
+            public override IComplexFormulaNode<StagingSetout, int> GetFormula() =>
+                Count<StagingSetoutForm, Guid>(
+                    x => x.Property(x => x.ID),
+                    Filter<StagingSetoutForm>.Where(x => x.FormCompleted).IsEqualTo(DateTime.MinValue))
+                .WithLink(x => x.Parent.ID, x => x.ID);
+        }
         [NullEditor]
-        [Aggregate(typeof(StagingSetoutOpenFormsAggregate))]
+        [ComplexFormula(typeof(OpenFormsAggregate))]
         public int OpenForms { get; set; }
        
         private class JobScopeLookup : LookupDefinitionGenerator<JobScope, StagingSetout>

+ 34 - 6
prs.desktop/Panels/Staging/Setouts/StagingSetoutGrid.cs

@@ -112,6 +112,8 @@ public class StagingSetoutGrid : DynamicDataGrid<StagingSetout>
     private Button PastePacketsButton;
     private StagingSetout? CopyPacketsSource;
 
+    private Dictionary<Guid, byte[]?> _formDocuments = new();
+
     public StagingPanellSettings PanelSettings { get; set; } = new StagingPanellSettings();
 
     public StagingSetoutGrid()
@@ -367,8 +369,6 @@ public class StagingSetoutGrid : DynamicDataGrid<StagingSetout>
         return false;
     }
 
-    
-    
     private void Menu_Build(DynamicMenuColumn column, CoreRow? row)
     {
         if (row is null)
@@ -386,8 +386,38 @@ public class StagingSetoutGrid : DynamicDataGrid<StagingSetout>
             () => new Client<StagingSetout>().Query(
                 Filter<StagingSetout>.Where(x => x.ID).IsEqualTo(designID),
                 Columns.Required<StagingSetout>()).ToObjects<StagingSetout>()
-            .FirstOrDefault() ?? new StagingSetout()
-        );
+            .FirstOrDefault() ?? new StagingSetout(),
+            customiseNewForm: CustomiseNewForm);
+    }
+
+    private void CustomiseNewForm(StagingSetout setout, StagingSetoutForm form)
+    {
+        var variable = PanelSettings.FormVariable;
+        if (string.IsNullOrEmpty(variable)) return;
+
+        var doc = Client.Query(
+            Filter<Document>.Where(x => x.ID).InQuery(
+                Filter<StagingSetoutDocument>.Where(x => x.EntityLink.ID).IsEqualTo(setout.ID),
+                x => x.DocumentLink.ID),
+            Columns.None<Document>().Add(x => x.Data),
+            range: CoreRange.Database(1))
+            .ToObjects<Document>().FirstOrDefault();
+        if (doc?.Data is null || doc.Data.Length == 0) return;
+
+        var bytes = ImageUtils.PDFToBitmap(doc.Data, 0);
+
+        var storage = DigitalForm.DeserializeFormSaveData(form) ?? new();
+
+        var value = new DFLayoutEmbeddedMediaValue
+        {
+            Data = bytes,
+            ID = DigitalFormDocumentFactory.SaveDocument(bytes),
+            Thumbnail = ImageUtils.GetPDFThumbnail(doc.Data, 200, 200)
+        };
+        var entry = storage.GetEntry(variable);
+        value.Serialize(entry);
+
+        DigitalForm.SerializeFormData(form, storage);
     }
 
     private void ImportComponents(CoreRow? row)
@@ -432,8 +462,6 @@ public class StagingSetoutGrid : DynamicDataGrid<StagingSetout>
 
         return null;
     }
-
-    
     
     private BitmapImage? FormsImage(CoreRow? arg)
     {

+ 11 - 3
prs.desktop/Panels/Staging/StagingPanel.xaml.cs

@@ -29,18 +29,26 @@ public class StagingPanellSettings : BaseObject, IGlobalConfigurationSettings
 {
     [Caption("PDF Markup Program Pathway", IncludePath = false)]
     [FileNameEditor]
+    [EditorSequence(1)]
     public string MarkupPathway { get; set; }
 
     [FolderEditor(Environment.SpecialFolder.CommonDocuments)]
+    [EditorSequence(2)]
     public string SetoutsFolder { get; set; }
 
-    [ScriptEditor]
-    public string? Script { get; set; }
-
     [Comment("Maximum Document Size (MB)")]
     [IntegerEditor(Caption = "Maximum Document Size (MB)", ToolTip = "The user will be warned when uploading documents which are larger than this size in megabytes. Set to zero for no maximum.")]
+    [EditorSequence(3)]
     public int MaximumDocumentSize { get; set; }
 
+    [ScriptEditor]
+    [EditorSequence(4)]
+    public string? Script { get; set; }
+
+    [Comment("Variable name for the EmbeddedImage document field on StagingSetout forms")]
+    [EditorSequence(5)]
+    public string FormVariable { get; set; }
+
     public StagingPanellSettings()
     {
         MarkupPathway = "";

+ 90 - 85
prs.desktop/Utils/FormUtils.cs

@@ -8,102 +8,107 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 
-namespace PRSDesktop
+namespace PRSDesktop;
+
+public static class FormUtils
 {
-    public static class FormUtils
+    public static void Register()
     {
-        public static void Register()
-        {
-            DFUtils.AddFormUtils<AssignmentForm, Assignment, AssignmentLink>(CanEditAssignmentForm, requiredColumnsFunc: RequiredAssignmentColumns);
-            DFUtils.AddFormUtils<EmployeeForm, Employee, EmployeeLink>(CanEditEmployeeForm);
-            DFUtils.AddFormUtils<JobForm, Job, JobLink>(CanEditJobForm);
-            DFUtils.AddFormUtils<JobITPForm, JobITP, JobITPLink>(CanEditJobITPForm);
-            DFUtils.AddFormUtils<KanbanForm, Kanban, KanbanLink>(CanEditKanbanForm, NewKanban, KanbanOnSave, requiredColumnsFunc: RequiredKanbanColumns);
-            DFUtils.AddFormUtils<LeaveRequestForm, LeaveRequest, LeaveRequestLink>(CanEditLeaveRequestForm, requiredColumnsFunc: RequiredLeaveRequestColumns);
-            DFUtils.AddFormUtils<PurchaseOrderItemForm, PurchaseOrderItem, PurchaseOrderItemLink>(CanEditPurchaseOrderItemForm);
-            DFUtils.AddFormUtils<TimeSheetForm, TimeSheet, TimeSheetLink>(CanEditTimeSheetForm, requiredColumnsFunc: RequiredTimeSheetColumns);
-            DFUtils.AddFormUtils<JobDocumentSetMileStoneForm, JobDocumentSetMileStone, JobDocumentSetMileStoneLink>(CanEditJobDocumentSetMileStoneForm);
-        }
+        DFUtils.AddFormUtils<AssignmentForm, Assignment, AssignmentLink>(CanEditAssignmentForm, requiredColumnsFunc: RequiredAssignmentColumns);
+        DFUtils.AddFormUtils<EmployeeForm, Employee, EmployeeLink>(CanEditEmployeeForm);
+        DFUtils.AddFormUtils<JobForm, Job, JobLink>(CanEditJobForm);
+        DFUtils.AddFormUtils<JobITPForm, JobITP, JobITPLink>(CanEditJobITPForm);
+        DFUtils.AddFormUtils<KanbanForm, Kanban, KanbanLink>(CanEditKanbanForm, NewKanban, KanbanOnSave, requiredColumnsFunc: RequiredKanbanColumns);
+        DFUtils.AddFormUtils<LeaveRequestForm, LeaveRequest, LeaveRequestLink>(CanEditLeaveRequestForm, requiredColumnsFunc: RequiredLeaveRequestColumns);
+        DFUtils.AddFormUtils<PurchaseOrderItemForm, PurchaseOrderItem, PurchaseOrderItemLink>(CanEditPurchaseOrderItemForm);
+        DFUtils.AddFormUtils<TimeSheetForm, TimeSheet, TimeSheetLink>(CanEditTimeSheetForm, requiredColumnsFunc: RequiredTimeSheetColumns);
+        DFUtils.AddFormUtils<JobDocumentSetMileStoneForm, JobDocumentSetMileStone, JobDocumentSetMileStoneLink>(CanEditJobDocumentSetMileStoneForm);
+        DFUtils.AddFormUtils<StagingSetoutForm, StagingSetout, StagingSetoutLink>(CanEditStagingSetoutForm);
+    }
 
-        private static Columns<Assignment> RequiredAssignmentColumns()
-        {
-            return Columns.None<Assignment>().Add(x => x.EmployeeLink.ID);
-        }
+    private static Columns<Assignment> RequiredAssignmentColumns()
+    {
+        return Columns.None<Assignment>().Add(x => x.EmployeeLink.ID);
+    }
 
-        public static bool CanEditAssignmentForm(AssignmentForm form, Assignment assignment)
-        {
-            return assignment.EmployeeLink.ID == App.EmployeeID;
-        }
-        public static bool CanEditEmployeeForm(EmployeeForm form, Employee employee)
-        {
-            return employee.ID == App.EmployeeID;
-        }
-        public static bool CanEditJobForm(JobForm form, Job job)
-        {
-            return true;
-        }
-        public static bool CanEditJobITPForm(JobITPForm form, JobITP jobITP)
-        {
-            return false;
-        }
-        public static bool CanEditJobDocumentSetMileStoneForm(JobDocumentSetMileStoneForm form, JobDocumentSetMileStone assignment)
-        {
-            return true;
-        }
+    public static bool CanEditAssignmentForm(AssignmentForm form, Assignment assignment)
+    {
+        return assignment.EmployeeLink.ID == App.EmployeeID;
+    }
+    public static bool CanEditEmployeeForm(EmployeeForm form, Employee employee)
+    {
+        return employee.ID == App.EmployeeID;
+    }
+    public static bool CanEditJobForm(JobForm form, Job job)
+    {
+        return true;
+    }
+    public static bool CanEditJobITPForm(JobITPForm form, JobITP jobITP)
+    {
+        return false;
+    }
+    public static bool CanEditJobDocumentSetMileStoneForm(JobDocumentSetMileStoneForm form, JobDocumentSetMileStone assignment)
+    {
+        return true;
+    }
 
-        public static bool CanEditKanbanForm(KanbanForm form, Kanban kanban)
-        {
-            return kanban.EmployeeLink.ID == App.EmployeeID;
-        }
-        private static Kanban NewKanban(DigitalForm form)
-        {
-            var kanban = new Kanban();
-            kanban.EmployeeLink.ID = App.EmployeeID;
-            kanban.DueDate = DateTime.Today;
-            kanban.Title = $"Form - {form.Description}";
-            kanban.Notes = new[] { "Created by desktop forms" };
-            kanban.Status = KanbanStatus.InProgress;
-            return kanban;
-        }
+    public static bool CanEditKanbanForm(KanbanForm form, Kanban kanban)
+    {
+        return kanban.EmployeeLink.ID == App.EmployeeID;
+    }
+    private static Kanban NewKanban(DigitalForm form)
+    {
+        var kanban = new Kanban();
+        kanban.EmployeeLink.ID = App.EmployeeID;
+        kanban.DueDate = DateTime.Today;
+        kanban.Title = $"Form - {form.Description}";
+        kanban.Notes = new[] { "Created by desktop forms" };
+        kanban.Status = KanbanStatus.InProgress;
+        return kanban;
+    }
 
-        private static void KanbanOnSave(KanbanForm form, Kanban entity)
+    private static void KanbanOnSave(KanbanForm form, Kanban entity)
+    {
+        var subscriber = new KanbanSubscriber
         {
-            var subscriber = new KanbanSubscriber
-            {
-                Assignee = true
-            };
-            subscriber.Kanban.ID = entity.ID;
-            subscriber.Employee.ID = entity.EmployeeLink.ID;
-            new Client<KanbanSubscriber>().Save(subscriber, "");
-        }
+            Assignee = true
+        };
+        subscriber.Kanban.ID = entity.ID;
+        subscriber.Employee.ID = entity.EmployeeLink.ID;
+        new Client<KanbanSubscriber>().Save(subscriber, "");
+    }
 
-        private static Columns<Kanban> RequiredKanbanColumns()
-        {
-            return Columns.None<Kanban>().Add(x => x.EmployeeLink.ID);
-        }
+    private static Columns<Kanban> RequiredKanbanColumns()
+    {
+        return Columns.None<Kanban>().Add(x => x.EmployeeLink.ID);
+    }
 
-        public static bool CanEditLeaveRequestForm(LeaveRequestForm form, LeaveRequest leaveRequest)
-        {
-            return leaveRequest.EmployeeLink.ID == App.EmployeeID;
-        }
+    public static bool CanEditLeaveRequestForm(LeaveRequestForm form, LeaveRequest leaveRequest)
+    {
+        return leaveRequest.EmployeeLink.ID == App.EmployeeID;
+    }
 
-        private static Columns<LeaveRequest> RequiredLeaveRequestColumns()
-        {
-            return Columns.None<LeaveRequest>().Add(x => x.EmployeeLink.ID);
-        }
+    private static Columns<LeaveRequest> RequiredLeaveRequestColumns()
+    {
+        return Columns.None<LeaveRequest>().Add(x => x.EmployeeLink.ID);
+    }
 
-        public static bool CanEditPurchaseOrderItemForm(PurchaseOrderItemForm form, PurchaseOrderItem purchaseOrderItem)
-        {
-            return false;
-        }
-        public static bool CanEditTimeSheetForm(TimeSheetForm form, TimeSheet timeSheet)
-        {
-            return timeSheet.EmployeeLink.ID == App.EmployeeID;
-        }
+    public static bool CanEditPurchaseOrderItemForm(PurchaseOrderItemForm form, PurchaseOrderItem purchaseOrderItem)
+    {
+        return false;
+    }
+    public static bool CanEditTimeSheetForm(TimeSheetForm form, TimeSheet timeSheet)
+    {
+        return timeSheet.EmployeeLink.ID == App.EmployeeID;
+    }
 
-        private static Columns<TimeSheet> RequiredTimeSheetColumns()
-        {
-            return Columns.None<TimeSheet>().Add(x => x.EmployeeLink.ID);
-        }
+    private static Columns<TimeSheet> RequiredTimeSheetColumns()
+    {
+        return Columns.None<TimeSheet>().Add(x => x.EmployeeLink.ID);
+    }
+
+    private static bool CanEditStagingSetoutForm(StagingSetoutForm form, StagingSetout entity)
+    {
+        return true;
     }
 }

+ 1 - 1
prs.shared/Database Update Scripts/Update_7_34.cs

@@ -374,7 +374,7 @@ namespace PRS.Shared
                 }
             }
 
-            DigitalForm.SerializeFormData(instance, variables, save);
+            DigitalForm.SerializeFormData(instance, save);
             
 
             return instance.IsChanged();