Переглянути джерело

Added Consignment Links to Supplier Bills

frogsoftware 1 рік тому
батько
коміт
346516c845

+ 30 - 2
prs.classes/Entities/Bill/BillLine.cs

@@ -37,10 +37,37 @@ namespace Comal.Classes
                 return new Columns<BillLine>(x => x.BillLink.SupplierLink.ID);
             }
         }
+        
         [LookupDefinition(typeof(PurchaseOrderItemLookup))]
         [EntityRelationship(DeleteAction.SetNull)]
         [EditorSequence(1)]
         public PurchaseOrderItemLink OrderItem { get; set; }
+        
+        
+        private class ConsignmentLookup : LookupDefinitionGenerator<Consignment, BillLine>
+        {
+            public override Filter<Consignment> DefineFilter(BillLine[] items)
+            {
+                if (!items.Any())
+                    return new Filter<Consignment>().None();
+                
+                var supplierID = items.Select(x => x.BillLink.SupplierLink.ID).Distinct().SingleOrDefault();
+                if(supplierID == Guid.Empty)
+                    return new Filter<Consignment>().None();
+                
+                return new Filter<Consignment>(x => x.Supplier.ID).IsEqualTo(supplierID)
+                    .And(x=>x.BillLine.ID).IsEqualTo(Guid.Empty);
+            }
+
+            public override Columns<BillLine> DefineFilterColumns()
+            {
+                return new Columns<BillLine>(x => x.BillLink.SupplierLink.ID);
+            }
+        }
+        
+        [LookupDefinition(typeof(ConsignmentLookup))]
+        [EntityRelationship(DeleteAction.SetNull)]
+        public ConsignmentLink Consignment { get; set; }
 
         private class ProductLookupGenerator : LookupDefinitionGenerator<Product, BillLine>
         {
@@ -73,13 +100,14 @@ namespace Comal.Classes
         public double TaxRate { get; set; }
 
         [CurrencyEditor(Summary = Summary.Sum)]
+        [EditorSequence(7)]
         public double Tax { get; set; }
 
         [CurrencyEditor(Summary = Summary.Sum)]
-        [EditorSequence(7)]
+        [EditorSequence(8)]
         public double IncTax { get; set; }
 
-        [EditorSequence(8)]
+        [EditorSequence(9)]
         public JobLink Job { get; set; }
 
         [NullEditor]

+ 4 - 0
prs.classes/Entities/Consignment/Consignment.cs

@@ -156,6 +156,10 @@ namespace Comal.Classes
         [EditorSequence(22)]
         [CurrencyEditor(Visible = Visible.Default, Summary = Summary.Sum)]
         public double IncTax { get; set; }
+        
+        [NullEditor]
+        [EntityRelationship(DeleteAction.SetNull)]
+        public BillLineLink BillLine { get; set; }
 
         static Consignment()
         {

+ 1 - 1
prs.classes/SecurityDescriptors/Mobile_Access.cs

@@ -92,7 +92,7 @@ namespace Comal.Classes.SecurityDescriptors
     public class ViewMobileQualificationsModule : EnabledSecurityDescriptor<MobileAccessLicence>
     { 
     }
-    [Caption("View MobileTimesheets Module")]
+    [Caption("View Mobile Timesheets Module")]
     public class ViewMobileTimesheetsModule : EnabledSecurityDescriptor<MobileAccessLicence>
     { 
     }

+ 280 - 42
prs.desktop/Panels/Suppliers/Bills/SupplierBillLineGrid.cs

@@ -1,8 +1,11 @@
 using System;
 using System.Collections.Generic;
+using System.Data;
+using System.Globalization;
 using System.Linq;
 using System.Windows;
 using System.Windows.Controls;
+using System.Windows.Data;
 using System.Windows.Media.Imaging;
 using Comal.Classes;
 using InABox.Clients;
@@ -21,7 +24,7 @@ public class SupplierBillLineGrid : DynamicOneToManyGrid<Bill, BillLine>
     public SupplierBillLineGrid()
     {
 
-        AddButton("Import", PRSDesktop.Resources.purchase.AsBitmapImage(), ImportPOLines);
+        AddButton("Import", PRSDesktop.Resources.purchase.AsBitmapImage(), ImportLines);
 
         HiddenColumns.Add(x => x.TaxCode.ID);
         HiddenColumns.Add(x => x.TaxCode.Code);
@@ -33,7 +36,11 @@ public class SupplierBillLineGrid : DynamicOneToManyGrid<Bill, BillLine>
         HiddenColumns.Add(x => x.IncTax);
         HiddenColumns.Add(x => x.Description);
         
+        HiddenColumns.Add(x=>x.Consignment.ID);
+        HiddenColumns.Add(x=>x.Consignment.Number);
+
         HiddenColumns.Add(x=>x.OrderItem.ID);
+        HiddenColumns.Add(x=>x.OrderItem.PurchaseOrderLink.ID);
         HiddenColumns.Add(x=>x.OrderItem.PurchaseOrderLink.PONumber);
         HiddenColumns.Add(x=>x.OrderItem.Product.Code);
         HiddenColumns.Add(x=>x.OrderItem.Description);
@@ -43,9 +50,121 @@ public class SupplierBillLineGrid : DynamicOneToManyGrid<Bill, BillLine>
         HiddenColumns.Add(x=>x.OrderItem.Tax);
         HiddenColumns.Add(x=>x.OrderItem.IncTax);
 
+        ActionColumns.Add(
+            new DynamicTextColumn(DisplayLinkText,DisplayLinkClick)
+            {
+                Position = DynamicActionColumnPosition.Start, 
+                Width = 50,
+                HeaderText = "Link",
+                ToolTip = DisplayLinkToolTip,
+                Alignment = Alignment.MiddleCenter
+            }
+        );
+        
         ActionColumns.Add(new DynamicImageColumn(pencil, BillLineEdit_Click));
     }
 
+    private object DisplayLinkText(CoreRow? row)
+    {
+        if (row == null)
+            return "";
+        var poid = row.Get<BillLine, Guid>(x => x.OrderItem.PurchaseOrderLink.ID);
+        var conid = row.Get<BillLine, Guid>(x => x.Consignment.ID);
+        return !Guid.Equals(poid,Guid.Empty) 
+            ? "PO"
+            : !Guid.Equals(conid,Guid.Empty)
+                ? "C"
+                : "--";
+    }
+
+    private bool DisplayLinkClick(CoreRow? row)
+    {
+        return false;
+    }
+    
+    private FrameworkElement? DisplayLinkToolTip(DynamicActionColumn column, CoreRow? row)
+    {
+        var text = !Guid.Equals(Guid.Empty, row?.Get<BillLine, Guid>(x => x.OrderItem.PurchaseOrderLink.ID) ?? Guid.Empty)
+            ? String.Format("PO {0}: {1:F2} x {2}",
+                row?.Get<BillLine, String>(x => x.OrderItem.PurchaseOrderLink.PONumber),
+                row?.Get<BillLine, double>(x => x.OrderItem.Qty),
+                row?.Get<BillLine, String>(x => x.OrderItem.Description)
+                )
+            : !Guid.Equals(Guid.Empty, row?.Get<BillLine, Guid>(x => x.Consignment.ID) ?? Guid.Empty)
+                ? String.Format("Cons. {0}: {1}",
+                    row?.Get<BillLine, String>(x => x.Consignment.Number),
+                    row?.Get<BillLine, String>(x => x.Consignment.Description)
+                )
+                : "";
+    
+        return String.IsNullOrWhiteSpace(text)
+            ? column.TextToolTip(text)
+            : null;
+    }
+
+    // private class BillLineConverter : IValueConverter
+    // {
+    //     public Func<CoreTable> Data { get; set; }
+    //
+    //     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+    //     {
+    //         if (value is null)
+    //             return value;
+    //         
+    //         var datarow = (value as DataRowView).Row;
+    //         var index = datarow.Table.Rows.IndexOf(datarow);
+    //         var row = Data().Rows[index];
+    //         
+
+    //     }
+    //
+    //     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+    //     {
+    //         throw new NotImplementedException();
+    //     }
+    // }
+    //
+    // private FrameworkElement DisplayLink()
+    // {
+    //     var button = new Button();
+    //     button.SetBinding(Button.ContentProperty, new Binding(".") { Converter = new BillLineConverter() { Data = () => Data} });
+    //     button.SetBinding(Button.DataContextProperty, new Binding("."));
+    //     button.Click += (sender, args) =>
+    //     {
+    //         var datarow = ((sender as Button)?.DataContext as DataRowView)?.Row;
+    //         if (datarow != null)
+    //         {
+    //             var index = datarow.Table.Rows.IndexOf(datarow);
+    //             var row = Data.Rows[index];
+    //
+    //             ContextMenu menu = new ContextMenu();
+    //             
+    //             var cons = new MenuItem() { Header = "Consignment" };
+    //             cons.Click += (o,e) => SelectConsignment(row);
+    //             menu.Items.Add(cons);
+    //             
+    //             var po = new MenuItem() { Header = "PO Item" };
+    //             po.Click += (o,e) => SelectPOItem(row);
+    //             menu.Items.Add(po);
+    //
+    //             menu.IsOpen = true;
+    //         }
+    //     };
+    //     
+    //     return button;
+    // }
+    //
+    // private void SelectPOItem(CoreRow row)
+    // {
+    //     if (ImportPOLines(row))
+    //         InvalidateRow(row);
+    // }
+    //
+    // private void SelectConsignment(CoreRow row)
+    // {
+    //     throw new NotImplementedException();
+    // }
+
     public override DynamicGridColumns GenerateColumns()
     {
         if (IsDirectEditMode())
@@ -107,8 +226,119 @@ public class SupplierBillLineGrid : DynamicOneToManyGrid<Bill, BillLine>
         }
         return false;
     }
+    
+    private bool ImportLines(Button button, CoreRow[] rows)
+    {
+        ContextMenu menu = new ContextMenu();
+        
+        var cons = new MenuItem() { Header = "Consignment" };
+        cons.Click += (o,e) => ImportConsignments();
+        menu.Items.Add(cons);
+        
+        var po = new MenuItem() { Header = "PO Item" };
+        po.Click += (o, e) => ImportPOLines();
+        menu.Items.Add(po);
+        
+        menu.IsOpen = true;
+        return false;
+    }
+
+    private void ImportConsignments()
+    {
+        var consignments = ExtractValues(x => x.Consignment.ID, Selection.All).ToArray();
+
+        var dlg = new MultiSelectDialog<Consignment>(
+            new Filter<Consignment>(x => x.Supplier.ID).IsEqualTo(Item.SupplierLink.ID)
+                .And(x => x.BillLine.ID).IsEqualTo(Guid.Empty)
+                .And(x => x.ID).NotInList(consignments),
+            new Columns<Consignment>(
+                x => x.ID));
+        if (dlg.ShowDialog() == true)
+        {
+            var imports = dlg.Data();
+            var consids = imports.ExtractValues<PurchaseOrderItem, Guid>(x => x.Consignment.ID).Distinct().ToArray();
+
+            var results = Client.QueryMultiple(
+                new KeyedQueryDef<Consignment>(
+                    new Filter<Consignment>(x => x.ID).InList(dlg.IDs()),
+                    new Columns<Consignment>(x => x.ID)
+                        .Add(x => x.Number)
+                        .Add(x => x.Description)
+                        .Add(x => x.TaxCode.ID)
+                        .Add(x => x.TaxCode.Code)
+                        .Add(x => x.TaxCode.Description)
+                        .Add(x => x.TaxCode.Rate)
+                        .Add(x => x.TaxRate)
+                        .Add(x => x.ExTax)
+                        .Add(x => x.Tax)
+                        .Add(x => x.IncTax)
+                        .Add(x => x.Created)),
+                new KeyedQueryDef<ConsignmentDocument>(
+                    new Filter<ConsignmentDocument>(x => x.EntityLink.ID).InList(consids),
+                    new Columns<ConsignmentDocument>(x => x.DocumentLink.ID)
+                        .Add(x => x.DocumentLink.FileName)
+                        .Add(x => x.Thumbnail)));
+
+            var items = results.Get<Consignment>();
+            
+            CreateItems(() =>
+            {
+                List<BillLine> lines = new List<BillLine>();
+                foreach (var row in items.Rows)
+                {
+                    var line = CreateItem();
+                    line.Consignment.ID = row.Get<Consignment, Guid>(x => x.ID);
+                    line.Consignment.Number = row.Get<Consignment, String>(x => x.Number);
+                    line.Consignment.Description = row.Get<Consignment, string>(x => x.Description);
+
+                    line.ExTax = row.Get<Consignment, double>(x => x.ExTax);
+                    line.TaxCode.ID = row.Get<Consignment, Guid>(x => x.TaxCode.ID);
+                    line.TaxCode.Code = row.Get<Consignment, string>(x => x.TaxCode.Code);
+                    line.TaxCode.Description = row.Get<Consignment, string>(x => x.TaxCode.Description);
+                    line.TaxCode.Rate = row.Get<Consignment, double>(x => x.TaxCode.Rate);
+                    line.TaxRate = row.Get<Consignment, double>(x => x.TaxRate);
+                    line.Tax = row.Get<Consignment, double>(x => x.Tax);
+                    line.IncTax = row.Get<Consignment, double>(x => x.IncTax);
 
-    private bool ImportPOLines(Button arg1, CoreRow[] arg2)
+                    line.Description =
+                        $"{row.Get<Consignment, string>(x => x.Number)} : {row.Get<Consignment, String>(x => x.Description)}";
+                    lines.Add(line);
+                }
+
+                return lines;
+            });
+            
+            
+            var docpage = EditorGrid.Pages.FirstOrDefault(x=>x is BillDocumentGrid) as BillDocumentGrid;
+            if (!docpage.Ready)
+                docpage.Load(Item,null);
+            
+            if (docpage != null)
+            {
+                var docIDs = docpage.Data.ExtractValues<BillDocument, Guid>(x => x.DocumentLink.ID).ToHashSet();
+                foreach(var eDoc in results.GetObjects<ConsignmentDocument>())
+                {
+                    if (!docIDs.Contains(eDoc.DocumentLink.ID))
+                    {
+                        var doc = new BillDocument();
+                        doc.EntityLink.ID = Item.ID;
+                        doc.DocumentLink.ID = eDoc.DocumentLink.ID;
+                        doc.DocumentLink.FileName = eDoc.DocumentLink.FileName;
+                        doc.Thumbnail = eDoc.Thumbnail;
+                        docpage.SaveItem(doc);
+                        docIDs.Add(eDoc.DocumentLink.ID);
+                    }
+                }
+
+                docpage.Refresh(false,true);
+            }
+            DoChanged();
+            Refresh(false,false);
+        }
+        
+    }
+    
+    private void ImportPOLines()
     {
         var poItems = ExtractValues(x => x.OrderItem.ID, Selection.All).ToArray();
 
@@ -161,45 +391,53 @@ public class SupplierBillLineGrid : DynamicOneToManyGrid<Bill, BillLine>
                         .Add(x => x.Thumbnail)));
             
             var items = results.Get<PurchaseOrderItem>();
-            foreach (var row in items.Rows)
+            CreateItems(() =>
             {
-                var line = CreateItem();
-
-                line.OrderItem.ID = row.Get<PurchaseOrderItem, Guid>(x => x.ID);
-                line.OrderItem.PurchaseOrderLink.ID = row.Get<PurchaseOrderItem, Guid>(x => x.PurchaseOrderLink.ID);
-                line.OrderItem.PurchaseOrderLink.PONumber = row.Get<PurchaseOrderItem, String>(x => x.PurchaseOrderLink.PONumber);
-
-                line.OrderItem.Product.ID = row.Get<PurchaseOrderItem, Guid>(x => x.Product.ID);
-                line.OrderItem.Product.Code = row.Get<PurchaseOrderItem, string>(x => x.Product.Code);
-                line.OrderItem.Product.Name = row.Get<PurchaseOrderItem, string>(x => x.Product.Name);
-                
-                line.OrderItem.Description = row.Get<PurchaseOrderItem, string>(x => x.Description);
-                line.OrderItem.Qty = row.Get<PurchaseOrderItem, double>(x => x.Qty);
-                line.OrderItem.ExTax = row.Get<PurchaseOrderItem, double>(x => x.ExTax);
-                line.OrderItem.TaxCode.ID = row.Get<PurchaseOrderItem, Guid>(x => x.TaxCode.ID);
-                line.OrderItem.TaxCode.Code = row.Get<PurchaseOrderItem, string>(x => x.TaxCode.Code);
-                line.OrderItem.TaxCode.Description = row.Get<PurchaseOrderItem, string>(x => x.TaxCode.Description);
-                line.OrderItem.TaxCode.Rate = row.Get<PurchaseOrderItem, double>(x => x.TaxCode.Rate);
-                line.OrderItem.PurchaseGL.ID = row.Get<PurchaseOrderItem, Guid>(x => x.PurchaseGL.ID);
-                line.OrderItem.CostCentre.ID = row.Get<PurchaseOrderItem, Guid>(x => x.CostCentre.ID);
-                
-                line.ExTax = row.Get<PurchaseOrderItem, double>(x => x.ExTax);
-                line.TaxCode.ID = row.Get<PurchaseOrderItem, Guid>(x => x.TaxCode.ID);
-                line.TaxCode.Code = row.Get<PurchaseOrderItem, string>(x => x.TaxCode.Code);
-                line.TaxCode.Description = row.Get<PurchaseOrderItem, string>(x => x.TaxCode.Description);
-                line.TaxCode.Rate = row.Get<PurchaseOrderItem, double>(x => x.TaxCode.Rate);
-                line.TaxRate = row.Get<PurchaseOrderItem, double>(x => x.TaxRate);                    
-                line.Tax = row.Get<PurchaseOrderItem, double>(x => x.Tax);
-                line.IncTax = row.Get<PurchaseOrderItem, double>(x => x.IncTax);
-                line.PurchaseGL.ID = row.Get<PurchaseOrderItem, Guid>(x => x.PurchaseGL.ID);
-                line.CostCentre.ID = row.Get<PurchaseOrderItem, Guid>(x => x.CostCentre.ID);
-                
-                
-                Items.Add(line);
-            }
+                List<BillLine> lines = new List<BillLine>();
+                foreach (var row in items.Rows)
+                {
+
+                    var line = CreateItem();
+
+                    line.OrderItem.ID = row.Get<PurchaseOrderItem, Guid>(x => x.ID);
+                    line.OrderItem.PurchaseOrderLink.ID = row.Get<PurchaseOrderItem, Guid>(x => x.PurchaseOrderLink.ID);
+                    line.OrderItem.PurchaseOrderLink.PONumber =
+                        row.Get<PurchaseOrderItem, String>(x => x.PurchaseOrderLink.PONumber);
+
+                    line.OrderItem.Product.ID = row.Get<PurchaseOrderItem, Guid>(x => x.Product.ID);
+                    line.OrderItem.Product.Code = row.Get<PurchaseOrderItem, string>(x => x.Product.Code);
+                    line.OrderItem.Product.Name = row.Get<PurchaseOrderItem, string>(x => x.Product.Name);
+
+                    line.OrderItem.Description = row.Get<PurchaseOrderItem, string>(x => x.Description);
+                    line.OrderItem.Qty = row.Get<PurchaseOrderItem, double>(x => x.Qty);
+                    line.OrderItem.ExTax = row.Get<PurchaseOrderItem, double>(x => x.ExTax);
+                    line.OrderItem.TaxCode.ID = row.Get<PurchaseOrderItem, Guid>(x => x.TaxCode.ID);
+                    line.OrderItem.TaxCode.Code = row.Get<PurchaseOrderItem, string>(x => x.TaxCode.Code);
+                    line.OrderItem.TaxCode.Description = row.Get<PurchaseOrderItem, string>(x => x.TaxCode.Description);
+                    line.OrderItem.TaxCode.Rate = row.Get<PurchaseOrderItem, double>(x => x.TaxCode.Rate);
+                    line.OrderItem.PurchaseGL.ID = row.Get<PurchaseOrderItem, Guid>(x => x.PurchaseGL.ID);
+                    line.OrderItem.CostCentre.ID = row.Get<PurchaseOrderItem, Guid>(x => x.CostCentre.ID);
+
+                    line.ExTax = row.Get<PurchaseOrderItem, double>(x => x.ExTax);
+                    line.TaxCode.ID = row.Get<PurchaseOrderItem, Guid>(x => x.TaxCode.ID);
+                    line.TaxCode.Code = row.Get<PurchaseOrderItem, string>(x => x.TaxCode.Code);
+                    line.TaxCode.Description = row.Get<PurchaseOrderItem, string>(x => x.TaxCode.Description);
+                    line.TaxCode.Rate = row.Get<PurchaseOrderItem, double>(x => x.TaxCode.Rate);
+                    line.TaxRate = row.Get<PurchaseOrderItem, double>(x => x.TaxRate);
+                    line.Tax = row.Get<PurchaseOrderItem, double>(x => x.Tax);
+                    line.IncTax = row.Get<PurchaseOrderItem, double>(x => x.IncTax);
+                    line.PurchaseGL.ID = row.Get<PurchaseOrderItem, Guid>(x => x.PurchaseGL.ID);
+                    line.CostCentre.ID = row.Get<PurchaseOrderItem, Guid>(x => x.CostCentre.ID);
+                    var description = row.Get<PurchaseOrderItem, String>(x => x.Description);
+                    if (String.IsNullOrWhiteSpace(description))
+                        description = row.Get<PurchaseOrderItem, String>(x => x.Product.Name);
+                    line.Description = $"{row.Get<PurchaseOrderItem, double>(x => x.Qty):F2} x {description}";
+
+                    lines.Add(line);
+                }
+                return lines;
+            });
 
-            
-            
             var docpage = EditorGrid.Pages.FirstOrDefault(x=>x is BillDocumentGrid) as BillDocumentGrid;
             if (!docpage.Ready)
                 docpage.Load(Item,null);
@@ -208,7 +446,7 @@ public class SupplierBillLineGrid : DynamicOneToManyGrid<Bill, BillLine>
             {
                 var docIDs = docpage.Data.ExtractValues<BillDocument, Guid>(x => x.DocumentLink.ID).ToHashSet();
                 foreach(var eDoc in (results.GetObjects<PurchaseOrderDocument>() as IEnumerable<IEntityDocument>)
-                    .Concat(results.GetObjects<ConsignmentDocument>()))
+                        .Concat(results.GetObjects<ConsignmentDocument>()))
                 {
                     if (!docIDs.Contains(eDoc.DocumentLink.ID))
                     {
@@ -225,9 +463,9 @@ public class SupplierBillLineGrid : DynamicOneToManyGrid<Bill, BillLine>
                 docpage.Refresh(false,true);
             }
             DoChanged();
-            return true;
+            Refresh(false,false);
         }
-        return false;
+        
     }
 
     protected override void HandleDragOver(object sender, DragEventArgs e)