def get_resource(self, resource_id, resource_uri): if resource_id: return current_app.db_session.query( Resource ).filter(Resource.id == resource_id).one() if resource_uri: return get_resource_for_uri("/%s" % resource_uri)
def post(self): data = request.get_json() person_uri = data["person"]["uri"] text = data["text"] resource_uri = data["resource"]["uri"] resource = get_resource_for_uri(resource_uri) settings = SettingsResource().get() if not (resource.auto_approval_allowed and settings["strotime_booking_allowed"]): abort(403, __error__=[u"Strøtimer ikke tillatt"]) person = get_person_for_uri(person_uri) application = Application(person, None, text, None, resource) datetime_now = datetime.now() slots = [self.parse_slot_request(d, application) for d in data["slots"]] for slot in slots: start_date = slot.start_time.date() end_date = slot.end_time.date() week_day = slot.start_time.isoweekday() start_time = slot.start_time.time() end_time = slot.end_time.time() self.validate_start_and_end_times(start_date, end_date, start_time, end_time) if slot.start_time < nearest_hour(datetime_now): abort(400, __error__=[u"Du kan ikke søke om en time tilbake i tid"]) if self.is_conflict_slot_time( resource, start_date, end_date, week_day, start_time, end_time ) or self.is_conflict_rammetid(resource, start_date, end_date, week_day, start_time, end_time): abort(400, __error__=[u"Tiden du har søkt på er ikke tilgjengelig"]) if self.is_conflict_blocked_time(resource, start_date, end_date, week_day, start_time, end_time): abort(400, __error__=[u"Tiden du har søkt på er blokkert"]) # The start time must be in the range 3-21 days (inclusive) days = (slot.start_time.date() - datetime_now.date()).days if days >= 3 and days <= 21: application.add_strotime_slot(slot) else: abort(400, __error__=[u"Tiden må være innenfor 3-21 dager fra dagens dato"]) application.status = "Granted" current_app.db_session.add(application) current_app.db_session.commit() current_app.db_session.refresh(application) send_email_strotime_granted(application) send_email_to_resource(application) return application, 201
def put(self, rammetid_id): data = request.get_json() rammetid = self.get_object_by_id(rammetid_id) status = data.get("status", None) resource_data = data.get("resource", None) if resource_data: resource_uri = resource_data["uri"] resource = get_resource_for_uri(resource_uri) if not resource: abort(403, __error__=[u'Ressursen ble ikke funnet.']) else: abort(403, __error__=[u'Data om ressursen mangler.']) # The rammetid might have been # moved to a different resource rammetid.resource = resource # The rammtid status might # have been changed rammetid.status = status rammetid_slots_data = data.get("rammetid_slots", None) if rammetid_slots_data: for rammetid_slot in rammetid_slots_data: rammetid_slot_parsed = parse_repeating_slot(rammetid_slot) if BaseApplicationResource.is_conflict_rammetid(resource, rammetid_slot_parsed.start_date, rammetid_slot_parsed.end_date, rammetid_slot_parsed.week_day, rammetid_slot_parsed.start_time, rammetid_slot_parsed.end_time): abort( 400, __error__=[u'Tiden er ikke tilgjengelig'] ) if BaseApplicationResource.is_conflict_blocked_time(resource, rammetid_slot_parsed.start_date, rammetid_slot_parsed.end_date, rammetid_slot_parsed.week_day, rammetid_slot_parsed.start_time, rammetid_slot_parsed.end_time): abort( 400, __error__=[u'Tiden er blokkert'] ) rammetid.add_rammetid_slot(rammetid_slot_parsed) current_app.db_session.add(rammetid) current_app.db_session.commit() current_app.db_session.refresh(rammetid) return marshal(rammetid, rammetid_fields)
def post(self): data = request.get_json() resource_data = data.get("resource", None) if resource_data: resource_uri = resource_data["uri"] resource = get_resource_for_uri(resource_uri) if not resource: abort(403, __error__=[u'Ressursen ble ikke funnet.']) else: abort(403, __error__=[u'Data om ressursen mangler.']) umbrella_organisation_data = data.get("umbrella_organisation", None) if umbrella_organisation_data: umbrella_organisation_uri = umbrella_organisation_data["uri"] umbrella_organisation = get_umbrella_organisation_for_uri(umbrella_organisation_uri) if not umbrella_organisation: abort(403, __error__=[u'Paraplyorganisasjonen ble ikke funnet.']) else: abort(403, __error__=[u'Data om paraplyorganisasjonen mangler.']) rammetid = Rammetid(umbrella_organisation, resource) rammetid_slots_data = data.get("rammetid_slots", None) if rammetid_slots_data: for rammetid_slot in rammetid_slots_data: rammetid_slot_parsed = parse_repeating_slot(rammetid_slot) if BaseApplicationResource.is_conflict_rammetid(resource, rammetid_slot_parsed.start_date, rammetid_slot_parsed.end_date, rammetid_slot_parsed.week_day, rammetid_slot_parsed.start_time, rammetid_slot_parsed.end_time): abort( 400, __error__=[u'Tiden er ikke tilgjengelig'] ) if BaseApplicationResource.is_conflict_blocked_time(resource, rammetid_slot_parsed.start_date, rammetid_slot_parsed.end_date, rammetid_slot_parsed.week_day, rammetid_slot_parsed.start_time, rammetid_slot_parsed.end_time): abort( 400, __error__=[u'Tiden er blokkert'] ) rammetid.add_rammetid_slot(rammetid_slot_parsed) current_app.db_session.add(rammetid) current_app.db_session.commit() current_app.db_session.refresh(rammetid) return marshal(rammetid, rammetid_fields), 201
def post(self): data = request.get_json() is_arrangement = data.get("isArrangement", False) person = data.get('person', None) if not person or not person.get('uri', None): abort(400) person_uri = person["uri"] text = data["text"] facilitation = data["facilitation"] resource_uri = data["resource"]["uri"] resource = get_resource_for_uri(resource_uri) settings = SettingsResource().get() user = get_user(request.cookies) # Check that the resource allows the type of application if not settings["single_booking_allowed"] and not (has_role(user, 'flod_brukere') or has_role(user, 'flod_saksbehandlere')) or \ not resource.single_booking_allowed: abort(403, __error__=[u'Engangslån ikke tillatt']) organisation_data = data.get("organisation", None) if organisation_data: organisation_uri = organisation_data["uri"] organisation = get_organisation_for_uri(organisation_uri) else: organisation = None person = get_person_for_uri(person_uri) application = Application( person, organisation, text, facilitation, resource, amenities=data.get('amenities'), accessibility=data.get('accessibility'), equipment=data.get('equipment'), suitability=data.get('suitability'), facilitators=data.get('facilitators') ) application.is_arrangement = is_arrangement slots = [self.parse_slot_request(d) for d in data["slots"]] if not slots: abort(400, __error__=[u'Tidspunkt mangler']) for slot in slots: start_date = slot.start_time.date() end_date = slot.end_time.date() week_day = slot.start_time.isoweekday() start_time = slot.start_time.time() end_time = slot.end_time.time() self.validate_end_date_of_slot(settings["single_booking_enddate"], end_date.isoformat(), u'engangslån') self.validate_start_and_end_times(start_date, end_date, start_time, end_time) if not is_arrangement: if self.is_conflict_slot_time(resource, start_date, end_date, week_day, start_time, end_time) or \ self.is_conflict_rammetid(resource, start_date, end_date, week_day, start_time, end_time): abort( 400, __error__=[u'Tiden du har søkt på er ikke tilgjengelig'] ) if self.is_conflict_blocked_time(resource, start_date, end_date, week_day, start_time, end_time): abort( 400, __error__=[u'Tiden du har søkt på er blokkert'] ) application.request_single_slot(slot) current_app.db_session.add(application) current_app.db_session.commit() current_app.db_session.refresh(application) send_email_to_resource(application) send_email_to_applicant(application) return application, 201
def put(self, application_id): data = request.get_json() application = self.get_object_by_id(application_id) ensure(PUT, application) status = data.get("status", None) resource_uri = data["resource"]["uri"] application_message = data.get("message", "") to_be_invoiced = data.get("to_be_invoiced", None) invoice_amount = data.get("invoice_amount") or None if invoice_amount is not None and type(invoice_amount) is not int \ and not invoice_amount.isdigit(): abort(400, __error__=[u'Fakturabeløp må være heltall']) resource = get_resource_for_uri(resource_uri) if not resource: abort(404) resource_details = get_resource_from_web(application.resource.uri) if not resource_details: abort(404) settings = SettingsResource().get() user = get_user(request.cookies) # Check that the resource allows the type of application if application.get_type() == "single" and not resource.single_booking_allowed: abort(403, __error__=[u'Det er ikke mulig å behandle en søknad om engangslån fordi type utlån er deaktivert for lokalet']) if application.get_type() == "repeating" and (not resource.repeating_booking_allowed or \ (resource.repeating_booking_allowed and not settings["repeating_booking_allowed"] and not has_role(user, 'flod_saksbehandlere'))): abort(403, __error__=[u'Det er ikke mulig å behandle en søknad om fast lån fordi type utlån er deaktivert for lokalet']) # The application might have been moved to a different resource. application.resource = resource if status == "Pending": application.amenities = application.requested_amenities application.accessibility = application.requested_accessibility application.equipment = application.requested_equipment application.suitability = application.requested_suitability application.facilitators = application.requested_facilitators else: application.amenities = data.get('amenities') application.accessibility = data.get('accessibility') application.equipment = data.get('equipment') application.suitability = data.get('suitability') application.facilitators = data.get('facilitators') slot_data = data.get("slots", None) if status == "Granted" and not slot_data: abort(403, __error__=[u'Tildelt tid mangler']) if application.get_type() == "single": slots = [parse_single_slot(slot, application) for slot in slot_data] application.single_slots = slots elif application.get_type() == "repeating": slots = [parse_repeating_slot(slot, application) for slot in slot_data] application.repeating_slots = slots # Check if there are any conflicts for slot in slots: if application.get_type() == "single": start_date = slot.start_time.date() end_date = slot.end_time.date() week_day = slot.start_time.isoweekday() start_time = slot.start_time.time() end_time = slot.end_time.time() elif application.get_type() == "repeating": start_date = slot.start_date end_date = slot.end_date week_day = slot.week_day start_time = slot.start_time end_time = slot.end_time if application.get_type() == "single": self.validate_end_date_of_slot(settings["single_booking_enddate"], end_date.isoformat(), u'engangslån') elif application.get_type() == "repeating": self.validate_end_date_of_slot(settings["repeating_booking_enddate"], end_date.isoformat(), u'fast lån') self.validate_start_and_end_times(start_date, end_date, start_time, end_time) if application.is_arrangement or status == "Denied": # NOTE: Arrangements trumph all other applications. If we reject an application, we dont nede to # check if the time is available... pass else: if self.is_conflict_slot_time(resource, start_date, end_date, week_day, start_time, end_time) or \ self.is_conflict_rammetid(resource, start_date, end_date, week_day, start_time, end_time): abort( 400, __error__=[u'Tiden du har søkt på er ikke tilgjengelig'] ) if status != "Denied": if self.is_conflict_blocked_time(resource, start_date, end_date, week_day, start_time, end_time): abort( 400, __error__=[u'Tiden du har søkt på er blokkert'] ) if status == "Granted" or status == "Denied" or (status == "Pending" and len(slots) == 0): application.status = status else: application.status = "Processing" application.message = application_message application.invoice_amount = invoice_amount application.to_be_invoiced = to_be_invoiced application.comment = data.get('comment') current_app.db_session.add(application) current_app.db_session.commit() current_app.db_session.refresh(application) document = '' if status == "Granted" or status == "Denied": document = send_email_application_processed(application) # Create erv code if invoice_amount is not None and status == "Granted": invoice_amount = int(invoice_amount) org_number = None if application.organisation is not None: organisation = get_organisation_from_web( application.organisation.uri) org_number = organisation.get('org_number', None) if org_number is None: person = get_person_from_web(application.person.uri) erv_code = erv_person(application, invoice_amount, person['national_identity_number']) else: erv_code = erv_organisation(application, invoice_amount, org_number) print 'erv: "{}"'.format(erv_code) # Skip sending mail for now # send_erv_code_mail("{},".format(erv_code)) application_dict = {} if application.get_type() == "single": application_dict = marshal(application, single_application_fields) elif application.get_type() == "repeating": # Authentication is not implemented for all resources yet, so we # skip creating sak/journalpost if no auth_token exists if status == 'Granted' and 'auth_token' in request.cookies: arkiver(application, document) application_dict = marshal(application, repeating_application_fields) # Include emails in response, if requested if data.get("include_emails", False): _, granted_message = render_email_template(application, "Granted") _, denied_message = render_email_template(application, "Denied") application_dict['emails'] = dict( granted_message=granted_message, denied_message=denied_message ) return application_dict
def post(self): data = request.get_json() rammetid_to_application = RammetidToApplication(data.get('umbrella_organisation').get('uri')) ensure(POST, rammetid_to_application) resource = data.get("resource", None) if not resource: abort(403, __error__=[u'Ressurs er ikke angitt.']) resource = get_resource_for_uri(resource['uri']) if not resource: abort(404, __error__=[u'Ressursen finnes ikke.']) if not resource.repeating_booking_allowed: abort(403, __error__=[u'Gjentakende lån ikke tillatt']) user = get_user(request.cookies) person_uri = '/persons/{}'.format(user['person_id']) person = get_person_for_uri(person_uri) if not person: abort(404, __error__=[u'Personen finnes ikke.']) # get umbrella member orgs from organisations backend umbrella_member_organisations = get_umbrella_organisation_from_web(data.get('umbrella_organisation').get('uri')).get('organisations', []) # get local umbrella organisation object umbrella_organisation = get_umbrella_organisation_for_uri(data.get('umbrella_organisation').get('uri')) text = "Rammetid fordeling" applications = [] organisations = data.get('organisations', None) for organisation in organisations: organisation_data = organisations[organisation] # have to be superuser if the organisation is not public and not copied to booking already organisation = get_organisation_for_uri(organisation_data['uri'], cookies=make_superuser_auth_cookie()) if not organisation: abort(404, __error__=[u'Organisasjonen finnes ikke.']) if not any(org.get('uri') == organisation_data['uri'] for org in umbrella_member_organisations): abort(403, __error__=[u'Organisasjonen hører ikke til paraplyorganisasjonen']) application = Application(person, organisation, text, None, resource) application.status = 'Granted' slots = organisation_data["slots"] for slot_data in slots: slot = self.parse_slot(slot_data, application) slot_request = self.parse_slot_request(slot_data) start_date = slot.start_date end_date = slot.end_date week_day = slot.week_day start_time = slot.start_time end_time = slot.end_time self.validate_start_and_end_times(start_date, end_date, start_time, end_time) if not self.has_matching_rammetid(umbrella_organisation.id, start_date, end_date, week_day, start_time, end_time): abort(400, __error__=[u'Ingen rammetid passer']) if self.is_conflict_slot_time(resource, start_date, end_date, week_day, start_time, end_time): abort(400, __error__=[u'Tiden du har søkt på er ikke tilgjengelig']) if self.is_conflict_blocked_time(resource, start_date, end_date, week_day, start_time, end_time): abort(400, __error__=[u'Tiden du har søkt på er blokkert']) application.request_repeating_slot(slot_request) application.add_repeating_slot(slot) applications.append(application) for application in applications: current_app.db_session.add(application) current_app.db_session.commit() current_app.db_session.refresh(application) return applications, 201
def get_resource_statistic(facility_id, start_date, end_date): resource_uri = "/facilities/%s" % facility_id resource = get_resource_for_uri(resource_uri) resource_details = get_resource_from_web(resource_uri) resource_area = resource_details['area'] statuses = ["Granted"] resource_id = resource.id single_booking = current_app.db_session.query(Organisation.uri.label("organisation_uri"), func.sum(Slot.end_time - Slot.start_time).label("time")) \ .outerjoin(Application.organisation) \ .filter(Application.resource_id == resource_id, Slot.application_id == Application.id, Application.to_be_invoiced != True, # != True to include both False and None Application.status.in_(statuses), # Get all slots between start and end date cast(Slot.start_time, Date).between(start_date, end_date), cast(Slot.end_time, Date).between(start_date, end_date), ) \ .group_by(Organisation.uri) strotime_booking = current_app.db_session.query(Organisation.uri.label("organisation_uri"), func.sum(StrotimeSlot.end_time - StrotimeSlot.start_time).label("time")) \ .outerjoin(Application.organisation) \ .filter(Application.resource_id == resource_id, StrotimeSlot.application_id == Application.id, Application.to_be_invoiced != True, # != True to include both False and None Application.status.in_(statuses), # Get all slots between start and end date cast(StrotimeSlot.start_time, Date).between(start_date, end_date), cast(StrotimeSlot.end_time, Date).between(start_date, end_date), ) \ .group_by(Organisation.uri) repeating_booking = current_app.db_session.query(Organisation.uri.label("organisation_uri"), RepeatingSlot.start_date, RepeatingSlot.end_date, RepeatingSlot.start_time, RepeatingSlot.end_time, RepeatingSlot.week_day) \ .outerjoin(Application.organisation) \ .filter(Application.resource_id == resource_id, RepeatingSlot.application_id == Application.id, Application.to_be_invoiced != True, # != True to include both False and None Application.status.in_(statuses), # Get all slots between start and end date cast(RepeatingSlot.start_date, Date) <= end_date, cast(RepeatingSlot.end_date, Date) >= start_date, ) results = [] for single in single_booking.all(): add_hours(results, single, resource_area) for strotime in strotime_booking.all(): add_hours(results, strotime, resource_area) for repeating in repeating_booking.all(): start = repeating.start_date if start < start_date: start = start_date end = repeating.end_date if end > end_date: end = end_date weeks = (end - start).days / 7 starthours = datetime.combine(date.min, repeating.start_time) endhours = datetime.combine(date.min, repeating.end_time) hours = (endhours - starthours).total_seconds() / 3600.0 total_hours = hours * weeks if ((end == start and start.isoweekday() == repeating.week_day) # exact day or ((end - start).days % 7 != 0 # remaining week # repeating weekday after start and before end. I.E start is tuesday, repeating is wednesday, end is friday and ((start.isoweekday() <= repeating.week_day <= end.isoweekday()) # repeating weekday before start and before end, and start is after end. I.E start is friday, repeating is tuesday and end is wednesday or (end.isoweekday() <= start.isoweekday() >= repeating.week_day <= end.isoweekday())))): total_hours += hours if total_hours > 0: item = find_organisation(results, repeating.organisation_uri) item['hours'] += total_hours item['area_time'] += total_hours * resource_area return marshal(results, resource_statistic_fields)
def post(self): data = request.get_json() person = data.get('person', None) if not person or not person.get('uri', None): abort(400) person_uri = person["uri"] text = data["text"] facilitation = data['facilitation'] resource_uri = data["resource"]["uri"] resource = get_resource_for_uri(resource_uri) settings = SettingsResource().get() user = get_user(request.cookies) # Check that the resource allows the type of application if (resource.repeating_booking_allowed and not settings["repeating_booking_allowed"] and not has_role(user, 'flod_saksbehandlere')) or \ (not settings["repeating_booking_allowed"] and not (has_role(user, 'flod_brukere') or has_role(user, 'flod_saksbehandlere'))) or \ not resource.repeating_booking_allowed: abort(403, __error__=[u'Gjentakende lån ikke tillatt']) organisation_data = data.get("organisation", None) if organisation_data: organisation_uri = organisation_data["uri"] organisation = get_organisation_for_uri(organisation_uri) else: organisation = None if not organisation: abort( 403, __error__=[u'Du kan ikke søke gjentakende lån som privatperson'] ) person = get_person_for_uri(person_uri) application = Application( person, organisation, text, facilitation, resource, amenities=data.get('amenities'), accessibility=data.get('accessibility'), equipment=data.get('equipment'), suitability=data.get('suitability'), facilitators=data.get('facilitators') ) slots = None try: slots = [self.parse_slot_request(d) for d in data["slots"]] except BookingDomainException as e: abort(400, __error__=[e.message]) if not slots: abort(400, __error__=[u'Tidspunkt mangler']) for slot in slots: start_date = slot.start_date end_date = slot.end_date week_day = slot.week_day start_time = slot.start_time end_time = slot.end_time self.validate_end_date_of_slot(settings["repeating_booking_enddate"], end_date.isoformat(), u'fast lån') self.validate_start_and_end_times(start_date, end_date, start_time, end_time) if self.is_conflict_slot_time(resource, start_date, end_date, week_day, start_time, end_time) or \ self.is_conflict_rammetid(resource, start_date, end_date, week_day, start_time, end_time): abort( 400, __error__=[u'Tiden du har søkt på er ikke tilgjengelig'] ) if self.is_conflict_blocked_time(resource, start_date, end_date, week_day, start_time, end_time): abort( 400, __error__=[u'Tiden du har søkt på er blokkert'] ) application.request_repeating_slot(slot) current_app.db_session.add(application) current_app.db_session.commit() current_app.db_session.refresh(application) send_email_to_resource(application) return application, 201