diff --git a/JSONParser.sln b/JSONParser.sln new file mode 100644 index 0000000..e23e4c2 --- /dev/null +++ b/JSONParser.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34728.123 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JSONParser", "JSONParser\JSONParser.csproj", "{DF1EDBD8-CD2B-4996-B4BE-CB03789C9093}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DF1EDBD8-CD2B-4996-B4BE-CB03789C9093}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DF1EDBD8-CD2B-4996-B4BE-CB03789C9093}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DF1EDBD8-CD2B-4996-B4BE-CB03789C9093}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DF1EDBD8-CD2B-4996-B4BE-CB03789C9093}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E2AB0450-9608-4D7E-98D6-88571CCC66AA} + EndGlobalSection +EndGlobal diff --git a/JSONParser/JSONParser.csproj b/JSONParser/JSONParser.csproj new file mode 100644 index 0000000..e57b292 --- /dev/null +++ b/JSONParser/JSONParser.csproj @@ -0,0 +1,19 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + + diff --git a/JSONParser/JSONStructure.cs b/JSONParser/JSONStructure.cs new file mode 100644 index 0000000..d6a37a7 --- /dev/null +++ b/JSONParser/JSONStructure.cs @@ -0,0 +1,222 @@ +using JSONParser.Structure; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static System.Runtime.InteropServices.JavaScript.JSType; + +namespace JSONParser +{ + public class JSONStructure + { + //private JArray _array; + private List _orgs; + private List _depts; + private List _jobs; + private List _emps; + + public List BusinessUnits { get; set; } + public List Departments { get; set; } + public List JobTitles { get; set; } + public List Employees { get; set; } + public List Persons { get; set; } + public List Logins { get; set; } + + public List NotFoundDepartments { get; set; } = new List(); + public List NotFoundEmployees { get; set; } = new List(); + + public JSONStructure(JArray array) + { + //var filePath = @"C:\Users\anboevdd\Desktop\ОШС_2024-10-30.json"; + //var json = File.ReadAllText(filePath); + //var array = JArray.Parse(json); + Persons = array.Where(x => (string)x["Type"] == "ФизическиеЛица").Select(x => new Person + { + Type = (string)x["Type"], + Sid = (string)x["Sid"], + FirstName = (string)x["FirstName"], + LastName = (string)x["LastName"], + MiddleName = (string)x["MiddleName"] + }).ToList(); + Logins = array.Where(x => (string)x["Type"] == "УчетныеЗаписи").Select(x => new Login + { + Type = (string)x["Type"], + Sid = (string)x["Sid"], + LoginName = (string)x["LoginName"] == null ? null : $"POLY\\{(string)x["LoginName"]}", + TypeAuthentication = (string)x["TypeAuthentication"], + Status = (bool)x["Status"] + }).ToList(); + _orgs = array.Where(x => (string)x["Type"] == "Организации").ToList(); + _depts = array.Where(x => (string)x["Type"] == "ПодразделенияОрганизаций").ToList(); + _jobs = array.Where(x => (string)x["Type"] == "Должности").ToList(); + _emps = array.Where(x => (string)x["Type"] == "Сотрудники").ToList(); + + BusinessUnits = GetBusinessUnits(); + Departments = GetDepartments(); + JobTitles = GetJobTitles(); + Employees = GetEmployees(); + BusinessUnits.ForEach(x => x.NCEO = CreateEmployee(x.NCEO.Sid)); + BusinessUnits.ForEach(x => x.Account = CreateEmployee(x.Account.Sid)); + } + + private List GetEmployees() + { + var result = new List(); + foreach (var item in _emps) + { + result.Add(CreateEmployee((string)item["Sid"])); + } + return result; + } + + private List GetJobTitles() + { + var result = new List(); + foreach (var item in _jobs) + { + result.Add(CreateJobTitle((string)item["Sid"])); + } + return result; + } + + private List GetDepartments() + { + var result = new List(); + foreach (var item in _depts) + { + result.Add(CreateDepartment((string)item["Sid"])); + } + return result; + } + + private Department CreateDepartment(string sid) + { + if (Guid.Parse(sid) == Guid.Empty) return null; + var department = new Department(); + var dept = _depts.FirstOrDefault(x => (string)x["Sid"] == sid); + if (dept != null) + { + department.Type = (string)dept["Type"]; + department.Sid = (string)dept["Sid"]; + department.Name = (string)dept["Name"]; + department.ShortName = (string)dept["ShortName"]; + //department.BusinessUnit = BusinessUnits.FirstOrDefault(x => x.Sid == (string)dept["BusinessUnit"]); + department.BusinessUnit = CreateBusinessUnit((string)dept["BusinessUnit"]); + if (string.IsNullOrEmpty((string)dept["HeadOffice"])) + { + department.HeadOffice = null; + } + else + { + department.HeadOffice = CreateDepartment((string)dept["HeadOffice"]); + } + department.Status = (string)dept["Status"]; + } + else + { + department.Sid = sid; + NotFoundDepartments.Add(sid); + //Console.WriteLine($"Department {sid}"); + } + return department; + } + + private List GetBusinessUnits() + { + var result = new List(); + foreach (var item in _orgs) + { + result.Add(CreateBusinessUnit((string)item["Sid"])); + } + return result; + } + + private BusinessUnit CreateBusinessUnit(string sid) + { + var org = _orgs.FirstOrDefault(x => (string)x["Sid"] == sid); + var bu = new BusinessUnit(); + if (org != null) + { + bu.Type = (string)org["Type"]; + bu.Sid = (string)org["Sid"]; + bu.Name = (string)org["Name"]; + bu.LegalName = (string)org["LegalName"]; + bu.NCEO = new Employee { Sid = (string)org["NCEO"] }; + bu.Account = new Employee { Sid = (string)org["Account"] }; + if ((string)org["Sid"] == (string)org["HeadCompany"] || Guid.Parse((string)org["Sid"]) == Guid.Empty) + { + bu.HeadCompany = null; + } + else + { + bu.HeadCompany = CreateBusinessUnit((string)org["HeadCompany"]); + } + bu.BINArmadoc = (string)org["BINArmadoc"]; + bu.LegalAddress = (string)org["LegalAddress"]; + bu.PostalAddress = (string)org["PostalAddress"]; + bu.Phones = (string)org["Phones"]; + } + else + { + bu.Sid = sid; + //Console.WriteLine($"BusinessUnit - {sid}"); + } + return bu; + } + + private Employee CreateEmployee(string? sid) + { + if (Guid.Parse(sid) == Guid.Empty) return null; + var employee = new Employee(); + var emp = _emps.FirstOrDefault(x => (string)x["Sid"] == sid); + if (emp != null) + { + employee.Type = (string)emp["Type"]; + employee.Sid = (string)emp["Sid"]; + employee.Person = Persons.FirstOrDefault(x => x.Sid == (string)emp["Person"]); + employee.Login = Logins.FirstOrDefault(x => x.Sid == (string)emp["Login"]); + employee.Email = (string)emp["Email"]; + employee.Status = (bool)emp["Status"]; + //employee.Department = Departments.FirstOrDefault(x => x.Sid == (string)emp["Department"]); + employee.Department = CreateDepartment((string)emp["Department"]); + employee.JobTitleName = (string)emp["JobTitleName"]; + employee.JobTitle = new JobTitle + { + Type = "Должности", + Sid = Guid.NewGuid().ToString(), + Name = employee.JobTitleName, + Department = employee.Department + }; + //employee.JobTitle = CreateJobTitle((string)emp["JobTitle"]); + } + else + { + employee.Sid = sid; + NotFoundEmployees.Add(sid); + //Console.WriteLine($"Employee - {sid}"); + } + return employee; + } + + private JobTitle CreateJobTitle(string sid) + { + var jt = _jobs.FirstOrDefault(x => (string)x["Sid"] == sid); + var jobTitle = new JobTitle(); + if (jt != null) + { + jobTitle.Type = (string)jt["Type"]; + jobTitle.Sid = (string)jt["Sid"]; + jobTitle.Name = (string)jt["Name"]; + jobTitle.Department = CreateDepartment((string)jt["Department"]); + } + else + { + jobTitle.Sid = sid; + //Console.WriteLine($"JobTitle - {sid}"); + } + return jobTitle; + } + } +} diff --git a/JSONParser/Logger/CustomFileLogger.cs b/JSONParser/Logger/CustomFileLogger.cs new file mode 100644 index 0000000..3774260 --- /dev/null +++ b/JSONParser/Logger/CustomFileLogger.cs @@ -0,0 +1,50 @@ +using Microsoft.Extensions.Logging; + +namespace JSONParser.Logger +{ + // Customized ILogger, writes logs to text files + public class CustomFileLogger : ILogger + { + private readonly string _categoryName; + private readonly StreamWriter _logFileWriter; + + public CustomFileLogger(string categoryName, StreamWriter logFileWriter) + { + _categoryName = categoryName; + _logFileWriter = logFileWriter; + } + + public IDisposable BeginScope(TState state) + { + return null; + } + + public bool IsEnabled(LogLevel logLevel) + { + // Ensure that only information level and higher logs are recorded + return logLevel >= LogLevel.Information; + } + + public void Log( + LogLevel logLevel, + EventId eventId, + TState state, + Exception exception, + Func formatter) + { + // Ensure that only information level and higher logs are recorded + if (!IsEnabled(logLevel)) + { + return; + } + + // Get the formatted log message + var message = formatter(state, exception); + + //Write log messages to text file + //_logFileWriter.WriteLine($"[{logLevel}] [{_categoryName}] {message}"); + _logFileWriter.WriteLine($"[{logLevel}] {message}"); + _logFileWriter.Flush(); + } + } +} diff --git a/JSONParser/Logger/CustomFileLoggerProvider.cs b/JSONParser/Logger/CustomFileLoggerProvider.cs new file mode 100644 index 0000000..0e2ad62 --- /dev/null +++ b/JSONParser/Logger/CustomFileLoggerProvider.cs @@ -0,0 +1,30 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JSONParser.Logger +{ + // Customized ILoggerProvider, writes logs to text files + public class CustomFileLoggerProvider : ILoggerProvider + { + private readonly StreamWriter _logFileWriter; + + public CustomFileLoggerProvider(StreamWriter logFileWriter) + { + _logFileWriter = logFileWriter ?? throw new ArgumentNullException(nameof(logFileWriter)); + } + + public ILogger CreateLogger(string categoryName) + { + return new CustomFileLogger(categoryName, _logFileWriter); + } + + public void Dispose() + { + _logFileWriter.Dispose(); + } + } +} diff --git a/JSONParser/Program.cs b/JSONParser/Program.cs new file mode 100644 index 0000000..a8c0fb2 --- /dev/null +++ b/JSONParser/Program.cs @@ -0,0 +1,132 @@ +// See https://aka.ms/new-console-template for more information +using JSONParser; +using JSONParser.Logger; +using JSONParser.QDocWrapper; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json.Linq; +using System.ComponentModel.DataAnnotations; +using System.Net.Http.Headers; +using System.Text; + +Console.OutputEncoding = Encoding.UTF8; + +var odata = new ODataAccess(); +var odataClient = odata.Client; + +//var cnt = await odataClient +// .For("IEmployees") +// .Expand("Department/BusinessUnit") +// .Filter("Department/BusinessUnit/Name eq 'Бакырчикское горнодобывающее предприятие ТОО' and Status eq 'Active'") +// .FindEntriesAsync(); + +//var responsePath = @"C:\ОШС_logs\2024_11_20\response.json"; +//var resp = File.ReadAllText(responsePath); +//var arr = JArray.Parse(resp); + +var logFolderPath = $@"C:\ОШС_logs\{DateTime.Now:yyyy_MM_dd}"; + +Directory.CreateDirectory(logFolderPath); + +using (StreamWriter logFileWriter = new($@"{logFolderPath}\{DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss")}_log.log", append: true)) +{ + ILoggerFactory loggerFactory = LoggerFactory.Create(builder => + { + builder.AddSimpleConsole(options => + { + options.IncludeScopes = true; + options.SingleLine = true; + options.TimestampFormat = "HH:mm:ss"; + }); + builder.AddProvider(new CustomFileLoggerProvider(logFileWriter)); + }); + ILogger logger = loggerFactory.CreateLogger("ОШС"); + var wrapper = new QDocWrapper(odataClient, logger); + + Console.WriteLine("Получение данных из сервиса 1С"); + var jarray = await GetArrayFromService(); + //var jarray = arr; + File.WriteAllText($@"{logFolderPath}\{DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss")}_response.json", jarray.ToString()); + Console.WriteLine("Данные получены"); + Console.WriteLine("Парсинг..."); + var structure = new JSONStructure(jarray); + Console.WriteLine("Данные структурированы. Создание записей в QDoc."); + + foreach (var businessUnit in structure.BusinessUnits) + { + var id = await wrapper.CreateBusinessUnit(businessUnit); + } + + foreach (var department in structure.Departments) + { + var id = await wrapper.CreateDepartment(department); + } + + foreach (var jobTitle in structure.JobTitles) + { + var id = await wrapper.CreateJobTitle(jobTitle); + } + + + foreach (var employee in structure.Employees) + { + try + { + var id = await wrapper.CreateEmployee(employee); + } + catch (Exception) + { + logger.LogError($"{employee.Type} - {employee.Sid} - Failed to create"); + } + } + + foreach (var businessUnit in structure.BusinessUnits) + { + var ceoId = await businessUnit.CreateNCEO(odataClient); + if (ceoId > 0) + { + logger.LogInformation($"{businessUnit.Type} - {businessUnit.Sid} - CEO_Created"); + } + else + { + logger.LogWarning($"{businessUnit.Type} - {businessUnit.Sid} - CEO_Skip"); + if (businessUnit.NCEO != null && businessUnit.NCEO.Sid != null) + { + logger.LogWarning($"Сотрудники - {businessUnit.NCEO.Sid} - Skipped_CEO_Sid"); + } + } + var accountId = await businessUnit.CreateAccount(odataClient); + if (accountId > 0) + { + logger.LogInformation($"{businessUnit.Type} - {businessUnit.Sid} - Account_Created"); + } + else + { + logger.LogWarning($"{businessUnit.Type} - {businessUnit.Sid} - Account_Skip"); + if (businessUnit.Account != null && businessUnit.Account.Sid != null) + { + logger.LogWarning($"Сотрудники - {businessUnit.Account.Sid} - Skipped_Account_Sid"); + } + } + } +} + +//var serialized = JsonConvert.SerializeObject(notValid); +Console.ReadLine(); + +static async Task GetArrayFromService() +{ + JArray array = []; + using (var client = new HttpClient()) + { + var byteArray = Encoding.ASCII.GetBytes("QDoc:Xe3xihuz"); + client.Timeout = new TimeSpan(0, 10, 0); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray)); + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + + HttpResponseMessage response = await client.GetAsync("http://ast1c/HRMkz31/hs/qdoc/staff"); + await client.DeleteAsync("http://ast1c/HRMkz31/hs/qdoc/staff"); + string responseBody = await response.Content.ReadAsStringAsync(); + array = JArray.Parse(responseBody); + } + return array; +} \ No newline at end of file diff --git a/JSONParser/QDocWrapper/ODataAccess.cs b/JSONParser/QDocWrapper/ODataAccess.cs new file mode 100644 index 0000000..bb7b70a --- /dev/null +++ b/JSONParser/QDocWrapper/ODataAccess.cs @@ -0,0 +1,48 @@ +using Simple.OData.Client; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JSONParser.QDocWrapper +{ + public class ODataAccess + { + // URL сервиса интеграции. +#if DEBUG + //private const string IntegrationServiceUrl = "http://astsrvdds.polymetal.ru/Integration/odata/"; + //private const string Login = "Administrator"; + //private const string Password = "11111"; + + //private const string IntegrationServiceUrl = "https://astsrvqtest.solidcore-resources.com/Integration/odata/"; + //private const string Login = "Administrator"; + //private const string Password = "D3cTXol8Se"; + + private const string IntegrationServiceUrl = "https://qdoc.solidcore-resources.com/Integration/odata/"; + private const string Login = "Administrator"; + private const string Password = "MQVuEw9avO"; +#endif + +#if RELEASE + private const string IntegrationServiceUrl = "https://qdoc.polymetal.ru/Integration/odata/"; + private const string Login = "Administrator"; + private const string Password = "MQVuEw9avO"; +#endif + + public ODataAccess() + { + // Настройки Simple OData Client: добавление ко всем запросам URL сервиса и + // заголовка с данными аутентификации. + var odataClientSettings = new ODataClientSettings(new Uri(IntegrationServiceUrl)); + odataClientSettings.BeforeRequest += (HttpRequestMessage message) => + { + var authenticationHeaderValue = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{Login}:{Password}")); + message.Headers.Add("Authorization", "Basic " + authenticationHeaderValue); + }; + Client = new ODataClient(odataClientSettings); + } + + public ODataClient? Client { get; set; } + } +} diff --git a/JSONParser/QDocWrapper/QDocWrapper.cs b/JSONParser/QDocWrapper/QDocWrapper.cs new file mode 100644 index 0000000..3780995 --- /dev/null +++ b/JSONParser/QDocWrapper/QDocWrapper.cs @@ -0,0 +1,355 @@ +using JSONParser.Structure; +using Microsoft.Extensions.Logging; +using Simple.OData.Client; +using System; +using System.Collections.Generic; +using System.ComponentModel.Design.Serialization; +using System.Linq; +using System.Resources; +using System.Text; +using System.Threading.Tasks; + +namespace JSONParser.QDocWrapper +{ + public class QDocWrapper + { + ODataClient _client; + ILogger _logger; + public QDocWrapper(ODataClient client, ILogger logger) + { + _client = client; + _logger = logger; + } + + public async Task CreateEmployee(Employee employee) + { + if (employee == null) return 0; + + var emp = await _client + .For("IEmployee") + .Expand("Department") + .Expand("Person") + .Expand("JobTitle") + .Expand("Login") + .Filter($"ExternalId eq '{employee.Sid}' and Status eq 'Active'") + //.Filter($"ExternalId eq '{employee.Sid}'") + .FindEntryAsync(); + + if ((employee.Person == null || employee.Department == null) || employee.Status == false && emp == null) + { + _logger.LogWarning($"{employee.Type} - {employee.Sid} - Skip"); + return 0; + } + + long result = 0; + + if (employee.Department != null) + { + var id = await employee.Department.GetIdBySid(_client); + employee.Department.DirectumId = id; + } + else + { + dynamic empDept = emp["Department"]; + employee.Department = new Department + { + Sid = (string)empDept["ExternalId"], + DirectumId = (long)empDept["Id"], + Name = (string)empDept["Name"], + ShortName = (string)empDept["ShortName"] + }; + employee.JobTitle.Department = employee.Department; + } + + if (employee.Person != null) + { + var id = await employee.Person.GetIdBySid(_client); + if (id == 0) + { + id = await employee.Person.Create(_client); + } + employee.Person.DirectumId = id; + } + else + { + dynamic empPerson = emp["Person"]; + employee.Person = new Person { DirectumId = (long)empPerson["Id"] }; + } + + if (employee.JobTitle != null) + { + var id = await employee.JobTitle.GetIdBySid(_client); + employee.JobTitle.DirectumId = id; + } + else + { + dynamic empJobTitle = emp["JobTitle"]; + employee.JobTitle = new JobTitle { DirectumId = (long)empJobTitle["Id"] }; + } + + if (employee.Login != null) + { + var id = await employee.Login.GetIdBySid(_client); + if (id == 0) + { + id = await employee.Login.Create(_client); + } + employee.Login.DirectumId = id; + } + else if (emp != null) + { + dynamic empLogin = emp["Login"]; + if (empLogin != null) + { + employee.Login = new Login { DirectumId = (long)empLogin["Id"] }; + } + } + + if (employee.Person.DirectumId == 0 || employee.Department.DirectumId == 0 || employee.JobTitle.DirectumId == 0) + { + _logger.LogInformation($"{employee.Type} - {employee.Sid} - Not Valid"); + return result; + } + + var empByLogin = await employee.FindByLogin(_client); + if (emp != null && employee.IsEqual(emp)) + { + result = (long)emp["Id"]; + employee.DirectumId = result; + _logger.LogInformation($"{employee.Type} - {employee.Sid} - Unchanged"); + } + else if (emp != null && empByLogin == 0) + { + result = (long)emp["Id"]; + await employee.Update(_client, result); + employee.DirectumId = result; + _logger.LogInformation($"{employee.Type} - {employee.Sid} - Updated"); + } + else if (emp != null && empByLogin > 0) + { + result = (long)emp["Id"]; + if (result != empByLogin) + { + await employee.CloseRecord(_client, empByLogin); + _logger.LogInformation($"{employee.Type} - {employee.Sid} - Closed"); + } + await employee.Update(_client, result); + employee.DirectumId = result; + _logger.LogInformation($"{employee.Type} - {employee.Sid} - Updated"); + } + else if (emp == null && empByLogin > 0) + { + await employee.CloseRecord(_client, empByLogin); + _logger.LogInformation($"{employee.Type} - {employee.Sid} - Closed"); + if (employee.Person != null && employee.Department != null) + { + result = await employee.Create(_client); + _logger.LogInformation($"{employee.Type} - {employee.Sid} - Created"); + } + } + else + { + if (employee.Person != null && employee.Department != null) + { + result = await employee.Create(_client); + _logger.LogInformation($"{employee.Type} - {employee.Sid} - Created"); + } + } + return result; + } + + public async Task CreateDepartment(Department department) + { + if (department == null || department.Status == "Closed" || string.IsNullOrEmpty(department.Name)) return 0; + if (department.HeadOffice != null && department.HeadOffice.DirectumId == null) + { + var id = await department.HeadOffice.GetIdBySid(_client); + if (id > 0) + { + department.HeadOffice.DirectumId = id; + } + } + if (department.BusinessUnit != null && department.BusinessUnit.DirectumId == null) + { + var id = await department.BusinessUnit.GetIdBySid(_client); + if (id > 0) + { + department.BusinessUnit.DirectumId = id; + } + } + var dept = await _client + .For("IDepartment") + .Expand("BusinessUnit") + .Expand("HeadOffice") + .Filter($"ExternalId eq '{department.Sid}'") + .FindEntryAsync(); + long result = 0; + + if (department.BusinessUnit.DirectumId == 0) + { + _logger.LogInformation($"{department.Type} - {department.Sid} - Not Valid"); + return result; + } + + if (dept != null && department.IsEqual(dept)) + { + result = (long)dept["Id"]; + department.DirectumId = result; + _logger.LogInformation($"{department.Type} - {department.Sid} - Unchanged"); + } + else if (dept != null) + { + result = (long)dept["Id"]; + await department.Update(_client, result); + department.DirectumId = result; + _logger.LogInformation($"{department.Type} - {department.Sid} - Updated"); + } + else + { + result = await department.Create(_client); + _logger.LogInformation($"{department.Type} - {department.Sid} - Created"); + } + return result; + } + + public async Task CreateJobTitle(JobTitle jobTitle) + { + if (jobTitle == null) return 0; + long result = 0; + var job = await _client + .For("IJobTitles") + .Expand("Department") + .Filter($"Name eq '{jobTitle.Name}' and Department/ExternalId eq '{jobTitle.Department.Sid}'") + .FindEntryAsync(); + + if (jobTitle.Department != null) + { + await jobTitle.Department.GetIdBySid(_client); + } + + if (job != null && jobTitle.IsEqual(job)) + { + result = (long)job["Id"]; + jobTitle.DirectumId = result; + dynamic dept = job["Department"]; + jobTitle.Department.DirectumId = (long)dept["Id"]; + _logger.LogInformation($"{jobTitle.Type} - {jobTitle.Sid} - Unchanged"); + } + else if (job != null) + { + result = (long)job["Id"]; + await jobTitle.Update(_client, result); + jobTitle.DirectumId = result; + dynamic dept = job["Department"]; + jobTitle.Department.DirectumId = (long)dept["Id"]; + _logger.LogInformation($"{jobTitle.Type} - {jobTitle.Sid} - Updated"); + } + else + { + if (jobTitle.Department != null) + { + result = await jobTitle.Create(_client); + _logger.LogInformation($"{jobTitle.Type} - {jobTitle.Sid} - Created"); + } + } + return result; + } + + public async Task CreatePerson(Person person) + { + if (person == null) return 0; + var per = await _client + .For("IPersons") + .Filter($"ExternalId eq '{person.Sid}'") + .FindEntryAsync(); + long result; + if (per != null && person.IsEqual(per)) + { + result = (long)per["Id"]; + person.DirectumId = result; + _logger.LogInformation($"{person.Type} - {person.Sid} - Unchanged"); + } + else if (per != null) + { + result = (long)per["Id"]; + await person.Update(_client, result); + person.DirectumId = result; + _logger.LogInformation($"{person.Type} - {person.Sid} - Updated"); + } + else + { + result = await person.Create(_client); + _logger.LogInformation($"{person.Type} - {person.Sid} - Created"); + } + return result; + } + + public async Task CreateBusinessUnit(BusinessUnit businessUnit) + { + if (businessUnit == null) return 0; + if (businessUnit.HeadCompany != null && businessUnit.HeadCompany.DirectumId == null) + { + var id = await businessUnit.HeadCompany.GetIdBySid(_client); + if (id > 0) + { + businessUnit.HeadCompany.DirectumId = id; + } + } + long result = 0; + var bu = await _client + .For("IBusinessUnits") + .Expand("HeadCompany") + .Filter($"ExternalId eq '{businessUnit.Sid}'") + .FindEntryAsync(); + + if (bu != null && businessUnit.IsEqual(bu)) + { + result = (long)bu["Id"]; + businessUnit.DirectumId = result; + _logger.LogInformation($"{businessUnit.Type} - {businessUnit.Sid} - Unchanged"); + } + else if (bu != null) + { + result = (long)bu["Id"]; + await businessUnit.Update(_client, result); + businessUnit.DirectumId = result; + _logger.LogInformation($"{businessUnit.Type} - {businessUnit.Sid} - Updated"); + } + else + { + result = await businessUnit.Create(_client); + _logger.LogInformation($"{businessUnit.Type} - {businessUnit.Sid} - Created"); + } + return result; + } + + public async Task CreateLogin(Login login) + { + if (login == null) return 0; + long result = 0; + var log = await _client + .For("ILogins") + .Filter($"LoginName eq '{login.LoginName}'") + .FindEntryAsync(); + if (log != null && login.IsEqual(log)) + { + result = (long)log["Id"]; + login.DirectumId = result; + _logger.LogInformation($"{login.Type} - {login.Sid} - Unchanged"); + } + else if (log != null) + { + result = (long)log["Id"]; + await login.Update(_client, result); + login.DirectumId = result; + _logger.LogInformation($"{login.Type} - {login.Sid} - Updated"); + } + else + { + result = await login.Create(_client); + _logger.LogInformation($"{login.Type} - {login.Sid} - Created"); + } + return result; + } + } +} \ No newline at end of file diff --git a/JSONParser/Structure/BusinessUnit.cs b/JSONParser/Structure/BusinessUnit.cs new file mode 100644 index 0000000..3561349 --- /dev/null +++ b/JSONParser/Structure/BusinessUnit.cs @@ -0,0 +1,180 @@ +using Simple.OData.Client; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JSONParser.Structure +{ + public class BusinessUnit : Entity + { + public string Name { get; set; } + public string LegalName { get; set; } + public Employee NCEO { get; set; } + public Employee Account { get; set; } + public BusinessUnit HeadCompany { get; set; } + public string BINArmadoc { get; set; } + public string LegalAddress { get; set; } + public string PostalAddress { get; set; } + public string Phones { get; set; } + + public override string ToString() + { + return Name; + } + + public async override Task Create(ODataClient client) + { + var newBusinessUnit = new + { + ExternalId = Sid, + Name = Name, + LegalName = LegalName, + LegalAddress = LegalAddress, + PostalAddress = PostalAddress, + HeadCompany = new { Id = HeadCompany == null ? 0 : this.HeadCompany.DirectumId }, + BINArmadoc = BINArmadoc, + Status = "Active" + }; + var created = await client + .For("IBusinessUnits") + .Set(newBusinessUnit) + .InsertEntryAsync(); + this.DirectumId = (long)created["Id"]; + return (long)created["Id"]; + } + + public async override Task Update(ODataClient client, long id) + { + var newBusinessUnit = new + { + ExternalId = Sid, + Name = Name, + LegalName = LegalName, + LegalAddress = LegalAddress, + PostalAddress = PostalAddress, + HeadCompany = new { Id = HeadCompany == null ? 0 : HeadCompany.DirectumId }, + BINArmadoc = BINArmadoc, + Phones = Phones, + Status = "Active" + }; + var updated = await client + .For("IBusinessUnits") + .Key(id) + .Set(newBusinessUnit) + .UpdateEntryAsync(); + this.DirectumId = (long)updated["Id"]; + return (long)updated["Id"]; + } + + public bool IsEqual(IDictionary businessUnit) + { + var result = false; + long? headComapnyId = null; + if (businessUnit["HeadCompany"] != null) + { + headComapnyId = businessUnit["HeadCompany"]["Id"]; + } + dynamic headCompany = businessUnit["HeadCompany"]; + if (headCompany != null) + { + headComapnyId = (long)headCompany["Id"]; + } + if (Name == (string)businessUnit["Name"] && + LegalName == (string)businessUnit["LegalName"] && + HeadCompany?.DirectumId == headComapnyId && + BINArmadoc == (string)businessUnit["BINArmadoc"] && + LegalAddress == (string)businessUnit["LegalAddress"] && + PostalAddress == (string)businessUnit["PostalAddress"] && + Phones == (string)businessUnit["Phones"]) + result = true; + + return result; + } + + public async Task CreateNCEO(ODataClient client) + { + long result = 0; + if (NCEO != null) + { + dynamic emp = await client + .For("IEmployees") + .Filter($"ExternalId eq '{NCEO.Sid}' and Status eq 'Active'") + .FindEntryAsync(); + + dynamic bu = await client + .For("IBusinessUnits") + .Filter($"ExternalId eq '{Sid}'") + .FindEntryAsync(); + + + if (emp != null && bu != null) + { + var newBusinessUnit = new + { + CEO = new { Id = (long)emp["Id"] } + }; + var updated = await client + .For("IBusinessUnits") + .Key((long)bu["Id"]) + .Set(newBusinessUnit) + .UpdateEntryAsync(); + result = (long)updated["Id"]; + } + } + return result; + } + + public async Task CreateAccount(ODataClient client) + { + long result = 0; + if (Account != null) + { + dynamic emp = await client + .For("IEmployees") + .Filter($"ExternalId eq '{Account.Sid}' and Status eq 'Active'") + .FindEntryAsync(); + + dynamic bu = await client + .For("IBusinessUnits") + .Filter($"ExternalId eq '{Sid}'") + .FindEntryAsync(); + + + if (emp != null && bu != null) + { + var newBusinessUnit = new + { + CAO = new { Id = (long)emp["Id"] } + }; + var updated = await client + .For("IBusinessUnits") + .Key((long)bu["Id"]) + .Set(newBusinessUnit) + .UpdateEntryAsync(); + result = (long)updated["Id"]; + } + } + return result; + } + + public async Task GetIdBySid(ODataClient client) + { + long result = 0; + if (!string.IsNullOrEmpty(Sid)) + { + var found = await client + .For("IBusinessUnits") + .Filter($"ExternalId eq '{this.Sid}'") + .FindEntryAsync(); + if (found != null) + { + DirectumId = (long)found["Id"]; + result = (long)found["Id"]; + } + } + return result; + } + } +} diff --git a/JSONParser/Structure/Department.cs b/JSONParser/Structure/Department.cs new file mode 100644 index 0000000..6ffccb1 --- /dev/null +++ b/JSONParser/Structure/Department.cs @@ -0,0 +1,99 @@ + +using Simple.OData.Client; + +namespace JSONParser.Structure +{ + public class Department : Entity + { + public string Name { get; set; } + public string ShortName { get; set; } + public BusinessUnit BusinessUnit { get; set; } + public Department HeadOffice { get; set; } + public string Status { get; set; } + + public override string ToString() + { + return Name; + } + + public override async Task Create(ODataClient client) + { + var newDept = new + { + Name = this.Name, + Status = "Active", + ShortName = this.ShortName, + ExternalId = this.Sid, + HeadOffice = new { Id = this.HeadOffice == null ? 0 : this.HeadOffice.DirectumId }, + BusinessUnit = new { Id = this.BusinessUnit?.DirectumId } + }; + var created = await client + .For("IDepartment") + .Set(newDept) + .InsertEntryAsync(); + this.DirectumId = (long)created["Id"]; + return (long)created["Id"]; + } + + public async override Task Update(ODataClient client, long id) + { + var newDept = new + { + Name = this.Name, + Status = "Active", + ShortName = this.ShortName, + ExternalId = this.Sid, + HeadOffice = new { Id = this.HeadOffice == null ? 0 : this.HeadOffice.DirectumId }, + BusinessUnit = new { Id = this.BusinessUnit?.DirectumId } + }; + var updated = await client + .For("IDepartment") + .Key(id) + .Set(newDept) + .UpdateEntryAsync(); + this.DirectumId = (long)updated["Id"]; + return (long)updated["Id"]; + } + + public async Task GetIdBySid(ODataClient client) + { + long result = 0; + if (!string.IsNullOrEmpty(Sid)) + { + var found = await client + .For("IDepartment") + .Filter($"ExternalId eq '{this.Sid}'") + .FindEntryAsync(); + if (found != null) + { + DirectumId = (long)found["Id"]; + result = (long)found["Id"]; + } + } + return result; + } + + public bool IsEqual(IDictionary dept) + { + var result = false; + long? businessUnitId = null; + long? headOfficeId = null; + if (dept["BusinessUnit"] != null) + { + businessUnitId = dept["BusinessUnit"]["Id"]; + } + if (dept["HeadOffice"] != null) + { + headOfficeId = dept["HeadOffice"]["Id"]; + } + if (Name == dept["Name"] && + ShortName == dept["ShortName"] && + BusinessUnit?.DirectumId == businessUnitId && + HeadOffice?.DirectumId == headOfficeId) + { + result = true; + } + return result; + } + } +} diff --git a/JSONParser/Structure/Employee.cs b/JSONParser/Structure/Employee.cs new file mode 100644 index 0000000..5dc4a20 --- /dev/null +++ b/JSONParser/Structure/Employee.cs @@ -0,0 +1,155 @@ +using Simple.OData.Client; + +namespace JSONParser.Structure +{ + public class Employee : Entity + { + public Person Person { get; set; } + public Login Login { get; set; } + public string Email { get; set; } + public Department Department { get; set; } + public JobTitle JobTitle { get; set; } + public string JobTitleName { get; set; } + public bool Status { get; set; } + + public override string ToString() + { + if (Person != null) + { + var fullname = $"{Person.LastName} {Person.FirstName}"; + if (!string.IsNullOrEmpty(Person.MiddleName)) + { + fullname += $" {Person.MiddleName}"; + } + return fullname; + } + return base.ToString(); + } + + public async Task FindByLogin(ODataClient client) + { + if (Login == null) return 0; + var byLogin = await client + .For("IEmployees") + .Expand("Login") + .Filter($"tolower(Login/LoginName) eq '{Login.LoginName?.ToLower()}'") + .FindEntryAsync(); + if (byLogin == null) return 0; + return (long)byLogin["Id"]; + } + + public async override Task Create(ODataClient client) + { + var newEmployee = new + { + ExternalId = Sid, + Person = new { Id = Person.DirectumId }, + Department = new { Id = Department.DirectumId }, + JobTitle = new { Id = JobTitle.DirectumId }, + Login = new { Id = Login == null ? 0 : Login.DirectumId }, + Email = Email, + NeedNotifyExpiredAssignments = false, + NeedNotifyNewAssignments = false, + NeedNotifyAssignmentsSummary = false, + Status = "Active" + }; + var created = await client + .For("IEmployees") + .Set(newEmployee) + .InsertEntryAsync(); + + this.DirectumId = (long)created["Id"]; + return (long)created["Id"]; + } + + public async override Task Update(ODataClient client, long id) + { + var newEmployee = new + { + ExternalId = Sid, + Person = new { Id = Person.DirectumId }, + Department = new { Id = Department.DirectumId }, + JobTitle = new { Id = JobTitle.DirectumId }, + Login = new { Id = Login == null ? 0 : Login.DirectumId }, + Email = Email, + NeedNotifyExpiredAssignments = false, + NeedNotifyNewAssignments = false, + NeedNotifyAssignmentsSummary = false, + Status = Status ? "Active" : "Closed" + }; + var updated = await client + .For("IEmployees") + .Key(id) + .Set(newEmployee) + .UpdateEntryAsync(); + this.DirectumId = (long)updated["Id"]; + return (long)updated["Id"]; + } + + public async Task CloseRecord(ODataClient client, long id) + { + var update = new { Login = new { Id = 0 }, Status = "Closed" }; + await client + .For("IEmployees") + .Key(id) + .Set(update) + .UpdateEntryAsync(); + } + + internal bool IsEqual(IDictionary? emp) + { + bool result = false; + long? personId = null; + long? loginId = null; + long? departmentId = null; + long? jobTitleId = null; + bool status = false; + + if (emp["Person"] != null) + { + personId = emp["Person"]["Id"]; + } + if (emp["Login"] != null) + { + loginId = emp["Login"]["Id"]; + } + if (emp["Department"] != null) + { + departmentId = emp["Department"]["Id"]; + } + if (emp["JobTitle"] != null) + { + jobTitleId = emp["JobTitle"]["Id"]; + } + if (emp["Status"] != null) + { + status = emp["Status"] == "Active" ? true : false; + } + if (Person?.DirectumId == personId && + Login?.DirectumId == loginId && + Email == (string)emp["Email"] && + Department?.DirectumId == departmentId && + JobTitle?.DirectumId == jobTitleId && + Status == status) + { + result = true; + } + + return result; + } + + public async Task TryFindBySid(ODataClient client) + { + long result = 0; + var employee = await client + .For("IEmployees") + .Filter($"ExternalId eq '{Sid}' and Status eq 'Active'") + .FindEntryAsync(); + if (employee != null) + { + result = (long)employee["Id"]; + } + return result; + } + } +} diff --git a/JSONParser/Structure/Entity.cs b/JSONParser/Structure/Entity.cs new file mode 100644 index 0000000..47bce0a --- /dev/null +++ b/JSONParser/Structure/Entity.cs @@ -0,0 +1,26 @@ +using Simple.OData.Client; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JSONParser.Structure +{ + public class Entity + { + public string Type { get; set; } + public string Sid { get; set; } + public long? DirectumId { get; set; } + + public virtual Task Create(ODataClient client) + { + throw new NotImplementedException(); + } + + public virtual Task Update(ODataClient client, long id) + { + throw new NotImplementedException(); + } + } +} diff --git a/JSONParser/Structure/JobTitle.cs b/JSONParser/Structure/JobTitle.cs new file mode 100644 index 0000000..c1a7ab5 --- /dev/null +++ b/JSONParser/Structure/JobTitle.cs @@ -0,0 +1,82 @@ + +using Simple.OData.Client; + +namespace JSONParser.Structure +{ + public class JobTitle : Entity + { + public string Name { get; set; } + public Department Department { get; set; } + + public override string ToString() + { + return Name; + } + + public override async Task Create(ODataClient client) + { + var newJobTitle = new + { + Name = Name, + Department = new { Id = Department.DirectumId }, + Status = "Active" + }; + var created = await client + .For("IJobTitles") + .Set(newJobTitle) + .InsertEntryAsync(); + this.DirectumId = (long)created["Id"]; + return (long)created["Id"]; + } + public async override Task Update(ODataClient client, long id) + { + var newJobTitle = new + { + Name = Name, + Department = new { Id = Department.DirectumId }, + Status = "Active" + }; + var updated = await client + .For("IJobTitles") + .Key(id) + .Set(newJobTitle) + .UpdateEntryAsync(); + this.DirectumId = (long)updated["Id"]; + return (long)updated["Id"]; + } + + public bool IsEqual(IDictionary job) + { + bool result = false; + long? jobTitleId = null; + if (job["Department"] != null) + { + jobTitleId = job["Department"]["Id"]; + } + if (Name == (string)job["Name"] && + Department?.DirectumId == jobTitleId) + { + result = true; + } + return result; + } + + public async Task GetIdBySid(ODataClient client) + { + long result = 0; + if (!string.IsNullOrEmpty(Name) && Department != null) + { + var job = await client + .For("IJobTitles") + .Expand("Department") + .Filter($"Name eq '{Name}' and Department/ExternalId eq '{Department.Sid}'") + .FindEntryAsync(); + if (job != null) + { + result = (long)job["Id"]; + } + } + return result; + } + } +} diff --git a/JSONParser/Structure/Login.cs b/JSONParser/Structure/Login.cs new file mode 100644 index 0000000..ddbe99e --- /dev/null +++ b/JSONParser/Structure/Login.cs @@ -0,0 +1,78 @@ +using Simple.OData.Client; +using System.Dynamic; + +namespace JSONParser.Structure +{ + public class Login : Entity + { + public string LoginName { get; set; } + public string TypeAuthentication { get; set; } + public bool Status { get; set; } + + public override string ToString() + { + return LoginName; + } + + public override async Task Create(ODataClient client) + { + var newPerson = new + { + LoginName = $"{LoginName}", + TypeAuthentication = TypeAuthentication, + Status = "Active" + }; + var created = await client + .For("ILogins") + .Set(newPerson) + .InsertEntryAsync(); + this.DirectumId = (long)created["Id"]; + return (long)created["Id"]; + } + + public async override Task Update(ODataClient client, long id) + { + var newPerson = new + { + LoginName = LoginName, + TypeAuthentication = TypeAuthentication, + Status = "Active" + }; + var created = await client + .For("ILogins") + .Key(id) + .Set(newPerson) + .UpdateEntryAsync(); + this.DirectumId = (long)created["Id"]; + return (long)created["Id"]; + } + + public bool IsEqual(IDictionary log) + { + bool result = false; + if (LoginName == log["LoginName"] && + TypeAuthentication == log["TypeAuthentication"]) + { + result = true; + } + return result; + } + + public async Task GetIdBySid(ODataClient client) + { + long result = 0; + if (!string.IsNullOrEmpty(LoginName)) + { + var log = await client + .For("ILogins") + .Filter($"tolower(LoginName) eq '{LoginName.ToLower()}'") + .FindEntryAsync(); + if (log != null) + { + result = (long)log["Id"]; + } + } + return result; + } + } +} diff --git a/JSONParser/Structure/Person.cs b/JSONParser/Structure/Person.cs new file mode 100644 index 0000000..11b14d7 --- /dev/null +++ b/JSONParser/Structure/Person.cs @@ -0,0 +1,89 @@ + +using Simple.OData.Client; +using System; + +namespace JSONParser.Structure +{ + public class Person : Entity + { + public string FirstName { get; set; } + public string LastName { get; set; } + public string MiddleName { get; set; } + + public override string ToString() + { + var fullname = $"{LastName} {FirstName}"; + if (!string.IsNullOrEmpty(MiddleName)) + { + fullname += $" {MiddleName}"; + } + return fullname; + } + + public override async Task Create(ODataClient client) + { + var newPerson = new + { + ExternalId = Sid, + FirstName = FirstName, + LastName = LastName, + MiddleName = MiddleName, + Status = "Active" + }; + var created = await client + .For("IPersons") + .Set(newPerson) + .InsertEntryAsync(); + this.DirectumId = (long)created["Id"]; + return (long)created["Id"]; + } + + public async override Task Update(ODataClient client, long id) + { + var newPerson = new + { + ExternalId = Sid, + FirstName = FirstName, + LastName = LastName, + MiddleName = MiddleName, + Status = "Active" + }; + var updated = await client + .For("IPersons") + .Key(id) + .Set(newPerson) + .UpdateEntryAsync(); + this.DirectumId = (long)updated["Id"]; + return (long)updated["Id"]; + } + + public bool IsEqual(IDictionary per) + { + bool result = false; + if (FirstName == (string)per["FirstName"] && + LastName == (string)per["LastName"] && + MiddleName == (string)per["MiddleName"]) + { + result = true; + } + return result; + } + + public async Task GetIdBySid(ODataClient client) + { + long result = 0; + if (!string.IsNullOrEmpty(Sid)) + { + var per = await client + .For("IPersons") + .Filter($"ExternalId eq '{Sid}'") + .FindEntryAsync(); + if (per != null) + { + result = (long)per["Id"]; + } + } + return result; + } + } +}