Browse Source

Merge remote-tracking branch 'origin/nick' into kenric

Kenric Nugteren 2 years ago
parent
commit
bab27a7998

+ 26 - 3
prs.desktop/Panels/Products/Locations/StockLocationGrid.cs

@@ -2,18 +2,22 @@
 using System.Collections.Generic;
 using System.Drawing;
 using System.Linq;
+using System.Windows;
 using System.Windows.Controls;
 using Comal.Classes;
+using InABox.Clients;
 using InABox.Core;
 using InABox.DynamicGrid;
 using InABox.WPF;
+using NPOI.SS.Formula.Functions;
 
 namespace PRSDesktop
 {
     public class StockLocationGrid : DynamicDataGrid<StockLocation>
     {
         private bool bShowAll;
-
+        public Button ShowAllBtn;
+        public Button StockTakeBtn;
         public StockLocationGrid()
         {
             Options.AddRange(
@@ -22,7 +26,10 @@ namespace PRSDesktop
                 DynamicGridOption.SelectColumns
             );
 
-            AddButton("Show All", PRSDesktop.Resources.parcel.AsBitmapImage(Color.White), ToggleHiddenJobs);
+            ShowAllBtn = AddButton("Show All", PRSDesktop.Resources.parcel.AsBitmapImage(Color.White), ToggleHiddenJobs);
+
+            if (Security.CanEdit<StockMovement>())
+                StockTakeBtn = AddButton("Stock Take", PRSDesktop.Resources.rack.AsBitmapImage(Color.White), DoStockTake);
             HiddenColumns.Add(x => x.Job.ID);
 
             //HiddenColumns.Add(x => x.Movements);
@@ -30,6 +37,22 @@ namespace PRSDesktop
             OnCustomiseEditor += CustomiseEditor;
         }
 
+        private bool DoStockTake(Button sender, CoreRow[] rows)
+        {
+            if (!rows.Any())
+            {
+                MessageBox.Show("Please select at least one row for Stocktake!");
+                return false;
+            }
+
+            var page = new StockTakeWindow(rows);
+
+            page.Show();
+
+            return true;
+        }
+
+
         private bool ToggleHiddenJobs(Button sender, CoreRow[] rows)
         {
             bShowAll = !bShowAll;
@@ -74,7 +97,7 @@ namespace PRSDesktop
                 //editor.Editable = bHasHoldings ? Editable.Disabled : Editable.Enabled;
                 //if (bHasHoldings)
                 var item = items?.FirstOrDefault();
-                if(item is not null)
+                if (item is not null)
                     item.Active = true;
             }
         }

+ 28 - 0
prs.desktop/Panels/Products/Locations/StockTakeWindow.xaml

@@ -0,0 +1,28 @@
+<Window x:Class="PRSDesktop.StockTakeWindow"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:PRSDesktop"
+        mc:Ignorable="d"
+        Title="Stock Take" Height="800" Width="1200" WindowStartupLocation="CenterScreen">
+    <Grid Margin="5">
+        <DockPanel Grid.Row="0" Margin="2,0,0,0">
+            <Border CornerRadius="5,5,0,0" BorderBrush="Gray" BorderThickness="0.75" DockPanel.Dock="Top"
+                    Background="WhiteSmoke">
+                <Label Content="Stock Summary For Selected Locations" HorizontalContentAlignment="Center" />
+            </Border>
+            <local:StockTakeHoldingGrid x:Name="Holdings" DockPanel.Dock="Top" Margin="0,2,0,0" />
+        </DockPanel>
+
+        <Grid Grid.Row="0" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="170" Height="36" Margin="0">
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="*"/>
+                <ColumnDefinition Width="*"/>
+            </Grid.ColumnDefinitions>
+            <Button Grid.Column="0" Content="OK" Margin="5, 6, 2.5, 0" BorderBrush="DarkGray" Click="Ok_Button_Click"/>
+            <Button Grid.Column="1" Content="Cancel" Margin="2.5, 6, 0, 0" BorderBrush="DarkGray" Click="Cancel_Button_Click"/>
+        </Grid>
+        
+    </Grid>
+</Window>

+ 543 - 0
prs.desktop/Panels/Products/Locations/StockTakeWindow.xaml.cs

@@ -0,0 +1,543 @@
+using Comal.Classes;
+using InABox.Clients;
+using InABox.Configuration;
+using InABox.Core;
+using InABox.DynamicGrid;
+using InABox.WPF;
+using Microsoft.Win32;
+using NPOI.SS.Formula.Functions;
+using NPOI.SS.UserModel;
+using NPOI.SS.Util;
+using NPOI.XSSF.UserModel;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace PRSDesktop
+{
+    /// <summary>
+    /// Interaction logic for StockTakeWindow.xaml
+    /// </summary>
+    public partial class StockTakeWindow : Window
+    {
+        #region Fields / constructor
+        CoreRow[] Rows;
+
+        List<StockTakeHolding> StockTakeHoldings = new List<StockTakeHolding>();
+
+        List<StockHolding> OriginalHoldings = new List<StockHolding>();
+
+        Guid EmployeeID = Guid.Empty;
+        public StockTakeWindow(CoreRow[] rows)
+        {
+            InitializeComponent();
+            Rows = rows;
+            Setup();
+        }
+        #endregion
+
+        #region Setup
+        private void Setup()
+        {
+            SetupStockHoldingGrid();
+
+            Progress.ShowModal("Loading", (progress) =>
+            {
+                EmployeeID = new Client<Employee>().Query(new Filter<Employee>(x => x.UserID).IsEqualTo(ClientFactory.UserGuid)).Rows.FirstOrDefault().Get<Employee, Guid>(x => x.ID);
+
+                QueryList(Rows.Select(x => x.Get<StockLocation, Guid>(c => c.ID)));
+
+                Dispatcher.Invoke(() =>
+                {
+                    Holdings.Items = StockTakeHoldings;
+                    Holdings.Refresh(true, true);
+                });
+            });
+
+
+        }
+
+        private void SetupStockHoldingGrid()
+        {
+            Holdings.Options.Remove(DynamicGridOption.EditRows);
+            Holdings.Options.Remove(DynamicGridOption.DeleteRows);
+            Holdings.Options.Remove(DynamicGridOption.ImportData);
+            Holdings.Options.Remove(DynamicGridOption.ExportData);
+            Holdings.Options.Add(DynamicGridOption.RecordCount);
+            Holdings.Options.Add(DynamicGridOption.AddRows);
+
+            Holdings.Options.Add(DynamicGridOption.DirectEdit);
+
+            Holdings.OnCustomiseEditor += Page_OnCustomiseEditor;
+            Holdings.OnValidate += Page_OnValidate;
+            Holdings.OnBeforeSave += Page_OnSave;
+
+            Holdings.AddButton("Pre-Fill Actual Qty", PRSDesktop.Resources.copy.AsBitmapImage(), FillValues);
+            Holdings.AddButton("Reset Actual Qty to Zero", PRSDesktop.Resources.refresh.AsBitmapImage(), ClearValues);
+            Holdings.AddButton("Export", PRSDesktop.Resources.doc_xls.AsBitmapImage(), Export);
+        }
+
+
+        private void QueryList(IEnumerable<Guid> ids)
+        {
+            CoreTable table = new Client<StockHolding>().Query(new Filter<StockHolding>(x => x.Location.ID).InList(ids.ToArray())
+                .And(x => x.Dimensions.UnitSize).IsNotEqualTo(null)
+                .And(x => x.Qty).IsGreaterThan(0.1),
+                new Columns<StockHolding>(
+                    x => x.ID,
+                    x => x.Qty,
+                    x => x.Job.ID,
+                    x => x.Job.JobNumber,
+                    x => x.Product.ID,
+                    x => x.Product.Code,
+                    x => x.Product.Name,
+                    x => x.Style.ID,
+                    x => x.Style.Code,
+                    x => x.Style.Description,
+                    x => x.Location.ID,
+                    x => x.Location.Code,
+                    x => x.Location.Description,
+                    x => x.Dimensions.Unit.ID,
+                    x => x.Dimensions.UnitSize,
+                    x => x.Dimensions.Unit.Format,
+                    x => x.Dimensions.Unit.Formula,
+                    x => x.Dimensions.Unit.HasLength,
+                    x => x.Dimensions.Unit.HasHeight,
+                    x => x.Dimensions.Unit.HasWeight,
+                    x => x.Dimensions.Unit.HasWidth,
+                    x => x.Dimensions.Unit.HasQuantity,
+                    x => x.Dimensions.Quantity,
+                    x => x.Dimensions.Length,
+                    x => x.Dimensions.Height,
+                    x => x.Dimensions.Width,
+                    x => x.Dimensions.Weight
+                    ));
+            foreach (CoreRow row in table.Rows)
+            {
+                StockHolding holding = row.ToObject<StockHolding>();
+                OriginalHoldings.Add(holding);
+
+                StockTakeHolding displayHolding = new StockTakeHolding();
+                displayHolding.ID = holding.ID;
+                displayHolding.OriginalQty = holding.Qty;
+
+                displayHolding.Job.ID = holding.Job.ID;
+                displayHolding.Job.JobNumber = holding.Job.JobNumber;
+
+                displayHolding.Product.ID = holding.Product.ID;
+                displayHolding.Product.Code = holding.Product.Code;
+                displayHolding.Product.Name = holding.Product.Name;
+
+                displayHolding.Style.ID = holding.Style.ID;
+                displayHolding.Style.Code = holding.Style.Code;
+                displayHolding.Style.Description = holding.Style.Description;
+
+                displayHolding.Location.ID = holding.Location.ID;
+                displayHolding.Location.Code = holding.Location.Code;
+                displayHolding.Location.Description = holding.Location.Description;
+
+                displayHolding.Dimensions.CopyFrom(holding.Dimensions);
+
+                StockTakeHoldings.Add(displayHolding);
+            }
+        }
+
+        #region Editor Setup
+        private void Page_OnSave(IDynamicEditorForm editor, StockTakeHolding[] items)
+        {
+            foreach (StockTakeHolding item in items)
+            {
+                item.UpdateDimensions();
+            }
+        }
+
+        private void Page_OnValidate(object sender, StockTakeHolding[] items, List<string> errors)
+        {
+            var bQty = false;
+            var bProd = false;
+            var bLocn = false;
+            foreach (var item in items)
+            {
+                bQty = bQty || item.NewQty == 0.0F;
+                bProd = bProd || !item.Product.IsValid();
+                bLocn = bLocn || !item.Location.IsValid();
+            }
+
+            if (bQty)
+                errors.Add("Quantity may not be zero");
+            if (bProd)
+                errors.Add("Product may not be blank");
+            if (bLocn)
+                errors.Add("Location may not be blank");
+        }
+
+        private void Page_OnCustomiseEditor(IDynamicEditorForm sender, StockTakeHolding[]? items, DynamicGridColumn column, BaseEditor editor)
+        {
+            if (column.ColumnName.Equals("OriginalQty"))
+                editor.Editable = Editable.Hidden;
+
+            if (column.ColumnName.Equals("NewQty"))
+                editor.Caption = "Qty";
+
+            if (column.ColumnName.Equals("Dimensions.Quantity"))
+                editor.Editable = Editable.Hidden;
+
+            if (column.ColumnName.Equals("Dimensions.Length"))
+                editor.Editable = Editable.Hidden;
+
+            if (column.ColumnName.Equals("Dimensions.Weight"))
+                editor.Editable = Editable.Hidden;
+
+            if (column.ColumnName.Equals("Dimensions.Height"))
+                editor.Editable = Editable.Hidden;
+
+            if (column.ColumnName.Equals("Dimensions.Width"))
+                editor.Editable = Editable.Hidden;
+        }
+        #endregion
+
+        #region Added Buttons
+        private bool ClearValues(Button arg1, CoreRow[] arg2)
+        {
+            var result = MessageBox.Show("This will clear all new quantities entered. Proceed?", "Warning", MessageBoxButton.YesNo);
+            if (result != MessageBoxResult.Yes)
+                return false;
+
+            foreach (var holding in Holdings.Items)
+                holding.ClearQty();
+
+            return true;
+        }
+
+        private bool FillValues(Button arg1, CoreRow[] rows)
+        {
+            var result = MessageBox.Show("This will prefill all new quantities with the original quantity. Proceed?", "Warning", MessageBoxButton.YesNo);
+            if (result != MessageBoxResult.Yes)
+                return false;
+
+            foreach (var holding in Holdings.Items)
+                holding.PreFillQty();
+
+            return true;
+        }
+
+        private void Cancel_Button_Click(object sender, RoutedEventArgs e)
+        {
+            bool changes = false;
+            foreach (var holding in StockTakeHoldings)
+            {
+                if (holding.NewQty != 0)
+                    changes = true;
+            }
+            if (changes)
+            {
+                var result = MessageBox.Show("Warning - any unsaved changes will be lost. Continue?", "Warning", MessageBoxButton.YesNo);
+                if (result == MessageBoxResult.Yes)
+                    Close();
+            }
+            else
+                Close();
+        }
+
+        private bool Export(Button arg1, CoreRow[] arg2)
+        {
+            var result = AddColumns();
+            result.LoadRows(Holdings.Items);
+            ExcelExporter.DoExport<StockTakeHolding>(result, "Stock Take " + DateTime.Now.ToString("HH:mm dd MMM yy"));
+
+            return true;
+        }
+
+        private CoreTable AddColumns()
+        {
+            var result = new CoreTable();
+
+            result.Columns.Add(
+                new CoreColumn()
+                {
+                    ColumnName = "Location.Code",
+                    DataType = typeof(string)
+                });
+
+            result.Columns.Add(
+                new CoreColumn()
+                {
+                    ColumnName = "Product.Code",
+                    DataType = typeof(string)
+                });
+
+            result.Columns.Add(
+                new CoreColumn()
+                {
+                    ColumnName = "Product.Name",
+                    DataType = typeof(string)
+                });
+
+            result.Columns.Add(
+                new CoreColumn()
+                {
+                    ColumnName = "Dimensions.UnitSize",
+                    DataType = typeof(string)
+                });
+
+            result.Columns.Add(
+                new CoreColumn()
+                {
+                    ColumnName = "Job.JobNumber",
+                    DataType = typeof(string)
+                });
+
+            result.Columns.Add(
+                new CoreColumn()
+                {
+                    ColumnName = "Job.Name",
+                    DataType = typeof(string)
+                });
+
+            result.Columns.Add(
+                new CoreColumn()
+                {
+                    ColumnName = "Style.Description",
+                    DataType = typeof(string)
+                });
+
+            result.Columns.Add(
+               new CoreColumn()
+               {
+                   ColumnName = "OriginalQty",
+                   DataType = typeof(double)
+               });
+
+            result.Columns.Add(
+                new CoreColumn()
+                {
+                    ColumnName = "NewQty",
+                    DataType = typeof(double)
+                });
+
+            return result;
+        }
+        #endregion
+        #endregion
+
+        #region Saving Stocktake
+        #region Button Press / Validate
+        private void Ok_Button_Click(object sender, RoutedEventArgs e)
+        {
+            var result = MessageBox.Show("This will now generate stock movements for each line, whether the quantity has changed or not. Proceed?", "Information", MessageBoxButton.YesNo);
+            if (result != MessageBoxResult.Yes)
+                return;
+
+            if (!ValidateQty())
+                return;
+
+            CreateMovements();
+
+            MessageBox.Show("Success - Stocktake complete");
+
+            Close();
+        }
+
+        private bool ValidateQty()
+        {
+            bool zerosPresent = false;
+            foreach (var holding in StockTakeHoldings)
+            {
+                if (holding.NewQty < 0)
+                {
+                    MessageBox.Show("Negative quantities are not allowed!");
+                    return false;
+                }
+                if (holding.NewQty == 0)
+                    zerosPresent = true;
+            }
+            if (zerosPresent)
+            {
+                var result = MessageBox.Show("One or more rows have been left as Zero. This will create an issuing stock movement of any existing stock for that row. Proceed?", "Warning", MessageBoxButton.YesNo);
+                if (result != MessageBoxResult.Yes)
+                    return false;
+            }
+
+            return true;
+        }
+        #endregion
+
+        #region Stock Movements
+        private void CreateMovements()
+        {
+            StockMovementBatch batch = CreateBatch();
+
+            List<StockMovement> movements = CompareHoldingsAndCreateMovements(batch.ID);
+
+            new Client<StockMovement>().Save(movements, "Created on Desktop Stocktake");
+        }
+
+        private StockMovementBatch CreateBatch()
+        {
+            StockMovementBatch batch = new StockMovementBatch();
+            batch.Notes = "Stocktake";
+            batch.Employee.ID = EmployeeID;
+            batch.Type = StockMovementBatchType.Stocktake;
+
+            new Client<StockMovementBatch>().Save(batch, "Created on Desktop Stocktake");
+
+            return batch;
+        }
+        private List<StockMovement> CompareHoldingsAndCreateMovements(Guid batchID)
+        {
+            List<StockMovement> movements = new List<StockMovement>();
+            foreach (var holding in StockTakeHoldings)
+            {
+                StockHolding original = OriginalHoldings.Find(x => x.ID == holding.ID);
+                if (original != null)
+                    movements.Add(CreateMovement(holding, holding.NewQty - holding.OriginalQty, batchID));
+                else
+                    movements.Add(CreateMovement(holding, holding.NewQty, batchID));
+            }
+            return movements;
+        }
+
+        private StockMovement CreateMovement(StockTakeHolding holding, double qty, Guid batchID)
+        {
+            StockMovement movement = CreateBaseMovement(holding, batchID);
+
+            return DetermineMovementType(movement, qty);
+        }
+
+        private StockMovement CreateBaseMovement(StockTakeHolding holding, Guid batchID)
+        {
+            StockMovement movement = new StockMovement();
+
+            movement.Batch.ID = batchID;
+            movement.IsTransfer = false;
+            movement.Issued = 0;
+            movement.Received = 0;
+            movement.Product.ID = holding.Product.ID;
+            movement.Job.ID = holding.Job.ID;
+            movement.Style.ID = holding.Style.ID;
+            movement.Employee.ID = EmployeeID;
+            movement.Notes = "Correct Qty on Stocktake";
+            movement.Dimensions.CopyFrom(holding.Dimensions);
+            movement.Date = DateTime.Now;
+            movement.Location.ID = holding.Location.ID;
+            movement.IsRemnant = false;
+
+            return movement;
+        }
+
+        private StockMovement DetermineMovementType(StockMovement movement, double qty)
+        {
+            if (qty < 0)
+            {
+                movement.Notes = "Updated Qty on Stocktake";
+                movement.Issued = 0 - qty;
+            }
+
+            if (qty > 0)
+            {
+                movement.Notes = "Updated Qty on Stocktake";
+                movement.Received = qty;
+            }
+
+            return movement;
+        }
+        #endregion
+        #endregion
+
+    }
+
+    #region Intermediate Class
+    [DoNotPersist]
+    public class StockTakeHolding : Entity
+    {
+        [DoubleEditor(Editable = Editable.Disabled)]
+        public double OriginalQty { get; set; }
+
+        [DoubleEditor(Editable = Editable.Enabled)]
+        public double NewQty { get; set; }
+
+        [NullEditor]
+        public Guid ID { get; set; }
+
+        public ProductLink Product { get; set; }
+
+        public ProductStyleLink Style { get; set; }
+
+        public StockLocationLink Location { get; set; }
+
+        public JobLink Job { get; set; }
+
+        public StockDimensions Dimensions { get; set; }
+
+        protected override void Init()
+        {
+            OriginalQty = 0;
+            NewQty = 0;
+            ID = Guid.Empty;
+            Style = new ProductStyleLink();
+            Location = new StockLocationLink();
+            Job = new JobLink();
+            Dimensions = new StockDimensions(() => this);
+            Product = new ProductLink(() => this);
+            base.Init();
+        }
+
+        public void UpdateDimensions()
+        {
+            if (Product.ID != Guid.Empty)
+            {
+                CoreTable table = new Client<Product>().Query(new Filter<Product>(x => x.ID).IsEqualTo(Product.ID));
+                Product product = table.Rows.FirstOrDefault().ToObject<Product>();
+
+                Dimensions.CopyFrom(product.Dimensions);
+            }
+        }
+
+        public void PreFillQty()
+        {
+            if (OriginalQty != 0)
+                NewQty = OriginalQty;
+        }
+
+        public void ClearQty()
+        {
+            NewQty = 0;
+        }
+    }
+    #endregion
+
+    #region Grid
+    public class StockTakeHoldingGrid : DynamicItemsListGrid<StockTakeHolding>
+    {
+        protected override void Reload(Filters<StockTakeHolding> criteria, Columns<StockTakeHolding> columns, ref SortOrder<StockTakeHolding>? sort, Action<CoreTable?, Exception?> action)
+        {
+            base.Reload(criteria, columns, ref sort, action);
+        }
+
+        protected override DynamicGridColumns LoadColumns()
+        {
+            var columns = new DynamicGridColumns();
+
+            columns.Add<StockTakeHolding, string>(x => x.Location.Code, 150, "Location Code", "", Alignment.MiddleCenter);
+
+            columns.Add<StockTakeHolding, string>(x => x.Product.Code, 100, "Product Code", "", Alignment.MiddleCenter);
+            columns.Add<StockTakeHolding, string>(x => x.Product.Name, 0, "Product Name", "", Alignment.MiddleCenter);
+
+            columns.Add<StockTakeHolding, string>(x => x.Dimensions.UnitSize, 80, "Dimensions Unit", "", Alignment.MiddleCenter);
+
+            columns.Add<StockTakeHolding, string>(x => x.Job.JobNumber, 80, "Job Number", "", Alignment.MiddleCenter);
+            columns.Add<StockTakeHolding, string>(x => x.Job.Name, 80, "Job Name", "", Alignment.MiddleCenter);
+
+            columns.Add<StockTakeHolding, string>(x => x.Style.Description, 80, "Style", "", Alignment.MiddleCenter);
+
+            columns.Add<StockTakeHolding, double>(x => x.OriginalQty, 80, "Original Qty", "", Alignment.MiddleCenter);
+            columns.Add<StockTakeHolding, double>(x => x.NewQty, 80, "Actual Qty", "", Alignment.MiddleCenter);
+            return columns;
+        }
+    }
+    #endregion
+}

+ 1 - 1
prs.mobile/comal.timesheets.Android/Resources/Resource.designer.cs

@@ -14,7 +14,7 @@ namespace comal.timesheets.Droid
 {
 	
 	
-	[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "13.1.0.5")]
+	[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "13.0.0.73")]
 	public partial class Resource
 	{
 		

+ 2 - 2
prs.mobile/comal.timesheets/DigitalForms/DigitalFormHost.xaml

@@ -12,8 +12,8 @@
             </Grid.ColumnDefinitions>
             <Button Grid.Column="0" HorizontalOptions="Start" VerticalOptions="Center" TextColor="White" BackgroundColor="Transparent" Margin="0" Padding="0"
                 Text="Cancel" Clicked="ExitBtn_Clicked"/>
-            <Label x:Name="titleLbl" Grid.Column="1" Text="Edit Form" HorizontalOptions="Fill" HorizontalTextAlignment="Center" VerticalOptions="Fill" VerticalTextAlignment="Center" TextColor="White"/>
-             <Button x:Name="saveProgressBtn" Grid.Column="2" HorizontalOptions="Center" VerticalOptions="Center" TextColor="White" BackgroundColor="Transparent" Margin="0" Padding="0" 
+            <!--<Label x:Name="titleLbl" Grid.Column="1" Text="Edit Form" HorizontalOptions="Fill" HorizontalTextAlignment="Center" VerticalOptions="Fill" VerticalTextAlignment="Center" TextColor="White"/>-->
+             <Button x:Name="saveProgressBtn" Grid.Column="1" HorizontalOptions="Center" VerticalOptions="Center" TextColor="White" BackgroundColor="Transparent" Margin="0" Padding="0" 
                  Text="Save Progress" Clicked="SaveProgressBtn_Clicked" FontAttributes="Bold" IsVisible="true"/> 
             <Button Grid.Column="2" HorizontalOptions="End" VerticalOptions="Center" TextColor="White" BackgroundColor="Transparent" Margin="0" Padding="0"
                     x:Name="saveBtn"

+ 1 - 1
prs.mobile/comal.timesheets/DigitalForms/DigitalFormHost.xaml.cs

@@ -43,7 +43,7 @@ namespace comal.timesheets
             InitializeComponent();
             NavigationPage.SetHasBackButton(this, false);
             Model = model;
-            titleLbl.Text = Model.DigitalFormDataModel.Instance.Form.Description;
+            //titleLbl.Text = Model.DigitalFormDataModel.Instance.Form.Description;
             Model.OnDigitalFormHostModelBeforeSave += () =>
             {
                 Model.SetPropertyValues(viewer);