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