def __init__(self, location, bound_data=None, *args, **kwargs): self.location = location kwargs['prefix'] = 'main' # seed form data from couch doc kwargs['initial'] = dict(self.location._doc) kwargs['initial']['parent_id'] = self.cur_parent_id lat, lon = (getattr(self.location, k, None) for k in ('latitude', 'longitude')) kwargs['initial']['coordinates'] = '%s, %s' % ( lat, lon) if lat is not None else '' super(LocationForm, self).__init__(bound_data, *args, **kwargs) self.fields['parent_id'].widget.domain = self.location.domain # custom properties self.sub_forms = {} # TODO think i need to change this to iterate over all types, since the parent # can be changed dynamically for potential_type in allowed_child_types(self.location.domain, self.location.parent): subform = LocationCustomPropertiesSubForm(self.location, potential_type, bound_data) if subform.fields: self.sub_forms[potential_type] = subform
def clean_location_type(self): loc_type = self.cleaned_data['location_type'] child_types = allowed_child_types(self.location.domain, self.cleaned_data.get('parent')) if not child_types: assert False, 'the selected parent location cannot have sub-locations!' elif loc_type not in child_types: assert False, 'not valid for the select parent location' return loc_type
def __init__(self, location, bound_data=None, *args, **kwargs): self.location = location kwargs['prefix'] = 'main' # seed form data from couch doc kwargs['initial'] = self.location._doc kwargs['initial']['parent_id'] = self.cur_parent_id super(LocationForm, self).__init__(bound_data, *args, **kwargs) self.fields['parent_id'].widget.domain = self.location.domain # custom properties self.sub_forms = {} # TODO think i need to change this to iterate over all types, since the parent # can be changed dynamically for potential_type in allowed_child_types(self.location.domain, self.location.parent): subform = LocationCustomPropertiesSubForm(self.location, potential_type, bound_data) if subform.fields: self.sub_forms[potential_type] = subform
def __init__(self, location, bound_data=None, *args, **kwargs): self.location = location kwargs['prefix'] = 'main' # seed form data from couch doc kwargs['initial'] = dict(self.location._doc) kwargs['initial']['parent_id'] = self.cur_parent_id lat, lon = (getattr(self.location, k, None) for k in ('latitude', 'longitude')) kwargs['initial']['coordinates'] = '%s, %s' % (lat, lon) if lat is not None else '' super(LocationForm, self).__init__(bound_data, *args, **kwargs) self.fields['parent_id'].widget.domain = self.location.domain # custom properties self.sub_forms = {} # TODO think i need to change this to iterate over all types, since the parent # can be changed dynamically for potential_type in allowed_child_types(self.location.domain, self.location.parent): subform = LocationCustomPropertiesSubForm(self.location, potential_type, bound_data) if subform.fields: self.sub_forms[potential_type] = subform
def import_location(domain, loc_row, hierarchy_fields, property_fields, update, loc_cache=None): if loc_cache is None: loc_cache = LocationCache(domain) def get_cell(field): if loc_row[field]: return loc_row[field].strip() else: return None hierarchy = [(p, get_cell(p)) for p in hierarchy_fields] properties = dict((p, get_cell(p)) for p in property_fields) # backwards compatibility if 'outlet_code' in property_fields: properties['site_code'] = properties['outlet_code'] del properties['outlet_code'] terminal_type = hierarchy[-1][0] # create parent hierarchy if it does not exist parent = None for loc_type, loc_name in hierarchy: row_name = '%s %s' % (parent.name, parent.location_type) if parent else '-root-' # are we at the leaf loc? is_terminal = (loc_type == terminal_type) if not loc_name: # name is empty; this level of hierarchy is skipped if is_terminal and any(properties.values()): yield 'warning: %s properties specified on row that won\'t create a %s! (%s)' % (terminal_type, terminal_type, row_name) continue def save(existing=None): messages = [] error = False data = { 'name': loc_name, 'location_type': loc_type, 'parent_id': parent._id if parent else None, } if is_terminal: data.update(((terminal_type, k), v) for k, v in properties.iteritems()) form = make_form(domain, parent, data, existing) form.strict = False # optimization hack to turn off strict validation if form.is_valid(): child = form.save() if existing: messages.append('updated %s %s' % (loc_type, loc_name)) else: loc_cache.add(child) messages.append('created %s %s' % (loc_type, loc_name)) else: # TODO move this to LocationForm somehow error = True child = None forms = filter(None, [form, form.sub_forms.get(loc_type)]) for k, v in itertools.chain(*(f.errors.iteritems() for f in forms)): if k != '__all__': messages.append('error in %s %s; %s: %s' % (loc_type, loc_name, k, v)) return child, messages, error child = loc_cache.get_by_name(loc_name, loc_type, parent) if child: if is_terminal: if update: # (x or None) is to not distinguish between '' and None properties_changed = any((v or None) != (getattr(child, k, None) or None) for k, v in properties.iteritems()) if properties_changed: _, messages, _ = save(child) for m in messages: yield m else: yield '%s %s unchanged; skipping...' % (loc_type, loc_name) else: yield '%s %s exists; skipping...' % (loc_type, loc_name) else: if loc_type not in allowed_child_types(domain, parent): yield 'error: %s %s cannot be child of %s' % (loc_type, loc_name, row_name) return child, messages, error = save() for m in messages: yield m if error: return parent = child
def import_location(domain, loc_row, hierarchy_fields, property_fields, update, loc_cache=None): if loc_cache is None: loc_cache = LocationCache(domain) def get_cell(field): val = loc_row[field].strip() return val if val else None hierarchy = [(p, get_cell(p)) for p in hierarchy_fields] properties = dict((p, get_cell(p)) for p in property_fields) # backwards compatibility if 'outlet_code' in property_fields: properties['site_code'] = properties['outlet_code'] del properties['outlet_code'] terminal_type = hierarchy[-1][0] # create parent hierarchy if it does not exist parent = None for loc_type, loc_name in hierarchy: row_name = '%s %s' % (parent.name, parent.location_type) if parent else '-root-' # are we at the leaf loc? is_terminal = (loc_type == terminal_type) if not loc_name: # name is empty; this level of hierarchy is skipped if is_terminal and any(properties.values()): yield 'warning: %s properties specified on row that won\'t create a %s! (%s)' % (terminal_type, terminal_type, row_name) continue def save(existing=None): messages = [] error = False data = { 'name': loc_name, 'location_type': loc_type, 'parent_id': parent._id if parent else None, } if is_terminal: data.update(((terminal_type, k), v) for k, v in properties.iteritems()) form = make_form(domain, parent, data, existing) form.strict = False # optimization hack to turn off strict validation if form.is_valid(): child = form.save() if existing: messages.append('updated %s %s' % (loc_type, loc_name)) else: loc_cache.add(child) messages.append('created %s %s' % (loc_type, loc_name)) else: # TODO move this to LocationForm somehow error = True child = None forms = filter(None, [form, form.sub_forms.get(loc_type)]) for k, v in itertools.chain(*(f.errors.iteritems() for f in forms)): if k != '__all__': messages.append('error in %s %s; %s: %s' % (loc_type, loc_name, k, v)) return child, messages, error child = loc_cache.get_by_name(loc_name, loc_type, parent) if child: if is_terminal: if update: # (x or None) is to not distinguish between '' and None properties_changed = any((v or None) != (getattr(child, k, None) or None) for k, v in properties.iteritems()) if properties_changed: _, messages, _ = save(child) for m in messages: yield m else: yield '%s %s unchanged; skipping...' % (loc_type, loc_name) else: yield '%s %s exists; skipping...' % (loc_type, loc_name) else: if loc_type not in allowed_child_types(domain, parent): yield 'error: %s %s cannot be child of %s' % (loc_type, loc_name, row_name) return child, messages, error = save() for m in messages: yield m if error: return parent = child