Files
raven/server/AyaNova/biz/ImportAyaNova7Biz.cs
2018-10-04 00:16:17 +00:00

265 lines
12 KiB
C#

using System;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using EnumsNET;
using AyaNova.Util;
using AyaNova.Api.ControllerHelpers;
using AyaNova.Biz;
using AyaNova.Models;
namespace AyaNova.Biz
{
internal class ImportAyaNova7Biz : BizObject, IJobObject
{
// private readonly AyContext ct;
// public readonly long userId;
// private readonly AuthorizationRoles userRoles;
internal ImportAyaNova7Biz(AyContext dbcontext, long currentUserId, AuthorizationRoles userRoles)
{
ct = dbcontext;
UserId = currentUserId;
CurrentUserRoles = userRoles;
BizType = AyaType.AyaNova7Import;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//JOB / OPERATIONS
//
public async Task HandleJobAsync(OpsJob job)
{
//Hand off the particular job to the corresponding processing code
//NOTE: If this code throws an exception the caller (JobsBiz::ProcessJobsAsync) will automatically set the job to failed and log the exeption so
//basically any error condition during job processing should throw up an exception if it can't be handled
//There might be future other job types so doing it like this for all biz job handlers for now
switch (job.JobType)
{
case JobType.ImportV7Data:
await ProcessImportV7JobAsync(job);
break;
default:
throw new System.ArgumentOutOfRangeException($"ImportAyaNovaBiz.HandleJob-> Invalid job type{job.JobType.ToString()}");
}
}
/// <summary>
/// /// Handle the test job
/// </summary>
/// <param name="job"></param>
private async Task ProcessImportV7JobAsync(OpsJob job)
{
//NOTE: If this code throws an exception the caller will automatically set the job to failed and log the exeption so
//basically any error condition during job processing should throw up an exception if it can't be handled
List<ImportAyaNova7MapItem> importMap = new List<ImportAyaNova7MapItem>();
JobsBiz.UpdateJobStatus(job.GId, JobStatus.Running, ct);
JobsBiz.LogJob(job.GId, $"ImportAyaNova7 starting", ct);
//Get the import filename from the jsondata
JObject jobData = JObject.Parse(job.JobInfo);
var importFileName = jobData["ImportFileName"].Value<string>();
if (string.IsNullOrWhiteSpace(importFileName))
{
throw new System.ArgumentNullException("ImportAyaNova7 job failed due to no import filename being specified");
}
if (!FileUtil.UtilityFileExists(importFileName))
{
throw new System.ArgumentNullException("ImportAyaNova7 job failed due to import file specified not existing");
}
//get the contents of the archive
List<string> zipEntries = FileUtil.ZipGetUtilityFileEntries(importFileName);
//Iterate through the import items in the preferred order, checking for corresponding entries in the zip file
//In turn try to instantiate the type and id job that can handle that import, attempt to case or see if implements IImportAyaNova7Object
//, if null / not supported for import then skip and log as not currently supported
//Pass off the JSON data from the import file into the import job item by item
//NOTE: Many of these require a second pass - one to get the object imported and then another to set another imported object to that object
//for example scheduleable user groups are imported as tags, but then a second pass is required to tag the users of that group
//USERS
await DoImport("GZTW.AyaNova.BLL.User", "main", AyaType.User, job.GId, importMap, importFileName, zipEntries);
//Now can do event log entries
await DoImport("GZTW.AyaNova.BLL.User", "eventlog", AyaType.User, job.GId, importMap, importFileName, zipEntries);
//IMPORT UNIT MODEL CATEGORIES AS TAGS
await DoImport("GZTW.AyaNova.BLL.UnitModelCategory", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries);
//IMPORT Unit service type AS TAGS
await DoImport("GZTW.AyaNova.BLL.UnitServiceType", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries);
//IMPORT Workorder Item Type AS TAGS
await DoImport("GZTW.AyaNova.BLL.WorkorderItemType", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries);
//IMPORT Client group AS TAGS
await DoImport("GZTW.AyaNova.BLL.ClientGroup", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries);
//IMPORT Workorder category AS TAGS
await DoImport("GZTW.AyaNova.BLL.WorkorderCategory", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries);
//IMPORT Part Category AS TAGS
await DoImport("GZTW.AyaNova.BLL.PartCategory", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries);
//IMPORT Dispatch zones AS TAGS
await DoImport("GZTW.AyaNova.BLL.DispatchZone", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries);
//IMPORT Scheduleable User Groups AS TAGS
await DoImport("GZTW.AyaNova.BLL.ScheduleableUserGroup", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries);
//Now can set users to correct tag for scheduleable user group
await DoImport("GZTW.AyaNova.BLL.ScheduleableUserGroup", "scheduleableusergrouptags", AyaType.Tag, job.GId, importMap, importFileName, zipEntries);
//IMPORT REGIONS AS TAGS
await DoImport("GZTW.AyaNova.BLL.Region", "main", AyaType.Tag, job.GId, importMap, importFileName, zipEntries);
//IMPORT LOCALES
await DoImport("GZTW.AyaNova.BLL.Locale", "main", AyaType.Locale, job.GId, importMap, importFileName, zipEntries);
//Now can do user locale settings properly
await DoImport("GZTW.AyaNova.BLL.User", "locale", AyaType.User, job.GId, importMap, importFileName, zipEntries);
//TODO: CLIENT
//do import for client here
//Now can do user client settings properly
//await DoImport("GZTW.AyaNova.BLL.User","clientid", AyaType.User, job.GId, importMap, importFileName, zipEntries);
//TODO: HEADOFFICE
//do import for ho here
//Now can do user ho settings properly
//await DoImport("GZTW.AyaNova.BLL.User","headofficeid", AyaType.User, job.GId, importMap, importFileName, zipEntries);
//----------------
JobsBiz.LogJob(job.GId, "ImportAyaNova7 finished", ct);
JobsBiz.UpdateJobStatus(job.GId, JobStatus.Completed, ct);
}
/// <summary>
/// This method does the actual import by
/// - Fetching the list of entries in the zip archive that match the passed in startsWtih (folder name in zip archive)
/// - Instantiating the corresponding new biz object type to handle the import
/// - Passing the json parsed to the biz object one at a time to do the import
/// </summary>
/// <param name="entryStartsWith"></param>
/// <param name="importTask"></param>
/// <param name="importerType"></param>
/// <param name="jobId"></param>
/// <param name="importMap"></param>
/// <param name="importFileName"></param>
/// <param name="zipEntries"></param>
/// <returns></returns>
private async Task DoImport(string entryStartsWith, string importTask, AyaType importerType, Guid jobId, List<ImportAyaNova7MapItem> importMap, string importFileName, List<string> zipEntries)
{
var zipObjectList = zipEntries.Where(m => m.StartsWith(entryStartsWith)).ToList();
long importCount = 0;
long notImportCount = 0;
if (zipObjectList.Count > 0)
{
if (importTask != "main")
{
JobsBiz.LogJob(jobId, $"Starting import sub-task {importTask} of {entryStartsWith} objects", ct);
}
else
{
JobsBiz.LogJob(jobId, $"Starting import of {entryStartsWith} objects", ct);
}
var jList = FileUtil.ZipGetUtilityArchiveEntriesAsJsonObjects(zipObjectList, importFileName);
IImportAyaNova7Object o = (IImportAyaNova7Object)BizObjectFactory.GetBizObject(importerType, ct);
foreach (JObject j in jList)
{
bool bImportSucceeded = false;
//some new types can import multiple old types and it might matter which is which to the importer
//so tag it with the original type
//------
j.Add("V7_TYPE", JToken.FromObject(entryStartsWith));
j.Add("IMPORT_TASK", JToken.FromObject(importTask));
bImportSucceeded = await o.ImportV7Async(j, importMap, jobId);
if (bImportSucceeded)
importCount++;
else
notImportCount++;
}
if (importCount > 0)
{
if (importTask != "main")
{
JobsBiz.LogJob(jobId, $"Successfully ran import subtask {importTask} on {importCount.ToString()} of {zipObjectList.Count.ToString()} {entryStartsWith} objects", ct);
}
else
{
JobsBiz.LogJob(jobId, $"Successfully imported {importCount.ToString()} of {zipObjectList.Count.ToString()} {entryStartsWith} objects", ct);
}
}
if (notImportCount > 0)
{
if (importTask != "main")
{
JobsBiz.LogJob(jobId, $"Failed to run import subtask {importTask} on {notImportCount.ToString()} of {zipObjectList.Count.ToString()} {entryStartsWith} objects", ct);
}
else
{
JobsBiz.LogJob(jobId, $"Did not import {notImportCount.ToString()} of {zipObjectList.Count.ToString()} {entryStartsWith} objects", ct);
}
}
}
}
//Other job handlers here...
//////////////////////////////////////////////////////////////////
//UTILITIES
internal static async Task LogEventCreatedModifiedEvents(JObject j, List<ImportAyaNova7MapItem> importMap, AyaType ayaType, AyContext ct)
{
var V7Id = new Guid(j["ID"].Value<string>());
var RavenId = importMap.Where(m => m.V7ObjectId == V7Id).First().NewObjectAyaTypeId.ObjectId;
var Creator = importMap.Where(m => m.V7ObjectId == new Guid(j["Creator"].Value<string>())).First().NewObjectAyaTypeId.ObjectId;
var Modifier = importMap.Where(m => m.V7ObjectId == new Guid(j["Modifier"].Value<string>())).First().NewObjectAyaTypeId.ObjectId;
var Created = j["Created"].Value<DateTime>();
var Modified = j["Modified"].Value<DateTime>();
//handle EventLog entries for users now that we have the user's created
//Created
EventLogProcessor.AddEntryToContextNoSave(new Event(Creator, RavenId, ayaType, AyaEvent.Created, Created), ct);
//MODIFIED
EventLogProcessor.AddEntryToContextNoSave(new Event(Modifier, RavenId, ayaType, AyaEvent.Modified, Modified), ct);
await ct.SaveChangesAsync();
}
/////////////////////////////////////////////////////////////////////
}//eoc
}//eons