Selaa lähdekoodia

QuickPick Module now allows negative quantities, as well as the ability to add items not currently in a scanned location

Frank van den Bos 7 kuukautta sitten
vanhempi
commit
fdbf6cd052

+ 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="824300" android:versionName="8.24.3" package="comal.timesheets.Android">
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="825000" android:versionName="8.25.0" package="comal.timesheets.Android">
 	<uses-sdk android:minSdkVersion="28" android:targetSdkVersion="34" />
 	<queries>
 		<intent>

+ 1 - 0
prs.mobile.new/PRS.Mobile.Droid/Resources/Resource.designer.cs

@@ -2,6 +2,7 @@
 //------------------------------------------------------------------------------
 // <auto-generated>
 //     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
 //
 //     Changes to this file may cause incorrect behavior and will be lost if
 //     the code is regenerated.

+ 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>8.24.3</string>
+	<string>8.25.0</string>
 	<key>UILaunchStoryboardName</key>
 	<string>LaunchScreen</string>
 	<key>CFBundleName</key>

+ 2 - 2
prs.mobile.new/PRS.Mobile/Modules/Requisitions/Edit/Views/Items/SelectFromHoldingView.xaml.cs

@@ -153,12 +153,12 @@ namespace PRS.Mobile
 
         private void TakeNone_Click(object sender, MobileButtonClickEventArgs args)
         {
-                _viewModel.Quantity = 0.0F;
+            _viewModel.Quantity = 0.0F;
         }
 
         private void SubtractOne_Click(object sender, MobileButtonClickEventArgs args)
         {
-            _viewModel.Quantity = Math.Min(0, _viewModel.Quantity + 1.0F);
+            _viewModel.Quantity -= 1.0F;
         }
 
         private void AddOne_Click(object sender, MobileButtonClickEventArgs args)

+ 14 - 3
prs.mobile.new/PRS.Mobile/Modules/Warehousing/QuickPick/QuickPickModule.xaml

@@ -15,6 +15,7 @@
         <mobile:ByteArrayToImageSourceConverter x:Key="ByteArrayToImageSourceConverter" BlankIfEmpty="False"/>
         <mobile:StringWithDefaultValueConverter x:Key="DefaultToGeneralStock" Default="(General Stock)" />
         <mobile:DoubleCalculator x:Key="ScannerHeightCalculator" Type="Product" Constants="0.65"/>
+        <mobile:IntToBooleanConverter x:Key="ItemsPageVisible" Value="0" Result="True" />
         <mobile:IntToBooleanConverter x:Key="SummaryPageVisible" Value="1" Result="True" />
         <mobile:BooleanMatcher x:Key="MatchAll" Type="All" Value="True" />
         <mobile:StringWithDefaultValueConverter x:Key="JobNameConverter" Default="(Select Job)" />
@@ -188,11 +189,21 @@
     </mobile:MobilePage.Resources>
     
     <mobile:MobilePage.PrimaryMenu>
+        
+        <mobile:MobileMenuButton
+            Image="plus" Clicked="AddHolding_Clicked">
+            <mobile:MobileMenuButton.IsVisible>
+                <MultiBinding Converter="{StaticResource MatchAll}">
+                    <Binding Path="IsLocation" />
+                    <Binding Source="{x:Reference _tabStrip}" Path="SelectedIndex" Converter="{StaticResource ItemsPageVisible}" />
+                </MultiBinding>
+            </mobile:MobileMenuButton.IsVisible>
+        </mobile:MobileMenuButton>
+        
         <mobile:MobileMenuButton Image="save" Clicked="SaveList_Click">
             <mobile:MobileMenuButton.IsVisible>
                 <MultiBinding Converter="{StaticResource MatchAll}">
                     <Binding Path="HasItems" />
-                    <!-- <Binding Path="Job.ID" Converter="{StaticResource GuidToBooleanConverter}" /> -->
                     <Binding Source="{x:Reference _tabStrip}" Path="SelectedIndex" Converter="{StaticResource SummaryPageVisible}" />
                 </MultiBinding>
             </mobile:MobileMenuButton.IsVisible>
@@ -266,7 +277,7 @@
                                         <Polyline Points="20,20 00,20 00,00" Grid.Row="3" Grid.Column="1" x:Name="bottomleft" Stroke="Red"  StrokeThickness="2"/>
                                         
                                         <Label 
-                                            Text="Scan Barcode" 
+                                            Text="{Binding Title}" 
                                             TextColor="White" 
                                             BackgroundColor="Transparent" 
                                             Grid.Row="4" 
@@ -276,7 +287,7 @@
                                             VerticalTextAlignment="Center"/>
                                     </Grid>
                                 </mobile:MobileCard>
- 
+                                
                                 <mobile:MobileListView
                                     views:DockLayout.Dock="Top"
                                     x:Name="_holdings"

+ 115 - 4
prs.mobile.new/PRS.Mobile/Modules/Warehousing/QuickPick/QuickPickModule.xaml.cs

@@ -48,6 +48,26 @@ namespace PRS.Mobile
     {
         public bool HasItems { get; set; }
         public StockHoldingModel Holdings { get; private set; }
+
+        public void RefreshHoldings(bool force, Guid barcode)
+        {
+            Holdings.Refresh(true, () =>
+            {
+                IsLocation = Holdings.Items.Select(x => x.LocationID).All(x => x == barcode);
+                IsProduct = Holdings.Items.Select(x => x.ProductID).All(x => x == barcode);
+                
+            });
+        }
+        
+        public bool IsLocation { get; private set; }
+        public bool IsProduct { get; private set; }
+
+        public string Title => IsLocation
+            ? $"{Holdings.Items.FirstOrDefault()?.LocationCode} - {Holdings.Items.FirstOrDefault()?.LocationDescription}"
+            : IsProduct
+                ? $"{Holdings.Items.FirstOrDefault()?.ProductCode} - {Holdings.Items.FirstOrDefault()?.ProductName}"
+                : "Scan Barcode";
+        
         public RequisitionItemModel RequisitionItems { get; private set; }
         
         public JobShell Job { get; set; }
@@ -142,8 +162,8 @@ namespace PRS.Mobile
             //{
                 _viewModel.Holdings.Filter = () =>
                     new Filter<StockHolding>(x => x.Location.ID).IsEqualTo(id).Or(x=>x.Product.ID).IsEqualTo(id);
-                _viewModel.Holdings.Refresh(true);
-            //}
+                _viewModel.RefreshHoldings(true, id);
+                //}
         }
         
         private void SelectFromHolding_Click(object sender, EventArgs e)
@@ -158,7 +178,7 @@ namespace PRS.Mobile
                     var editor = new SelectFromHoldingView(holding, qty, _viewModel.RequisitionItems);
                     editor.OnSave += (o, args) =>
                     {
-                        if (args.Quantity.IsEffectivelyGreaterThan(0.0))
+                        if (!args.Quantity.IsEffectivelyEqual(0.0))
                         {
                             var requiItem = _viewModel.RequisitionItems.CreateItem();
                             requiItem.LocationID = args.Holding.LocationID;
@@ -253,7 +273,11 @@ namespace PRS.Mobile
                     {
                         if (_viewModel.Job.ID != _item.JobID)
                             _item.TargetJRI = Guid.Empty;
-
+                        
+                        // This should stop the multi-transaction thingy if returning items to stock
+                        if (_item.Quantity.IsEffectivelyLessThan(0.0))
+                            _item.JobID = requi.JobID;
+                        
                         _item.RequisitionID = requi.ID;
                     }
 
@@ -280,5 +304,92 @@ namespace PRS.Mobile
                 _viewModel.RequisitionItems.DeleteItem(shell);
             }
         }
+
+        private void AddHolding_Clicked(object sender, MobileMenuButtonClickedEventArgs args)
+        {
+            var first = _viewModel.Holdings.FirstOrDefault();
+            if (first == null)
+                return;
+            var holding = _viewModel.Holdings.CreateItem();
+            holding.LocationID = first.LocationID;
+            holding.LocationCode = first.LocationCode;
+            holding.LocationDescription = first.LocationDescription;
+            
+            var transaction = new StockTransaction(StockTransactionType.StockTake, holding, holding);
+            transaction.Allocations = new StockTransactionAllocation[]
+            {
+                new StockTransactionAllocation()
+                {
+                    ID = Guid.Empty,
+                    Description = "General Stock",
+                    Quantity = 0.0F,
+                    Maximum = double.MaxValue
+                }
+            };
+            
+            var popup = new StockTakeEdit(transaction);
+            popup.TransactionSaved += (o,e) =>
+            {
+                holding.ProductID = transaction.ProductID;
+                holding.ProductCode = transaction.ProductCode;
+                holding.ProductName = transaction.ProductName;
+                
+                holding.DimensionsUnitID = transaction.DimensionsUnitID;
+                
+                holding.DimensionsHeight = transaction.DimensionsHeight;
+                holding.DimensionsWidth = transaction.DimensionsWidth;
+                holding.DimensionsLength = transaction.DimensionsLength;
+                holding.DimensionsQuantity = transaction.DimensionsQuantity;
+                holding.DimensionsWeight = transaction.DimensionsWeight;
+                holding.DimensionsValue = transaction.DimensionsValue;
+                holding.DimensionsUnitSize = transaction.DimensionsUnitSize;
+                
+                holding.StyleID = transaction.Target.StyleID;
+                holding.StyleCode = transaction.Target.StyleCode;
+                holding.StyleDescription = transaction.Target.StyleDescription;
+                
+                holding.JobID = transaction.Target.JobID;
+                holding.JobNumber = transaction.Target.JobNumber;
+                holding.JobName = transaction.Target.JobName;
+                holding.AverageCost = transaction.Cost;
+                //holding.Units = transaction.Quantity;
+                
+                _viewModel.Holdings.CommitItem(holding);
+                
+                var requiItem = _viewModel.RequisitionItems.CreateItem();
+                
+                requiItem.LocationID = holding.LocationID;
+                requiItem.ProductID = holding.ProductID;
+                requiItem.ProductCode = holding.ProductCode;
+                requiItem.ProductName = holding.ProductName;
+                requiItem.StyleID = holding.StyleID;
+                requiItem.StyleCode = holding.StyleCode;
+                requiItem.StyleDescription = holding.StyleDescription;
+                requiItem.JobID = holding.JobID;
+                requiItem.DimensionsUnitID = holding.DimensionsUnitID;
+                requiItem.DimensionsHeight = holding.DimensionsHeight;
+                requiItem.DimensionsWidth = holding.DimensionsWidth;
+                requiItem.DimensionsLength = holding.DimensionsLength;
+                requiItem.DimensionsQuantity = holding.DimensionsQuantity;
+                requiItem.DimensionsWeight = holding.DimensionsWeight;
+                requiItem.DimensionsValue = holding.DimensionsValue;
+                requiItem.DimensionsUnitSize = holding.DimensionsUnitSize;
+                requiItem.ImageID = holding.ImageID;
+                if (holding.Parent.Images.TryGetValue(holding.ImageID, out var _image))
+                    _viewModel.RequisitionItems.Images[holding.ImageID] = _image;
+                requiItem.SourceJRI = Guid.Empty;
+                requiItem.TargetJRI = Guid.Empty;
+                requiItem.Quantity = 0 - transaction.Quantity;
+                requiItem.ActualQuantity = 0 - transaction.Quantity;
+                requiItem.Cost = transaction.Cost;
+                requiItem.Done = true;
+                _viewModel.RequisitionItems.CommitItem(requiItem);
+                
+                _viewModel.Holdings.Refresh(false);
+                DismissPopup();
+            };
+            Navigation.PushAsync(popup);
+            
+        }
     }
 }

+ 66 - 50
prs.mobile.new/PRS.Mobile/Modules/Warehousing/Stocktake/Edit/StockTakeEdit.xaml.cs

@@ -118,63 +118,79 @@ namespace PRS.Mobile
         private void SelectProduct_Clicked(object sender, MobileButtonClickEventArgs args)
         {
             ShowPopup(() =>
-                SelectionView.Execute<ProductShell>(
-                    columns =>
-                    {
-                        columns.Add(new MobileGridTextColumn<ProductShell>()
-                            { Column = x => x.Code, Width = 200 });
-                        columns.Add(new MobileGridTextColumn<ProductShell>()
-                            { Column = x => x.Name, Width = GridLength.Star });
-                    },
-                    refresh => App.Data.Products.Refresh(false),
-                    products =>
-                    {
-                        ViewModel.Transaction.ProductID = products.FirstOrDefault()?.ID ?? Guid.Empty;
-                        ViewModel.Transaction.ProductCode = products.FirstOrDefault()?.Code ?? string.Empty;
-                        ViewModel.Transaction.ProductName = products.FirstOrDefault()?.Name ?? string.Empty;
-                        
-                        if (ViewModel.Transaction.Source.Shell != null)
+                {
+                    bool force = false;
+                    return SelectionView.Execute<ProductShell>(
+                        columns =>
                         {
-                            ViewModel.Transaction.Source.Shell.DimensionsHasLength =
-                                products.FirstOrDefault()?.DimensionsUnit?.HasLength ?? false;
-                            ViewModel.Transaction.Source.Shell.DimensionsHasWidth =
-                                products.FirstOrDefault()?.DimensionsUnit?.HasWidth ?? false;
-                            ViewModel.Transaction.Source.Shell.DimensionsHasHeight =
-                                products.FirstOrDefault()?.DimensionsUnit?.HasHeight ?? false;
-                            ViewModel.Transaction.Source.Shell.DimensionsHasQuantity =
-                                products.FirstOrDefault()?.DimensionsUnit?.HasQuantity ?? false;
-                            ViewModel.Transaction.Source.Shell.DimensionsHasWeight =
-                                products.FirstOrDefault()?.DimensionsUnit?.HasWeight ?? false;
-                        }                        
-                        ViewModel.Transaction.DimensionsUnitID = products.FirstOrDefault()?.DimensionsUnitID ?? Guid.Empty;
-                        ViewModel.Transaction.DimensionsHeight = products.FirstOrDefault()?.DimensionsHeight ?? 0.0;
-                        ViewModel.Transaction.DimensionsWidth = products.FirstOrDefault()?.DimensionsWidth ?? 0.0;
-                        ViewModel.Transaction.DimensionsLength = products.FirstOrDefault()?.DimensionsLength ?? 0.0;
-                        ViewModel.Transaction.DimensionsQuantity = products.FirstOrDefault()?.DimensionsQuantity ?? 0.0;
-                        ViewModel.Transaction.DimensionsValue = products.FirstOrDefault()?.DimensionsValue ?? 0.0;
-                        ViewModel.Transaction.DimensionsUnitSize = products.FirstOrDefault()?.DimensionsUnitSize ?? string.Empty;
-                        
-                        ViewModel.Transaction.Cost = products.FirstOrDefault()?.AverageCost ?? 0.0;
-
-                        ViewModel.Transaction.ImageID = products.FirstOrDefault()?.ImageID ??Guid.Empty;
-                        if (ViewModel.Transaction.ImageID != Guid.Empty && products.FirstOrDefault()?.Parent != null)
+                            columns.Add(new MobileGridTextColumn<ProductShell>()
+                                { Column = x => x.Code, Width = 200 });
+                            columns.Add(new MobileGridTextColumn<ProductShell>()
+                                { Column = x => x.Name, Width = GridLength.Star });
+                        },
+                        refresh =>
+                        {
+                            var result = App.Data.Products.Refresh(force);
+                            force = true;
+                            return result;
+                        },
+                        products =>
                         {
-                            
-                            if (products.FirstOrDefault()!.Parent.Images.TryGetValue(ViewModel.Transaction.ImageID, out var data))
-                                ViewModel.Transaction.Image = data;
-                            else
+                            ViewModel.Transaction.ProductID = products.FirstOrDefault()?.ID ?? Guid.Empty;
+                            ViewModel.Transaction.ProductCode = products.FirstOrDefault()?.Code ?? string.Empty;
+                            ViewModel.Transaction.ProductName = products.FirstOrDefault()?.Name ?? string.Empty;
+
+                            if (ViewModel.Transaction.Source.Shell != null)
                             {
-                                DocumentModel docmodel = new DocumentModel(App.Data,
-                                    () => new Filter<Document>(x => x.ID).IsEqualTo(ViewModel.Transaction.ImageID));
-                                docmodel.Refresh(true);
-                                ViewModel.Transaction.Image = docmodel.Items.FirstOrDefault()?.Data ?? new byte[] { };
+                                ViewModel.Transaction.Source.Shell.DimensionsHasLength =
+                                    products.FirstOrDefault()?.DimensionsUnit?.HasLength ?? false;
+                                ViewModel.Transaction.Source.Shell.DimensionsHasWidth =
+                                    products.FirstOrDefault()?.DimensionsUnit?.HasWidth ?? false;
+                                ViewModel.Transaction.Source.Shell.DimensionsHasHeight =
+                                    products.FirstOrDefault()?.DimensionsUnit?.HasHeight ?? false;
+                                ViewModel.Transaction.Source.Shell.DimensionsHasQuantity =
+                                    products.FirstOrDefault()?.DimensionsUnit?.HasQuantity ?? false;
+                                ViewModel.Transaction.Source.Shell.DimensionsHasWeight =
+                                    products.FirstOrDefault()?.DimensionsUnit?.HasWeight ?? false;
                             }
-                        }
 
+                            ViewModel.Transaction.DimensionsUnitID =
+                                products.FirstOrDefault()?.DimensionsUnitID ?? Guid.Empty;
+                            ViewModel.Transaction.DimensionsHeight = products.FirstOrDefault()?.DimensionsHeight ?? 0.0;
+                            ViewModel.Transaction.DimensionsWidth = products.FirstOrDefault()?.DimensionsWidth ?? 0.0;
+                            ViewModel.Transaction.DimensionsLength = products.FirstOrDefault()?.DimensionsLength ?? 0.0;
+                            ViewModel.Transaction.DimensionsQuantity =
+                                products.FirstOrDefault()?.DimensionsQuantity ?? 0.0;
+                            ViewModel.Transaction.DimensionsValue = products.FirstOrDefault()?.DimensionsValue ?? 0.0;
+                            ViewModel.Transaction.DimensionsUnitSize =
+                                products.FirstOrDefault()?.DimensionsUnitSize ?? string.Empty;
 
-                        DismissPopup();
-                    })
+                            ViewModel.Transaction.Cost = products.FirstOrDefault()?.AverageCost ?? 0.0;
+
+                            ViewModel.Transaction.ImageID = products.FirstOrDefault()?.ImageID ?? Guid.Empty;
+                            if (ViewModel.Transaction.ImageID != Guid.Empty &&
+                                products.FirstOrDefault()?.Parent != null)
+                            {
+
+                                if (products.FirstOrDefault()!.Parent.Images.TryGetValue(ViewModel.Transaction.ImageID,
+                                        out var data))
+                                    ViewModel.Transaction.Image = data;
+                                else
+                                {
+                                    DocumentModel docmodel = new DocumentModel(App.Data,
+                                        () => new Filter<Document>(x => x.ID).IsEqualTo(ViewModel.Transaction.ImageID));
+                                    docmodel.Refresh(true);
+                                    ViewModel.Transaction.Image =
+                                        docmodel.Items.FirstOrDefault()?.Data ?? new byte[] { };
+                                }
+                            }
+
+
+                            DismissPopup();
+                        });
+                }
             );
+            
         }
         
         private void InputView_OnTextChanged(object sender, TextChangedEventArgs e)