def setup_monthly_compost_density(self): # get the monthly density record and approve if compost_density = CompostDensityRegister.get( CompostDensityRegister.date == date(2014, 5, 1)) compost_density.status = Submission.APPROVED with transaction.manager: DBSession.add(compost_density)
def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ engine = engine_from_config(settings, 'sqlalchemy.') DBSession.configure(bind=engine) Base.metadata.bind = engine session_factory = UnencryptedCookieSessionFactoryConfig( settings['secret_key']) config = Configurator(settings=settings, root_factory='composting.models.base.RootFactory', session_factory=session_factory) config.set_authentication_policy( AuthTktAuthenticationPolicy(settings['secret_key'], callback=group_finder, hashalg='sha512')) config.set_authorization_policy(ACLAuthorizationPolicy()) config.set_default_permission('authenticated') logging.config.fileConfig(global_config['__file__'], disable_existing_loggers=False) # configure password context pwd_context.load_path(global_config['__file__']) # include ourselves includeme(config) return config.make_wsgi_app()
def delete(self): skip = self.request.context municipality_id = skip.municipality_id DBSession.delete(skip) self.request.session.flash(u"The skip has been deleted.", "success") return HTTPFound( self.request.route_url('municipalities', traverse=(municipality_id, 'skips')))
def test_get_or_create_report_returns_existing_report_if_one_exist(self): submission = Submission.newest() submission_id = submission.id report = Report(submission=submission, report_json={'key': 'value'}) with transaction.manager: DBSession.add(report) submission = Submission.get(Submission.id == submission_id) report = submission.get_or_create_report() self.assertTrue(instance_state(report).persistent)
def populate_daily_vehicle_data_register_reports(self): query = self.get_pending_submissions_by_class(DailyVehicleDataRegister) daily_vehicle_registers = query.all() for daily_vehicle_register in daily_vehicle_registers: daily_vehicle_register.status = Submission.APPROVED with transaction.manager: DBSession.add_all(daily_vehicle_registers) self.assertEqual(query.count(), 0)
def setUp(self): registry = Registry() registry.settings = settings self.config = testing.setUp(registry=registry) pwd_context.load_path('test.ini') # setup db DBSession.configure(bind=engine, expire_on_commit=False) Base.metadata.bind = engine Base.metadata.drop_all() Base.metadata.create_all() # enable logging logging.config.fileConfig('test.ini', disable_existing_loggers=False)
def test_delete_report(self): submission = Submission.newest() submission_id = submission.id report = Report(submission=submission, report_json={'key': 'value'}) with transaction.manager: DBSession.add(report) num_reports = Report.count(Report.submission_id == submission_id) self.assertEqual(num_reports, 1) submission = Submission.get(Submission.id == submission_id) submission.delete_report() self.assertEqual(Report.count(Report.submission_id == submission_id), num_reports - 1)
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 test_get_monthly_rejects_density_returns_none_if_exists(self): self.setup_test_data() with transaction.manager: DBSession.query(MonthlyRejectsDensity).update({ 'status': Submission.APPROVED }) municipality = Municipality.get(Municipality.name == "Mukono") rejects_landfilled = DailyRejectsLandfilled( date=date(2014, 6, 13), municipality_submission=MunicipalitySubmission( municipality=municipality ) ) monthly_rejects_landfilled = rejects_landfilled\ .get_monthly_rejects_density() self.assertIsInstance(monthly_rejects_landfilled, MonthlyRejectsDensity)
def test_volume_calculation(self): self.setup_test_data() with transaction.manager: DBSession.query(MonthlyRejectsDensity).update({ 'status': Submission.APPROVED }) municipality = Municipality.get(Municipality.name == "Mukono") rejects_landfilled = DailyRejectsLandfilled( date=date(2014, 6, 13), json_data={ 'barrows_number_frm_sieving': '10' }, municipality_submission=MunicipalitySubmission( municipality=municipality ) ) self.assertEqual(rejects_landfilled.volume(), 6.25)
def populate_compost_density(self): # Should be run before compost sales to make sure compost sales have a # density to reference # approve compost density records to have data to aggregate on query = self.get_pending_submissions_by_class(CompostDensityRegister) compost_densities = query.all() for compost_density in compost_densities: compost_density.status = Submission.APPROVED with transaction.manager: DBSession.add_all(compost_densities) # check that our number of un-approved compost densities self.assertEqual(query.count(), 0) return compost_densities
def __call__(self, json_payload, **kwargs): submission, is_updated = self.get_or_create_submission( json_payload, **kwargs) if not is_updated: # determine the municipality id(object) municipality = self.get_municipality_from_payload(json_payload) if municipality is not None: municipality_submission = MunicipalitySubmission( submission=submission, municipality=municipality) DBSession.add(municipality_submission) return # add the submission because we can save even when we can't determine # its municipality DBSession.add(submission)
def setup_test_data(self): admin = User(id=1, username='******', password='******', active=True, group='nema') municipality = Municipality(name="Mukono") other_municipality = Municipality(name="Jinja") manager = User(id=2, username='******', password='******', active=True, group='sm', municipality=municipality) other_manager = User(id=3, username='******', password='******', active=True, group='sm', municipality=other_municipality) skip_a = Skip(municipality=municipality, skip_type='A', small_length=20, large_length=30, small_breadth=10, large_breadth=16) skip_b = Skip(municipality=municipality, skip_type='B', small_length=20, large_length=30, small_breadth=10, large_breadth=16) submission_handler_manager.clear() hook_submission_handlers() with transaction.manager: DBSession.add_all( [admin, manager, municipality, skip_a, skip_b, other_manager]) for status, raw_json in self.submissions: json_payload = json.loads(raw_json) handler_class = submission_handler_manager.find_handler( json_payload) handler_class().__call__(json_payload, status=status)
def populate_monthly_density_reports(self): # Should be run before daily wastes to make sure daily wastes have a # density to reference # approve monthly density records to have data to aggregate on query = self.get_pending_submissions_by_class(MonthlyDensity) monthly_densities = query.all() # change the monthly density threshold to MonthlyDensity.THRESHOLD_MIN = 3 for monthly_density in monthly_densities: monthly_density.status = Submission.APPROVED with transaction.manager: DBSession.add_all(monthly_densities) # check that our number of approved monthly densities self.assertEqual(query.count(), 0) return monthly_densities
def test_create_or_update_report(self): self.setup_test_data() with transaction.manager: DBSession.query(MonthlyRejectsDensity).update({ 'status': Submission.APPROVED }) municipality = Municipality.get(Municipality.name == "Mukono") rejects_landfilled = DailyRejectsLandfilled( date=date(2014, 6, 13), json_data={ 'barrows_number_frm_sieving': '10' }, municipality_submission=MunicipalitySubmission( municipality=municipality ) ) report = rejects_landfilled.create_or_update_report() self.assertEqual(report.report_json, { 'volume': 6.25, 'tonnage': 1.7999999999999998 })
def test_weight_calculation(self): self.setup_test_data() municipality = Municipality.get(Municipality.name == "Mukono") compost_density = CompostDensityRegister.get( CompostDensityRegister.date >= datetime.date(2014, 5, 1), CompostDensityRegister.date <= datetime.date(2014, 5, 31)) compost_density.status = Submission.APPROVED with transaction.manager: DBSession.add(compost_density) compost_sale = CompostSalesRegister( date=datetime.datetime(2014, 05, 01), json_data={ 'bagged_compost': 'no', 'compost_length': '3.0', 'compost_width': '4.0', 'compost_height': '5.0' }, municipality_submission=MunicipalitySubmission( municipality=municipality)) weight = compost_sale.weight() self.assertAlmostEqual(weight, 864.0 / 1000) # div to convert to tonnes
def __getitem__(self, item): from composting.models.municipality_submission import ( MunicipalitySubmission) try: submission = DBSession.query(Submission)\ .join(MunicipalitySubmission)\ .filter(Submission.id == item)\ .one() except NoResultFound: raise KeyError else: submission.__parent__ = self submission.name = item return submission
def __call__(self, node, value): try: skip = DBSession.query(Skip)\ .filter( Skip.municipality_id == self.municipality_id, Skip.skip_type == value)\ .one() except NoResultFound: # no match pass else: if (self.skip_id is None or (self.skip_id is not None and self.skip_id != skip.id)): raise colander.Invalid(node, self.msg.format(skip_type=value))
def fuel_consumption(self, start_date, end_date): submission_subclass = DailyVehicleDataRegister query = (DBSession.query( sqla_sum(submission_subclass.json_data[ submission_subclass.FUEL_PURCHASED_LTRS].cast(Float))).join( MunicipalitySubmission, (MunicipalitySubmission.submission_id == submission_subclass.id)). filter(MunicipalitySubmission.municipality == self).filter( submission_subclass.status == Submission.APPROVED).filter( and_(Submission.date >= start_date, Submission.date <= end_date))) return query.first()[0]
def average_distance_travelled(self, start_date, end_date): submission_subclass = CompostSalesRegister query = (DBSession.query( func.avg(submission_subclass.json_data[ submission_subclass.DISTANCE_TRAVELLED].cast(Float))).join( MunicipalitySubmission, (MunicipalitySubmission.submission_id == submission_subclass.id)). filter(MunicipalitySubmission.municipality == self).filter( submission_subclass.status == Submission.APPROVED).filter( and_(Submission.date >= start_date, Submission.date <= end_date))) return query.first()[0]
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_municipality_from_payload(cls, json_payload): """ Try to determine the municipality the submission user belongs to from the payload :return: Municipality or None """ submitted_by = json_payload.get(constants.SUBMITTED_BY) if submitted_by is None: return None # find the user and join to municipality try: municipality = DBSession.query(Municipality)\ .select_from(User)\ .filter(User.username == submitted_by)\ .join(Municipality).one() except NoResultFound: return None else: return municipality
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 get_report_by_date(cls, date, municipality): return DBSession.query(SiteReport)\ .filter(and_( extract('month', SiteReport.report_date) == date.month, extract('year', SiteReport.report_date) == date.year, SiteReport.municipality == municipality)).one()
def get_items_query(cls, *criterion): return DBSession.query(cls)\ .filter(*criterion)
def get_users_by_group_query(self, group): return DBSession.query(User)\ .filter(User.group == group, User.municipality == self)
def get_skips(self, *criterion): return DBSession.query(Skip)\ .filter(Skip.municipality == self, *criterion)\ .all()
def test_get_item(self): submission = DBSession.query(Submission).first() submission_id = submission.id item = SubmissionFactory(testing.DummyRequest())[submission.id] self.assertIsInstance(item, Submission) self.assertEqual(submission_id, item.id)
def tearDown(self): DBSession.remove() testing.tearDown()