Compare commits

...

4 Commits

12 changed files with 498 additions and 3 deletions

View File

@ -0,0 +1,112 @@
<UserControl x:Class="ENI2.Controls.EasyPeasyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ENI2.Controls"
mc:Ignorable="d"
d:DesignHeight="650" d:DesignWidth="800" Loaded="UserControl_Loaded" Unloaded="UserControl_Unloaded">
<DockPanel>
<!-- Header with logo -->
<Border DockPanel.Dock="Top" Padding="10" Background="#FFFDF6">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" >
<!-- Embed SVG via Image (optional): place your SVG as a DrawingImage in resources, or replace with PNG -->
<TextBlock Text="🍋 easy-peasy" FontSize="20" FontWeight="Bold" Margin="0,0,16,0"/>
<TextBlock Text="Edit • Paste • Export XML" VerticalAlignment="Center"/>
</StackPanel>
</Border>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel Margin="12" Orientation="Vertical" >
<!-- Top-level fields -->
<UniformGrid Columns="4" Rows="3" Margin="0,0,0,12">
<TextBlock Text="DelegateIdentificationType" />
<TextBox Text="{Binding DelegateIdentificationType, UpdateSourceTrigger=PropertyChanged}" Margin="2" />
<TextBlock Text="TraderIdentificationType" />
<TextBox Text="{Binding TraderIdentificationType, UpdateSourceTrigger=PropertyChanged}" Margin="2" />
<TextBlock Text="LRN" />
<TextBox Text="{Binding LRN, UpdateSourceTrigger=PropertyChanged}" Margin="2" />
<TextBlock Text="TraderIdentificationNumber" />
<TextBox Text="{Binding TraderIdentificationNumber, UpdateSourceTrigger=PropertyChanged}" Margin="2" />
<TextBlock Text="Country" />
<TextBox Text="{Binding Country, UpdateSourceTrigger=PropertyChanged}" Margin="2" />
<TextBlock Text="DelegateIdentificationNumber" />
<TextBox Text="{Binding DelegateIdentificationNumber, UpdateSourceTrigger=PropertyChanged}" Margin="2" />
</UniformGrid>
<!-- ProofInformation -->
<GroupBox Header="ProofInformationT2LT2LF">
<StackPanel Margin="8">
<UniformGrid Columns="4" Rows="4" Margin="0,0,0,12">
<TextBlock Text="CompetentCustomsOffice"/>
<TextBox Text="{Binding ProofInformationT2LT2LF.CompetentCustomsOffice, UpdateSourceTrigger=PropertyChanged}" Margin="2" />
<TextBlock Text="DeclarationType"/>
<TextBox Text="{Binding ProofInformationT2LT2LF.DeclarationType, UpdateSourceTrigger=PropertyChanged}" Margin="2" />
<TextBlock Text="DeclarationDate (yyyy-MM-ddTHH:mm:ss)"/>
<TextBox Text="{Binding ProofInformationT2LT2LF.DeclarationDate, StringFormat={}{0:yyyy-MM-ddTHH:mm:ss}, UpdateSourceTrigger=PropertyChanged}" Margin="2" />
<TextBlock Text="TotalGrossMassKg"/>
<TextBox Text="{Binding ProofInformationT2LT2LF.TotalGrossMassKg, UpdateSourceTrigger=PropertyChanged}" Margin="2" />
<TextBlock Text="RequestedValidityOfTheProof.NumberOfDays"/>
<TextBox Text="{Binding ProofInformationT2LT2LF.RequestedValidityOfTheProof.NumberOfDays, UpdateSourceTrigger=PropertyChanged}" Margin="2" />
<TextBlock Text="RequestType"/>
<TextBox Text="{Binding ProofInformationT2LT2LF.RequestType, UpdateSourceTrigger=PropertyChanged}" Margin="2" />
</UniformGrid>
<GroupBox Header="LocationOfGoods">
<UniformGrid Columns="6" Margin="8">
<TextBlock Text="TypeOfLocation"/>
<TextBox Text="{Binding ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF.LocationOfGoods.TypeOfLocation}" Margin="2" />
<TextBlock Text="QualifierOfIdentification"/>
<TextBox Text="{Binding ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF.LocationOfGoods.QualifierOfIdentification}" Margin="2" />
<TextBlock Text="UNLocode"/>
<TextBox Text="{Binding ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF.LocationOfGoods.UNLocode}" Margin="2" />
</UniformGrid>
</GroupBox>
<CheckBox Content="ContainerIndication"
IsChecked="{Binding ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF.ContainerIndication}"/>
<!-- Goods Items grid (paste target) -->
<TextBlock Text="GoodsItemsForT2LT2LF (Paste tab/CSV with columns: HS, Item#, Description, Gross, Net, Pkgs, Type, Marks)" Margin="0,12,0,4"/>
<DataGrid ItemsSource="{Binding ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF.GoodsItemsForT2LT2LF}"
AutoGenerateColumns="False" CanUserAddRows="True"
PreviewKeyDown="DataGrid_PreviewKeyDown" >
<DataGrid.Columns>
<DataGridTextColumn Header="HS Code" Binding="{Binding Commodity.HarmonizedSystemSubHeadingCode}"/>
<DataGridTextColumn Header="Item #" Binding="{Binding GoodsItemNumber}"/>
<DataGridTextColumn Header="Description" Binding="{Binding DescriptionOfGoods}" Width="2*"/>
<DataGridTextColumn Header="Gross" Binding="{Binding GoodsMeasure.GrossMass}"/>
<DataGridTextColumn Header="Net" Binding="{Binding GoodsMeasure.NetMass}"/>
<DataGridTextColumn Header="Pkgs" Binding="{Binding Packaging.NumberOfPackages}"/>
<DataGridTextColumn Header="Type" Binding="{Binding Packaging.TypeOfPackages}"/>
<DataGridTextColumn Header="Marks" Binding="{Binding Packaging.ShippingMarks}" Width="*"/>
</DataGrid.Columns>
</DataGrid>
<GroupBox Header="TransportDocuments" Margin="0,12,0,0">
<UniformGrid Columns="4" Margin="8">
<TextBlock Text="Type"/>
<TextBox Text="{Binding ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF.TransportDocuments.Type}" Margin="2" />
<TextBlock Text="ReferenceNumber"/>
<TextBox Text="{Binding ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF.TransportDocuments.ReferenceNumber}" Margin="2" />
</UniformGrid>
</GroupBox>
</StackPanel>
</GroupBox>
<!-- Actions -->
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,16,0,0">
<Button x:Name="buttonImport" Content="Import" Width="100" Margin="0,0,8,0" Click="buttonImport_Click" />
<Button x:Name="buttonClear" Content="Clear" Width="100" Margin="0,0,8,0" Click="buttonClear_Click"/>
<Button x:Name="buttonExport" Content="Export" Width="120" Click="buttonExport_Click"/>
</StackPanel>
</StackPanel>
</ScrollViewer>
</DockPanel>
</UserControl>

View File

@ -0,0 +1,196 @@
// Copyright (c) 2017- schick Informatik
// Description: Display dialog for customs XML data upload app
//
using bsmd.database.EasyPeasy;
using ENI2.Util;
using Microsoft.Office.Interop.Excel;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;
using System.Xml.Serialization;
namespace ENI2.Controls
{
/// <summary>
/// Interaction logic for EasyPeasyControl.xaml
/// </summary>
public partial class EasyPeasyControl : UserControl
{
private ProofRequest _vm;
public EasyPeasyControl()
{
InitializeComponent();
}
private void DataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.V && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
if (Clipboard.ContainsText())
{
var text = Clipboard.GetText();
PasteGoodsItems(text);
e.Handled = true;
}
}
}
private void buttonClear_Click(object sender, RoutedEventArgs e)
{
this._vm = EasyPeasyState.CreateDefault();
this.DataContext = this._vm;
}
private void buttonExport_Click(object sender, RoutedEventArgs e)
{
var dlg = new SaveFileDialog
{
FileName = "proofRequest.xml",
Filter = "XML file|*.xml",
OverwritePrompt = true
};
if (dlg.ShowDialog() == true)
{
try
{
var ser = new XmlSerializer(typeof(ProofRequest));
// Namespaces (if needed)
// var ns = new XmlSerializerNamespaces();
// ns.Add("xsd", "http://www.w3.org/2001/XMLSchema");
// ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
var settings = new XmlWriterSettings
{
Indent = true,
OmitXmlDeclaration = true
};
using (var fs = File.Create(dlg.FileName))
using (var xw = XmlWriter.Create(fs, settings))
{
ser.Serialize(xw, _vm); //, ns);
}
MessageBox.Show("Exported successfully.", "easy-peasy", MessageBoxButton.OK, MessageBoxImage.Information);
}
catch (Exception ex)
{
MessageBox.Show("Export failed:\n" + ex.Message, "easy-peasy", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
_vm = EasyPeasyState.LoadOrCreate();
if (_vm.ProofInformationT2LT2LF == null)
_vm.ProofInformationT2LT2LF = new ProofInformationT2LT2LF();
if (_vm.ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF == null)
_vm.ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF = new GoodsShipmentForT2LT2LF
{
LocationOfGoods = new LocationOfGoods(),
TransportDocuments = new TransportDocuments()
};
this.DataContext = _vm;
}
private void UserControl_Unloaded(object sender, RoutedEventArgs e)
{
try
{
EasyPeasyState.Save(_vm);
}
catch { }
}
private void PasteGoodsItems(string text)
{
if (_vm?.ProofInformationT2LT2LF?.GoodsShipmentForT2LT2LF == null) return;
var lines = text.Replace("\r\n", "\n").Replace('\r', '\n')
.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
// Split by tab first; if only one column, try CSV
var cells = line.Split('\t');
if (cells.Length == 1) cells = SplitCsv(line);
// Expected order: HS, Item#, Description, Gross, Net, Pkgs, Type, Marks
var item = new GoodsItemForT2LT2LF();
if (cells.Length > 0) item.Commodity.HarmonizedSystemSubHeadingCode = cells[0].Trim();
if (cells.Length > 1 && int.TryParse(cells[1], out var n)) item.GoodsItemNumber = n;
if (cells.Length > 2) item.DescriptionOfGoods = cells[2].Trim();
if (cells.Length > 3 && decimal.TryParse(cells[3], out var gross)) item.GoodsMeasure.GrossMass = gross;
if (cells.Length > 4 && decimal.TryParse(cells[4], out var net)) item.GoodsMeasure.NetMass = net;
if (cells.Length > 5 && int.TryParse(cells[5], out var pkgs)) item.Packaging.NumberOfPackages = pkgs;
if (cells.Length > 6) item.Packaging.TypeOfPackages = cells[6].Trim();
if (cells.Length > 7) item.Packaging.ShippingMarks = cells[7].Trim();
_vm.ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF.GoodsItemsForT2LT2LF.Add(item);
}
}
// Very small CSV splitter (handles quotes)
private static string[] SplitCsv(string line)
{
var res = new System.Collections.Generic.List<string>();
var sb = new StringBuilder();
bool inQuotes = false;
for (int i = 0; i < line.Length; i++)
{
char c = line[i];
if (c == '\"')
{
if (inQuotes && i + 1 < line.Length && line[i + 1] == '\"')
{ sb.Append('\"'); i++; }
else { inQuotes = !inQuotes; }
}
else if (c == ',' && !inQuotes)
{ res.Add(sb.ToString()); sb.Clear(); }
else { sb.Append(c); }
}
res.Add(sb.ToString());
return res.ToArray();
}
private void buttonImport_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "XML file|*.xml";
ofd.RestoreDirectory = true;
ofd.Multiselect = false;
if (ofd.ShowDialog() == true)
{
using (var fs = File.OpenRead(ofd.FileName))
{
var ser = new XmlSerializer(typeof(ProofRequest));
_vm = (ProofRequest)ser.Deserialize(fs);
this.DataContext = _vm;
}
}
}
}
}

View File

@ -37,7 +37,7 @@
<CreateWebPageOnPublish>true</CreateWebPageOnPublish>
<WebPage>publish.html</WebPage>
<ApplicationRevision>8</ApplicationRevision>
<ApplicationVersion>7.2.10.8</ApplicationVersion>
<ApplicationVersion>7.2.12.0</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<CreateDesktopShortcut>true</CreateDesktopShortcut>
<PublishWizardCompleted>true</PublishWizardCompleted>
@ -297,6 +297,9 @@
<Compile Include="Controls\ConditionGroupControl.xaml.cs">
<DependentUpon>ConditionGroupControl.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\EasyPeasyControl.xaml.cs">
<DependentUpon>EasyPeasyControl.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\EditWindowBase.cs" />
<Compile Include="Controls\ENIDataGrid.cs" />
<Compile Include="Controls\IHighlightControlContainer.cs" />
@ -558,6 +561,7 @@
<Compile Include="Util\ByteConverter.cs" />
<Compile Include="Util\CutoffConverter.cs" />
<Compile Include="Util\DatabaseEntityWatchdog.cs" />
<Compile Include="Util\EasyPeasyState.cs" />
<Compile Include="Util\EnumHelper.cs" />
<Compile Include="Util\EnumToBooleanConverter.cs" />
<Compile Include="Util\EnumToCollectionConverter.cs" />
@ -587,6 +591,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Controls\EasyPeasyControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Controls\LocodeControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View File

@ -95,6 +95,7 @@
<MenuItem x:Name="menuItemUserAdministration" Header="{x:Static p:Resources.textUserAdministration}" Click="radioButton_Click" Visibility="Hidden"/>
<MenuItem x:Name="menuItemMaersk" Header="{x:Static p:Resources.textPOLists}" Click="radioButton_Click" Visibility="Hidden" />
<MenuItem x:Name="menuItemValueMappings" Header="{x:Static p:Resources.textExcelValueMappings}" Click="radioButton_Click" Visibility="Hidden" />
<MenuItem x:Name="menuItemEasyPeasy" Header="{x:Static p:Resources.textEasyPeasy}" Click="radioButton_Click" Visibility="Hidden" />
<MenuItem x:Name="labelStatusId" />
<MenuItem Header="Help" HorizontalAlignment="Right">
<MenuItem Header="Change Password" Click="buttonChangePassword_Click">

View File

@ -39,6 +39,7 @@ namespace ENI2
private ServerStatusControl statusControl;
private readonly SucheControl sucheControl;
private CompareExcelDialog compareExcelDialog;
private EasyPeasyControl easyPeasyControl;
private bool dbConnected;
private readonly ScaleTransform _transform = new ScaleTransform(1.0, 1.0);
@ -324,6 +325,14 @@ namespace ENI2
}
this.rootContainer.Children.Add(this.vmControl);
}
else if(sender == this.menuItemEasyPeasy)
{
if(this.easyPeasyControl == null)
{
this.easyPeasyControl = new EasyPeasyControl();
}
this.rootContainer.Children.Add(this.easyPeasyControl);
}
}
private void buttonCompareSheets_Click(object sender, RoutedEventArgs ev)
@ -690,6 +699,7 @@ namespace ENI2
ReportingParty.CurrentReportingParty = this.userEntity;
this.menuItemMaersk.Visibility = Visibility.Visible;
this.menuItemValueMappings.Visibility = Visibility.Visible;
this.menuItemEasyPeasy.Visibility = Visibility.Visible;
if (this.userEntity.IsAdmin)
{
this.menuItemUserAdministration.Visibility = Visibility.Visible;
@ -753,5 +763,6 @@ namespace ENI2
#endregion
}
}

View File

@ -2871,6 +2871,15 @@ namespace ENI2.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Easy Peasy 🍋.
/// </summary>
public static string textEasyPeasy {
get {
return ResourceManager.GetString("textEasyPeasy", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to _Edit.
/// </summary>

View File

@ -2265,4 +2265,7 @@ New entry: {1}
Proceed?</value>
</data>
<data name="textEasyPeasy" xml:space="preserve">
<value>Easy Peasy 🍋</value>
</data>
</root>

View File

@ -0,0 +1,63 @@
// Copyright (c) 2017- schick Informatik
// Description: Helper class for customs data serialization
//
using bsmd.database.EasyPeasy;
using System;
using System.IO;
using System.Xml.Serialization;
namespace ENI2.Util
{
public static class EasyPeasyState
{
private static readonly string Root = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"EasyPeasy");
private static readonly string StatePath = Path.Combine(Root, "state.xml");
public static ProofRequest LoadOrCreate()
{
try
{
if (File.Exists(StatePath))
{
using (var fs = File.OpenRead(StatePath))
{
var ser = new XmlSerializer(typeof(ProofRequest));
return (ProofRequest)ser.Deserialize(fs);
}
}
}
catch { /* swallow & create new */ }
return CreateDefault();
}
public static void Save(ProofRequest data)
{
Directory.CreateDirectory(Root);
using (var fs = File.Create(StatePath))
{
var ser = new XmlSerializer(typeof(ProofRequest));
ser.Serialize(fs, data);
}
}
public static ProofRequest CreateDefault()
{
return new ProofRequest
{
ProofInformationT2LT2LF = new ProofInformationT2LT2LF
{
RequestedValidityOfTheProof = new RequestedValidityOfTheProof(),
GoodsShipmentForT2LT2LF = new GoodsShipmentForT2LT2LF
{
LocationOfGoods = new LocationOfGoods(),
TransportDocuments = new TransportDocuments()
}
}
};
}
}
}

View File

@ -0,0 +1,91 @@
// Copyright (c) 2024-present schick Informatik
// Description: Collection of classes for the customs XML upload app
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
namespace bsmd.database.EasyPeasy
{
// Root: <proofRequest>
[XmlRoot("proofRequest")]
public class ProofRequest
{
public string DelegateIdentificationType { get; set; }
public string TraderIdentificationType { get; set; }
public string LRN { get; set; }
public string TraderIdentificationNumber { get; set; }
public string Country { get; set; }
public ProofInformationT2LT2LF ProofInformationT2LT2LF { get; set; }
public string DelegateIdentificationNumber { get; set; }
}
public class ProofInformationT2LT2LF
{
public string CompetentCustomsOffice { get; set; }
public string DeclarationType { get; set; }
public DateTime DeclarationDate { get; set; }
public decimal TotalGrossMassKg { get; set; }
public RequestedValidityOfTheProof RequestedValidityOfTheProof { get; set; }
public GoodsShipmentForT2LT2LF GoodsShipmentForT2LT2LF { get; set; }
public string RequestType { get; set; }
}
public class RequestedValidityOfTheProof
{
public int NumberOfDays { get; set; }
}
public class GoodsShipmentForT2LT2LF
{
public bool ContainerIndication { get; set; }
public LocationOfGoods LocationOfGoods { get; set; }
[XmlElement("GoodsItemsForT2LT2LF")]
public List<GoodsItemForT2LT2LF> GoodsItemsForT2LT2LF { get; set; } = new List<GoodsItemForT2LT2LF>();
public TransportDocuments TransportDocuments { get; set; }
}
public class LocationOfGoods
{
public string TypeOfLocation { get; set; }
public string QualifierOfIdentification { get; set; }
public string UNLocode { get; set; }
}
public class GoodsItemForT2LT2LF
{
public Commodity Commodity { get; set; } = new Commodity();
public int GoodsItemNumber { get; set; }
public string DescriptionOfGoods { get; set; }
public GoodsMeasure GoodsMeasure { get; set; } = new GoodsMeasure();
public Packaging Packaging { get; set; } = new Packaging();
}
public class Commodity
{
public string HarmonizedSystemSubHeadingCode { get; set; }
}
public class GoodsMeasure
{
public decimal GrossMass { get; set; }
public decimal NetMass { get; set; }
}
public class Packaging
{
public string ShippingMarks { get; set; }
public int NumberOfPackages { get; set; }
public string TypeOfPackages { get; set; }
}
public class TransportDocuments
{
public string Type { get; set; }
public string ReferenceNumber { get; set; }
}
}

View File

@ -2,6 +2,6 @@
[assembly: AssemblyCompany("schick Informatik")]
[assembly: AssemblyProduct("BSMD NSW interface")]
[assembly: AssemblyInformationalVersion("7.2.10")]
[assembly: AssemblyInformationalVersion("7.2.12")]
[assembly: AssemblyCopyright("Copyright © 2014-2025 schick Informatik")]
[assembly: AssemblyTrademark("")]

View File

@ -1,4 +1,4 @@
using System.Reflection;
[assembly: AssemblyVersion("7.2.10.*")]
[assembly: AssemblyVersion("7.2.12.*")]

View File

@ -119,6 +119,7 @@
<Compile Include="Customer.cs" />
<Compile Include="DatabaseEntityAsync.cs" />
<Compile Include="DBManagerAsync.cs" />
<Compile Include="EasyPeasy.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="HAZ.cs" />
<Compile Include="HAZPosTemplate.cs" />