180 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			180 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using Elwig.Helpers.Billing;
 | 
						|
using Elwig.Models.Entities;
 | 
						|
using Microsoft.EntityFrameworkCore;
 | 
						|
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.ComponentModel.DataAnnotations.Schema;
 | 
						|
using System.Linq;
 | 
						|
using System.Threading.Tasks;
 | 
						|
 | 
						|
namespace Elwig.Models.Dtos {
 | 
						|
    public class CreditNoteDeliveryData : DataTable<CreditNoteDeliveryRow> {
 | 
						|
 | 
						|
        private static readonly (string, string, string?)[] FieldNames = [
 | 
						|
            ("", "", null), // TODO
 | 
						|
        ];
 | 
						|
 | 
						|
        private readonly int Year;
 | 
						|
        private readonly int? TgNr;
 | 
						|
        private readonly int? AvNr;
 | 
						|
        private readonly int? MgNr;
 | 
						|
 | 
						|
        private CreditNoteDeliveryData(IEnumerable<CreditNoteDeliveryRow> rows, int year, int? tgnr, int? avnr = null, int? mgnr = null) :
 | 
						|
            base($"Traubengutschrift {year}/{tgnr}", rows, FieldNames) {
 | 
						|
            Year = year;
 | 
						|
            TgNr = tgnr;
 | 
						|
            AvNr = avnr;
 | 
						|
            MgNr = mgnr;
 | 
						|
        }
 | 
						|
 | 
						|
        public static async Task<IDictionary<int, CreditNoteDeliveryData>> ForPaymentVariant(DbSet<CreditNoteDeliveryRowSingle> table, DbSet<PaymentVar> paymentVariants, int year, int avnr) {
 | 
						|
            var variant = await paymentVariants.FindAsync(year, avnr);
 | 
						|
            BillingData? varData = null;
 | 
						|
            try { varData = variant != null ? BillingData.FromJson(variant.Data) : null; } catch { }
 | 
						|
            return (await FromDbSet(table, year, avnr))
 | 
						|
                .GroupBy(
 | 
						|
                    r => new { r.Year, r.AvNr, r.MgNr, r.TgNr, r.DId, r.DPNr },
 | 
						|
                    (k, g) => new CreditNoteDeliveryRow(g, variant, varData))
 | 
						|
                .GroupBy(
 | 
						|
                    r => new { r.Year, r.AvNr, r.MgNr, r.TgNr },
 | 
						|
                    (k, g) => new CreditNoteDeliveryData(g, k.Year, k.TgNr, mgnr: k.MgNr))
 | 
						|
                .ToDictionary(d => d.MgNr ?? 0);
 | 
						|
        }
 | 
						|
 | 
						|
        private static async Task<IEnumerable<CreditNoteDeliveryRowSingle>> FromDbSet(DbSet<CreditNoteDeliveryRowSingle> table, int? year = null, int? avnr = null, int? mgnr = null) {
 | 
						|
            var y = year?.ToString() ?? "NULL";
 | 
						|
            var v = avnr?.ToString() ?? "NULL";
 | 
						|
            var m = mgnr?.ToString() ?? "NULL";
 | 
						|
            return await table.FromSqlRaw($"""
 | 
						|
                SELECT d.year, c.tgnr, v.avnr, d.mgnr, d.did, d.lsnr, d.dpnr, d.weight, d.modifiers,
 | 
						|
                       b.bktnr, d.sortid, b.discr, b.value, pb.price, pb.amount, p.net_amount, p.amount AS total_amount,
 | 
						|
                       s.name AS variety, a.name AS attribute, c.name AS cultivation, q.qualid AS qualid, q.name AS quality_level, d.oe, d.kmw, d.net_weight
 | 
						|
                FROM v_delivery d
 | 
						|
                    JOIN wine_variety s ON s.sortid = d.sortid
 | 
						|
                    LEFT JOIN wine_attribute a ON a.attrid = d.attrid
 | 
						|
                    LEFT JOIN wine_cultivation c ON c.cultid = d.cultid
 | 
						|
                    JOIN wine_quality_level q ON q.qualid = d.qualid
 | 
						|
                    LEFT JOIN delivery_part_bucket b ON (b.year, b.did, b.dpnr) = (d.year, d.did, d.dpnr)
 | 
						|
                    LEFT JOIN payment_variant v ON v.year = d.year
 | 
						|
                    LEFT JOIN payment_delivery_part p ON (p.year, p.did, p.dpnr, p.avnr) = (d.year, d.did, d.dpnr, v.avnr)
 | 
						|
                    LEFT JOIN payment_delivery_part_bucket pb ON (pb.year, pb.did, pb.dpnr, pb.bktnr, pb.avnr) = (b.year, b.did, b.dpnr, b.bktnr, v.avnr)
 | 
						|
                    LEFT JOIN credit c ON (c.year, c.avnr, c.mgnr) = (d.year, v.avnr, d.mgnr)
 | 
						|
                WHERE b.value > 0 AND (d.year = {y} OR {y} IS NULL) AND (v.avnr = {v} OR {v} IS NULL) AND (d.mgnr = {m} OR {m} IS NULL)
 | 
						|
                ORDER BY d.year, v.avnr, d.mgnr, d.lsnr, d.dpnr
 | 
						|
                """).ToListAsync();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public class CreditNoteDeliveryRow {
 | 
						|
 | 
						|
        public int Year;
 | 
						|
        public int? TgNr;
 | 
						|
        public int? AvNr;
 | 
						|
        public int MgNr;
 | 
						|
 | 
						|
        public string LsNr;
 | 
						|
        public int DPNr;
 | 
						|
        public string Variety;
 | 
						|
        public string? Attribute;
 | 
						|
        public string? Cultivation;
 | 
						|
        public string[] Modifiers;
 | 
						|
        public string QualId;
 | 
						|
        public string QualityLevel;
 | 
						|
        public (double Oe, double Kmw) Gradation;
 | 
						|
        public (string Name, int Value, decimal? Price, decimal? Amount)[] Buckets;
 | 
						|
        public decimal? TotalModifiers;
 | 
						|
        public decimal? Amount;
 | 
						|
        public double WeighingModifier;
 | 
						|
 | 
						|
        public CreditNoteDeliveryRow(IEnumerable<CreditNoteDeliveryRowSingle> rows, PaymentVar paymentVariant, BillingData? varData) {
 | 
						|
            var f = rows.First();
 | 
						|
            Year = f.Year;
 | 
						|
            TgNr = f.TgNr;
 | 
						|
            AvNr = f.AvNr;
 | 
						|
            MgNr = f.MgNr;
 | 
						|
            var season = paymentVariant.Season;
 | 
						|
 | 
						|
            LsNr = f.LsNr;
 | 
						|
            DPNr = f.DPNr;
 | 
						|
            Variety = f.Variety;
 | 
						|
            Attribute = f.Attribute;
 | 
						|
            Cultivation = f.Cultivation;
 | 
						|
            var modifiers = (IEnumerable<Modifier>)(f.Modifiers ?? "").Split(',')
 | 
						|
                .Select(m => season?.Modifiers.FirstOrDefault(s => s.ModId == m))
 | 
						|
                .Where(m => m != null)
 | 
						|
                .OrderBy(m => m.Ordering)
 | 
						|
                .ToList();
 | 
						|
            Modifiers = modifiers.Select(m => m.Name).ToArray();
 | 
						|
            QualId = f.QualId;
 | 
						|
            QualityLevel = f.QualityLevel;
 | 
						|
            Gradation = (f.Oe, f.Kmw);
 | 
						|
            Buckets = rows
 | 
						|
                .Where(b => b.Value > 0)
 | 
						|
                .OrderByDescending(b => b.BktNr)
 | 
						|
                .Select(b => (b.Discr == "_" ? "ungeb." : $"geb. {f.SortId}{b.Discr}", b.Value,
 | 
						|
                              b.Price != null ? season?.DecFromDb((long)b.Price) : null,
 | 
						|
                              b.Amount != null ? season?.DecFromDb((long)b.Amount) : null))
 | 
						|
                .ToArray();
 | 
						|
            WeighingModifier = (varData == null || !varData.ConsiderDelieryModifiers) ? 0 : f.NetWeight ? varData.NetWeightModifier : varData.GrossWeightModifier;
 | 
						|
            Amount = f.TotalAmount != null ? season?.DecFromDb((long)f.TotalAmount) : null;
 | 
						|
            var netAmount = f.NetAmount != null ? season?.DecFromDb((long)f.NetAmount) : null;
 | 
						|
            var amt = netAmount * (decimal)(1.0 + WeighingModifier);
 | 
						|
            TotalModifiers = Amount - (amt != null ? Math.Round((decimal)amt, season?.Precision ?? 0) : null);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    [Keyless]
 | 
						|
    public class CreditNoteDeliveryRowSingle {
 | 
						|
        [Column("year")]
 | 
						|
        public int Year { get; set; }
 | 
						|
        [Column("tgnr")]
 | 
						|
        public int? TgNr { get; set; }
 | 
						|
        [Column("avnr")]
 | 
						|
        public int? AvNr { get; set; }
 | 
						|
        [Column("mgnr")]
 | 
						|
        public int MgNr { get; set; }
 | 
						|
        [Column("did")]
 | 
						|
        public int DId { get; set; }
 | 
						|
        [Column("lsnr")]
 | 
						|
        public required string LsNr { get; set; }
 | 
						|
        [Column("dpnr")]
 | 
						|
        public int DPNr { get; set; }
 | 
						|
        [Column("weight")]
 | 
						|
        public int Weight { get; set; }
 | 
						|
        [Column("modifiers")]
 | 
						|
        public string? Modifiers { get; set; }
 | 
						|
        [Column("bktnr")]
 | 
						|
        public int BktNr { get; set; }
 | 
						|
        [Column("sortid")]
 | 
						|
        public required string SortId { get; set; }
 | 
						|
        [Column("discr")]
 | 
						|
        public required string Discr { get; set; }
 | 
						|
        [Column("value")]
 | 
						|
        public int Value { get; set; }
 | 
						|
        [Column("price")]
 | 
						|
        public long? Price { get; set; }
 | 
						|
        [Column("amount")]
 | 
						|
        public long? Amount { get; set; }
 | 
						|
        [Column("net_amount")]
 | 
						|
        public long? NetAmount { get; set; }
 | 
						|
        [Column("total_amount")]
 | 
						|
        public long? TotalAmount { get; set; }
 | 
						|
        [Column("variety")]
 | 
						|
        public required string Variety { get; set; }
 | 
						|
        [Column("attribute")]
 | 
						|
        public string? Attribute { get; set; }
 | 
						|
        [Column("cultivation")]
 | 
						|
        public string? Cultivation { get; set; }
 | 
						|
        [Column("qualid")]
 | 
						|
        public required string QualId { get; set; }
 | 
						|
        [Column("quality_level")]
 | 
						|
        public required string QualityLevel { get; set; }
 | 
						|
        [Column("oe")]
 | 
						|
        public double Oe { get; set; }
 | 
						|
        [Column("kmw")]
 | 
						|
        public double Kmw { get; set; }
 | 
						|
        [Column("net_weight")]
 | 
						|
        public bool NetWeight { get; set; }
 | 
						|
    }
 | 
						|
}
 |