示例#1
0
    def handle(self, *args, **options):
        ids = get_form_ids_by_type('ipm-senegal', 'XFormInstance')

        to_save = []
        for doc in iter_docs(XFormInstance.get_db(), ids):
            try:
                if 'location_id' in doc[
                        'form'] and not doc['form']['location_id']:
                    case = SupplyPointCase.get(doc['form']['case']['@case_id'])
                    if case.type == 'supply-point':
                        instance = XFormInstance.get(doc['_id'])

                        # fix the XFormInstance
                        instance.form['location_id'] = case.location_id

                        # fix the actual form.xml
                        xml_object = etree.fromstring(instance.get_xml())
                        location_id_node = xml_object.find(
                            re.sub('}.*', '}location_id', xml_object.tag))
                        location_id_node.text = case.location_id
                        updated_xml = etree.tostring(xml_object)

                        attachment_builder = CouchAttachmentsBuilder(
                            instance._attachments)
                        attachment_builder.add(
                            name='form.xml',
                            content=updated_xml,
                            content_type=instance._attachments['form.xml']
                            ['content_type'])
                        instance._attachments = attachment_builder.to_json()

                        print 'Updating XFormInstance:', doc['_id']
                        to_save.append(instance)
示例#2
0
 def _set_up_supply_point(self, location, ews_location):
     if location.location_type in ['country', 'region', 'district']:
         supply_point_with_stock_data = filter(
             lambda x: x.last_reported and x.active, ews_location.supply_points
         )
         for supply_point in supply_point_with_stock_data:
             created_location = self._create_location_from_supply_point(supply_point, location)
             fake_location = Loc(
                 _id=created_location._id,
                 name=supply_point.name,
                 external_id=str(supply_point.id),
                 domain=self.domain
             )
             SupplyPointCase.get_or_create_by_location(fake_location)
             created_location.save()
     elif ews_location.supply_points:
         active_supply_points = filter(lambda sp: sp.active, ews_location.supply_points)
         if active_supply_points:
             supply_point = active_supply_points[0]
         else:
             supply_point = ews_location.supply_points[0]
         location.name = supply_point.name
         location.site_code = supply_point.code
         location.location_type = supply_point.type
         self._create_supply_point_from_location(supply_point, location)
         location.save()
     else:
         SupplyPointCase.get_or_create_by_location(location)
         location.save()
         location.archive()
示例#3
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 setUp(self):
        self.endpoint = MockEndpoint("http://test-api.com/", "dummy", "dummy")
        self.stock_api_object = MockILSStockDataSynchronization(TEST_DOMAIN, self.endpoint)
        self.datapath = os.path.join(os.path.dirname(__file__), "data")
        initial_bootstrap(TEST_DOMAIN)
        self.api_object = ILSGatewayAPI(TEST_DOMAIN, self.endpoint)
        self.api_object.prepare_commtrack_config()
        config = ILSGatewayConfig()
        config.domain = TEST_DOMAIN
        config.enabled = True
        config.all_stock_data = True
        config.password = "******"
        config.username = "******"
        config.url = "http://test-api.com/"
        config.save()
        l1 = Location(name="Test location 1", external_id="3445", location_type="FACILITY", domain=TEST_DOMAIN)

        l2 = Location(name="Test location 2", external_id="4407", location_type="FACILITY", domain=TEST_DOMAIN)

        l1.save()
        l2.save()

        SupplyPointCase.create_from_location(TEST_DOMAIN, l1)
        SupplyPointCase.create_from_location(TEST_DOMAIN, l2)

        with open(os.path.join(self.datapath, "sample_products.json")) as f:
            for product_json in json.loads(f.read()):
                self.api_object.product_sync(Product(product_json))

        StockTransaction.objects.all().delete()
示例#5
0
    def _create_data(self, domain_name, i):
        product = Product(domain=domain_name, name='test-{}'.format(i))
        product.save()

        location = Location(
            domain=domain_name,
            site_code='testcode-{}'.format(i),
            name='test-{}'.format(i),
            location_type='facility'
        )
        location.save()
        SupplyPointCase.create_from_location(domain_name, location)
        report = StockReport.objects.create(
            type='balance',
            domain=domain_name,
            form_id='fake',
            date=datetime.utcnow()
        )

        StockTransaction.objects.create(
            report=report,
            product_id=product.get_id,
            sql_product=SQLProduct.objects.get(product_id=product.get_id),
            section_id='stock',
            type='stockonhand',
            case_id=location.linked_supply_point().get_id,
            stock_on_hand=100
        )
示例#6
0
def delete_all_locations():
    ids = [
        doc['id'] for doc in
        SupplyPointCase.get_db().view('supply_point_by_loc/view', reduce=False).all()
    ]
    iter_bulk_delete(SupplyPointCase.get_db(), ids)
    delete_all_docs_by_doc_type(Location.get_db(), ['Location'])
    SQLLocation.objects.all().delete()
示例#7
0
def delete_all_locations():
    ids = [
        doc['id'] for doc in
        SupplyPointCase.get_db().view('supply_point_by_loc/view', reduce=False).all()
    ]
    iter_bulk_delete(SupplyPointCase.get_db(), ids)
    SQLLocation.objects.all().delete()
    LocationType.objects.all().delete()
 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()
示例#9
0
def delete_all_locations():
    ids = [
        doc['id'] for doc in
        SupplyPointCase.get_db().view('commtrack/supply_point_by_loc', reduce=False).all()
    ]
    iter_bulk_delete(SupplyPointCase.get_db(), ids)

    iter_bulk_delete(Location.get_db(), SQLLocation.objects.location_ids())

    SQLLocation.objects.all().delete()
 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()
示例#11
0
def make_loc(code, name, domain, type, metadata=None, parent=None):
    name = name or code
    location_type, _ = LocationType.objects.get_or_create(domain=domain, name=type)
    loc = Location(site_code=code, name=name, domain=domain, location_type=type, parent=parent)
    loc.metadata = metadata or {}
    loc.save()
    if not location_type.administrative:
        SupplyPointCase.create_from_location(domain, loc)
        loc.save()
    return loc
示例#12
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))
示例#13
0
    def handle(self, *args, **options):
        ids = get_form_ids_by_type('ipm-senegal', 'XFormInstance')

        to_save = []

        locations = SQLLocation.objects.filter(
            domain='ipm-senegal').values_list('location_id', 'name')
        locations_map = {
            location_id: name
            for (location_id, name) in locations
        }

        for doc in iter_docs(XFormInstance.get_db(), ids):
            try:
                if 'PPS_name' in doc['form'] and not doc['form']['PPS_name']:
                    case = SupplyPointCase.get(doc['form']['case']['@case_id'])
                    if case.type == 'supply-point':
                        print 'Updating XFormInstance:', doc['_id']

                        pps_name = locations_map[case.location_id]

                        instance = XFormInstance.get(doc['_id'])

                        # fix the XFormInstance
                        instance.form['PPS_name'] = pps_name
                        for instance_prod in instance.form['products']:
                            instance_prod['PPS_name'] = instance_prod[
                                'PPS_name'] or pps_name

                        # fix the actual form.xml
                        xml_object = etree.fromstring(instance.get_xml())
                        pps_name_node = xml_object.find(
                            re.sub('}.*', '}PPS_name', xml_object.tag))
                        pps_name_node.text = pps_name

                        products_nodes = xml_object.findall(
                            re.sub('}.*', '}products', xml_object.tag))
                        for product_node in products_nodes:
                            product_pps_name_node = product_node.find(
                                re.sub('}.*', '}PPS_name', xml_object.tag))
                            product_pps_name_node.text = pps_name
                        updated_xml = etree.tostring(xml_object)

                        attachment_builder = CouchAttachmentsBuilder(
                            instance._attachments)
                        attachment_builder.add(
                            name='form.xml',
                            content=updated_xml,
                            content_type=instance._attachments['form.xml']
                            ['content_type'])
                        instance._attachments = attachment_builder.to_json()

                        to_save.append(instance)
示例#14
0
    def test_archive_flips_sp_cases(self):
        loc = make_loc('someloc')
        sp = make_supply_point(self.domain.name, loc)

        self.assertFalse(sp.closed)
        loc.archive()
        sp = SupplyPointCase.get(sp._id)
        self.assertTrue(sp.closed)

        loc.unarchive()
        sp = SupplyPointCase.get(sp._id)
        self.assertFalse(sp.closed)
示例#15
0
    def test_archive_flips_sp_cases(self):
        loc = make_loc('someloc')
        sp = make_supply_point(self.domain.name, loc)

        self.assertFalse(sp.closed)
        loc.archive()
        sp = SupplyPointCase.get(sp._id)
        self.assertTrue(sp.closed)

        loc.unarchive()
        sp = SupplyPointCase.get(sp._id)
        self.assertFalse(sp.closed)
示例#16
0
    def test_archive_flips_sp_cases(self):
        loc = make_loc('someloc')
        sp = loc.linked_supply_point()

        self.assertFalse(sp.closed)
        loc.archive()
        sp = SupplyPointCase.get(sp.case_id)
        self.assertTrue(sp.closed)

        loc.unarchive()
        sp = SupplyPointCase.get(sp.case_id)
        self.assertFalse(sp.closed)
示例#17
0
文件: api.py 项目: ekush/commcare-hq
 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))
示例#18
0
def locations_fix(domain):
    locations = SQLLocation.objects.filter(domain=domain, location_type__in=['country', 'region', 'district'])
    for loc in locations:
        sp = Location.get(loc.location_id).linked_supply_point()
        if sp:
            sp.external_id = None
            sp.save()
        else:
            fake_location = Location(
                _id=loc.location_id,
                name=loc.name,
                domain=domain
            )
            SupplyPointCase.get_or_create_by_location(fake_location)
示例#19
0
def make_loc(code, name, domain, type, parent=None):
    name = name or code
    sql_type, _ = LocationType.objects.get_or_create(domain=domain, name=type)
    loc = Location(site_code=code, name=name, domain=domain, location_type=type, parent=parent)
    loc.save()

    if not sql_type.administrative:
        SupplyPointCase.create_from_location(domain, loc)
        loc.save()

    sql_location = loc.sql_location
    sql_location.products = []
    sql_location.save()
    return loc
示例#20
0
def locations_fix(domain):
    locations = SQLLocation.objects.filter(domain=domain, location_type__in=['country', 'region', 'district'])
    for loc in locations:
        sp = Location.get(loc.location_id).linked_supply_point()
        if sp:
            sp.external_id = None
            sp.save()
        else:
            fake_location = Location(
                _id=loc.location_id,
                name=loc.name,
                domain=domain
            )
            SupplyPointCase.get_or_create_by_location(fake_location)
示例#21
0
 def get_location_id(self, facility):
     sp = SupplyPointCase.view('hqcase/by_domain_external_id',
                               key=[self.domain, str(facility)],
                               reduce=False,
                               include_docs=True,
                               limit=1).first()
     return sp.location_id
示例#22
0
def get_supply_point(domain, facility_or_code):
    facility_code = facility_or_code if isinstance(facility_or_code, basestring) else facility_or_code.code
    return SupplyPointCase.view('hqcase/by_domain_external_id',
        key=[domain, facility_code],
        reduce=False,
        include_docs=True,
    ).one()
示例#23
0
    def get_data(self):
        sp_ids = get_relevant_supply_point_ids(
            self.domain,
            self.active_location
        )

        products = Product.by_domain(self.domain)
        if self.program_id:
            products = filter(
                lambda product: product.program_id == self.program_id, products
            )

        for sp_id in sp_ids:
            for product in products:
                loc = SupplyPointCase.get(sp_id).location
                last_transaction = StockTransaction.latest(
                    sp_id,
                    STOCK_SECTION_TYPE,
                    product._id
                )

                yield {
                    'loc_id': loc._id,
                    'loc_path': loc.path,
                    'name': loc.name,
                    'type': loc.location_type,
                    'reporting_status': reporting_status(
                        last_transaction,
                        self.start_date,
                        self.end_date
                    ),
                    'geo': loc._geopoint,
                }
示例#24
0
def sync_ilsgateway_webuser(domain, ilsgateway_webuser):
    user = WebUser.get_by_username(ilsgateway_webuser.email.lower())
    user_dict = {
        'first_name': ilsgateway_webuser.first_name,
        'last_name': ilsgateway_webuser.last_name,
        'is_staff': ilsgateway_webuser.is_staff,
        'is_active': ilsgateway_webuser.is_active,
        'is_superuser': ilsgateway_webuser.is_superuser,
        'last_login': force_to_datetime(ilsgateway_webuser.last_login),
        'date_joined': force_to_datetime(ilsgateway_webuser.date_joined),
        'password_hashed': True,
    }
    sp = SupplyPointCase.view('hqcase/by_domain_external_id',
                              key=[domain, str(ilsgateway_webuser.location)],
                              reduce=False,
                              include_docs=True,
                              limit=1).first()
    role_id = ilsgateway_webuser.role_id if hasattr(ilsgateway_webuser, 'role_id') else None
    location_id = sp.location_id if sp else None

    if user is None:
        try:
            user = WebUser.create(domain=None, username=ilsgateway_webuser.email.lower(),
                                  password=ilsgateway_webuser.password, email=ilsgateway_webuser.email, **user_dict)
            user.add_domain_membership(domain, role_id=role_id, location_id=location_id)
            user.save()
        except Exception as e:
            logging.error(e)
    else:
        if domain not in user.get_domains():
            user.add_domain_membership(domain, role_id=role_id, location_id=location_id)
            user.save()

    return user
示例#25
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)
                        })
示例#26
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()
示例#27
0
def get_default_column_data(domain, location_types):
    data = {
        'headers': {},
        'values': {}
    }

    if Domain.get_by_name(domain).commtrack_settings.individual_consumption_defaults:
        products = Product.by_domain(domain)

        for loc_type in location_types:
            loc = get_loc_config(domain)[loc_type]
            if not loc.administrative:
                data['headers'][loc_type] = [
                    'default_' +
                    p.code for p in products
                ]

                locations = Location.filter_by_type(domain, loc_type)
                for loc in locations:
                    sp = SupplyPointCase.get_or_create_by_location(loc)

                    data['values'][loc._id] = [
                        get_default_consumption(
                            domain,
                            p._id,
                            loc_type,
                            sp._id
                        ) or '' for p in products
                    ]
            else:
                data['headers'][loc_type] = []
    return data
示例#28
0
    def leaf_node_data(self, stock_states):
        for state in stock_states:
            product = Product.get(state.product_id)

            result = {
                'product_id': product._id,
                'product_name': product.name,
                'current_stock': format_decimal(state.stock_on_hand),
            }

            if self._include_advanced_data():
                result.update({
                    'location_id':
                    SupplyPointCase.get(state.case_id).location_id,
                    'location_lineage':
                    None,
                    'category':
                    state.stock_category,
                    'consumption':
                    state.get_monthly_consumption(),
                    'months_remaining':
                    state.months_remaining,
                    'resupply_quantity_needed':
                    state.resupply_quantity_needed
                })

            yield result
示例#29
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())
示例#30
0
def get_supply_point_by_external_id(domain, external_id):
    return SupplyPointCase.view('hqcase/by_domain_external_id',
        key=[domain, str(external_id)],
        reduce=False,
        include_docs=True,
        limit=1
    ).first()
示例#31
0
def get_default_column_data(domain, location_types):
    data = {
        'headers': {},
        'values': {}
    }

    if Domain.get_by_name(domain).commtrack_settings.individual_consumption_defaults:
        products = Product.by_domain(domain)

        for loc_type in location_types:
            loc = get_loc_config(domain)[loc_type]
            if not loc.administrative:
                data['headers'][loc_type] = [
                    'default_' +
                    p.code for p in products
                ]

                locations = Location.filter_by_type(domain, loc_type)
                for loc in locations:
                    sp = SupplyPointCase.get_or_create_by_location(loc)

                    data['values'][loc._id] = [
                        get_default_monthly_consumption(
                            domain,
                            p._id,
                            loc_type,
                            sp._id
                        ) or '' for p in products
                    ]
            else:
                data['headers'][loc_type] = []
    return data
示例#32
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())
def iter_location_join_supply_point(all_location_ids, chunksize=100):

    # this function was copy-paste-modified from iter_docs

    database = Location.get_db()
    for location_ids in chunked(all_location_ids, chunksize):
        # sync supply point id
        locations = [row.get('doc')
                     for row in get_docs(database, keys=location_ids)
                     if row.get('doc')
                     and row.get('doc')['domain'] not in EXCLUDE_DOMAINS]

        supply_points = SupplyPointCase.view(
            'commtrack/supply_point_by_loc',
            keys=[[location['domain'], location['_id']]
                  for location in locations],
            include_docs=True,
            classes={'CommCareCase': SupplyPointCase},
        ).all()

        supply_points_index = {}

        for supply_point in supply_points:
            key = (supply_point.domain, supply_point.location_id)
            if key in supply_points_index:
                raise Exception(
                    "Multiple supply points have "
                    "domain={!r}, location_id={!r}".format(*key))
            supply_points_index[key] = supply_point

        for location in locations:
            yield (
                location,
                supply_points_index.get((location['domain'], location['_id']))
            )
示例#34
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)
                        }
                    )
示例#35
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])
示例#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 = 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())
示例#37
0
    def sms_user_sync(self, ews_smsuser, **kwargs):
        sms_user = super(EWSApi, self).sms_user_sync(ews_smsuser, **kwargs)
        if not sms_user:
            return None
        sms_user.user_data['to'] = ews_smsuser.to
        sms_user.save()
        if ews_smsuser.supply_point:
            if ews_smsuser.supply_point.id:
                sp = SupplyPointCase.view('hqcase/by_domain_external_id',
                                          key=[self.domain, str(ews_smsuser.supply_point.id)],
                                          reduce=False,
                                          include_docs=True,
                                          limit=1).first()
            else:
                sp = None

            if sp:
                couch_location = sp.location
            elif ews_smsuser.supply_point.location_id:
                try:
                    location = SQLLocation.objects.get(domain=self.domain,
                                                       external_id=ews_smsuser.supply_point.location_id)
                    couch_location = location.couch_location
                except SQLLocation.DoesNotExist:
                    couch_location = None
            else:
                couch_location = None
            if couch_location:
                sms_user.set_location(couch_location)
        return sms_user
    def test_create_facility_location(self):
        with open(os.path.join(self.datapath, 'sample_locations.json')) as f:
            location = Location(json.loads(f.read())[1])

        with open(os.path.join(self.datapath, 'sample_products.json')) as f:
            for p in json.loads(f.read()):
                self.api_object.product_sync(Product(p))
        self.assertEqual(8, SQLProduct.objects.filter(domain=TEST_DOMAIN).count())
        ewsghana_location = self.api_object.location_sync(location)
        self.assertEqual(ewsghana_location.name, location.supply_points[0].name)
        self.assertEqual(ewsghana_location.site_code, location.supply_points[0].code)
        self.assertEqual("Hospital", ewsghana_location.location_type)
        self.assertEqual(ewsghana_location.longitude, float(location.longitude))
        self.assertEqual(ewsghana_location.latitude, float(location.latitude))
        self.assertFalse(ewsghana_location.is_archived)

        sql_location = ewsghana_location.sql_location
        self.assertEqual(ewsghana_location.get_id, sql_location.location_id)
        self.assertEqual(int(sql_location.parent.external_id), location.parent_id)
        self.assertIsNotNone(sql_location.id)
        self.assertIsNotNone(sql_location.supply_point_id)
        supply_point = SupplyPointCase.get_by_location_id(TEST_DOMAIN, sql_location.location_id)
        self.assertIsNotNone(supply_point)
        self.assertEqual(supply_point.location, ewsghana_location)
        self.assertEqual(location.supply_points[0].id, int(supply_point.external_id))
        self.assertEqual(location.supply_points[0].name, supply_point.name)
        self.assertSetEqual(set(location.supply_points[0].products),
                            {product.code for product in ewsghana_location.sql_location.products})
示例#39
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
        }
示例#40
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
        }
示例#41
0
 def get_closed_and_open_by_location_id_and_domain(domain, location_id):
     return SupplyPointCase.view(
         'supply_point_by_loc/view',
         key=[domain, location_id],
         include_docs=True,
         classes={'CommCareCase': SupplyPointCase},
         limit=1,
     ).one()
示例#42
0
def supply_point_ids(locations):
    keys = [[loc.domain, loc._id] for loc in locations]
    rows = SupplyPointCase.get_db().view(
        'commtrack/supply_point_by_loc',
        keys=keys,
        include_docs=False,
    )
    return [row['id'] for row in rows]
示例#43
0
    def test_delete_closes_sp_cases(self):
        loc = make_loc('test_loc')
        sp = loc.linked_supply_point()

        self.assertFalse(sp.closed)
        loc.full_delete()
        sp = SupplyPointCase.get(sp.case_id)
        self.assertTrue(sp.closed)
示例#44
0
 def linked_supply_point(self):
     from corehq.apps.commtrack.models import SupplyPointCase
     if not self.supply_point_id:
         return None
     try:
         return SupplyPointCase.get(self.supply_point_id)
     except:
         return None
示例#45
0
def supply_point_ids(locations):
    keys = [[loc.domain, loc._id] for loc in locations]
    rows = SupplyPointCase.get_db().view(
        'commtrack/supply_point_by_loc',
        keys=keys,
        include_docs=False,
    )
    return [row['id'] for row in rows]
示例#46
0
def get_supply_point(domain, facility_or_code):
    facility_code = facility_or_code if isinstance(facility_or_code, basestring) else facility_or_code.code
    return SupplyPointCase.view('hqcase/by_domain_external_id',
        key=[domain, facility_code],
        reduce=False,
        include_docs=True,
        limit=1
    ).first()
示例#47
0
def get_supply_point_case_by_location_id(domain, location_id):
    from corehq.apps.commtrack.models import SupplyPointCase
    return SupplyPointCase.view(
        'commtrack/supply_point_by_loc',
        key=[domain, location_id],
        include_docs=True,
        classes={'CommCareCase': SupplyPointCase},
    ).one()
示例#48
0
def get_default_column_data(domain, location_types):
    data = {
        'headers': {},
        'values': {}
    }

    if Domain.get_by_name(domain).commtrack_settings.individual_consumption_defaults:
        products = Product.by_domain(domain)

        supply_point_map = SupplyPointCase.get_location_map_by_domain(domain)

        consumption_dict = build_consumption_dict(domain)

        if not consumption_dict:
            return data

        for loc_type in location_types:
            loc = get_loc_config(domain)[loc_type]
            if not loc.administrative:
                data['headers'][loc_type] = [
                    'default_' +
                    p.code for p in products
                ]

                locations = Location.filter_by_type(domain, loc_type)
                for loc in locations:
                    if loc._id in supply_point_map:
                        sp_id = supply_point_map[loc._id]
                    else:
                        # this only happens if the supply point case did
                        # not already exist
                        sp_id = SupplyPointCase.get_or_create_by_location(loc)._id

                    data['values'][loc._id] = [
                        get_loaded_default_monthly_consumption(
                            consumption_dict,
                            domain,
                            p._id,
                            loc_type,
                            sp_id
                        ) or '' for p in products
                    ]
            else:
                data['headers'][loc_type] = []
    return data
示例#49
0
    def get_data(self):
        # todo: this will probably have to paginate eventually
        if self.all_relevant_forms:
            sp_ids = get_relevant_supply_point_ids(
                self.domain,
                self.active_location,
            )

            supply_points = (
                SupplyPointCase.wrap(doc)
                for doc in iter_docs(SupplyPointCase.get_db(), sp_ids))
            form_xmlnses = [
                form['xmlns'] for form in self.all_relevant_forms.values()
            ]

            for supply_point in supply_points:
                # todo: get locations in bulk
                loc = supply_point.location
                transactions = StockTransaction.objects.filter(
                    case_id=supply_point._id,
                ).exclude(report__date__lte=self.start_date).exclude(
                    report__date__gte=self.end_date).order_by('-report__date')
                matched = False
                for trans in transactions:
                    if XFormInstance.get(
                            trans.report.form_id).xmlns in form_xmlnses:
                        yield {
                            'loc_id': loc._id,
                            'loc_path': loc.path,
                            'name': loc.name,
                            'type': loc.location_type,
                            'reporting_status': 'reporting',
                            'geo': loc._geopoint,
                        }
                        matched = True
                        break
                if not matched:
                    yield {
                        'loc_id': loc._id,
                        'loc_path': loc.path,
                        'name': loc.name,
                        'type': loc.location_type,
                        'reporting_status': 'nonreporting',
                        'geo': loc._geopoint,
                    }
示例#50
0
def get_supply_point_case_in_domain_by_id(domain, supply_point_integer_id):
    from corehq.apps.commtrack.models import SupplyPointCase
    return SupplyPointCase.view(
        'cases_by_domain_external_id/view',
        key=[domain, str(supply_point_integer_id)],
        reduce=False,
        include_docs=True,
        limit=1,
    ).first()
示例#51
0
def get_supply_point_case_by_location_id(domain, location_id):
    from corehq.apps.commtrack.models import SupplyPointCase
    return SupplyPointCase.view(
        'commtrack/supply_point_by_loc',
        key=[domain, location_id],
        include_docs=True,
        classes={
            'CommCareCase': SupplyPointCase
        },
    ).one()
示例#52
0
 def get_ids(self):
     supply_points_ids = SQLLocation.objects.filter(
         domain=self.domain,
         location_type__administrative=False
     ).order_by('created_at').values_list('supply_point_id', flat=True)
     return [
         doc['external_id']
         for doc in iter_docs(SupplyPointCase.get_db(), supply_points_ids)
         if doc['external_id']
     ]
示例#53
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)
    def test_change_to_administrative_and_back(self):
        # at first it should have a supply point
        self.assertHasSupplyPoint(self.boston)
        supply_point_id = self.boston.supply_point_id

        self.city_type.administrative = True
        self.city_type.save()

        # Now that it's administrative, it shouldn't have one
        # The case should still exist, but be closed
        self.assertHasNoSupplyPoint(self.boston)
        self.assertTrue(SupplyPointCase.get(supply_point_id).closed)

        self.city_type.administrative = False
        self.city_type.save()

        # The same supply point case should be reopened
        self.assertHasSupplyPoint(self.boston)
        self.assertEqual(self.boston.supply_point_id, supply_point_id)
        self.assertFalse(SupplyPointCase.get(supply_point_id).closed)
示例#55
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
示例#56
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)
示例#57
0
def get_supply_points_json_in_domain_by_location(domain):
    from corehq.apps.commtrack.models import SupplyPointCase
    results = SupplyPointCase.get_db().view(
        'commtrack/supply_point_by_loc',
        startkey=[domain],
        endkey=[domain, {}],
        include_docs=True,
    )

    for result in results:
        location_id = result['key'][-1]
        case = result['doc']
        yield location_id, case
示例#58
0
    def setUp(self):
        self.endpoint = MockEndpoint('http://test-api.com/', 'dummy', 'dummy')
        self.stock_api_object = MockEWSStockDataSynchronization(
            TEST_DOMAIN, self.endpoint)
        self.datapath = os.path.join(os.path.dirname(__file__), 'data')
        initial_bootstrap(TEST_DOMAIN)
        self.api_object = EWSApi(TEST_DOMAIN, self.endpoint)
        self.api_object.prepare_commtrack_config()
        config = EWSGhanaConfig()
        config.domain = TEST_DOMAIN
        config.enabled = True
        config.all_stock_data = True
        config.password = '******'
        config.username = '******'
        config.url = 'http://test-api.com/'
        config.save()
        l1 = Location(name='Test location 1',
                      external_id='3445',
                      location_type='Hospital',
                      domain=TEST_DOMAIN)

        l2 = Location(name='Test location 2',
                      external_id='4407',
                      location_type='Hospital',
                      domain=TEST_DOMAIN)

        l1.save()
        l2.save()

        SupplyPointCase.create_from_location(TEST_DOMAIN, l1)
        SupplyPointCase.create_from_location(TEST_DOMAIN, l2)

        l1.save()
        l2.save()

        with open(os.path.join(self.datapath, 'sample_products.json')) as f:
            for product_json in json.loads(f.read()):
                self.api_object.product_sync(Product(product_json))
示例#59
0
def supply_points_with_latest_status_by_datespan(locations, status_type, status_value, datespan):
    """
    This very similar method is used by the reminders.
    """
    ids = [loc.location_id for loc in locations]
    inner = SupplyPointStatus.objects.filter(location_id__in=ids,
                                             status_type=status_type,
                                             status_date__gte=datespan.startdate,
                                             status_date__lte=datespan.enddate).annotate(pk=Max('id'))
    ids = SupplyPointStatus.objects.filter(
        id__in=inner.values('pk').query,
        status_type=status_type,
        status_value=status_value).distinct().values_list("location_id", flat=True)
    return [SupplyPointCase.get(id) for id in ids]