90 lines
4.1 KiB
C#
90 lines
4.1 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Elwig.Helpers.Billing {
|
|
public class BillingVariant : Billing {
|
|
|
|
private readonly int AvNr;
|
|
|
|
public BillingVariant(int year, int avnr) : base(year) {
|
|
AvNr = avnr;
|
|
}
|
|
|
|
public async Task Calculate() {
|
|
await DeleteInDb();
|
|
await CalculatePrices();
|
|
await CalculateModifiers();
|
|
}
|
|
|
|
protected async Task DeleteInDb() {
|
|
using var cnx = await AppDbContext.ConnectAsync();
|
|
using (var cmd = cnx.CreateCommand()) {
|
|
cmd.CommandText = $"DELETE FROM payment_delivery_part_bucket WHERE (year, avnr) = ({Year}, {AvNr})";
|
|
await cmd.ExecuteNonQueryAsync();
|
|
}
|
|
using (var cmd = cnx.CreateCommand()) {
|
|
cmd.CommandText = $"DELETE FROM payment_delivery_part WHERE (year, avnr) = ({Year}, {AvNr})";
|
|
await cmd.ExecuteNonQueryAsync();
|
|
}
|
|
using (var cmd = cnx.CreateCommand()) {
|
|
cmd.CommandText = $"DELETE FROM payment_member WHERE (year, avnr) = ({Year}, {AvNr})";
|
|
await cmd.ExecuteNonQueryAsync();
|
|
}
|
|
}
|
|
|
|
protected async Task CalculatePrices() {
|
|
using var cnx = await AppDbContext.ConnectAsync();
|
|
|
|
var parts = new List<(int Year, int DId, int DPNr, int BktNr, string SortId, string Discr, int Value, bool MinQuw, double Oe, double Kmw)>();
|
|
using (var cmd = cnx.CreateCommand()) {
|
|
cmd.CommandText = $"""
|
|
SELECT d.year, d.did, d.dpnr, b.bktnr, d.sortid, b.discr, b.value, d.min_quw, d.oe, d.kmw
|
|
FROM delivery_part_bucket b
|
|
JOIN v_delivery d ON (d.year, d.did, d.dpnr) = (b.year, b.did, b.dpnr)
|
|
WHERE b.year = {Year}
|
|
""";
|
|
using var reader = await cmd.ExecuteReaderAsync();
|
|
while (await reader.ReadAsync()) {
|
|
parts.Add((
|
|
reader.GetInt32(0), reader.GetInt32(1), reader.GetInt32(2), reader.GetInt32(3),
|
|
reader.GetString(4), reader.GetString(5), reader.GetInt32(6),
|
|
reader.GetBoolean(7), reader.GetDouble(8), reader.GetDouble(9)
|
|
));
|
|
}
|
|
}
|
|
|
|
var inserts = new List<(int Year, int DId, int DPNr, int BktNr, long Price, long Amount)>();
|
|
foreach (var part in parts) {
|
|
var price = !part.MinQuw ? 0.5m : ((part.BktNr == 2 ? 0.8m : (part.BktNr == 1 ? 0.7m : 0.6m)) + ((decimal)(part.Oe - 73) * 0.005m)); // TODO
|
|
var priceL = Utils.DecToDb(price, 4);
|
|
var amount = Utils.DecToDb(price * part.Value, 4);
|
|
inserts.Add((part.Year, part.DId, part.DPNr, part.BktNr, priceL, amount));
|
|
}
|
|
|
|
using (var cmd = cnx.CreateCommand()) {
|
|
cmd.CommandText = $"""
|
|
INSERT INTO payment_delivery_part_bucket (year, did, dpnr, bktnr, avnr, price, amount)
|
|
VALUES {string.Join(",\n ", inserts.Select(i => $"({i.Year}, {i.DId}, {i.DPNr}, {i.BktNr}, {AvNr}, {i.Price}, {i.Amount})"))}
|
|
""";
|
|
await cmd.ExecuteNonQueryAsync();
|
|
}
|
|
}
|
|
|
|
protected async Task CalculateModifiers() {
|
|
using var cnx = await AppDbContext.ConnectAsync();
|
|
using var cmd = cnx.CreateCommand();
|
|
cmd.CommandText = $"""
|
|
INSERT INTO payment_delivery_part (year, did, dpnr, avnr, net_amount, mod_abs, mod_rel)
|
|
SELECT d.year, d.did, d.dpnr, {AvNr}, 0, COALESCE(m.abs, 0), COALESCE(m.rel, 0)
|
|
FROM delivery_part d
|
|
LEFT JOIN delivery_part_modifier p ON (p.year, p.did, p.dpnr) = (d.year, d.did, d.dpnr)
|
|
LEFT JOIN modifier m ON m.modid = p.modid
|
|
WHERE d.year = {Year}
|
|
ON CONFLICT DO UPDATE SET mod_abs = mod_abs + excluded.mod_abs, mod_rel = mod_rel + excluded.mod_rel;
|
|
""";
|
|
await cmd.ExecuteNonQueryAsync();
|
|
}
|
|
}
|
|
}
|