This commit is contained in:
2021-07-26 15:40:06 +00:00
parent f514211b7c
commit 6bcee0dd88
2 changed files with 791 additions and 3 deletions

View 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

View File

@@ -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];
}