This commit is contained in:
@@ -67,6 +67,9 @@ namespace AyaNova.Api.Controllers
|
||||
WorkOrderBiz biz = WorkOrderBiz.GetBiz(ct, HttpContext);
|
||||
if (!Authorized.HasCreateRole(HttpContext.Items, biz.BizType))
|
||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
||||
if (newObject.Items.Count > 0)
|
||||
return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, "generalerror", "Work order POST route accepts header only; POST Work order descendants separately"));
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(new ApiErrorResponse(ModelState));
|
||||
WorkOrder o = await biz.WorkOrderCreateAsync(newObject);
|
||||
@@ -127,7 +130,7 @@ namespace AyaNova.Api.Controllers
|
||||
/// Update WorkOrder
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="updatedObject">WorkOrder - top level only, no descendants</param>
|
||||
/// <param name="updatedObject">WorkOrder - top level only, no Items or other descendants</param>
|
||||
/// <returns>Updated work order header</returns>
|
||||
[HttpPut]
|
||||
public async Task<IActionResult> PutWorkOrder([FromBody] WorkOrder updatedObject)
|
||||
|
||||
@@ -10,10 +10,11 @@ namespace AyaNova.Biz
|
||||
{
|
||||
//see core-notifications.txt spec doc for a bit more info on each type (they are named a little bit differently)
|
||||
//#### NOTE: once event is NOTED IN COMMENT (not necessarily coded yet as some can't be yet) in NotifyEventProcessor I'll mark it with a * in the comment so I know if I miss any
|
||||
//#### NOTE: once event is fully coded I'll mark it with CODED at the start of the comment line
|
||||
ObjectDeleted = 1,//* Deletion of any object of conditional specific AyaType and optionally conditional tags
|
||||
ObjectCreated = 2,//* creation of any object of conditional specific AyaType and optionally conditional tags
|
||||
ObjectModified = 3,//* Modification / update of any kind of any object of conditional specific AyaType and optionally conditional tags
|
||||
WorkorderStatusChange = 4,//* Workorder object, any *change* of status including from no status (new) to a specific conditional status ID value
|
||||
WorkorderStatusChange = 4,//* Workorder object, any NEW status set. Conditions: specific status ID value, Workorder TAGS
|
||||
ContractExpiring = 5,//* Contract object, aged notification with optional advance notice for expiration date of contract. Customer version and User version deliveries possible.
|
||||
CSRAccepted = 6,//*CustomerServiceRequest object, saved with ACCEPTED status, delivered to Customer only
|
||||
CSRRejected = 7,//*CustomerServiceRequest object, saved with REJECTED status, delivered to Customer only
|
||||
|
||||
@@ -77,9 +77,9 @@ namespace AyaNova.Biz
|
||||
await WorkOrderSearchIndexAsync(newObject, true);
|
||||
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null);
|
||||
|
||||
//Was this a full workorder posted all at once?
|
||||
//(seeder or api user, not something AyaNova front end would do)
|
||||
if (newObject.Items.Count > 0)//our front end will post the header alone on new so this indicates a fully populated wo was saved
|
||||
//# NOTE: only internal code can post an entire workorder graph, no external user can as controller will reject right up front
|
||||
//however, internally seeder will post entire workorders
|
||||
if (newObject.Items.Count > 0)
|
||||
{
|
||||
await GetCurrentContractFromContractIdAsync(newObject.ContractId);
|
||||
|
||||
@@ -111,6 +111,8 @@ namespace AyaNova.Biz
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//NOTE: not running individual notification here for children, seeder won't require it and that's all that posts an entire wo currently
|
||||
}
|
||||
await transaction.CommitAsync();
|
||||
if (populateViz)
|
||||
@@ -985,6 +987,14 @@ namespace AyaNova.Biz
|
||||
|
||||
//SPECIFIC EVENTS FOR THIS OBJECT
|
||||
|
||||
if (ayaEvent == AyaEvent.Deleted)
|
||||
{
|
||||
//remove any potential time delayed STATUS notifications for OVERDUE NOT CLOSED STATUS
|
||||
//NOTE: if the workorder is deleted the above process standard etc will automatically
|
||||
//remove *ALL* events created for this workorder so no need to remove overdue or any wo related time delayed status here
|
||||
|
||||
}
|
||||
|
||||
//todo: contract response time notification
|
||||
|
||||
}//end of process notifications
|
||||
@@ -1029,6 +1039,7 @@ namespace AyaNova.Biz
|
||||
await ct.WorkOrderState.AddAsync(newObject);
|
||||
await ct.SaveChangesAsync();
|
||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderStatus, AyaEvent.Created), ct);
|
||||
await StateHandlePotentialNotificationEvent(AyaEvent.Created, newObject);
|
||||
return newObject;
|
||||
}
|
||||
}
|
||||
@@ -1074,9 +1085,12 @@ namespace AyaNova.Biz
|
||||
|
||||
foreach (var wostate in stateList)
|
||||
{
|
||||
await StateHandlePotentialNotificationEvent(AyaEvent.Deleted, wostate);
|
||||
ct.WorkOrderState.Remove(wostate);
|
||||
await ct.SaveChangesAsync();
|
||||
//no need to call this because it's only going to run this method if the workorder is deleted and
|
||||
//via process standard notifciation events for workorder deletion will remove any state delayed notifications anyway so
|
||||
//nothing to call or do here related to notification
|
||||
// await StateHandlePotentialNotificationEvent(AyaEvent.Deleted, wostate);
|
||||
}
|
||||
}
|
||||
catch
|
||||
@@ -1139,24 +1153,89 @@ namespace AyaNova.Biz
|
||||
|
||||
|
||||
//STANDARD EVENTS FOR ALL OBJECTS
|
||||
await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct);
|
||||
//NONE: state notifications are specific and not the same as for general objects so don't process standard events
|
||||
|
||||
//SPECIFIC EVENTS FOR THIS OBJECT
|
||||
//WorkorderStatusChange = 4,//* Workorder object, any *change* of status including from no status (new) to a specific conditional status ID value
|
||||
//WorkorderFinishStatusOverdue = 15,//* Workorder object not set to a "Finished" flagged workorder status type in selected time span from creation of workorderWorkorderSetToFinishedStatus
|
||||
//WorkorderStatusAge = 24,//* Workorder object Created / Updated, conditional on exact status selected IdValue, Tags conditional, advance notice can be set
|
||||
|
||||
WorkOrderState o = (WorkOrderState)proposedObj;
|
||||
WorkOrder wo = await ct.WorkOrder.AsNoTracking().FirstOrDefaultAsync(x => x.Id == o.WorkOrderId);
|
||||
|
||||
//## DELETED EVENTS
|
||||
//any event added below needs to be removed, so
|
||||
//just blanket remove any event for this object of eventtype that would be added below here
|
||||
//do it regardless any time there's an update and then
|
||||
//let this code below handle the refreshing addition that could have changes
|
||||
// await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, o.Id, NotifyEventType.ContractExpiring);
|
||||
//A state cannot be deleted so nothing to handle that is required
|
||||
//a workorder CAN be deleted and it will automatically remove all events for it so also no need to remove time delayed status events either if wo is deleted.
|
||||
//so in essence there is nothing to be done regarding deleted events with states
|
||||
|
||||
//NO, the above is not correct, time delayed ones should NOT be removed for example finished until appropriate or if wo deleted
|
||||
//so there should be a deleted event here handled with delete of all notifications sitting and the blanket remove below should be more surgical
|
||||
//and only apply to stuff that it is approriate to remove
|
||||
|
||||
//#NOTE: state can be deleted so this block will handle that
|
||||
await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, o.Id, NotifyEventType.WorkorderStatusChange);
|
||||
await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, o.Id, NotifyEventType.WorkorderFinishStatusOverdue);
|
||||
await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, o.Id, NotifyEventType.WorkorderStatusAge);
|
||||
|
||||
|
||||
//## CREATED / MODIFIED EVENTS
|
||||
if (ayaEvent == AyaEvent.Created || ayaEvent == AyaEvent.Modified)
|
||||
//## CREATED (this is the only possible notification CREATION ayaEvent type for a workorder state as they are create only)
|
||||
if (ayaEvent == AyaEvent.Created)
|
||||
{
|
||||
|
||||
//todo: fix etc, tons of shit here incoming
|
||||
//# STATUS CHANGE (create new status)
|
||||
{
|
||||
var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.WorkorderStatusChange).ToListAsync();
|
||||
foreach (var sub in subs)
|
||||
{
|
||||
//not for inactive users
|
||||
if (!await UserBiz.UserIsActive(sub.UserId)) continue;
|
||||
|
||||
//Tag match? (will be true if no sub tags so always safe to call this)
|
||||
if (NotifyEventHelper.TagsMatch(wo.Tags, sub.Tags))
|
||||
{
|
||||
NotifyEvent n = new NotifyEvent()
|
||||
{
|
||||
EventType = NotifyEventType.WorkorderStatusChange,
|
||||
UserId = sub.UserId,
|
||||
AyaType = o.AyaType,
|
||||
ObjectId = o.Id,
|
||||
NotifySubscriptionId = sub.Id,
|
||||
Name = wo.Serial.ToString()
|
||||
};
|
||||
await ct.NotifyEvent.AddAsync(n);
|
||||
log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]");
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}//workorder status change event
|
||||
|
||||
|
||||
//# WorkorderFinishStatusOverdue
|
||||
{//* Workorder object not set to a "Finished" flagged workorder status type in selected time span from creation of workorderWorkorderSetToFinishedStatus
|
||||
var subs = await ct.NotifySubscription.Where(z => z.EventType == NotifyEventType.WorkorderStatusChange).ToListAsync();
|
||||
foreach (var sub in subs)
|
||||
{
|
||||
//not for inactive users
|
||||
if (!await UserBiz.UserIsActive(sub.UserId)) continue;
|
||||
|
||||
//Tag match? (will be true if no sub tags so always safe to call this)
|
||||
if (NotifyEventHelper.TagsMatch(wo.Tags, sub.Tags))
|
||||
{
|
||||
NotifyEvent n = new NotifyEvent()
|
||||
{
|
||||
EventType = NotifyEventType.WorkorderStatusChange,
|
||||
UserId = sub.UserId,
|
||||
AyaType = o.AyaType,
|
||||
ObjectId = o.Id,
|
||||
NotifySubscriptionId = sub.Id,
|
||||
Name = wo.Serial.ToString()
|
||||
};
|
||||
await ct.NotifyEvent.AddAsync(n);
|
||||
log.LogDebug($"Adding NotifyEvent: [{n.ToString()}]");
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}//workorder finish change event
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -23,16 +23,12 @@ namespace AyaNova.Biz
|
||||
|
||||
|
||||
private static DateTime lastRun = DateTime.MinValue;
|
||||
// private static TimeSpan DELETE_AFTER_AGE = new TimeSpan(90, 0, 0, 0);
|
||||
// private static TimeSpan RUN_EVERY_INTERVAL = new TimeSpan(0, 2, 0);//once every 2 minutes minimum
|
||||
private static DateTime lastNotifyHealthCheckSentLocal = DateTime.MinValue;
|
||||
private static TimeSpan TS_24_HOURS = new TimeSpan(24, 0, 0);//used to ensure daily ops happen no more than that
|
||||
|
||||
#if (DEBUG)
|
||||
private static TimeSpan DELETE_AFTER_AGE = new TimeSpan(0, 12, 0, 0);
|
||||
#if (DEBUG)
|
||||
private static TimeSpan RUN_EVERY_INTERVAL = new TimeSpan(0, 0, 20);//no more frequently than once every 20 seconds
|
||||
#else
|
||||
private static TimeSpan DELETE_AFTER_AGE = new TimeSpan(90, 0, 0, 0);
|
||||
#else
|
||||
private static TimeSpan RUN_EVERY_INTERVAL = new TimeSpan(0, 2, 0);//no more frequently than once every 2 minutes
|
||||
#endif
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace AyaNova.Generator
|
||||
/*
|
||||
todo: improve this
|
||||
it should timeout: https://stackoverflow.com/questions/23476576/cancellationtoken-timeout-vs-task-delay-and-timeout
|
||||
it should never stop running no matter what unless teh server shuts down
|
||||
it should never stop running no matter what unless the server shuts down
|
||||
*/
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
|
||||
@@ -107,7 +107,7 @@ CREATE TABLE [dbo].[APARTBYWAREHOUSEINVENTORY](
|
||||
[APARTID] [uniqueidentifier] NOT NULL,
|
||||
[APARTWAREHOUSEID] [uniqueidentifier] NOT NULL,
|
||||
[AQUANTITYONHAND] [decimal](19, 5) NOT NULL,
|
||||
[AQUANTITYONORDER] [decimal](19, 5) NOT NULL,//calculated on teh fly from active PO's
|
||||
[AQUANTITYONORDER] [decimal](19, 5) NOT NULL,//calculated on the fly from active PO's
|
||||
[AMINSTOCKLEVEL] [decimal](19, 5) NOT NULL,//New table / feature PartRestock (partid/warhouseid/stocklevel)
|
||||
[AQTYONORDERCOMMITTED] [decimal](19, 5) NOT NULL, //Calculated on the fly from po and partrequests
|
||||
*/
|
||||
@@ -66,7 +66,7 @@ namespace AyaNova.Core
|
||||
//Current license key, can be empty
|
||||
private static AyaNovaLicenseKey _ActiveLicense = new AyaNovaLicenseKey();
|
||||
|
||||
//The license dbid, separate from teh server dbid
|
||||
//The license dbid, separate from the server dbid
|
||||
private static string LicenseDbId { get; set; }
|
||||
|
||||
#region license classes
|
||||
|
||||
Reference in New Issue
Block a user