Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
a2f49e1b8b | |||
99c3474fb6 | |||
9924795888 | |||
733ab0d208 | |||
6e2ba56a7c | |||
2507a2695f | |||
ddd83bf63d | |||
685793f0fb | |||
f6712704ee | |||
de500854c4 | |||
d992b6a206 | |||
d2b96736bb | |||
50b9f4e207 | |||
45fc0893b1 | |||
c4dd56075d | |||
f1084c716a |
@ -127,7 +127,7 @@ namespace Elwig {
|
||||
ZwstId = entry.Item1;
|
||||
BranchName = entry.Item2;
|
||||
BranchPlz = entry.Item3;
|
||||
BranchLocation = entry.Item4;
|
||||
BranchLocation = entry.Item4?.Split(" im ")[0]; // FIXME
|
||||
BranchAddress = entry.Item5;
|
||||
BranchPhoneNr = entry.Item6;
|
||||
BranchFaxNr = entry.Item7;
|
||||
@ -138,7 +138,7 @@ namespace Elwig {
|
||||
ZwstId = entry.Item1;
|
||||
BranchName = entry.Item2;
|
||||
BranchPlz = entry.Item3;
|
||||
BranchLocation = entry.Item4;
|
||||
BranchLocation = entry.Item4?.Split(" im ")[0]; // FIXME
|
||||
BranchAddress = entry.Item5;
|
||||
BranchPhoneNr = entry.Item6;
|
||||
BranchFaxNr = entry.Item7;
|
||||
|
@ -6,9 +6,10 @@
|
||||
xmlns:local="clr-namespace:Elwig.Windows"
|
||||
mc:Ignorable="d"
|
||||
ResizeMode="NoResize"
|
||||
Loaded="Window_Loaded"
|
||||
Title="Anlieferungsbestätingungen - Elwig" Height="400" Width="600">
|
||||
<Grid>
|
||||
<GroupBox Header="Sortieren nach" Margin="10,10,10,10" Width="150" Height="80" VerticalAlignment="Top" HorizontalAlignment="Left">
|
||||
<GroupBox Header="Sortieren nach" Margin="10,10,10,10" Width="180" Height="80" VerticalAlignment="Top" HorizontalAlignment="Left">
|
||||
<StackPanel Margin="5,5,0,5">
|
||||
<RadioButton GroupName="Order" x:Name="OrderMgNrInput" Content="Mitgliedsnummer" IsChecked="True"/>
|
||||
<RadioButton GroupName="Order" x:Name="OrderNameInput" Content="Name"/>
|
||||
@ -16,16 +17,20 @@
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<TextBox x:Name="TextElement" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible" AcceptsReturn="True"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="170,10,10,10" Height="Auto"/>
|
||||
<CheckBox x:Name="AllMembersInput" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,100,10,10">
|
||||
<TextBlock>Auch Mitglieder ohne<LineBreak/>Lieferungen miteinbeziehen</TextBlock>
|
||||
</CheckBox>
|
||||
|
||||
<Button x:Name="TestButton" Content="Stichprobe" FontSize="14" Width="150" Margin="10,10,10,74" Height="27"
|
||||
<TextBox x:Name="TextElement" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible" AcceptsReturn="True"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="200,10,10,10" Height="Auto"/>
|
||||
|
||||
<Button x:Name="TestButton" Content="Stichprobe" FontSize="14" Width="180" Margin="10,10,10,74" Height="27" Tag="Print" IsEnabled="False"
|
||||
Click="TestButton_Click"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
|
||||
<Button x:Name="ShowButton" Content="Vorschau" FontSize="14" Width="150" Margin="10,10,10,42" Height="27"
|
||||
<Button x:Name="ShowButton" Content="Vorschau" FontSize="14" Width="180" Margin="10,10,10,42" Height="27" Tag="Print" IsEnabled="False"
|
||||
Click="ShowButton_Click"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
|
||||
<Button x:Name="PrintButton" Content="Drucken" FontSize="14" Width="150" Margin="10,10,10,10" Height="27"
|
||||
<Button x:Name="PrintButton" Content="Drucken" FontSize="14" Width="180" Margin="10,10,10,10" Height="27" Tag="Print" IsEnabled="False"
|
||||
Click="PrintButton_Click"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
|
||||
</Grid>
|
||||
|
@ -24,6 +24,12 @@ namespace Elwig.Dialogs {
|
||||
}
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
||||
TestButton.IsEnabled = App.IsPrintingReady;
|
||||
ShowButton.IsEnabled = App.IsPrintingReady;
|
||||
PrintButton.IsEnabled = App.IsPrintingReady;
|
||||
}
|
||||
|
||||
protected override async Task OnRenewContext() { }
|
||||
|
||||
private async Task UpdateTextParameter() {
|
||||
@ -40,13 +46,19 @@ namespace Elwig.Dialogs {
|
||||
Mouse.OverrideCursor = Cursors.AppStarting;
|
||||
await UpdateTextParameter();
|
||||
|
||||
var members = Context.Members.FromSqlRaw($"""
|
||||
SELECT m.*
|
||||
FROM member m
|
||||
INNER JOIN delivery d ON d.mgnr = m.mgnr
|
||||
WHERE d.year = {Year}
|
||||
GROUP BY m.mgnr
|
||||
""");
|
||||
IQueryable<Member> members;
|
||||
if (AllMembersInput.IsChecked == true) {
|
||||
members = Context.Members.Where(m => m.IsActive);
|
||||
} else {
|
||||
members = Context.Members.FromSqlRaw($"""
|
||||
SELECT m.*
|
||||
FROM member m
|
||||
INNER JOIN delivery d ON d.mgnr = m.mgnr
|
||||
WHERE d.year = {Year}
|
||||
GROUP BY m.mgnr
|
||||
""");
|
||||
}
|
||||
|
||||
if (OrderMgNrInput.IsChecked == true) {
|
||||
members = members
|
||||
.OrderBy(m => m.MgNr);
|
||||
|
@ -109,41 +109,52 @@
|
||||
<th><b>Lese @Model.Year</b> per @($"{Model.Date:dd.MM.yyyy}") [kg]</th>
|
||||
<th>Lieferpflicht</th>
|
||||
<th>Lieferrecht</th>
|
||||
<th>Unterliefert<br/>(bzgl. Zuget.)</th>
|
||||
<th>Noch zu liefern<br/>(bzgl. Gelft.)</th>
|
||||
<th>Überliefert<br/>(bzgl. Gelft.)</th>
|
||||
<th>Unterliefert</th>
|
||||
<th>Noch lieferbar</th>
|
||||
<th>Überliefert</th>
|
||||
<th>Zugeteilt</th>
|
||||
<th>Geliefert</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@{
|
||||
string FormatRow(int obligation, int right, int sum, int? payment = null) {
|
||||
var isGa = payment == null;
|
||||
string FormatRow(int mode, int obligation, int right, int sum, int? payment = null) {
|
||||
var isGa = mode == 0;
|
||||
payment ??= sum;
|
||||
return $"<td>{obligation:N0}</td>" +
|
||||
$"<td>{right:N0}</td>" +
|
||||
$"<td>{(payment < obligation ? $"<b>{obligation - payment:N0}\x3c/b>" : "-")}</td>" +
|
||||
$"<td>{(sum >= obligation && sum <= right ? $"{right - sum:N0}" : "-")}</td>" +
|
||||
$"<td>{(obligation == 0 && right == 0 ? "-" : (sum > right ? ((isGa ? "<b>" : "") + $"{sum - right:N0}" + (isGa ? "</b>" : "")) : "-"))}</td>" +
|
||||
$"<td>{(obligation == 0 && right == 0 ? "-" : $"{payment:N0}")}</td>" +
|
||||
return $"<td>{(mode == 1 ? "" : obligation == 0 ? "-" : $"{obligation:N0}")}</td>" +
|
||||
$"<td>{(mode == 1 ? "" : right == 0 ? "-" : $"{right:N0}")}</td>" +
|
||||
$"<td>{(mode == 1 ? "" : payment < obligation ? $"<b>{obligation - payment:N0}\x3c/b>" : "-")}</td>" +
|
||||
$"<td>{(mode == 1 ? "" : payment >= obligation && sum <= right ? $"{right - sum:N0}" : "-")}</td>" +
|
||||
$"<td>{(mode == 1 ? "" : obligation == 0 && right == 0 ? "-" : (sum > right ? ((isGa ? "<b>" : "") + $"{sum - right:N0}" + (isGa ? "</b>" : "")) : "-"))}</td>" +
|
||||
$"<td>{(mode != 2 ? "" : obligation == 0 && right == 0 ? "-" : $"{payment:N0}")}</td>" +
|
||||
$"<td>{sum:N0}</td>";
|
||||
}
|
||||
var mBins = Model.MemberBins.Where(b => b.Value.Item2 > 0 || b.Value.Item3 > 0 || b.Value.Item4 > 0).ToList();
|
||||
var fbVars = mBins.Where(b => b.Value.Item2 > 0 || b.Value.Item3 > 0).Select(b => b.Key.Replace("_", "")).Order().ToArray();
|
||||
var fbs = mBins.Where(b => fbVars.Contains(b.Key)).OrderBy(b => b.Value.Item1);
|
||||
var rem = mBins.Where(b => !fbVars.Contains(b.Key)).OrderBy(b => b.Value.Item1);
|
||||
}
|
||||
<tr>
|
||||
<th>Gesamtlieferung lt. gez. GA</th>
|
||||
@Raw(FormatRow(Model.Member.DeliveryObligation, Model.Member.DeliveryRight, Model.Member.Deliveries.Where(d => d.Year == Model.Year).Sum(d => d.Weight)))
|
||||
@Raw(FormatRow(0, Model.Member.DeliveryObligation, Model.Member.DeliveryRight, Model.Member.Deliveries.Where(d => d.Year == Model.Year).Sum(d => d.Weight)))
|
||||
</tr>
|
||||
<tr class="subheading">
|
||||
<th>Flächenbindungen:</th>
|
||||
</tr>
|
||||
@foreach (var (id, (name, right, obligation, sum, payment)) in Model.MemberBins.OrderBy(b => b.Key)) {
|
||||
if (right > 0 || obligation > 0 || sum > 0) {
|
||||
<tr>
|
||||
<th>@name</th>
|
||||
@Raw(FormatRow(obligation, right, sum, payment))
|
||||
</tr>
|
||||
}
|
||||
@if (rem.Any()) {
|
||||
<tr class="subheading"><th colspan="8">Sortenaufteilung:</th></tr>
|
||||
}
|
||||
@foreach (var (id, (name, right, obligation, sum, payment)) in rem) {
|
||||
<tr>
|
||||
<th>@name</th>
|
||||
@Raw(FormatRow(1, obligation, right, sum, payment))
|
||||
</tr>
|
||||
}
|
||||
@if (fbs.Any()){
|
||||
<tr class="subheading"><th colspan="8">Flächenbindungen:</th></tr>
|
||||
}
|
||||
@foreach (var (id, (name, right, obligation, sum, payment)) in fbs) {
|
||||
<tr>
|
||||
<th>@name</th>
|
||||
@Raw(FormatRow(2, obligation, right, sum, payment))
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -13,7 +13,7 @@ namespace Elwig.Documents {
|
||||
public Dictionary<string, (string, int, int, int, int)> MemberBins;
|
||||
|
||||
public DeliveryConfirmation(AppDbContext ctx, int year, Member m) :
|
||||
base($"Anlieferungsbestätigung {year} – {((IAddress?)m.BillingAddress ?? m).Name}", m) {
|
||||
base($"Anlieferungsbestätigung {year}", m) {
|
||||
Year = year;
|
||||
ShowDateAndLocation = true;
|
||||
UseBillingAddress = true;
|
||||
|
@ -92,7 +92,7 @@
|
||||
<th>Lieferpflicht</th>
|
||||
<th>Lieferrecht</th>
|
||||
<th>Unterliefert</th>
|
||||
<th>Noch zu liefern</th>
|
||||
<th>Noch lieferbar</th>
|
||||
<th>Überliefert</th>
|
||||
<th>Geliefert</th>
|
||||
</tr>
|
||||
|
@ -134,7 +134,7 @@ namespace Elwig.Documents {
|
||||
|
||||
public void Show() {
|
||||
if (_pdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
|
||||
Pdf.Show(_pdfFile.NewReference(), Title);
|
||||
Pdf.Show(_pdfFile.NewReference(), Title + (this is BusinessDocument b ? $" - {b.Member.Name}" : ""));
|
||||
}
|
||||
|
||||
private class InternalDocument : Document {
|
||||
|
@ -106,3 +106,8 @@ table.delivery-confirmation-stats tbody th {
|
||||
font-style: italic;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
table.delivery-confirmation-stats tr.subheading th {
|
||||
font-weight: bold;
|
||||
border-top: 0.5pt solid black;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
<UseWPF>true</UseWPF>
|
||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||
<ApplicationIcon>elwig.ico</ApplicationIcon>
|
||||
<Version>0.4.0</Version>
|
||||
<Version>0.4.2</Version>
|
||||
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -215,17 +215,7 @@ namespace Elwig.Helpers {
|
||||
cnx ??= await ConnectAsync();
|
||||
var bins = new Dictionary<int, Dictionary<string, (int, int)>>();
|
||||
using (var cmd = cnx.CreateCommand()) {
|
||||
cmd.CommandText = $"""
|
||||
SELECT mgnr, t.vtrgid,
|
||||
ROUND(SUM(COALESCE(area * min_kg_per_ha, 0)) / 10000.0) AS min_kg,
|
||||
ROUND(SUM(COALESCE(area * max_kg_per_ha, 0)) / 10000.0) AS max_kg
|
||||
FROM area_commitment c
|
||||
JOIN area_commitment_type t ON t.vtrgid = c.vtrgid
|
||||
WHERE (year_from IS NULL OR year_from <= {year}) AND
|
||||
(year_to IS NULL OR year_to >= {year})
|
||||
GROUP BY mgnr, t.vtrgid
|
||||
ORDER BY LENGTH(t.vtrgid) DESC, t.vtrgid
|
||||
""";
|
||||
cmd.CommandText = $"SELECT mgnr, bin, min_kg, max_kg FROM v_area_commitment_bin WHERE year = {year}";
|
||||
using var reader = await cmd.ExecuteReaderAsync();
|
||||
while (await reader.ReadAsync()) {
|
||||
var mgnr = reader.GetInt32(0);
|
||||
@ -305,7 +295,7 @@ namespace Elwig.Helpers {
|
||||
var variety = await WineVarieties.FindAsync(id[..2]);
|
||||
var attrIds = id[2..];
|
||||
var attrs = await WineAttributes.Where(a => attrIds.Contains(a.AttrId)).ToListAsync();
|
||||
var name = (variety?.Name ?? "") + (attrs.Count > 0 ? $" ({string.Join(" / ", attrs.Select(a => a.Name))})" : "");
|
||||
var name = (variety?.Name ?? "") + (attrIds == "_" ? " (kein Qual.Wein)" : attrs.Count > 0 ? $" ({string.Join(" / ", attrs.Select(a => a.Name))})" : "");
|
||||
bins[id] = (
|
||||
name,
|
||||
rightsAndObligations.GetValueOrDefault(id).Item1,
|
||||
|
@ -4,11 +4,11 @@ using System;
|
||||
namespace Elwig.Helpers {
|
||||
public static class AppDbUpdater {
|
||||
|
||||
public static readonly int RequiredSchemaVersion = 3;
|
||||
public static readonly int RequiredSchemaVersion = 4;
|
||||
|
||||
private static int _versionOffset = 0;
|
||||
private static readonly Action<SqliteConnection>[] _updaters = new[] {
|
||||
UpdateDbSchema_1_To_2, UpdateDbSchema_2_To_3
|
||||
UpdateDbSchema_1_To_2, UpdateDbSchema_2_To_3, UpdateDbSchema_3_To_4
|
||||
};
|
||||
|
||||
private static void ExecuteNonQuery(SqliteConnection cnx, string sql) {
|
||||
@ -184,5 +184,34 @@ namespace Elwig.Helpers {
|
||||
|
||||
ExecuteNonQuery(cnx, "ALTER TABLE wine_attribute ADD COLUMN fill_lower_bins INTEGER NOT NULL CHECK (fill_lower_bins IN (0, 1, 2)) DEFAULT 0");
|
||||
}
|
||||
|
||||
private static void UpdateDbSchema_3_To_4(SqliteConnection cnx) {
|
||||
ExecuteNonQuery(cnx, "DROP VIEW v_payment_bin");
|
||||
ExecuteNonQuery(cnx, """
|
||||
CREATE VIEW v_payment_bin AS
|
||||
SELECT d.year, d.mgnr,
|
||||
sortid || discr AS bin,
|
||||
SUM(value) AS weight
|
||||
FROM v_delivery d
|
||||
JOIN delivery_part_bin b ON (b.year, b.did, b.dpnr) = (d.year, d.did, d.dpnr)
|
||||
GROUP BY d.year, d.mgnr, bin
|
||||
HAVING SUM(value) > 0
|
||||
ORDER BY d.year, d.mgnr, LENGTH(bin) DESC, bin;
|
||||
""");
|
||||
|
||||
ExecuteNonQuery(cnx, """
|
||||
CREATE VIEW v_area_commitment_bin AS
|
||||
SELECT s.year, c.mgnr,
|
||||
c.vtrgid AS bin,
|
||||
CAST(ROUND(SUM(COALESCE(area * min_kg_per_ha, 0)) / 10000.0, 0) AS INTEGER) AS min_kg,
|
||||
CAST(ROUND(SUM(COALESCE(area * max_kg_per_ha, 0)) / 10000.0, 0) AS INTEGER) AS max_kg
|
||||
FROM area_commitment c, season s
|
||||
JOIN area_commitment_type t ON t.vtrgid = c.vtrgid
|
||||
WHERE (year_from IS NULL OR year_from <= s.year) AND
|
||||
(year_to IS NULL OR year_to >= s.year)
|
||||
GROUP BY s.year, c.mgnr, c.vtrgid
|
||||
ORDER BY s.year, c.mgnr, LENGTH(c.vtrgid) DESC, c.vtrgid;
|
||||
""");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ namespace Elwig.Helpers.Billing {
|
||||
COALESCE(LENGTH(attributes), 0) ASC, attribute_prio DESC, COALESCE(attributes, '~'),
|
||||
kmw DESC, lsnr, dpnr
|
||||
""";
|
||||
var reader = await cmd.ExecuteReaderAsync();
|
||||
using var reader = await cmd.ExecuteReaderAsync();
|
||||
while (await reader.ReadAsync()) {
|
||||
deliveries.Add((
|
||||
reader.GetInt32(0), reader.GetInt32(1), reader.GetInt32(2), reader.GetString(3), reader.GetInt32(4),
|
||||
@ -125,7 +125,81 @@ namespace Elwig.Helpers.Billing {
|
||||
await cmd.ExecuteNonQueryAsync();
|
||||
}
|
||||
|
||||
// TODO add second round to avoid under deliveries
|
||||
if (!avoidUnderDeliveries)
|
||||
return;
|
||||
|
||||
var underDeliveries = new Dictionary<(int, string), int>();
|
||||
using (var cmd = cnx.CreateCommand()) {
|
||||
cmd.CommandText = $"""
|
||||
SELECT c.mgnr, c.bin, COALESCE(p.weight, 0) - c.min_kg AS diff
|
||||
FROM v_area_commitment_bin c
|
||||
LEFT JOIN v_payment_bin p ON (p.year, p.mgnr, p.bin) = (c.year, c.mgnr, c.bin)
|
||||
WHERE c.year = {Year} AND LENGTH(c.bin) = 2 AND diff < 0
|
||||
""";
|
||||
using var reader = await cmd.ExecuteReaderAsync();
|
||||
while (await reader.ReadAsync()) {
|
||||
underDeliveries[(reader.GetInt32(0), reader.GetString(1))] = reader.GetInt32(2);
|
||||
}
|
||||
}
|
||||
|
||||
var fittingBins = new Dictionary<(int, string), int>();
|
||||
using (var cmd = cnx.CreateCommand()) {
|
||||
cmd.CommandText = $"""
|
||||
SELECT c.mgnr, c.bin, COALESCE(p.weight, 0) - c.min_kg AS diff
|
||||
FROM v_area_commitment_bin c
|
||||
LEFT JOIN v_payment_bin p ON (p.year, p.mgnr, p.bin) = (c.year, c.mgnr, c.bin)
|
||||
WHERE c.year = {Year} AND LENGTH(c.bin) = 3 AND diff > 0
|
||||
""";
|
||||
using var reader = await cmd.ExecuteReaderAsync();
|
||||
while (await reader.ReadAsync()) {
|
||||
fittingBins[(reader.GetInt32(0), reader.GetString(1))] = reader.GetInt32(2);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in fittingBins) {
|
||||
var mgnr = item.Key.Item1;
|
||||
var id = item.Key.Item2[..2];
|
||||
var attr = item.Key.Item2[2..];
|
||||
var available = item.Value;
|
||||
var needed = -underDeliveries.GetValueOrDefault((mgnr, id), 0);
|
||||
if (needed <= 0) continue;
|
||||
|
||||
var fittingDeliveries = new List<(int, int, int, int)>();
|
||||
using (var cmd = cnx.CreateCommand()) {
|
||||
cmd.CommandText = $"""
|
||||
SELECT d.did, d.dpnr, d.weight, b.value
|
||||
FROM v_delivery d
|
||||
JOIN delivery_part_bin b ON (b.year, b.did, b.dpnr) = (d.year, d.did, d.dpnr) AND b.discr = '{attr}'
|
||||
WHERE d.year = {Year} AND mgnr = {mgnr} AND sortid = '{id}' AND attributes = '{attr}'
|
||||
ORDER BY kmw ASC, lsnr DESC, d.dpnr DESC
|
||||
""";
|
||||
using var reader = await cmd.ExecuteReaderAsync();
|
||||
while (await reader.ReadAsync()) {
|
||||
fittingDeliveries.Add((
|
||||
reader.GetInt32(0), reader.GetInt32(1), reader.GetInt32(2), reader.GetInt32(3)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
var changes = new List<(int, int, int, int)>();
|
||||
foreach (var (did, dpnr, _, w) in fittingDeliveries) {
|
||||
int v = Math.Min(needed, w);
|
||||
needed -= v;
|
||||
changes.Add((did, dpnr, 1, v));
|
||||
changes.Add((did, dpnr, 2, w - v));
|
||||
if (needed == 0) break;
|
||||
}
|
||||
|
||||
using (var cmd = cnx.CreateCommand()) {
|
||||
cmd.CommandText = $"""
|
||||
INSERT INTO delivery_part_bin (year, did, dpnr, binnr, discr, value)
|
||||
VALUES {string.Join(",\n ", changes.Select(i => $"({Year}, {i.Item1}, {i.Item2}, {i.Item3}, '', {i.Item4})"))}
|
||||
ON CONFLICT DO UPDATE
|
||||
SET value = excluded.value
|
||||
""";
|
||||
await cmd.ExecuteNonQueryAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
xmlns:local="clr-namespace:Elwig.Windows"
|
||||
mc:Ignorable="d"
|
||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
Title="Flächenbindungen - Elwig" Height="480" Width="850"
|
||||
Title="Flächenbindungen - Elwig" Height="480" Width="1100"
|
||||
Loaded="Window_Loaded">
|
||||
<Window.Resources>
|
||||
<Style TargetType="Label">
|
||||
@ -52,7 +52,7 @@
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="330"/>
|
||||
<ColumnDefinition Width="340"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Menu Grid.ColumnSpan="2" BorderThickness="0,0,0,1" BorderBrush="LightGray" Background="White">
|
||||
@ -74,13 +74,15 @@
|
||||
<DataGridTextColumn Header="Katastralgemeinde" Binding="{Binding Kg.AtKg.Name}" Width="6*"/>
|
||||
<DataGridTextColumn Header="Ried" Binding="{Binding Rd.Name}" Width="4*"/>
|
||||
<DataGridTextColumn Header="Parzelle" Binding="{Binding GstNr}" Width="4*"/>
|
||||
<DataGridTextColumn Header="Fläche" Binding="{Binding Area, StringFormat='{}{0:N0} m²'}" Width="4*">
|
||||
<DataGridTextColumn Header="Fläche" Binding="{Binding Area, StringFormat='{}{0:N0} m²'}" Width="3*">
|
||||
<DataGridTextColumn.CellStyle>
|
||||
<Style>
|
||||
<Setter Property="TextBlock.TextAlignment" Value="Right"/>
|
||||
</Style>
|
||||
</DataGridTextColumn.CellStyle>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Header="Sorte" Binding="{Binding AreaComType.WineVar.Name}" Width="4*"/>
|
||||
<DataGridTextColumn Header="Attribut" Binding="{Binding AreaComType.WineAttr1.Name}" Width="3*"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
|
@ -318,7 +318,7 @@ namespace Elwig.Windows {
|
||||
var filter = TextFilter.ToList();
|
||||
if (filter.Count > 0) {
|
||||
var var = await Context.WineVarieties.ToDictionaryAsync(v => v.SortId, v => v);
|
||||
var qual = await Context.WineQualityLevels.ToDictionaryAsync(q => q.QualId, q => q);
|
||||
var qual = await Context.WineQualityLevels.Where(q => !q.IsPredicate).ToDictionaryAsync(q => q.QualId, q => q);
|
||||
var mgnr = await Context.Members.ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
|
||||
var zwst = await Context.Branches.ToDictionaryAsync(b => b.Name.ToLower().Split(" ")[0], b => b);
|
||||
var attr = await Context.WineAttributes.ToDictionaryAsync(a => a.Name.ToLower().Split(" ")[0], a => a);
|
||||
|
@ -29,7 +29,7 @@
|
||||
Margin="50,80,0,0"/>
|
||||
<CheckBox x:Name="AllowAttrIntoLowerBinsInput" Content="Erlauben Lieferungen auch auf (konfigurierte) "schlechtere" Flächenbindungen aufzuteilen" IsChecked="True"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="255,68,0,0"/>
|
||||
<CheckBox x:Name="AvoidUnderDeliveriesInput" Content="Unterlieferungen durch Abzug bei "besseren" Flächenbindungen vermeiden" IsEnabled="False"
|
||||
<CheckBox x:Name="AvoidUnderDeliveriesInput" Content="Unterlieferungen durch Abzug bei "besseren" Flächenbindungen vermeiden" IsChecked="True"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="255,88,0,0"/>
|
||||
<CheckBox x:Name="HonorGebundenInput" Margin="255,108,0,0" VerticalAlignment="Top">
|
||||
<TextBlock>Bei Lieferungen das Feld <Italic>Gebunden</Italic> berücksichtigen</TextBlock>
|
||||
|
@ -1,6 +1,10 @@
|
||||
using Elwig.Dialogs;
|
||||
using Elwig.Helpers;
|
||||
using Elwig.Helpers.Billing;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
@ -51,7 +55,96 @@ namespace Elwig.Windows {
|
||||
d.Show();
|
||||
}
|
||||
|
||||
private void OverUnderDeliveryButton_Click(object sender, RoutedEventArgs evt) {
|
||||
private async void OverUnderDeliveryButton_Click(object sender, RoutedEventArgs evt) {
|
||||
if (SeasonInput.Value is not int year)
|
||||
return;
|
||||
var d = new SaveFileDialog() {
|
||||
FileName = $"Über-Unterlieferungen-{year}.csv",
|
||||
DefaultExt = "csv",
|
||||
Filter = "CSV-Datei (*.csv)|*.csv",
|
||||
Title = $"Über-/Unterlieferungen {year} speichern unter - Elwig"
|
||||
};
|
||||
if (d.ShowDialog() == false)
|
||||
return;
|
||||
|
||||
Mouse.OverrideCursor = Cursors.AppStarting;
|
||||
|
||||
try {
|
||||
using var file = new StreamWriter(d.FileName, false, Encoding.Latin1);
|
||||
using var cnx = await AppDbContext.ConnectAsync();
|
||||
await file.WriteLineAsync($"Auswertungen {year};;;;;;;;;;;");
|
||||
|
||||
await file.WriteLineAsync($";;;;;;;;;;;");
|
||||
await file.WriteLineAsync($"Über-/Unterlieferungen lt. gez. GA;;;;;;;;;;;");
|
||||
await file.WriteLineAsync($"MgNr;Name;Vorname;Adresse;PLZ;Ort;GA;Lieferpflicht;Lieferrecht;Geliefert;Über-/Unterliefert;Prozent");
|
||||
using (var cmd = cnx.CreateCommand()) {
|
||||
cmd.CommandText = $"""
|
||||
SELECT m.mgnr, m.family_name, m.given_name, p.plz, o.name, m.address, m.business_shares,
|
||||
m.business_shares * (SELECT value FROM client_parameter WHERE param = 'DELIVERY_OBLIGATION') AS min_kg,
|
||||
m.business_shares * (SELECT value FROM client_parameter WHERE param = 'DELIVERY_RIGHT') AS max_kg,
|
||||
COALESCE(SUM(d.weight), 0) AS sum
|
||||
FROM member m
|
||||
LEFT JOIN AT_plz_dest p ON p.id = m.postal_dest
|
||||
LEFT JOIN AT_ort o ON o.okz = p.okz
|
||||
LEFT JOIN v_delivery d ON d.mgnr = m.mgnr AND d.year = {year}
|
||||
WHERE m.active = 1
|
||||
GROUP BY d.year, m.mgnr
|
||||
ORDER BY sum = 0 DESC, 100.0 * sum / max_kg, m.mgnr;
|
||||
""";
|
||||
using var reader = await cmd.ExecuteReaderAsync();
|
||||
while (await reader.ReadAsync()) {
|
||||
var mgnr = reader.GetInt32(0);
|
||||
var familyName = reader.GetString(1);
|
||||
var givenName = reader.GetString(2);
|
||||
var plz = reader.GetInt32(3);
|
||||
var ort = reader.GetString(4);
|
||||
var addr = reader.GetString(5);
|
||||
var ga = reader.GetInt32(6);
|
||||
var minKg = reader.GetInt32(7);
|
||||
var maxKg = reader.GetInt32(8);
|
||||
var sum = reader.GetInt32(9);
|
||||
var s1 = sum < minKg ? $"{sum - minKg}" : sum > maxKg ? $"{sum - maxKg}" : "";
|
||||
var s2 = sum < minKg ? $"{sum * 100.0 / minKg - 100.0:0.0}" : sum > maxKg ? $"{sum * 100.0 / maxKg - 100:0.0}" : "";
|
||||
await file.WriteLineAsync($"{mgnr};{familyName};{givenName};{addr};{plz};{ort};{ga};{minKg};{maxKg};{sum};{s1};{s2}");
|
||||
}
|
||||
}
|
||||
|
||||
await file.WriteLineAsync($";;;;;;;;;;;");
|
||||
await file.WriteLineAsync($"Unterlieferungen lt. Flächenbindungen;;;;;;;;;;;");
|
||||
await file.WriteLineAsync($"MgNr;Name;Vorname;Adresse;PLZ;Ort;Vertrag;Lieferpflicht;Lieferrecht;Geliefert;Unterliefert;Prozent");
|
||||
using (var cmd = cnx.CreateCommand()) {
|
||||
cmd.CommandText = $"""
|
||||
SELECT m.mgnr, m.family_name, m.given_name, p.plz, o.name, m.address,
|
||||
c.bin, c.min_kg, c.max_kg, b.weight
|
||||
FROM member m
|
||||
LEFT JOIN AT_plz_dest p ON p.id = m.postal_dest
|
||||
LEFT JOIN AT_ort o ON o.okz = p.okz
|
||||
JOIN v_area_commitment_bin c ON c.mgnr = m.mgnr AND c.year = {year}
|
||||
LEFT JOIN v_payment_bin b ON (b.mgnr, b.bin) = (m.mgnr, c.bin) AND b.year = {year}
|
||||
WHERE m.active = 1 AND b.weight < c.min_kg
|
||||
ORDER BY m.mgnr, c.bin
|
||||
""";
|
||||
using var reader = await cmd.ExecuteReaderAsync();
|
||||
while (await reader.ReadAsync()) {
|
||||
var mgnr = reader.GetInt32(0);
|
||||
var familyName = reader.GetString(1);
|
||||
var givenName = reader.GetString(2);
|
||||
var plz = reader.GetInt32(3);
|
||||
var ort = reader.GetString(4);
|
||||
var addr = reader.GetString(5);
|
||||
var id = reader.GetString(6);
|
||||
var minKg = reader.GetInt32(7);
|
||||
var maxKg = reader.GetInt32(8);
|
||||
var sum = reader.GetInt32(9);
|
||||
await file.WriteLineAsync($"{mgnr};{familyName};{givenName};{addr};{plz};{ort};{id};{minKg};{maxKg};{sum};{sum - minKg};{sum * 100.0 / minKg - 100.0:0.0}");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception exc) {
|
||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
|
||||
Mouse.OverrideCursor = null;
|
||||
}
|
||||
|
||||
private void PaymentButton_Click(object sender, RoutedEventArgs evt) {
|
||||
|
Reference in New Issue
Block a user