Browse Source

Working on Warehouse/Stocktake Module

Frank van den Bos 4 months ago
parent
commit
2177b3953b

+ 36 - 0
PRS.Avalonia/PRS.Avalonia.iOS.sln

@@ -37,64 +37,99 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InABox.RPC.Shared", "..\..\
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InABox.Client.RPC", "..\..\inabox\InABox.Client.RPC\InABox.Client.RPC.csproj", "{942BE71A-B1F6-4F49-A00F-ED8077C9260D}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InABox.Formatters.Core", "..\..\inabox\InABox.Formatters.Core\InABox.Formatters.Core.csproj", "{4777E56E-D3B2-4297-BB47-7406AC7B8B81}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
 		Release|Any CPU = Release|Any CPU
+		Publish|Any CPU = Publish|Any CPU
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 		{CC49EB9C-7E0F-4952-B3E2-E9E1D4E3C069}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{CC49EB9C-7E0F-4952-B3E2-E9E1D4E3C069}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{CC49EB9C-7E0F-4952-B3E2-E9E1D4E3C069}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{CC49EB9C-7E0F-4952-B3E2-E9E1D4E3C069}.Release|Any CPU.Build.0 = Release|Any CPU
+		{CC49EB9C-7E0F-4952-B3E2-E9E1D4E3C069}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
+		{CC49EB9C-7E0F-4952-B3E2-E9E1D4E3C069}.Publish|Any CPU.Build.0 = Publish|Any CPU
 		{0E42BD95-7FFA-45AE-90C8-8553DE69DE81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{0E42BD95-7FFA-45AE-90C8-8553DE69DE81}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{0E42BD95-7FFA-45AE-90C8-8553DE69DE81}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{0E42BD95-7FFA-45AE-90C8-8553DE69DE81}.Release|Any CPU.Build.0 = Release|Any CPU
+		{0E42BD95-7FFA-45AE-90C8-8553DE69DE81}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
+		{0E42BD95-7FFA-45AE-90C8-8553DE69DE81}.Publish|Any CPU.Build.0 = Publish|Any CPU
 		{44AD72A8-7A66-4E64-9EDA-0C069EC5B88B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{44AD72A8-7A66-4E64-9EDA-0C069EC5B88B}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{44AD72A8-7A66-4E64-9EDA-0C069EC5B88B}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{44AD72A8-7A66-4E64-9EDA-0C069EC5B88B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{44AD72A8-7A66-4E64-9EDA-0C069EC5B88B}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
+		{44AD72A8-7A66-4E64-9EDA-0C069EC5B88B}.Publish|Any CPU.Build.0 = Publish|Any CPU
 		{C97D4AF6-A56D-4C47-81FF-ED6CE3F8A370}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{C97D4AF6-A56D-4C47-81FF-ED6CE3F8A370}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{C97D4AF6-A56D-4C47-81FF-ED6CE3F8A370}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{C97D4AF6-A56D-4C47-81FF-ED6CE3F8A370}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C97D4AF6-A56D-4C47-81FF-ED6CE3F8A370}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
+		{C97D4AF6-A56D-4C47-81FF-ED6CE3F8A370}.Publish|Any CPU.Build.0 = Publish|Any CPU
 		{EFF425D8-1394-49B3-8B80-E311AFE71591}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{EFF425D8-1394-49B3-8B80-E311AFE71591}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{EFF425D8-1394-49B3-8B80-E311AFE71591}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{EFF425D8-1394-49B3-8B80-E311AFE71591}.Release|Any CPU.Build.0 = Release|Any CPU
+		{EFF425D8-1394-49B3-8B80-E311AFE71591}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
+		{EFF425D8-1394-49B3-8B80-E311AFE71591}.Publish|Any CPU.Build.0 = Publish|Any CPU
 		{AF7B7FFA-B47F-4E58-813E-E58AA7C2EA7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{AF7B7FFA-B47F-4E58-813E-E58AA7C2EA7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{AF7B7FFA-B47F-4E58-813E-E58AA7C2EA7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{AF7B7FFA-B47F-4E58-813E-E58AA7C2EA7E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{AF7B7FFA-B47F-4E58-813E-E58AA7C2EA7E}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
+		{AF7B7FFA-B47F-4E58-813E-E58AA7C2EA7E}.Publish|Any CPU.Build.0 = Publish|Any CPU
 		{03DA1BA1-0012-4780-84C4-D0458148DDF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{03DA1BA1-0012-4780-84C4-D0458148DDF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{03DA1BA1-0012-4780-84C4-D0458148DDF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{03DA1BA1-0012-4780-84C4-D0458148DDF5}.Release|Any CPU.Build.0 = Release|Any CPU
+		{03DA1BA1-0012-4780-84C4-D0458148DDF5}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
+		{03DA1BA1-0012-4780-84C4-D0458148DDF5}.Publish|Any CPU.Build.0 = Publish|Any CPU
 		{0ABFAD18-FC5A-4914-930A-8921AA39D580}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{0ABFAD18-FC5A-4914-930A-8921AA39D580}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{0ABFAD18-FC5A-4914-930A-8921AA39D580}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{0ABFAD18-FC5A-4914-930A-8921AA39D580}.Release|Any CPU.Build.0 = Release|Any CPU
+		{0ABFAD18-FC5A-4914-930A-8921AA39D580}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
+		{0ABFAD18-FC5A-4914-930A-8921AA39D580}.Publish|Any CPU.Build.0 = Publish|Any CPU
 		{5D804C1F-BAB4-4CEB-A33A-68D3800E1F43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{5D804C1F-BAB4-4CEB-A33A-68D3800E1F43}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{5D804C1F-BAB4-4CEB-A33A-68D3800E1F43}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{5D804C1F-BAB4-4CEB-A33A-68D3800E1F43}.Release|Any CPU.Build.0 = Release|Any CPU
+		{5D804C1F-BAB4-4CEB-A33A-68D3800E1F43}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
+		{5D804C1F-BAB4-4CEB-A33A-68D3800E1F43}.Publish|Any CPU.Build.0 = Publish|Any CPU
 		{7A93CDBB-D339-452D-BD82-1A348A2DC663}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{7A93CDBB-D339-452D-BD82-1A348A2DC663}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{7A93CDBB-D339-452D-BD82-1A348A2DC663}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{7A93CDBB-D339-452D-BD82-1A348A2DC663}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7A93CDBB-D339-452D-BD82-1A348A2DC663}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
+		{7A93CDBB-D339-452D-BD82-1A348A2DC663}.Publish|Any CPU.Build.0 = Publish|Any CPU
 		{97B7BDE3-20F7-430D-A9D0-BC5D6CFDD88D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{97B7BDE3-20F7-430D-A9D0-BC5D6CFDD88D}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{97B7BDE3-20F7-430D-A9D0-BC5D6CFDD88D}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{97B7BDE3-20F7-430D-A9D0-BC5D6CFDD88D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{97B7BDE3-20F7-430D-A9D0-BC5D6CFDD88D}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
+		{97B7BDE3-20F7-430D-A9D0-BC5D6CFDD88D}.Publish|Any CPU.Build.0 = Publish|Any CPU
 		{68BDC463-F712-4CB1-8889-247A1E958D6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{68BDC463-F712-4CB1-8889-247A1E958D6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{68BDC463-F712-4CB1-8889-247A1E958D6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{68BDC463-F712-4CB1-8889-247A1E958D6A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{68BDC463-F712-4CB1-8889-247A1E958D6A}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
+		{68BDC463-F712-4CB1-8889-247A1E958D6A}.Publish|Any CPU.Build.0 = Publish|Any CPU
 		{942BE71A-B1F6-4F49-A00F-ED8077C9260D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{942BE71A-B1F6-4F49-A00F-ED8077C9260D}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{942BE71A-B1F6-4F49-A00F-ED8077C9260D}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{942BE71A-B1F6-4F49-A00F-ED8077C9260D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{942BE71A-B1F6-4F49-A00F-ED8077C9260D}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
+		{942BE71A-B1F6-4F49-A00F-ED8077C9260D}.Publish|Any CPU.Build.0 = Publish|Any CPU
+		{4777E56E-D3B2-4297-BB47-7406AC7B8B81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{4777E56E-D3B2-4297-BB47-7406AC7B8B81}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{4777E56E-D3B2-4297-BB47-7406AC7B8B81}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{4777E56E-D3B2-4297-BB47-7406AC7B8B81}.Release|Any CPU.Build.0 = Release|Any CPU
+		{4777E56E-D3B2-4297-BB47-7406AC7B8B81}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
+		{4777E56E-D3B2-4297-BB47-7406AC7B8B81}.Publish|Any CPU.Build.0 = Debug|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -116,5 +151,6 @@ Global
 		{97B7BDE3-20F7-430D-A9D0-BC5D6CFDD88D} = {9233F95A-14CB-4187-A1B3-C38F75A35D69}
 		{68BDC463-F712-4CB1-8889-247A1E958D6A} = {9233F95A-14CB-4187-A1B3-C38F75A35D69}
 		{942BE71A-B1F6-4F49-A00F-ED8077C9260D} = {9233F95A-14CB-4187-A1B3-C38F75A35D69}
+		{4777E56E-D3B2-4297-BB47-7406AC7B8B81} = {9233F95A-14CB-4187-A1B3-C38F75A35D69}
 	EndGlobalSection
 EndGlobal

+ 2 - 2
PRS.Avalonia/PRS.Avalonia.iOS/Info.plist

@@ -7,9 +7,9 @@
 	<key>CFBundleIdentifier</key>
 	<string>com.prs.avalonia</string>
 	<key>CFBundleShortVersionString</key>
-	<string>1.7</string>
+	<string>1.9</string>
 	<key>CFBundleVersion</key>
-	<string>1.7</string>
+	<string>1.9</string>
 	<key>LSRequiresIPhoneOS</key>
 	<false/>
 	<key>MinimumOSVersion</key>

+ 15 - 7
PRS.Avalonia/PRS.Avalonia.iOS/PRS.Avalonia.iOS.csproj

@@ -1,22 +1,24 @@
 <Project Sdk="Microsoft.NET.Sdk">
     <PropertyGroup>
         <OutputType>Exe</OutputType>
-        <TargetFrameworks>net8.0-ios;net9.0-ios</TargetFrameworks>
+        <TargetFramework>net9.0-ios</TargetFramework>
         <SupportedOSPlatformVersion>13.0</SupportedOSPlatformVersion>
         <Nullable>enable</Nullable>
+        <Configurations>Debug;Release;Publish</Configurations>
+        <Platforms>AnyCPU</Platforms>
 <!--        <IsAotCompatible>false</IsAotCompatible>-->
 <!--        <EnableNativeAOT>false</EnableNativeAOT>-->
 <!--        <PublishAot>false</PublishAot>-->
 <!--        <PublishAotUsingRuntimePack>false</PublishAotUsingRuntimePack>-->
-        <MtouchUseLlvm>false</MtouchUseLlvm>
+<!--        <MtouchUseLlvm>false</MtouchUseLlvm>-->
     </PropertyGroup>
     
-    <!-- Forces the use of the iOS interpreter during builds -->
+<!--     Forces the use of the iOS interpreter during builds -->
 <!--    <PropertyGroup Condition="$(TargetFramework.Contains('-ios'))">-->
 <!--        <UseInterpreter>true</UseInterpreter>-->
 <!--    </PropertyGroup>-->
 
-    <!-- Disables the new "managed-static" registrar. Could cause the app's size to be slightly larger. May enable in the future --><!-- See : https://github.com/xamarin/xamarin-macios/wiki/.NET-9-release-notes#type-registrar-managed-static-as-the-new-default -->
+<!--     Disables the new "managed-static" registrar. Could cause the app's size to be slightly larger. May enable in the future  See : https://github.com/xamarin/xamarin-macios/wiki/.NET-9-release-notes#type-registrar-managed-static-as-the-new-default -->
 <!--    <Target Name="SelectStaticRegistrar" AfterTargets="SelectRegistrar">-->
 <!--        <PropertyGroup Condition="'$(Registrar)' == 'managed-static'">-->
 <!--            <Registrar>static</Registrar>-->
@@ -25,15 +27,21 @@
     
     <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
       <CodesignKey>iPhone Developer</CodesignKey>
-      <MtouchDebug>true</MtouchDebug>
-      <IOSDebugOverWiFi>true</IOSDebugOverWiFi>
-      <CodesignProvision>PRS Avalonia Development</CodesignProvision>
+<!--      <MtouchDebug>true</MtouchDebug>-->
+<!--      <IOSDebugOverWiFi>true</IOSDebugOverWiFi>-->
+      <CodesignProvision>Development (com.prs.avalonia)</CodesignProvision>
     </PropertyGroup>
     
     <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
       <CodesignKey>iPhone Distribution</CodesignKey>
+      <CodesignProvision>Ad hoc (com.prs.avalonia)</CodesignProvision>
     </PropertyGroup>
     
+    <PropertyGroup Condition=" '$(Configuration)' == 'Publish' ">
+      <CodesignKey>iPhone Distribution</CodesignKey>
+        <CodesignProvision>App Store (com.prs.avalonia)</CodesignProvision>
+    </PropertyGroup>    
+    
     <ItemGroup>
         <ProjectReference Include="..\..\..\inabox\InABox.Avalonia.Platform.iOS\InABox.Avalonia.Platform.iOS.csproj" />
         <ProjectReference Include="..\..\..\inabox\InABox.Avalonia.Platform\InABox.Avalonia.Platform.csproj" />

+ 1 - 1
PRS.Avalonia/PRS.Avalonia/HomePage/HomePageViewModel.cs

@@ -52,7 +52,7 @@ public partial class HomePageViewModel : ViewModelBase
         Modules.Add<ViewMobileDocumentScannerModule, DocumentScannerViewModel>("Doc Scanner", "", Images.camera, isVisible: false);
         Modules.Add<ViewMobileSiteModule, SiteViewModel>("Site Module", "", Images.construction);
         Modules.Add<ViewMobileMyTasksModule, MyTasksViewModel>("My Tasks", "", Images.task, isVisible: false);
-        Modules.Add<ViewMobileWarehousingModule, WarehouseModuleViewModel>("Warehouse", "", Images.warehouse, isVisible: false);
+        Modules.Add<ViewMobileWarehousingModule, WarehouseModuleViewModel>("Warehouse", "", Images.warehouse, isVisible: true);
         Modules.Add("Update App", "", Images.version, UpdateApp, isVisible: false);
     }
     

+ 209 - 0
PRS.Avalonia/PRS.Avalonia/Modules/WarehouseModule/Common/StockLocationSelectionView.axaml

@@ -0,0 +1,209 @@
+<UserControl xmlns="https://github.com/avaloniaui"
+             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:listView="clr-namespace:PRS.Avalonia.Components.ListView"
+             xmlns:modules="clr-namespace:PRS.Avalonia.Modules"
+             xmlns:local="clr-namespace:PRS.Avalonia"
+             xmlns:converters="clr-namespace:InABox.Avalonia.Converters;assembly=InABox.Avalonia"
+             xmlns:components="clr-namespace:InABox.Avalonia.Components;assembly=InABox.Avalonia"
+             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
+             x:Class="PRS.Avalonia.Modules.StockLocationSelectionView"
+             x:DataType="modules:StockLocationSelectionViewModel">
+    <UserControl.Resources>
+        
+        <converters:StringWithDefaultConverter x:Key="WarehouseConverter" Default="(All Warehouses)" />
+        <converters:StringWithDefaultConverter x:Key="AreaConverter" Default="(All Areas)" />
+        <converters:BooleanToGridLengthConverter x:Key="MultiSelectColumnWidth" TrueValue="*" FalseValue="0.0" />
+        <converters:BoolToIntegerConverter x:Key="AddColumnConverter" TrueValue="1" FalseValue="0"/>
+        <converters:StringWithDefaultConverter x:Key="JobNumberConverter" Default="--"/>
+        <converters:BooleanToColorConverter x:Key="CurrentStockTakesConverter" True="Yellow" False="{StaticResource PrsSurfaceBackground}" />
+        <modules:StockLocationLastStockTakeConverter x:Key="LastStockTakeConverter" />
+        <modules:StockLocationStockTakeStatusConverter x:Key="StockTakeStatusConverter" />
+        <modules:StockLocationStockTakeColorConverter x:Key="StockTakeColorConverter" />
+        
+        <converters:BooleanToBooleanConverter x:Key="NotTrue" Invert="True" />
+        <converters:BooleanMatcher x:Key="MatchAll" Type="All" Value="True" /> 
+        
+        <DataTemplate x:Key="LocationTemplate" x:DataType="local:StockLocationShell">
+            <Button Classes="Standard"
+                Command="{Binding $parent[listView:PrsListView].((modules:StockLocationSelectionViewModel)DataContext).SelectLocationCommand}"
+                CommandParameter="{Binding .}"
+                Background="{Binding ., Converter={StaticResource StockTakeColorConverter}}"
+                Height="40"
+                Margin="0,0,0,5"
+                Padding="4">
+                <Button.Content>
+                    <Grid>
+                        <Grid.RowDefinitions>
+                            <RowDefinition Height="*"/>
+                            <RowDefinition Height="Auto" />
+                        </Grid.RowDefinitions>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="Auto"/>
+                            <ColumnDefinition Width="100"/>
+                            <ColumnDefinition Width="*" />
+                            <ColumnDefinition Width="100"/>
+                        </Grid.ColumnDefinitions>
+                        
+                        <Image
+                            Grid.Row="0"
+                            Grid.RowSpan="2"
+                            Grid.Column="0"
+                            Source="{SvgImage /Images/notification.svg}"
+                            Margin="0,0,5,0"
+                            Stretch="UniformToFill"
+                            VerticalAlignment="Center"
+                            HorizontalAlignment="Center"
+                            IsVisible="{Binding ., Converter={StaticResource StockTakeStatusConverter}}"/>
+                        
+                        <DockPanel
+                            Grid.Row="0"
+                            Grid.Column="1"
+                            Grid.ColumnSpan="3"
+                            HorizontalAlignment="Stretch">
+                            <Label 
+                                DockPanel.Dock="Left"
+                                Content="{Binding Code}" 
+                                FontSize="{StaticResource PrsFontSizeExtraSmall}"
+                                Foreground="{StaticResource {StaticResource PrsSurfaceBackground}}" 
+                                HorizontalContentAlignment="Center"
+                                VerticalContentAlignment="Center"/>
+                            <Label 
+                                DockPanel.Dock="Left"
+                                Content=" : " 
+                                FontSize="{StaticResource PrsFontSizeExtraSmall}"
+                                Foreground="{StaticResource PrsSurfaceForeground}" 
+                                HorizontalContentAlignment="Center"
+                                VerticalContentAlignment="Center"/>                               
+                            <Label 
+                                DockPanel.Dock="Left"
+                                Content="{Binding Description}" 
+                                FontSize="{StaticResource PrsFontSizeExtraSmall}"
+                                Foreground="{StaticResource {StaticResource PrsSurfaceBackground}}" 
+                                HorizontalContentAlignment="Center"
+                                VerticalContentAlignment="Center"/>
+                            
+                            <Label 
+                                DockPanel.Dock="Left"
+                                Content="{Binding ., Converter={StaticResource LastStockTakeConverter}}" 
+                                FontSize="{StaticResource PrsFontSizeExtraSmall}"
+                                Foreground="{StaticResource {StaticResource PrsSurfaceBackground}}" 
+                                HorizontalContentAlignment="Right"
+                                VerticalContentAlignment="Center"
+                            />
+
+                        </DockPanel>
+                        
+                        <Label 
+                            Grid.Row="1"
+                            Grid.Column="1"
+                            Content="{Binding JobNumber, Converter={StaticResource JobNumberConverter}, StringFormat='Job : {0}'}" 
+                            FontSize="{StaticResource PrsFontSizeExtraSmall}"
+                            Foreground="{StaticResource {StaticResource PrsSurfaceBackground}}" 
+                            HorizontalContentAlignment="Left"
+                            VerticalContentAlignment="Center"
+                            />
+                        
+                        <DockPanel
+                            Grid.Row="1"
+                            Grid.Column="2"
+                            HorizontalAlignment="Center">
+                            <Label 
+                                DockPanel.Dock="Right"
+                                Content="{Binding AreaCode}" 
+                                FontSize="{StaticResource PrsFontSizeExtraSmall}"
+                                Foreground="{StaticResource {StaticResource PrsSurfaceBackground}}" 
+                                VerticalContentAlignment="Center"/>
+                            <Label 
+                                DockPanel.Dock="Right"
+                                Content=" / " 
+                                FontSize="{StaticResource PrsFontSizeExtraSmall}"
+                                Foreground="{StaticResource {StaticResource PrsSurfaceBackground}}" 
+                                VerticalContentAlignment="Center"/>
+                            <Label 
+                                DockPanel.Dock="Right"
+                                Content="{Binding WarehouseCode}" 
+                                FontSize="{StaticResource PrsFontSizeExtraSmall}"
+                                Foreground="{StaticResource {StaticResource PrsSurfaceBackground}}" 
+                                VerticalContentAlignment="Center"/>
+                        </DockPanel>
+                        
+                        <Label 
+                            Grid.Row="1"
+                            Grid.Column="3"
+                            Content="{Binding Holdings, StringFormat='Items : {0}'}" 
+                            FontSize="{StaticResource PrsFontSizeExtraSmall}"
+                            Foreground="{StaticResource {StaticResource PrsSurfaceBackground}}" 
+                            HorizontalContentAlignment="Right"
+                            VerticalContentAlignment="Center"/>
+                        
+                    </Grid>
+                </Button.Content>
+            </Button>
+        </DataTemplate>
+        
+    </UserControl.Resources>
+    
+    <Grid>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="*" />
+            <RowDefinition Height="Auto"/>
+        </Grid.RowDefinitions>
+        
+        <components:PageStack
+            Grid.Row="0"
+            SelectedIndex="{Binding SelectedIndex, ElementName=Buttons}">
+        
+            <components:PageStackItem>
+                
+                <Grid>
+                    <Grid.RowDefinitions>
+                        <RowDefinition Height="Auto"/>
+                        <RowDefinition Height="Auto"/>
+                        <RowDefinition Height="*"/>
+                    </Grid.RowDefinitions>
+                    
+                    <Button
+                        x:Name="Warehouse"
+                        Grid.Row="0"
+                        Margin="0,5,0,0"
+                        Content="{Binding Warehouse.Description, Converter={StaticResource WarehouseConverter}}"
+                        Command="{Binding SelectWarehouseCommand}"
+                        />
+                
+                    <Button
+                        x:Name="Area"
+                        Grid.Row="1"
+                        Margin="0,5,0,0"
+                        Content="{Binding Area.Description, Converter={StaticResource AreaConverter}}"
+                        Command="{Binding SelectAreaCommand}"/>
+                    
+                <listView:PrsListView
+                    Grid.Row="2"
+                    Margin="0,5,0,0"
+                    ItemTemplate="{StaticResource LocationTemplate}"
+                    Repository="{Binding Locations}"/>
+                
+                </Grid>
+            </components:PageStackItem>
+            
+        </components:PageStack>
+        
+        <components:ButtonStrip
+            x:Name="Buttons"
+            Grid.Row="1"
+            Margin="0,5,0,0"
+            SelectedIndex="1">
+            
+            <components:ButtonStripItem 
+                Text="Locations" />
+            
+            <components:ButtonStripItem 
+                Text="Favourites" />
+        </components:ButtonStrip>
+        
+    </Grid>
+    
+
+</UserControl>

+ 66 - 0
PRS.Avalonia/PRS.Avalonia/Modules/WarehouseModule/Common/StockLocationSelectionView.axaml.cs

@@ -0,0 +1,66 @@
+using System;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using Avalonia.Media;
+using Comal.Classes;
+using InABox.Avalonia.Converters;
+using InABox.Core;
+
+namespace PRS.Avalonia.Modules;
+
+public class StockLocationStockTakeColorConverter : AbstractConverter<StockLocationShell, IBrush>
+{
+        
+    public bool Active { get; set; }
+
+    protected override IBrush Convert(StockLocationShell? value, object? parameter = null)
+    {
+        return !Active || value == null
+            ? Brushes.LightYellow
+            : !value.CurrentStocktake.IsEmpty()
+                ? Brushes.Yellow               
+                : value.StocktakeFrequency == StockTakeFrequency.Never
+                    ? Brushes.Gainsboro
+                    : value.NextStocktake.Date > DateTime.Today
+                        ? Brushes.LightGreen
+                        : Brushes.Orange;
+    }
+}
+
+public class StockLocationStockTakeStatusConverter : AbstractConverter<StockLocationShell, bool>
+{
+    public bool Active { get; set; }
+    
+    protected override bool Convert(StockLocationShell? value, object? parameter = null)
+    {
+        return Active && value != null && !value.CurrentStocktake.IsEmpty();
+    }
+}
+
+public class StockLocationLastStockTakeConverter : AbstractConverter<StockLocationShell, string>
+{
+        
+    public bool Active { get; set; }
+        
+    protected override string? Convert(StockLocationShell? value, object? parameter = null)
+    {
+        return !Active || value == null
+            ? ""
+            : !value.CurrentStocktake.IsEmpty()
+                ? "Stocktake In Progress"
+                : value.StocktakeFrequency == StockTakeFrequency.Never
+                    ? value.LastStocktake.IsEmpty()
+                        ? $"Last Stocktake : Never"
+                        : $"Last Stocktake : {value.LastStocktake:dd MMM yy}"
+                    : $"Stocktake Due : {value.NextStocktake:dd MMM yy}";
+    }
+}
+
+public partial class StockLocationSelectionView : UserControl
+{
+    public StockLocationSelectionView()
+    {
+        InitializeComponent();
+    }
+}

+ 166 - 0
PRS.Avalonia/PRS.Avalonia/Modules/WarehouseModule/Common/StockLocationSelectionViewModel.cs

@@ -0,0 +1,166 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Linq;
+using System.Threading.Tasks;
+using Avalonia;
+using Avalonia.Media;
+using Avalonia.Threading;
+using Comal.Classes;
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using InABox.Avalonia.Components;
+using InABox.Core;
+
+namespace PRS.Avalonia.Modules;
+
+public class StockLocationSelectionViewModelOptions
+{
+
+    //public Guid[] ExcludeLocations { get; set; } = { };
+    //public bool MultiSelect { get; set; } = false;
+    //public bool AllowAdd { get; set; } = true;
+    public bool ShowFavourites { get; set; } = true;
+    public String Title { get; set; } = "Select Location";
+    public bool DisplayStockTakeInfo { get; set; } = false;
+    public bool IncludeInactive { get; set; } = false;
+    //public bool PullToRefresh { get; set; }
+}
+
+public partial class StockLocationSelectionViewModel : ModuleViewModel
+{
+    
+    public override string Title => Options.Title;
+    
+    public StockLocationSelectionViewModelOptions Options { get; private set; } = new();
+    
+    public StockLocationModel Locations { get; }
+    
+    [ObservableProperty] 
+    private StockWarehouseShell _warehouse = new();
+    partial void OnWarehouseChanged(StockWarehouseShell? value) 
+        => Area = new StockAreaShell();
+    
+    [ObservableProperty] private StockAreaShell _area = new();
+    
+    partial void OnAreaChanged(StockAreaShell? value)
+        => LocationsChanged();
+    
+    [ObservableProperty] private IEnumerable<Guid> _excluded = [];
+    
+    partial void OnExcludedChanged(IEnumerable<Guid>? value)
+        => LocationsChanged();
+    
+
+
+    [ObservableProperty] private string _searchText;
+    
+    //[ObservableProperty] private IEnumerable<StockLocationShell> _visible = [];
+    
+    [ObservableProperty] private bool _multiSelect;
+    
+    public CoreObservableCollection<StockLocationShell> Selected { get; }
+    
+    [ObservableProperty] 
+    private DateTime _lastUpdated;
+
+    [ObservableProperty] 
+    private bool _currentStockTakesOnly;
+
+    partial void OnCurrentStockTakesOnlyChanged(bool value)
+    {
+        Locations.RefreshAsync(false);
+    }
+
+    public StockLocationSelectionViewModel()
+    {
+        PrimaryMenu.Add(
+            new AvaloniaMenuItem(Images.lines, BuildMenu)
+        );
+        
+        Locations = new(
+            DataAccess, 
+            () => new Filter<StockLocation>().All(),
+            () => nameof(StockLocationSelectionViewModel)
+        );
+        
+        Locations.Changed += (sender, args) => LocationsChanged();
+        Locations.SearchPredicate = x =>
+            !Excluded.Contains(x.ID)
+            && (!Options.IncludeInactive || x.Active)
+            && (!Options.ShowFavourites || x.Favourite)
+            && (!CurrentStockTakesOnly || !x.CurrentStocktake.IsEmpty())
+            && (Area.ID == Guid.Empty || x.AreaID == Area.ID)
+            && (Warehouse.ID == Guid.Empty || x.WarehouseID == Warehouse.ID)
+            && (String.IsNullOrWhiteSpace(SearchText)
+                || x.Code.ToUpper().Contains(SearchText.ToUpper())
+                || x.Description.ToUpper().Contains(SearchText.ToUpper()));
+        
+        Selected = new();
+        Selected.CollectionChanged += SelectedChanged;
+    }
+    
+    private CoreMenu<IImage>? BuildMenu()
+    {
+        var menu = new CoreMenu<IImage>();
+        menu.AddItem(
+            "Current Stocktakes Only",
+            CurrentStockTakesOnly ? Images.tick : null, async () => 
+            {
+                await Dispatcher.UIThread.InvokeAsync(() => CurrentStockTakesOnly = !CurrentStockTakesOnly);
+                return true;
+            },
+            null
+        );
+        return menu;
+    }
+
+    protected override async Task<TimeSpan> OnRefresh()
+    {
+        await Locations.RefreshAsync(false);
+        return TimeSpan.Zero;
+    }
+
+    [RelayCommand]
+    private void SelectWarehouse()
+    {
+        
+    }
+    
+    [RelayCommand]
+    private void SelectArea()
+    {
+        
+    }
+
+    private void LocationsChanged()
+    {
+        //var selectedids = Selected.Select(x => x.ID).ToArray() ?? [];
+        // Visible = _locationModel.Items.Where(x =>
+        //     !Excluded.Contains(x.ID)
+        //     && (!IncludeInactive || x.Active)
+        //     && (!Favourites || x.Favourite)
+        //     && (!CurrentStockTakesOnly || !x.CurrentStocktake.IsEmpty())
+        //     && (Area.ID == Guid.Empty || x.AreaID == Area.ID)
+        //     && (Warehouse.ID == Guid.Empty || x.WarehouseID == Warehouse.ID)
+        //     && (String.IsNullOrWhiteSpace(SearchText)
+        //         || x.Code.ToUpper().Contains(SearchText.ToUpper())
+        //         || x.Description.ToUpper().Contains(SearchText.ToUpper()))
+        // );
+
+        //Selected.ReplaceRange(Visible.Where(x => selectedids.Contains(x.ID)));
+    }
+
+    [RelayCommand]
+    private void SelectLocation(StockWarehouseShell? value)
+    {
+        
+    }
+    
+    private void SelectedChanged(object? sender, NotifyCollectionChangedEventArgs e)
+    {
+        // Trigger Event Here
+    }
+
+
+}

+ 7 - 2
PRS.Avalonia/PRS.Avalonia/Modules/WarehouseModule/WarehouseModuleViewModel.cs

@@ -27,10 +27,15 @@ public partial class WarehouseModuleViewModel : ModuleViewModel
             "Shift a Location to different Area",
             Images.stock_relocate);
         
-        Modules.Add<WarehouseStockTakeViewModel>(
+        Modules.Add<StockLocationSelectionViewModel>(
             "Stock Take", 
             "Perform a Stock Take on a Location", 
-            Images.stock_stocktake);
+            Images.stock_stocktake,
+            (model) =>
+            {
+                model.Options.Title = "Select Location for Stock Take";
+                model.Options.DisplayStockTakeInfo = true;
+            });
         
         Modules.Add<WarehousePickingListsViewModel>(
             "Picking Lists", 

+ 12 - 0
PRS.Avalonia/PRS.Avalonia/Modules/WarehouseModule/WarehouseStockTake/WarehouseStockTakeView.axaml

@@ -0,0 +1,12 @@
+<UserControl xmlns="https://github.com/avaloniaui"
+             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:modules="clr-namespace:PRS.Avalonia.Modules"
+             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
+             x:Class="PRS.Avalonia.Modules.WarehouseStockTakeView"
+             x:DataType="modules:WarehouseStockTakeViewModel">
+    <UserControl.Resources>
+        
+    </UserControl.Resources>
+</UserControl>

+ 13 - 0
PRS.Avalonia/PRS.Avalonia/Modules/WarehouseModule/WarehouseStockTake/WarehouseStockTakeView.axaml.cs

@@ -0,0 +1,13 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace PRS.Avalonia.Modules;
+
+public partial class WarehouseStockTakeView : UserControl
+{
+    public WarehouseStockTakeView()
+    {
+        InitializeComponent();
+    }
+}

+ 4 - 1
PRS.Avalonia/PRS.Avalonia/PRS.Avalonia.csproj

@@ -3,7 +3,8 @@
         <TargetFrameworks>net8.0;net9.0</TargetFrameworks>
         <Nullable>enable</Nullable>
         <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
-        <Configurations>Debug;Release;DebugDev</Configurations>
+        <Configurations>Debug;Release;DebugDev;Publish</Configurations>
+        <Platforms>AnyCPU</Platforms>
     </PropertyGroup>
 
 	<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDev|AnyCPU'">
@@ -303,6 +304,8 @@
 
     <ItemGroup>
         
+        <PackageReference Include="Avalonia.Skia" Version="11.2.2" />
+        
         <PackageReference Include="Avalonia.Svg.Skia" Version="11.2.0.2" />
         <PackageReference Include="Avalonia.Controls.ColorPicker" Version="11.2.2" />
         <PackageReference Include="Avalonia.Themes.Fluent" Version="11.2.2" />

+ 1 - 1
PRS.Avalonia/PRS.Avalonia/Repositories/StockLocation/StockLocationModel.cs

@@ -7,7 +7,7 @@ namespace PRS.Avalonia;
 
 public class StockLocationModel : CoreRepository<StockLocationModel, StockLocationShell, StockLocation>
 {
-    public StockLocationModel(IModelHost host, Func<Filter<StockLocation>> filter) : base(host, filter)
+    public StockLocationModel(IModelHost host, Func<Filter<StockLocation>> filter, Func<string>? filename = null) : base(host, filter, filename)
     {
     }
 }

+ 1 - 1
PRS.Avalonia/PRS.Avalonia/ViewModelBase.cs

@@ -20,7 +20,7 @@ using PRS.Avalonia.Dialogs;
 
 namespace PRS.Avalonia;
 
-public abstract partial class ViewModelBase : ObservableObject, IViewModelBase
+public abstract partial class ViewModelBase : ObservableValidator, IViewModelBase
 {
     private static DataAccessLayer? _dataAccessLayer;
 

+ 2 - 0
PRS.DigitalKey/PRS.DigitalKey.iOS/PRS.DigitalKey.iOS.csproj

@@ -9,6 +9,8 @@
         <PublishTrimmed>True</PublishTrimmed>
         <IsTrimmable>True</IsTrimmable>
         <RuntimeIdentifier>ios-arm64</RuntimeIdentifier>
+        <Configurations>Debug;Release;Publish</Configurations>
+        <Platforms>AnyCPU</Platforms>
     </PropertyGroup>
 
     <PropertyGroup>

+ 2 - 0
PRS.DigitalKey/PRS.DigitalKey/PRS.DigitalKey.csproj

@@ -4,6 +4,8 @@
         <TargetFrameworks>net8.0;net9.0</TargetFrameworks>
         <ImplicitUsings>enable</ImplicitUsings>
         <Nullable>enable</Nullable>
+        <Configurations>Debug;Release;Publish</Configurations>
+        <Platforms>AnyCPU</Platforms>
     </PropertyGroup>
     
     <ItemGroup>

+ 2 - 1
prs.classes/PRSClasses.csproj

@@ -3,8 +3,9 @@
     <PropertyGroup>
         <RootNamespace>Comal.Classes</RootNamespace>
 		<Nullable>enable</Nullable>
-		<Configurations>Debug;Release;Test</Configurations>
+		<Configurations>Debug;Release;Test;Publish</Configurations>
 		<TargetFramework>netstandard2.1</TargetFramework>
+		<Platforms>AnyCPU</Platforms>
     </PropertyGroup>
 
     <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">