diff --git a/source/Plugins/AyaNova.Plugin.V8/V8.cs b/source/Plugins/AyaNova.Plugin.V8/V8.cs index 3812d9b..8120e89 100644 --- a/source/Plugins/AyaNova.Plugin.V8/V8.cs +++ b/source/Plugins/AyaNova.Plugin.V8/V8.cs @@ -168,12 +168,7 @@ namespace AyaNova.PlugIn.V8 #endregion - //this holds all objects set to use banking - //so that as a final step the servicebank can iterate - //it and migrate (objects need to exist first in v8) - // private Dictionary BankedObjects = new Dictionary(); - - + private Dictionary V7ToV8IdMap = new Dictionary(); private void Addv7v8IdMap(Guid v7id, long v8id) { @@ -236,6 +231,10 @@ namespace AyaNova.PlugIn.V8 return V7ToV8IdMap[id]; } + + + + private enum RavenUserType : int { Service = 1, @@ -1327,12 +1326,14 @@ namespace AyaNova.PlugIn.V8 dynamic dcr = new JObject(); if (RateList[cr.RateID].RateType == RateTypes.Service) { - dcr.serviceRateId = Getv7v8IdMap(cr.RateID, "ServiceRate for Contract " + d.name); + //dcr.serviceRateId = Getv7v8IdMap(cr.RateID, "ServiceRate for Contract " + d.name); + dcr.serviceRateId = await GetRate(false, cr.RateID, true); dServiceRateItems.Add(dcr); } else { - dcr.travelRateId = Getv7v8IdMap(cr.RateID, "TravelRate for Contract " + d.name); + //dcr.travelRateId = Getv7v8IdMap(cr.RateID, "TravelRate for Contract " + d.name); + dcr.travelRateId = await GetRate(true, cr.RateID, true); dTravelRateItems.Add(dcr); } } @@ -2390,9 +2391,13 @@ namespace AyaNova.PlugIn.V8 #endregion Vendors #region Rates + private Dictionary TravelRateMap = new Dictionary(); + private Dictionary ServiceRateMap = new Dictionary(); private async System.Threading.Tasks.Task ExportRates(ProgressForm progress) { ResetUniqueNames(); + TravelRateMap.Clear(); + ServiceRateMap.Clear(); if (!progress.KeepGoing) return; progress.Op("Start Rates export"); progress.SubOp(""); @@ -2414,6 +2419,15 @@ namespace AyaNova.PlugIn.V8 dynamic d = new JObject(); d.name = GetUniqueName(i.Name); + bool isTravelRate = i.RateType == RateTypes.Travel; + + if (!isTravelRate) + { + if (ServiceRateMap.ContainsKey(i.ID)) continue; + } + else + if (TravelRateMap.ContainsKey(i.ID)) continue; + if (IsDuplicatev7v8IdMapItem(i.ID, i.Name, progress)) continue; progress.Op(ObjectTypeName + " " + d.name); d.active = i.Active; @@ -2443,7 +2457,10 @@ namespace AyaNova.PlugIn.V8 var rMainObject = await util.PostAsync(route, d.ToString()); long RavenId = util.IdFromResponse(rMainObject); - Addv7v8IdMap(i.ID, RavenId); + if (isTravelRate) + TravelRateMap.Add(i.ID, RavenId); + else + ServiceRateMap.Add(i.ID, RavenId); //----- @@ -2453,6 +2470,70 @@ namespace AyaNova.PlugIn.V8 } } + + //rates in v7 are combined travel and service and the ui allows to change them so some records may need + //a historical travel rate but it is now a service rate in v7 and was exported as such + //so this code either returns the rate if ok or cross exports the rate to the other type then returns that rate + private async System.Threading.Tasks.Task GetRate(bool wantTravel, Guid rateId, bool mustExist=false) + { + if(!mustExist && rateId==Guid.Empty) return null; + + if (!wantTravel)//looking for a service rate + { + //we have it already? + if (ServiceRateMap.ContainsKey(rateId)) return ServiceRateMap[rateId]; + //not in service rates, maybe it's a cross rate from travel check there... + if (TravelRateMap.ContainsKey(rateId)) + { + //yup, it is now a travel rate but once was a service rate so dupe this travel to service, add to service mapt and return the id + long sourceRavenRateId = TravelRateMap[rateId]; + //get the source rate and save to the cross rate add to map and return + dynamic d = (await util.GetAsync("travel-rate/" + sourceRavenRateId)).ObjectResponse; + d.active = false;//assume it's no longer active + d.name = d.name + " (v8 migrate required)"; + d.notes = d.notes + "\nThis record created automatically by v8 migrate because a migrated record is using this as a Service rate but it was changed in v7 to a Travel rate"; + d.remove("id"); + d.remove("concurrency"); + long ravenId = util.IdFromResponse((await util.PostAsync("service-rate", d.ToString()))); + ServiceRateMap.Add(rateId, ravenId); + return ravenId; + } + //nope, it's non-existant anywhere + if (mustExist) + throw new Exception("Mandatory Rate missing, cannot proceed, last logged item needs to be fixed"); + else + return null; + } + else + {//looking for travel rate + //we have it already? + if (TravelRateMap.ContainsKey(rateId)) return TravelRateMap[rateId]; + //not in travel rates, maybe it's a cross rate from service check there... + if (ServiceRateMap.ContainsKey(rateId)) + { + //yup, it is now a service rate but once was a travel rate so dupe this service to travel + //, add to travel map and return the id + long sourceRavenRateId = ServiceRateMap[rateId]; + //get the source rate and save to the cross rate add to map and return + dynamic d = (await util.GetAsync("service-rate/" + sourceRavenRateId)).ObjectResponse; + d.active = false;//assume it's no longer active + d.name = d.name + " (v8 migrate required)"; + d.notes = d.notes + "\nThis record created automatically by v8 migrate because a migrated record is using this as a Travel rate but it was changed in v7 to a Service rate"; + d.remove("id"); + d.remove("concurrency"); + long ravenId = util.IdFromResponse((await util.PostAsync("travel-rate", d.ToString()))); + TravelRateMap.Add(rateId, ravenId); + return ravenId; + } + //nope, it's non-existant anywhere + if (mustExist) + throw new Exception("Mandatory Rate missing, cannot proceed, last logged item needs to be fixed"); + else + return null; + } + + + } #endregion Rates #region TaxCodes @@ -2929,7 +3010,8 @@ namespace AyaNova.PlugIn.V8 dwisu.startDate = util.DateToV8(wisu.StartDate); dwisu.stopDate = util.DateToV8(wisu.StopDate); dwisu.estimatedQuantity = wisu.EstimatedQuantity; - dwisu.serviceRateId = Getv7v8IdMapNullOk(wisu.ServiceRateID); + //dwisu.serviceRateId = Getv7v8IdMapNullOk(wisu.ServiceRateID); + dwisu.serviceRateId = await GetRate(false,wisu.ServiceRateID); await util.PostAsync("workorder/items/scheduled-users", dwisu.ToString()); } @@ -3084,7 +3166,7 @@ namespace AyaNova.PlugIn.V8 dwl.serviceRateQuantity = wl.ServiceRateQuantity; dwl.noChargeQuantity = wl.NoChargeQuantity; dwl.taxCodeSaleId = Getv7v8IdMapNullOk(wl.TaxRateSaleID); - dwl.serviceRateId = Getv7v8IdMapNullOk(wl.ServiceRateID); + dwl.serviceRateId = await GetRate(false, wl.ServiceRateID);//Getv7v8IdMapNullOk(wl.ServiceRateID); dwl.serviceDetails = wl.ServiceDetails; await util.PostAsync("workorder/items/labors", dwl.ToString()); @@ -3104,7 +3186,7 @@ namespace AyaNova.PlugIn.V8 dwt.travelRateQuantity = wt.TravelRateQuantity; dwt.noChargeQuantity = wt.NoChargeQuantity; dwt.taxCodeSaleId = Getv7v8IdMapNullOk(wt.TaxRateSaleID); - dwt.travelRateId = Getv7v8IdMapNullOk(wt.TravelRateID); + dwt.travelRateId = await GetRate(true, wt.TravelRateID);// Getv7v8IdMapNullOk(wt.TravelRateID); dwt.travelDetails = wt.TravelDetails; dwt.distance = wt.Distance; await util.PostAsync("workorder/items/travels", dwt.ToString()); @@ -3462,7 +3544,7 @@ namespace AyaNova.PlugIn.V8 dwisu.startDate = util.DateToV8(wisu.StartDate); dwisu.stopDate = util.DateToV8(wisu.StopDate); dwisu.estimatedQuantity = wisu.EstimatedQuantity; - dwisu.serviceRateId = Getv7v8IdMapNullOk(wisu.ServiceRateID); + dwisu.serviceRateId = await GetRate(false, wisu.ServiceRateID);//Getv7v8IdMapNullOk(wisu.ServiceRateID); await util.PostAsync("quote/items/scheduled-users", dwisu.ToString()); } @@ -3513,7 +3595,7 @@ namespace AyaNova.PlugIn.V8 dwl.serviceRateQuantity = wl.ServiceRateQuantity; dwl.noChargeQuantity = wl.NoChargeQuantity; dwl.taxCodeSaleId = Getv7v8IdMapNullOk(wl.TaxRateSaleID); - dwl.serviceRateId = Getv7v8IdMapNullOk(wl.ServiceRateID); + dwl.serviceRateId = await GetRate(false, wl.ServiceRateID);//Getv7v8IdMapNullOk(wl.ServiceRateID); dwl.serviceDetails = wl.ServiceDetails; await util.PostAsync("quote/items/labors", dwl.ToString()); @@ -3533,7 +3615,7 @@ namespace AyaNova.PlugIn.V8 dwt.travelRateQuantity = wt.TravelRateQuantity; dwt.noChargeQuantity = wt.NoChargeQuantity; dwt.taxCodeSaleId = Getv7v8IdMapNullOk(wt.TaxRateSaleID); - dwt.travelRateId = Getv7v8IdMapNullOk(wt.TravelRateID); + dwt.travelRateId = await GetRate(true, wt.TravelRateID);//Getv7v8IdMapNullOk(wt.TravelRateID); dwt.travelDetails = wt.TravelDetails; dwt.distance = wt.Distance; await util.PostAsync("quote/items/travels", dwt.ToString()); @@ -3785,7 +3867,7 @@ namespace AyaNova.PlugIn.V8 dwisu.startDate = util.DateToV8(wisu.StartDate); dwisu.stopDate = util.DateToV8(wisu.StopDate); dwisu.estimatedQuantity = wisu.EstimatedQuantity; - dwisu.serviceRateId = Getv7v8IdMapNullOk(wisu.ServiceRateID); + dwisu.serviceRateId = await GetRate(false,wisu.ServiceRateID);//Getv7v8IdMapNullOk(wisu.ServiceRateID); await util.PostAsync("pm/items/scheduled-users", dwisu.ToString()); } @@ -3836,7 +3918,7 @@ namespace AyaNova.PlugIn.V8 dwl.serviceRateQuantity = wl.ServiceRateQuantity; dwl.noChargeQuantity = wl.NoChargeQuantity; dwl.taxCodeSaleId = Getv7v8IdMapNullOk(wl.TaxRateSaleID); - dwl.serviceRateId = Getv7v8IdMapNullOk(wl.ServiceRateID); + dwl.serviceRateId = await GetRate(false, wl.ServiceRateID);//Getv7v8IdMapNullOk(wl.ServiceRateID); dwl.serviceDetails = wl.ServiceDetails; await util.PostAsync("pm/items/labors", dwl.ToString()); @@ -3856,7 +3938,7 @@ namespace AyaNova.PlugIn.V8 dwt.travelRateQuantity = wt.TravelRateQuantity; dwt.noChargeQuantity = wt.NoChargeQuantity; dwt.taxCodeSaleId = Getv7v8IdMapNullOk(wt.TaxRateSaleID); - dwt.travelRateId = Getv7v8IdMapNullOk(wt.TravelRateID); + dwt.travelRateId = await GetRate(true, wt.TravelRateID);//Getv7v8IdMapNullOk(wt.TravelRateID); dwt.travelDetails = wt.TravelDetails; dwt.distance = wt.Distance; await util.PostAsync("pm/items/travels", dwt.ToString());