def monthly_density_list(self): municipality = self.request.context # parse date from request if any date_string = self.request.GET.get('period') if date_string: try: date = datetime.datetime.strptime(date_string, '%Y-%m') except ValueError: return HTTPBadRequest("Couldn't understand the date format") else: date = datetime.datetime.now() # determine the date ranges start, end = get_month_start_end(date) criterion = and_(MonthlyDensity.date >= start, MonthlyDensity.date <= end) municipality_submissions = MunicipalitySubmission.get_items( municipality, MonthlyDensity, criterion) monthly_densities = [s for ms, s in municipality_submissions] average_density = MonthlyDensity.get_average_density(date) return { 'municipality': municipality, 'items': monthly_densities, 'average_density': average_density, 'date': date }
def get_last_meter_reading(cls, municipality, current_date): """ Based on the specified month/year, get the meter reading for said municipality for the previous month, or None :param municipality: Municipality to check :param current_date: The current month/year with day set to 01 :return: the ElectricityRegister record or None """ # get the start end dates for the current month start, end = get_month_start_end(current_date) # determine the previous month/year previous_month_year = get_previous_month_year(current_date) # select the `newest` ElectricityRegister->meter_reading that falls # under previous_month_year result = DBSession.query( cls.json_data[cls.METER_READING_FIELD].astext)\ .select_from(MunicipalitySubmission)\ .join(MunicipalitySubmission.submission)\ .filter(MunicipalitySubmission.municipality == municipality, Submission.date >= previous_month_year, Submission.date < start)\ .order_by(desc(Submission.date))\ .limit(1)\ .first() return result and result[0] or None
def get_monthly_rejects_density(self): """ Get the monthly density of rejects from sieving instance which matches this date and is approved :return: MonthlyRejectsDensity monthly rejects density record or None if not found """ municipality_submission = self.municipality_submission if municipality_submission is None: return None start, end = get_month_start_end(self.date) return DBSession\ .query(MonthlyRejectsDensity)\ .select_from(MunicipalitySubmission)\ .join(MonthlyRejectsDensity)\ .filter( MunicipalitySubmission.municipality == municipality_submission.municipality, MonthlyRejectsDensity.xform_id == MonthlyRejectsDensity.XFORM_ID, MonthlyRejectsDensity.date >= start, MonthlyRejectsDensity.date <= end, MonthlyRejectsDensity.status == Submission.APPROVED)\ .order_by(desc(MonthlyRejectsDensity.date))\ .first()
def test_site_reports_sets_start_end_to_current_month_if_not_specified( self): self.request.context = self.municipality result = self.views.site_reports() start, end = get_month_start_end(datetime.date.today()) # if end is beyond today's date, end with be set to today today = datetime.date.today() end = today if end > today else end self.assertEqual(start, result['start']) self.assertEqual(end, result['end'])
def site_reports(self): municipality = self.request.context # default to start and end of current month today = datetime.date.today() default_start, default_end = get_month_start_end(today) start, end = get_start_end_date(self.request.GET, default_start, default_end, today) # not necessary but pretty format the date range when we can if start == default_start and end == default_end: label = "This Month" elif (today - start).days == 1: label = "Yesterday" elif end == today: time_labels = [ # if start and end are the same, the label is today (lambda dt: dt.days == 0, "Today"), # if timedelta between start and end is less than 31 days, # last # days (lambda dt: 1 < dt.days < 30, "Last {} days") ] time_delta = today - start labels = [l for f, l in time_labels if f(time_delta)] label = labels[0].format(time_delta.days + 1)\ if len(labels) == 1 else None else: label = None # confirm if site report for selected month period is available show_save_report = False update_report = False if (end - start).days <= 31: # show save button if the time period selected is a month show_save_report = True try: # try to retrieve month report SiteReport.get_report_by_date(end, municipality) update_report = True except NoResultFound: pass return { 'municipality': municipality, 'start': start, 'end': end, 'label': label, 'show_save_report': show_save_report, 'update_report': update_report }
def save_site_report(self): # get the selected month to create a report for # if another report already exists, update it with the report_data # contained in the municipality today = datetime.date.today() default_start, default_end = get_month_start_end(today) start, end = get_start_end_date(self.request.POST, default_start, default_end, today) municipality = self.request.context # Populate report_data json report_json = municipality.get_data_map(start, end) # Get start and end date for the month being reported on month_start, month_end = get_month_start_end(start) try: site_report = SiteReport.get_report_by_date( month_start, municipality) site_report.report_json = report_json self.request.session.flash(u"The site report has been updated.", "success") except NoResultFound: site_report = SiteReport(report_date=month_start, municipality=municipality, report_json=report_json) self.request.session.flash(u"The site report has been saved.", "success") site_report.save() return HTTPFound( self.request.route_url('municipalities', traverse=(municipality.id, 'reports'), _query={ 'start': start, 'end': end }))
def get_compost_density(self, municipality): start, end = get_month_start_end(self.date) # with our date as ref. find the density for the month self._compost_density = self._compost_density\ or DBSession.query(CompostDensityRegister)\ .select_from(MunicipalitySubmission)\ .join(MunicipalitySubmission.submission)\ .filter(MunicipalitySubmission.municipality == municipality, CompostDensityRegister.date >= start, CompostDensityRegister.date <= end, CompostDensityRegister.status == Submission.APPROVED)\ .order_by(desc(CompostDensityRegister.date))\ .limit(1)\ .first() return self._compost_density
def get_by_date(cls, date, municipality, *criterion): from composting.models.municipality_submission import\ MunicipalitySubmission """ Tries to retrieve newest compost density record for whichever month is specified by date :param date: the target month :return: """ start, end = get_month_start_end(date) return DBSession.query(cls)\ .select_from(MunicipalitySubmission)\ .join(cls)\ .filter( cls.xform_id == cls.XFORM_ID, cls.date >= start, cls.date <= end, MunicipalitySubmission.municipality == municipality, *criterion)\ .order_by(desc(cls.date))\ .first()
def get_average_density(cls, date): """ Get the average density for the month that said date falls in """ # get the minimum threshold threshold_min = cls.THRESHOLD_MIN settings = get_current_registry().settings if settings: threshold_min = int(settings['monthly_density_threshold_min']) # determine the start and end days for the month start, end = get_month_start_end(date) # get monthly density records that monthly_densities = DBSession.query(cls)\ .filter( cls.date >= start, cls.date <= end, cls.status == Submission.APPROVED)\ .all() if len(monthly_densities) >= threshold_min: return cls.calculate_average_density(monthly_densities) else: return None
def monthly_waste_composition_list(self): municipality = self.request.context # parse date from request if any date_string = self.request.GET.get('period') if date_string: try: date = datetime.datetime.strptime(date_string, '%Y-%m') except ValueError: return HTTPBadRequest("Couldn't understand the date format") else: date = datetime.datetime.now() # determine the date ranges start, end = get_month_start_end(date) criterion = and_(MonthlyWasteComposition.date >= start, MonthlyWasteComposition.date <= end) municipality_submissions = MunicipalitySubmission.get_items( municipality, MonthlyWasteComposition, criterion) monthly_waste_compositions = [s for ms, s in municipality_submissions] # calculate means and percentages total_waste_mean = MonthlyWasteComposition.get_total_waste_mean( monthly_waste_compositions) means = MonthlyWasteComposition.get_means(monthly_waste_compositions) percentages = MonthlyWasteComposition.get_percentages( monthly_waste_compositions) return { 'municipality': municipality, 'items': monthly_waste_compositions, 'date': date, 'total_waste_mean': total_waste_mean, 'means': means, 'percentages': percentages }
def test_get_month_start_end_if_end_month(self): date = datetime.date(2014, 2, 28) start, end = utils.get_month_start_end(date) self.assertEqual(start, datetime.date(2014, 2, 1)) self.assertEqual(end, datetime.date(2014, 2, 28))
def test_get_month_start_end_if_end_year(self): date = datetime.date(2013, 12, 25) start, end = utils.get_month_start_end(date) self.assertEqual(start, datetime.date(2013, 12, 1)) self.assertEqual(end, datetime.date(2013, 12, 31))