def test_package_qr_codes(self):
     self.form_submission = PackageScanFormSubmission(PACKAGE_JSON)
     self.assertEqual(set(['test']), self.form_submission.get_qr_codes())
 def test_no_gps(self):
     data = VOUCHER_JSON.copy()
     data.pop('gps')
     self.form_submission = PackageScanFormSubmission(data)
     self.assertFalse(hasattr(self.form_submission, 'gps'))
Beispiel #3
0
def process_new_scans():
    """Updates the local database with new package tracking form submissions"""
    logger.debug("process_new_scans task starting...")
    try:
        form_ids = [int(x) for x in settings.ONA_FORM_IDS]
        for form_id in form_ids:
            if form_id in bad_form_ids:
                return

            client = OnaApiClient()

            if form_id in form_defs:
                form_def = form_defs[form_id]
            else:
                form_def = client.get_form_definition(form_id)
                if form_def:
                    form_defs[form_id] = form_def
                else:
                    # Logging an error should result in an email to the admins so they
                    # know to fix this.
                    logger.error("Bad ONA_FORM_ID: %s" % form_id)
                    # Let's not keep trying for the bad form ID. We'll have to change the
                    # settings and restart to fix it.
                    bad_form_ids.add(form_id)
                    return

            # What's the last submission we got (if any)
            most_recent_submission = FormSubmission.objects.filter(form_id=form_id)\
                .order_by('-submission_time').first()
            if most_recent_submission:
                # Don't re-fetch the last form
                since = most_recent_submission.submission_time
                logger.debug("Getting forms since %s" % since)
            else:
                logger.debug("No form submissions yet for %r" % form_id)
                since = None

            try:
                submissions = client.get_form_submissions(form_id, since=since)
            except Http404:
                logger.error(
                    "Got 404 getting submissions for ONA_FORM_ID = %s" %
                    form_id)
                return
            except OnaApiClientException as e:
                if e.status_code != 404:
                    raise
                logger.error(
                    "Got 404 getting submissions for ONA_FORM_ID = %s" %
                    form_id)
                return

            logger.debug("process_new_scans downloaded %d submitted forms" %
                         len(submissions))
            # add the form definition JSON to each submission
            for data in submissions:
                data.update({'form_id': form_id})
                data.update({'form_definition': form_def})
            # create a list of API repr objects and ensure they are sorted by submission date
            objects = [PackageScanFormSubmission(x) for x in submissions]
            objects.sort(key=lambda x: x._submission_time)
            logger.debug("There are %d objects to look at" % len(objects))
            for submission in objects:
                existing = FormSubmission.objects.filter(
                    uuid=submission._uuid).first()
                if not existing:
                    logger.debug("Got new form, creating new record")
                    try:
                        FormSubmission.from_ona_form_data(submission)
                    except Exception:
                        logger.exception(
                            "HEY got exception creating new FormSubmission")
                else:
                    logger.debug("Form %s (%r, %s) already existed" %
                                 (submission._uuid, submission.form_id,
                                  existing.submission_time))
    except ConnectionError:
        logger.exception("Error connecting to Ona server")
    except OnaApiClientException:
        logger.exception("Error communicating with Ona server")
    except Exception:
        logger.exception("Something blew up in process_new_scans")
    logger.debug("process_new_scans task done")
 def setUp(self):
     self.form_submission = PackageScanFormSubmission(VOUCHER_JSON)
Beispiel #5
0
 def test_get_latitude_no_gps(self):
     data = SUBMISSION_JSON.copy()
     data.pop('gps')
     self.form_submission = PackageScanFormSubmission(data)
     self.assertIsNone(self.form_submission.get_lat())
Beispiel #6
0
 def setUp(self):
     self.form_submission = PackageScanFormSubmission(SUBMISSION_JSON)
Beispiel #7
0
 def test_record_package_location(self):
     PackageFactory(code=QR_CODE)
     self.assertFalse(PackageScan.objects.all())
     form_data = PackageScanFormSubmission(json.loads(PACKAGE_DATA))
     FormSubmission.from_ona_form_data(form_data)
     self.assertTrue(PackageScan.objects.all())
Beispiel #8
0
def record_package_location(sender, instance, **kwargs):
    # Only record package locations for package tracking forms
    try:
        logger.debug("record_package_location...")
        form_id = int(settings.ONA_PACKAGE_FORM_ID)
        if kwargs.get('created', False) and int(
                instance.data['form_id']) == form_id:
            submission = PackageScanFormSubmission(instance.data)
            logger.debug("New formsubmission. %d QR codes",
                         len(submission.get_qr_codes()))
            for code in submission.get_qr_codes():
                logger.debug("QR code: %s" % code)
                try:
                    pkg = Package.objects.get(code=code)
                except Package.DoesNotExist:
                    logger.exception("Scanned Package with code %s not found" %
                                     code)
                else:
                    scan_status_label = submission.get_current_packagescan_label(
                    )
                    PackageScan.objects.create(
                        package=pkg,
                        longitude=submission.get_lng(),
                        latitude=submission.get_lat(),
                        altitude=submission.get_altitude(),
                        accuracy=submission.get_accuracy(),
                        when=submission._submission_time,
                        status_label=scan_status_label)
                    logger.debug("created location")
                    # Update Package and Shipment Status based on selected current_location value
                    # Values should look similar to the following samples, defined by the
                    # Ona XLSFOrm:
                    # STATUS_IN_TRANSIT-Zero_Point
                    # STATUS_IN_TRANSIT-Partner_Warehouse
                    # STATUS_IN_TRANSIT-Pre-Distribution_Point
                    # STATUS_RECEIVED-Distribution Point
                    # STATUS_RECEIVED-Post-Distribution Point
                    # The prefix part (before the first -) is one of the predefined status
                    # names that are attributes of the Shipment model.
                    status = submission.current_location.split('-', 1)[0]
                    logger.debug("status=%r" % status)
                    if not hasattr(Shipment, status):
                        # If no match is found, log the invalid package status as it is
                        # indicative of the app and Ona being out of sync
                        msg = "FormSubmission with form id of %s has invalid package status: %s" \
                            % (instance.form_id, status)
                        logger.error(msg)
                        continue
                    status = getattr(Shipment, status, None)
                    if status:
                        update_fields = ['last_scan_status_label']
                        pkg.last_scan_status_label = scan_status_label
                        if pkg.status != status:
                            update_fields.append('status')
                            pkg.status = status
                        if status == Shipment.STATUS_RECEIVED and not pkg.date_received:
                            update_fields.append('date_received')
                            pkg.date_received = submission._submission_time
                        elif status == Shipment.STATUS_PICKED_UP and not pkg.date_picked_up:
                            update_fields.append('date_picked_up')
                            pkg.date_picked_up = submission._submission_time
                        elif status == Shipment.STATUS_IN_TRANSIT and not pkg.date_in_transit:
                            update_fields.append('date_in_transit')
                            pkg.date_in_transit = submission._submission_time
                        pkg.save(update_fields=update_fields)
                        pkg.shipment.status = status
                        pkg.shipment.last_scan_status_label = scan_status_label
                        pkg.shipment.save(
                            update_fields=['status', 'last_scan_status_label'])
                        logger.debug("set status to %s" %
                                     pkg.get_status_display())
        else:
            logger.debug(
                "Ignoring this FormSubmission.  kwargs[created]=%s, form_id=%s,"
                " form_id=%s" % (kwargs.get(
                    'created', False), int(instance.data['form_id']), form_id))
    except Exception:
        logger.exception("Something blew up in record_package_location")
Beispiel #9
0
 def setUp(self):
     super(ShipmentDashboardViewTest, self).setUp()
     self.package = PackageFactory(shipment=self.shipment, code=QR_CODE)
     form_data = PackageScanFormSubmission(json.loads(PACKAGE_DATA))
     FormSubmission.from_ona_form_data(form_data)
     self.url = reverse('shipments_dashboard')