Taylohtio/IDP/parsers/parser-management-fee/fivaldi/Program.cs

254 lines
8.9 KiB
C#

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<string, Guid> flats;
private static string period = "201911";
private static List<Record> 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<CondoMapping> GetCondo(string condoName)
{
var table = tableClient.GetTableReference("mdbCondoMappings");
table.CreateIfNotExists();
var allCondos = table.CreateQuery<CondoMapping>().ToList();
if (condoName != null)
{
return allCondos.Where(x => condoName.Contains(x.PMSCondoName)).ToList();
}
return allCondos;
}
private static List<Flat> 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<Flat>()
.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<List<string>>();
items = new List<Record>();
var paymentTypes = new Dictionary<string, string>();
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<string>(parts));
}
}
int flatCount = 0;
var distinct = new HashSet<string>();
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<string> line, int column)
{
return numeric.IsMatch(line[column + 3]) && !numeric.IsMatch(line[column + 1]) && !numeric.IsMatch(line[column + 4]);
}
private static bool FindAhead(List<string> 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<string> line, int column)
{
return numcode.IsMatch(line[column + 1]) && !numcode.IsMatch(line[column + 2]);
}
private static List<Payment> CollectPayments(List<List<string>> data, int rowStart, int columnStart)
{
var result = new List<Payment>();
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;
}
}
}