diff --git a/source/Plugins/AyaNova.Plugin.V8/V8.cs b/source/Plugins/AyaNova.Plugin.V8/V8.cs
index ae00f33..8d7a6c0 100644
--- a/source/Plugins/AyaNova.Plugin.V8/V8.cs
+++ b/source/Plugins/AyaNova.Plugin.V8/V8.cs
@@ -3660,22 +3660,33 @@ namespace AyaNova.PlugIn.V8
╚═╝ ╚═╝ ╚═╝
*/
#region PM Workorders
+
+ int _highestPMNumberExported = 0;
private async System.Threading.Tasks.Task ExportPMs(ProgressForm progress)
{
if (!progress.KeepGoing) return;
progress.Op("Start Preventive Maintenance export");
progress.SubOp("");
- var ObjectTypeName = "Preventive Maintenance";
- var RavenObjectName = "PM";
- //TODO: this in the workorder Items loop
- ////Step 1: export the CustomFields to FormCustom if applicable so that when doing individual items we can export their custom data too
- //var ocf = ObjectHasCustomFieldDataToExport("WorkorderItem");
- //bool ShouldExportCustom = ocf != null;
- //var DateCustomFields = await ExportCustomFieldSchema(ocf, "WorkorderItem", "WorkOrderItem");
+
+ var ObjectTypeName = "PM";
+ progress.SubOp("");
+ //Step 1: export the CustomFields to FormCustom if applicable so that when doing individual items we can export their custom data too
+ var ocf = ObjectHasCustomFieldDataToExport("WorkorderItem");
+ bool ShouldExportCustom = ocf != null;
+ var DateCustomFields = await ExportCustomFieldSchema(ocf, "WorkorderItem", "WorkOrderItem");
//Step 2: export the objects
- WorkorderPMList pl = WorkorderPMList.GetList("");
- progress.Append("Exporting " + pl.Count.ToString() + " Service " + ObjectTypeName + "s");
+ //sort by woid
+ var crit = @"
+
+
+";
+
+ WorkorderPMList pl = WorkorderPMList.GetList(crit);
+ progress.Append("Exporting " + pl.Count.ToString() + " Preventive Maintenance orders");
+
+ //task picklist used over and over
+ var AllTasks = TaskPickList.GetList();
foreach (WorkorderPMList.WorkorderPMListInfo i in pl)
{
@@ -3683,58 +3694,248 @@ namespace AyaNova.PlugIn.V8
List tags = new List();
AddImportTag(tags);
+
Workorder c = Workorder.GetItem(i.LT_O_WorkorderPreventiveMaintenance.Value);
if (IsDuplicatev7v8IdMapItem(c.ID, c.WorkorderPreventiveMaintenance.PreventiveMaintenanceNumber.ToString(), progress)) continue;
var ObjectTID = new TypeAndID(RootObjectTypes.WorkorderPreventiveMaintenance, c.ID);
- //make one on the server to update
- var rMainObject = await util.PostAsync("pm" + "/Create?serial=" + c.WorkorderPreventiveMaintenance.PreventiveMaintenanceNumber);
- long RavenId = util.IdFromResponse(rMainObject);
- Addv7v8IdMap(c.ID, RavenId);
-
dynamic d = new JObject();
- d.concurrency = util.CTokenFromResponse(rMainObject);
progress.Op(ObjectTypeName + " " + c.WorkorderPreventiveMaintenance.PreventiveMaintenanceNumber);
- d.active = true;//probably can remove this at server, just stubbed in for now
+ progress.SubOp("");
+ d.serial = c.WorkorderPreventiveMaintenance.PreventiveMaintenanceNumber;
+ if (c.WorkorderPreventiveMaintenance.PreventiveMaintenanceNumber > _highestPMNumberExported)
+ _highestPMNumberExported = c.WorkorderPreventiveMaintenance.PreventiveMaintenanceNumber;
+ d.customerId = Getv7v8IdMap(c.ClientID, "Client for pm " + d.serial);
+ d.notes = c.Summary;
+ d.projectId = Getv7v8IdMapNullOk(c.ProjectID);
+ d.internalReferenceNumber = c.InternalReferenceNumber;
+ d.customerReferenceNumber = c.CustomerReferenceNumber;
+ d.customerContactName = c.CustomerContactName;
+ d.createdDate = util.DateToV8(c.Created, true);
+ d.contractId = Getv7v8IdMapNullOk(c.ContractIDResolved());
+
+ //PM specific fields
+
+
+
+ var client = c.uiClient;
+ if (client != null)
+ {
+ d.postAddress = client.MailToAddress.DeliveryAddress;
+ d.postCity = client.MailToAddress.City;
+ d.postRegion = client.MailToAddress.StateProv;
+ d.postCode = client.MailToAddress.Postal;
+ d.address = client.GoToAddress.DeliveryAddress;
+ d.city = client.GoToAddress.City;
+ d.region = client.GoToAddress.StateProv;
+ d.country = client.GoToAddress.Country;
+ d.latitude = client.GoToAddress.Latitude;
+ d.longitude = client.GoToAddress.Longitude;
+ }
+
TagFromv7Guid(c.RegionID, tags);
+ TagFromv7Guid(c.WorkorderCategoryID, tags);
+
SetTags(d, tags);
- ////Custom fields?
- //if (ShouldExportCustom)
- // d.customFields = CustomFieldData(c, DateCustomFields);
-
- // var rMainObject = await util.PostAsync(RavenObjectName, d.ToString());
+ var rMainObject = await util.PostAsync("pm", d.ToString());
+ long RavenId = util.IdFromResponse(rMainObject);
+ Addv7v8IdMap(c.ID, RavenId);
+ d = rMainObject.ObjectResponse["data"];
//Attachments / FILES
- await ExportAttachments(ObjectTID, progress, util.AyaType.PM);
+ await ExportAttachments(ObjectTID, progress, util.AyaType.WorkOrder);
+
+ //-----
- //-----
- bool repost = false;
- d = rMainObject.ObjectResponse["data"];
// wiki
if (WikiPage.HasWiki(c.ID))
- {
- // await ExportAttachments(ObjectTID, progress);
d.wiki = GetWikiContent(ObjectTID);
- repost = true;
- }
//docs
- string NonFileUrls = await ExportDocs(ObjectTID, c.Docs, progress, util.AyaType.PM);
+ string NonFileUrls = await ExportDocs(ObjectTID, c.Docs, progress, util.AyaType.WorkOrder);
if (!string.IsNullOrEmpty(NonFileUrls))
- {
d.notes = NonFileUrls + "\n-----------------\n" + d.notes;
- repost = true;
- }
- if (repost)
- await util.PutAsync("pm", d.ToString());
+
+ //put the header object
+ await util.PutAsync("pm", d.ToString());
//-----
//Event log fixup
- await util.EventLog(util.AyaType.PM, RavenId, SafeGetUserMap(c.Creator), SafeGetUserMap(c.Modifier), c.Created, c.Modified);
+ await util.EventLog(util.AyaType.WorkOrder, RavenId, SafeGetUserMap(c.Creator), SafeGetUserMap(c.Modifier), c.Created, c.Modified);
- //todo: workorder items etc
+
+ //##### ITEMS
+ int nSequence = 0;
+ foreach (WorkorderItem wi in c.WorkorderItems)
+ {
+ List witags = new List();
+ progress.SubOp("PMItem " + wi.ID.ToString());
+ dynamic dwi = new JObject();
+ dwi.pmId = RavenId;
+ dwi.sequence = ++nSequence;
+ if (!string.IsNullOrWhiteSpace(wi.Summary))//in v8 summary is reqd.
+ dwi.notes = wi.Summary;
+ else
+ dwi.notes = "Item " + nSequence.ToString();
+ dwi.techNotes = wi.TechNotes;
+ dwi.requestDate = util.DateToV8(wi.RequestDate);//allow empty dates if empty source
+ dwi.workorderItemStatusId = Getv7v8WorkOrderItemStatusIdNullOk(wi.WorkorderStatusID);
+ dwi.workorderItemPriorityId = Getv7v8IdMapNullOk(wi.PriorityID);
+ dwi.warrantyService = wi.WarrantyService;
+
+
+ TagFromv7Guid(wi.TypeID, witags);
+ SetTags(dwi, witags);
+
+ ////Custom fields?
+ if (ShouldExportCustom)
+ dwi.customFields = CustomFieldData(wi, DateCustomFields);
+
+
+ var ravenwoitemid = util.IdFromResponse(await util.PostAsync("pm/items", dwi.ToString()));
+ await util.EventLog(util.AyaType.WorkOrderItem, ravenwoitemid, SafeGetUserMap(wi.Creator), SafeGetUserMap(wi.Modifier), wi.Created, wi.Modified);
+
+ //##### WORKORDER ITEM UNIT
+ if (wi.UnitID != Guid.Empty)
+ {
+
+ //make sure we have a matching unit already
+ var ravUnitId = Getv7v8IdMapNullOk(wi.UnitID);
+ if (ravUnitId != null)
+ {
+ //we have a legit unit record, make it for v8
+ progress.SubOp("PMItemUnit " + wi.UnitID.ToString());
+ dynamic dwiu = new JObject();
+ dwiu.pmId = RavenId;
+ dwiu.pmItemId = ravenwoitemid;
+ dwiu.unitId = ravUnitId;
+ List wiutags = new List();
+ TagFromv7Guid(wi.WorkorderItemUnitServiceTypeID, wiutags);
+ SetTags(dwiu, wiutags);
+ await util.PostAsync("pm/items/units", dwiu.ToString());
+ }
+ }
+
+
+ //##### WORKORDER ITEM SCHEDULED USER
+ foreach (WorkorderItemScheduledUser wisu in wi.ScheduledUsers)
+ {
+ progress.SubOp("PMItemScheduledUser " + wisu.ID.ToString());
+ dynamic dwisu = new JObject();
+ dwisu.pmId = RavenId;
+ dwisu.pmItemId = ravenwoitemid;
+ //null is ok here for a sched user
+ dwisu.userId = Getv7v8IdMapNullOk(wisu.UserID);
+ dwisu.startDate = util.DateToV8(wisu.StartDate);
+ dwisu.stopDate = util.DateToV8(wisu.StopDate);
+ dwisu.estimatedQuantity = wisu.EstimatedQuantity;
+ dwisu.serviceRateId = Getv7v8IdMapNullOk(wisu.ServiceRateID);
+ await util.PostAsync("pm/items/scheduled-users", dwisu.ToString());
+ }
+
+ //##### WORKORDER ITEM PART
+ foreach (WorkorderItemPart wip in wi.Parts)
+ {
+ progress.SubOp("PMItemPart " + wip.ID.ToString());
+ dynamic dwip = new JObject();
+ dwip.pmId = RavenId;
+ dwip.pmItemId = ravenwoitemid;
+ dwip.quantity = wip.Quantity;
+ var tryPartId = Getv7v8IdMapNullOk(wip.PartID);
+ if (tryPartId == null)
+ {
+ dwip.partId = UnknownV7PartId;
+ if (wip.Quantity == 0 && string.IsNullOrWhiteSpace(wip.Description))
+ continue; //no part record, no quantity, no text at all, just skip it
+ }
+ else
+ dwip.partId = tryPartId;
+ dwip.partWarehouseId = Getv7v8IdMap(wip.PartWarehouseID, "warehouse");
+ dwip.taxPartSaleId = Getv7v8IdMapNullOk(wip.TaxPartSaleID);
+ if (wip.Discount != 0)
+ dwip.priceOverride = wip.Price - (wip.Price * wip.Discount);
+ else
+ dwip.priceOverride = wip.Price;
+ dwip.price = wip.Price;
+ dwip.cost = wip.Cost;
+ dwip.description = wip.Description;
+ if (wip.PartSerialID != Guid.Empty)
+ dwip.serials = PartSerial.GetSerialNumberFromPartSerialID(wip.PartSerialID);
+ await util.PostAsync("pm/items/parts", dwip.ToString());
+ }
+
+
+
+ //##### WORKORDER ITEM LABOR
+ foreach (WorkorderItemLabor wl in wi.Labors)
+ {
+ progress.SubOp("PMItemLabor " + wl.ID.ToString());
+ dynamic dwl = new JObject();
+ dwl.pmId = RavenId;
+ dwl.pmItemId = ravenwoitemid;
+ //null is ok here for user
+ dwl.userId = Getv7v8IdMapNullOk(wl.UserID);
+ dwl.serviceStartDate = util.DateToV8(wl.ServiceStartDate);
+ dwl.serviceStopDate = util.DateToV8(wl.ServiceStopDate);
+ dwl.serviceRateQuantity = wl.ServiceRateQuantity;
+ dwl.noChargeQuantity = wl.NoChargeQuantity;
+ dwl.taxCodeSaleId = Getv7v8IdMapNullOk(wl.TaxRateSaleID);
+ dwl.serviceRateId = Getv7v8IdMapNullOk(wl.ServiceRateID);
+ dwl.serviceDetails = wl.ServiceDetails;
+
+ await util.PostAsync("pm/items/labors", dwl.ToString());
+ }
+
+ //##### WORKORDER ITEM TRAVEL
+ foreach (WorkorderItemTravel wt in wi.Travels)
+ {
+ progress.SubOp("PMItemTravel " + wt.ID.ToString());
+ dynamic dwt = new JObject();
+ dwt.pmId = RavenId;
+ dwt.pmItemId = ravenwoitemid;
+ //null is ok here for user
+ dwt.userId = Getv7v8IdMapNullOk(wt.UserID);
+ dwt.travelStartDate = util.DateToV8(wt.TravelStartDate);
+ dwt.travelStopDate = util.DateToV8(wt.TravelStopDate);
+ dwt.travelRateQuantity = wt.TravelRateQuantity;
+ dwt.noChargeQuantity = wt.NoChargeQuantity;
+ dwt.taxCodeSaleId = Getv7v8IdMapNullOk(wt.TaxRateSaleID);
+ dwt.travelRateId = Getv7v8IdMapNullOk(wt.TravelRateID);
+ dwt.travelDetails = wt.TravelDetails;
+ dwt.distance = wt.Distance;
+ await util.PostAsync("pm/items/travels", dwt.ToString());
+ }
+
+ //##### WORKORDER ITEM TASKS
+ int nTaskSequence = 0;
+ foreach (WorkorderItemTask wt in wi.Tasks)
+ {
+ progress.SubOp("PMItemTask " + wt.ID.ToString());
+ //var tg = TaskGroup.GetItem(wt.TaskGroupID);
+ dynamic dwt = new JObject();
+ dwt.pmId = RavenId;
+ dwt.pmItemId = ravenwoitemid;
+ dwt.sequence = ++nTaskSequence;
+ var task = AllTasks[wt.TaskID];
+ dwt.task = task.Name;
+ dwt.status = (int)wt.WorkorderItemTaskCompletionType;//same enum values in v8
+ //these two fields don't really exist in v7 so leaving out for now
+ //but could wing it if necessary for some reason
+ //dwt.completedByUserId = Getv7v8IdMapNullOk(wt.Modifier);
+ //dwt.completedDate=
+ await util.PostAsync("pm/items/tasks", dwt.ToString());
+ }
+
+
+ }//items loop
+ }//wo loop
+
+ //set new seed number for work orders
+ _highestPMNumberExported += 1;
+ {
+ await util.PutAsync("global-biz-setting/seeds/21/" + _highestPMNumberExported.ToString());
}
}
#endregion PM Workorders