diff --git a/src/PostalRegistry.Api.Oslo/Infrastructure/Modules/ApiModule.cs b/src/PostalRegistry.Api.Oslo/Infrastructure/Modules/ApiModule.cs index 09999b4c..5255c9f5 100644 --- a/src/PostalRegistry.Api.Oslo/Infrastructure/Modules/ApiModule.cs +++ b/src/PostalRegistry.Api.Oslo/Infrastructure/Modules/ApiModule.cs @@ -8,6 +8,7 @@ namespace PostalRegistry.Api.Oslo.Infrastructure.Modules using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; + using Nuts; using Projections.Legacy; using Projections.Syndication.Modules; @@ -39,6 +40,9 @@ protected override void Load(ContainerBuilder builder) .RegisterType() .AsSelf(); + builder.RegisterType() + .SingleInstance(); + builder.Populate(_services); } } diff --git a/src/PostalRegistry.Api.Oslo/Nuts/Nuts3Service.cs b/src/PostalRegistry.Api.Oslo/Nuts/Nuts3Service.cs new file mode 100644 index 00000000..6a88dca3 --- /dev/null +++ b/src/PostalRegistry.Api.Oslo/Nuts/Nuts3Service.cs @@ -0,0 +1,59 @@ +namespace PostalRegistry.Api.Oslo.Nuts +{ + using System; + using System.Collections.Generic; + using System.Globalization; + using System.IO; + using System.Linq; + using System.Text; + using CsvHelper; + using CsvHelper.Configuration; + + public sealed class Nuts3Service + { + private const string Nuts3FileName = "nuts3_postal_v1.csv"; + private readonly List _nuts3Records = new List(); + + public Nuts3Service() + { + var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Nuts", Nuts3FileName); + + if (!File.Exists(filePath)) + { + // Handle the case where the file does not exist + throw new FileNotFoundException("NUTS3 CSV file not found."); + } + + var csvConfiguration = new CsvConfiguration(CultureInfo.InvariantCulture){ + Delimiter = ";", + HasHeaderRecord = true, + Encoding = Encoding.UTF8, + Quote = '\'' + }; + + using var reader = new StreamReader(filePath); + using var csvReader = new CsvReader(reader, csvConfiguration); + csvReader.Read(); // skip first record Header as ReadHeader doesn't work + + while (csvReader.Read()) + { + var nuts3Code = csvReader.GetField(0); + var postalCode = csvReader.GetField(1); + + _nuts3Records.Add(new Nuts3Record(nuts3Code, postalCode)); + } + } + + public Nuts3Record? GetNuts3ByPostalCode(string postalCode) + { + return _nuts3Records.FirstOrDefault(x => x.PostalCode == postalCode); + } + + public IEnumerable GetPostalCodesByNuts3(string nuts3Code) + { + return _nuts3Records.Where(x => string.Equals(x.Nuts3Code, nuts3Code, StringComparison.OrdinalIgnoreCase)); + } + } + + public record Nuts3Record(string Nuts3Code, string PostalCode); +} diff --git a/src/PostalRegistry.Api.Oslo/Nuts/nuts3_postal_v1.csv b/src/PostalRegistry.Api.Oslo/Nuts/nuts3_postal_v1.csv new file mode 100644 index 00000000..b374e462 --- /dev/null +++ b/src/PostalRegistry.Api.Oslo/Nuts/nuts3_postal_v1.csv @@ -0,0 +1,1147 @@ +NUTS3;CODE +'BE100';'1000' +'BE100';'1020' +'BE100';'1030' +'BE100';'1040' +'BE100';'1050' +'BE100';'1060' +'BE100';'1070' +'BE100';'1080' +'BE100';'1081' +'BE100';'1082' +'BE100';'1083' +'BE100';'1090' +'BE100';'1120' +'BE100';'1130' +'BE100';'1140' +'BE100';'1150' +'BE100';'1160' +'BE100';'1170' +'BE100';'1180' +'BE100';'1190' +'BE100';'1200' +'BE100';'1210' +'BE212';'2220' +'BE212';'2221' +'BE212';'2222' +'BE212';'2223' +'BE212';'2500' +'BE212';'2560' +'BE212';'2570' +'BE212';'2580' +'BE212';'2590' +'BE212';'2800' +'BE212';'2801' +'BE212';'2811' +'BE212';'2812' +'BE212';'2820' +'BE212';'2830' +'BE212';'2860' +'BE212';'2861' +'BE212';'2870' +'BE212';'2880' +'BE212';'2890' +'BE213';'2200' +'BE213';'2230' +'BE213';'2235' +'BE213';'2250' +'BE213';'2260' +'BE213';'2270' +'BE213';'2275' +'BE213';'2280' +'BE213';'2288' +'BE213';'2290' +'BE213';'2300' +'BE213';'2310' +'BE213';'2320' +'BE213';'2322' +'BE213';'2323' +'BE213';'2328' +'BE213';'2330' +'BE213';'2340' +'BE213';'2350' +'BE213';'2360' +'BE213';'2370' +'BE213';'2380' +'BE213';'2381' +'BE213';'2382' +'BE213';'2387' +'BE213';'2400' +'BE213';'2430' +'BE213';'2431' +'BE213';'2440' +'BE213';'2450' +'BE213';'2460' +'BE213';'2470' +'BE213';'2480' +'BE213';'2490' +'BE213';'2491' +'BE223';'3570' +'BE223';'3620' +'BE223';'3621' +'BE223';'3630' +'BE223';'3631' +'BE223';'3700' +'BE223';'3717' +'BE223';'3720' +'BE223';'3721' +'BE223';'3722' +'BE223';'3723' +'BE223';'3724' +'BE223';'3730' +'BE223';'3732' +'BE223';'3740' +'BE223';'3742' +'BE223';'3746' +'BE223';'3770' +'BE223';'3790' +'BE223';'3791' +'BE223';'3792' +'BE223';'3793' +'BE223';'3798' +'BE223';'3830' +'BE223';'3831' +'BE223';'3832' +'BE223';'3840' +'BE223';'3870' +'BE224';'3500' +'BE224';'3501' +'BE224';'3510' +'BE224';'3511' +'BE224';'3512' +'BE224';'3520' +'BE224';'3540' +'BE224';'3545' +'BE224';'3550' +'BE224';'3560' +'BE224';'3580' +'BE224';'3581' +'BE224';'3582' +'BE224';'3583' +'BE224';'3590' +'BE224';'3600' +'BE224';'3665' +'BE224';'3668' +'BE224';'3690' +'BE224';'3800' +'BE224';'3803' +'BE224';'3806' +'BE224';'3850' +'BE224';'3890' +'BE224';'3891' +'BE224';'3945' +'BE224';'3970' +'BE224';'3971' +'BE224';'3980' +'BE225';'3530' +'BE225';'3640' +'BE225';'3650' +'BE225';'3660' +'BE225';'3670' +'BE225';'3680' +'BE225';'3900' +'BE225';'3910' +'BE225';'3920' +'BE225';'3930' +'BE225';'3940' +'BE225';'3941' +'BE225';'3950' +'BE225';'3960' +'BE225';'3990' +'BE231';'9300' +'BE231';'9308' +'BE231';'9310' +'BE231';'9320' +'BE231';'9340' +'BE231';'9400' +'BE231';'9401' +'BE231';'9402' +'BE231';'9403' +'BE231';'9404' +'BE231';'9406' +'BE231';'9420' +'BE231';'9450' +'BE231';'9451' +'BE231';'9470' +'BE231';'9472' +'BE231';'9473' +'BE231';'9500' +'BE231';'9506' +'BE231';'9520' +'BE231';'9521' +'BE231';'9550' +'BE231';'9551' +'BE231';'9552' +'BE231';'9620' +'BE233';'9060' +'BE233';'9900' +'BE233';'9960' +'BE233';'9961' +'BE233';'9968' +'BE233';'9970' +'BE233';'9971' +'BE233';'9980' +'BE233';'9981' +'BE233';'9982' +'BE233';'9988' +'BE233';'9990' +'BE233';'9991' +'BE233';'9992' +'BE234';'9000' +'BE234';'9030' +'BE234';'9031' +'BE234';'9032' +'BE234';'9040' +'BE234';'9041' +'BE234';'9042' +'BE234';'9050' +'BE234';'9051' +'BE234';'9052' +'BE234';'9070' +'BE234';'9080' +'BE234';'9090' +'BE234';'9180' +'BE234';'9185' +'BE234';'9800' +'BE234';'9810' +'BE234';'9820' +'BE234';'9830' +'BE234';'9831' +'BE234';'9840' +'BE234';'9850' +'BE234';'9860' +'BE234';'9870' +'BE234';'9880' +'BE234';'9881' +'BE234';'9890' +'BE234';'9910' +'BE234';'9920' +'BE234';'9921' +'BE234';'9930' +'BE234';'9931' +'BE234';'9932' +'BE234';'9940' +'BE234';'9950' +'BE235';'9570' +'BE235';'9571' +'BE235';'9572' +'BE235';'9600' +'BE235';'9630' +'BE235';'9636' +'BE235';'9660' +'BE235';'9661' +'BE235';'9667' +'BE235';'9680' +'BE235';'9681' +'BE235';'9688' +'BE235';'9690' +'BE235';'9700' +'BE235';'9750' +'BE235';'9770' +'BE235';'9771' +'BE235';'9772' +'BE235';'9790' +'BE236';'9100' +'BE236';'9111' +'BE236';'9112' +'BE236';'9120' +'BE236';'9130' +'BE236';'9140' +'BE236';'9150' +'BE236';'9160' +'BE236';'9170' +'BE236';'9190' +'BE241';'1500' +'BE241';'1501' +'BE241';'1502' +'BE241';'1540' +'BE241';'1541' +'BE241';'1547' +'BE241';'1560' +'BE241';'1570' +'BE241';'1600' +'BE241';'1601' +'BE241';'1602' +'BE241';'1620' +'BE241';'1630' +'BE241';'1640' +'BE241';'1650' +'BE241';'1651' +'BE241';'1652' +'BE241';'1653' +'BE241';'1654' +'BE241';'1670' +'BE241';'1671' +'BE241';'1673' +'BE241';'1674' +'BE241';'1700' +'BE241';'1701' +'BE241';'1702' +'BE241';'1703' +'BE241';'1730' +'BE241';'1731' +'BE241';'1740' +'BE241';'1741' +'BE241';'1742' +'BE241';'1745' +'BE241';'1750' +'BE241';'1755' +'BE241';'1760' +'BE241';'1761' +'BE241';'1770' +'BE241';'1780' +'BE241';'1785' +'BE241';'1790' +'BE241';'1800' +'BE241';'1820' +'BE241';'1830' +'BE241';'1831' +'BE241';'1840' +'BE241';'1850' +'BE241';'1851' +'BE241';'1852' +'BE241';'1853' +'BE241';'1860' +'BE241';'1861' +'BE241';'1880' +'BE241';'1910' +'BE241';'1930' +'BE241';'1932' +'BE241';'1933' +'BE241';'1950' +'BE241';'1970' +'BE241';'1980' +'BE241';'1981' +'BE241';'1982' +'BE241';'3090' +'BE251';'8000' +'BE251';'8020' +'BE251';'8200' +'BE251';'8210' +'BE251';'8211' +'BE251';'8300' +'BE251';'8301' +'BE251';'8310' +'BE251';'8340' +'BE251';'8370' +'BE251';'8377' +'BE251';'8380' +'BE251';'8490' +'BE251';'8730' +'BE251';'8820' +'BE252';'8600' +'BE252';'8610' +'BE252';'8647' +'BE252';'8650' +'BE252';'8680' +'BE253';'8640' +'BE253';'8900' +'BE253';'8902' +'BE253';'8904' +'BE253';'8906' +'BE253';'8908' +'BE253';'8920' +'BE253';'8940' +'BE253';'8950' +'BE253';'8951' +'BE253';'8952' +'BE253';'8953' +'BE253';'8954' +'BE253';'8956' +'BE253';'8957' +'BE253';'8958' +'BE253';'8970' +'BE253';'8978' +'BE253';'8980' +'BE254';'8500' +'BE254';'8501' +'BE254';'8510' +'BE254';'8511' +'BE254';'8520' +'BE254';'8530' +'BE254';'8531' +'BE254';'8540' +'BE254';'8550' +'BE254';'8551' +'BE254';'8552' +'BE254';'8553' +'BE254';'8554' +'BE254';'8560' +'BE254';'8570' +'BE254';'8572' +'BE254';'8573' +'BE254';'8580' +'BE254';'8581' +'BE254';'8582' +'BE254';'8583' +'BE254';'8710' +'BE254';'8790' +'BE254';'8791' +'BE254';'8792' +'BE254';'8793' +'BE254';'8860' +'BE254';'8930' +'BE255';'8400' +'BE255';'8420' +'BE255';'8421' +'BE255';'8430' +'BE255';'8431' +'BE255';'8432' +'BE255';'8433' +'BE255';'8434' +'BE255';'8450' +'BE255';'8460' +'BE255';'8470' +'BE255';'8480' +'BE256';'8770' +'BE256';'8800' +'BE256';'8810' +'BE256';'8830' +'BE256';'8840' +'BE256';'8870' +'BE256';'8880' +'BE256';'8890' +'BE258';'8620' +'BE258';'8630' +'BE258';'8660' +'BE258';'8670' +'BE258';'8690' +'BE258';'8691' +'BE258';'8972' +'BE310';'1300' +'BE310';'1301' +'BE310';'1310' +'BE310';'1315' +'BE310';'1320' +'BE310';'1325' +'BE310';'1330' +'BE310';'1331' +'BE310';'1332' +'BE310';'1340' +'BE310';'1341' +'BE310';'1342' +'BE310';'1348' +'BE310';'1350' +'BE310';'1357' +'BE310';'1360' +'BE310';'1367' +'BE310';'1370' +'BE310';'1380' +'BE310';'1390' +'BE310';'1400' +'BE310';'1401' +'BE310';'1402' +'BE310';'1404' +'BE310';'1410' +'BE310';'1420' +'BE310';'1421' +'BE310';'1428' +'BE310';'1430' +'BE310';'1435' +'BE310';'1440' +'BE310';'1450' +'BE310';'1457' +'BE310';'1460' +'BE310';'1461' +'BE310';'1470' +'BE310';'1471' +'BE310';'1472' +'BE310';'1473' +'BE310';'1474' +'BE310';'1476' +'BE310';'1480' +'BE310';'1490' +'BE310';'1495' +'BE323';'7000' +'BE323';'7011' +'BE323';'7012' +'BE323';'7020' +'BE323';'7021' +'BE323';'7022' +'BE323';'7024' +'BE323';'7030' +'BE323';'7031' +'BE323';'7032' +'BE323';'7033' +'BE323';'7034' +'BE323';'7040' +'BE323';'7041' +'BE323';'7050' +'BE323';'7080' +'BE323';'7300' +'BE323';'7301' +'BE323';'7330' +'BE323';'7331' +'BE323';'7332' +'BE323';'7333' +'BE323';'7334' +'BE323';'7340' +'BE323';'7350' +'BE323';'7370' +'BE323';'7380' +'BE323';'7382' +'BE323';'7387' +'BE323';'7390' +'BE323';'7870' +'BE328';'7500' +'BE328';'7501' +'BE328';'7502' +'BE328';'7503' +'BE328';'7504' +'BE328';'7506' +'BE328';'7520' +'BE328';'7521' +'BE328';'7522' +'BE328';'7530' +'BE328';'7531' +'BE328';'7532' +'BE328';'7533' +'BE328';'7534' +'BE328';'7536' +'BE328';'7538' +'BE328';'7540' +'BE328';'7542' +'BE328';'7543' +'BE328';'7548' +'BE328';'7600' +'BE328';'7601' +'BE328';'7602' +'BE328';'7603' +'BE328';'7604' +'BE328';'7608' +'BE328';'7610' +'BE328';'7611' +'BE328';'7618' +'BE328';'7620' +'BE328';'7621' +'BE328';'7622' +'BE328';'7623' +'BE328';'7624' +'BE328';'7640' +'BE328';'7641' +'BE328';'7642' +'BE328';'7643' +'BE328';'7700' +'BE328';'7711' +'BE328';'7712' +'BE328';'7730' +'BE328';'7740' +'BE328';'7742' +'BE328';'7743' +'BE328';'7750' +'BE328';'7760' +'BE328';'7781' +'BE328';'7782' +'BE328';'7783' +'BE328';'7784' +'BE328';'7900' +'BE328';'7901' +'BE328';'7903' +'BE328';'7904' +'BE328';'7906' +'BE328';'8587' +'BE329';'7100' +'BE329';'7110' +'BE329';'7120' +'BE329';'7130' +'BE329';'7131' +'BE329';'7133' +'BE329';'7134' +'BE329';'7140' +'BE329';'7141' +'BE32B';'6000' +'BE32B';'6001' +'BE32B';'6010' +'BE32B';'6020' +'BE32B';'6030' +'BE32B';'6031' +'BE32B';'6032' +'BE32B';'6040' +'BE32B';'6041' +'BE32B';'6042' +'BE32B';'6043' +'BE32B';'6044' +'BE32B';'6060' +'BE32B';'6061' +'BE32B';'6110' +'BE32B';'6111' +'BE32B';'6140' +'BE32B';'6141' +'BE32B';'6142' +'BE32B';'6180' +'BE32B';'6181' +'BE32B';'6182' +'BE32B';'6183' +'BE32B';'6200' +'BE32B';'6210' +'BE32B';'6211' +'BE32B';'6220' +'BE32B';'6221' +'BE32B';'6222' +'BE32B';'6223' +'BE32B';'6224' +'BE32B';'6230' +'BE32B';'6238' +'BE32B';'6240' +'BE32B';'6250' +'BE32B';'6280' +'BE32B';'7160' +'BE32C';'7060' +'BE32C';'7061' +'BE32C';'7062' +'BE32C';'7063' +'BE32C';'7070' +'BE32C';'7090' +'BE32C';'7170' +'BE32C';'7180' +'BE32C';'7181' +'BE32C';'7190' +'BE32C';'7191' +'BE32D';'6120' +'BE32D';'6150' +'BE32D';'6440' +'BE32D';'6441' +'BE32D';'6460' +'BE32D';'6461' +'BE32D';'6462' +'BE32D';'6463' +'BE32D';'6464' +'BE32D';'6470' +'BE32D';'6500' +'BE32D';'6511' +'BE32D';'6530' +'BE32D';'6531' +'BE32D';'6532' +'BE32D';'6533' +'BE32D';'6534' +'BE32D';'6536' +'BE32D';'6540' +'BE32D';'6542' +'BE32D';'6543' +'BE32D';'6560' +'BE32D';'6567' +'BE32D';'6590' +'BE32D';'6591' +'BE32D';'6592' +'BE32D';'6593' +'BE32D';'6594' +'BE32D';'6596' +'BE331';'4160' +'BE331';'4161' +'BE331';'4162' +'BE331';'4163' +'BE331';'4180' +'BE331';'4181' +'BE331';'4190' +'BE331';'4210' +'BE331';'4217' +'BE331';'4218' +'BE331';'4480' +'BE331';'4500' +'BE331';'4520' +'BE331';'4530' +'BE331';'4537' +'BE331';'4540' +'BE331';'4550' +'BE331';'4557' +'BE331';'4560' +'BE331';'4570' +'BE331';'4577' +'BE331';'4590' +'BE332';'4000' +'BE332';'4020' +'BE332';'4030' +'BE332';'4031' +'BE332';'4032' +'BE332';'4040' +'BE332';'4041' +'BE332';'4042' +'BE332';'4050' +'BE332';'4051' +'BE332';'4052' +'BE332';'4053' +'BE332';'4100' +'BE332';'4101' +'BE332';'4102' +'BE332';'4120' +'BE332';'4121' +'BE332';'4122' +'BE332';'4130' +'BE332';'4140' +'BE332';'4141' +'BE332';'4170' +'BE332';'4171' +'BE332';'4340' +'BE332';'4342' +'BE332';'4400' +'BE332';'4420' +'BE332';'4430' +'BE332';'4431' +'BE332';'4432' +'BE332';'4450' +'BE332';'4451' +'BE332';'4452' +'BE332';'4453' +'BE332';'4458' +'BE332';'4460' +'BE332';'4600' +'BE332';'4601' +'BE332';'4602' +'BE332';'4606' +'BE332';'4607' +'BE332';'4608' +'BE332';'4610' +'BE332';'4620' +'BE332';'4621' +'BE332';'4623' +'BE332';'4624' +'BE332';'4630' +'BE332';'4631' +'BE332';'4632' +'BE332';'4633' +'BE332';'4670' +'BE332';'4671' +'BE332';'4672' +'BE332';'4680' +'BE332';'4681' +'BE332';'4682' +'BE332';'4683' +'BE332';'4684' +'BE332';'4690' +'BE332';'4920' +'BE334';'4219' +'BE334';'4250' +'BE334';'4252' +'BE334';'4253' +'BE334';'4254' +'BE334';'4257' +'BE334';'4260' +'BE334';'4261' +'BE334';'4263' +'BE334';'4280' +'BE334';'4287' +'BE334';'4300' +'BE334';'4317' +'BE334';'4347' +'BE334';'4350' +'BE334';'4351' +'BE334';'4357' +'BE334';'4360' +'BE334';'4367' +'BE334';'4470' +'BE336';'4700' +'BE336';'4701' +'BE336';'4710' +'BE336';'4711' +'BE336';'4720' +'BE336';'4721' +'BE336';'4728' +'BE336';'4730' +'BE336';'4731' +'BE336';'4750' +'BE336';'4760' +'BE336';'4761' +'BE336';'4771' +'BE336';'4780' +'BE336';'4782' +'BE336';'4783' +'BE336';'4784' +'BE336';'4790' +'BE336';'4791' +'BE341';'6630' +'BE341';'6700' +'BE341';'6704' +'BE341';'6706' +'BE341';'6717' +'BE341';'6780' +'BE341';'6781' +'BE341';'6782' +'BE341';'6790' +'BE341';'6791' +'BE341';'6792' +'BE342';'6600' +'BE342';'6637' +'BE342';'6640' +'BE342';'6642' +'BE342';'6660' +'BE342';'6661' +'BE342';'6662' +'BE342';'6663' +'BE342';'6666' +'BE342';'6670' +'BE342';'6671' +'BE342';'6672' +'BE342';'6673' +'BE342';'6674' +'BE342';'6680' +'BE342';'6681' +'BE342';'6686' +'BE342';'6687' +'BE342';'6688' +'BE342';'6690' +'BE342';'6692' +'BE342';'6698' +'BE343';'6900' +'BE343';'6940' +'BE343';'6941' +'BE343';'6950' +'BE343';'6951' +'BE343';'6952' +'BE343';'6953' +'BE343';'6960' +'BE343';'6970' +'BE343';'6971' +'BE343';'6972' +'BE343';'6980' +'BE343';'6982' +'BE343';'6983' +'BE343';'6984' +'BE343';'6986' +'BE343';'6987' +'BE343';'6990' +'BE343';'6997' +'BE344';'6800' +'BE344';'6830' +'BE344';'6831' +'BE344';'6832' +'BE344';'6833' +'BE344';'6834' +'BE344';'6836' +'BE344';'6838' +'BE344';'6840' +'BE344';'6850' +'BE344';'6851' +'BE344';'6852' +'BE344';'6853' +'BE344';'6856' +'BE344';'6860' +'BE344';'6870' +'BE344';'6880' +'BE344';'6887' +'BE344';'6890' +'BE344';'6920' +'BE344';'6921' +'BE344';'6922' +'BE344';'6924' +'BE344';'6927' +'BE344';'6929' +'BE351';'5360' +'BE351';'5361' +'BE351';'5362' +'BE351';'5363' +'BE351';'5364' +'BE351';'5370' +'BE351';'5372' +'BE351';'5374' +'BE351';'5376' +'BE351';'5377' +'BE351';'5500' +'BE351';'5501' +'BE351';'5502' +'BE351';'5503' +'BE351';'5504' +'BE351';'5520' +'BE351';'5521' +'BE351';'5522' +'BE351';'5523' +'BE351';'5524' +'BE351';'5530' +'BE351';'5537' +'BE351';'5540' +'BE351';'5541' +'BE351';'5542' +'BE351';'5543' +'BE351';'5544' +'BE351';'5550' +'BE351';'5555' +'BE351';'5560' +'BE351';'5561' +'BE351';'5562' +'BE351';'5563' +'BE351';'5564' +'BE351';'5570' +'BE351';'5571' +'BE351';'5572' +'BE351';'5573' +'BE351';'5574' +'BE351';'5575' +'BE351';'5576' +'BE351';'5580' +'BE351';'5590' +'BE352';'5000' +'BE352';'5001' +'BE352';'5002' +'BE352';'5003' +'BE352';'5004' +'BE352';'5020' +'BE352';'5021' +'BE352';'5022' +'BE352';'5024' +'BE352';'5030' +'BE352';'5031' +'BE352';'5032' +'BE352';'5060' +'BE352';'5070' +'BE352';'5080' +'BE352';'5081' +'BE352';'5100' +'BE352';'5101' +'BE352';'5140' +'BE352';'5150' +'BE352';'5170' +'BE352';'5190' +'BE352';'5300' +'BE352';'5310' +'BE352';'5330' +'BE352';'5332' +'BE352';'5333' +'BE352';'5334' +'BE352';'5336' +'BE352';'5340' +'BE352';'5350' +'BE352';'5351' +'BE352';'5352' +'BE352';'5353' +'BE352';'5354' +'BE352';'5380' +'BE352';'5640' +'BE352';'5641' +'BE352';'5644' +'BE352';'5646' +'BE353';'5600' +'BE353';'5620' +'BE353';'5621' +'BE353';'5630' +'BE353';'5650' +'BE353';'5651' +'BE353';'5660' +'BE353';'5670' +'BE353';'5680' +'BE211';'2000' +'BE211';'2018' +'BE211';'2020' +'BE211';'2030' +'BE211';'2040' +'BE211';'2050' +'BE211';'2060' +'BE211';'2070' +'BE211';'2100' +'BE211';'2110' +'BE211';'2140' +'BE211';'2150' +'BE211';'2160' +'BE211';'2170' +'BE211';'2180' +'BE211';'2240' +'BE211';'2242' +'BE211';'2243' +'BE211';'2390' +'BE211';'2520' +'BE211';'2530' +'BE211';'2531' +'BE211';'2540' +'BE211';'2547' +'BE211';'2550' +'BE211';'2600' +'BE211';'2610' +'BE211';'2620' +'BE211';'2627' +'BE211';'2630' +'BE211';'2640' +'BE211';'2650' +'BE211';'2660' +'BE211';'2840' +'BE211';'2845' +'BE211';'2850' +'BE211';'2900' +'BE211';'2910' +'BE211';'2920' +'BE211';'2930' +'BE211';'2940' +'BE211';'2950' +'BE211';'2960' +'BE211';'2970' +'BE211';'2980' +'BE211';'2990' +'BE232';'9200' +'BE232';'9220' +'BE232';'9230' +'BE232';'9240' +'BE232';'9250' +'BE232';'9255' +'BE232';'9260' +'BE232';'9270' +'BE232';'9280' +'BE232';'9290' +'BE242';'3000' +'BE242';'3001' +'BE242';'3010' +'BE242';'3012' +'BE242';'3018' +'BE242';'3020' +'BE242';'3040' +'BE242';'3050' +'BE242';'3051' +'BE242';'3052' +'BE242';'3053' +'BE242';'3054' +'BE242';'3060' +'BE242';'3061' +'BE242';'3070' +'BE242';'3071' +'BE242';'3078' +'BE242';'3080' +'BE242';'3110' +'BE242';'3111' +'BE242';'3118' +'BE242';'3120' +'BE242';'3128' +'BE242';'3130' +'BE242';'3140' +'BE242';'3150' +'BE242';'3190' +'BE242';'3191' +'BE242';'3200' +'BE242';'3201' +'BE242';'3202' +'BE242';'3210' +'BE242';'3211' +'BE242';'3212' +'BE242';'3220' +'BE242';'3221' +'BE242';'3270' +'BE242';'3271' +'BE242';'3272' +'BE242';'3290' +'BE242';'3293' +'BE242';'3294' +'BE242';'3300' +'BE242';'3320' +'BE242';'3321' +'BE242';'3350' +'BE242';'3360' +'BE242';'3370' +'BE242';'3380' +'BE242';'3381' +'BE242';'3384' +'BE242';'3390' +'BE242';'3391' +'BE242';'3400' +'BE242';'3401' +'BE242';'3404' +'BE242';'3440' +'BE242';'3450' +'BE242';'3454' +'BE242';'3460' +'BE242';'3461' +'BE242';'3470' +'BE242';'3471' +'BE242';'3472' +'BE242';'3473' +'BE257';'8700' +'BE257';'8720' +'BE257';'8740' +'BE257';'8750' +'BE257';'8755' +'BE257';'8760' +'BE257';'8780' +'BE257';'8850' +'BE257';'8851' +'BE32A';'7320' +'BE32A';'7321' +'BE32A';'7322' +'BE32A';'7800' +'BE32A';'7801' +'BE32A';'7802' +'BE32A';'7803' +'BE32A';'7804' +'BE32A';'7810' +'BE32A';'7811' +'BE32A';'7812' +'BE32A';'7822' +'BE32A';'7823' +'BE32A';'7830' +'BE32A';'7850' +'BE32A';'7860' +'BE32A';'7861' +'BE32A';'7862' +'BE32A';'7863' +'BE32A';'7864' +'BE32A';'7866' +'BE32A';'7880' +'BE32A';'7890' +'BE32A';'7910' +'BE32A';'7911' +'BE32A';'7912' +'BE32A';'7940' +'BE32A';'7941' +'BE32A';'7942' +'BE32A';'7943' +'BE32A';'7950' +'BE32A';'7951' +'BE32A';'7970' +'BE32A';'7971' +'BE32A';'7972' +'BE32A';'7973' +'BE335';'4650' +'BE335';'4651' +'BE335';'4652' +'BE335';'4653' +'BE335';'4654' +'BE335';'4770' +'BE335';'4800' +'BE335';'4801' +'BE335';'4802' +'BE335';'4820' +'BE335';'4821' +'BE335';'4830' +'BE335';'4831' +'BE335';'4834' +'BE335';'4837' +'BE335';'4840' +'BE335';'4841' +'BE335';'4845' +'BE335';'4850' +'BE335';'4851' +'BE335';'4852' +'BE335';'4860' +'BE335';'4861' +'BE335';'4870' +'BE335';'4877' +'BE335';'4880' +'BE335';'4890' +'BE335';'4900' +'BE335';'4910' +'BE335';'4950' +'BE335';'4960' +'BE335';'4970' +'BE335';'4980' +'BE335';'4983' +'BE335';'4987' +'BE335';'4990' +'BE345';'6720' +'BE345';'6721' +'BE345';'6723' +'BE345';'6724' +'BE345';'6730' +'BE345';'6740' +'BE345';'6741' +'BE345';'6742' +'BE345';'6743' +'BE345';'6747' +'BE345';'6750' +'BE345';'6760' +'BE345';'6761' +'BE345';'6762' +'BE345';'6767' +'BE345';'6769' +'BE345';'6810' +'BE345';'6811' +'BE345';'6812' +'BE345';'6813' +'BE345';'6820' +'BE345';'6821' +'BE345';'6823' +'BE345';'6824' +'BE328';'7780' +'BE213';'2321' diff --git a/src/PostalRegistry.Api.Oslo/PostalInformation/PostalInformationOsloController.cs b/src/PostalRegistry.Api.Oslo/PostalInformation/PostalInformationOsloController.cs index 5d2a36bb..9116e308 100644 --- a/src/PostalRegistry.Api.Oslo/PostalInformation/PostalInformationOsloController.cs +++ b/src/PostalRegistry.Api.Oslo/PostalInformation/PostalInformationOsloController.cs @@ -20,6 +20,7 @@ namespace PostalRegistry.Api.Oslo.PostalInformation using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; + using Nuts; using Projections.Legacy; using Projections.Syndication; using Query; @@ -39,6 +40,7 @@ public class PostalInformationOsloController : ApiController /// /// /// + /// /// De postcode. /// /// Als de postcode gevonden is. @@ -56,6 +58,7 @@ public async Task Get( [FromServices] LegacyContext context, [FromServices] SyndicationContext syndicationContext, [FromServices] IOptions responseOptions, + [FromServices] Nuts3Service nuts3Service, [FromRoute] string postalCode, CancellationToken cancellationToken = default) { @@ -76,6 +79,8 @@ public async Task Get( responseOptions.Value.GemeenteDetailUrl, cancellationToken); + var nuts3Record = nuts3Service.GetNuts3ByPostalCode(postalInformation.PostalCode); + return Ok( new PostalInformationOsloResponse( responseOptions.Value.Naamruimte, @@ -85,7 +90,8 @@ public async Task Get( postalInformation.VersionTimestamp.ToBelgianDateTimeOffset(), postalInformation.IsRetired ? PostInfoStatus.Gehistoreerd - : PostInfoStatus.Gerealiseerd) + : PostInfoStatus.Gerealiseerd, + nuts3Record?.Nuts3Code) { Postnamen = postalInformation .PostalNames? @@ -100,6 +106,7 @@ public async Task Get( /// /// /// + /// /// /// Als de opvraging van een lijst met postcodes gelukt is. /// Als er een interne fout is opgetreden. @@ -113,6 +120,7 @@ public async Task List( [FromServices] LegacyContext legacyContext, [FromServices] SyndicationContext syndicationContext, [FromServices] IOptions responseOptions, + [FromServices] Nuts3Service nuts3Service, CancellationToken cancellationToken = default) { var filtering = Request.ExtractFilteringRequest(); @@ -120,7 +128,7 @@ public async Task List( var pagination = Request.ExtractPaginationRequest(); var pagedPostalInformationSet = - new PostalInformationListOsloQuery(legacyContext, syndicationContext) + new PostalInformationListOsloQuery(legacyContext, syndicationContext, nuts3Service) .Fetch(filtering, sorting, pagination); Response.AddPagedQueryResultHeaders(pagedPostalInformationSet); @@ -153,6 +161,7 @@ public async Task List( /// /// /// + /// /// /// Als de opvraging van het totaal aantal gelukt is. /// Als er een interne fout is opgetreden. @@ -165,6 +174,7 @@ public async Task List( public async Task Count( [FromServices] LegacyContext context, [FromServices] SyndicationContext syndicationContext, + [FromServices] Nuts3Service nuts3Service, CancellationToken cancellationToken = default) { var filtering = Request.ExtractFilteringRequest(); @@ -175,7 +185,7 @@ public async Task Count( new TotaalAantalResponse { Aantal = filtering.ShouldFilter - ? await new PostalInformationListOsloQuery(context, syndicationContext) + ? await new PostalInformationListOsloQuery(context, syndicationContext, nuts3Service) .Fetch(filtering, sorting, pagination) .Items .CountAsync(cancellationToken) diff --git a/src/PostalRegistry.Api.Oslo/PostalInformation/Query/PostalInformationListOsloQuery.cs b/src/PostalRegistry.Api.Oslo/PostalInformation/Query/PostalInformationListOsloQuery.cs index 00763100..25808ead 100644 --- a/src/PostalRegistry.Api.Oslo/PostalInformation/Query/PostalInformationListOsloQuery.cs +++ b/src/PostalRegistry.Api.Oslo/PostalInformation/Query/PostalInformationListOsloQuery.cs @@ -7,6 +7,7 @@ namespace PostalRegistry.Api.Oslo.PostalInformation.Query using Be.Vlaanderen.Basisregisters.Api.Search.Sorting; using Be.Vlaanderen.Basisregisters.GrAr.Common; using Microsoft.EntityFrameworkCore; + using Nuts; using Projections.Legacy; using Projections.Legacy.PostalInformation; using Projections.Syndication; @@ -15,13 +16,18 @@ public class PostalInformationListOsloQuery : Query new PostalInformationSorting(); - public PostalInformationListOsloQuery(LegacyContext context, SyndicationContext syndicationContext) + public PostalInformationListOsloQuery( + LegacyContext context, + SyndicationContext syndicationContext, + Nuts3Service nuts3Service) { _context = context; _syndicationContext = syndicationContext; + _nuts3Service = nuts3Service; } protected override IQueryable Filter(FilteringHeader filtering) @@ -58,6 +64,18 @@ protected override IQueryable Filter(FilteringHeader x.PostalNames.Any(y => y.SearchName == filterPostalName)); } + if (!string.IsNullOrEmpty(filtering.Filter.Nuts3Code)) + { + var nuts3Records = _nuts3Service.GetPostalCodesByNuts3(filtering.Filter.Nuts3Code) + .Select(x => x.PostalCode) + .ToList(); + + if(!nuts3Records.Any()) + return Enumerable.Empty().AsQueryable(); + + postalInformationSet = postalInformationSet.Where(x => nuts3Records.Any(y => y == x.PostalCode)); + } + return postalInformationSet; } } @@ -78,5 +96,7 @@ public class PostalInformationFilter public string MunicipalityName { get; set; } public string PostalName { get; set; } + + public string Nuts3Code { get; set; } } } diff --git a/src/PostalRegistry.Api.Oslo/PostalInformation/Responses/PostalInformationOsloResponse.cs b/src/PostalRegistry.Api.Oslo/PostalInformation/Responses/PostalInformationOsloResponse.cs index 7ea424d6..9a90e98c 100644 --- a/src/PostalRegistry.Api.Oslo/PostalInformation/Responses/PostalInformationOsloResponse.cs +++ b/src/PostalRegistry.Api.Oslo/PostalInformation/Responses/PostalInformationOsloResponse.cs @@ -60,19 +60,28 @@ public class PostalInformationOsloResponse [JsonProperty(Required = Required.DisallowNull)] public PostInfoStatus PostInfoStatus { get; set; } + /// + /// De NUTS3 code van de postcode. + /// + [DataMember(Name = "Nuts3", Order = 5)] + [JsonProperty(Required = Required.Default)] + public string? Nuts3Code { get; set; } + public PostalInformationOsloResponse( string naamruimte, string contextUrlDetail, string postcode, PostinfoDetailGemeente? gemeente, DateTimeOffset version, - PostInfoStatus postInfoStatus) + PostInfoStatus postInfoStatus, + string? nuts3Code) { Context = contextUrlDetail; Identificator = new PostinfoIdentificator(naamruimte, postcode, version); Gemeente = gemeente; PostInfoStatus = postInfoStatus; Postnamen = new List(); + Nuts3Code = nuts3Code; } } @@ -97,7 +106,8 @@ public PostalInformationOsloResponse GetExamples() "8200", gemeente, DateTimeOffset.Now.ToExampleOffset(), - PostInfoStatus.Gerealiseerd) + PostInfoStatus.Gerealiseerd, + "BE251") { Postnamen = new List { diff --git a/src/PostalRegistry.Api.Oslo/PostalRegistry.Api.Oslo.csproj b/src/PostalRegistry.Api.Oslo/PostalRegistry.Api.Oslo.csproj index 32b13a19..c38e8e48 100644 --- a/src/PostalRegistry.Api.Oslo/PostalRegistry.Api.Oslo.csproj +++ b/src/PostalRegistry.Api.Oslo/PostalRegistry.Api.Oslo.csproj @@ -28,6 +28,7 @@ + diff --git a/src/PostalRegistry.Api.Oslo/paket.references b/src/PostalRegistry.Api.Oslo/paket.references index 87329282..4cb64122 100644 --- a/src/PostalRegistry.Api.Oslo/paket.references +++ b/src/PostalRegistry.Api.Oslo/paket.references @@ -5,5 +5,7 @@ Be.Vlaanderen.Basisregisters.DataDog.Tracing.Autofac AspNetCore.HealthChecks.SqlServer +CsvHelper + SourceLink.Embed.AllSourceFiles SourceLink.Copy.PdbFiles