This commit is contained in:
@@ -206,6 +206,9 @@ namespace AyaNova.Biz
|
|||||||
await CoreJobNotify.DoWorkAsync();
|
await CoreJobNotify.DoWorkAsync();
|
||||||
await CoreNotificationSweeper.DoWorkAsync();
|
await CoreNotificationSweeper.DoWorkAsync();
|
||||||
|
|
||||||
|
//PM GENERATION
|
||||||
|
await CoreJobPMGenerate.DoWorkAsync();
|
||||||
|
|
||||||
//JOB SWEEPER / AND USER COUNT CHECK
|
//JOB SWEEPER / AND USER COUNT CHECK
|
||||||
await CoreJobSweeper.DoWorkAsync();
|
await CoreJobSweeper.DoWorkAsync();
|
||||||
|
|
||||||
|
|||||||
@@ -13,488 +13,488 @@ using System.Collections.Generic;
|
|||||||
namespace AyaNova.Biz
|
namespace AyaNova.Biz
|
||||||
{
|
{
|
||||||
|
|
||||||
#region v7 code for Generate service workorder from PM
|
#region v7 code for Generate service workorder from PM
|
||||||
/* /// <summary>
|
/* /// <summary>
|
||||||
/// Generates a service workorder from a PM type Workorder
|
/// Generates a service workorder from a PM type Workorder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="SourceWorkorderID">ID of PM</param>
|
/// <param name="SourceWorkorderID">ID of PM</param>
|
||||||
/// <returns>A new service workorder</returns>
|
/// <returns>A new service workorder</returns>
|
||||||
public static Workorder NewServiceWorkorderFromPM(Guid SourceWorkorderID)
|
public static Workorder NewServiceWorkorderFromPM(Guid SourceWorkorderID)
|
||||||
{
|
{
|
||||||
//Fetch the source workorder and verify it's a PM
|
//Fetch the source workorder and verify it's a PM
|
||||||
Workorder source = Workorder.GetItemNoMRU(SourceWorkorderID);
|
Workorder source = Workorder.GetItemNoMRU(SourceWorkorderID);
|
||||||
if (source.WorkorderType != WorkorderTypes.PreventiveMaintenance)
|
if (source.WorkorderType != WorkorderTypes.PreventiveMaintenance)
|
||||||
throw new NotSupportedException(LocalizedTextTable.GetLocalizedTextDirect("Workorder.Label.Error.SourceInvalidType"));
|
throw new NotSupportedException(LocalizedTextTable.GetLocalizedTextDirect("Workorder.Label.Error.SourceInvalidType"));
|
||||||
|
|
||||||
//if it's inactive then there is nothing to Process
|
//if it's inactive then there is nothing to Process
|
||||||
//this is a backstop, the list the pm is being generated off of
|
//this is a backstop, the list the pm is being generated off of
|
||||||
//should have already selected only active items that have not reached their
|
//should have already selected only active items that have not reached their
|
||||||
//expiry date
|
//expiry date
|
||||||
if (source.WorkorderPreventiveMaintenance.Active == false)
|
if (source.WorkorderPreventiveMaintenance.Active == false)
|
||||||
{
|
{
|
||||||
throw new System.ApplicationException("NewServiceWorkorderFromPM: source PM workorder is not active");
|
throw new System.ApplicationException("NewServiceWorkorderFromPM: source PM workorder is not active");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source.WorkorderPreventiveMaintenance.StopGeneratingDate != System.DBNull.Value &&
|
if (source.WorkorderPreventiveMaintenance.StopGeneratingDate != System.DBNull.Value &&
|
||||||
source.WorkorderPreventiveMaintenance.dtStopGeneratingDate < DBUtil.CurrentWorkingDateTime)
|
source.WorkorderPreventiveMaintenance.dtStopGeneratingDate < DBUtil.CurrentWorkingDateTime)
|
||||||
{
|
{
|
||||||
throw new System.ApplicationException("NewServiceWorkorderFromPM: source PM workorder is past StopGeneratingDate");
|
throw new System.ApplicationException("NewServiceWorkorderFromPM: source PM workorder is past StopGeneratingDate");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Ok, so far so good, create the new one
|
//Ok, so far so good, create the new one
|
||||||
bool bUseInventory = AyaBizUtils.GlobalSettings.UseInventory;
|
bool bUseInventory = AyaBizUtils.GlobalSettings.UseInventory;
|
||||||
|
|
||||||
//case 1387
|
//case 1387
|
||||||
Workorder dest = Workorder.NewItem(WorkorderTypes.Service);
|
Workorder dest = Workorder.NewItem(WorkorderTypes.Service);
|
||||||
|
|
||||||
////NOTE: THIS DOESN'T CALL THE SHARED NEW ITEM METHOD
|
////NOTE: THIS DOESN'T CALL THE SHARED NEW ITEM METHOD
|
||||||
//Workorder dest = new Workorder();
|
//Workorder dest = new Workorder();
|
||||||
//dest.WorkorderType=WorkorderTypes.Service;
|
//dest.WorkorderType=WorkorderTypes.Service;
|
||||||
//dest.mService=WorkorderService.NewItem(dest);
|
//dest.mService=WorkorderService.NewItem(dest);
|
||||||
|
|
||||||
#region copy workorder data
|
#region copy workorder data
|
||||||
|
|
||||||
//WORKORDER HEADER
|
//WORKORDER HEADER
|
||||||
dest.ClientID = source.ClientID;
|
dest.ClientID = source.ClientID;
|
||||||
dest.CustomerContactName = source.CustomerContactName;
|
dest.CustomerContactName = source.CustomerContactName;
|
||||||
dest.CustomerReferenceNumber = source.CustomerReferenceNumber;
|
dest.CustomerReferenceNumber = source.CustomerReferenceNumber;
|
||||||
dest.mFromPMID = source.WorkorderPreventiveMaintenance.ID;
|
dest.mFromPMID = source.WorkorderPreventiveMaintenance.ID;
|
||||||
dest.InternalReferenceNumber = source.InternalReferenceNumber;
|
dest.InternalReferenceNumber = source.InternalReferenceNumber;
|
||||||
dest.Onsite = source.Onsite;
|
dest.Onsite = source.Onsite;
|
||||||
dest.ProjectID = source.ProjectID;
|
dest.ProjectID = source.ProjectID;
|
||||||
//dest.RegionID=source.RegionID;
|
//dest.RegionID=source.RegionID;
|
||||||
dest.Summary = source.Summary;
|
dest.Summary = source.Summary;
|
||||||
dest.WorkorderCategoryID = source.WorkorderCategoryID;
|
dest.WorkorderCategoryID = source.WorkorderCategoryID;
|
||||||
|
|
||||||
//PM SPECIFIC
|
//PM SPECIFIC
|
||||||
dest.WorkorderService.WorkorderStatusID = source.WorkorderPreventiveMaintenance.WorkorderStatusID;
|
dest.WorkorderService.WorkorderStatusID = source.WorkorderPreventiveMaintenance.WorkorderStatusID;
|
||||||
//Date stuff (note that date is assumed to have been advanced the last time a workorder was
|
//Date stuff (note that date is assumed to have been advanced the last time a workorder was
|
||||||
//generated off the pm (see bottom of this method for that))
|
//generated off the pm (see bottom of this method for that))
|
||||||
dest.WorkorderService.ServiceDate = source.WorkorderPreventiveMaintenance.NextServiceDate;
|
dest.WorkorderService.ServiceDate = source.WorkorderPreventiveMaintenance.NextServiceDate;
|
||||||
|
|
||||||
|
|
||||||
//WORKORDERITEMS
|
//WORKORDERITEMS
|
||||||
foreach (WorkorderItem wisource in source.WorkorderItems)
|
foreach (WorkorderItem wisource in source.WorkorderItems)
|
||||||
{
|
{
|
||||||
WorkorderItem widest = dest.WorkorderItems.Add(dest);
|
WorkorderItem widest = dest.WorkorderItems.Add(dest);
|
||||||
widest.Custom0 = wisource.Custom0;
|
widest.Custom0 = wisource.Custom0;
|
||||||
widest.Custom1 = wisource.Custom1;
|
widest.Custom1 = wisource.Custom1;
|
||||||
widest.Custom2 = wisource.Custom2;
|
widest.Custom2 = wisource.Custom2;
|
||||||
widest.Custom3 = wisource.Custom3;
|
widest.Custom3 = wisource.Custom3;
|
||||||
widest.Custom4 = wisource.Custom4;
|
widest.Custom4 = wisource.Custom4;
|
||||||
widest.Custom5 = wisource.Custom5;
|
widest.Custom5 = wisource.Custom5;
|
||||||
widest.Custom6 = wisource.Custom6;
|
widest.Custom6 = wisource.Custom6;
|
||||||
widest.Custom7 = wisource.Custom7;
|
widest.Custom7 = wisource.Custom7;
|
||||||
widest.Custom8 = wisource.Custom8;
|
widest.Custom8 = wisource.Custom8;
|
||||||
widest.Custom9 = wisource.Custom9;
|
widest.Custom9 = wisource.Custom9;
|
||||||
widest.PriorityID = wisource.PriorityID;
|
widest.PriorityID = wisource.PriorityID;
|
||||||
widest.RequestDate = wisource.RequestDate;
|
widest.RequestDate = wisource.RequestDate;
|
||||||
widest.Summary = wisource.Summary;
|
widest.Summary = wisource.Summary;
|
||||||
widest.TechNotes = wisource.TechNotes;
|
widest.TechNotes = wisource.TechNotes;
|
||||||
widest.TypeID = wisource.TypeID;
|
widest.TypeID = wisource.TypeID;
|
||||||
widest.UnitID = wisource.UnitID;
|
widest.UnitID = wisource.UnitID;
|
||||||
widest.WarrantyService = wisource.WarrantyService;
|
widest.WarrantyService = wisource.WarrantyService;
|
||||||
widest.WorkorderItemUnitServiceTypeID = wisource.WorkorderItemUnitServiceTypeID;
|
widest.WorkorderItemUnitServiceTypeID = wisource.WorkorderItemUnitServiceTypeID;
|
||||||
widest.WorkorderStatusID = wisource.WorkorderStatusID;
|
widest.WorkorderStatusID = wisource.WorkorderStatusID;
|
||||||
|
|
||||||
//PARTS
|
//PARTS
|
||||||
foreach (WorkorderItemPart partsource in wisource.Parts)
|
foreach (WorkorderItemPart partsource in wisource.Parts)
|
||||||
{
|
{
|
||||||
WorkorderItemPart partdest = widest.Parts.Add(widest);
|
WorkorderItemPart partdest = widest.Parts.Add(widest);
|
||||||
partdest.Cost = partsource.Cost;
|
partdest.Cost = partsource.Cost;
|
||||||
partdest.Description = partsource.Description;
|
partdest.Description = partsource.Description;
|
||||||
partdest.Discount = partsource.Discount;
|
partdest.Discount = partsource.Discount;
|
||||||
partdest.DiscountType = partsource.DiscountType;
|
partdest.DiscountType = partsource.DiscountType;
|
||||||
partdest.PartID = partsource.PartID;
|
partdest.PartID = partsource.PartID;
|
||||||
partdest.PartWarehouseID = partsource.PartWarehouseID;
|
partdest.PartWarehouseID = partsource.PartWarehouseID;
|
||||||
partdest.Price = partsource.Price;
|
partdest.Price = partsource.Price;
|
||||||
if (bUseInventory)
|
if (bUseInventory)
|
||||||
{
|
{
|
||||||
partdest.QuantityReserved = partsource.Quantity;
|
partdest.QuantityReserved = partsource.Quantity;
|
||||||
partdest.Quantity = 0;
|
partdest.Quantity = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
partdest.Quantity = partsource.Quantity;
|
partdest.Quantity = partsource.Quantity;
|
||||||
partdest.TaxPartSaleID = partsource.TaxPartSaleID;
|
partdest.TaxPartSaleID = partsource.TaxPartSaleID;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//**********************************************************
|
//**********************************************************
|
||||||
//Part requests would be here if copying a service workorder
|
//Part requests would be here if copying a service workorder
|
||||||
//**********************************************************
|
//**********************************************************
|
||||||
|
|
||||||
//SCHEDULED USERS
|
//SCHEDULED USERS
|
||||||
foreach (WorkorderItemScheduledUser usersource in wisource.ScheduledUsers)
|
foreach (WorkorderItemScheduledUser usersource in wisource.ScheduledUsers)
|
||||||
{
|
{
|
||||||
WorkorderItemScheduledUser userdest = widest.ScheduledUsers.Add(widest);
|
WorkorderItemScheduledUser userdest = widest.ScheduledUsers.Add(widest);
|
||||||
userdest.EstimatedQuantity = usersource.EstimatedQuantity;
|
userdest.EstimatedQuantity = usersource.EstimatedQuantity;
|
||||||
userdest.ServiceRateID = usersource.ServiceRateID;
|
userdest.ServiceRateID = usersource.ServiceRateID;
|
||||||
userdest.StartDate = usersource.StartDate;
|
userdest.StartDate = usersource.StartDate;
|
||||||
userdest.StopDate = usersource.StopDate;
|
userdest.StopDate = usersource.StopDate;
|
||||||
userdest.UserID = usersource.UserID;
|
userdest.UserID = usersource.UserID;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//LABOR
|
//LABOR
|
||||||
foreach (WorkorderItemLabor laborsource in wisource.Labors)
|
foreach (WorkorderItemLabor laborsource in wisource.Labors)
|
||||||
{
|
{
|
||||||
WorkorderItemLabor labordest = widest.Labors.Add(widest);
|
WorkorderItemLabor labordest = widest.Labors.Add(widest);
|
||||||
labordest.NoChargeQuantity = laborsource.NoChargeQuantity;
|
labordest.NoChargeQuantity = laborsource.NoChargeQuantity;
|
||||||
labordest.ServiceDetails = laborsource.ServiceDetails;
|
labordest.ServiceDetails = laborsource.ServiceDetails;
|
||||||
labordest.ServiceRateID = laborsource.ServiceRateID;
|
labordest.ServiceRateID = laborsource.ServiceRateID;
|
||||||
labordest.ServiceRateQuantity = laborsource.ServiceRateQuantity;
|
labordest.ServiceRateQuantity = laborsource.ServiceRateQuantity;
|
||||||
labordest.ServiceStartDate = laborsource.ServiceStartDate;
|
labordest.ServiceStartDate = laborsource.ServiceStartDate;
|
||||||
labordest.ServiceStopDate = laborsource.ServiceStopDate;
|
labordest.ServiceStopDate = laborsource.ServiceStopDate;
|
||||||
labordest.TaxRateSaleID = laborsource.TaxRateSaleID;
|
labordest.TaxRateSaleID = laborsource.TaxRateSaleID;
|
||||||
labordest.UserID = laborsource.UserID;
|
labordest.UserID = laborsource.UserID;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//**********************************************************
|
//**********************************************************
|
||||||
//Expenses would be here if copying a service workorder
|
//Expenses would be here if copying a service workorder
|
||||||
//**********************************************************
|
//**********************************************************
|
||||||
|
|
||||||
|
|
||||||
//**********************************************************
|
//**********************************************************
|
||||||
//Loans would be here if copying a service workorder
|
//Loans would be here if copying a service workorder
|
||||||
//**********************************************************
|
//**********************************************************
|
||||||
|
|
||||||
//TRAVEL
|
//TRAVEL
|
||||||
foreach (WorkorderItemTravel travelsource in wisource.Travels)
|
foreach (WorkorderItemTravel travelsource in wisource.Travels)
|
||||||
{
|
{
|
||||||
WorkorderItemTravel traveldest = widest.Travels.Add(widest);
|
WorkorderItemTravel traveldest = widest.Travels.Add(widest);
|
||||||
traveldest.TravelDetails = travelsource.TravelDetails;
|
traveldest.TravelDetails = travelsource.TravelDetails;
|
||||||
traveldest.TravelRateID = travelsource.TravelRateID;
|
traveldest.TravelRateID = travelsource.TravelRateID;
|
||||||
traveldest.TravelRateQuantity = travelsource.TravelRateQuantity;
|
traveldest.TravelRateQuantity = travelsource.TravelRateQuantity;
|
||||||
traveldest.TravelStartDate = travelsource.TravelStartDate;
|
traveldest.TravelStartDate = travelsource.TravelStartDate;
|
||||||
traveldest.TravelStopDate = travelsource.TravelStopDate;
|
traveldest.TravelStopDate = travelsource.TravelStopDate;
|
||||||
traveldest.TaxRateSaleID = travelsource.TaxRateSaleID;
|
traveldest.TaxRateSaleID = travelsource.TaxRateSaleID;
|
||||||
traveldest.UserID = travelsource.UserID;
|
traveldest.UserID = travelsource.UserID;
|
||||||
traveldest.Distance = travelsource.Distance;
|
traveldest.Distance = travelsource.Distance;
|
||||||
traveldest.Notes = travelsource.Notes;
|
traveldest.Notes = travelsource.Notes;
|
||||||
traveldest.NoChargeQuantity = travelsource.NoChargeQuantity;
|
traveldest.NoChargeQuantity = travelsource.NoChargeQuantity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//TASKS
|
//TASKS
|
||||||
foreach (WorkorderItemTask tasksource in wisource.Tasks)
|
foreach (WorkorderItemTask tasksource in wisource.Tasks)
|
||||||
{
|
{
|
||||||
WorkorderItemTask taskdest = widest.Tasks.Add(widest);
|
WorkorderItemTask taskdest = widest.Tasks.Add(widest);
|
||||||
taskdest.TaskGroupID = tasksource.TaskGroupID;
|
taskdest.TaskGroupID = tasksource.TaskGroupID;
|
||||||
taskdest.TaskID = tasksource.TaskID;
|
taskdest.TaskID = tasksource.TaskID;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//**********************************************************
|
//**********************************************************
|
||||||
//Outside service would be here if copying a service workorder
|
//Outside service would be here if copying a service workorder
|
||||||
//**********************************************************
|
//**********************************************************
|
||||||
|
|
||||||
}//foreach workorderitem loop
|
}//foreach workorderitem loop
|
||||||
|
|
||||||
//case 1387
|
//case 1387
|
||||||
|
|
||||||
//Delete the auto-created dummy workorder item
|
//Delete the auto-created dummy workorder item
|
||||||
//if there are more than it present
|
//if there are more than it present
|
||||||
if (dest.WorkorderItems.Count > 1)
|
if (dest.WorkorderItems.Count > 1)
|
||||||
dest.WorkorderItems.RemoveAt(0);
|
dest.WorkorderItems.RemoveAt(0);
|
||||||
|
|
||||||
#endregion copy workorder data
|
#endregion copy workorder data
|
||||||
|
|
||||||
//Now save it to ensure it was created properly so
|
//Now save it to ensure it was created properly so
|
||||||
//that we know it's now safe to advance the next service date and all others
|
//that we know it's now safe to advance the next service date and all others
|
||||||
|
|
||||||
//case 868 previously didn't set dest to result of save causing it to be a copy
|
//case 868 previously didn't set dest to result of save causing it to be a copy
|
||||||
dest = (Workorder)dest.Save();
|
dest = (Workorder)dest.Save();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region Calculate reschedule dates
|
#region Calculate reschedule dates
|
||||||
//Get the current next service date for calcs
|
//Get the current next service date for calcs
|
||||||
DateTime dtNext = GetDateFromSpanAndUnit(source.WorkorderPreventiveMaintenance.dtNextServiceDate,
|
DateTime dtNext = GetDateFromSpanAndUnit(source.WorkorderPreventiveMaintenance.dtNextServiceDate,
|
||||||
source.WorkorderPreventiveMaintenance.GenerateSpanUnit,
|
source.WorkorderPreventiveMaintenance.GenerateSpanUnit,
|
||||||
source.WorkorderPreventiveMaintenance.GenerateSpan);
|
source.WorkorderPreventiveMaintenance.GenerateSpan);
|
||||||
|
|
||||||
//Get to the desired day of the week if necessary...
|
//Get to the desired day of the week if necessary...
|
||||||
if (source.mWorkorderPreventiveMaintenance.DayOfTheWeek != AyaDayOfWeek.AnyDayOfWeek)
|
if (source.mWorkorderPreventiveMaintenance.DayOfTheWeek != AyaDayOfWeek.AnyDayOfWeek)
|
||||||
{
|
{
|
||||||
DayOfWeek desired = AyaToSystemDayOfWeek(source.mWorkorderPreventiveMaintenance.DayOfTheWeek);
|
DayOfWeek desired = AyaToSystemDayOfWeek(source.mWorkorderPreventiveMaintenance.DayOfTheWeek);
|
||||||
while (dtNext.DayOfWeek != desired)
|
while (dtNext.DayOfWeek != desired)
|
||||||
{
|
{
|
||||||
dtNext = dtNext.AddDays(1);
|
dtNext = dtNext.AddDays(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get the time span to add to all the other relevant dates on teh workorder to match
|
//Get the time span to add to all the other relevant dates on teh workorder to match
|
||||||
//the amount the next service date has been advanced
|
//the amount the next service date has been advanced
|
||||||
System.TimeSpan tsToNext = dtNext - source.WorkorderPreventiveMaintenance.dtNextServiceDate;
|
System.TimeSpan tsToNext = dtNext - source.WorkorderPreventiveMaintenance.dtNextServiceDate;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
//Will the next workorder service date fall after the
|
//Will the next workorder service date fall after the
|
||||||
//stop generating date?
|
//stop generating date?
|
||||||
if (source.WorkorderPreventiveMaintenance.StopGeneratingDate != System.DBNull.Value &&
|
if (source.WorkorderPreventiveMaintenance.StopGeneratingDate != System.DBNull.Value &&
|
||||||
source.WorkorderPreventiveMaintenance.dtStopGeneratingDate < dtNext)
|
source.WorkorderPreventiveMaintenance.dtStopGeneratingDate < dtNext)
|
||||||
{
|
{
|
||||||
//Yes it will, so set it to inactive and bail out
|
//Yes it will, so set it to inactive and bail out
|
||||||
source.WorkorderPreventiveMaintenance.Active = false;
|
source.WorkorderPreventiveMaintenance.Active = false;
|
||||||
source.Save();
|
source.Save();
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Reschedule PM
|
#region Reschedule PM
|
||||||
|
|
||||||
source.WorkorderPreventiveMaintenance.dtNextServiceDate = dtNext;
|
source.WorkorderPreventiveMaintenance.dtNextServiceDate = dtNext;
|
||||||
//Calcs the generate date (threshold date)
|
//Calcs the generate date (threshold date)
|
||||||
source.WorkorderPreventiveMaintenance.SetGenerateDate();
|
source.WorkorderPreventiveMaintenance.SetGenerateDate();
|
||||||
//WORKORDERITEMS
|
//WORKORDERITEMS
|
||||||
foreach (WorkorderItem wisource in source.WorkorderItems)
|
foreach (WorkorderItem wisource in source.WorkorderItems)
|
||||||
{
|
{
|
||||||
|
|
||||||
wisource.RequestDate = wisource.RequestDate;
|
wisource.RequestDate = wisource.RequestDate;
|
||||||
|
|
||||||
|
|
||||||
//PARTS
|
//PARTS
|
||||||
//no date changes required
|
//no date changes required
|
||||||
|
|
||||||
|
|
||||||
//SCHEDULED USERS
|
//SCHEDULED USERS
|
||||||
foreach (WorkorderItemScheduledUser usersource in wisource.ScheduledUsers)
|
foreach (WorkorderItemScheduledUser usersource in wisource.ScheduledUsers)
|
||||||
{
|
{
|
||||||
//Changed: 2-Oct-2006
|
//Changed: 2-Oct-2006
|
||||||
//check to not add a date if the original date was empty
|
//check to not add a date if the original date was empty
|
||||||
if (usersource.StartDate != System.DBNull.Value)
|
if (usersource.StartDate != System.DBNull.Value)
|
||||||
usersource.dtStartDate = usersource.dtStartDate.Add(tsToNext);
|
usersource.dtStartDate = usersource.dtStartDate.Add(tsToNext);
|
||||||
|
|
||||||
if (usersource.StopDate != System.DBNull.Value)
|
if (usersource.StopDate != System.DBNull.Value)
|
||||||
usersource.dtStopDate = usersource.dtStopDate.Add(tsToNext);
|
usersource.dtStopDate = usersource.dtStopDate.Add(tsToNext);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//LABOR
|
//LABOR
|
||||||
foreach (WorkorderItemLabor laborsource in wisource.Labors)
|
foreach (WorkorderItemLabor laborsource in wisource.Labors)
|
||||||
{
|
{
|
||||||
//Changed: 2-Oct-2006
|
//Changed: 2-Oct-2006
|
||||||
//check to not add a date if the original date was empty
|
//check to not add a date if the original date was empty
|
||||||
if (laborsource.ServiceStartDate != System.DBNull.Value)
|
if (laborsource.ServiceStartDate != System.DBNull.Value)
|
||||||
laborsource.dtServiceStartDate = laborsource.dtServiceStartDate.Add(tsToNext);
|
laborsource.dtServiceStartDate = laborsource.dtServiceStartDate.Add(tsToNext);
|
||||||
|
|
||||||
if (laborsource.ServiceStopDate != System.DBNull.Value)
|
if (laborsource.ServiceStopDate != System.DBNull.Value)
|
||||||
laborsource.dtServiceStopDate = laborsource.dtServiceStopDate.Add(tsToNext);
|
laborsource.dtServiceStopDate = laborsource.dtServiceStopDate.Add(tsToNext);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//**********************************************************
|
//**********************************************************
|
||||||
//Expenses would be here if copying a service workorder
|
//Expenses would be here if copying a service workorder
|
||||||
//**********************************************************
|
//**********************************************************
|
||||||
|
|
||||||
|
|
||||||
//**********************************************************
|
//**********************************************************
|
||||||
//Loans would be here if copying a service workorder
|
//Loans would be here if copying a service workorder
|
||||||
//**********************************************************
|
//**********************************************************
|
||||||
|
|
||||||
//TRAVEL
|
//TRAVEL
|
||||||
foreach (WorkorderItemTravel travelsource in wisource.Travels)
|
foreach (WorkorderItemTravel travelsource in wisource.Travels)
|
||||||
{
|
{
|
||||||
//Changed: 2-Oct-2006
|
//Changed: 2-Oct-2006
|
||||||
//check to not add a date if the original date was empty
|
//check to not add a date if the original date was empty
|
||||||
if (travelsource.TravelStartDate != DBNull.Value)
|
if (travelsource.TravelStartDate != DBNull.Value)
|
||||||
travelsource.dtTravelStartDate = travelsource.dtTravelStartDate.Add(tsToNext);
|
travelsource.dtTravelStartDate = travelsource.dtTravelStartDate.Add(tsToNext);
|
||||||
|
|
||||||
if (travelsource.TravelStopDate != DBNull.Value)
|
if (travelsource.TravelStopDate != DBNull.Value)
|
||||||
travelsource.dtTravelStopDate = travelsource.dtTravelStopDate.Add(tsToNext);
|
travelsource.dtTravelStopDate = travelsource.dtTravelStopDate.Add(tsToNext);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//TASKS
|
//TASKS
|
||||||
|
|
||||||
|
|
||||||
//**********************************************************
|
//**********************************************************
|
||||||
//Outside service would be here if copying a service workorder
|
//Outside service would be here if copying a service workorder
|
||||||
//**********************************************************
|
//**********************************************************
|
||||||
|
|
||||||
}//foreach workorderitem loop
|
}//foreach workorderitem loop
|
||||||
#endregion reschedule pm
|
#endregion reschedule pm
|
||||||
|
|
||||||
//Ok, Source PM is now rescheduled, save it
|
//Ok, Source PM is now rescheduled, save it
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//case 1959 try catch block added to prevent infinite generation issue
|
//case 1959 try catch block added to prevent infinite generation issue
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
source = (Workorder)source.Save();
|
source = (Workorder)source.Save();
|
||||||
}
|
}
|
||||||
catch (Exception exx)
|
catch (Exception exx)
|
||||||
{
|
{
|
||||||
dest.Delete();
|
dest.Delete();
|
||||||
dest.Save();
|
dest.Save();
|
||||||
//crack the exception
|
//crack the exception
|
||||||
while (exx.InnerException != null)
|
while (exx.InnerException != null)
|
||||||
exx = exx.InnerException;
|
exx = exx.InnerException;
|
||||||
|
|
||||||
Memo mwarn = Memo.NewItem();
|
Memo mwarn = Memo.NewItem();
|
||||||
mwarn.ToID = User.AdministratorID;
|
mwarn.ToID = User.AdministratorID;
|
||||||
|
|
||||||
//case 3826
|
//case 3826
|
||||||
if (User.CurrentUserType == UserTypes.Utility)
|
if (User.CurrentUserType == UserTypes.Utility)
|
||||||
{
|
{
|
||||||
//Utility accounts should not be sending memos, it fucks up downstream
|
//Utility accounts should not be sending memos, it fucks up downstream
|
||||||
//trying to view the memo, also it's confusing
|
//trying to view the memo, also it's confusing
|
||||||
mwarn.FromID = User.AdministratorID;
|
mwarn.FromID = User.AdministratorID;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mwarn.FromID = User.CurrentThreadUserID;
|
mwarn.FromID = User.CurrentThreadUserID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mwarn.Subject = "SYSTEM WARNING: Preventive Maintenance WO PROBLEM";
|
mwarn.Subject = "SYSTEM WARNING: Preventive Maintenance WO PROBLEM";
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.AppendLine("This is an automated message sent on behalf of the current user from the \"NewServiceWorkorderFromPM\" module.");
|
sb.AppendLine("This is an automated message sent on behalf of the current user from the \"NewServiceWorkorderFromPM\" module.");
|
||||||
sb.AppendLine("This message concerns Preventive Maintenance workorder number " + source.WorkorderPreventiveMaintenance.PreventiveMaintenanceNumber.ToString());
|
sb.AppendLine("This message concerns Preventive Maintenance workorder number " + source.WorkorderPreventiveMaintenance.PreventiveMaintenanceNumber.ToString());
|
||||||
sb.AppendLine("The Preventive Maintenance workorder had an error when trying to save it during generation of a service workorder.");
|
sb.AppendLine("The Preventive Maintenance workorder had an error when trying to save it during generation of a service workorder.");
|
||||||
sb.AppendLine("This kind of problem could result in loop which generates a very large number of identical service workorders.");
|
sb.AppendLine("This kind of problem could result in loop which generates a very large number of identical service workorders.");
|
||||||
sb.AppendLine("In order to prevent this the operation has been stopped and this message generated so you can fix the problem with the source PM workorder.");
|
sb.AppendLine("In order to prevent this the operation has been stopped and this message generated so you can fix the problem with the source PM workorder.");
|
||||||
sb.AppendLine("See below for details and examine the PM workorder for problems or contact support@ayanova.com for help with the information in this message.");
|
sb.AppendLine("See below for details and examine the PM workorder for problems or contact support@ayanova.com for help with the information in this message.");
|
||||||
sb.AppendLine("Here are the details of the error preventing save:");
|
sb.AppendLine("Here are the details of the error preventing save:");
|
||||||
sb.AppendLine("=================================");
|
sb.AppendLine("=================================");
|
||||||
sb.AppendLine("Exception saving source PM:");
|
sb.AppendLine("Exception saving source PM:");
|
||||||
sb.AppendLine(exx.Message);
|
sb.AppendLine(exx.Message);
|
||||||
sb.AppendLine("=================================");
|
sb.AppendLine("=================================");
|
||||||
string sSourceErr = source.GetBrokenRulesString();
|
string sSourceErr = source.GetBrokenRulesString();
|
||||||
if (!string.IsNullOrWhiteSpace(sSourceErr))
|
if (!string.IsNullOrWhiteSpace(sSourceErr))
|
||||||
{
|
{
|
||||||
sb.AppendLine("Broken business rules on PM object:");
|
sb.AppendLine("Broken business rules on PM object:");
|
||||||
sb.AppendLine(sSourceErr);
|
sb.AppendLine(sSourceErr);
|
||||||
sb.AppendLine("==============================");
|
sb.AppendLine("==============================");
|
||||||
}
|
}
|
||||||
mwarn.Message = sb.ToString();
|
mwarn.Message = sb.ToString();
|
||||||
mwarn.Save();
|
mwarn.Save();
|
||||||
throw new System.ApplicationException("Workorder->NewServiceWorkorderFromPM: Error during service workorder generation. Memo with details sent to Administrator account.");
|
throw new System.ApplicationException("Workorder->NewServiceWorkorderFromPM: Error during service workorder generation. Memo with details sent to Administrator account.");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//case 1630
|
//case 1630
|
||||||
//copy wikipage from pm to service workorder
|
//copy wikipage from pm to service workorder
|
||||||
if (dest.CanWiki && source.HasWiki)
|
if (dest.CanWiki && source.HasWiki)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WikiPage wpSource = WikiPage.GetItem(new TypeAndID(RootObjectTypes.WorkorderPreventiveMaintenance, source.ID));
|
WikiPage wpSource = WikiPage.GetItem(new TypeAndID(RootObjectTypes.WorkorderPreventiveMaintenance, source.ID));
|
||||||
WikiPage wpDest = WikiPage.GetItem(new TypeAndID(RootObjectTypes.WorkorderService, dest.ID));
|
WikiPage wpDest = WikiPage.GetItem(new TypeAndID(RootObjectTypes.WorkorderService, dest.ID));
|
||||||
wpDest.SetContent(wpSource.GetContent());
|
wpDest.SetContent(wpSource.GetContent());
|
||||||
wpDest.Save();
|
wpDest.Save();
|
||||||
}
|
}
|
||||||
catch { };
|
catch { };
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Calculate generate date based on service date and
|
/// Calculate generate date based on service date and
|
||||||
/// threshold span and unit
|
/// threshold span and unit
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal void SetGenerateDate()
|
internal void SetGenerateDate()
|
||||||
{
|
{
|
||||||
if (this.mNextServiceDate.IsEmpty) return;
|
if (this.mNextServiceDate.IsEmpty) return;
|
||||||
if (this.mThresholdSpan == 0)
|
if (this.mThresholdSpan == 0)
|
||||||
{
|
{
|
||||||
this.mGenerateDate = this.mNextServiceDate;
|
this.mGenerateDate = this.mNextServiceDate;
|
||||||
MarkDirty();
|
MarkDirty();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mGenerateDate = new SmartDate(Workorder.GetDateFromSpanAndUnit(mNextServiceDate.Date, this.mThresholdSpanUnit, -mThresholdSpan));
|
mGenerateDate = new SmartDate(Workorder.GetDateFromSpanAndUnit(mNextServiceDate.Date, this.mThresholdSpanUnit, -mThresholdSpan));
|
||||||
MarkDirty();
|
MarkDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region Date time calcs helpers
|
#region Date time calcs helpers
|
||||||
//Takes an AyaNova day of week and returns
|
//Takes an AyaNova day of week and returns
|
||||||
//a System.DayOfWeek
|
//a System.DayOfWeek
|
||||||
//Assumes that AyaDayOfWeek is NOT "AnyDay"
|
//Assumes that AyaDayOfWeek is NOT "AnyDay"
|
||||||
internal static System.DayOfWeek AyaToSystemDayOfWeek(AyaDayOfWeek day)
|
internal static System.DayOfWeek AyaToSystemDayOfWeek(AyaDayOfWeek day)
|
||||||
{
|
{
|
||||||
switch (day)
|
switch (day)
|
||||||
{
|
{
|
||||||
case AyaDayOfWeek.Monday:
|
case AyaDayOfWeek.Monday:
|
||||||
return DayOfWeek.Monday;
|
return DayOfWeek.Monday;
|
||||||
case AyaDayOfWeek.Tuesday:
|
case AyaDayOfWeek.Tuesday:
|
||||||
return DayOfWeek.Tuesday;
|
return DayOfWeek.Tuesday;
|
||||||
case AyaDayOfWeek.Wednesday:
|
case AyaDayOfWeek.Wednesday:
|
||||||
return DayOfWeek.Wednesday;
|
return DayOfWeek.Wednesday;
|
||||||
case AyaDayOfWeek.Thursday:
|
case AyaDayOfWeek.Thursday:
|
||||||
return DayOfWeek.Thursday;
|
return DayOfWeek.Thursday;
|
||||||
case AyaDayOfWeek.Friday:
|
case AyaDayOfWeek.Friday:
|
||||||
return DayOfWeek.Friday;
|
return DayOfWeek.Friday;
|
||||||
case AyaDayOfWeek.Saturday:
|
case AyaDayOfWeek.Saturday:
|
||||||
return DayOfWeek.Saturday;
|
return DayOfWeek.Saturday;
|
||||||
case AyaDayOfWeek.Sunday:
|
case AyaDayOfWeek.Sunday:
|
||||||
return DayOfWeek.Sunday;
|
return DayOfWeek.Sunday;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new System.ArgumentOutOfRangeException("DayOfWeekConverter: AyaDayOfWeek.AnyDayOfWeek is not supported");
|
throw new System.ArgumentOutOfRangeException("DayOfWeekConverter: AyaDayOfWeek.AnyDayOfWeek is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal static DateTime GetDateFromSpanAndUnit(DateTime StartDate, AyaUnitsOfTime unit, int multiple)
|
internal static DateTime GetDateFromSpanAndUnit(DateTime StartDate, AyaUnitsOfTime unit, int multiple)
|
||||||
{
|
{
|
||||||
switch (unit)
|
switch (unit)
|
||||||
{
|
{
|
||||||
case AyaUnitsOfTime.Seconds:
|
case AyaUnitsOfTime.Seconds:
|
||||||
return StartDate.AddSeconds(multiple);
|
return StartDate.AddSeconds(multiple);
|
||||||
|
|
||||||
case AyaUnitsOfTime.Minutes:
|
case AyaUnitsOfTime.Minutes:
|
||||||
return StartDate.AddMinutes(multiple);
|
return StartDate.AddMinutes(multiple);
|
||||||
|
|
||||||
case AyaUnitsOfTime.Hours:
|
case AyaUnitsOfTime.Hours:
|
||||||
return StartDate.AddHours(multiple);
|
return StartDate.AddHours(multiple);
|
||||||
|
|
||||||
case AyaUnitsOfTime.Days:
|
case AyaUnitsOfTime.Days:
|
||||||
return StartDate.AddDays(multiple);
|
return StartDate.AddDays(multiple);
|
||||||
|
|
||||||
case AyaUnitsOfTime.Weeks:
|
case AyaUnitsOfTime.Weeks:
|
||||||
throw new System.NotSupportedException("GetDateFromSpanAndUnit: Weeks not supported");
|
throw new System.NotSupportedException("GetDateFromSpanAndUnit: Weeks not supported");
|
||||||
|
|
||||||
case AyaUnitsOfTime.Months:
|
case AyaUnitsOfTime.Months:
|
||||||
return StartDate.AddMonths(multiple);
|
return StartDate.AddMonths(multiple);
|
||||||
|
|
||||||
case AyaUnitsOfTime.Years:
|
case AyaUnitsOfTime.Years:
|
||||||
return StartDate.AddYears(multiple);
|
return StartDate.AddYears(multiple);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//fail safe:
|
//fail safe:
|
||||||
return StartDate;
|
return StartDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
#endregion gen service wo from pm
|
#endregion gen service wo from pm
|
||||||
|
|
||||||
internal class PMBiz : BizObject, IJobObject, ISearchAbleObject, IReportAbleObject, IExportAbleObject
|
internal class PMBiz : BizObject, IJobObject, ISearchAbleObject, IReportAbleObject, IExportAbleObject
|
||||||
{
|
{
|
||||||
@@ -1027,16 +1027,6 @@ namespace AyaNova.Biz
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// //GET WORKORDER ID FOR WORK ORDER NUMBER
|
|
||||||
// //
|
|
||||||
// internal static async Task<long> GetPMIdForNumberAsync(long woNumber, AyContext ct)
|
|
||||||
// {
|
|
||||||
// return await ct.PM.AsNoTracking()
|
|
||||||
// .Where(z => z.Serial == woNumber)
|
|
||||||
// .Select(z => z.Id)
|
|
||||||
// .SingleOrDefaultAsync();
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -5644,7 +5634,30 @@ namespace AyaNova.Biz
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region GENERATION
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Process generation of pms to workorders
|
||||||
|
//
|
||||||
|
internal static async Task Generate(AyContext ct, ILogger log)
|
||||||
|
{
|
||||||
|
#if (DEBUG)
|
||||||
|
log.LogInformation("PMBiz - Generating");
|
||||||
|
#endif
|
||||||
|
//Get a list of items
|
||||||
|
|
||||||
|
//process those items
|
||||||
|
//make new workorder
|
||||||
|
//fixup dates and update pm
|
||||||
|
|
||||||
|
//dummy query to turn off errors
|
||||||
|
var v = await ct.PM.AsNoTracking()
|
||||||
|
.Where(z => z.Serial == 1)
|
||||||
|
.Select(z => z.Id)
|
||||||
|
.SingleOrDefaultAsync();
|
||||||
|
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|||||||
80
server/AyaNova/generator/CoreJobPMGenerate.cs
Normal file
80
server/AyaNova/generator/CoreJobPMGenerate.cs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using AyaNova.Models;
|
||||||
|
using AyaNova.Util;
|
||||||
|
|
||||||
|
namespace AyaNova.Biz
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Preventive maintenance generator
|
||||||
|
/// turn PMs into Work orders
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
internal static class CoreJobPMGenerate
|
||||||
|
{
|
||||||
|
private static bool IsRunning = false;
|
||||||
|
private static ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger("CoreJobPMGenerate");
|
||||||
|
private static DateTime lastRun = DateTime.MinValue;
|
||||||
|
|
||||||
|
|
||||||
|
#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 RUN_EVERY_INTERVAL = new TimeSpan(0, 5, 0);//no more frequently than once every 5 minutes
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
public static async Task DoWorkAsync()
|
||||||
|
{
|
||||||
|
log.LogTrace("Checking if PMGenerate should run");
|
||||||
|
if (IsRunning)
|
||||||
|
{
|
||||||
|
log.LogTrace("PMGenerate is running already exiting this cycle");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//This will get triggered roughly every minute, but we don't want to deliver that frequently
|
||||||
|
if (DateTime.UtcNow - lastRun < RUN_EVERY_INTERVAL)
|
||||||
|
{
|
||||||
|
log.LogTrace($"PMGenerate ran less than {RUN_EVERY_INTERVAL} ago, exiting this cycle");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IsRunning = true;
|
||||||
|
log.LogTrace("PMGenerate set to RUNNING state and starting now");
|
||||||
|
|
||||||
|
using (AyContext ct = AyaNova.Util.ServiceProviderProvider.DBContext)
|
||||||
|
{
|
||||||
|
await PMBiz.Generate(ct, log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
log.LogError(ex, $"Error processing PMGenerate ");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
log.LogTrace("PMGenerate has completed; setting to not running state and tagging lastRun timestamp");
|
||||||
|
lastRun = DateTime.UtcNow;
|
||||||
|
IsRunning = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}//eoc
|
||||||
|
|
||||||
|
|
||||||
|
}//eons
|
||||||
|
|
||||||
Reference in New Issue
Block a user