Sfoglia il codice sorgente

Merge commit '5fabe0dd5382e23f3285ece30c76419de597fb6f' into frank

Frank van den Bos 1 anno fa
parent
commit
7bd0075e44

+ 1 - 1
prs.classes/Entities/Setout/SetoutDocument.cs

@@ -3,7 +3,7 @@
 namespace Comal.Classes
 {
     [UserTracking(typeof(ManufacturingPacket))]
-    public class SetoutDocument : EntityDocument<SetoutLink>, IManyToMany<Setout, Document>, ILicense<ManufacturingLicense>
+    public class SetoutDocument : EntityDocument<SetoutLink>, ILicense<ManufacturingLicense>
     {
     }
 }

+ 8 - 0
prs.classes/Entities/Setout/SetoutLink.cs

@@ -30,5 +30,13 @@ namespace Comal.Classes
 
         [NullEditor]
         public JobLink JobLink { get; set; }
+
+        public SetoutGroupLink Group { get; set; }
+
+        protected override void Init()
+        {
+            Group = new SetoutGroupLink();
+            base.Init();
+        }
     }
 }

+ 3 - 1
prs.desktop/Panels/Factory/FactoryPanel.xaml.cs

@@ -2139,6 +2139,7 @@ namespace PRSDesktop
             var estimateddate = packet.Get<ManufacturingPacket, DateTime>(c => c.EstimatedDate);
             var distributed = packet.Get<ManufacturingPacket, bool>(c => c.Distributed);
             var packetsection = packet.Get<ManufacturingPacket, string>(c => c.StageLink.Section);
+            var groupid = packet.Get<ManufacturingPacket, Guid>(c => c.SetoutLink.Group.ID);
 
             model.TemplateID = packet.Get<ManufacturingPacket, Guid>(c => c.ManufacturingTemplateLink.ID);
 
@@ -2154,7 +2155,7 @@ namespace PRSDesktop
             model.Quantity = barcodes;
             model.JobName = string.Format("{0}: {1}", setoutnumber, jobname);
             model.DueDate = duedate;
-
+            model.GroupID = groupid;
 
             var descrip = new List<string>
             {
@@ -2307,6 +2308,7 @@ namespace PRSDesktop
                         .Add(x => x.SetoutLink.Number)
                         .Add(x => x.SetoutLink.JobLink.JobNumber)
                         .Add(x => x.SetoutLink.JobLink.Name)
+                        .Add(x => x.SetoutLink.Group.ID)
                         .Add(x => x.DueDate)
                         .Add(x => x.SetoutLink.Location)
                         //.Add(x => x.SetoutLink.Reference)

+ 5 - 0
prs.desktop/Panels/Jobs/JobDesignDocumentGrid.cs

@@ -25,6 +25,11 @@ namespace PRSDesktop
                 PRSDesktop.Resources.tick.AsBitmapImage(),
                 SupercedeDocument
             ));
+            Options.Remove(DynamicGridOption.AddRows);
+            Options.Remove(DynamicGridOption.DeleteRows);
+            Options.Remove(DynamicGridOption.ImportData);
+            Options.Remove(DynamicGridOption.ExportData);
+            Options.Remove(DynamicGridOption.EditRows);
         }
 
         public Guid SetoutID { get; set; }

+ 2 - 1
prs.desktop/Panels/Manufacturing/ManufacturingAllocationPanel.xaml.cs

@@ -151,6 +151,7 @@ namespace PRSDesktop
                 var barqty = row.Get<ManufacturingPacket, int>(c => c.BarcodeQty);
                 var duedate = row.Get<ManufacturingPacket, DateTime>(c => c.DueDate);
                 var estdate = row.Get<ManufacturingPacket, DateTime>(c => c.EstimatedDate);
+                
 
                 var sectionid = row.Get<ManufacturingPacket, Guid>(c => c.StageLink.SectionID);
                 var pktsection = row.Get<ManufacturingPacket, string>(c => c.StageLink.Section);
@@ -217,7 +218,7 @@ namespace PRSDesktop
                 model.Flags = row.Get<ManufacturingPacket, bool>(c => c.Distributed)
                     ? !sectionid.Equals(section) ? string.IsNullOrEmpty(pktsection) ? "" : pktsection.ToUpper().Trim() : "DISTRIB"
                     : "";
-
+                model.GroupID = row.Get<ManufacturingPacket, Guid>(c => c.SetoutLink.Group.ID);
 
                 Kanbans.Add(model);
             }

+ 1 - 0
prs.desktop/Panels/Manufacturing/ManufacturingKanban.cs

@@ -29,6 +29,7 @@ namespace PRSDesktop
         public string Issues { get; set; }
         public BitmapImage IssuesImage { get; set; }
         public Guid TemplateID { get; set; }
+        public Guid GroupID { get; set; }
     }
 }
 

+ 2 - 0
prs.desktop/Panels/Manufacturing/ManufacturingPanel.xaml.cs

@@ -725,6 +725,7 @@ namespace PRSDesktop
             columns.Add(x => x.SetoutLink.Description);
             columns.Add(x => x.SetoutLink.Location);
             columns.Add(x => x.SetoutLink.JobLink.ID);
+            columns.Add(x => x.SetoutLink.Group.ID);
 
             columns.Add(x => x.OrderItem.ID);
             //columns.Add(x => x.OrderItem.ReceivedDate);
@@ -742,6 +743,7 @@ namespace PRSDesktop
             columns.Add(x => x.StageLink.Time);
             columns.Add(x => x.StageLink.PercentageComplete);
             columns.Add(x => x.StageLink.Deleted);
+            
             return columns;
         }
 

+ 1 - 0
prs.desktop/Panels/Manufacturing/ManufacturingPanelColumn.xaml

@@ -109,6 +109,7 @@
                         <Separator x:Name="ViewSetoutSeparator" />
 
                         <MenuItem x:Name="IssueSetout" Header="Issue Item" Click="IssueSetout_Click" Tag="{Binding}" />
+                        <MenuItem x:Name="IssueGroup" Header="Issue Cutting Group" Click="IssueGroup_Click" Tag="{Binding}" />
                         <MenuItem x:Name="ProgressSetout" Header="Progress Item" Click="ProgressSetout_Click"
                                   Tag="{Binding}" />
                         <MenuItem x:Name="SplitSetout" Header="Split Manufacturing" Click="SplitSetout_Click"

+ 56 - 29
prs.desktop/Panels/Manufacturing/ManufacturingPanelColumn.xaml.cs

@@ -224,6 +224,8 @@ namespace PRSDesktop
                 var templateid = packet.ManufacturingTemplateLink.ID;
                 var templatecode = Data.Templates.FirstOrDefault(x => x.ID.Equals(templateid))?.Code;
 
+                var groupid = packet.SetoutLink.Group.ID;
+
                 if (bOK)
                 {
                     var id = packet.ID;
@@ -341,6 +343,8 @@ namespace PRSDesktop
 
                     model.Template = templatecode;
 
+                    model.GroupID = groupid;
+
 
                     if (!stageValid || stageid.Equals(Guid.Empty) || stageid.Equals(CoreUtils.FullGuid))
                     {
@@ -421,42 +425,43 @@ namespace PRSDesktop
             var menu = sender as ContextMenu;
 
             var issue = menu.Items[2] as MenuItem;
-            var progress = menu.Items[3] as MenuItem;
-            var split = menu.Items[4] as MenuItem;
-            var revert = menu.Items[5] as MenuItem;
-            var progress_separator = menu.Items[6] as Separator;
-
-            var cancel = menu.Items[7] as MenuItem;
-            var cancel_separator = menu.Items[8] as Separator;
+            var issuegroup = menu.Items[3] as MenuItem;
+            var progress = menu.Items[4] as MenuItem;
+            var split = menu.Items[5] as MenuItem;
+            var revert = menu.Items[6] as MenuItem;
+            var progress_separator = menu.Items[7] as Separator;
+
+            var cancel = menu.Items[8] as MenuItem;
+            var cancel_separator = menu.Items[9] as Separator;
             var bHasCancel = false;
 
-            var complete = menu.Items[9] as MenuItem;
-            var complete_separator = menu.Items[10] as Separator;
+            var complete = menu.Items[10] as MenuItem;
+            var complete_separator = menu.Items[11] as Separator;
             var bHasComplete = false;
 
-            var template = menu.Items[11] as MenuItem;
-            var template_separator = menu.Items[12] as Separator;
+            var template = menu.Items[12] as MenuItem;
+            var template_separator = menu.Items[13] as Separator;
             var bHasTemplate = true;
 
-            var changedate = menu.Items[13] as MenuItem;
-            var changedate_separator = menu.Items[14] as Separator;
+            var changedate = menu.Items[14] as MenuItem;
+            var changedate_separator = menu.Items[15] as Separator;
 
-            var setpriority = menu.Items[15] as MenuItem;
-            var clearpriority = menu.Items[16] as MenuItem;
-            var priority_separator = menu.Items[17] as Separator;
+            var setpriority = menu.Items[16] as MenuItem;
+            var clearpriority = menu.Items[17] as MenuItem;
+            var priority_separator = menu.Items[18] as Separator;
 
-            var editissues = menu.Items[18] as MenuItem;
-            var sethold = menu.Items[19] as MenuItem;
-            var clearhold = menu.Items[20] as MenuItem;
-            var hold_separator = menu.Items[21] as Separator;
+            var editissues = menu.Items[19] as MenuItem;
+            var sethold = menu.Items[20] as MenuItem;
+            var clearhold = menu.Items[21] as MenuItem;
+            var hold_separator = menu.Items[22] as Separator;
 
-            var generate = menu.Items[22] as MenuItem;
-            var reprint = menu.Items[23] as MenuItem;
-            var revoke = menu.Items[24] as MenuItem;
-            var barcode_separator = menu.Items[25] as Separator;
+            var generate = menu.Items[23] as MenuItem;
+            var reprint = menu.Items[24] as MenuItem;
+            var revoke = menu.Items[25] as MenuItem;
+            var barcode_separator = menu.Items[26] as Separator;
             var bHasBarcode = false;
 
-            var archive = menu.Items[26] as MenuItem;
+            var archive = menu.Items[27] as MenuItem;
             var bHasArchive = false;
 
             var model = menu.Tag as ManufacturingKanban;
@@ -483,6 +488,7 @@ namespace PRSDesktop
                 current != null ? current.BarcodeType : BarcodeType.None; // row.Get<ManufacturingPacket, BarcodeType>(x => x.BarcodeType);
 
             issue.Visibility = !stageValid && Security.IsAllowed<CanIssuePackets>() ? Visibility.Visible : Visibility.Collapsed;
+            issuegroup.Visibility = !stageValid && Security.IsAllowed<CanIssuePackets>() ? Visibility.Visible : Visibility.Collapsed;
             progress.Visibility = stageid.Equals(CoreUtils.FullGuid) || !stageValid ? Visibility.Collapsed : Visibility.Visible;
             split.Visibility = !stageValid && qty > 1 && printed.IsEmpty() && OnlyOne ? Visibility.Visible : Visibility.Collapsed;
             revert.Visibility = !stageValid && completed.Equals(DateTime.MinValue) ? Visibility.Collapsed : Visibility.Visible;
@@ -694,20 +700,35 @@ namespace PRSDesktop
 
             var date = model.DueDate.IsEmpty() ? DateTime.Today.AddDays(14) : model.DueDate;
             if (DateEdit.Execute("Required Completion Date", ref date))
-                ProgressPacket(model, date);
+                ProgressPacket(model, date, Guid.Empty);
+        }
+
+        private void IssueGroup_Click(object sender, RoutedEventArgs e)
+        {
+            var item = (MenuItem)sender;
+            var model = (ManufacturingKanban)item.Tag;
+
+            var date = model.DueDate.IsEmpty() ? DateTime.Today.AddDays(14) : model.DueDate;
+            if (DateEdit.Execute("Required Completion Date", ref date))
+                ProgressPacket(model, date, model.GroupID);
         }
 
         private void ProgressSetout_Click(object sender, RoutedEventArgs e)
         {
             var item = (MenuItem)sender;
             var model = (ManufacturingKanban)item.Tag;
-            ProgressPacket(model, null);
+            ProgressPacket(model, null, Guid.Empty);
         }
 
-        private void ProgressPacket(ManufacturingKanban model, DateTime? date)
+        private void ProgressPacket(ManufacturingKanban model, DateTime? date, Guid groupID)
         {
             Progress.Show("");
-            var pkts = GetSelectedPackets(model.ID).ToList();
+            var pkts = groupID == Guid.Empty ? 
+                GetSelectedPackets(model.ID).ToList() 
+                : GetPacketsOfGroup(groupID);
+
+            if (pkts.Count == 0)
+                return;
 
             Progress.SetMessage("Loading Stages");
             Filter<ManufacturingPacketStage>? stgflt = null;
@@ -743,6 +764,11 @@ namespace PRSDesktop
             OnChanged?.Invoke(this, new EventArgs());
         }
 
+        private List<ManufacturingPacket> GetPacketsOfGroup(Guid groupID)
+        {
+            return Packets.Where(x => x.SetoutLink.Group.ID == groupID).ToList();
+        }
+
         private void SplitSetout_Click(object sender, RoutedEventArgs e)
         {
             var item = (MenuItem)sender;
@@ -1232,5 +1258,6 @@ namespace PRSDesktop
 
             }
         }
+
     }
 }

+ 3 - 1
prs.desktop/Panels/Staging/Setouts/StagingSetoutGrid.cs

@@ -166,7 +166,9 @@ namespace PRSDesktop
         {
             var job = _jobs.FirstOrDefault(x => x.JobNumber.Equals(filePreFix.Substring(0,4)));
             if (job == null)  
-                job = _jobs.FirstOrDefault(x => x.JobNumber.Equals(filePreFix.Substring(0, 5)));           
+                job = _jobs.FirstOrDefault(x => x.JobNumber.Equals(filePreFix.Substring(0, 5)));
+            if (job == null)
+                job = _jobs.FirstOrDefault(x => x.JobNumber.Equals(filePreFix.Substring(0, 6)));
             if (job == null)
                 return Guid.Empty;
 

+ 53 - 23
prs.desktop/Panels/Staging/StagingPanel.xaml.cs

@@ -38,6 +38,8 @@ namespace PRSDesktop
 
         StagingSetout _item = new StagingSetout();
 
+        List<StagingSetout> _items = new List<StagingSetout>();
+
         DynamicDataGrid<Document> _materialDocs;
         public StagingPanel()
         {
@@ -47,22 +49,49 @@ namespace PRSDesktop
 
         private void DocumentPreviewer_OnApproved(IEntityDocument stagingsetoutdocument)
         {
-            if (_item.Group.ID == Guid.Empty)
+            string message = "";
+
+            foreach (var item in _items)
+            {
+                var returnstring = ApproveSetout(item);
+                if (!string.IsNullOrWhiteSpace(returnstring))
+                    message = message + returnstring + Environment.NewLine;
+
+            }
+
+            foreach (var item in _items)
+                DeleteAndRefresh(item);
+
+            MessageBox.Show(message);
+        }
+
+        private string ApproveSetout(StagingSetout item)
+        {
+            if (item.Group.ID == Guid.Empty)
             {
                 var message = "Setout has no group assigned";
                 if (Security.IsAllowed<CanApproveSetoutsWithoutGroup>())
                 {
                     if (MessageBox.Show(message + ", continue?", "Continue?", MessageBoxButton.OKCancel) != MessageBoxResult.OK)
-                        return;
+                        return "";
                 }
                 else
                 {
                     MessageBox.Show(message + ", please assign a group!");
-                    return;
+                    return "";
                 }
             }
 
-            var table = new Client<Setout>().Query(new Filter<Setout>(x => x.Number).IsEqualTo(_item.Number),
+            var setoutdoctable = new Client<StagingSetoutDocument>().Query(
+                new Filter<StagingSetoutDocument>(x => x.EntityLink.ID).IsEqualTo(item.ID),
+                new Columns<StagingSetoutDocument>(x => x.ID, x => x.DocumentLink.ID, x => x.DocumentLink.FileName));
+
+            if (!setoutdoctable.Rows.Any())
+                return "";
+
+            var stagingsetoutdocument = setoutdoctable.Rows.FirstOrDefault().ToObject<SetoutDocument>();
+
+            var table = new Client<Setout>().Query(new Filter<Setout>(x => x.Number).IsEqualTo(item.Number),
                 new Columns<Setout>(x => x.ID));
 
             var setout = new Setout();
@@ -70,13 +99,13 @@ namespace PRSDesktop
             if (table.Rows.Any())
             {
                 if (MessageBox.Show("Supercede existing documents?", "Proceed?", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
-                    return;
+                    return "";
 
                 setout = table.Rows.FirstOrDefault().ToObject<Setout>();
 
-                setout.Group.ID = _item.Group.ID;
+                setout.Group.ID = item.Group.ID;
 
-                _item.Setout.ID = setout.ID;
+                item.Setout.ID = setout.ID;
 
                 var setoutdoc = new SetoutDocument();
                 setoutdoc.EntityLink.ID = setout.ID;
@@ -89,7 +118,7 @@ namespace PRSDesktop
 
                 CoreTable oldDocsTable = new Client<SetoutDocument>().Query(
                     new Filter<SetoutDocument>(x => x.EntityLink.ID).IsEqualTo(setout.ID)
-                    .And(x => x.DocumentLink.ID).IsNotEqualTo(_item.Group.OptimizationDocument.ID)
+                    .And(x => x.DocumentLink.ID).IsNotEqualTo(item.Group.OptimizationDocument.ID)
                     );
                 foreach (var row in oldDocsTable.Rows)
                 {
@@ -103,39 +132,35 @@ namespace PRSDesktop
                 new Client<SetoutDocument>().Save(setoutdocs, "Updated from Staging Screen");
                 new Client<Setout>().Save(setout, "Updated from Staging Screen");
 
-                MessageBox.Show("Documents for setout " + _item.Number + " superceded.", "Success");
-
-                DeleteAndRefresh(stagingsetoutdocument);
+                return item.Number + " Superceded";
             }
 
             //no setout for this pdf - create new
             else
             {
-                setout.Number = _item.Number;
-                setout.JobLink.ID = _item.JobLink.ID;
-                setout.Group.ID = _item.Group.ID;
+                setout.Number = item.Number;
+                setout.JobLink.ID = item.JobLink.ID;
+                setout.Group.ID = item.Group.ID;
 
                 var editor = new DynamicDataGrid<Setout>();
                 editor.OnAfterSave += (editor, items) =>
                 {
-                    _item.Setout.ID = setout.ID;
+                    item.Setout.ID = setout.ID;
 
                     var setoutdoc = new SetoutDocument();
                     setoutdoc.EntityLink.ID = setout.ID;
                     setoutdoc.DocumentLink.ID = stagingsetoutdocument.DocumentLink.ID;
 
                     new Client<SetoutDocument>().Save(setoutdoc, "Added from staging screen");
-
-                    MessageBox.Show("Setout created for document " + _item.Number, "Success");
-
-                    DeleteAndRefresh(stagingsetoutdocument);
                 };
 
                 if (!editor.EditItems(new[] { setout }))
                 {
                     MessageBox.Show("Setout Creation Cancelled");
-                    return;
+                    return "";
                 }
+                else
+                    return item.Number + " Created";
             }
 
             //currently not creating packets due to temporary change in requirements - to uncomment and check for validity when required
@@ -254,9 +279,9 @@ namespace PRSDesktop
             return stages;
         }
 
-        private void DeleteAndRefresh(IEntityDocument stagingsetoutdocument)
+        private void DeleteAndRefresh(StagingSetout item)
         {
-            new Client<StagingSetout>().Save(_item, "Updated from staging screen");
+            new Client<StagingSetout>().Save(item, "Updated from staging screen");
             _item = new StagingSetout();
 
             documentPreviewer.Document = new StagingSetoutDocument();
@@ -302,6 +327,11 @@ namespace PRSDesktop
 
         private void StagingSetoutGrid_OnSelectItem(object sender, InABox.DynamicGrid.DynamicGridSelectionEventArgs e)
         {
+            _items.Clear();
+
+            foreach (var row in stagingSetoutGrid.SelectedRows)
+                _items.Add(row.ToObject<StagingSetout>());
+
             _item = stagingSetoutGrid.SelectedRows.FirstOrDefault().ToObject<StagingSetout>();
 
             var doc = new Client<StagingSetoutDocument>().Query(
@@ -377,7 +407,7 @@ namespace PRSDesktop
         public void Refresh()
         {
             //stagingSetoutGrid.ScanFiles(_settings.SetoutsFolder);
-            stagingSetoutGrid.Refresh(false, true);        
+            stagingSetoutGrid.Refresh(false, true);
 
             manufacturingControl.StagingSetout = new StagingSetout();
             manufacturingControl.Refresh();

+ 1 - 1
prs.desktop/prsdesktop.iss

@@ -5,7 +5,7 @@
 #pragma verboselevel 9
 
 #define MyAppName "PRS Desktop"
-#define MyAppVersion "7.23"
+#define MyAppVersion "7.23b"
 #define MyAppPublisher "PRS Digital"
 #define MyAppURL "https://www.prs-software.com.au"
 #define MyAppExeName "PRSDesktop.exe"

+ 1 - 1
prs.mobile.new/PRS.Mobile.Droid/Properties/AndroidManifest.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="102120" android:versionName="1.02.12" package="comal.timesheets.Android">
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="103100" android:versionName="1.03.1" package="comal.timesheets.Android">
 	<uses-sdk android:minSdkVersion="29" android:targetSdkVersion="33" />
 	<queries>
 		<intent>

+ 1 - 1
prs.mobile.new/PRS.Mobile.iOS/Info.plist

@@ -27,7 +27,7 @@
 	<key>CFBundleIdentifier</key>
 	<string>com.prsdigital.prssiteapp</string>
 	<key>CFBundleVersion</key>
-	<string>1.02.12</string>
+	<string>1.03.1</string>
 	<key>UILaunchStoryboardName</key>
 	<string>LaunchScreen</string>
 	<key>CFBundleName</key>

+ 1 - 1
prs.server/PRSServer.iss

@@ -5,7 +5,7 @@
 #pragma verboselevel 9
 
 #define MyAppName "PRS Server"
-#define MyAppVersion "7.23"
+#define MyAppVersion "7.23b"
 #define MyAppPublisher "PRS Digital"
 #define MyAppURL "https://www.prs-software.com.au"
 #define MyAppExeName "PRSServer.exe"

+ 23 - 18
prs.stores/SetoutStore.cs

@@ -16,28 +16,33 @@ namespace Comal.Stores
         {
             if (entity.Group.ID != Guid.Empty)
             {
-                var table = Provider.Query<SetoutGroup>(new Filter<SetoutGroup>(x => x.ID).IsEqualTo(entity.Group.ID),
+                var table = Provider.Query<SetoutGroup>(new Filter<SetoutGroup>(x => x.ID).IsEqualTo(entity.Group.ID)
+                    .And(x => x.OptimizationDocument.ID).IsNotEqualTo(Guid.Empty),
                     new Columns<SetoutGroup>(x => x.OptimizationDocument.ID));
-                if (table.Rows.Any())
-                {
-                    var docID = table.Rows.FirstOrDefault().Get<SetoutGroup, Guid>(x => x.OptimizationDocument.ID);
-                    List<Guid> ids = new List<Guid>();
-                    var docsTable = Provider.Query<SetoutDocument>(
-                        new Filter<SetoutDocument>(x => x.EntityLink.ID).IsEqualTo(entity.ID),
-                        new Columns<SetoutDocument>(x => x.DocumentLink.ID)
-                        );
-                    foreach (var row in docsTable.Rows)
-                        ids.Add(row.Get<SetoutDocument, Guid>(x => x.DocumentLink.ID));
+                if (!table.Rows.Any())
+                    return;
+
+                var docID = table.Rows.FirstOrDefault().Get<SetoutGroup, Guid>(x => x.OptimizationDocument.ID);
+                if (docID == Guid.Empty)
+                    return;
 
-                    if (!ids.Contains(docID))
-                    {
-                        var setoutdoc = new SetoutDocument();
-                        setoutdoc.EntityLink.ID = entity.ID;
-                        setoutdoc.DocumentLink.ID = docID;
+                List<Guid> ids = new List<Guid>();
+                var docsTable = Provider.Query<SetoutDocument>(
+                    new Filter<SetoutDocument>(x => x.EntityLink.ID).IsEqualTo(entity.ID),
+                    new Columns<SetoutDocument>(x => x.DocumentLink.ID)
+                    );
+                foreach (var row in docsTable.Rows)
+                    ids.Add(row.Get<SetoutDocument, Guid>(x => x.DocumentLink.ID));
 
-                        FindSubStore<SetoutDocument>().Save(setoutdoc, "Added optimsation document from Group");
-                    }
+                if (!ids.Contains(docID))
+                {
+                    var setoutdoc = new SetoutDocument();
+                    setoutdoc.EntityLink.ID = entity.ID;
+                    setoutdoc.DocumentLink.ID = docID;
+
+                    FindSubStore<SetoutDocument>().Save(setoutdoc, "Added optimsation document from Group");
                 }
+
             }
             base.AfterSave(entity);
         }