From 2742d3a1a356fa218a3d3e5b978917af6aac0b61 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Tue, 17 Aug 2021 18:25:54 +0000 Subject: [PATCH] --- source/Plugins/AyaNova.Plugin.V8/V8.cs | 609 ++++++++++++++++++++----- 1 file changed, 505 insertions(+), 104 deletions(-) diff --git a/source/Plugins/AyaNova.Plugin.V8/V8.cs b/source/Plugins/AyaNova.Plugin.V8/V8.cs index b349de6..669dc34 100644 --- a/source/Plugins/AyaNova.Plugin.V8/V8.cs +++ b/source/Plugins/AyaNova.Plugin.V8/V8.cs @@ -368,9 +368,7 @@ namespace AyaNova.PlugIn.V8 await ExportWorkorderStatus(progress);//item and workorder both as split in v8 await ExportWorkOrderItemPriorities(progress); await ExportServiceWorkorders(progress); - //MIGRATE_OUTSTANDING - here can fixup loanitem workorder id's - - // await ExportQuotes(progress); + await ExportQuotes(progress); // await ExportPMs(progress); //Must be after all root objects due to followups @@ -1469,90 +1467,91 @@ namespace AyaNova.PlugIn.V8 } } - - private async System.Threading.Tasks.Task FlagWoForLoanItems(ProgressForm progress) - { + //todo: maybe, seems as though only v8 has a field in the loanitem for woid and v7 doesn't so...?? + //perhaps v8 is automatically flagging it when the woitemloan record is created? +// private async System.Threading.Tasks.Task FlagWoForLoanItems(ProgressForm progress) +// { - if (!progress.KeepGoing) return; - progress.Op("Start update loan items with current work order id"); - progress.SubOp(""); +// if (!progress.KeepGoing) return; +// progress.Op("Start update loan items with current work order id"); +// progress.SubOp(""); - PickListAutoComplete pl = PickListAutoComplete.GetList("**", "loanitem"); +// PickListAutoComplete pl = PickListAutoComplete.GetList("**", "loanitem"); - foreach (PickListAutoComplete.PickListAutoCompleteInfo i in pl) - { - if (!progress.KeepGoing) return; +// foreach (PickListAutoComplete.PickListAutoCompleteInfo i in pl) +// { +// if (!progress.KeepGoing) return; - LoanItem c = LoanItem.GetItem(i.ID); - dynamic d = new JObject(); - if(c.WorkorderLoanId!=guid.empty){ +// LoanItem c = LoanItem.GetItem(i.ID); +// dynamic d = new JObject(); +// if(c.l!=guid.empty){ - d= (await util.GetAsync("loan-unit/"+ Getv7v8IdMap(i.ID,"loan item for updat of workorder"))).objectResponse; +// d= (await util.GetAsync("loan-unit/"+ Getv7v8IdMap(i.ID,"loan item for updat of workorder"))).objectResponse; -d.workorderItemLoanId= - } +//d.workorderItemLoanId= +// } - d.name = GetUniqueName(c.Name); - if (IsDuplicatev7v8IdMapItem(c.ID, c.Name, progress)) continue; - progress.Op(ObjectTypeName + " " + d.name); - d.active = c.Active; - d.notes = c.Notes; - d.serial = c.Serial; - //MIGRATE_OUTSTANDING - //fixup after workorders - // - d.rateHour = c.RateHour; - d.rateHalfDay = c.RateHalfDay; - d.rateDay = c.RateDay; - d.rateWeek = c.RateWeek; - d.rateMonth = c.RateMonth; - d.rateYear = c.RateYear; - d.defaultRate = 1; +// d.name = GetUniqueName(c.Name); +// if (IsDuplicatev7v8IdMapItem(c.ID, c.Name, progress)) continue; +// progress.Op(ObjectTypeName + " " + d.name); +// d.active = c.Active; +// d.notes = c.Notes; +// d.serial = c.Serial; +// //MIGRATE_OUTSTANDING +// //fixup after workorders +// // +// d.rateHour = c.RateHour; +// d.rateHalfDay = c.RateHalfDay; +// d.rateDay = c.RateDay; +// d.rateWeek = c.RateWeek; +// d.rateMonth = c.RateMonth; +// d.rateYear = c.RateYear; +// d.defaultRate = 1; - TagFromv7Guid(c.RegionID, tags); - SetTags(d, tags); +// TagFromv7Guid(c.RegionID, tags); +// SetTags(d, tags); - //Custom fields? - if (ShouldExportCustom) - d.customFields = CustomFieldData(c, DateCustomFields); +// //Custom fields? +// if (ShouldExportCustom) +// d.customFields = CustomFieldData(c, DateCustomFields); - var rMainObject = await util.PostAsync("loan-unit", d.ToString()); - long RavenId = util.IdFromResponse(rMainObject); - Addv7v8IdMap(c.ID, RavenId); +// var rMainObject = await util.PostAsync("loan-unit", d.ToString()); +// long RavenId = util.IdFromResponse(rMainObject); +// Addv7v8IdMap(c.ID, RavenId); - //Attachments / FILES - await ExportAttachments(ObjectTID, progress); +// //Attachments / FILES +// await ExportAttachments(ObjectTID, progress); - //----- - bool repost = false; - d = rMainObject.ObjectResponse["data"]; - // wiki - if (WikiPage.HasWiki(c.ID)) - { - // await ExportAttachments(ObjectTID, progress); - d.wiki = GetWikiContent(ObjectTID); - repost = true; - } +// //----- +// 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); - if (!string.IsNullOrEmpty(NonFileUrls)) - { - d.notes = NonFileUrls + "\n-----------------\n" + d.notes; - repost = true; - } - if (repost) - await util.PutAsync("loan-unit", d.ToString()); - //----- +// //docs +// string NonFileUrls = await ExportDocs(ObjectTID, c.Docs, progress); +// if (!string.IsNullOrEmpty(NonFileUrls)) +// { +// d.notes = NonFileUrls + "\n-----------------\n" + d.notes; +// repost = true; +// } +// if (repost) +// await util.PutAsync("loan-unit", d.ToString()); +// //----- - //Event log fixup - await util.EventLog(util.AyaType.LoanUnit, RavenId, SafeGetUserMap(c.Creator), SafeGetUserMap(c.Modifier), c.Created, c.Modified); +// //Event log fixup +// await util.EventLog(util.AyaType.LoanUnit, RavenId, SafeGetUserMap(c.Creator), SafeGetUserMap(c.Modifier), c.Created, c.Modified); - } - } +// } +// } #endregion LoanItems @@ -3281,81 +3280,483 @@ d.workorderItemLoanId= ╚══▀▀═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝ */ #region Quote Workorders + int _highestQuoteNumberExported = 0; private async System.Threading.Tasks.Task ExportQuotes(ProgressForm progress) { if (!progress.KeepGoing) return; progress.Op("Start Quotes export"); progress.SubOp(""); var ObjectTypeName = "Quote"; - var RavenObjectName = "Quote"; - //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"); + + //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 - WorkorderQuoteList pl = WorkorderQuoteList.GetList(""); - progress.Append("Exporting " + pl.Count.ToString() + " " + ObjectTypeName + "s"); + //sort by woid + var crit = @" + + +"; - foreach (WorkorderQuoteList.WorkorderQuoteListInfo i in pl) + WorkorderQuoteList pl = WorkorderQuoteList.GetList(crit); + progress.Append("Exporting " + pl.Count.ToString() + " Quotes"); + + //task picklist used over and over + var AllTasks = TaskPickList.GetList(); + + foreach (WorkorderServiceList.WorkorderServiceListInfo i in pl) { if (!progress.KeepGoing) return; List tags = new List(); AddImportTag(tags); - Workorder c = Workorder.GetItem(i.LT_O_WorkorderQuote.Value); - if (IsDuplicatev7v8IdMapItem(c.ID, c.WorkorderQuote.QuoteNumber.ToString(), progress)) continue; - var ObjectTID = new TypeAndID(RootObjectTypes.WorkorderQuote, c.ID); - //make one on the server to update - var rMainObject = await util.PostAsync("quote" + "/Create?serial=" + c.WorkorderQuote.QuoteNumber); - long RavenId = util.IdFromResponse(rMainObject); - Addv7v8IdMap(c.ID, RavenId); + Workorder c = Workorder.GetItem(i.LT_O_Workorder.Value); + if (IsDuplicatev7v8IdMapItem(c.ID, c.WorkorderService.ServiceNumber.ToString(), progress)) continue; + var ObjectTID = new TypeAndID(RootObjectTypes.WorkorderService, c.ID); dynamic d = new JObject(); - d.concurrency = util.CTokenFromResponse(rMainObject); - progress.Op(ObjectTypeName + " " + c.WorkorderQuote.QuoteNumber); - d.active = true;//probably can remove this at server, just stubbed in for now + progress.Op(ObjectTypeName + " " + c.WorkorderService.ServiceNumber); + + d.serial = c.WorkorderService.ServiceNumber; + if (c.WorkorderService.ServiceNumber > _highestWorkOrderNumberExported) + _highestWorkOrderNumberExported = c.WorkorderService.ServiceNumber; + d.customerId = Getv7v8IdMap(c.ClientID, "Client for wo " + 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.serviceDate = util.DateToV8(c.WorkorderService.ServiceDate); + d.completeByDate = util.DateToV8(c.WorkorderService.CloseByDate); + d.invoiceNumber = c.WorkorderService.InvoiceNumber; + d.onsite = c.Onsite; + d.contractId = Getv7v8IdMapNullOk(c.ContractIDResolved()); + d.lastStatusId = Getv7v8IdMapNullOk(c.WorkorderService.WorkorderStatusID); + + 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; + } + + if (c.uiHasSignature) + { + d.customerSignature = util.v7StrokePathTov8SVG(c.WorkorderService.Signature.StrokePath, c.WorkorderService.Signature.Width, c.WorkorderService.Signature.Height); + d.customerSignatureCaptured = util.DateToV8(c.WorkorderService.Signature.ClientCapturedDateTime); + } 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("workorder", d.ToString()); + long RavenId = util.IdFromResponse(rMainObject); + Addv7v8IdMap(c.ID, RavenId); + d = rMainObject.ObjectResponse["data"]; //Attachments / FILES - await ExportAttachments(ObjectTID, progress, util.AyaType.Quote); + 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.Quote); + string NonFileUrls = await ExportDocs(ObjectTID, c.Docs, progress, util.AyaType.WorkOrder); if (!string.IsNullOrEmpty(NonFileUrls)) { + ////need to repost the user with the notes modified + + //d.login = null; + //d.password = null; d.notes = NonFileUrls + "\n-----------------\n" + d.notes; - repost = true; + } - if (repost) - await util.PutAsync("quote", d.ToString()); + + //put the header object + await util.PutAsync("workorder", d.ToString()); //----- //Event log fixup - await util.EventLog(util.AyaType.Quote, 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 + //######### STATE ####### + //if closed then set that state as well but always first set the current state + { + progress.SubOp("STATE"); + if (c.WorkorderService.WorkorderStatusID != Guid.Empty) + { + dynamic state = new JObject(); + state.workOrderId = RavenId; + state.workOrderStatusId = Getv7v8IdMap(c.WorkorderService.WorkorderStatusID, "Workorder status"); + state.created = util.DateToV8(c.Created, true); + state.userId = Getv7v8IdMap(c.Creator, "Workorder creator for status"); + await util.PostAsync("workorder/states", state.ToString()); + } + if (c.ServiceCompleted) + { + dynamic state = new JObject(); + state.workOrderId = RavenId; + state.workOrderStatusId = ServiceCompletedWorkOrderStatus; + state.created = util.DateToV8(c.Created, true); + state.userId = Getv7v8IdMap(c.Creator, "Workorder creator for status"); + await util.PostAsync("workorder/states", state.ToString()); + } + if (c.Closed) + { + dynamic state = new JObject(); + state.workOrderId = RavenId; + state.workOrderStatusId = ClosedWorkOrderStatus; + state.created = util.DateToV8(c.Created, true); + state.userId = Getv7v8IdMap(c.Creator, "Workorder creator for status"); + await util.PostAsync("workorder/states", state.ToString()); + } + } + + + //##### ITEMS + int nSequence = 0; + foreach (WorkorderItem wi in c.WorkorderItems) + { + List witags = new List(); + progress.SubOp("WorkorderItem " + wi.ID.ToString()); + dynamic dwi = new JObject(); + dwi.workOrderId = 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("workorder/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("WorkorderItemUnit " + wi.UnitID.ToString()); + dynamic dwiu = new JObject(); + dwiu.workOrderId = RavenId; + dwiu.workorderItemId = ravenwoitemid; + dwiu.unitId = ravUnitId; + List wiutags = new List(); + TagFromv7Guid(wi.WorkorderItemUnitServiceTypeID, wiutags); + SetTags(dwiu, wiutags); + await util.PostAsync("workorder/items/units", dwiu.ToString()); + } + } + + + //##### WORKORDER ITEM SCHEDULED USER + foreach (WorkorderItemScheduledUser wisu in wi.ScheduledUsers) + { + progress.SubOp("WorkorderItemScheduledUser " + wisu.ID.ToString()); + dynamic dwisu = new JObject(); + dwisu.workOrderId = RavenId; + dwisu.workorderItemId = 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("workorder/items/scheduled-users", dwisu.ToString()); + } + + //##### WORKORDER ITEM PART + foreach (WorkorderItemPart wip in wi.Parts) + { + progress.SubOp("WorkorderItemPart " + wip.ID.ToString()); + dynamic dwip = new JObject(); + dwip.workOrderId = RavenId; + dwip.workorderItemId = 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("workorder/items/parts", dwip.ToString()); + } + + //##### WORKORDER ITEM PARTREQUEST + foreach (WorkorderItemPartRequest wipr in wi.PartRequests) + { + progress.SubOp("WorkorderItemPartRequest " + wipr.ID.ToString()); + if (wipr.Quantity == 0) continue; + + JObject dPO = null; + JObject v8poitemtoupdate = null; + dynamic dwipr = new JObject(); + dwipr.workOrderId = RavenId; + dwipr.workorderItemId = ravenwoitemid; + dwipr.quantity = wipr.Quantity; + var tryPartId = Getv7v8IdMapNullOk(wipr.PartID); + if (tryPartId == null) + { + dwipr.partId = UnknownV7PartId; + } + else + dwipr.partId = tryPartId; + dwipr.partWarehouseId = Getv7v8IdMap(wipr.PartWarehouseID, "warehouse"); + + poitemtowoitempartrequest pto = PoItemPartRequestMap.FirstOrDefault(z => z.v7woitempartrequestid == wipr.ID); + if (pto != null) + { + //tag this part request with the v8 poitem id that matches + //get v8 po id + //fetch po + //iterate po and look for item with the vendorpartnumber set to this woitempartid by guid string + //update the po item with the raven partrequestid + //save po + long? v8poid = Getv7v8IdMapNullOk(pto.v7poid); + if (v8poid != null) + { + var a = await util.GetAsync("purchase-order/" + v8poid.ToString()); + dPO = (JObject)a.ObjectResponse["data"]; + if (dPO != null) + { + v8poitemtoupdate = (JObject)dPO["items"].FirstOrDefault(z => (string)z["vendorPartNumber"] == wipr.ID.ToString()); + if (v8poitemtoupdate != null) + { + //update the woitempart request purchase order item id + dwipr.purchaseOrderItemId = (long)v8poitemtoupdate["id"]; + + } + } + } + } + + //TODO: if migrate purchase orders this is reqd + // dwipr.purchaseOrderItemId = Getv7v8IdMapNullOk(wipr.PurchaseOrderItemID); + long v8partrequestid = util.IdFromResponse(await util.PostAsync("workorder/items/part-requests", dwipr.ToString())); + + //SAVE PO if fetched and updated here + if (dPO != null && v8poitemtoupdate != null) + { + //save the PO + v8poitemtoupdate["workorderItemPartRequestId"] = v8partrequestid; + v8poitemtoupdate["vendorPartNumber"] = null; + await util.PutAsync("purchase-order", dPO.ToString()); + } + + } + + //##### WORKORDER ITEM LOANERS + foreach (WorkorderItemLoan wil in wi.Loans) + { + progress.SubOp("WorkorderItemLoan " + wil.ID.ToString()); + dynamic dwil = new JObject(); + dwil.workOrderId = RavenId; + dwil.workorderItemId = ravenwoitemid; + + dwil.loanUnitId = Getv7v8IdMap(wil.LoanItemID, "loan unit for workorder"); + dwil.outDate = util.DateToV8(wil.OutDate); + dwil.dueDate = util.DateToV8(wil.DueDate); + dwil.returnDate = util.DateToV8(wil.ReturnDate); + dwil.taxCodeId = Getv7v8IdMapNullOk(wil.TaxCodeID); + dwil.quantity = wil.Quantity; + switch (wil.Rate) + { + case LoanItemRates.Days: + dwil.rate = 3; + break; + case LoanItemRates.HalfDays: + dwil.rate = 2; + break; + case LoanItemRates.Hours: + dwil.rate = 1; + break; + case LoanItemRates.Months: + dwil.rate = 5; + break; + case LoanItemRates.None: + dwil.rate = 0; + break; + case LoanItemRates.Weeks: + dwil.rate = 4; + break; + case LoanItemRates.Years: + dwil.rate = 6; + break; + } + dwil.priceOverride = wil.Charges; + dwil.notes = wil.Notes; + await util.PostAsync("workorder/items/loans", dwil.ToString()); + } + + //##### WORKORDER ITEM LABOR + foreach (WorkorderItemLabor wl in wi.Labors) + { + progress.SubOp("WorkorderItemLabor " + wl.ID.ToString()); + dynamic dwl = new JObject(); + dwl.workOrderId = RavenId; + dwl.workorderItemId = 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("workorder/items/labors", dwl.ToString()); + } + + //##### WORKORDER ITEM TRAVEL + foreach (WorkorderItemTravel wt in wi.Travels) + { + progress.SubOp("WorkorderItemTravel " + wt.ID.ToString()); + dynamic dwt = new JObject(); + dwt.workOrderId = RavenId; + dwt.workorderItemId = 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("workorder/items/travels", dwt.ToString()); + } + + //##### WORKORDER ITEM TASKS + int nTaskSequence = 0; + foreach (WorkorderItemTask wt in wi.Tasks) + { + progress.SubOp("WorkorderItemTask " + wt.ID.ToString()); + //var tg = TaskGroup.GetItem(wt.TaskGroupID); + dynamic dwt = new JObject(); + dwt.workOrderId = RavenId; + dwt.workorderItemId = 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("workorder/items/tasks", dwt.ToString()); + } + + //##### WORKORDER ITEM EXPENSES + foreach (WorkorderItemMiscExpense we in wi.Expenses) + { + progress.SubOp("WorkorderItemExpense " + we.ID.ToString()); + dynamic dwe = new JObject(); + dwe.workOrderId = RavenId; + dwe.workorderItemId = ravenwoitemid; + dwe.description = we.Description; + dwe.name = we.Name; + dwe.totalCost = we.TotalCost; + dwe.chargeAmount = we.ChargeAmount; + dwe.taxPaid = we.TaxPaid; + dwe.chargeTaxCodeId = Getv7v8IdMapNullOk(we.ChargeTaxCodeID); + dwe.reimburseUser = we.ReimburseUser; + dwe.userId = Getv7v8IdMapNullOk(we.UserID); + dwe.chargeToCustomer = we.ChargeToClient; + await util.PostAsync("workorder/items/expenses", dwe.ToString()); + } + + //##### WORKORDER ITEM OUTSIDE SERVICE + if (wi.HasOutsideService) + { + + //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("WorkorderItemOutsideService"); + dynamic dwio = new JObject(); + dwio.workOrderId = RavenId; + dwio.workorderItemId = ravenwoitemid; + dwio.unitId = ravUnitId; + dwio.notes = wi.OutsideService.Notes; + dwio.vendorSentToId = Getv7v8IdMapNullOk(wi.OutsideService.VendorSentToID); + dwio.vendorSentViaId = Getv7v8IdMapNullOk(wi.OutsideService.VendorSentViaID); + dwio.rMANumber = wi.OutsideService.RMANumber; + dwio.trackingNumber = wi.OutsideService.TrackingNumber; + dwio.repairCost = wi.OutsideService.RepairCost; + dwio.repairPrice = wi.OutsideService.RepairPrice; + dwio.shippingCost = wi.OutsideService.ShippingCost; + dwio.shippingPrice = wi.OutsideService.ShippingPrice; + dwio.sentDate = util.DateToV8(wi.OutsideService.DateSent); + dwio.eTADate = util.DateToV8(wi.OutsideService.DateETA); + dwio.returnDate = util.DateToV8(wi.OutsideService.DateReturned); + await util.PostAsync("workorder/items/outside-services", dwio.ToString()); + } + } + + + }//items loop + }//wo loop + + //set new seed number for work orders + _highestQuoteNumberExported += 1; + { + await util.PutAsync("global-biz-setting/seeds/27/" + _highestQuoteNumberExported.ToString()); } } #endregion Quotes