def get_rates(self, cart, contact): from satchmo_store.shop.models import Config error_ret = False, None, None shop_details = Config.objects.get_current() # always use production api keys for get_rates, you don't get charged # anyways cpa_kwargs = canada_post_api_kwargs(self.settings, production=True) cpa = CanadaPostAPI(**cpa_kwargs) # parcels is a list of (Parcel, pack(dimensions)) parcels, rest = self.make_parcels(cart) if rest: log.error("There's not boxes big enough for some of these " "products: {}".format(rest)) return error_ret log.debug("Calculated Parcels: [%s]", ",".join("({})".format(unicode(p)) for p in parcels)) origin = get_origin(shop_details) destination = get_destination(contact) services = [] for parcel, packs in parcels: # rates depend on dimensions + origin + destination only cache_key = "CP-GetRates-{W}-{l}x{w}x{h}-{fr}-{to}".format( W=parcel.weight, w=parcel.width, h=parcel.height, l=parcel.length, fr=origin.postal_code, to=destination.postal_code ) if cache.has_key(cache_key): parcel_services = cache.get(cache_key) else: try: parcel_services = cpa.get_rates(parcel, origin, destination) except CanadaPostError, e: if self.settings.RAISE_TOO_LARGE.value and e.code == 9111: raise ParcelTooLarge, e.message parcel_services = [] cache.set(cache_key, parcel_services) # so services is [(Service, parcel, [packs]),...] services.extend(product(filter(lambda s: s.code == self.service_code, parcel_services), [parcel], [packs]))