diff --git a/AyaNovaQBI/util.cs b/AyaNovaQBI/util.cs index ce7d836..617964c 100644 --- a/AyaNovaQBI/util.cs +++ b/AyaNovaQBI/util.cs @@ -5712,7 +5712,7 @@ namespace AyaNovaQBI if (!QBIntegration.Items.Any(z => z.AType == AyaType.Customer && z.ObjectId == w.CustomerId)) { bReturn = false; - AddMisMatch(AyaClientList.FirstOrDefault(z=>z.Id==w.CustomerId).Name, w.CustomerId, AyaType.Customer, MisMatchReason.NotLinkedToQB, MisMatches); + AddMisMatch(AyaClientList.FirstOrDefault(z => z.Id == w.CustomerId).Name, w.CustomerId, AyaType.Customer, MisMatchReason.NotLinkedToQB, MisMatches); } //Service rates: @@ -5727,9 +5727,9 @@ namespace AyaNovaQBI //Check that rate isn't actually guid.empty //it's possible that some users have not selected a rate on the workorder - if (null== wl.ServiceRateId || wl.ServiceRateId == 0) + if (null == wl.ServiceRateId || wl.ServiceRateId == 0) throw new System.ApplicationException($"ERROR: Workorder {w.Serial} has a Labor item with no rate selected\r\nThis is a serious problem for QBI and needs to be rectified before QBI can be used.\r\n"); - + if (!QBIntegration.Items.Any(z => z.AType == AyaType.ServiceRate && z.ObjectId == wl.ServiceRateId)) { bReturn = false; @@ -5747,7 +5747,7 @@ namespace AyaNovaQBI //Check that rate isn't actually empty //it's possible that some users have not selected a rate on the workorder - if (null==wt.TravelRateId || wt.TravelRateId == 0) + if (null == wt.TravelRateId || wt.TravelRateId == 0) throw new System.ApplicationException($"ERROR: Workorder {w.Serial} has a Travel item with no rate selected\r\nThis is a serious problem for QBI and needs to be rectified before QBI can be used.\r\n"); if (!QBIntegration.Items.Any(z => z.AType == AyaType.TravelRate && z.ObjectId == wt.TravelRateId)) @@ -5764,46 +5764,52 @@ namespace AyaNovaQBI //If there's *any* parts then there is something to invoice bSomethingToInvoice = true; - //Changed: 14-Nov-2006 to check that linked item id exists in qb - if (!QBI.Maps.Contains(wp.PartID) || QBItems.Rows.Find(QBI.Maps[wp.PartID].ForeignID) == null) + //Changed: 14-Nov-2006 to check that linked item id exists in qb + var mappedPart = QBIntegration.Items.FirstOrDefault(z => z.AType == AyaType.Part && z.ObjectId == wp.PartId); + if (mappedPart == null || QBItems.Rows.Find(mappedPart.IntegrationItemId) == null) { bReturn = false; - //Changed: 21-June-2006 to use display formatted name - AddMisMatch(AyaPartList[wp.PartID].DisplayName(Util.GlobalSettings.DefaultPartDisplayFormat), wp.PartID, AyaType.Part, MisMatchReason.NotLinkedToQB, MisMatches); + AddMisMatch(AyaPartList.FirstOrDefault(z => z.Id == wp.PartId).Name, wp.PartId, AyaType.Part, MisMatchReason.NotLinkedToQB, MisMatches); } else { //check the price - if (!PriceOverrides.Contains(wp.ID)) + if (!PriceOverrides.Contains(wp.Id)) { + var ayaPartRecord = AyaPartList.FirstOrDefault(z => z.Id == wp.PartId); + + decimal qbPrice = (decimal)QBItems.Rows.Find(mappedPart.IntegrationItemId)["Price"]; - decimal qbPrice = (decimal)QBItems.Rows.Find(QBI.Maps[wp.PartID].ForeignID)["Price"]; //------------DISCOUNT----------------- string disco = ""; //Added:20-July-2006 to incorporate discounts on parts into qb invoice - decimal charge; + decimal charge = wp.PriceViz;//price viz is the final per item price including any discounts - //Changed: 18-Nov-2006 CASE 158 - //this is all wrong, it was multiplying price by quantity to calculate charge when it shouldn't - //removed quanty * price in next line to just price - charge = decimal.Round(wp.Price, 2, MidpointRounding.AwayFromZero); - charge = charge - (decimal.Round(charge * wp.Discount, 2, MidpointRounding.AwayFromZero)); - if (wp.Discount != 0) + //was there an adjustment on the work order of the price? + if (wp.PriceViz != wp.ListPrice) { - disco = " (Price " + wp.Price.ToString("c") + " discounted on workorder " + wp.Discount.ToString("p") + ") \r\n"; + //there was some form of adjustment (not necessarily a discount) + disco = " (Price " + wp.ListPrice.ToString("c") + " adjusted on workorder to " + wp.PriceViz.ToString("c") + ") \r\n"; } + //----------------------------- //It's a match, let's see if the price matches as well if (charge != qbPrice) { bReturn = false; - AddMisMatch("WO: " + w.WorkorderService.ServiceNumber.ToString() + disco + " Part: " + AyaPartList[wp.PartID].DisplayName(Util.GlobalSettings.DefaultPartDisplayFormat),//Changed: 21-June-2006 to use display formatted name - wp.PartID, AyaType.Part, MisMatchReason.PriceDifferent, MisMatches, qbPrice, charge, wp.ID, - QBI.Maps[wp.PartID].ForeignID); + AddMisMatch($"WO: {w.Serial}{disco} Part: {ayaPartRecord.Name}", + wp.PartId, + AyaType.Part, + MisMatchReason.PriceDifferent, + MisMatches, + qbPrice, + charge, + wp.Id, + mappedPart.IntegrationItemId); } } @@ -5814,19 +5820,18 @@ namespace AyaNovaQBI #region Outside service charges - if (wi.HasOutsideService) + if (wi.OutsideServices.Count > 0) { - if (wi.OutsideService.RepairPrice != 0 || wi.OutsideService.ShippingPrice != 0) + if (wi.OutsideServices.Any(z => z.PriceViz != 0))//priceviz incorporates shipping and repairs together so unlike in qbi v7 only need to check that one field for the entire collection { bSomethingToInvoice = true; //there is something billable, just need to make sure //that there is a QB charge defined for outside service - if (QDat.OutsideServiceChargeAs == null || - QDat.OutsideServiceChargeAs == "" || + if (string.IsNullOrWhiteSpace(QDat.OutsideServiceChargeAs) || !QBItems.Rows.Contains(QDat.OutsideServiceChargeAs)) { bReturn = false; - AddMisMatch("Outside service", Guid.Empty, AyaType.WorkOrderItemOutsideService, MisMatchReason.NotLinkedToQB, MisMatches); + AddMisMatch("Outside services - can't be billed as not yet mapped to a QB Charge item\r\nSet in Tools->Preferences", 0, AyaType.WorkOrderItemOutsideService, MisMatchReason.NotLinkedToQB, MisMatches); } } @@ -5835,28 +5840,28 @@ namespace AyaNovaQBI #region Workorder item loan charges - if (wi.HasLoans) + if (wi.Loans.Count>0) { - foreach (WorkOrderItemLoan wil in wi.Loans) + //foreach (WorkOrderItemLoan wil in wi.Loans) + if(wi.Loans.Any(z => z.PriceViz != 0)) { - if (wil.Charges != 0) - { + //if (wil.PriceViz != 0) + //{ //case 772 bSomethingToInvoice = true; //there is something billable, just need to make sure //that there is a QB charge defined for loaned item charges - if (QDat.WorkOrderItemLoanChargeAs == null || - QDat.WorkOrderItemLoanChargeAs == "" || - !QBItems.Rows.Contains(QDat.WorkOrderItemLoanChargeAs)) + if (string.IsNullOrWhiteSpace(QDat.WorkorderItemLoanChargeAs) || + !QBItems.Rows.Contains(QDat.WorkorderItemLoanChargeAs)) { bReturn = false; - AddMisMatch("Workorder item loan", Guid.Empty, AyaType.WorkOrderItemLoan, MisMatchReason.NotLinkedToQB, MisMatches); + AddMisMatch("Workorder item loan - can't be billed as not yet mapped to a QB Charge item\r\nSet in Tools->Preferences", 0, AyaType.WorkOrderItemLoan, MisMatchReason.NotLinkedToQB, MisMatches); break; } - } + //} } } #endregion @@ -5926,7 +5931,7 @@ namespace AyaNovaQBI { foreach (var m in Mismatches) - { + { //Have to check ID and type here because for outside service //and loans and misc expenses the id is always empty so type is //the only way to differentiate