Esempio n. 1
0
def get_supply_point(domain, site_code=None, loc=None):
    if loc is None:
        loc = Location.view('commtrack/locations_by_code',
                            key=[domain, site_code.lower()],
                            include_docs=True).first()
    if loc:
        case = SupplyPointCase.get_by_location(loc)
 def handle(self, *args, **options):
     for retailer_location in Location.filter_by_type(
             "colalifezambia", "retailer"):
         retailer_case = SupplyPointCase.get_by_location(retailer_location)
         wholesaler_location = retailer_location.parent
         wholesaler_case = SupplyPointCase.get_by_location(
             wholesaler_location)
         retailer_case.wholesaler_case_id = wholesaler_case._id
         retailer_case.save()
 def handle(self, *args, **options):
     for retailer_location in Location.filter_by_type(
             "colalifezambia", "retailer"):
         retailer_case = SupplyPointCase.get_by_location(retailer_location)
         wholesaler_location = retailer_location.parent
         wholesaler_case = SupplyPointCase.get_by_location(
             wholesaler_location
         )
         retailer_case.wholesaler_case_id = wholesaler_case._id
         retailer_case.save()
Esempio n. 4
0
def sync_ilsgateway_location(domain, endpoint, ilsgateway_location):
    location = Location.view('commtrack/locations_by_code',
                             key=[domain, ilsgateway_location.code.lower()],
                             include_docs=True).first()
    if not location:
        if ilsgateway_location.parent:
            loc_parent = SupplyPointCase.view('hqcase/by_domain_external_id',
                                              key=[domain, str(ilsgateway_location.parent)],
                                              reduce=False,
                                              include_docs=True).first()
            if not loc_parent:
                parent = endpoint.get_location(ilsgateway_location.parent)
                loc_parent = sync_ilsgateway_location(domain, endpoint, Loc.from_json(parent))
            else:
                loc_parent = loc_parent.location
            location = Location(parent=loc_parent)
        else:
            location = Location()
            location.lineage = []
        location.domain = domain
        location.name = ilsgateway_location.name
        if ilsgateway_location.groups:
            location.metadata = {'groups': ilsgateway_location.groups}
        if ilsgateway_location.latitude:
            location.latitude = float(ilsgateway_location.latitude)
        if ilsgateway_location.longitude:
            location.longitude = float(ilsgateway_location.longitude)
        location.location_type = ilsgateway_location.type
        location.site_code = ilsgateway_location.code
        location.external_id = str(ilsgateway_location.id)
        location.save()
        if not SupplyPointCase.get_by_location(location):
            SupplyPointCase.create_from_location(domain, location)
    else:
        location_dict = {
            'name': ilsgateway_location.name,
            'latitude': float(ilsgateway_location.latitude) if ilsgateway_location.latitude else None,
            'longitude': float(ilsgateway_location.longitude) if ilsgateway_location.longitude else None,
            'type': ilsgateway_location.type,
            'site_code': ilsgateway_location.code.lower(),
            'external_id': str(ilsgateway_location.id),
        }
        case = SupplyPointCase.get_by_location(location)
        if apply_updates(location, location_dict):
            location.save()
            if case:
                case.update_from_location(location)
            else:
                SupplyPointCase.create_from_location(domain, location)
    return location
Esempio n. 5
0
def sync_ilsgateway_location(domain, endpoint, ilsgateway_location):
    location = Location.view('commtrack/locations_by_code',
                             key=[domain, ilsgateway_location.code.lower()],
                             include_docs=True).first()
    if not location:
        if ilsgateway_location.parent:
            loc_parent = SupplyPointCase.view('hqcase/by_domain_external_id',
                                              key=[domain, str(ilsgateway_location.parent)],
                                              reduce=False,
                                              include_docs=True).first()
            if not loc_parent:
                parent = endpoint.get_location(ilsgateway_location.parent)
                loc_parent = sync_ilsgateway_location(domain, endpoint, Loc.from_json(parent))
            else:
                loc_parent = loc_parent.location
            location = Location(parent=loc_parent)
        else:
            location = Location()
            location.lineage = []
        location.domain = domain
        location.name = ilsgateway_location.name
        if ilsgateway_location.groups:
            location.metadata = {'groups': ilsgateway_location.groups}
        if ilsgateway_location.latitude:
            location.latitude = float(ilsgateway_location.latitude)
        if ilsgateway_location.longitude:
            location.longitude = float(ilsgateway_location.longitude)
        location.location_type = ilsgateway_location.type
        location.site_code = ilsgateway_location.code
        location.external_id = str(ilsgateway_location.id)
        location.save()
        if not SupplyPointCase.get_by_location(location):
            SupplyPointCase.create_from_location(domain, location)
    else:
        location_dict = {
            'name': ilsgateway_location.name,
            'latitude': float(ilsgateway_location.latitude) if ilsgateway_location.latitude else None,
            'longitude': float(ilsgateway_location.longitude) if ilsgateway_location.longitude else None,
            'type': ilsgateway_location.type,
            'site_code': ilsgateway_location.code.lower(),
            'external_id': str(ilsgateway_location.id),
        }
        case = SupplyPointCase.get_by_location(location)
        if apply_updates(location, location_dict):
            location.save()
            if case:
                case.update_from_location(location)
            else:
                SupplyPointCase.create_from_location(domain, location)
Esempio n. 6
0
def bootstrap_user(
    username=TEST_USER,
    domain=TEST_DOMAIN,
    phone_number=TEST_NUMBER,
    password=TEST_PASSWORD,
    backend=TEST_BACKEND,
    first_name='',
    last_name='',
    home_loc=None,
    user_data=None,
):
    from corehq.apps.commtrack.helpers import make_supply_point

    user_data = user_data or {}
    user = CommCareUser.create(domain,
                               username,
                               password,
                               phone_numbers=[TEST_NUMBER],
                               user_data=user_data,
                               first_name=first_name,
                               last_name=last_name)

    if not SupplyPointCase.get_by_location(home_loc):
        make_supply_point(domain, home_loc)
        home_loc.save()
    user.set_location(home_loc)

    user.save_verified_number(domain,
                              phone_number,
                              verified=True,
                              backend_id=backend)
    return CommCareUser.wrap(user.to_json())
Esempio n. 7
0
 def handle(self, *args, **options):
     for location_type in ["wholesaler", "retailer"]:
         for location in Location.filter_by_type("colalifezambia",
                                                 location_type):
             supply_point_case = SupplyPointCase.get_by_location(location)
             supply_point_case.location_type = location_type
             supply_point_case.save()
Esempio n. 8
0
def bootstrap_user(username=TEST_USER, domain=TEST_DOMAIN,
                   phone_number=TEST_NUMBER, password=TEST_PASSWORD,
                   backend=TEST_BACKEND, first_name='', last_name='',
                   home_loc=None, user_data=None,
                   ):
    from corehq.apps.commtrack.helpers import make_supply_point

    user_data = user_data or {}
    user = CommCareUser.create(
        domain,
        username,
        password,
        phone_numbers=[TEST_NUMBER],
        user_data=user_data,
        first_name=first_name,
        last_name=last_name
    )

    if not SupplyPointCase.get_by_location(home_loc):
        make_supply_point(domain, home_loc)
        home_loc.save()
    user.set_location(home_loc)

    user.save_verified_number(domain, phone_number, verified=True, backend_id=backend)
    return CommCareUser.wrap(user.to_json())
Esempio n. 9
0
def bootstrap_user(
    setup,
    username=TEST_USER,
    domain=TEST_DOMAIN,
    phone_number=TEST_NUMBER,
    password=TEST_PASSWORD,
    backend=TEST_BACKEND,
    first_name='',
    last_name='',
    home_loc=None,
    user_data=None,
):
    user_data = user_data or {}
    user = CommTrackUser.create(domain,
                                username,
                                password,
                                phone_numbers=[TEST_NUMBER],
                                user_data=user_data,
                                first_name=first_name,
                                last_name=last_name)
    if home_loc == setup.loc.site_code:
        if not SupplyPointCase.get_by_location(setup.loc):
            make_supply_point(domain, setup.loc)

        user.add_location(setup.loc)
        user.save()

    user.save_verified_number(domain,
                              phone_number,
                              verified=True,
                              backend_id=backend)
    return CommTrackUser.wrap(user.to_json())
Esempio n. 10
0
def report_reminder_process_user(user, test=False):
    now = datetime.datetime.utcnow()
    date = now - datetime.timedelta(days=7)

    if not user.location or user.location.location_type.administrative:
        return
    sp = SupplyPointCase.get_by_location(user.location)
    if not sp:
        return
    transaction_exists = StockTransaction.objects.filter(
        case_id=sp._id,
        type="stockonhand",
        report__date__gte=date
    ).exists()
    if sp and not transaction_exists and user.get_verified_number():
        message = REPORT_REMINDER % (user.name, user.location.name)
        verified_number = user.get_verified_number()
        if not test:
            send_sms_to_verified_number(verified_number, message)
        else:
            send_test_message(verified_number, message)

        if can_receive_email(user, verified_number):
            email = str(user.email)
            send_mail('REPORT REMINDER', message, '*****@*****.**', [email])
Esempio n. 11
0
def stockout_process_user(user, test=False):
    if user_has_reporting_location(user):
        location = user.location
        supply_point = SupplyPointCase.get_by_location(location)
        if supply_point and user.get_verified_number():
            products = [
                SQLProduct.objects.get(product_id=state.product_id).name
                for state in StockState.objects.filter(
                    case_id=supply_point._id, stock_on_hand=0,
                    product_id__in=[product.product_id for product in location.sql_location.products]
                )
            ]
            if products:
                if not test:
                    send_sms_to_verified_number(
                        user.get_verified_number(),
                        STOCKOUT_REPORT % {
                            'name': user.name,
                            'facility': supply_point.name,
                            'date': datetime.datetime.utcnow().strftime('%b %d'),
                            'products': ", ".join(products)
                        }
                    )
                else:
                    send_test_message(
                        user.get_verified_number(),
                        STOCKOUT_REPORT % {
                            'name': user.name,
                            'facility': supply_point.name,
                            'date': datetime.datetime.utcnow().strftime('%b %d'),
                            'products': ", ".join(products)
                        }
                    )
Esempio n. 12
0
def stockout_process_user(user, test=False):
    if user_has_reporting_location(user):
        location = user.location
        supply_point = SupplyPointCase.get_by_location(location)
        if supply_point and user.get_verified_number():
            products = [
                SQLProduct.objects.get(product_id=state.product_id).name
                for state in StockState.objects.filter(
                    case_id=supply_point._id,
                    stock_on_hand=0,
                    product_id__in=[
                        product.product_id
                        for product in location.sql_location.products
                    ])
            ]
            if products:
                if not test:
                    send_sms_to_verified_number(
                        user.get_verified_number(), STOCKOUT_REPORT % {
                            'name': user.name,
                            'facility': supply_point.name,
                            'date':
                            datetime.datetime.utcnow().strftime('%b %d'),
                            'products': ", ".join(products)
                        })
                else:
                    send_test_message(
                        user.get_verified_number(), STOCKOUT_REPORT % {
                            'name': user.name,
                            'facility': supply_point.name,
                            'date':
                            datetime.datetime.utcnow().strftime('%b %d'),
                            'products': ", ".join(products)
                        })
Esempio n. 13
0
def submit_form(domain, parent, form_data, properties, existing, location_type, consumption):
    # don't save if there is nothing to save
    if no_changes_needed(domain, existing, properties, form_data, consumption):
        return {
            'id': existing._id,
            'message': 'no changes for %s %s' % (location_type, existing.name)
        }

    form_data.update(properties)

    form = make_form(domain, parent, form_data, existing)
    form.strict = False  # optimization hack to turn off strict validation
    if form.is_valid():
        loc = form.save()

        sp = SupplyPointCase.get_by_location(loc) if consumption else None

        if consumption and sp:
            for product_code, value in consumption:
                try:
                    amount = Decimal(value)

                    # only set it if there is a non-negative/non-null value
                    if amount and amount >= 0:
                        set_default_consumption_for_supply_point(
                            domain,
                            Product.get_by_code(domain, product_code)._id,
                            sp._id,
                            amount
                        )
                except (TypeError, InvalidOperation):
                    # should inform user, but failing hard due to non numbers
                    # being used on consumption is strange since the
                    # locations would be in a very inconsistent state
                    continue

        if existing:
            message = 'updated %s %s' % (location_type, loc.name)
        else:
            message = 'created %s %s' % (location_type, loc.name)

        return {
            'id': loc._id,
            'message': message
        }
    else:
        message = 'Form errors when submitting: '
        # TODO move this to LocationForm somehow
        forms = filter(None, [form, form.sub_forms.get(location_type)])
        for k, v in itertools.chain(*(f.errors.iteritems() for f in forms)):
            if k != '__all__':
                message += u'{0} {1}; {2}: {3}. '.format(
                    location_type, form_data.get('name', 'unknown'), k, v[0]
                )

        return {
            'id': None,
            'message': message
        }
Esempio n. 14
0
def submit_form(domain, parent, form_data, properties, existing, location_type, consumption):
    # don't save if there is nothing to save
    if no_changes_needed(domain, existing, properties, form_data, consumption):
        return {
            'id': existing._id,
            'message': 'no changes for %s %s' % (location_type, existing.name)
        }

    form_data.update(properties)

    form = make_form(domain, parent, form_data, existing)
    form.strict = False  # optimization hack to turn off strict validation
    if form.is_valid():
        loc = form.save()

        sp = SupplyPointCase.get_by_location(loc) if consumption else None

        if consumption and sp:
            for product_code, value in consumption:
                try:
                    amount = Decimal(value)

                    # only set it if there is a non-negative/non-null value
                    if amount and amount >= 0:
                        set_default_consumption_for_supply_point(
                            domain,
                            Product.get_by_code(domain, product_code)._id,
                            sp._id,
                            amount
                        )
                except (TypeError, InvalidOperation):
                    # should inform user, but failing hard due to non numbers
                    # being used on consumption is strange since the
                    # locations would be in a very inconsistent state
                    continue

        if existing:
            message = 'updated %s %s' % (location_type, loc.name)
        else:
            message = 'created %s %s' % (location_type, loc.name)

        return {
            'id': loc._id,
            'message': message
        }
    else:
        message = 'Form errors when submitting: '
        # TODO move this to LocationForm somehow
        forms = filter(None, [form, form.sub_forms.get(location_type)])
        for k, v in itertools.chain(*(f.errors.iteritems() for f in forms)):
            if k != '__all__':
                message += u'{0} {1}; {2}: {3}. '.format(
                    location_type, form_data.get('name', 'unknown'), k, v[0]
                )

        return {
            'id': None,
            'message': message
        }
Esempio n. 15
0
def get_supply_point(domain, site_code=None, loc=None):
    if loc is None:
        loc = Location.view("commtrack/locations_by_code", key=[domain, site_code.lower()], include_docs=True).first()
    if loc:
        case = SupplyPointCase.get_by_location(loc)
    else:
        case = None

    return {"case": case, "location": loc}
Esempio n. 16
0
def send_soh_reminder(domain, date):
    sp_ids = set()
    for user in CommTrackUser.by_domain(domain):
        if user.is_active and user.location and user.location.location_type == 'FACILITY':
            sp = SupplyPointCase.get_by_location(user.location)
            if sp and not StockTransaction.objects.filter(case_id=sp._id, report__date__gte=date,
                                                          type='stockonhand').exists():
                if user.get_verified_number():
                        send_sms_to_verified_number(user.get_verified_number(), REMINDER_STOCKONHAND)
                        sp_ids.add(sp._id)
    update_statuses(sp_ids, SupplyPointStatusTypes.SOH_FACILITY, SupplyPointStatusValues.REMINDER_SENT)
Esempio n. 17
0
def send_soh_reminder(domain, date):
    sp_ids = set()
    for user in CommTrackUser.by_domain(domain):
        if user.is_active and user.location and user.location.location_type == 'FACILITY':
            sp = SupplyPointCase.get_by_location(user.location)
            if sp and not StockTransaction.objects.filter(case_id=sp._id, report__date__gte=date,
                                                          type='stockonhand').exists():
                if user.get_verified_number():
                        send_sms_to_verified_number(user.get_verified_number(), REMINDER_STOCKONHAND)
                        sp_ids.add(sp._id)
    update_statuses(sp_ids, SupplyPointStatusTypes.SOH_FACILITY, SupplyPointStatusValues.REMINDER_SENT)
Esempio n. 18
0
def send_soh_reminder(domain, date, test_list=None):
    sp_ids = set()
    users = CommCareUser.by_domain(domain) if not test_list else test_list
    for user in users:
        if user.is_active and user.location and user.location.location_type == 'FACILITY':
            sp = SupplyPointCase.get_by_location(user.location)
            if sp and not StockTransaction.objects.filter(case_id=sp._id, report__date__gte=date,
                                                          type='stockonhand').exists():
                result = send_translated_message(user, REMINDER_STOCKONHAND)
                if not test_list and result:
                    sp_ids.add(sp._id)
    update_statuses(sp_ids, SupplyPointStatusTypes.SOH_FACILITY, SupplyPointStatusValues.REMINDER_SENT)
Esempio n. 19
0
def send_supervision_reminder(domain, date):
    sp_ids = set()
    for user in CommTrackUser.by_domain(domain):
        if user.is_active and user.location and user.location.location_type == 'FACILITY':
            sp = SupplyPointCase.get_by_location(user.location)
            if sp and not SupplyPointStatus.objects.filter(supply_point=sp._id,
                                                           status_type=SupplyPointStatusTypes.SUPERVISION_FACILITY,
                                                           status_date__gte=date).exists():
                if user.get_verified_number():
                        send_sms_to_verified_number(user.get_verified_number(), REMINDER_SUPERVISION)
                        sp_ids.add(sp._id)
    update_statuses(sp_ids, SupplyPointStatusTypes.SUPERVISION_FACILITY, SupplyPointStatusValues.REMINDER_SENT)
Esempio n. 20
0
 def _create_supply_point_from_location(self, supply_point, location):
     if not SupplyPointCase.get_by_location(location):
         if supply_point.supervised_by:
             location.metadata['supervised_by'] = supply_point.supervised_by
             location.save()
             sql_loc = location.sql_location
             sql_loc.products = SQLProduct.objects.filter(domain=self.domain, code__in=supply_point.products)
             sql_loc.save()
         return SupplyPointCase.get_or_create_by_location(Loc(_id=location._id,
                                                          name=supply_point.name,
                                                          external_id=str(supply_point.id),
                                                          domain=self.domain))
Esempio n. 21
0
    def save(self, user):
        commtrack_user = CommTrackUser.wrap(user.to_json())
        location_id = self.cleaned_data['supply_point']
        if location_id:
            loc = Location.get(location_id)

            commtrack_user.clear_locations()
            commtrack_user.add_location(loc, create_sp_if_missing=True)

            # add the supply point case id to user data fields
            # so that the phone can auto select
            supply_point = SupplyPointCase.get_by_location(loc)
            user.user_data['commtrack-supply-point'] = supply_point._id
Esempio n. 22
0
    def save(self, user):
        commtrack_user = CommTrackUser.wrap(user.to_json())
        location_id = self.cleaned_data['supply_point']
        if location_id:
            loc = Location.get(location_id)

            commtrack_user.clear_locations()
            commtrack_user.add_location(loc, create_sp_if_missing=True)

            # add the supply point case id to user data fields
            # so that the phone can auto select
            supply_point = SupplyPointCase.get_by_location(loc)
            user.user_data['commtrack-supply-point'] = supply_point._id
Esempio n. 23
0
 def _create_supply_point_from_location(self, supply_point, location):
     if not SupplyPointCase.get_by_location(location):
         if supply_point.supervised_by:
             location.metadata['supervised_by'] = supply_point.supervised_by
             location.save()
             sql_loc = location.sql_location
             sql_loc.products = SQLProduct.objects.filter(
                 domain=self.domain, code__in=supply_point.products)
             sql_loc.save()
         return SupplyPointCase.get_or_create_by_location(
             Loc(_id=location._id,
                 name=supply_point.name,
                 external_id=str(supply_point.id),
                 domain=self.domain))
Esempio n. 24
0
def send_soh_reminder(domain, date, test_list=None):
    sp_ids = set()
    users = CommCareUser.by_domain(domain) if not test_list else test_list
    for user in users:
        if user.is_active and user.location and user.location.location_type == 'FACILITY':
            sp = SupplyPointCase.get_by_location(user.location)
            if sp and not StockTransaction.objects.filter(
                    case_id=sp._id, report__date__gte=date,
                    type='stockonhand').exists():
                result = send_translated_message(user, REMINDER_STOCKONHAND)
                if not test_list and result:
                    sp_ids.add(sp._id)
    update_statuses(sp_ids, SupplyPointStatusTypes.SOH_FACILITY,
                    SupplyPointStatusValues.REMINDER_SENT)
Esempio n. 25
0
def send_supervision_reminder(domain, date):
    sp_ids = set()
    for user in CommTrackUser.by_domain(domain):
        if user.is_active and user.location and user.location.location_type == 'FACILITY':
            sp = SupplyPointCase.get_by_location(user.location)
            if sp and not SupplyPointStatus.objects.filter(
                    supply_point=sp._id,
                    status_type=SupplyPointStatusTypes.SUPERVISION_FACILITY,
                    status_date__gte=date).exists():
                if user.get_verified_number():
                    send_sms_to_verified_number(user.get_verified_number(),
                                                REMINDER_SUPERVISION)
                    sp_ids.add(sp._id)
    update_statuses(sp_ids, SupplyPointStatusTypes.SUPERVISION_FACILITY,
                    SupplyPointStatusValues.REMINDER_SENT)
Esempio n. 26
0
def submit_form(domain, parent, form_data, properties, existing, location_type, consumption):
    # don't save if there is nothing to save
    if no_changes_needed(domain, existing, properties, form_data, consumption):
        return {
            'id': existing._id,
            'message': 'no changes for %s %s' % (location_type, existing.name)
        }

    form_data.update(properties)

    form = make_form(domain, parent, form_data, existing)
    form.strict = False  # optimization hack to turn off strict validation
    if form.is_valid():
        loc = form.save()

        sp = SupplyPointCase.get_by_location(loc) if consumption else None

        if consumption and sp:
            for product_code, amount in consumption:
                set_default_consumption_for_supply_point(
                    domain,
                    Product.get_by_code(domain, product_code)._id,
                    sp._id,
                    amount
                )
        if existing:
            message = 'updated %s %s' % (location_type, loc.name)
        else:
            message = 'created %s %s' % (location_type, loc.name)

        return {
            'id': loc._id,
            'message': message
        }
    else:
        message = 'Form errors when submitting: '
        # TODO move this to LocationForm somehow
        forms = filter(None, [form, form.sub_forms.get(location_type)])
        for k, v in itertools.chain(*(f.errors.iteritems() for f in forms)):
            if k != '__all__':
                message += u'{0} {1}; {2}: {3}. '.format(
                    location_type, form_data.get('name', 'unknown'), k, v[0]
                )

        return {
            'id': None,
            'message': message
        }
Esempio n. 27
0
def second_soh_process_user(user, test=False):
    now = datetime.datetime.utcnow()
    date = now - datetime.timedelta(days=DAYS_UNTIL_LATE)
    supply_point = SupplyPointCase.get_by_location(user.location)
    if not supply_point:
        return

    stock_states = StockState.objects.filter(
        case_id=supply_point._id,
        last_modified_date__gte=date
    )
    products = user.sql_location.products
    location_products_ids = [product.product_id for product in products]
    reported_products_ids = [stock_state.product_id for stock_state in stock_states]
    missing_products_ids = set(location_products_ids) - set(reported_products_ids)
    if not user_has_reporting_location(user) or not user.get_verified_number():
        return

    if not stock_states:
        if not test:
            send_sms_to_verified_number(
                user.get_verified_number(),
                SECOND_STOCK_ON_HAND_REMINDER % {'name': user.name}
            )
        else:
            send_test_message(
                user.get_verified_number(),
                SECOND_STOCK_ON_HAND_REMINDER % {'name': user.name}
            )
    elif missing_products_ids:
        products_names = [
            product.name
            for product in products
            if product.product_id in missing_products_ids
        ]
        if not test:
            send_sms_to_verified_number(
                user.get_verified_number(),
                SECOND_INCOMPLETE_SOH_REMINDER %
                {'name': user.name, 'products': ", ".join(products_names)}
            )
        else:
            send_test_message(
                user.get_verified_number(),
                SECOND_INCOMPLETE_SOH_REMINDER %
                {'name': user.name, 'products': ", ".join(products_names)}
            )
Esempio n. 28
0
def second_soh_process_user(user, test=False):
    now = datetime.datetime.utcnow()
    date = now - datetime.timedelta(days=DAYS_UNTIL_LATE)
    supply_point = SupplyPointCase.get_by_location(user.location)
    if not supply_point:
        return

    stock_states = StockState.objects.filter(case_id=supply_point._id,
                                             last_modified_date__gte=date)
    products = user.sql_location.products
    location_products_ids = [product.product_id for product in products]
    reported_products_ids = [
        stock_state.product_id for stock_state in stock_states
    ]
    missing_products_ids = set(location_products_ids) - set(
        reported_products_ids)
    if not user_has_reporting_location(user) or not user.get_verified_number():
        return

    if not stock_states:
        if not test:
            send_sms_to_verified_number(
                user.get_verified_number(),
                SECOND_STOCK_ON_HAND_REMINDER % {'name': user.name})
        else:
            send_test_message(
                user.get_verified_number(),
                SECOND_STOCK_ON_HAND_REMINDER % {'name': user.name})
    elif missing_products_ids:
        products_names = [
            product.name for product in products
            if product.product_id in missing_products_ids
        ]
        if not test:
            send_sms_to_verified_number(
                user.get_verified_number(), SECOND_INCOMPLETE_SOH_REMINDER % {
                    'name': user.name,
                    'products': ", ".join(products_names)
                })
        else:
            send_test_message(
                user.get_verified_number(), SECOND_INCOMPLETE_SOH_REMINDER % {
                    'name': user.name,
                    'products': ", ".join(products_names)
                })
Esempio n. 29
0
def report_reminder():
    sp_ids = set()
    now = datetime.datetime.utcnow()
    date = now - datetime.timedelta(days=7)
    domains = EWSGhanaConfig.get_all_enabled_domains()
    for domain in domains:
        for user in CommCareUser.by_domain(domain):
            if user.location:
                sp = SupplyPointCase.get_by_location(user.location)
                if sp and not StockTransaction.objects.filter(
                    case_id=sp._id, type="stockonhand", report__date__gte=date).exists()\
                        and user.get_verified_number():
                    sp_ids.add(sp._id)
                    message = REPORT_REMINDER % (user.name, user.location.name)
                    send_sms_to_verified_number(user.get_verified_number(), message)
                    if user.email:
                        email = str(user.email)
                        send_mail('REPORT REMINDER', message, '*****@*****.**', [email])
Esempio n. 30
0
    def get_message_for_location(self, location):
        supply_point = SupplyPointCase.get_by_location(location)
        if not supply_point:
            return

        on_time_products, missing_products = report_status(location.sql_location, days_until_late=DAYS_UNTIL_LATE)

        if not on_time_products:
            return SECOND_STOCK_ON_HAND_REMINDER, {}
        elif missing_products:
            products_names = ', '.join([
                product.name
                for product in missing_products
            ])

            return SECOND_INCOMPLETE_SOH_REMINDER, {'products': products_names}

        return None, {}
Esempio n. 31
0
def first_soh_process_user(user, test=False):
    if user_has_reporting_location(user) and user_has_role(user, IN_CHARGE_ROLE):
        supply_point = SupplyPointCase.get_by_location(user.location)
        transaction_exists = StockTransaction.objects.filter(
            case_id=supply_point._id,
            type='stockonhand'
        ).exists()
        if supply_point and not transaction_exists and user.get_verified_number():
            message = STOCK_ON_HAND_REMINDER % {'name': user.name}
            if not test:
                send_sms_to_verified_number(
                    user.get_verified_number(),
                    message
                )
            else:
                send_test_message(
                    user.get_verified_number(),
                    message
                )
Esempio n. 32
0
def send_ror_reminder(domain, date, loc_type='FACILITY'):
    if loc_type == 'FACILITY':
        status_type = SupplyPointStatusTypes.R_AND_R_FACILITY
        sms_text = REMINDER_R_AND_R_FACILITY
    elif loc_type == 'DISTRICT':
        status_type = SupplyPointStatusTypes.R_AND_R_DISTRICT
        sms_text = REMINDER_R_AND_R_DISTRICT
    else:
        return
    current_group = get_current_group()
    sp_ids = set()
    for user in CommTrackUser.by_domain(domain):
        if user.is_active and user.location and user.location.location_type == loc_type:
            sp = SupplyPointCase.get_by_location(user.location)
            if current_group in get_groups(sp.location.metadata.get('groups', None)) \
                    and not SupplyPointStatus.objects.filter(supply_point=sp._id, status_type=status_type,
                                                             status_date__gte=date).exists():
                if user.get_verified_number():
                    send_sms_to_verified_number(user.get_verified_number(), sms_text)
                    sp_ids.add(sp._id)
    update_statuses(sp_ids, status_type, SupplyPointStatusValues.REMINDER_SENT)
Esempio n. 33
0
def send_ror_reminder(domain, date, loc_type='FACILITY'):
    if loc_type == 'FACILITY':
        status_type = SupplyPointStatusTypes.R_AND_R_FACILITY
        sms_text = REMINDER_R_AND_R_FACILITY
    elif loc_type == 'DISTRICT':
        status_type = SupplyPointStatusTypes.R_AND_R_DISTRICT
        sms_text = REMINDER_R_AND_R_DISTRICT
    else:
        return
    current_group = DeliveryGroups().current_submitting_group(date.month)
    sp_ids = set()
    for user in CommTrackUser.by_domain(domain):
        if user.is_active and user.location and user.location.location_type == loc_type:
            sp = SupplyPointCase.get_by_location(user.location)
            if current_group in get_groups(sp.location.metadata.get('groups', None)) \
                    and not SupplyPointStatus.objects.filter(supply_point=sp._id, status_type=status_type,
                                                             status_date__gte=date).exists():
                if user.get_verified_number():
                    send_sms_to_verified_number(user.get_verified_number(), sms_text)
                    sp_ids.add(sp._id)
    update_statuses(sp_ids, status_type, SupplyPointStatusValues.REMINDER_SENT)
Esempio n. 34
0
def second_soh_process_user(user, date, test=False):
    supply_point = SupplyPointCase.get_by_location(user.location)
    if not supply_point:
        return

    stock_states = StockState.objects.filter(
        case_id=supply_point._id,
        last_modified_date__gte=date
    )

    location_products = [product.product_id for product in user.location.sql_location.products]
    reported_products = [stock_state.product_id for stock_state in stock_states]
    missing_products = set(location_products) - set(reported_products)
    if user_has_reporting_location(user) and user_has_role(user, IN_CHARGE_ROLE):
        if user.get_verified_number():
            if not stock_states:
                if not test:
                    send_sms_to_verified_number(
                        user.get_verified_number(),
                        SECOND_STOCK_ON_HAND_REMINDER % {'name': user.name}
                    )
                else:
                    send_test_message(
                        user.get_verified_number(),
                        SECOND_STOCK_ON_HAND_REMINDER % {'name': user.name}
                    )
            elif missing_products:
                if not test:
                    send_sms_to_verified_number(
                        user.get_verified_number(),
                        SECOND_INCOMPLETE_SOH_REMINDER %
                        {'name': user.name, 'products': ", ".join(missing_products)}
                    )
                else:
                    send_test_message(
                        user.get_verified_number(),
                        SECOND_INCOMPLETE_SOH_REMINDER %
                        {'name': user.name, 'products': ", ".join(missing_products)}
                    )
Esempio n. 35
0
def stock_alerts(transactions, user):
    products_without_receipts = set()
    products_above = set()
    products_below = set()
    sp = SupplyPointCase.get_by_location(user.location)
    for i in range(0, len(transactions), 2):
        if StockState.objects.filter(case_id=sp._id, product_id=transactions[i + 1].product_id).exists():
            receipt = int(transactions[i].quantity)
            stock = int(transactions[i + 1].quantity)
            product = SQLProduct.objects.get(product_id=transactions[i].product_id).name
            last_stock = StockState.objects.get(
                case_id=sp._id, product_id=transactions[i].product_id).stock_on_hand

            stock_levels_config = CommtrackConfig.for_domain(user.domain).stock_levels_config
            over_stock_threshold = stock_levels_config.overstock_threshold
            under_stock_threshold = stock_levels_config.understock_threshold

            if stock > over_stock_threshold:
                products_above.add(product)
            elif stock < under_stock_threshold:
                products_below.add(product)
            if stock > last_stock and receipt == 0:
                products_without_receipts.add(product)

    if products_below:
        message = BELOW_REORDER_LEVELS % (user.name, user.location,
                                          ", ".join(sorted([str(prod) for prod in products_below])))
        send_sms_to_verified_number(user.get_verified_number(), message)
    elif products_above:
        message = ABOVE_THRESHOLD % (
            user.name, ", ".join(sorted([str(prod) for prod in products_above])))
        send_sms_to_verified_number(user.get_verified_number(), message)
    elif products_without_receipts:
        message = WITHOUT_RECEIPTS % (
            ', '.join(sorted([str(prod) for prod in products_without_receipts])))
        send_sms_to_verified_number(user.get_verified_number(), message)
    else:
        return False
Esempio n. 36
0
def bootstrap_user(setup, username=TEST_USER, domain=TEST_DOMAIN,
                   phone_number=TEST_NUMBER, password=TEST_PASSWORD,
                   backend=TEST_BACKEND, first_name='', last_name='',
                   home_loc=None, user_data=None,
                   ):
    user_data = user_data or {}
    user = CommCareUser.create(
        domain,
        username,
        password,
        phone_numbers=[TEST_NUMBER],
        user_data=user_data,
        first_name=first_name,
        last_name=last_name
    )
    if home_loc == setup.loc.site_code:
        if not SupplyPointCase.get_by_location(setup.loc):
            make_supply_point(domain, setup.loc)

        user.set_location(setup.loc)

    user.save_verified_number(domain, phone_number, verified=True, backend_id=backend)
    return CommCareUser.wrap(user.to_json())
Esempio n. 37
0
def report_reminder_process_user(user, test=False):
    now = datetime.datetime.utcnow()
    date = now - datetime.timedelta(days=7)

    if not user.location or user.location.location_type.administrative:
        return
    sp = SupplyPointCase.get_by_location(user.location)
    if not sp:
        return
    transaction_exists = StockTransaction.objects.filter(
        case_id=sp._id, type="stockonhand", report__date__gte=date).exists()
    if sp and not transaction_exists and user.get_verified_number():
        message = REPORT_REMINDER % (user.name, user.location.name)
        verified_number = user.get_verified_number()
        if not test:
            send_sms_to_verified_number(verified_number, message)
        else:
            send_test_message(verified_number, message)

        if can_receive_email(user, verified_number):
            email = str(user.email)
            send_mail('REPORT REMINDER', message,
                      '*****@*****.**', [email])
Esempio n. 38
0
 def linked_supply_point(self):
     from corehq.apps.commtrack.models import SupplyPointCase
     return SupplyPointCase.get_by_location(self)
Esempio n. 39
0
 def _create_supply_point_from_location(self, supply_point, location):
     if not SupplyPointCase.get_by_location(location):
         return SupplyPointCase.get_or_create_by_location(Loc(_id=location.get_id,
                                                          name=supply_point.name,
                                                          external_id=str(supply_point.id),
                                                          domain=self.domain))
Esempio n. 40
0
    def location_sync(self, ilsgateway_location):
        def get_or_create_msd_zone(region):
            msd_name = _get_msd_name(region.name)
            msd_code = MSDZONE_MAP[msd_name][0]
            try:
                sql_msd_loc = SQLLocation.objects.get(domain=self.domain,
                                                      site_code=msd_code)
                msd_location = Loc.get(sql_msd_loc.location_id)
            except SQLLocation.DoesNotExist:
                msd_location = Loc(parent=loc_parent)

            msd_location.domain = self.domain
            msd_location.name = msd_name
            msd_location.location_type = 'MSDZONE'
            msd_location.site_code = MSDZONE_MAP[msd_name][0]
            msd_location.save()
            return msd_location

        try:
            sql_loc = SQLLocation.objects.get(domain=self.domain,
                                              external_id=int(
                                                  ilsgateway_location.id))
            location = Loc.get(sql_loc.location_id)
        except SQLLocation.DoesNotExist:
            location = None
        except SQLLocation.MultipleObjectsReturned:
            return

        if not location:
            if ilsgateway_location.id in EXCLUDED_REGIONS:
                return

            if ilsgateway_location.parent_id:
                try:
                    sql_loc_parent = SQLLocation.objects.get(
                        domain=self.domain,
                        external_id=ilsgateway_location.parent_id)
                    loc_parent = sql_loc_parent.couch_location
                except SQLLocation.DoesNotExist:
                    parent = self.endpoint.get_location(
                        ilsgateway_location.parent_id)
                    loc_parent = self.location_sync(Location(parent))
                    if not loc_parent:
                        return

                if ilsgateway_location.type == 'REGION':
                    location = Loc(
                        parent=get_or_create_msd_zone(ilsgateway_location))
                else:
                    location = Loc(parent=loc_parent)
            else:
                location = Loc()
                location.lineage = []
            location.domain = self.domain
            location.name = ilsgateway_location.name
            if ilsgateway_location.groups:
                location.metadata = {'group': ilsgateway_location.groups[0]}
            if ilsgateway_location.latitude:
                location.latitude = float(ilsgateway_location.latitude)
            if ilsgateway_location.longitude:
                location.longitude = float(ilsgateway_location.longitude)
            location.location_type = ilsgateway_location.type
            location.site_code = ilsgateway_location.code
            location.external_id = unicode(ilsgateway_location.id)
            location.save()

            if ilsgateway_location.type == 'FACILITY' and not SupplyPointCase.get_by_location(
                    location):
                SupplyPointCase.create_from_location(self.domain, location)
                location.save()
        else:
            location_dict = {
                'name':
                ilsgateway_location.name,
                'latitude':
                float(ilsgateway_location.latitude)
                if ilsgateway_location.latitude else None,
                'longitude':
                float(ilsgateway_location.longitude)
                if ilsgateway_location.longitude else None,
                'location_type':
                ilsgateway_location.type,
                'site_code':
                ilsgateway_location.code.lower(),
                'external_id':
                str(ilsgateway_location.id),
                'metadata': {}
            }
            if ilsgateway_location.groups:
                location_dict['metadata'][
                    'group'] = ilsgateway_location.groups[0]
            case = SupplyPointCase.get_by_location(location)
            if apply_updates(location, location_dict):
                location.save()
                if case:
                    case.update_from_location(location)
                else:
                    SupplyPointCase.create_from_location(self.domain, location)
Esempio n. 41
0
def set_commtrack_location(user, location):
    user.commtrack_location = location._id
    supply_point_case = SupplyPointCase.get_by_location(location)
    reconcile_ownership(supply_point_case, user)
    user.save()
 def handle(self, *args, **options):
     for location_type in ["wholesaler", "retailer"]:
         for location in Location.filter_by_type("colalifezambia", location_type):
             supply_point_case = SupplyPointCase.get_by_location(location)
             supply_point_case.location_type = location_type
             supply_point_case.save()
Esempio n. 43
0
 def linked_supply_point(self):
     from corehq.apps.commtrack.models import SupplyPointCase
     return SupplyPointCase.get_by_location(self)
Esempio n. 44
0
    def submit_form(self, parent, form_data, existing, location_type, consumption):
        location = existing or Location(domain=self.domain, parent=parent)
        form = LocationForm(location, form_data)
        form.strict = False  # optimization hack to turn off strict validation
        if form.is_valid():
            # don't save if there is nothing to save
            if self.no_changes_needed(existing, form_data, consumption):
                return {
                    'id': existing._id,
                    'message': 'no changes for %s %s' % (location_type, existing.name)
                }

            loc = form.save()

            sp = SupplyPointCase.get_by_location(loc) if consumption else None

            if consumption and sp:
                for product_code, value in consumption:
                    product = self.get_product(product_code)

                    if not product:
                        # skip any consumption column that doesn't match
                        # to a real product. currently there is no easy
                        # way to alert here, though.
                        continue

                    try:
                        amount = Decimal(value)

                        # only set it if there is a non-negative/non-null value
                        if amount and amount >= 0:
                            set_default_consumption_for_supply_point(
                                self.domain,
                                product._id,
                                sp._id,
                                amount
                            )
                    except (TypeError, InvalidOperation):
                        # should inform user, but failing hard due to non numbers
                        # being used on consumption is strange since the
                        # locations would be in a very inconsistent state
                        continue

            if existing:
                message = 'updated %s %s' % (location_type, loc.name)
            else:
                message = 'created %s %s' % (location_type, loc.name)

            return {
                'id': loc._id,
                'message': message
            }
        else:
            message = 'Form errors when submitting: '
            for k, v in form.errors.iteritems():
                if k != '__all__':
                    message += u'{0} {1}; {2}: {3}. '.format(
                        location_type, form_data.get('name', 'unknown'), k, v[0]
                    )

            return {
                'id': None,
                'message': message
            }
Esempio n. 45
0
    def location_sync(self, ilsgateway_location):
        def get_or_create_msd_zone(region):
            msd_name = _get_msd_name(region.name)
            msd_code = MSDZONE_MAP[msd_name][0]
            try:
                sql_msd_loc = SQLLocation.objects.get(domain=self.domain, site_code=msd_code)
                msd_location = Loc.get(sql_msd_loc.location_id)
            except SQLLocation.DoesNotExist:
                msd_location = Loc(parent=loc_parent)

            msd_location.domain = self.domain
            msd_location.name = msd_name
            msd_location.location_type = "MSDZONE"
            msd_location.site_code = MSDZONE_MAP[msd_name][0]
            msd_location.save()
            return msd_location

        try:
            sql_loc = SQLLocation.objects.get(domain=self.domain, external_id=int(ilsgateway_location.id))
            location = Loc.get(sql_loc.location_id)
        except SQLLocation.DoesNotExist:
            location = None
        except SQLLocation.MultipleObjectsReturned:
            return

        if not location:
            if ilsgateway_location.id in EXCLUDED_REGIONS:
                return

            if ilsgateway_location.parent_id:
                try:
                    sql_loc_parent = SQLLocation.objects.get(
                        domain=self.domain, external_id=ilsgateway_location.parent_id
                    )
                    loc_parent = sql_loc_parent.couch_location
                except SQLLocation.DoesNotExist:
                    parent = self.endpoint.get_location(ilsgateway_location.parent_id)
                    loc_parent = self.location_sync(Location(parent))
                    if not loc_parent:
                        return

                if ilsgateway_location.type == "REGION":
                    location = Loc(parent=get_or_create_msd_zone(ilsgateway_location))
                else:
                    location = Loc(parent=loc_parent)
            else:
                location = Loc()
                location.lineage = []
            location.domain = self.domain
            location.name = ilsgateway_location.name
            if ilsgateway_location.groups:
                location.metadata = {"group": ilsgateway_location.groups[0]}
            if ilsgateway_location.latitude:
                location.latitude = float(ilsgateway_location.latitude)
            if ilsgateway_location.longitude:
                location.longitude = float(ilsgateway_location.longitude)
            location.location_type = ilsgateway_location.type
            location.site_code = ilsgateway_location.code
            location.external_id = unicode(ilsgateway_location.id)
            location.save()

            if ilsgateway_location.type == "FACILITY" and not SupplyPointCase.get_by_location(location):
                SupplyPointCase.create_from_location(self.domain, location)
                location.save()
        else:
            location_dict = {
                "name": ilsgateway_location.name,
                "latitude": float(ilsgateway_location.latitude) if ilsgateway_location.latitude else None,
                "longitude": float(ilsgateway_location.longitude) if ilsgateway_location.longitude else None,
                "location_type": ilsgateway_location.type,
                "site_code": ilsgateway_location.code.lower(),
                "external_id": str(ilsgateway_location.id),
                "metadata": {},
            }
            if ilsgateway_location.groups:
                location_dict["metadata"]["group"] = ilsgateway_location.groups[0]
            case = SupplyPointCase.get_by_location(location)
            if apply_updates(location, location_dict):
                location.save()
                if case:
                    case.update_from_location(location)
                else:
                    SupplyPointCase.create_from_location(self.domain, location)
        return location
Esempio n. 46
0
 def supply_point(self):
     return SupplyPointCase.get_by_location(self.location)
Esempio n. 47
0
 def supply_point(self):
     try:
         return SupplyPointCase.get_by_location(self.location)
     except MultipleResultsFound:
         raise MultipleSupplyPointException
Esempio n. 48
0
    def location_sync(self, ilsgateway_location):
        def get_or_create_msd_zone(region):
            msd_name = _get_msd_name(region.name)
            msd_code = MSDZONE_MAP[msd_name][0]
            try:
                sql_msd_loc = SQLLocation.objects.get(
                    domain=self.domain,
                    site_code=msd_code
                )
                msd_location = Loc.get(sql_msd_loc.location_id)
            except SQLLocation.DoesNotExist:
                msd_location = Loc(parent=loc_parent)

            msd_location.domain = self.domain
            msd_location.name = msd_name
            msd_location.location_type = 'MSDZONE'
            msd_location.site_code = MSDZONE_MAP[msd_name][0]
            msd_location.save()
            return msd_location

        try:
            sql_loc = SQLLocation.objects.get(
                domain=self.domain,
                external_id=int(ilsgateway_location.id)
            )
            location = Loc.get(sql_loc.location_id)
        except SQLLocation.DoesNotExist:
            location = None
        except SQLLocation.MultipleObjectsReturned:
            return

        if not location:
            if ilsgateway_location.parent_id:
                try:
                    sql_loc_parent = SQLLocation.objects.get(
                        domain=self.domain,
                        external_id=ilsgateway_location.parent_id
                    )
                    loc_parent = sql_loc_parent.couch_location
                except SQLLocation.DoesNotExist:
                    parent = self.endpoint.get_location(ilsgateway_location.parent_id)
                    loc_parent = self.location_sync(Location(parent))

                if ilsgateway_location.type == 'REGION':
                    location = Loc(parent=get_or_create_msd_zone(ilsgateway_location))
                else:
                    location = Loc(parent=loc_parent)
            else:
                location = Loc()
                location.lineage = []
            location.domain = self.domain
            location.name = ilsgateway_location.name
            if ilsgateway_location.groups:
                location.metadata = {'group': ilsgateway_location.groups[0]}
            if ilsgateway_location.latitude:
                location.latitude = float(ilsgateway_location.latitude)
            if ilsgateway_location.longitude:
                location.longitude = float(ilsgateway_location.longitude)
            location.location_type = ilsgateway_location.type
            location.site_code = ilsgateway_location.code
            location.external_id = unicode(ilsgateway_location.id)
            location.save()

            if ilsgateway_location.type == 'FACILITY' and not SupplyPointCase.get_by_location(location):
                SupplyPointCase.create_from_location(self.domain, location)
                location.save()
        else:
            location_dict = {
                'name': ilsgateway_location.name,
                'latitude': float(ilsgateway_location.latitude) if ilsgateway_location.latitude else None,
                'longitude': float(ilsgateway_location.longitude) if ilsgateway_location.longitude else None,
                'location_type': ilsgateway_location.type,
                'site_code': ilsgateway_location.code.lower(),
                'external_id': str(ilsgateway_location.id),
                'metadata': {}
            }
            if ilsgateway_location.groups:
                location_dict['metadata']['group'] = ilsgateway_location.groups[0]
            case = SupplyPointCase.get_by_location(location)
            if apply_updates(location, location_dict):
                location.save()
                if case:
                    case.update_from_location(location)
                else:
                    SupplyPointCase.create_from_location(self.domain, location)
        return location
Esempio n. 49
0
 def supply_point(self):
     return SupplyPointCase.get_by_location(self.location)