diff --git a/server/AyaNova/biz/JobsBiz.cs b/server/AyaNova/biz/JobsBiz.cs
index 49e9d2fa..0cf05e15 100644
--- a/server/AyaNova/biz/JobsBiz.cs
+++ b/server/AyaNova/biz/JobsBiz.cs
@@ -206,6 +206,9 @@ namespace AyaNova.Biz
await CoreJobNotify.DoWorkAsync();
await CoreNotificationSweeper.DoWorkAsync();
+ //PM GENERATION
+ await CoreJobPMGenerate.DoWorkAsync();
+
//JOB SWEEPER / AND USER COUNT CHECK
await CoreJobSweeper.DoWorkAsync();
diff --git a/server/AyaNova/biz/PMBiz.cs b/server/AyaNova/biz/PMBiz.cs
index 79a02ff9..499e1236 100644
--- a/server/AyaNova/biz/PMBiz.cs
+++ b/server/AyaNova/biz/PMBiz.cs
@@ -13,488 +13,488 @@ using System.Collections.Generic;
namespace AyaNova.Biz
{
- #region v7 code for Generate service workorder from PM
- /* ///
- /// Generates a service workorder from a PM type Workorder
- ///
- /// ID of PM
- /// A new service workorder
- public static Workorder NewServiceWorkorderFromPM(Guid SourceWorkorderID)
- {
- //Fetch the source workorder and verify it's a PM
- Workorder source = Workorder.GetItemNoMRU(SourceWorkorderID);
- if (source.WorkorderType != WorkorderTypes.PreventiveMaintenance)
- throw new NotSupportedException(LocalizedTextTable.GetLocalizedTextDirect("Workorder.Label.Error.SourceInvalidType"));
-
- //if it's inactive then there is nothing to Process
- //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
- //expiry date
- if (source.WorkorderPreventiveMaintenance.Active == false)
- {
- throw new System.ApplicationException("NewServiceWorkorderFromPM: source PM workorder is not active");
- }
-
- if (source.WorkorderPreventiveMaintenance.StopGeneratingDate != System.DBNull.Value &&
- source.WorkorderPreventiveMaintenance.dtStopGeneratingDate < DBUtil.CurrentWorkingDateTime)
- {
- throw new System.ApplicationException("NewServiceWorkorderFromPM: source PM workorder is past StopGeneratingDate");
- }
-
- //Ok, so far so good, create the new one
- bool bUseInventory = AyaBizUtils.GlobalSettings.UseInventory;
-
- //case 1387
- Workorder dest = Workorder.NewItem(WorkorderTypes.Service);
-
- ////NOTE: THIS DOESN'T CALL THE SHARED NEW ITEM METHOD
- //Workorder dest = new Workorder();
- //dest.WorkorderType=WorkorderTypes.Service;
- //dest.mService=WorkorderService.NewItem(dest);
-
- #region copy workorder data
-
- //WORKORDER HEADER
- dest.ClientID = source.ClientID;
- dest.CustomerContactName = source.CustomerContactName;
- dest.CustomerReferenceNumber = source.CustomerReferenceNumber;
- dest.mFromPMID = source.WorkorderPreventiveMaintenance.ID;
- dest.InternalReferenceNumber = source.InternalReferenceNumber;
- dest.Onsite = source.Onsite;
- dest.ProjectID = source.ProjectID;
- //dest.RegionID=source.RegionID;
- dest.Summary = source.Summary;
- dest.WorkorderCategoryID = source.WorkorderCategoryID;
-
- //PM SPECIFIC
- dest.WorkorderService.WorkorderStatusID = source.WorkorderPreventiveMaintenance.WorkorderStatusID;
- //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))
- dest.WorkorderService.ServiceDate = source.WorkorderPreventiveMaintenance.NextServiceDate;
-
-
- //WORKORDERITEMS
- foreach (WorkorderItem wisource in source.WorkorderItems)
- {
- WorkorderItem widest = dest.WorkorderItems.Add(dest);
- widest.Custom0 = wisource.Custom0;
- widest.Custom1 = wisource.Custom1;
- widest.Custom2 = wisource.Custom2;
- widest.Custom3 = wisource.Custom3;
- widest.Custom4 = wisource.Custom4;
- widest.Custom5 = wisource.Custom5;
- widest.Custom6 = wisource.Custom6;
- widest.Custom7 = wisource.Custom7;
- widest.Custom8 = wisource.Custom8;
- widest.Custom9 = wisource.Custom9;
- widest.PriorityID = wisource.PriorityID;
- widest.RequestDate = wisource.RequestDate;
- widest.Summary = wisource.Summary;
- widest.TechNotes = wisource.TechNotes;
- widest.TypeID = wisource.TypeID;
- widest.UnitID = wisource.UnitID;
- widest.WarrantyService = wisource.WarrantyService;
- widest.WorkorderItemUnitServiceTypeID = wisource.WorkorderItemUnitServiceTypeID;
- widest.WorkorderStatusID = wisource.WorkorderStatusID;
-
- //PARTS
- foreach (WorkorderItemPart partsource in wisource.Parts)
- {
- WorkorderItemPart partdest = widest.Parts.Add(widest);
- partdest.Cost = partsource.Cost;
- partdest.Description = partsource.Description;
- partdest.Discount = partsource.Discount;
- partdest.DiscountType = partsource.DiscountType;
- partdest.PartID = partsource.PartID;
- partdest.PartWarehouseID = partsource.PartWarehouseID;
- partdest.Price = partsource.Price;
- if (bUseInventory)
- {
- partdest.QuantityReserved = partsource.Quantity;
- partdest.Quantity = 0;
- }
- else
- partdest.Quantity = partsource.Quantity;
- partdest.TaxPartSaleID = partsource.TaxPartSaleID;
-
-
- }
-
- //**********************************************************
- //Part requests would be here if copying a service workorder
- //**********************************************************
-
- //SCHEDULED USERS
- foreach (WorkorderItemScheduledUser usersource in wisource.ScheduledUsers)
- {
- WorkorderItemScheduledUser userdest = widest.ScheduledUsers.Add(widest);
- userdest.EstimatedQuantity = usersource.EstimatedQuantity;
- userdest.ServiceRateID = usersource.ServiceRateID;
- userdest.StartDate = usersource.StartDate;
- userdest.StopDate = usersource.StopDate;
- userdest.UserID = usersource.UserID;
-
- }
-
- //LABOR
- foreach (WorkorderItemLabor laborsource in wisource.Labors)
- {
- WorkorderItemLabor labordest = widest.Labors.Add(widest);
- labordest.NoChargeQuantity = laborsource.NoChargeQuantity;
- labordest.ServiceDetails = laborsource.ServiceDetails;
- labordest.ServiceRateID = laborsource.ServiceRateID;
- labordest.ServiceRateQuantity = laborsource.ServiceRateQuantity;
- labordest.ServiceStartDate = laborsource.ServiceStartDate;
- labordest.ServiceStopDate = laborsource.ServiceStopDate;
- labordest.TaxRateSaleID = laborsource.TaxRateSaleID;
- labordest.UserID = laborsource.UserID;
-
- }
-
- //**********************************************************
- //Expenses would be here if copying a service workorder
- //**********************************************************
-
-
- //**********************************************************
- //Loans would be here if copying a service workorder
- //**********************************************************
-
- //TRAVEL
- foreach (WorkorderItemTravel travelsource in wisource.Travels)
- {
- WorkorderItemTravel traveldest = widest.Travels.Add(widest);
- traveldest.TravelDetails = travelsource.TravelDetails;
- traveldest.TravelRateID = travelsource.TravelRateID;
- traveldest.TravelRateQuantity = travelsource.TravelRateQuantity;
- traveldest.TravelStartDate = travelsource.TravelStartDate;
- traveldest.TravelStopDate = travelsource.TravelStopDate;
- traveldest.TaxRateSaleID = travelsource.TaxRateSaleID;
- traveldest.UserID = travelsource.UserID;
- traveldest.Distance = travelsource.Distance;
- traveldest.Notes = travelsource.Notes;
- traveldest.NoChargeQuantity = travelsource.NoChargeQuantity;
- }
-
-
-
- //TASKS
- foreach (WorkorderItemTask tasksource in wisource.Tasks)
- {
- WorkorderItemTask taskdest = widest.Tasks.Add(widest);
- taskdest.TaskGroupID = tasksource.TaskGroupID;
- taskdest.TaskID = tasksource.TaskID;
-
- }
-
- //**********************************************************
- //Outside service would be here if copying a service workorder
- //**********************************************************
-
- }//foreach workorderitem loop
+ #region v7 code for Generate service workorder from PM
+ /* ///
+ /// Generates a service workorder from a PM type Workorder
+ ///
+ /// ID of PM
+ /// A new service workorder
+ public static Workorder NewServiceWorkorderFromPM(Guid SourceWorkorderID)
+ {
+ //Fetch the source workorder and verify it's a PM
+ Workorder source = Workorder.GetItemNoMRU(SourceWorkorderID);
+ if (source.WorkorderType != WorkorderTypes.PreventiveMaintenance)
+ throw new NotSupportedException(LocalizedTextTable.GetLocalizedTextDirect("Workorder.Label.Error.SourceInvalidType"));
+
+ //if it's inactive then there is nothing to Process
+ //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
+ //expiry date
+ if (source.WorkorderPreventiveMaintenance.Active == false)
+ {
+ throw new System.ApplicationException("NewServiceWorkorderFromPM: source PM workorder is not active");
+ }
+
+ if (source.WorkorderPreventiveMaintenance.StopGeneratingDate != System.DBNull.Value &&
+ source.WorkorderPreventiveMaintenance.dtStopGeneratingDate < DBUtil.CurrentWorkingDateTime)
+ {
+ throw new System.ApplicationException("NewServiceWorkorderFromPM: source PM workorder is past StopGeneratingDate");
+ }
+
+ //Ok, so far so good, create the new one
+ bool bUseInventory = AyaBizUtils.GlobalSettings.UseInventory;
+
+ //case 1387
+ Workorder dest = Workorder.NewItem(WorkorderTypes.Service);
+
+ ////NOTE: THIS DOESN'T CALL THE SHARED NEW ITEM METHOD
+ //Workorder dest = new Workorder();
+ //dest.WorkorderType=WorkorderTypes.Service;
+ //dest.mService=WorkorderService.NewItem(dest);
+
+ #region copy workorder data
+
+ //WORKORDER HEADER
+ dest.ClientID = source.ClientID;
+ dest.CustomerContactName = source.CustomerContactName;
+ dest.CustomerReferenceNumber = source.CustomerReferenceNumber;
+ dest.mFromPMID = source.WorkorderPreventiveMaintenance.ID;
+ dest.InternalReferenceNumber = source.InternalReferenceNumber;
+ dest.Onsite = source.Onsite;
+ dest.ProjectID = source.ProjectID;
+ //dest.RegionID=source.RegionID;
+ dest.Summary = source.Summary;
+ dest.WorkorderCategoryID = source.WorkorderCategoryID;
+
+ //PM SPECIFIC
+ dest.WorkorderService.WorkorderStatusID = source.WorkorderPreventiveMaintenance.WorkorderStatusID;
+ //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))
+ dest.WorkorderService.ServiceDate = source.WorkorderPreventiveMaintenance.NextServiceDate;
+
+
+ //WORKORDERITEMS
+ foreach (WorkorderItem wisource in source.WorkorderItems)
+ {
+ WorkorderItem widest = dest.WorkorderItems.Add(dest);
+ widest.Custom0 = wisource.Custom0;
+ widest.Custom1 = wisource.Custom1;
+ widest.Custom2 = wisource.Custom2;
+ widest.Custom3 = wisource.Custom3;
+ widest.Custom4 = wisource.Custom4;
+ widest.Custom5 = wisource.Custom5;
+ widest.Custom6 = wisource.Custom6;
+ widest.Custom7 = wisource.Custom7;
+ widest.Custom8 = wisource.Custom8;
+ widest.Custom9 = wisource.Custom9;
+ widest.PriorityID = wisource.PriorityID;
+ widest.RequestDate = wisource.RequestDate;
+ widest.Summary = wisource.Summary;
+ widest.TechNotes = wisource.TechNotes;
+ widest.TypeID = wisource.TypeID;
+ widest.UnitID = wisource.UnitID;
+ widest.WarrantyService = wisource.WarrantyService;
+ widest.WorkorderItemUnitServiceTypeID = wisource.WorkorderItemUnitServiceTypeID;
+ widest.WorkorderStatusID = wisource.WorkorderStatusID;
+
+ //PARTS
+ foreach (WorkorderItemPart partsource in wisource.Parts)
+ {
+ WorkorderItemPart partdest = widest.Parts.Add(widest);
+ partdest.Cost = partsource.Cost;
+ partdest.Description = partsource.Description;
+ partdest.Discount = partsource.Discount;
+ partdest.DiscountType = partsource.DiscountType;
+ partdest.PartID = partsource.PartID;
+ partdest.PartWarehouseID = partsource.PartWarehouseID;
+ partdest.Price = partsource.Price;
+ if (bUseInventory)
+ {
+ partdest.QuantityReserved = partsource.Quantity;
+ partdest.Quantity = 0;
+ }
+ else
+ partdest.Quantity = partsource.Quantity;
+ partdest.TaxPartSaleID = partsource.TaxPartSaleID;
+
+
+ }
+
+ //**********************************************************
+ //Part requests would be here if copying a service workorder
+ //**********************************************************
+
+ //SCHEDULED USERS
+ foreach (WorkorderItemScheduledUser usersource in wisource.ScheduledUsers)
+ {
+ WorkorderItemScheduledUser userdest = widest.ScheduledUsers.Add(widest);
+ userdest.EstimatedQuantity = usersource.EstimatedQuantity;
+ userdest.ServiceRateID = usersource.ServiceRateID;
+ userdest.StartDate = usersource.StartDate;
+ userdest.StopDate = usersource.StopDate;
+ userdest.UserID = usersource.UserID;
+
+ }
+
+ //LABOR
+ foreach (WorkorderItemLabor laborsource in wisource.Labors)
+ {
+ WorkorderItemLabor labordest = widest.Labors.Add(widest);
+ labordest.NoChargeQuantity = laborsource.NoChargeQuantity;
+ labordest.ServiceDetails = laborsource.ServiceDetails;
+ labordest.ServiceRateID = laborsource.ServiceRateID;
+ labordest.ServiceRateQuantity = laborsource.ServiceRateQuantity;
+ labordest.ServiceStartDate = laborsource.ServiceStartDate;
+ labordest.ServiceStopDate = laborsource.ServiceStopDate;
+ labordest.TaxRateSaleID = laborsource.TaxRateSaleID;
+ labordest.UserID = laborsource.UserID;
+
+ }
+
+ //**********************************************************
+ //Expenses would be here if copying a service workorder
+ //**********************************************************
+
+
+ //**********************************************************
+ //Loans would be here if copying a service workorder
+ //**********************************************************
+
+ //TRAVEL
+ foreach (WorkorderItemTravel travelsource in wisource.Travels)
+ {
+ WorkorderItemTravel traveldest = widest.Travels.Add(widest);
+ traveldest.TravelDetails = travelsource.TravelDetails;
+ traveldest.TravelRateID = travelsource.TravelRateID;
+ traveldest.TravelRateQuantity = travelsource.TravelRateQuantity;
+ traveldest.TravelStartDate = travelsource.TravelStartDate;
+ traveldest.TravelStopDate = travelsource.TravelStopDate;
+ traveldest.TaxRateSaleID = travelsource.TaxRateSaleID;
+ traveldest.UserID = travelsource.UserID;
+ traveldest.Distance = travelsource.Distance;
+ traveldest.Notes = travelsource.Notes;
+ traveldest.NoChargeQuantity = travelsource.NoChargeQuantity;
+ }
+
+
+
+ //TASKS
+ foreach (WorkorderItemTask tasksource in wisource.Tasks)
+ {
+ WorkorderItemTask taskdest = widest.Tasks.Add(widest);
+ taskdest.TaskGroupID = tasksource.TaskGroupID;
+ taskdest.TaskID = tasksource.TaskID;
+
+ }
+
+ //**********************************************************
+ //Outside service would be here if copying a service workorder
+ //**********************************************************
+
+ }//foreach workorderitem loop
- //case 1387
+ //case 1387
- //Delete the auto-created dummy workorder item
- //if there are more than it present
- if (dest.WorkorderItems.Count > 1)
- dest.WorkorderItems.RemoveAt(0);
+ //Delete the auto-created dummy workorder item
+ //if there are more than it present
+ if (dest.WorkorderItems.Count > 1)
+ dest.WorkorderItems.RemoveAt(0);
- #endregion copy workorder data
+ #endregion copy workorder data
- //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
+ //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
- //case 868 previously didn't set dest to result of save causing it to be a copy
- dest = (Workorder)dest.Save();
+ //case 868 previously didn't set dest to result of save causing it to be a copy
+ dest = (Workorder)dest.Save();
- #region Calculate reschedule dates
- //Get the current next service date for calcs
- DateTime dtNext = GetDateFromSpanAndUnit(source.WorkorderPreventiveMaintenance.dtNextServiceDate,
- source.WorkorderPreventiveMaintenance.GenerateSpanUnit,
- source.WorkorderPreventiveMaintenance.GenerateSpan);
+ #region Calculate reschedule dates
+ //Get the current next service date for calcs
+ DateTime dtNext = GetDateFromSpanAndUnit(source.WorkorderPreventiveMaintenance.dtNextServiceDate,
+ source.WorkorderPreventiveMaintenance.GenerateSpanUnit,
+ source.WorkorderPreventiveMaintenance.GenerateSpan);
- //Get to the desired day of the week if necessary...
- if (source.mWorkorderPreventiveMaintenance.DayOfTheWeek != AyaDayOfWeek.AnyDayOfWeek)
- {
- DayOfWeek desired = AyaToSystemDayOfWeek(source.mWorkorderPreventiveMaintenance.DayOfTheWeek);
- while (dtNext.DayOfWeek != desired)
- {
- dtNext = dtNext.AddDays(1);
- }
+ //Get to the desired day of the week if necessary...
+ if (source.mWorkorderPreventiveMaintenance.DayOfTheWeek != AyaDayOfWeek.AnyDayOfWeek)
+ {
+ DayOfWeek desired = AyaToSystemDayOfWeek(source.mWorkorderPreventiveMaintenance.DayOfTheWeek);
+ while (dtNext.DayOfWeek != desired)
+ {
+ dtNext = dtNext.AddDays(1);
+ }
- }
+ }
- //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
- System.TimeSpan tsToNext = dtNext - source.WorkorderPreventiveMaintenance.dtNextServiceDate;
+ //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
+ System.TimeSpan tsToNext = dtNext - source.WorkorderPreventiveMaintenance.dtNextServiceDate;
- #endregion
+ #endregion
- //Will the next workorder service date fall after the
- //stop generating date?
- if (source.WorkorderPreventiveMaintenance.StopGeneratingDate != System.DBNull.Value &&
- source.WorkorderPreventiveMaintenance.dtStopGeneratingDate < dtNext)
- {
- //Yes it will, so set it to inactive and bail out
- source.WorkorderPreventiveMaintenance.Active = false;
- source.Save();
- return dest;
- }
+ //Will the next workorder service date fall after the
+ //stop generating date?
+ if (source.WorkorderPreventiveMaintenance.StopGeneratingDate != System.DBNull.Value &&
+ source.WorkorderPreventiveMaintenance.dtStopGeneratingDate < dtNext)
+ {
+ //Yes it will, so set it to inactive and bail out
+ source.WorkorderPreventiveMaintenance.Active = false;
+ source.Save();
+ return dest;
+ }
- #region Reschedule PM
+ #region Reschedule PM
- source.WorkorderPreventiveMaintenance.dtNextServiceDate = dtNext;
- //Calcs the generate date (threshold date)
- source.WorkorderPreventiveMaintenance.SetGenerateDate();
- //WORKORDERITEMS
- foreach (WorkorderItem wisource in source.WorkorderItems)
- {
+ source.WorkorderPreventiveMaintenance.dtNextServiceDate = dtNext;
+ //Calcs the generate date (threshold date)
+ source.WorkorderPreventiveMaintenance.SetGenerateDate();
+ //WORKORDERITEMS
+ foreach (WorkorderItem wisource in source.WorkorderItems)
+ {
- wisource.RequestDate = wisource.RequestDate;
+ wisource.RequestDate = wisource.RequestDate;
- //PARTS
- //no date changes required
+ //PARTS
+ //no date changes required
- //SCHEDULED USERS
- foreach (WorkorderItemScheduledUser usersource in wisource.ScheduledUsers)
- {
- //Changed: 2-Oct-2006
- //check to not add a date if the original date was empty
- if (usersource.StartDate != System.DBNull.Value)
- usersource.dtStartDate = usersource.dtStartDate.Add(tsToNext);
+ //SCHEDULED USERS
+ foreach (WorkorderItemScheduledUser usersource in wisource.ScheduledUsers)
+ {
+ //Changed: 2-Oct-2006
+ //check to not add a date if the original date was empty
+ if (usersource.StartDate != System.DBNull.Value)
+ usersource.dtStartDate = usersource.dtStartDate.Add(tsToNext);
- if (usersource.StopDate != System.DBNull.Value)
- usersource.dtStopDate = usersource.dtStopDate.Add(tsToNext);
+ if (usersource.StopDate != System.DBNull.Value)
+ usersource.dtStopDate = usersource.dtStopDate.Add(tsToNext);
- }
+ }
- //LABOR
- foreach (WorkorderItemLabor laborsource in wisource.Labors)
- {
- //Changed: 2-Oct-2006
- //check to not add a date if the original date was empty
- if (laborsource.ServiceStartDate != System.DBNull.Value)
- laborsource.dtServiceStartDate = laborsource.dtServiceStartDate.Add(tsToNext);
+ //LABOR
+ foreach (WorkorderItemLabor laborsource in wisource.Labors)
+ {
+ //Changed: 2-Oct-2006
+ //check to not add a date if the original date was empty
+ if (laborsource.ServiceStartDate != System.DBNull.Value)
+ laborsource.dtServiceStartDate = laborsource.dtServiceStartDate.Add(tsToNext);
- if (laborsource.ServiceStopDate != System.DBNull.Value)
- laborsource.dtServiceStopDate = laborsource.dtServiceStopDate.Add(tsToNext);
+ if (laborsource.ServiceStopDate != System.DBNull.Value)
+ 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
- foreach (WorkorderItemTravel travelsource in wisource.Travels)
- {
- //Changed: 2-Oct-2006
- //check to not add a date if the original date was empty
- if (travelsource.TravelStartDate != DBNull.Value)
- travelsource.dtTravelStartDate = travelsource.dtTravelStartDate.Add(tsToNext);
+ //TRAVEL
+ foreach (WorkorderItemTravel travelsource in wisource.Travels)
+ {
+ //Changed: 2-Oct-2006
+ //check to not add a date if the original date was empty
+ if (travelsource.TravelStartDate != DBNull.Value)
+ travelsource.dtTravelStartDate = travelsource.dtTravelStartDate.Add(tsToNext);
- if (travelsource.TravelStopDate != DBNull.Value)
- travelsource.dtTravelStopDate = travelsource.dtTravelStopDate.Add(tsToNext);
+ if (travelsource.TravelStopDate != DBNull.Value)
+ 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
- #endregion reschedule pm
+ }//foreach workorderitem loop
+ #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
- try
- {
- source = (Workorder)source.Save();
- }
- catch (Exception exx)
- {
- dest.Delete();
- dest.Save();
- //crack the exception
- while (exx.InnerException != null)
- exx = exx.InnerException;
-
- Memo mwarn = Memo.NewItem();
- mwarn.ToID = User.AdministratorID;
-
- //case 3826
- if (User.CurrentUserType == UserTypes.Utility)
- {
- //Utility accounts should not be sending memos, it fucks up downstream
- //trying to view the memo, also it's confusing
- mwarn.FromID = User.AdministratorID;
- }
- else
- {
- mwarn.FromID = User.CurrentThreadUserID;
- }
-
-
- mwarn.Subject = "SYSTEM WARNING: Preventive Maintenance WO PROBLEM";
- 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 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("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("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("=================================");
- sb.AppendLine("Exception saving source PM:");
- sb.AppendLine(exx.Message);
- sb.AppendLine("=================================");
- string sSourceErr = source.GetBrokenRulesString();
- if (!string.IsNullOrWhiteSpace(sSourceErr))
- {
- sb.AppendLine("Broken business rules on PM object:");
- sb.AppendLine(sSourceErr);
- sb.AppendLine("==============================");
- }
- mwarn.Message = sb.ToString();
- mwarn.Save();
- throw new System.ApplicationException("Workorder->NewServiceWorkorderFromPM: Error during service workorder generation. Memo with details sent to Administrator account.");
-
-
-
- }
+ //case 1959 try catch block added to prevent infinite generation issue
+ try
+ {
+ source = (Workorder)source.Save();
+ }
+ catch (Exception exx)
+ {
+ dest.Delete();
+ dest.Save();
+ //crack the exception
+ while (exx.InnerException != null)
+ exx = exx.InnerException;
+
+ Memo mwarn = Memo.NewItem();
+ mwarn.ToID = User.AdministratorID;
+
+ //case 3826
+ if (User.CurrentUserType == UserTypes.Utility)
+ {
+ //Utility accounts should not be sending memos, it fucks up downstream
+ //trying to view the memo, also it's confusing
+ mwarn.FromID = User.AdministratorID;
+ }
+ else
+ {
+ mwarn.FromID = User.CurrentThreadUserID;
+ }
- //case 1630
- //copy wikipage from pm to service workorder
- if (dest.CanWiki && source.HasWiki)
- {
- try
- {
- WikiPage wpSource = WikiPage.GetItem(new TypeAndID(RootObjectTypes.WorkorderPreventiveMaintenance, source.ID));
- WikiPage wpDest = WikiPage.GetItem(new TypeAndID(RootObjectTypes.WorkorderService, dest.ID));
- wpDest.SetContent(wpSource.GetContent());
- wpDest.Save();
- }
- catch { };
-
- }
-
- return dest;
-
-
-
-
-
- }
-
-
-
- ///
- /// Calculate generate date based on service date and
- /// threshold span and unit
- ///
- internal void SetGenerateDate()
- {
- if (this.mNextServiceDate.IsEmpty) return;
- if (this.mThresholdSpan == 0)
- {
- this.mGenerateDate = this.mNextServiceDate;
- MarkDirty();
- return;
- }
- mGenerateDate = new SmartDate(Workorder.GetDateFromSpanAndUnit(mNextServiceDate.Date, this.mThresholdSpanUnit, -mThresholdSpan));
- MarkDirty();
- }
-
-
- #region Date time calcs helpers
- //Takes an AyaNova day of week and returns
- //a System.DayOfWeek
- //Assumes that AyaDayOfWeek is NOT "AnyDay"
- internal static System.DayOfWeek AyaToSystemDayOfWeek(AyaDayOfWeek day)
- {
- switch (day)
- {
- case AyaDayOfWeek.Monday:
- return DayOfWeek.Monday;
- case AyaDayOfWeek.Tuesday:
- return DayOfWeek.Tuesday;
- case AyaDayOfWeek.Wednesday:
- return DayOfWeek.Wednesday;
- case AyaDayOfWeek.Thursday:
- return DayOfWeek.Thursday;
- case AyaDayOfWeek.Friday:
- return DayOfWeek.Friday;
- case AyaDayOfWeek.Saturday:
- return DayOfWeek.Saturday;
- case AyaDayOfWeek.Sunday:
- return DayOfWeek.Sunday;
-
-
-
- }
-
- throw new System.ArgumentOutOfRangeException("DayOfWeekConverter: AyaDayOfWeek.AnyDayOfWeek is not supported");
- }
-
-
- internal static DateTime GetDateFromSpanAndUnit(DateTime StartDate, AyaUnitsOfTime unit, int multiple)
- {
- switch (unit)
- {
- case AyaUnitsOfTime.Seconds:
- return StartDate.AddSeconds(multiple);
-
- case AyaUnitsOfTime.Minutes:
- return StartDate.AddMinutes(multiple);
- case AyaUnitsOfTime.Hours:
- return StartDate.AddHours(multiple);
+ mwarn.Subject = "SYSTEM WARNING: Preventive Maintenance WO PROBLEM";
+ 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 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("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("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("=================================");
+ sb.AppendLine("Exception saving source PM:");
+ sb.AppendLine(exx.Message);
+ sb.AppendLine("=================================");
+ string sSourceErr = source.GetBrokenRulesString();
+ if (!string.IsNullOrWhiteSpace(sSourceErr))
+ {
+ sb.AppendLine("Broken business rules on PM object:");
+ sb.AppendLine(sSourceErr);
+ sb.AppendLine("==============================");
+ }
+ mwarn.Message = sb.ToString();
+ mwarn.Save();
+ throw new System.ApplicationException("Workorder->NewServiceWorkorderFromPM: Error during service workorder generation. Memo with details sent to Administrator account.");
- case AyaUnitsOfTime.Days:
- return StartDate.AddDays(multiple);
- case AyaUnitsOfTime.Weeks:
- throw new System.NotSupportedException("GetDateFromSpanAndUnit: Weeks not supported");
- case AyaUnitsOfTime.Months:
- return StartDate.AddMonths(multiple);
+ }
- case AyaUnitsOfTime.Years:
- return StartDate.AddYears(multiple);
+ //case 1630
+ //copy wikipage from pm to service workorder
+ if (dest.CanWiki && source.HasWiki)
+ {
+ try
+ {
+ WikiPage wpSource = WikiPage.GetItem(new TypeAndID(RootObjectTypes.WorkorderPreventiveMaintenance, source.ID));
+ WikiPage wpDest = WikiPage.GetItem(new TypeAndID(RootObjectTypes.WorkorderService, dest.ID));
+ wpDest.SetContent(wpSource.GetContent());
+ wpDest.Save();
+ }
+ catch { };
+ }
- }
+ return dest;
- //fail safe:
- return StartDate;
- }
-
-*/
- #endregion gen service wo from pm
+
+
+
+
+ }
+
+
+
+ ///
+ /// Calculate generate date based on service date and
+ /// threshold span and unit
+ ///
+ internal void SetGenerateDate()
+ {
+ if (this.mNextServiceDate.IsEmpty) return;
+ if (this.mThresholdSpan == 0)
+ {
+ this.mGenerateDate = this.mNextServiceDate;
+ MarkDirty();
+ return;
+ }
+ mGenerateDate = new SmartDate(Workorder.GetDateFromSpanAndUnit(mNextServiceDate.Date, this.mThresholdSpanUnit, -mThresholdSpan));
+ MarkDirty();
+ }
+
+
+ #region Date time calcs helpers
+ //Takes an AyaNova day of week and returns
+ //a System.DayOfWeek
+ //Assumes that AyaDayOfWeek is NOT "AnyDay"
+ internal static System.DayOfWeek AyaToSystemDayOfWeek(AyaDayOfWeek day)
+ {
+ switch (day)
+ {
+ case AyaDayOfWeek.Monday:
+ return DayOfWeek.Monday;
+ case AyaDayOfWeek.Tuesday:
+ return DayOfWeek.Tuesday;
+ case AyaDayOfWeek.Wednesday:
+ return DayOfWeek.Wednesday;
+ case AyaDayOfWeek.Thursday:
+ return DayOfWeek.Thursday;
+ case AyaDayOfWeek.Friday:
+ return DayOfWeek.Friday;
+ case AyaDayOfWeek.Saturday:
+ return DayOfWeek.Saturday;
+ case AyaDayOfWeek.Sunday:
+ return DayOfWeek.Sunday;
+
+
+
+ }
+
+ throw new System.ArgumentOutOfRangeException("DayOfWeekConverter: AyaDayOfWeek.AnyDayOfWeek is not supported");
+ }
+
+
+ internal static DateTime GetDateFromSpanAndUnit(DateTime StartDate, AyaUnitsOfTime unit, int multiple)
+ {
+ switch (unit)
+ {
+ case AyaUnitsOfTime.Seconds:
+ return StartDate.AddSeconds(multiple);
+
+ case AyaUnitsOfTime.Minutes:
+ return StartDate.AddMinutes(multiple);
+
+ case AyaUnitsOfTime.Hours:
+ return StartDate.AddHours(multiple);
+
+ case AyaUnitsOfTime.Days:
+ return StartDate.AddDays(multiple);
+
+ case AyaUnitsOfTime.Weeks:
+ throw new System.NotSupportedException("GetDateFromSpanAndUnit: Weeks not supported");
+
+ case AyaUnitsOfTime.Months:
+ return StartDate.AddMonths(multiple);
+
+ case AyaUnitsOfTime.Years:
+ return StartDate.AddYears(multiple);
+
+
+ }
+
+ //fail safe:
+ return StartDate;
+ }
+
+ */
+ #endregion gen service wo from pm
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 GetPMIdForNumberAsync(long woNumber, AyContext ct)
- // {
- // return await ct.PM.AsNoTracking()
- // .Where(z => z.Serial == woNumber)
- // .Select(z => z.Id)
- // .SingleOrDefaultAsync();
- // }
@@ -1156,7 +1146,7 @@ namespace AyaNova.Biz
return;//this is a completely disqualifying error
}
-
+
/*
todo: quote status list first, it's a table of created items, keep properties from v7 but add the following properties:
@@ -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
/////////////////////////////////////////////////////////////////////
diff --git a/server/AyaNova/generator/CoreJobPMGenerate.cs b/server/AyaNova/generator/CoreJobPMGenerate.cs
new file mode 100644
index 00000000..242752b5
--- /dev/null
+++ b/server/AyaNova/generator/CoreJobPMGenerate.cs
@@ -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
+{
+
+ ///
+ /// Preventive maintenance generator
+ /// turn PMs into Work orders
+ ///
+ ///
+ 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
+