using Microsoft.Azure.CosmosDB.Table; using Microsoft.Azure.Storage; using Microsoft.VisualBasic.FileIO; using System; using System.Collections.Generic; using System.Configuration; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using taloyhtio.idp.parser.common.model; namespace taloyhtio.idp.parser.fivaldi { class Program { private static readonly Regex numeric = new Regex("^\\d+$", RegexOptions.Compiled); private static readonly Regex numcode = new Regex("^\\d{2,3}$", RegexOptions.Compiled); private const string MARKER = "Sidos"; private static CloudTableClient tableClient; private static string condoName; private static Guid pmcId; private static Dictionary flats; private static string period = "201911"; private static List items; private static void InitClient() { var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings[Constants.KEY_AZURE_STORAGE].ConnectionString); tableClient = storageAccount.CreateCloudTableClient( new TableConnectionPolicy() { UseDirectMode = false }); } private static List GetCondo(string condoName) { var table = tableClient.GetTableReference("mdbCondoMappings"); table.CreateIfNotExists(); var allCondos = table.CreateQuery().ToList(); if (condoName != null) { return allCondos.Where(x => condoName.Contains(x.PMSCondoName)).ToList(); } return allCondos; } private static List GetFlats(Guid taloyhtioPMCId, string pmsCondoName) { if (Guid.Empty.Equals(taloyhtioPMCId) || string.IsNullOrEmpty(pmsCondoName)) { return null; } var table = tableClient.GetTableReference("mdbFlats"); table.CreateIfNotExists(); var query = table.CreateQuery() .Where(d => d.PMCTaloyhtioId == taloyhtioPMCId && d.CondoPMS == pmsCondoName) .ToArray() .OrderBy(o => o.FlatTitle); return query.ToList(); } private static void SaveFees(Record record) { var table = tableClient.GetTableReference("mdbMaintenanceFees"); table.CreateIfNotExists(); record.Payments.ForEach(p => { var fee = new MaintenanceFee(Guid.NewGuid()) { Payer = record.Payer, FlatTitle = record.Apartment, FlatId = flats[record.Apartment], PaymentCode = p.Code, PaymentType = p.Name, PMSCondoName = condoName, PMCTaloyhtioId = pmcId, PeriodOfTime = "201911", Fee = Convert.ToDouble(p.Amount), PartitionKey = record.Payer, }; var result = table.Execute(TableOperation.InsertOrReplace(fee)); Console.WriteLine(result.HttpStatusCode); }); } private static string CalcMD5(Record data) { var md5 = MD5.Create(); var bytes = Encoding.ASCII.GetBytes(data.Payer + flats[data.Apartment].ToString() + period); var hash = md5.ComputeHash(bytes); var sb = new StringBuilder(); for (int i = 0; i < hash.Length; i++) { sb.Append(hash[i].ToString("X2")); } return sb.ToString(); } static void Main(string[] args) { InitClient(); condoName = "hiihtomaentie16"; pmcId = GetCondo(condoName)[0].TaloyhtioPMCId; flats = GetFlats(pmcId, condoName).ToDictionary(x => x.FlatTitle, x => x.Id); var records = new List>(); items = new List(); var paymentTypes = new Dictionary(); string dataUrl = Directory.GetCurrentDirectory() + "\\" + args[0]; using (TextReader reader = new StreamReader(dataUrl, Encoding.GetEncoding(1252))) using (TextFieldParser parser = new TextFieldParser(reader)) { parser.Delimiters = new string[] { ";" }; while (true) { var parts = parser.ReadFields(); if (parts == null) { break; } records.Add(new List(parts)); } } int flatCount = 0; var distinct = new HashSet(); for (int row = 0; row < records.Count; row++) { var line = records[row]; for (int column = 0; column < line.Count - 4; column++) { if (line[column].Equals(MARKER) && MatchRecordStart(line, column) && !FindAhead(line, column)) { if (!distinct.Add(line[column + 3])) { continue; } distinct.Add(line[column + 3]); flatCount++; var payments = CollectPayments(records, row, column + 5); payments.ForEach(x => paymentTypes[x.Code] = x.Name); var record = new Record { Apartment = line[column + 1].Replace(' ', (char)160), Building = line[column + 2], Binding = line[column + 3], Payer = line[column + 4], Payments = payments, Total = 0.0, }; items.Add(record); Console.WriteLine($"{record.Apartment} / {record.Building} / {record.Binding} / {record.Payer}"); foreach (var payment in record.Payments) { Console.WriteLine($"\t{payment.Code} {payment.Name}: {payment.Amount}"); } } } } items.Where(i => flats.ContainsKey(i.Apartment)).ToList().ForEach(i => SaveFees(i)); Console.WriteLine(); Console.WriteLine($"lines count: {flatCount}"); Console.WriteLine($"distinct count: {distinct.Count}"); Console.ReadLine(); } private static bool MatchRecordStart(List line, int column) { return numeric.IsMatch(line[column + 3]) && !numeric.IsMatch(line[column + 1]) && !numeric.IsMatch(line[column + 4]); } private static bool FindAhead(List line, int startColumn) { if (line.Count < startColumn + 5) { return false; } for (int column = startColumn + 5; column < line.Count; column++) { if (line[column].Equals(MARKER) && MatchRecordStart(line, column)) { return true; } } return false; } private static bool MatchPayment(List line, int column) { return numcode.IsMatch(line[column + 1]) && !numcode.IsMatch(line[column + 2]); } private static List CollectPayments(List> data, int rowStart, int columnStart) { var result = new List(); var first = true; var shouldExit = false; for (int row = rowStart; row < data.Count; row++) { var line = data[row]; for (int column = first ? columnStart : 0; column < line.Count; column++) { if (line[column].Equals(MARKER)) { if (MatchPayment(line, column)) { var payment = new Payment { Code = line[column + 1], Name = line[column + 2], Amount = line[column + 3] }; result.Add(payment); } else { shouldExit = true; break; } } } first = false; if (shouldExit) { break; } } return result; } } }