This commit is contained in:
220
server/AyaNova/biz/QuoteStatusBiz.cs
Normal file
220
server/AyaNova/biz/QuoteStatusBiz.cs
Normal file
@@ -0,0 +1,220 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using AyaNova.Util;
|
||||
using AyaNova.Api.ControllerHelpers;
|
||||
using AyaNova.Models;
|
||||
|
||||
namespace AyaNova.Biz
|
||||
{
|
||||
internal class QuoteStatusBiz : BizObject, ISearchAbleObject
|
||||
{
|
||||
internal QuoteStatusBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles)
|
||||
{
|
||||
ct = dbcontext;
|
||||
UserId = currentUserId;
|
||||
UserTranslationId = userTranslationId;
|
||||
CurrentUserRoles = UserRoles;
|
||||
BizType = AyaType.QuoteStatus;
|
||||
}
|
||||
|
||||
internal static QuoteStatusBiz GetBiz(AyContext ct, Microsoft.AspNetCore.Http.HttpContext httpContext = null)
|
||||
{
|
||||
if (httpContext != null)
|
||||
return new QuoteStatusBiz(ct, UserIdFromContext.Id(httpContext.Items), UserTranslationIdFromContext.Id(httpContext.Items), UserRolesFromContext.Roles(httpContext.Items));
|
||||
else
|
||||
return new QuoteStatusBiz(ct, 1, ServerBootConfig.AYANOVA_DEFAULT_TRANSLATION_ID, AuthorizationRoles.BizAdmin);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//EXISTS
|
||||
internal async Task<bool> ExistsAsync(long id)
|
||||
{
|
||||
return await ct.QuoteStatus.AnyAsync(z => z.Id == id);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//CREATE
|
||||
//
|
||||
internal async Task<QuoteStatus> CreateAsync(QuoteStatus newObject)
|
||||
{
|
||||
await ValidateAsync(newObject, null);
|
||||
if (HasErrors)
|
||||
return null;
|
||||
else
|
||||
{
|
||||
await ct.QuoteStatus.AddAsync(newObject);
|
||||
await ct.SaveChangesAsync();
|
||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct);
|
||||
await SearchIndexAsync(newObject, true);
|
||||
return newObject;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//GET
|
||||
//
|
||||
internal async Task<QuoteStatus> GetAsync(long id, bool logTheGetEvent = true)
|
||||
{
|
||||
var ret = await ct.QuoteStatus.AsNoTracking().SingleOrDefaultAsync(m => m.Id == id);
|
||||
if (logTheGetEvent && ret != null)
|
||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, id, BizType, AyaEvent.Retrieved), ct);
|
||||
return ret;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//UPDATE
|
||||
//
|
||||
internal async Task<QuoteStatus> PutAsync(QuoteStatus putObject)
|
||||
{
|
||||
var dbObject = await GetAsync(putObject.Id, false);
|
||||
if (dbObject == null)
|
||||
{
|
||||
AddError(ApiErrorCode.NOT_FOUND, "id");
|
||||
return null;
|
||||
}
|
||||
if (dbObject.Concurrency != putObject.Concurrency)
|
||||
{
|
||||
AddError(ApiErrorCode.CONCURRENCY_CONFLICT);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
await ValidateAsync(putObject, dbObject);
|
||||
if (HasErrors) return null;
|
||||
ct.Replace(dbObject, putObject);
|
||||
try
|
||||
{
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
catch (DbUpdateConcurrencyException)
|
||||
{
|
||||
if (!await ExistsAsync(putObject.Id))
|
||||
AddError(ApiErrorCode.NOT_FOUND);
|
||||
else
|
||||
AddError(ApiErrorCode.CONCURRENCY_CONFLICT);
|
||||
return null;
|
||||
}
|
||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct);
|
||||
await SearchIndexAsync(putObject, false);
|
||||
return putObject;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//DELETE
|
||||
//
|
||||
internal async Task<bool> DeleteAsync(long id)
|
||||
{
|
||||
using (var transaction = await ct.Database.BeginTransactionAsync())
|
||||
{
|
||||
try
|
||||
{
|
||||
var dbObject = await GetAsync(id, false);
|
||||
if (dbObject == null)
|
||||
{
|
||||
AddError(ApiErrorCode.NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
await ValidateCanDeleteAsync(dbObject);
|
||||
if (HasErrors)
|
||||
return false;
|
||||
ct.QuoteStatus.Remove(dbObject);
|
||||
await ct.SaveChangesAsync();
|
||||
|
||||
//Log event
|
||||
await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct);
|
||||
await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct);
|
||||
await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct);
|
||||
await transaction.CommitAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
//Just re-throw for now, let exception handler deal, but in future may want to deal with this more here
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//SEARCH
|
||||
//
|
||||
private async Task SearchIndexAsync(QuoteStatus obj, bool isNew)
|
||||
{
|
||||
var SearchParams = new Search.SearchIndexProcessObjectParameters(UserTranslationId, obj.Id, BizType);
|
||||
DigestSearchText(obj, SearchParams);
|
||||
if (isNew)
|
||||
await Search.ProcessNewObjectKeywordsAsync(SearchParams);
|
||||
else
|
||||
await Search.ProcessUpdatedObjectKeywordsAsync(SearchParams);
|
||||
}
|
||||
|
||||
public async Task<Search.SearchIndexProcessObjectParameters> GetSearchResultSummary(long id)
|
||||
{
|
||||
var obj = await GetAsync(id, false);
|
||||
var SearchParams = new Search.SearchIndexProcessObjectParameters();
|
||||
DigestSearchText(obj, SearchParams);
|
||||
return SearchParams;
|
||||
}
|
||||
|
||||
public void DigestSearchText(QuoteStatus obj, Search.SearchIndexProcessObjectParameters searchParams)
|
||||
{
|
||||
if (obj != null)
|
||||
searchParams.AddText(obj.Notes)
|
||||
.AddText(obj.Name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//VALIDATION
|
||||
//
|
||||
|
||||
private async Task ValidateAsync(QuoteStatus proposedObj, QuoteStatus currentObj)
|
||||
{
|
||||
|
||||
bool isNew = currentObj == null;
|
||||
|
||||
//Name required
|
||||
if (string.IsNullOrWhiteSpace(proposedObj.Name))
|
||||
AddError(ApiErrorCode.VALIDATION_REQUIRED, "Name");
|
||||
|
||||
|
||||
|
||||
//If name is otherwise OK, check that name is unique
|
||||
if (!PropertyHasErrors("Name"))
|
||||
{
|
||||
//Use Any command is efficient way to check existance, it doesn't return the record, just a true or false
|
||||
if (await ct.QuoteStatus.AnyAsync(m => m.Name == proposedObj.Name && m.Id != proposedObj.Id))
|
||||
{
|
||||
AddError(ApiErrorCode.VALIDATION_NOT_UNIQUE, "Name");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private async Task ValidateCanDeleteAsync(QuoteStatus inObj)
|
||||
{
|
||||
//MIGRATE_OUTSTANDING - check workorder records once wo is coded here
|
||||
await Task.CompletedTask;
|
||||
//Referential integrity
|
||||
//FOREIGN KEY CHECKS
|
||||
if (await ct.QuoteState.AnyAsync(m => m.QuoteStatusId == inObj.Id))
|
||||
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("QuoteStatus"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
}//eoc
|
||||
|
||||
|
||||
}//eons
|
||||
|
||||
@@ -1331,6 +1331,165 @@ namespace AyaNova.Util
|
||||
}
|
||||
|
||||
|
||||
//--------- quote status
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//WorkorderStatus
|
||||
{
|
||||
|
||||
{
|
||||
QuoteStatus stat = new QuoteStatus();
|
||||
stat.Name = "Submitted";
|
||||
stat.Active = true;
|
||||
stat.Color = "#c00000";
|
||||
stat.Completed = false;
|
||||
stat.Locked = true;
|
||||
stat.SelectRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
|
||||
stat.RemoveRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
|
||||
stat.Notes = "Use to lock quote after given to customer and wait for approval";
|
||||
using (AyContext ct = ServiceProviderProvider.DBContext)
|
||||
{
|
||||
QuoteStatusBiz biz = QuoteStatusBiz.GetBiz(ct);
|
||||
var NewObject = await biz.CreateAsync(stat);
|
||||
|
||||
if (NewObject == null)
|
||||
{
|
||||
var err = $"Seeder::SeedKnownObjects error creating quote status\r\n{biz.GetErrorsAsString()}";
|
||||
log.LogError(err);
|
||||
throw new System.Exception(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
QuoteStatus stat = new QuoteStatus();
|
||||
stat.Name = "Awarded";
|
||||
stat.Active = true;
|
||||
stat.Color = "#80ffff";
|
||||
stat.Completed = false;
|
||||
stat.Locked = false;
|
||||
stat.SelectRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
|
||||
stat.RemoveRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting | AuthorizationRoles.Service;
|
||||
stat.Notes = "Waiting for work order to be generated";
|
||||
using (AyContext ct = ServiceProviderProvider.DBContext)
|
||||
{
|
||||
QuoteStatusBiz biz = QuoteStatusBiz.GetBiz(ct);
|
||||
var NewObject = await biz.CreateAsync(stat);
|
||||
|
||||
if (NewObject == null)
|
||||
{
|
||||
var err = $"Seeder::SeedKnownObjects error creating quote status\r\n{biz.GetErrorsAsString()}";
|
||||
log.LogError(err);
|
||||
throw new System.Exception(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
QuoteStatus stat = new QuoteStatus();
|
||||
stat.Name = "In progress";
|
||||
stat.Active = true;
|
||||
stat.Color = "#00ff00";
|
||||
stat.Completed = false;
|
||||
stat.Locked = false;
|
||||
stat.SelectRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
|
||||
stat.RemoveRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
|
||||
stat.Notes = "In process of completing this quote";
|
||||
using (AyContext ct = ServiceProviderProvider.DBContext)
|
||||
{
|
||||
QuoteStatusBiz biz = QuoteStatusBiz.GetBiz(ct);
|
||||
var NewObject = await biz.CreateAsync(stat);
|
||||
|
||||
if (NewObject == null)
|
||||
{
|
||||
var err = $"Seeder::SeedKnownObjects error creating quote status\r\n{biz.GetErrorsAsString()}";
|
||||
log.LogError(err);
|
||||
throw new System.Exception(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
QuoteStatus stat = new QuoteStatus();
|
||||
stat.Name = "Not repairable";
|
||||
stat.Active = true;
|
||||
stat.Color = "#ff0000";
|
||||
stat.Completed = true;
|
||||
stat.Locked = true;
|
||||
stat.SelectRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
|
||||
stat.RemoveRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
|
||||
stat.Notes = "Beyond economical repair";
|
||||
using (AyContext ct = ServiceProviderProvider.DBContext)
|
||||
{
|
||||
QuoteStatusBiz biz = QuoteStatusBiz.GetBiz(ct);
|
||||
var NewObject = await biz.CreateAsync(stat);
|
||||
|
||||
if (NewObject == null)
|
||||
{
|
||||
var err = $"Seeder::SeedKnownObjects error creating quote status\r\n{biz.GetErrorsAsString()}";
|
||||
log.LogError(err);
|
||||
throw new System.Exception(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
QuoteStatus stat = new QuoteStatus();
|
||||
stat.Name = "New";
|
||||
stat.Active = true;
|
||||
stat.Color = "#8080ff";
|
||||
stat.Completed = false;
|
||||
stat.Locked = true;
|
||||
stat.SelectRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
|
||||
stat.RemoveRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
|
||||
stat.Notes = "New quote required; Sales to complete this Quote for submission";
|
||||
using (AyContext ct = ServiceProviderProvider.DBContext)
|
||||
{
|
||||
QuoteStatusBiz biz = QuoteStatusBiz.GetBiz(ct);
|
||||
var NewObject = await biz.CreateAsync(stat);
|
||||
|
||||
if (NewObject == null)
|
||||
{
|
||||
var err = $"Seeder::SeedKnownObjects error creating quote status\r\n{biz.GetErrorsAsString()}";
|
||||
log.LogError(err);
|
||||
throw new System.Exception(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
QuoteStatus stat = new QuoteStatus();
|
||||
stat.Name = "Not awarded";
|
||||
stat.Active = true;
|
||||
stat.Color = "#f2f2f2";
|
||||
stat.Completed = true;
|
||||
stat.Locked = true;
|
||||
stat.SelectRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
|
||||
stat.RemoveRoles = AuthorizationRoles.BizAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Accounting;
|
||||
|
||||
using (AyContext ct = ServiceProviderProvider.DBContext)
|
||||
{
|
||||
QuoteStatusBiz biz = QuoteStatusBiz.GetBiz(ct);
|
||||
var NewObject = await biz.CreateAsync(stat);
|
||||
|
||||
if (NewObject == null)
|
||||
{
|
||||
var err = $"Seeder::SeedKnownObjects error creating quote status\r\n{biz.GetErrorsAsString()}";
|
||||
log.LogError(err);
|
||||
throw new System.Exception(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--------- /quote status
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//TASKGROUP
|
||||
//
|
||||
@@ -2259,7 +2418,7 @@ namespace AyaNova.Util
|
||||
//var rerun=await biz.GetAsync(NewObject.Id,false);
|
||||
|
||||
//newObject is still being tracked so can just set the unitid and save it here
|
||||
NewObject.UnitId=newUnit.Id;
|
||||
NewObject.UnitId = newUnit.Id;
|
||||
await ct.SaveChangesAsync();
|
||||
//await biz.PutAsync(NewObject);
|
||||
|
||||
@@ -2945,7 +3104,7 @@ namespace AyaNova.Util
|
||||
woItemExpense = new WorkOrderItemExpense()
|
||||
{
|
||||
UserId = RandomServiceTechUserId(),
|
||||
// TotalCost = cost * 2m,
|
||||
// TotalCost = cost * 2m,
|
||||
ChargeAmount = cost * 2.2m,
|
||||
ChargeToCustomer = true,
|
||||
ReimburseUser = true,
|
||||
@@ -3074,12 +3233,421 @@ namespace AyaNova.Util
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------- QUOTE --------------------------
|
||||
|
||||
private int TotalSeededQuotes = 0;
|
||||
//////////////////////////////////////////////////////
|
||||
//Quote
|
||||
//
|
||||
public async Task SeedQuoteAsync(ILogger log, int count)
|
||||
{
|
||||
DateTime seedStartWindow = DateTime.UtcNow.AddMonths(-9);
|
||||
DateTime seedEndWindow = DateTime.UtcNow.AddMonths(3);
|
||||
for (int x = 0; x < count; x++)
|
||||
{
|
||||
Quote o = new Quote();
|
||||
o.Notes = Fake.Lorem.Sentence();
|
||||
o.Tags = RandomTags();
|
||||
if (Fake.Random.Bool())//50% have projects
|
||||
o.ProjectId = Fake.Random.Long(1, TotalSeededProjects);
|
||||
var tempDate = Fake.Date.Between(seedStartWindow, seedEndWindow);
|
||||
var tempHour = Fake.Random.Int(9, 17);//9am to 5 pm (except some times may be in different dst state so this will be out by an hour for example depending on time of year and time zone in question)
|
||||
var woDate = DesiredTimeInUtc(new DateTime(tempDate.Year, tempDate.Month, tempDate.Day, tempHour, 0, 0));
|
||||
|
||||
o.CreatedDate = woDate > DateTime.UtcNow ? DateTime.UtcNow : woDate;//no created dates in future but want a range of past dates to show off age of wo
|
||||
// o.CompleteByDate = woDate.AddDays(5);
|
||||
// o.CustomerContactName = "contact name here";
|
||||
o.CustomerId = GetRandomCustomerId();//Fake.Random.Long(1, TotalSeededCustomers);
|
||||
|
||||
using (AyContext ct = ServiceProviderProvider.DBContext)
|
||||
{
|
||||
var cust = await ct.Customer.AsNoTracking().FirstAsync(z => z.Id == o.CustomerId);
|
||||
o.Latitude = cust.Latitude;
|
||||
o.Longitude = cust.Longitude;
|
||||
o.Address = cust.Address;
|
||||
o.City = cust.City;
|
||||
o.Region = cust.Region;
|
||||
o.Country = cust.Country;
|
||||
|
||||
|
||||
if (cust.BillHeadOffice && cust.HeadOfficeId != null)
|
||||
{
|
||||
var head = await ct.HeadOffice.AsNoTracking().FirstAsync(z => z.Id == cust.HeadOfficeId);
|
||||
o.PostAddress = head.PostAddress;
|
||||
o.PostCity = head.PostCity;
|
||||
o.PostRegion = head.PostRegion;
|
||||
o.PostCountry = head.PostCountry;
|
||||
o.PostCode = head.PostCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
o.PostAddress = cust.PostAddress;
|
||||
o.PostCity = cust.PostCity;
|
||||
o.PostRegion = cust.PostRegion;
|
||||
o.PostCountry = cust.PostCountry;
|
||||
o.PostCode = cust.PostCode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
o.CustomerReferenceNumber = "crf-" + Fake.Finance.Account(4);
|
||||
o.InternalReferenceNumber = "irf-" + Fake.Finance.Account(4);
|
||||
//o.ServiceDate = woDate;
|
||||
|
||||
int woItemCount = Fake.Random.Int(1, 4);
|
||||
for (int y = 0; y < woItemCount; y++)
|
||||
{
|
||||
var woItem = new QuoteItem()
|
||||
{
|
||||
Sequence = y + 1,
|
||||
Notes = $"itemnotes - {y} ",
|
||||
TechNotes = $"technotes - {y}",
|
||||
RequestDate = woDate.AddMinutes(y),
|
||||
WorkOrderItemPriorityId = Fake.Random.Long(1, 5),//there are 5 different sample priorities
|
||||
WorkOrderItemStatusId = Fake.Random.Long(1, 3)//there are 3 different sample woitem status
|
||||
};
|
||||
|
||||
//UNITS
|
||||
var woItemUnit = new QuoteItemUnit()
|
||||
{
|
||||
UnitId = GetRandomUnitForCustomer(o.CustomerId),
|
||||
Notes = Fake.Lorem.Sentence()
|
||||
};
|
||||
woItem.Units.Add(woItemUnit);
|
||||
|
||||
woItemUnit = new QuoteItemUnit()
|
||||
{
|
||||
UnitId = GetRandomUnitForCustomer(o.CustomerId),
|
||||
Notes = Fake.Lorem.Sentence()
|
||||
};
|
||||
woItem.Units.Add(woItemUnit);
|
||||
|
||||
//SCHEDULED USERS
|
||||
var woItemScheduledUser = new QuoteItemScheduledUser()
|
||||
{
|
||||
UserId = RandomServiceTechUserId(),
|
||||
EstimatedQuantity = 1,
|
||||
StartDate = woDate,
|
||||
StopDate = woDate.AddHours(1)
|
||||
};
|
||||
woItem.ScheduledUsers.Add(woItemScheduledUser);
|
||||
|
||||
|
||||
woItemScheduledUser = new QuoteItemScheduledUser()
|
||||
{
|
||||
UserId = RandomServiceTechUserId(),
|
||||
EstimatedQuantity = 2,
|
||||
StartDate = woDate,
|
||||
StopDate = woDate.AddHours(1)
|
||||
};
|
||||
woItem.ScheduledUsers.Add(woItemScheduledUser);
|
||||
|
||||
if (y == 1)
|
||||
{
|
||||
//known tech and subcontractor on every item
|
||||
woItemScheduledUser = new QuoteItemScheduledUser()
|
||||
{
|
||||
UserId = KnownUserTechId,
|
||||
EstimatedQuantity = 2,
|
||||
StartDate = woDate,
|
||||
StopDate = woDate.AddHours(2)
|
||||
};
|
||||
woItem.ScheduledUsers.Add(woItemScheduledUser);
|
||||
|
||||
woItemScheduledUser = new QuoteItemScheduledUser()
|
||||
{
|
||||
UserId = KnownUserSubContractorId,
|
||||
EstimatedQuantity = 2,
|
||||
StartDate = woDate,
|
||||
StopDate = woDate.AddHours(2)
|
||||
};
|
||||
woItem.ScheduledUsers.Add(woItemScheduledUser);
|
||||
}
|
||||
|
||||
if (y == 3)
|
||||
{
|
||||
//known restricted tech and subcontractor on some items
|
||||
woItemScheduledUser = new QuoteItemScheduledUser()
|
||||
{
|
||||
UserId = KnownUserTechRestrictedId,
|
||||
EstimatedQuantity = 2,
|
||||
StartDate = woDate,
|
||||
StopDate = woDate.AddHours(2)
|
||||
};
|
||||
woItem.ScheduledUsers.Add(woItemScheduledUser);
|
||||
|
||||
woItemScheduledUser = new QuoteItemScheduledUser()
|
||||
{
|
||||
UserId = KnownUserSubContractorRestrictedId,
|
||||
EstimatedQuantity = 2,
|
||||
StartDate = woDate,
|
||||
StopDate = woDate.AddHours(2)
|
||||
};
|
||||
woItem.ScheduledUsers.Add(woItemScheduledUser);
|
||||
}
|
||||
|
||||
//PARTS
|
||||
var woItemPart = new QuoteItemPart()
|
||||
{
|
||||
|
||||
Quantity = 1,
|
||||
PartId = Fake.Random.Long(1, TotalSeededParts),
|
||||
PartWarehouseId = 1
|
||||
};
|
||||
woItem.Parts.Add(woItemPart);
|
||||
|
||||
woItemPart = new QuoteItemPart()
|
||||
{
|
||||
|
||||
Quantity = 1,
|
||||
PartId = Fake.Random.Long(1, TotalSeededParts),
|
||||
PartWarehouseId = 1
|
||||
};
|
||||
woItem.Parts.Add(woItemPart);
|
||||
|
||||
|
||||
|
||||
//LOANERS
|
||||
var woItemLoan = new QuoteItemLoan()
|
||||
{
|
||||
OutDate = woDate.AddHours(1),
|
||||
DueDate = woDate.AddHours(4),
|
||||
Quantity = 4,
|
||||
Rate = LoanUnitRateUnit.Hours,
|
||||
LoanUnitId = Fake.Random.Long(1, TotalSeededLoanUnits)
|
||||
};
|
||||
woItem.Loans.Add(woItemLoan);
|
||||
|
||||
woItemLoan = new QuoteItemLoan()
|
||||
{
|
||||
OutDate = woDate.AddHours(2),
|
||||
DueDate = woDate.AddHours(3),
|
||||
Quantity = 1,
|
||||
Rate = LoanUnitRateUnit.Hours,
|
||||
LoanUnitId = Fake.Random.Long(1, TotalSeededLoanUnits)
|
||||
};
|
||||
woItem.Loans.Add(woItemLoan);
|
||||
|
||||
|
||||
//LABOR
|
||||
var techId = RandomServiceTechUserId();
|
||||
var woItemLabor = new QuoteItemLabor()
|
||||
{
|
||||
UserId = techId,
|
||||
ServiceRateQuantity = 1,
|
||||
ServiceStartDate = woDate,
|
||||
ServiceStopDate = woDate.AddHours(1),
|
||||
ServiceRateId = Fake.Random.Long(1, TotalSeededServiceRates),
|
||||
ServiceDetails = Fake.Lorem.Sentence()
|
||||
};
|
||||
woItem.Labors.Add(woItemLabor);
|
||||
|
||||
woItemLabor = new QuoteItemLabor()
|
||||
{
|
||||
UserId = RandomServiceTechUserId(),
|
||||
ServiceRateQuantity = 2,
|
||||
ServiceStartDate = woDate,
|
||||
ServiceStopDate = woDate.AddHours(1),
|
||||
ServiceRateId = Fake.Random.Long(1, TotalSeededServiceRates),
|
||||
ServiceDetails = Fake.Lorem.Sentence()
|
||||
};
|
||||
woItem.Labors.Add(woItemLabor);
|
||||
|
||||
|
||||
//TRAVEL
|
||||
var woItemTravel = new QuoteItemTravel()
|
||||
{
|
||||
UserId = techId,
|
||||
TravelRateQuantity = 1,
|
||||
TravelStartDate = woDate,
|
||||
TravelStopDate = woDate.AddHours(1),
|
||||
TravelRateId = Fake.Random.Long(1, TotalSeededTravelRates),
|
||||
TravelDetails = Fake.Lorem.Sentence(),
|
||||
Distance = Fake.Random.Decimal(1.0m, 20.0m)
|
||||
};
|
||||
woItem.Travels.Add(woItemTravel);
|
||||
|
||||
woItemTravel = new QuoteItemTravel()
|
||||
{
|
||||
UserId = RandomServiceTechUserId(),
|
||||
TravelRateQuantity = 2,
|
||||
TravelStartDate = woDate,
|
||||
TravelStopDate = woDate.AddHours(1),
|
||||
TravelRateId = Fake.Random.Long(1, TotalSeededTravelRates),
|
||||
TravelDetails = Fake.Lorem.Sentence(),
|
||||
Distance = Fake.Random.Decimal(1.0m, 20.0m)
|
||||
};
|
||||
woItem.Travels.Add(woItemTravel);
|
||||
|
||||
//TASKS
|
||||
var woItemTask = new QuoteItemTask()
|
||||
{
|
||||
CompletedByUserId = techId,
|
||||
Task = "Dis-assemble",
|
||||
Sequence = 1,
|
||||
Status = WorkorderItemTaskCompletionType.Incomplete
|
||||
};
|
||||
woItem.Tasks.Add(woItemTask);
|
||||
|
||||
woItemTask = new QuoteItemTask()
|
||||
{
|
||||
CompletedByUserId = techId,
|
||||
Task = "Lubricate",
|
||||
Sequence = 2,
|
||||
Status = WorkorderItemTaskCompletionType.Incomplete
|
||||
};
|
||||
woItem.Tasks.Add(woItemTask);
|
||||
|
||||
|
||||
woItemTask = new QuoteItemTask()
|
||||
{
|
||||
CompletedByUserId = techId,
|
||||
Task = "Repair",
|
||||
Sequence = 3,
|
||||
Status = WorkorderItemTaskCompletionType.Incomplete
|
||||
};
|
||||
woItem.Tasks.Add(woItemTask);
|
||||
|
||||
woItemTask = new QuoteItemTask()
|
||||
{
|
||||
CompletedByUserId = techId,
|
||||
Task = "Re-assemble",
|
||||
Sequence = 4,
|
||||
Status = WorkorderItemTaskCompletionType.Incomplete
|
||||
};
|
||||
woItem.Tasks.Add(woItemTask);
|
||||
|
||||
woItemTask = new QuoteItemTask()
|
||||
{
|
||||
CompletedByUserId = techId,
|
||||
Task = "Test and confirm repair",
|
||||
Sequence = 5,
|
||||
Status = WorkorderItemTaskCompletionType.Incomplete
|
||||
};
|
||||
woItem.Tasks.Add(woItemTask);
|
||||
|
||||
|
||||
|
||||
|
||||
//EXPENSES
|
||||
var cost = Fake.Random.Decimal(1, 10);
|
||||
var woItemExpense = new QuoteItemExpense()
|
||||
{
|
||||
UserId = RandomServiceTechUserId(),
|
||||
//TotalCost = cost,
|
||||
ChargeAmount = cost * 1.2m,
|
||||
ChargeToCustomer = true,
|
||||
ReimburseUser = true,
|
||||
ChargeTaxCodeId = TCGoods,
|
||||
Name = Fake.Commerce.ProductName()
|
||||
|
||||
};
|
||||
woItem.Expenses.Add(woItemExpense);
|
||||
|
||||
woItemExpense = new QuoteItemExpense()
|
||||
{
|
||||
UserId = RandomServiceTechUserId(),
|
||||
// TotalCost = cost * 2m,
|
||||
ChargeAmount = cost * 2.2m,
|
||||
ChargeToCustomer = true,
|
||||
ReimburseUser = true,
|
||||
ChargeTaxCodeId = TCGoods,
|
||||
Name = Fake.Commerce.ProductName()
|
||||
|
||||
};
|
||||
woItem.Expenses.Add(woItemExpense);
|
||||
|
||||
|
||||
//OUTSIDE SERVICES
|
||||
var ShippingCost = Fake.Random.Decimal(5, 20);
|
||||
var RepairCost = Fake.Random.Decimal(50, 1000);
|
||||
var woItemOutsideService = new QuoteItemOutsideService()
|
||||
{
|
||||
UnitId = GetRandomUnitForCustomer(o.CustomerId),
|
||||
Notes = Fake.Lorem.Sentence(),
|
||||
VendorSentToId = Fake.Random.Long(1, TotalSeededVendors),
|
||||
VendorSentViaId = Fake.Random.Long(1, TotalSeededVendors),
|
||||
RMANumber = "RMA" + Fake.Finance.Account(6),
|
||||
TrackingNumber = "TR" + Fake.Finance.Account(8),
|
||||
RepairCost = RepairCost,
|
||||
RepairPrice = RepairCost * 1.5m,
|
||||
ShippingCost = ShippingCost,
|
||||
ShippingPrice = ShippingCost * 1.5m,
|
||||
SentDate = woDate,
|
||||
ETADate = woDate.AddDays(7),
|
||||
ReturnDate = woDate.AddDays(8),
|
||||
TaxCodeId = 1
|
||||
};
|
||||
woItem.OutsideServices.Add(woItemOutsideService);
|
||||
|
||||
ShippingCost = Fake.Random.Decimal(5, 20);
|
||||
RepairCost = Fake.Random.Decimal(50, 1000);
|
||||
woItemOutsideService = new QuoteItemOutsideService()
|
||||
{
|
||||
UnitId = GetRandomUnitForCustomer(o.CustomerId),
|
||||
Notes = Fake.Lorem.Sentence(),
|
||||
VendorSentToId = Fake.Random.Long(1, TotalSeededVendors),
|
||||
VendorSentViaId = Fake.Random.Long(1, TotalSeededVendors),
|
||||
RMANumber = "RMA" + Fake.Finance.Account(6),
|
||||
TrackingNumber = "TR" + Fake.Finance.Account(8),
|
||||
RepairCost = RepairCost,
|
||||
RepairPrice = RepairCost * 1.5m,
|
||||
ShippingCost = ShippingCost,
|
||||
ShippingPrice = ShippingCost * 1.5m,
|
||||
SentDate = woDate,
|
||||
ETADate = woDate.AddDays(7),
|
||||
ReturnDate = woDate.AddDays(8),
|
||||
TaxCodeId = 1
|
||||
};
|
||||
woItem.OutsideServices.Add(woItemOutsideService);
|
||||
|
||||
o.Items.Add(woItem);
|
||||
}
|
||||
|
||||
//sample status changes
|
||||
{
|
||||
var WoState = new QuoteState()
|
||||
{
|
||||
QuoteStatusId = (long)SeedQuoteStatus.InProcess,
|
||||
UserId = RandomServiceTechUserId(),
|
||||
Created = woDate.AddMinutes(5)
|
||||
};
|
||||
o.States.Add(WoState);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//This seems wrong to do in a loop but is 4 times faster this way ?!?
|
||||
using (AyContext ct = ServiceProviderProvider.DBContext)
|
||||
{
|
||||
QuoteBiz biz = QuoteBiz.GetBiz(ct);
|
||||
var NewObject = await biz.QuoteCreateAsync(o, false);
|
||||
TotalSeededQuotes++;
|
||||
if (NewObject == null)
|
||||
{
|
||||
var err = $"Seeder::SeedQuote error creating {o.Serial}\r\n{biz.GetErrorsAsString()}";
|
||||
log.LogError(err);
|
||||
throw new System.Exception(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------- /quote ------------------------
|
||||
|
||||
|
||||
|
||||
private long GetRandomUnitForCustomer(long customerId)
|
||||
{
|
||||
var l = CustomerUnits.Where(x => x.Key == customerId).FirstOrDefault();//Fake.Random.Long(1, TotalSeededUnits);
|
||||
var numUnits = l.Value.Count();
|
||||
//because faker values are INCLUSIVE and this is going to be used as an index on an array need to -1 each end of the range
|
||||
var i = Fake.Random.Int(0, numUnits-1);
|
||||
var i = Fake.Random.Int(0, numUnits - 1);
|
||||
return l.Value[i];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user