Compare commits
	
		
			3 Commits
		
	
	
		
			7086a72fab
			...
			f9d95a48f2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f9d95a48f2 | |||
| be734b880f | |||
| 1c45e95ef3 | 
@@ -43,6 +43,7 @@ namespace Elwig.Helpers {
 | 
			
		||||
        public DbSet<DeliveryPartAttr> DeliveryPartAttributes { get; private set; }
 | 
			
		||||
        public DbSet<DeliveryPartModifier> DeliveryPartModifiers { get; private set; }
 | 
			
		||||
        public DbSet<PaymentVar> PaymentVariants { get; private set; }
 | 
			
		||||
        public DbSet<PaymentMember> MemberPayments { get; private set; }
 | 
			
		||||
 | 
			
		||||
        private readonly StreamWriter? LogFile = null;
 | 
			
		||||
        public static DateTime LastWriteTime => File.GetLastWriteTime(App.Config.DatabaseFile);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								Elwig/Helpers/Billing/Transaction.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Elwig/Helpers/Billing/Transaction.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
using Elwig.Models;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Helpers.Billing {
 | 
			
		||||
    public class Transaction {
 | 
			
		||||
 | 
			
		||||
        public readonly Member Member;
 | 
			
		||||
        public readonly int AmountCent;
 | 
			
		||||
 | 
			
		||||
        public Transaction(Member m, decimal amount) {
 | 
			
		||||
            Member = m;
 | 
			
		||||
            AmountCent = (int)(amount * 100);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,51 @@
 | 
			
		||||
using Elwig.Models;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Helpers.Export {
 | 
			
		||||
    public class Bki {
 | 
			
		||||
    public class Bki : Csv<DeliveryPart> {
 | 
			
		||||
 | 
			
		||||
        private readonly string _clientData;
 | 
			
		||||
 | 
			
		||||
        public Bki(string filename) : base(filename, ';', Encoding.Latin1) {
 | 
			
		||||
            Header = """
 | 
			
		||||
                EDV-Liste zum automatischen Einlesen in die Weindatenbank;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
			
		||||
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
			
		||||
                Stammdaten;;;;;;;;;;;;;;Transportschein;;;;;;;;;;;;;;;;
 | 
			
		||||
                Empfänger:;;;;;;;Versender:;;;;;;;;;;;;;;;;;;;;;;;
 | 
			
		||||
                Betriebsnr;Name od. Firmenname;Vorname;Straße;Hausnr;Plz;Ort;Betriebsnr;Name od. Firmenname;Vorname;Straße;Hausnr;Plz;Ort;Datum der Lieferung;Menge in kg;Art;Weiß;Rot;Sorte1;Sorte2;Sorte3;Qualitätsstufe;Jahrgang;Herkunft;°KMW;°Oe;Vollablieferer;Ha Gesamt;Ha Ertragsfähig;Flächenbindung in Ha für AMA
 | 
			
		||||
                """;
 | 
			
		||||
            var c = App.Client;
 | 
			
		||||
            var (a1, a2) = Utils.SplitAddress(c.Address);
 | 
			
		||||
            _clientData = $"{c.LfbisNr};{c.NameFull};;{a1};{a2};{c.Plz};{c.Ort}";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task ExportAsync(AppDbContext ctx, int year) {
 | 
			
		||||
            await ExportAsync(await ctx.DeliveryParts.Where(p => p.Year == year).ToListAsync());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Export(AppDbContext ctx, int year) {
 | 
			
		||||
            ExportAsync(ctx, year).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string FormatRow(DeliveryPart p) {
 | 
			
		||||
            var d = p.Delivery;
 | 
			
		||||
            var m = d.Member;
 | 
			
		||||
            string memberData;
 | 
			
		||||
            if (m.BillingAddress is BillingAddr a) {
 | 
			
		||||
                var (n1, n2) = Utils.SplitName(a.Name, m.FamilyName);
 | 
			
		||||
                var (a1, a2) = Utils.SplitAddress(a.Address);
 | 
			
		||||
                memberData = $"{m.LfbisNr};{n1};{n2};{a1};{a2};{a.PostalDest.AtPlz?.Plz};{a.PostalDest.AtPlz?.Ort.Name}";
 | 
			
		||||
            } else {
 | 
			
		||||
                var (a1, a2) = Utils.SplitAddress(m.Address);
 | 
			
		||||
                memberData = $"{m.LfbisNr};{m.FamilyName};{m.AdministrativeName2};{a1};{a2};{m.PostalDest.AtPlz?.Plz};{m.PostalDest.AtPlz?.Ort.Name}";
 | 
			
		||||
            }
 | 
			
		||||
            var s = p.Variant;
 | 
			
		||||
            var deliveryData = $"{d.Date:dd.MM.yyyy};{p.Weight};TB;{(s.IsWhite ? "J" : "")};{(s.IsRed ? "J" : "")};{s.SortId};;;{p.QualId};{d.Year};{p.HkId};{p.Kmw};{p.Oe}";
 | 
			
		||||
            var vollData = $"N;;;{m.AreaCommitments.Where(a => a.YearFrom <= d.Year && (a.YearTo == null || a.YearTo >= d.Year)).Sum(a => a.Area) / 10_000.0}";
 | 
			
		||||
            return $"{_clientData};{memberData};{deliveryData};{vollData}";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,50 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Helpers.Export {
 | 
			
		||||
    public class Csv {
 | 
			
		||||
    public abstract class Csv<T> : IExporter<T> {
 | 
			
		||||
        public static string FileExtension => "csv";
 | 
			
		||||
 | 
			
		||||
        protected readonly StreamWriter Writer;
 | 
			
		||||
        protected readonly char Separator;
 | 
			
		||||
        protected string? Header;
 | 
			
		||||
 | 
			
		||||
        public Csv(string filename, char separator = ';') : this(filename, separator, Encoding.UTF8) { }
 | 
			
		||||
 | 
			
		||||
        public Csv(string filename, char separator, Encoding encoding) {
 | 
			
		||||
            Writer = new StreamWriter(filename, false, encoding);
 | 
			
		||||
            Separator = separator;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Dispose() {
 | 
			
		||||
            GC.SuppressFinalize(this);
 | 
			
		||||
            Writer.Dispose();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ValueTask DisposeAsync() {
 | 
			
		||||
            GC.SuppressFinalize(this);
 | 
			
		||||
            return Writer.DisposeAsync();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task ExportAsync(IEnumerable<T> data) {
 | 
			
		||||
            if (Header != null) await Writer.WriteLineAsync(Header);
 | 
			
		||||
            foreach (var row in data) {
 | 
			
		||||
                await Writer.WriteLineAsync(FormatRow(row));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Export(IEnumerable<T> data) {
 | 
			
		||||
            ExportAsync(data).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string FormatRow(IEnumerable row) {
 | 
			
		||||
            return string.Join(Separator, row);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public abstract string FormatRow(T row);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,26 @@
 | 
			
		||||
using Elwig.Models;
 | 
			
		||||
using Elwig.Helpers.Billing;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Helpers.Export {
 | 
			
		||||
    public class Ebics : IBankingProvider {
 | 
			
		||||
    public class Ebics : IBankingExporter {
 | 
			
		||||
 | 
			
		||||
        public string FileExtension => "xml";
 | 
			
		||||
        public static string FileExtension => "xml";
 | 
			
		||||
 | 
			
		||||
        public Task Export(string filename, int avnr, IEnumerable<Member> members) {
 | 
			
		||||
        public void Dispose() {
 | 
			
		||||
            throw new NotImplementedException();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ValueTask DisposeAsync() {
 | 
			
		||||
            throw new NotImplementedException();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Export(IEnumerable<Transaction> data) {
 | 
			
		||||
            throw new NotImplementedException();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Task ExportAsync(IEnumerable<Transaction> data) {
 | 
			
		||||
            throw new NotImplementedException();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,14 @@
 | 
			
		||||
using Elwig.Models;
 | 
			
		||||
using Elwig.Helpers.Billing;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Helpers.Export {
 | 
			
		||||
    public class Elba : IBankingProvider {
 | 
			
		||||
    public class Elba : Csv<Transaction>, IBankingExporter {
 | 
			
		||||
 | 
			
		||||
        public string FileExtension => "elba";
 | 
			
		||||
        public static new string FileExtension => "elba";
 | 
			
		||||
 | 
			
		||||
        public Task Export(string filename, int avnr, IEnumerable<Member> members) {
 | 
			
		||||
        public Elba(string filename) : base(filename) { }
 | 
			
		||||
 | 
			
		||||
        public override string FormatRow(Transaction row) {
 | 
			
		||||
            throw new NotImplementedException();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								Elwig/Helpers/Export/IBankingExporter.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								Elwig/Helpers/Export/IBankingExporter.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
using Elwig.Helpers.Billing;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Helpers.Export {
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Interface for exporting banking data
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public interface IBankingExporter : IExporter<Transaction> { }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
using Elwig.Models;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Helpers.Export {
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Interface for exporting banking data
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public interface IBankingProvider {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The default file extension of the exported files to be used (whithout a preceding ".")
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        string FileExtension { get; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Export the member payment data of the given payment variant to the given file.
 | 
			
		||||
        /// (The amount of the last payed variant is deducted from the calculated amount.)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="filename">The file to export the data to</param>
 | 
			
		||||
        /// <param name="avnr">The number of the payment variant to export</param>
 | 
			
		||||
        /// <param name="members">The members whose data to include in the export</param>
 | 
			
		||||
        Task Export(string filename, int avnr, IEnumerable<Member> members);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								Elwig/Helpers/Export/IExporter.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								Elwig/Helpers/Export/IExporter.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Helpers.Export {
 | 
			
		||||
    public interface IExporter<T> : IDisposable, IAsyncDisposable {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The default file extension of the exported files to be used (whithout a preceding ".")
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        static string FileExtension { get; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Export the given data to the given file.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="data">The data to be exported</param>
 | 
			
		||||
        void Export(IEnumerable<T> data);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Export the given data to the given file.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="data">The data to be exported</param>
 | 
			
		||||
        Task ExportAsync(IEnumerable<T> data);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -25,6 +25,7 @@ namespace Elwig.Helpers {
 | 
			
		||||
        public static readonly Regex PartialDateRegex = GeneratedPartialDateRegex();
 | 
			
		||||
        public static readonly Regex FromToRegex = GeneratedFromToRegex();
 | 
			
		||||
        public static readonly Regex FromToTimeRegex = GeneratedFromToTimeRegex();
 | 
			
		||||
        public static readonly Regex AddressRegex = GeneratedAddressRegex();
 | 
			
		||||
 | 
			
		||||
        [GeneratedRegex("^serial://([A-Za-z0-9]+):([0-9]+)(,([5-9]),([NOEMSnoems]),(0|1|1\\.5|2|))?$", RegexOptions.Compiled)]
 | 
			
		||||
        private static partial Regex GeneratedSerialRegex();
 | 
			
		||||
@@ -41,6 +42,9 @@ namespace Elwig.Helpers {
 | 
			
		||||
        [GeneratedRegex(@"^([0-9]{1,2}:[0-9]{2})?-([0-9]{1,2}:[0-9]{2})?$", RegexOptions.Compiled)]
 | 
			
		||||
        private static partial Regex GeneratedFromToTimeRegex();
 | 
			
		||||
 | 
			
		||||
        [GeneratedRegex(@"^(.*?) +([0-9].*)$", RegexOptions.Compiled)]
 | 
			
		||||
        private static partial Regex GeneratedAddressRegex();
 | 
			
		||||
 | 
			
		||||
        private static readonly ushort[] Crc16ModbusTable = {
 | 
			
		||||
            0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
 | 
			
		||||
            0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
 | 
			
		||||
@@ -292,5 +296,30 @@ namespace Elwig.Helpers {
 | 
			
		||||
        public static string GenerateLsNr(Delivery d) => GenerateLsNr(d.Date, d.ZwstId, d.LNr);
 | 
			
		||||
 | 
			
		||||
        public static string GenerateLsNr(DateOnly date, string zwstid, int lnr) => $"{date:yyyyMMdd}{zwstid}{lnr:000}";
 | 
			
		||||
 | 
			
		||||
        public static (string, string?) SplitAddress(string address) {
 | 
			
		||||
            var m = AddressRegex.Match(address);
 | 
			
		||||
            return (m.Groups[1].Value, m.Groups[2].Value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static (string, string?) SplitName(string fullName, string? familyName) {
 | 
			
		||||
            if (familyName == null) return (fullName, null);
 | 
			
		||||
            var p0 = fullName.ToLower().IndexOf(familyName.ToLower());
 | 
			
		||||
            if (p0 == -1) return (fullName, null);
 | 
			
		||||
            var p1 = fullName.IndexOf(" und ");
 | 
			
		||||
            var p2 = fullName.ToLower().LastIndexOf(" und ");
 | 
			
		||||
            if (p1 != p2) {
 | 
			
		||||
                if (p0 > p1) {
 | 
			
		||||
                    // A und B familyName [und ...]
 | 
			
		||||
                    return (fullName[p0..^0], fullName[0..(p0 - 1)]);
 | 
			
		||||
                } else {
 | 
			
		||||
                    // familyName und ... A und B
 | 
			
		||||
                    var p3 = fullName.LastIndexOf(' ', p2 - 1);
 | 
			
		||||
                    return (fullName[0..p3], fullName[(p3 + 1)..^0]);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                return (familyName, fullName.Replace(familyName, "").Replace("  ", " ").Trim());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,12 +19,8 @@ namespace Elwig.Models {
 | 
			
		||||
 | 
			
		||||
        [NotMapped]
 | 
			
		||||
        public DateOnly Date {
 | 
			
		||||
            get {
 | 
			
		||||
                return DateOnly.ParseExact(DateString, "yyyy-MM-dd");
 | 
			
		||||
            }
 | 
			
		||||
            set {
 | 
			
		||||
                DateString = value.ToString("yyyy-MM-dd");
 | 
			
		||||
            }
 | 
			
		||||
            get => DateOnly.ParseExact(DateString, "yyyy-MM-dd");
 | 
			
		||||
            set => DateString = value.ToString("yyyy-MM-dd");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Column("time")]
 | 
			
		||||
@@ -32,19 +28,13 @@ namespace Elwig.Models {
 | 
			
		||||
 | 
			
		||||
        [NotMapped]
 | 
			
		||||
        public TimeOnly? Time {
 | 
			
		||||
            get {
 | 
			
		||||
                return (TimeString == null) ? null : TimeOnly.ParseExact(TimeString, "HH:mm:ss");
 | 
			
		||||
            }
 | 
			
		||||
            set {
 | 
			
		||||
                TimeString = value?.ToString("HH:mm:ss");
 | 
			
		||||
            }
 | 
			
		||||
            get => (TimeString == null) ? null : TimeOnly.ParseExact(TimeString, "HH:mm:ss");
 | 
			
		||||
            set => TimeString = value?.ToString("HH:mm:ss");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NotMapped]
 | 
			
		||||
        public DateTime DateTime {
 | 
			
		||||
            get {
 | 
			
		||||
                return Date.ToDateTime(Time ?? TimeOnly.MinValue);
 | 
			
		||||
            }
 | 
			
		||||
            get => Date.ToDateTime(Time ?? TimeOnly.MinValue);
 | 
			
		||||
            set {
 | 
			
		||||
                Date = DateOnly.FromDateTime(value);
 | 
			
		||||
                Time = TimeOnly.FromDateTime(value);
 | 
			
		||||
@@ -72,6 +62,9 @@ namespace Elwig.Models {
 | 
			
		||||
        [Column("comment")]
 | 
			
		||||
        public string? Comment { get; set; }
 | 
			
		||||
 | 
			
		||||
        [ForeignKey("Year")]
 | 
			
		||||
        public virtual Season Season { get; private set; }
 | 
			
		||||
 | 
			
		||||
        [InverseProperty("Delivery")]
 | 
			
		||||
        public virtual ISet<DeliveryPart> Parts { get; private set; }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										31
									
								
								Elwig/Models/PaymentMember.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								Elwig/Models/PaymentMember.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Models {
 | 
			
		||||
    [Table("payment_member"), PrimaryKey("Year", "AvNr", "MgNr")]
 | 
			
		||||
    public class PaymentMember {
 | 
			
		||||
        [Column("year")]
 | 
			
		||||
        public int Year { get; set; }
 | 
			
		||||
 | 
			
		||||
        [Column("avnr")]
 | 
			
		||||
        public int AvNr { get; set; }
 | 
			
		||||
 | 
			
		||||
        [Column("mgnr")]
 | 
			
		||||
        public int MgNr { get; set; }
 | 
			
		||||
 | 
			
		||||
        [Column("amount")]
 | 
			
		||||
        public long AmountValue { get; set; }
 | 
			
		||||
 | 
			
		||||
        [NotMapped]
 | 
			
		||||
        public decimal Amount {
 | 
			
		||||
            get => Variant.Season.DecFromDb(AmountValue);
 | 
			
		||||
            set => AmountValue = Variant.Season.DecToDb(value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [ForeignKey("Year, AvNr")]
 | 
			
		||||
        public virtual PaymentVar Variant { get; private set; }
 | 
			
		||||
 | 
			
		||||
        [ForeignKey("MgNr")]
 | 
			
		||||
        public virtual Member Member { get; private set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using System;
 | 
			
		||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
			
		||||
 | 
			
		||||
@@ -65,5 +65,8 @@ namespace Elwig.Models {
 | 
			
		||||
 | 
			
		||||
        [Column("data")]
 | 
			
		||||
        public string Data { get; set; }
 | 
			
		||||
 | 
			
		||||
        [ForeignKey("Year")]
 | 
			
		||||
        public virtual Season Season { get; private set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,9 @@ namespace Elwig.Models {
 | 
			
		||||
 | 
			
		||||
        public string CommentFormat => (Comment != null) ? $" ({Comment})" : "";
 | 
			
		||||
 | 
			
		||||
        public bool IsRed => Type == "R";
 | 
			
		||||
        public bool IsWhite => Type == "W";
 | 
			
		||||
 | 
			
		||||
        public override string ToString() {
 | 
			
		||||
            return Name;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -68,5 +68,37 @@ namespace Tests {
 | 
			
		||||
                Assert.Throws<ArgumentException>(() => Utils.Modulo("789", -1));
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void Test_SplitAddress() {
 | 
			
		||||
            Assert.Multiple(() => {
 | 
			
		||||
                Assert.That(Utils.SplitAddress("Winzerstra<72>e 1"), Is.EqualTo(("Winzerstra<72>e", "1")));
 | 
			
		||||
                Assert.That(Utils.SplitAddress("Auf dem Feld 12"), Is.EqualTo(("Auf dem Feld", "12")));
 | 
			
		||||
                Assert.That(Utils.SplitAddress("Winzerstra<72>e 5a"), Is.EqualTo(("Winzerstra<72>e", "5a")));
 | 
			
		||||
                Assert.That(Utils.SplitAddress("Winzerstra<72>e 1-3/2"), Is.EqualTo(("Winzerstra<72>e", "1-3/2")));
 | 
			
		||||
                Assert.That(Utils.SplitAddress("Winzerstra<72>e 3/4/5"), Is.EqualTo(("Winzerstra<72>e", "3/4/5")));
 | 
			
		||||
                Assert.That(Utils.SplitAddress("Winzerstra<72>e 7/2/4/77"), Is.EqualTo(("Winzerstra<72>e", "7/2/4/77")));
 | 
			
		||||
                Assert.That(Utils.SplitAddress("Winzerstra<72>e 95b"), Is.EqualTo(("Winzerstra<72>e", "95b")));
 | 
			
		||||
                Assert.That(Utils.SplitAddress("Winzerstra<72>e 1, TOP 3"), Is.EqualTo(("Winzerstra<72>e", "1, TOP 3")));
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void Test_SplitName() {
 | 
			
		||||
            Assert.Multiple(() => {
 | 
			
		||||
                Assert.That(Utils.SplitName("Max Bauer", "Bauer"), Is.EqualTo(("Bauer", "Max")));
 | 
			
		||||
                Assert.That(Utils.SplitName("Bauer Max", "Bauer"), Is.EqualTo(("Bauer", "Max")));
 | 
			
		||||
                Assert.That(Utils.SplitName("Max und Moritz Bauer", "Bauer"), Is.EqualTo(("Bauer", "Max und Moritz")));
 | 
			
		||||
                Assert.That(Utils.SplitName("Bauer Max und Moritz", "Bauer"), Is.EqualTo(("Bauer", "Max und Moritz")));
 | 
			
		||||
                Assert.That(Utils.SplitName("Bauer GesbR", "Bauer"), Is.EqualTo(("Bauer", "GesbR")));
 | 
			
		||||
                Assert.That(Utils.SplitName("Max und Moritz Bauer GesbR", "Bauer"), Is.EqualTo(("Bauer", "Max und Moritz GesbR")));
 | 
			
		||||
                Assert.That(Utils.SplitName("Bauer Max und Moritz GesbR", "Bauer"), Is.EqualTo(("Bauer", "Max und Moritz GesbR")));
 | 
			
		||||
                Assert.That(Utils.SplitName("Weingut Bauer", "Bauer"), Is.EqualTo(("Bauer", "Weingut")));
 | 
			
		||||
                Assert.That(Utils.SplitName("Bauer Weingut", "Bauer"), Is.EqualTo(("Bauer", "Weingut")));
 | 
			
		||||
                Assert.That(Utils.SplitName("Max und Moritz Bauer und Mustermann", "Bauer"), Is.EqualTo(("Bauer und Mustermann", "Max und Moritz")));
 | 
			
		||||
                Assert.That(Utils.SplitName("Bauer und Mustermann Max und Moritz", "Bauer"), Is.EqualTo(("Bauer und Mustermann", "Max und Moritz")));
 | 
			
		||||
                Assert.That(Utils.SplitName("ABC GesbR", "Bauer"), Is.EqualTo(((string, string?))("ABC GesbR", null)));
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user