This commit is contained in:
@@ -987,7 +987,6 @@ namespace AyaNova.Biz
|
|||||||
bool isNew = currentObj == null;
|
bool isNew = currentObj == null;
|
||||||
|
|
||||||
PM oProposed = (PM)proposedObj;
|
PM oProposed = (PM)proposedObj;
|
||||||
proposedObj.Name = oProposed.Serial.ToString();
|
|
||||||
|
|
||||||
//STANDARD EVENTS FOR ALL OBJECTS
|
//STANDARD EVENTS FOR ALL OBJECTS
|
||||||
await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct);//Note: will properly handle all delete events and event removal if deleted
|
await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct);//Note: will properly handle all delete events and event removal if deleted
|
||||||
|
|||||||
@@ -684,42 +684,6 @@ namespace AyaNova.Biz
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
todo: quote status list first, it's a table of created items, keep properties from v7 but add the following properties:
|
|
||||||
SelectRoles - who can select the status (still shows if they can't select but that's the current status, like active does)
|
|
||||||
This is best handled at the client. It prefetches all the status out of the normal picklist process, more like how other things are separately handled now without a picklist
|
|
||||||
client then knows if a status is available or not and can process to only present available ones
|
|
||||||
#### Server can use a biz rule to ensure that it can't be circumvented
|
|
||||||
UI defaults to any role
|
|
||||||
DeselectRoles - who can unset this status (important for process control)
|
|
||||||
UI defaults to any role
|
|
||||||
CompletedStatus bool - this is a final status indicating all work on the quote is completed, affects notification etc
|
|
||||||
UI defaults to false but when set to true auto sets lockworkorder to true (but user can just unset lockworkorder)
|
|
||||||
LockWorkorder - this status is considered read only and the quote is locked
|
|
||||||
Just a read only thing, can just change status to "unlock" it
|
|
||||||
to support states where no one should work on a wo for whatever reason but it's not necessarily completed
|
|
||||||
e.g. "Hold for inspection", "On hold" generally etc
|
|
||||||
*/
|
|
||||||
// //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.Quote.AnyAsync(z => z.Name == proposedObj.Name && z.Id != proposedObj.Id))
|
|
||||||
// {
|
|
||||||
// AddError(ApiErrorCode.VALIDATION_NOT_UNIQUE, "Name");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
//Any form customizations to validate?
|
//Any form customizations to validate?
|
||||||
var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.Quote.ToString());
|
var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.Quote.ToString());
|
||||||
if (FormCustomization != null)
|
if (FormCustomization != null)
|
||||||
@@ -732,11 +696,9 @@ namespace AyaNova.Biz
|
|||||||
//validate custom fields
|
//validate custom fields
|
||||||
CustomFieldsValidator.Validate(this, FormCustomization, proposedObj.CustomFields);
|
CustomFieldsValidator.Validate(this, FormCustomization, proposedObj.CustomFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private async Task QuoteValidateCanDelete(Quote dbObject)
|
private async Task QuoteValidateCanDelete(Quote dbObject)
|
||||||
{
|
{
|
||||||
//Check restricted role preventing create
|
//Check restricted role preventing create
|
||||||
@@ -747,35 +709,9 @@ namespace AyaNova.Biz
|
|||||||
}
|
}
|
||||||
if (await ct.WorkOrder.AnyAsync(m => m.FromQuoteId == dbObject.Id))
|
if (await ct.WorkOrder.AnyAsync(m => m.FromQuoteId == dbObject.Id))
|
||||||
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("Quote"));
|
AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("Quote"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//############### NOTIFICATION TODO
|
|
||||||
/*
|
|
||||||
|
|
||||||
todo: quote notifications remove #30 and #32 as redundant
|
|
||||||
WorkorderStatusChange = 4,//* Workorder object, any *change* of status including from no status (new) to a specific conditional status ID value
|
|
||||||
|
|
||||||
WorkorderStatusAge = 24,//* Workorder object Created / Updated, conditional on exact status selected IdValue, Tags conditional, advance notice can be set
|
|
||||||
|
|
||||||
//THESE TWO ARE REDUNDANT:
|
|
||||||
|
|
||||||
this is actually workorderstatuschange because can just pick any status under workorderstatuschange to be notified about
|
|
||||||
WorkorderCompleted = 30, //*travel work order is set to any status that is flagged as a "Completed" type of status. Customer & User
|
|
||||||
|
|
||||||
//This one could be accomplished with WorkorderStatusAge, just pick a Completed status and set a time frame and wala!
|
|
||||||
WorkorderCompletedFollowUp = 32, //* travel quote closed status follow up again after this many TIMESPAN
|
|
||||||
|
|
||||||
todo: CHANGE WorkorderCompletedStatusOverdue = 15,//* Workorder object not set to a "Completed" flagged quote status type in selected time span from creation of quote
|
|
||||||
Change this to a new type that is based on so many days *without* being set to a particular status
|
|
||||||
but first check if tied to contract response time stuff, how that's handled
|
|
||||||
that's closeby date in v7 but isn't that deprecated now without a "close"?
|
|
||||||
maybe I do need the Completed status bool thing above
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// GET PARTIAL WORKORDER FOR REPORTING
|
// GET PARTIAL WORKORDER FOR REPORTING
|
||||||
// (returns quote consisting only of the path from child or grandchild up to header populated
|
// (returns quote consisting only of the path from child or grandchild up to header populated
|
||||||
@@ -883,64 +819,6 @@ namespace AyaNova.Biz
|
|||||||
foreach (long batchId in batch)
|
foreach (long batchId in batch)
|
||||||
batchResults.Add(await QuoteGetPartialAsync(dataListSelectedRequest.AType, batchId, dataListSelectedRequest.IncludeWoItemDescendants, true));
|
batchResults.Add(await QuoteGetPartialAsync(dataListSelectedRequest.AType, batchId, dataListSelectedRequest.IncludeWoItemDescendants, true));
|
||||||
|
|
||||||
#region unnecessary shit removed
|
|
||||||
//This is unnecessary because the re-ordering bit is only needed when the records are fetched in batches directly from the sql server as they
|
|
||||||
//return in db natural order and need to be put back into the same order as the ID List
|
|
||||||
//Here in the quote however, this code is fetching individually one at a time so they are always going to be in the correct order so this re-ordering is unnecessary
|
|
||||||
//I'm keeping this here for future reference when I ineveitably wonder what the hell is happening here :)
|
|
||||||
|
|
||||||
|
|
||||||
//order the results back into original
|
|
||||||
//IEnumerable<Quote> orderedList = null;
|
|
||||||
|
|
||||||
//TODO: WHAT IS THIS BATCH RESULT ORDERING CODE REALLY DOING AND CAN IT BE REMOVED / CHANGED????
|
|
||||||
//isn't it alredy working in order? If not maybe simply reversed so reverse it again before querying above or...??
|
|
||||||
|
|
||||||
//todo: can't assume the grandchild item is index 0 anymore as we might have multiple of them if includedescendants is true
|
|
||||||
//so need to find index first then do this
|
|
||||||
// switch (dataListSelectedRequest.AType)
|
|
||||||
// {
|
|
||||||
// case AyaType.Quote:
|
|
||||||
// orderedList = from id in batch join z in batchResults on id equals z.Id select z;
|
|
||||||
// break;
|
|
||||||
// case AyaType.QuoteItem:
|
|
||||||
// orderedList = from id in batch join z in batchResults on id equals z.Items[0].Id select z;
|
|
||||||
// break;
|
|
||||||
// case AyaType.QuoteItemExpense:
|
|
||||||
// orderedList = from id in batch join z in batchResults on id equals z.Items[0].Expenses[0].Id select z;
|
|
||||||
// break;
|
|
||||||
// case AyaType.QuoteItemLabor:
|
|
||||||
// orderedList = from id in batch join z in batchResults on id equals z.Items[0].Labors[0].Id select z;
|
|
||||||
// break;
|
|
||||||
// case AyaType.QuoteItemLoan:
|
|
||||||
// orderedList = from id in batch join z in batchResults on id equals z.Items[0].Loans[0].Id select z;
|
|
||||||
// break;
|
|
||||||
// case AyaType.QuoteItemPart:
|
|
||||||
// orderedList = from id in batch join z in batchResults on id equals z.Items[0].Parts[0].Id select z;
|
|
||||||
// break;
|
|
||||||
// case AyaType.QuoteItemPartRequest:
|
|
||||||
// orderedList = from id in batch join z in batchResults on id equals z.Items[0].PartRequests[0].Id select z;
|
|
||||||
// break;
|
|
||||||
// case AyaType.QuoteItemScheduledUser:
|
|
||||||
// orderedList = from id in batch join z in batchResults on id equals z.Items[0].ScheduledUsers[0].Id select z;
|
|
||||||
// break;
|
|
||||||
// case AyaType.QuoteItemTask:
|
|
||||||
// orderedList = from id in batch join z in batchResults on id equals z.Items[0].Tasks[0].Id select z;
|
|
||||||
// break;
|
|
||||||
// case AyaType.QuoteItemTravel:
|
|
||||||
// orderedList = from id in batch join z in batchResults on id equals z.Items[0].Travels[0].Id select z;
|
|
||||||
// break;
|
|
||||||
// case AyaType.QuoteItemOutsideService:
|
|
||||||
// orderedList = from id in batch join z in batchResults on id equals z.Items[0].OutsideServices[0].Id select z;
|
|
||||||
// break;
|
|
||||||
// case AyaType.QuoteItemUnit:
|
|
||||||
// orderedList = from id in batch join z in batchResults on id equals z.Items[0].Units[0].Id select z;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
|
|
||||||
//foreach (Quote w in orderedList)
|
|
||||||
#endregion unnecessary shit
|
|
||||||
|
|
||||||
foreach (Quote w in batchResults)
|
foreach (Quote w in batchResults)
|
||||||
{
|
{
|
||||||
var jo = JObject.FromObject(w);
|
var jo = JObject.FromObject(w);
|
||||||
@@ -1159,7 +1037,7 @@ namespace AyaNova.Biz
|
|||||||
bool isNew = currentObj == null;
|
bool isNew = currentObj == null;
|
||||||
|
|
||||||
Quote oProposed = (Quote)proposedObj;
|
Quote oProposed = (Quote)proposedObj;
|
||||||
proposedObj.Name = oProposed.Serial.ToString();
|
|
||||||
|
|
||||||
//STANDARD EVENTS FOR ALL OBJECTS
|
//STANDARD EVENTS FOR ALL OBJECTS
|
||||||
await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct);//Note: will properly handle all delete events and event removal if deleted
|
await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct);//Note: will properly handle all delete events and event removal if deleted
|
||||||
|
|||||||
@@ -1267,7 +1267,7 @@ namespace AyaNova.Biz
|
|||||||
bool isNew = currentObj == null;
|
bool isNew = currentObj == null;
|
||||||
|
|
||||||
WorkOrder oProposed = (WorkOrder)proposedObj;
|
WorkOrder oProposed = (WorkOrder)proposedObj;
|
||||||
proposedObj.Name = oProposed.Serial.ToString();
|
|
||||||
|
|
||||||
//STANDARD EVENTS FOR ALL OBJECTS
|
//STANDARD EVENTS FOR ALL OBJECTS
|
||||||
await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct);//Note: will properly handle all delete events and event removal if deleted
|
await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct);//Note: will properly handle all delete events and event removal if deleted
|
||||||
@@ -4878,6 +4878,7 @@ namespace AyaNova.Biz
|
|||||||
var wid = await GetWorkOrderIdFromRelativeAsync(AyaType.WorkOrderItem, oProposed.WorkOrderItemId, ct);
|
var wid = await GetWorkOrderIdFromRelativeAsync(AyaType.WorkOrderItem, oProposed.WorkOrderItemId, ct);
|
||||||
var WorkorderInfo = await ct.WorkOrder.AsNoTracking().Where(x => x.Id == wid.ParentId).Select(x => new { Serial = x.Serial, Tags = x.Tags }).FirstOrDefaultAsync();
|
var WorkorderInfo = await ct.WorkOrder.AsNoTracking().Where(x => x.Id == wid.ParentId).Select(x => new { Serial = x.Serial, Tags = x.Tags }).FirstOrDefaultAsync();
|
||||||
proposedObj.Tags = WorkorderInfo.Tags;
|
proposedObj.Tags = WorkorderInfo.Tags;
|
||||||
|
|
||||||
proposedObj.Name = WorkorderInfo.Serial.ToString();
|
proposedObj.Name = WorkorderInfo.Serial.ToString();
|
||||||
|
|
||||||
//STANDARD EVENTS FOR ALL OBJECTS
|
//STANDARD EVENTS FOR ALL OBJECTS
|
||||||
|
|||||||
@@ -116,9 +116,16 @@ namespace AyaNova.Models
|
|||||||
[NotMapped, JsonIgnore]
|
[NotMapped, JsonIgnore]
|
||||||
public AyaType AyaType { get => AyaType.PM; }
|
public AyaType AyaType { get => AyaType.PM; }
|
||||||
|
|
||||||
//workaround for notification
|
//workaround for notification
|
||||||
[NotMapped, JsonIgnore]
|
[NotMapped, JsonIgnore]
|
||||||
public string Name { get; set; }
|
public string Name
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.Serial.ToString();
|
||||||
|
}
|
||||||
|
set => throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}//eoc
|
}//eoc
|
||||||
|
|||||||
@@ -110,9 +110,16 @@ namespace AyaNova.Models
|
|||||||
[NotMapped, JsonIgnore]
|
[NotMapped, JsonIgnore]
|
||||||
public AyaType AyaType { get => AyaType.Quote; }
|
public AyaType AyaType { get => AyaType.Quote; }
|
||||||
|
|
||||||
//workaround for notification
|
//workaround for notification
|
||||||
[NotMapped, JsonIgnore]
|
[NotMapped, JsonIgnore]
|
||||||
public string Name { get; set; }
|
public string Name
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.Serial.ToString();
|
||||||
|
}
|
||||||
|
set => throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}//eoc
|
}//eoc
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ namespace AyaNova.Models
|
|||||||
public bool UserCanViewLoanerCosts { get; set; }
|
public bool UserCanViewLoanerCosts { get; set; }
|
||||||
|
|
||||||
|
|
||||||
[NotMapped,JsonProperty(NullValueHandling=NullValueHandling.Ignore)]
|
[NotMapped, JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public AyaTypeId GenCopyAttachmentsFrom { get; set; }//INTERNAL, USED TO SIGNIFY ATTACHMENTS NEED TO BE COPIED ON SAVE
|
public AyaTypeId GenCopyAttachmentsFrom { get; set; }//INTERNAL, USED TO SIGNIFY ATTACHMENTS NEED TO BE COPIED ON SAVE
|
||||||
|
|
||||||
[NotMapped, JsonIgnore]
|
[NotMapped, JsonIgnore]
|
||||||
@@ -124,7 +124,14 @@ namespace AyaNova.Models
|
|||||||
|
|
||||||
//workaround for notification
|
//workaround for notification
|
||||||
[NotMapped, JsonIgnore]
|
[NotMapped, JsonIgnore]
|
||||||
public string Name { get; set; }
|
public string Name
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.Serial.ToString();
|
||||||
|
}
|
||||||
|
set => throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}//eoc
|
}//eoc
|
||||||
|
|||||||
Reference in New Issue
Block a user