Пример #1
0
 def setUp(self):
     self.interface = CanadaPostAPI(
         customer_number=api_details.AUTH.customer_number,
         username=api_details.AUTH.username,
         password=api_details.AUTH.password,
         contract_number=None,
         dev=api_details.AUTH.dev)
class TestNonContractShipping(unittest.TestCase):
    """
    Tests the Non-Contract Shipping use case  as detailed on Canada 
    Posts's Non-Contract Shipping documentation
    """
    
    def setUp(self):
        self.interface = CanadaPostAPI(
            customer_number=api_details.AUTH.customer_number,
            username=api_details.AUTH.username,
            password=api_details.AUTH.password,
            contract_number=None,
            dev=api_details.AUTH.dev)
    
    #def test_interface_auth(self):
    #    """ Test the CanadaPostAPI interface constructon with Auth object """
    #    interface = CanadaPostAPI(auth = api_details.AUTH)
    #    self.assertEqual(interface.auth.username, api_details.AUTH.username)
    
    def test_interface_kwargs(self):
        """ Test the CanadaPostAPI interface constructor with key word args"""
        self.assertEqual(self.interface.auth.username,
                         api_details.AUTH.username)
    
    def test_create_nc_shipment(self):
        """
        The typical route used for shipping without a Canada Post contract:
        
        * Create Non-Contract Shipment
        
        * Get Artifact
        """
        pass
    
    def test_get_nc_shipment_receipt(self):
        """
        Test the Get Non-Contract Shipment receipt
        """
        pass
    
    def test_get_nc_shipment_details(self):
        """
        Tests Get Non-Contract Shipment Details
        """
    
    def test_get_nc_shipments(self):
        """
        Tests Get Non-Contract Shipments
        """
        from_date = date(1960, 1, 1).strftime("%Y%m%d0000")
        self.interface.nc_get_shipments(from_date)
        
    
    def test_get_nc_shipment(self):
        """
        Get Non-Contract Shipment
        """
        pass
Пример #3
0
class TestNonContractShipping(unittest.TestCase):
    """
    Tests the Non-Contract Shipping use case  as detailed on Canada 
    Posts's Non-Contract Shipping documentation
    """
    def setUp(self):
        self.interface = CanadaPostAPI(
            customer_number=api_details.AUTH.customer_number,
            username=api_details.AUTH.username,
            password=api_details.AUTH.password,
            contract_number=None,
            dev=api_details.AUTH.dev)

    #def test_interface_auth(self):
    #    """ Test the CanadaPostAPI interface constructon with Auth object """
    #    interface = CanadaPostAPI(auth = api_details.AUTH)
    #    self.assertEqual(interface.auth.username, api_details.AUTH.username)

    def test_interface_kwargs(self):
        """ Test the CanadaPostAPI interface constructor with key word args"""
        self.assertEqual(self.interface.auth.username,
                         api_details.AUTH.username)

    def test_create_nc_shipment(self):
        """
        The typical route used for shipping without a Canada Post contract:
        
        * Create Non-Contract Shipment
        
        * Get Artifact
        """
        pass

    def test_get_nc_shipment_receipt(self):
        """
        Test the Get Non-Contract Shipment receipt
        """
        pass

    def test_get_nc_shipment_details(self):
        """
        Tests Get Non-Contract Shipment Details
        """

    def test_get_nc_shipments(self):
        """
        Tests Get Non-Contract Shipments
        """
        from_date = date(1960, 1, 1).strftime("%Y%m%d0000")
        self.interface.nc_get_shipments(from_date)

    def test_get_nc_shipment(self):
        """
        Get Non-Contract Shipment
        """
        pass
Пример #4
0
    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 setUp(self):
     self.interface = CanadaPostAPI(
         customer_number=api_details.AUTH.customer_number,
         username=api_details.AUTH.username,
         password=api_details.AUTH.password,
         contract_number=None,
         dev=api_details.AUTH.dev)
Пример #6
0
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))
Пример #7
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]))
Пример #8
0
    def void_shipments(self, request, queryset=None, id=-1):
        if queryset is None:
            if queryset is None:
                queryset = [get_object_or_404(OrderShippingService,
                                              id=id)]
            else:
                queryset = queryset.select_related()

        cpa_kwargs = canada_post_api_kwargs(self.settings)
        cpa = CanadaPostAPI(**cpa_kwargs)
        errcnt = 0
        gdcnt = 0
        dne = 0
        for detail in queryset:
            for parcel in detail.parceldescription_set.all().select_related():
                try:
                    shipment = parcel.shipment
                    cpa_shipment = shipment.get_shipment()
                    if not cpa.void_shipment(cpa_shipment):
                        errcnt += 1
                        self.message_user(request, _("Could not void shipment "
                                                     "{shipment_id} for order "
                                                     "{order_id}").format(
                            shipment_id=shipment.id, order_id=detail.order.id))
                    else:
                        gdcnt += 1
                        shipment.delete()
                except Shipment.DoesNotExist:
                    dne += 1

        if not errcnt:
            self.message_user(request, _("All shipments voided"))
        else:
            messages.warning(request, _("{good_count} shipments voided, "
                                        "{bad_count} problems").format(
                good_count=gdcnt, bad_count=errcnt))
        if dne:
            self.message_user(request, _("{count} shipments didn't "
                                         "exist").format(count=dne))
        if id >= 0:
            return HttpResponseRedirect("..")
Пример #9
0
    def void_shipments(self, request, queryset=None, id=-1):
        log.info("void shipments %s", queryset or str(id))
        if queryset is None:
            if queryset is None:
                queryset = [get_object_or_404(OrderShippingService,
                                              id=id)]
            else:
                queryset = queryset.select_related()

        cpa_kwargs = canada_post_api_kwargs(self.settings)
        cpa = CanadaPostAPI(**cpa_kwargs)
        errcnt = 0
        gdcnt = 0
        dne = 0
        for detail in queryset:
            log.debug('Processing detail: %s', detail)
            for parcel in detail.parceldescription_set.all().select_related():
                log.debug("Processing parcel: %s", parcel)
                try:
                    shipment = parcel.shipment
                    log.debug("Got shipment %s", shipment)
                    cpa_shipment = shipment.get_shipment()
                    if not time_f(cpa.void_shipment,
                                  'canada-post-dp-shipping.void-shipment',
                                  cpa_shipment):
                        log.warn("Problem voiding shipment: %s", cpa_shipment)
                        errcnt += 1
                        self.message_user(request, _("Could not void shipment "
                                                     "{shipment_id} for order "
                                                     "{order_id}").format(
                            shipment_id=shipment.id, order_id=detail.order.id))
                    else:
                        log.debug("Shipment voided, deleting from DB")
                        gdcnt += 1
                        shipment.delete()
                except Shipment.DoesNotExist:
                    log.debug("Shipment does not exist!")
                    dne += 1

        if not errcnt:
            log.info("All shipments voided")
            self.message_user(request, _("All shipments voided"))
        else:
            log.warn("%d shipments voided, %d problems", gdcnt, errcnt)
            messages.warning(request, _("{good_count} shipments voided, "
                                        "{bad_count} problems").format(
                good_count=gdcnt, bad_count=errcnt))
        if dne:
            log.debug("%d shipments didn't exist", dne)
            self.message_user(request, _("{count} shipments didn't "
                                         "exist").format(count=dne))
        if id >= 0:
            return HttpResponseRedirect("..")
Пример #10
0
def get_manifests(links):
    log.info("Getting manifests from links: %s", links)
    settings = config_get_group('canada_post_dp_shipping')
    cpa_kwargs = canada_post_api_kwargs(settings)
    cpa = CanadaPostAPI(**cpa_kwargs)
    manifests = []
    for link in links:
        log.debug("Getting manifest from %s", link['href'])
        try:
            cpa_manifest = time_f(cpa.get_manifest,
                                  'canada-post-dp-shipping.get-manifest', link)
            manifest = Manifest(manifest=cpa_manifest)
            manifest_pdf = time_f(cpa.get_artifact,
                                  'canada-post-dp-shipping.get-artifact',
                                  cpa_manifest)
            filename = os.path.basename(link['href'].rstrip('/'))
            if not filename.endswith('.pdf'):
                filename += '.pdf'
            manifest.artifact = File(manifest_pdf, filename)
            manifest.save()
            shipments = time_f(
                cpa.get_manifest_shipments,
                'canada-post-dp-shipping.get-manifest-shipments', cpa_manifest)
            for shipment_id in shipments:
                log.info("Setting manifest for shipment %s", shipment_id)
                try:
                    shipment = Shipment.objects.select_related().get(
                        id=shipment_id)
                    shipping_detail = shipment.parcel.shipping_detail
                    shipping_detail.manifest = manifest
                    shipping_detail.save()
                except Shipment.DoesNotExist:
                    log.error("Requested shipment does not exist")
            manifests.append(manifest)
        except Exception, e:
            log.error("Error processing manifest: %s", e, exc_info=True)
Пример #11
0
    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("..")