def transmit_shipments(queryset=None, send_msg=None): log.info("transmit_shipments invoked") log.debug("queryset: %s", str(queryset)) if send_msg is None: send_msg = lambda x: x if queryset is None: queryset = OrderShippingService.objects.all() from satchmo_store.shop.models import Config shop_details = Config.objects.get_current() settings = config_get_group('canada_post_dp_shipping') cpa_kwargs = canada_post_api_kwargs(settings) cpa = CanadaPostAPI(**cpa_kwargs) origin = get_origin(shop_details) groups = [] order_shippings = [] for order_shipping in queryset.filter(transmitted=False): log.debug("processing order shipping: %s", order_shipping) if order_shipping.shipments_created(): log.debug("shipments created") group = unicode(order_shipping.shipping_group()) groups.append(group) order_shippings.append(order_shipping) else: log.debug("shipments not created") log.debug("using groups: %s", groups) if groups: log.info("transmitting shipments") links = time_f(cpa.transmit_shipments, 'canada-post-dp-shipping.transmit-shipments', origin, groups) log.debug("received manifests: %s", links) log.debug("marking order shippings as transmitted") for order_shipping in order_shippings: order_shipping.transmitted = True order_shipping.save() manifest_count = len(links) log.info("received %d manifests", manifest_count) send_msg( ungettext_lazy( "{count} manifest generated. It will be sent via email in a " "couple of minutes".format(count=manifest_count), "{count} manifests generated. They will be sent via email in a " "couple of minutes".format(count=manifest_count), manifest_count)) if USE_CELERY: get_manifests_async.apply_async(args=(links, ), cowntdown=1) else: get_manifests(links) group_count = len(groups) send_msg( ungettext_lazy( "Transmitted shipments for {count} group".format( count=group_count), "Transmitted shipments for {count} groups".format( count=group_count), group_count))
def transmit_shipments(queryset=None, send_msg=None): log.info("transmit_shipments invoked") log.debug("queryset: %s", str(queryset)) if send_msg is None: send_msg = lambda x: x if queryset is None: queryset = OrderShippingService.objects.all() from satchmo_store.shop.models import Config shop_details = Config.objects.get_current() settings = config_get_group('canada_post_dp_shipping') cpa_kwargs = canada_post_api_kwargs(settings) cpa = CanadaPostAPI(**cpa_kwargs) origin = get_origin(shop_details) groups = [] order_shippings = [] for order_shipping in queryset.filter( transmitted=False): log.debug("processing order shipping: %s", order_shipping) if order_shipping.shipments_created(): log.debug("shipments created") group = unicode(order_shipping.shipping_group()) groups.append(group) order_shippings.append(order_shipping) else: log.debug("shipments not created") log.debug("using groups: %s", groups) if groups: log.info("transmitting shipments") links = time_f(cpa.transmit_shipments, 'canada-post-dp-shipping.transmit-shipments', origin, groups) log.debug("received manifests: %s", links) log.debug("marking order shippings as transmitted") for order_shipping in order_shippings: order_shipping.transmitted = True order_shipping.save() manifest_count = len(links) log.info("received %d manifests", manifest_count) send_msg(ungettext_lazy( "{count} manifest generated. It will be sent via email in a " "couple of minutes".format(count=manifest_count), "{count} manifests generated. They will be sent via email in a " "couple of minutes".format(count=manifest_count), manifest_count)) if USE_CELERY: get_manifests_async.apply_async(args=(links,), cowntdown=1) else: get_manifests(links) group_count = len(groups) send_msg(ungettext_lazy( "Transmitted shipments for {count} group".format(count=group_count), "Transmitted shipments for {count} groups".format(count=group_count), group_count))
def get_rates(self, cart, contact): from satchmo_store.shop.models import Config error_ret = False, 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: from django.contrib.sites.models import Site site = Site.objects.get_current() error_message = (u"There's not boxes big enough for some of these " u"products: ({})").format(u", ".join( u"Package({})".format(unicode(p)) for p in rest)) subject = u"There's not boxes big enough for some products" send_store_mail(subject, context={ 'site': site, 'product_list': rest }, template=("canada_post_dp_shipping/admin/mail/" "add_boxes.txt"), send_to_store=True) raise ParcelDimensionError, error_message log.debug(u"Calculated Parcels: [%s]", u",".join(u"({},[{}])".format( pr, u",".join(unicode(pk) for pk in pks)) for pr, pks 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 ) parcel_services = cache.get(cache_key) if parcel_services is None: try: parcel_services = time_f( cpa.get_rates, 'canada-post-dp-shipping.get-rates', parcel, origin, destination) except CanadaPostError, e: if self.settings.RAISE_TOO_LARGE.value and e.code == 9111: raise ParcelDimensionError, e.message else: log.error(u"Canada Post returned with error: %s|%s", e.code, 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]))
def create_shipments(self, request, id): from satchmo_store.shop.models import Config order_shipping = get_object_or_404(OrderShippingService, id=id) if request.method == 'GET': opts = self.model._meta title = _("Please confirm the parcels size and weight") object_name = unicode(opts.verbose_name) app_label = opts.app_label context = { "title": title, "object_name": object_name, "object": order_shipping, "opts": opts, "root_path": self.admin_site.root_path, "app_label": app_label, } return render(request, ("canada_post_dp_shipping/admin/" "confirm_shipments.html"), context) elif request.REQUEST.get('post', None) == "yes": # else method is POST shop_details = Config.objects.get_current() cpa_kwargs = canada_post_api_kwargs(self.settings) cpa = CanadaPostAPI(**cpa_kwargs) origin = get_origin(shop_details) destination = get_destination(order_shipping.order.contact) group = unicode(order_shipping.shipping_group()) cnt = 0 exs = 0 for parcel in (order_shipping.parceldescription_set .select_related().all()): try: if parcel.shipment: exs += 1 except Shipment.DoesNotExist: shipment = cpa.create_shipment( parcel=parcel.get_parcel(), origin=origin, destination=destination, service=order_shipping.get_service(), group=group) Shipment(shipment=shipment, parcel=parcel).save() cnt += 1 self.message_user(request, _("{count} shipments created for order " "{order}").format( count=cnt, order=order_shipping.order)) if exs > 0: messages.warning(request, _("{count} shipments already existed " "for {order}").format( count=exs, order=order_shipping.order)) else: messages.error(request, _("Unexpected error, please retry")) return HttpResponseRedirect("..")
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]))
def create_shipments(self, request, id): log.info("Creating shipments for %s", str(id)) from satchmo_store.shop.models import Config order_shipping = get_object_or_404(OrderShippingService, id=id) log.debug("Got OrderShippingService: %s", order_shipping) if request.method == 'GET': log.debug("GET. Ask for confirmation") opts = self.model._meta title = _("Please confirm the parcels size and weight") object_name = unicode(opts.verbose_name) app_label = opts.app_label context = { "title": title, "object_name": object_name, "object": order_shipping, "opts": opts, "root_path": self.admin_site.root_path, "app_label": app_label, } return render(request, ("canada_post_dp_shipping/admin/" "confirm_shipments.html"), context) elif request.REQUEST.get('post', None) == "yes": log.debug("POST with value=yes") # else method is POST shop_details = Config.objects.get_current() cpa_kwargs = canada_post_api_kwargs(self.settings) cpa = CanadaPostAPI(**cpa_kwargs) origin = get_origin(shop_details) destination = get_destination(order_shipping.order.contact) options = None if destination.country_code != 'CA': # TODO: make this selectable through website options = [Option(code='RASE')] group = unicode(order_shipping.shipping_group()) cnt = 0 exs = 0 for parcel in (order_shipping.parceldescription_set .select_related().all()): log.debug("Creating shipment for parcel %s", parcel) try: if parcel.shipment: log.warn("Shipment already existed in DB! %s", parcel.shipment) exs += 1 except Shipment.DoesNotExist: log.debug("Creating shipment") cpa_ship = time_f( cpa.create_shipment, 'canada-post-dp-shipping.create-shipping', parcel=parcel.get_parcel(), origin=origin, destination=destination, service=order_shipping.get_service(), group=group, options=options) shipment = Shipment(shipment=cpa_ship, parcel=parcel) shipment.save() log.debug("Shipment created: %s", shipment) if USE_CELERY: from canada_post_dp_shipping.tasks import get_label log.debug("Calling get_label celery task") get_label.apply_async(args=(shipment.id, cpa.auth.username, cpa.auth.password), # download labels in 3 minutes countdown=3*60) cnt += 1 log.info("%d shipments created for order %s", cnt, order_shipping.order) self.message_user(request, _(u"{count} shipments created for order " u"{order}").format( count=cnt, order=order_shipping.order)) if USE_CELERY: log.debug("Using celery. Task to download labels should run in " "3 minutes") self.message_user(request, _(u"Shipping labels will be " u"automatically downloaded in " u"three minutes")) if exs > 0: log.warn("%d shipments already existed for order %s", exs, order_shipping.order) messages.warning(request, _(u"{count} shipments already existed " u"for {order}").format( count=exs, order=order_shipping.order)) else: messages.error(request, _("Unexpected error, please retry")) return HttpResponseRedirect("..")