def edit(request, city_tag=None, bldg_tag=None, unit_tag=None): (city, building, unit) = find_by_tags(city_tag, bldg_tag, unit_tag) results = '' #UtilityFormSet = formset_factory(UtilityOneRowForm, extra=12) UtilityFormSet = formset_factory(UtilityOneRowForm, extra=0) (provider_names, utility_providers) = make_provider_names(city) if request.method == 'POST': meta = MetaUtilityForm(request.POST, prefix='meta') #http://stackoverflow.com/questions/657607/setting-the-selected-value-on-a-django-forms-choicefield meta.fields['utility_provider'].choices = provider_names utility_set = UtilityFormSet(request.POST, prefix='months') if meta.is_valid() and utility_set.is_valid(): # All validation rules pass errors = False (provider, company_name) = parse_form_providers(meta) #keep query around for all rows main_query = None unit_updated = False #go through each item in utility_set for form in utility_set: #see if there is data if form.cleaned_data['cost'] or form.cleaned_data['amount']: #if we haven't done the initial lookup yet, do it now if not main_query: main_query = UtilitySummary.objects.filter(building=building, unit=unit, type=meta.cleaned_data['utility_type']) #look up the corresponding UtilitySummary model object subset = main_query.filter(start_date=form.cleaned_data['start_date']) updated = False #if len(subset): if subset.count(): #already have something in the database... #look at that and update accordingly #print "Updating existing entry:" #following equivalent? summary = subset[0] #summary = subset.first() #if different, apply and save changes if summary.cost != form.cleaned_data['cost']: summary.cost = form.cleaned_data['cost'] updated = True if summary.amount != form.cleaned_data['amount']: summary.amount = form.cleaned_data['amount'] updated = True if provider: if summary.provider != provider: summary.provider = provider updated = True else: if summary.vendor != company_name: summary.vendor = company_name updated = True else: summary = UtilitySummary() summary.building = building summary.unit = unit summary.type = meta.cleaned_data['utility_type'] #should set one of these if provider: summary.provider = provider else: summary.vendor = company_name summary.start_date = form.cleaned_data['start_date'] summary.cost = form.cleaned_data['cost'] summary.amount = form.cleaned_data['amount'] #summary.save() #print "Saving new!!" updated = True if updated: #TODO: #consider logging any changes to prevent data loss summary.save() #print "Changes saved" unit_updated = True if unit_updated: #this takes care of updating corresponding averages and scores unit.save_and_update(request) #TODO: #would be better to redirect back to the building detail page #and show a thank you message #that message should include options to share, tweet, etc #in chrome, the original post url stays in the address bar... #finished_url = reverse('utility.views.thank_you') finished_url = thankyou_url(unit) return redirect(finished_url) else: #form = ShareForm() now = timezone.now() months = previous_months() months.reverse() #for i in range(1,13): # print i initial = [] for month in months: initial.append( {'start_date': month} ) utility_set = UtilityFormSet(initial=initial, prefix='months') meta = MetaUtilityForm(initial={'start_date':months[-1], 'end_date':months[0]}, prefix='meta') meta.fields['utility_provider'].choices = provider_names #meta.start_date = months[-1] #meta.end_date = months[0] #view_url = reverse('utility.views.upload_handler') view_url = request.path #print unit context = { 'city': city.name, #'state': state, 'bldg': building, 'unit': unit, #forms: 'meta': meta, 'utility': utility_set, 'providers': json.dumps(utility_providers), 'results': results, #'upload_url': upload_url, } return render(request, 'utility_generic.html', context)
def share_data(request): """ this is the controller for the share form found on the front page bare minimum needed for data collection """ results = '' #probably OK to show the calculator worksheet either way #once we're on the short form destination page #show_calculator = True show_calculator = False unitform = None bldgform = None if request.method == 'POST': #make this either way shareform = ShareForm(request.POST, prefix='share') #make and test the bldgform (and unitform, if necessary) (result, bldgform, unitform) = validate_building_and_unit(request) #might need these anywhere: errors = bldgform._errors.setdefault(forms.forms.NON_FIELD_ERRORS, ErrorList()) if result: if result.errors: #we had difficulty finding the corresponding building #add errors to the form #http://stackoverflow.com/questions/188886/inject-errors-into-already-validated-form #although once this is on django 1.7: #https://docs.djangoproject.com/en/dev/ref/forms/api/#django.forms.Form.add_error for error in result.errors: #print "Adding error: %s" % error errors.append(error) #should already be errors if not result.building, #so this could just be else, but this is more clear: elif result.building and result.unit: ## print ## print "Found building!" ## print #TODO #consider filling in any empty fields in the form #with data we have previously collected about chosen building #image button must submit a hybrid value with x and y... #discovered by printing POST results: #print request.POST if 'calculator.x' in request.POST or 'calculator.y' in request.POST: show_calculator = True #print "SHOWING CALCULATOR!!" if not shareform.is_valid(): # All validation rules pass #print "FORM WAS NOT VALID" pass else: #print "FORM WAS VALID" errors = False #now check if rental / rent combo is complete... #custome validation check ## if shareform.cleaned_data['property_type'] == 'rental': ## result.unit.status = 'rented' ## if not shareform.cleaned_data['rent']: ## shareform.errors['rent'] = "Please specify the rent." ## errors = True ## else: ## result.unit.rent = shareform.cleaned_data['rent'] ## else: ## result.unit.status = 'owner-occupied' if shareform.cleaned_data['is_rental'] == 'true': result.unit.status = 'rented' if not shareform.cleaned_data['rent']: shareform.errors['rent'] = "Please specify the rent." errors = True else: result.unit.rent = shareform.cleaned_data['rent'] else: result.unit.status = 'owner-occupied' #check if we have electricity #or natural gas average bill amounts if not errors: #print "NO ERRORS WITH RENTAL / RENT" #save what ever we have #also add these to the current month #for that utility type. #that way data will persist if other monthly data added result.unit.bedrooms = shareform.cleaned_data['bedrooms'] if not shareform.cleaned_data['electricity'] is None: #this won't track supplied averages over time: #result.unit.average_electricity = shareform.cleaned_data['electricity'] add_utility_average_to_unit(result.unit, shareform.cleaned_data['electricity'], 'electricity') if not shareform.cleaned_data['gas'] is None: #result.unit.average_gas = shareform.cleaned_data['gas'] add_utility_average_to_unit(result.unit, shareform.cleaned_data['gas'], 'gas') result.unit.save_and_update(request) messages.add_message(request, messages.INFO, 'Saved changes to unit.') thank_you = thankyou_url(result.unit) #args=(updated.building.tag, city.tag, updated.tag) #return redirect(finished_url) return redirect(thank_you) #in chrome, the original post url stays in the address bar. #finished_url = reverse('utility.views.thank_you') #return redirect(finished_url) else: errors.append("There was a problem locating the requested building") else: bldgform = NewBuildingForm(prefix='building') #shareform = ShareForm(prefix='share', initial={'is_rental': True}) shareform = ShareForm(prefix='share') #view_url = reverse('utility.views.upload_handler') view_url = request.path #upload_url, upload_data = prepare_upload(request, view_url) #upload_url = create_upload_url(view_url) upload_data = {} action_url = reverse('content.views.share_data') #print form['utility_type'].errors #print form['utility_type'].label #print form['utility_type'] #print dir(form['energy_options']) #print form['energy_options'] context = { 'user': request.user, 'bldgform': bldgform, 'unitform': unitform, 'form': shareform, 'show_calculator': show_calculator, 'action_url': action_url, } return render(request, 'share.html', context )