Added parsing from Excel and fixed grid refresh error

This commit is contained in:
Daniel Schick 2025-09-29 11:07:44 +02:00
parent a0b72f63a8
commit e3b12ae531
2 changed files with 133 additions and 4 deletions

View File

@ -6,7 +6,10 @@ using bsmd.database.EasyPeasy;
using ENI2.Util; using ENI2.Util;
using Microsoft.Win32; using Microsoft.Win32;
using System; using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
@ -42,7 +45,10 @@ namespace ENI2.Controls
private void buttonClear_Click(object sender, RoutedEventArgs e) private void buttonClear_Click(object sender, RoutedEventArgs e)
{ {
this._vm = EasyPeasyState.CreateDefault(); this._vm = EasyPeasyState.CreateDefault();
if (_vm.ProofInformationT2LT2LF?.GoodsShipmentForT2LT2LF?.GoodsItemsForT2LT2LF == null)
_vm.ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF.GoodsItemsForT2LT2LF = new ObservableCollection<GoodsItemForT2LT2LF>();
this.DataContext = this._vm; this.DataContext = this._vm;
} }
@ -99,6 +105,11 @@ namespace ENI2.Controls
{ {
var ser = new XmlSerializer(typeof(ProofRequest)); var ser = new XmlSerializer(typeof(ProofRequest));
_vm = (ProofRequest)ser.Deserialize(fs); _vm = (ProofRequest)ser.Deserialize(fs);
// after loading/creating _vm
if (_vm.ProofInformationT2LT2LF?.GoodsShipmentForT2LT2LF?.GoodsItemsForT2LT2LF == null)
_vm.ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF.GoodsItemsForT2LT2LF = new ObservableCollection<GoodsItemForT2LT2LF>();
this.DataContext = _vm; this.DataContext = _vm;
} }
} }
@ -142,7 +153,9 @@ namespace ENI2.Controls
if (Clipboard.ContainsText()) if (Clipboard.ContainsText())
{ {
var text = Clipboard.GetText(); var text = Clipboard.GetText();
PasteGoodsItems(text);
if(!TryPaste_EspHsPkgsGross(text))
PasteGoodsItems(text);
e.Handled = true; e.Handled = true;
} }
} }
@ -200,6 +213,121 @@ namespace ENI2.Controls
return res.ToArray(); return res.ToArray();
} }
private bool TryPaste_EspHsPkgsGross(string text)
{
if (_vm?.ProofInformationT2LT2LF?.GoodsShipmentForT2LT2LF == null) return false;
// Normalize and split lines
var lines = text.Replace("\r\n", "\n").Replace('\r', '\n')
.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
if (lines.Length == 0) return false;
// Determine next item number
var list = _vm.ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF.GoodsItemsForT2LT2LF;
int nextItemNo = list.Any() ? list.Max(x => x.GoodsItemNumber) + 1 : 1;
bool anyAdded = false;
bool countrySeen = false;
foreach (var raw in lines)
{
var line = raw; // do not Trim() entirely; keep leading tab as empty first cell
var cells = line.Split('\t'); // keeps empty entries
// Expected:
// - 4 cells: [ESP or ""], [HS], [Pkgs], [Gross]
// - 3 cells: [HS], [Pkgs], [Gross]
string hs = null, pkgs = null, gross = null;
if (cells.Length >= 4)
{
string c0 = cells[0]?.Trim();
// Optionally capture the first token like "ESP" (country tag),
// only once and only if alphabetic (won't throw if numeric)
if (!countrySeen && !string.IsNullOrWhiteSpace(c0) && c0.All(ch => char.IsLetter(ch)))
{
// If you decide later this should set a field, uncomment:
// if (string.IsNullOrWhiteSpace(_vm.Country)) _vm.Country = c0;
countrySeen = true;
}
hs = (cells.Length > 1 ? cells[1] : null);
pkgs = (cells.Length > 2 ? cells[2] : null);
gross = (cells.Length > 3 ? cells[3] : null);
}
else if (cells.Length == 3)
{
hs = cells[0];
pkgs = cells[1];
gross = cells[2];
}
else
{
// Not enough data for this format; skip the row
continue;
}
if (string.IsNullOrWhiteSpace(hs)) continue;
var item = new GoodsItemForT2LT2LF
{
GoodsItemNumber = nextItemNo++,
DescriptionOfGoods = "" // per spec
};
item.Commodity.HarmonizedSystemSubHeadingCode = hs.Trim();
if (TryParseIntFlexible(pkgs, out var pk))
item.Packaging.NumberOfPackages = pk;
if (TryParseDecimalFlexible(gross, out var g))
{
item.GoodsMeasure.GrossMass = g;
var net = g - 1m;
if (net < 0m) net = 0m;
item.GoodsMeasure.NetMass = net;
}
list.Add(item);
anyAdded = true;
}
return anyAdded;
}
#endregion
#region static utils
// this will go somewhere else later
// Try parse decimal with current culture, invariant, and comma/dot flip
private static bool TryParseDecimalFlexible(string s, out decimal value)
{
s = (s ?? "").Trim();
// 1) current culture
if (decimal.TryParse(s, NumberStyles.Number, CultureInfo.CurrentCulture, out value)) return true;
// 2) invariant
if (decimal.TryParse(s, NumberStyles.Number, CultureInfo.InvariantCulture, out value)) return true;
// 3) flip comma/dot and retry (helps when clipboard mixes locales)
string flipped = s.Contains(",") ? s.Replace(",", ".") : s.Replace(".", ",");
if (decimal.TryParse(flipped, NumberStyles.Number, CultureInfo.CurrentCulture, out value)) return true;
if (decimal.TryParse(flipped, NumberStyles.Number, CultureInfo.InvariantCulture, out value)) return true;
value = 0m;
return false;
}
private static bool TryParseIntFlexible(string s, out int value)
{
s = (s ?? "").Trim();
// Extract leading integer if something like "12 pcs"
var digits = new string(s.TakeWhile(ch => char.IsDigit(ch) || ch == '-' || ch == '+').ToArray());
if (string.IsNullOrEmpty(digits)) digits = s;
return int.TryParse(digits, NumberStyles.Integer, CultureInfo.CurrentCulture, out value)
|| int.TryParse(digits, NumberStyles.Integer, CultureInfo.InvariantCulture, out value);
}
#endregion #endregion
} }

View File

@ -2,7 +2,7 @@
// Description: Collection of classes for the customs XML upload app // Description: Collection of classes for the customs XML upload app
using System; using System;
using System.Collections.Generic; using System.Collections.ObjectModel;
using System.Xml.Serialization; using System.Xml.Serialization;
namespace bsmd.database.EasyPeasy namespace bsmd.database.EasyPeasy
@ -44,7 +44,7 @@ namespace bsmd.database.EasyPeasy
public LocationOfGoods LocationOfGoods { get; set; } public LocationOfGoods LocationOfGoods { get; set; }
[XmlElement("GoodsItemsForT2LT2LF")] [XmlElement("GoodsItemsForT2LT2LF")]
public List<GoodsItemForT2LT2LF> GoodsItemsForT2LT2LF { get; set; } = new List<GoodsItemForT2LT2LF>(); public ObservableCollection<GoodsItemForT2LT2LF> GoodsItemsForT2LT2LF { get; set; } = new ObservableCollection<GoodsItemForT2LT2LF>();
public TransportDocuments TransportDocuments { get; set; } public TransportDocuments TransportDocuments { get; set; }
} }
@ -88,4 +88,5 @@ namespace bsmd.database.EasyPeasy
public string Type { get; set; } public string Type { get; set; }
public string ReferenceNumber { get; set; } public string ReferenceNumber { get; set; }
} }
} }