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 get_supply_point_case_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())
def sync_location_supply_point(loc): """ This method syncs the location/supply point connection and is triggered whenever a location is edited or created. """ # circular import from corehq.apps.domain.models import Domain domain = Domain.get_by_name(loc.domain) if not domain.commtrack_enabled: return def _needs_supply_point(loc, domain): """Exclude administrative-only locs""" return loc.location_type in [loc_type.name for loc_type in domain.location_types if not loc_type.administrative] if _needs_supply_point(loc, domain): supply_point = get_supply_point_case_by_location(loc) if supply_point: supply_point.update_from_location(loc) updated_supply_point = supply_point else: updated_supply_point = SupplyPointCase.create_from_location(loc.domain, loc) # need to sync this sp change to the sql location # but saving the doc will trigger a loop try: sql_loc = SQLLocation.objects.get(location_id=loc._id) sql_loc.supply_point_id = updated_supply_point._id sql_loc.save() except SQLLocation.DoesNotExist: pass
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 = get_supply_point_case_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}
def get_or_create_by_location(cls, location): sp = get_supply_point_case_by_location(location) if not sp: sp = SupplyPointCase.create_from_location(location.domain, location) # todo: if you come across this after july 2015 go search couchlog # and see how frequently this is happening. # if it's not happening at all we should remove it. logging.warning( "supply_point_dynamically_created, {}, {}, {}".format(location.name, sp._id, location.domain) ) return sp
def get_or_create_by_location(cls, location): sp = get_supply_point_case_by_location(location) if not sp: sp = SupplyPointCase.create_from_location( location.domain, location ) # todo: if you come across this after july 2015 go search couchlog # and see how frequently this is happening. # if it's not happening at all we should remove it. logging.warning('supply_point_dynamically_created, {}, {}, {}'.format( location.name, sp._id, location.domain, )) return sp
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 get_supply_point_case_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())
def supply_point(self): try: return get_supply_point_case_by_location(self.location) except MultipleResultsFound: raise MultipleSupplyPointException
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 = get_supply_point_case_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 }
def test_get_supply_point_case_by_location(self): actual = get_supply_point_case_by_location(self.locations[0]) expected = SupplyPointCase.wrap(self.supply_points[0].to_json()) self.assertEqual(type(actual), type(expected)) self.assertEqual(actual.to_json(), expected.to_json())
def get_by_location(cls, location): return get_supply_point_case_by_location(location)
def linked_supply_point(self): return get_supply_point_case_by_location(self)