public async Task <Shipment> GetRatesAsync( Shipment shipment, UspsRateOptions rateOptions, CancellationToken cancellationToken = default) { shipment = shipment.IsDomestic() ? await UspsDomesticRate(shipment, rateOptions).ConfigureAwait(false) : await UspsInternationalRate(shipment, rateOptions); return(shipment); }
private Shipment ParseInternationalResult( Shipment shipment, UspsRateOptions rateOptions, string response) { var document = XDocument.Load(new StringReader(response)); var rates = document .Descendants("Service") .GroupBy(item => (string)item.Element("SvcDescription")) .Select(g => new { Name = g.Key, DeliveryDate = g.Select(x => (string)x.Element("GuaranteeAvailability")).FirstOrDefault(), TotalCharges = g.Sum(x => decimal.Parse((string)x.Element("Postage"))) }); foreach (var r in rates) { var name = Regex.Replace(r.Name, "<.*gt;", string.Empty); if (rateOptions.ServiceName == name || rateOptions.ServiceName == "ALL") { if (r.DeliveryDate != null && DateTime.TryParse(r.DeliveryDate, out var deliveryDate)) { shipment.Rates.Add(new Rate( $"USPS {name}", name, r.TotalCharges, r.TotalCharges, (DateTime?)deliveryDate, false, shipment.Options.PreferredCurrencyCode)); } else { shipment.Rates.Add(new Rate( $"USPS {name}", name, r.TotalCharges, r.TotalCharges, rateOptions.DefaultGuaranteedDelivery, false, shipment.Options.PreferredCurrencyCode)); } } } // check for errors return(document.Root.ParseErrors(shipment)); }
private async Task <Shipment> UspsInternationalRate(Shipment shipment, UspsRateOptions rateOptions) { try { var sb = CreateInternationalRequest(shipment); var rateUri = new Uri(_options.Value.BaseUri, $"?API=IntlRateV2&XML={sb}"); var response = await _httpClient.GetStringAsync(rateUri).ConfigureAwait(false); shipment = ParseInternationalResult(shipment, rateOptions, response); } catch (Exception ex) { shipment.InternalErrors.Add($"{nameof(UspsRateProvider)}Domestic exception: {ex?.Message}"); } return(shipment); }
public async Task Get_First_Class_International_Mail_Successfully(string w, string c) { var sp = GetServices(); var provider = sp.GetRequiredService <IUspsRateProvider>(); Assert.NotNull(provider); var weight = Convert.ToDecimal(w); var charge = Convert.ToDecimal(c); var destination = new Address("1851, BUR JUMAN BUSINESS TOWER,MAKHOOL ", "Dubai", string.Empty, string.Empty, "AE", isResidential: true); // CASE: UM606525025US First Class International (R) Large Envelope or Flat $36.56 weight 2 lbs 4 oz var packages = new List <Package> { // weight from 1 oz to 4lbs for First-Class Package International Service UspsRateConfigurator.GetIntlBox(weight) }; var shipOptions = new ShipmentOptions { PackagingType = nameof(IntlPackageType.ALL), ShippingDate = DateTime.Now.AddBusinessDays(1), }; var shipment = new Shipment(_origin, destination, packages, shipOptions); var rateOptions = new UspsRateOptions { ServiceName = "First-Class Package International Service" }; var result = await provider.GetRatesAsync(shipment, rateOptions); var rate = result.Rates.FirstOrDefault(); Assert.NotNull(rate); // expectable rate for this package due to the weight Assert.Equal(charge, rate?.TotalCharges); Assert.Null(rate?.GuaranteedDelivery); _output.WriteLine($"{rate?.ServiceName} - ${rate?.TotalCharges} - {rate?.GuaranteedDelivery}"); }
public async Task Get_Priority_Mail_International_Package_5lbs_Successfully() { var sp = GetServices(); var provider = sp.GetRequiredService <IUspsRateProvider>(); Assert.NotNull(provider); var destination = new Address("FLAT 22 TOLBUT COURT", "ROMFORD", string.Empty, string.Empty, "GB", isResidential: true); var packages = new List <Package> { // https://www.usps.com/international/priority-mail-international.htm // Maximum weight for Priority Mail International Flat Rate Envelopes and small Flat Rate Boxes is 4 lbs. // Fast international delivery time: 6–10 business days // new Package(11M, 5M, 1M, 5M, 0.0M), UspsRateConfigurator.GetIntlBox(5m) }; var shipOptions = new ShipmentOptions { PackagingType = nameof(IntlPackageType.PACKAGE), ShippingDate = DateTime.Now.AddBusinessDays(1), }; var shipment = new Shipment(_origin, destination, packages, shipOptions); var rateOptions = new UspsRateOptions { ServiceName = "Priority Mail International" }; var result = await provider.GetRatesAsync(shipment, rateOptions); var rate = result.Rates.FirstOrDefault(); Assert.NotNull(rate); Assert.Equal(77.60m, rate?.TotalCharges); _output.WriteLine($"{rate?.ServiceName}- ${rate?.TotalCharges} - {rate?.GuaranteedDelivery}"); }
private async Task <Shipment> UspsDomesticRate(Shipment shipment, UspsRateOptions rateOptions) { try { var sb = CreateDometicRequest(shipment, rateOptions); var rateUri = new Uri(_options.Value.BaseUri, $"?API=RateV4&XML={sb}"); var response = await _httpClient.GetStringAsync(rateUri).ConfigureAwait(false); var specialServiceCodes = new List <string>(); if (shipment.Packages.Any(x => x.SignatureRequiredOnDelivery)) { specialServiceCodes.Add("119"); // 119 represents Adult Signature Requiredgnature Required } shipment = ParseDomesticResult(shipment, response, rateOptions, specialServiceCodes); } catch (Exception ex) { shipment.InternalErrors.Add($"{nameof(UspsRateProvider)}Domestic exception: {ex?.Message}"); } return(shipment); }
private string CreateDometicRequest(Shipment shipment, UspsRateOptions rateOptions) { var sb = new StringBuilder(); // var signatureOnDeliveryRequired = false; var settings = new XmlWriterSettings { Indent = false, OmitXmlDeclaration = true, NewLineHandling = NewLineHandling.None }; using (var writer = XmlWriter.Create(sb, settings)) { writer.WriteStartElement("RateV4Request"); writer.WriteAttributeString("USERID", _options.Value.UserId); if (!rateOptions.BaseRatesOnly) { writer.WriteElementString("Revision", "2"); } var i = 0; foreach (var package in shipment.Packages) { string size; var container = shipment.Options?.PackagingType?.Replace("_", " "); if (package.IsPackageLarge()) { size = "LARGE"; // Container must be RECTANGULAR or NONRECTANGULAR when SIZE is LARGE if (container == null || !string.Equals(container, "NONRECTANGULAR", StringComparison.InvariantCultureIgnoreCase)) { container = "RECTANGULAR"; } } else { size = "REGULAR"; if (string.IsNullOrEmpty(container)) { container = string.Empty; } } writer.WriteStartElement("Package"); writer.WriteAttributeString("ID", i.ToString()); writer.WriteElementString("Service", rateOptions.ServiceName); if (rateOptions.ServiceName.Contains("First")) { writer.WriteElementString("FirstClassMailType", container); } writer.WriteElementString("ZipOrigination", shipment.OriginAddress.CountryCode == "US" && shipment.OriginAddress.PostalCode.Length > 5 ? shipment.OriginAddress.PostalCode.Substring(0, 5) : shipment.OriginAddress.PostalCode); writer.WriteElementString("ZipDestination", shipment.DestinationAddress.CountryCode == "US" && shipment.DestinationAddress.PostalCode.Length > 5 ? shipment.DestinationAddress.PostalCode.Substring(0, 5) : shipment.DestinationAddress.PostalCode); writer.WriteElementString("Pounds", package.PoundsAndOunces.Pounds.ToString()); writer.WriteElementString("Ounces", package.PoundsAndOunces.Ounces.ToString()); if (rateOptions.ServiceName == "First Class") { writer.WriteElementString("Container", string.Empty); } else { writer.WriteElementString("Container", container); } writer.WriteElementString("Size", size); writer.WriteElementString("Width", package.Dimensions.RoundedWidth.ToString()); writer.WriteElementString("Length", package.Dimensions.RoundedLength.ToString()); writer.WriteElementString("Height", package.Dimensions.RoundedHeight.ToString()); writer.WriteElementString("Girth", package.Dimensions.Girth.ToString()); writer.WriteElementString("Machinable", package.IsPackageMachinable().ToString()); if (shipment.Options.ShippingDate != null) { writer.WriteElementString( "ShipDate", shipment.Options.ShippingDate.Value.AddDays(1).ToString("yyyy-MM-dd")); } if (package.SignatureRequiredOnDelivery) { // signatureOnDeliveryRequired = true; } writer.WriteEndElement(); i++; } writer.WriteEndElement(); writer.Flush(); } return(sb.ToString()); }
private Shipment ParseDomesticResult( Shipment shipment, string response, UspsRateOptions rateOptions, IList <string>?includeSpecialServiceCodes = null) { var document = XElement.Parse(response, LoadOptions.None); var rates = from item in document.Descendants("Postage") group item by(string) item.Element("MailService") into g select new { Name = g.Key, TotalCharges = g.Sum(x => decimal.Parse((string)x.Element("Rate"))), DeliveryDate = g.Select(x => (string)x.Element("CommitmentDate")).FirstOrDefault(), SpecialServices = g.Select(x => x.Element("SpecialServices")).FirstOrDefault() }; foreach (var r in rates) { var name = Regex.Replace(r.Name, "<.*>", string.Empty); var additionalCharges = 0.0m; if (includeSpecialServiceCodes?.Count > 0 && r.SpecialServices != null) { var specialServices = r.SpecialServices.XPathSelectElements("SpecialService").ToList(); if (specialServices.Count > 0) { foreach (var specialService in specialServices) { var serviceId = (string)specialService.Element("ServiceID"); var price = decimal.Parse((string)specialService.Element("Price")); if (includeSpecialServiceCodes.Contains(serviceId)) { additionalCharges += price; } } } } var charges = r.TotalCharges + additionalCharges; if (r.DeliveryDate != null && DateTime.TryParse(r.DeliveryDate, out var deliveryDate)) { var saturdayDelivery = shipment.Options.SaturdayDelivery && deliveryDate.DayOfWeek == DayOfWeek.Saturday; shipment.Rates.Add(new Rate( $"USPS {name}", name, charges, charges, (DateTime?)deliveryDate, saturdayDelivery, shipment.Options.GetCurrencyCode())); } else { shipment.Rates.Add(new Rate( $"USPS {name}", name, charges, charges, rateOptions.DefaultGuaranteedDelivery, false, shipment.Options.GetCurrencyCode())); } } // check for errors return(document.ParseErrors(shipment)); }