Esempio n. 1
0
    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]))