def render_email_template(application, status=None):
    resource_details = get_resource_from_web(application.resource.uri)
    requested_resource_details = get_resource_from_web(
        application.requested_resource.uri)
    org_name = None
    org_email = None
    org_local_email = None
    if application.organisation is not None:
        org_details = get_organisation_from_web(application.organisation.uri)
        org_name = org_details.get('name')
        org_email = org_details.get('email_address', None)
        org_local_email = org_details.get('local_email_address', None)

    email_address = None
    if application.person is not None:
        person_details = get_person_from_web(application.person.uri)
        email_address = person_details.get("email_address", None)

    resource_name = resource_details['name']
    requested_resource_name = requested_resource_details['name']
    application_time = application.application_time.strftime("%Y.%m.%d %H:%M")

    # Override status if given, used for previewing template
    if status is not None:
        application_status = format_application_status_for_email(status)
    else:
        application_status = format_application_status_for_email(
            application.status)

    application_type = application.get_type()
    requested_slots = format_slots_for_email(application.requested_slots,
                                             application_type)
    slots = format_slots_for_email(application.slots, application_type)

    requested_period = get_period_from_slots(application.requested_slots, application_type)
    period = get_period_from_slots(application.slots, application_type)

    changed_period = not is_period_equal(period, requested_period)
    changed_time = not is_slots_equal(slots, requested_slots) or changed_period;

    resource_documents = resource_details.get("documents", [])

    message = render_template("email_applications_processed.txt",
                              org_name=org_name,
                              resource_name=resource_name,
                              requested_resource_name=requested_resource_name,
                              application_time=application_time,
                              message=application.message,
                              application_status=application_status,
                              resource_documents=resource_documents,
                              slots=slots,
                              requested_slots=requested_slots,
                              changed_period=changed_period,
                              changed_time=changed_time,
                              period=period,
                              requested_period=requested_period)

    return [email_address, org_email, org_local_email], message
def get_facilities_from_web(facilities):
    resources = []
    for facility_id in facilities:
        resource_uri = "/facilities/%s?show_not_published=True" % facility_id
        resource = get_resource_from_web(resource_uri)
        resources.append(resource)
    return resources
def send_email_to_applicant(application):

    person_data = get_person_from_web(application.person.uri)
    resource_data = get_resource_from_web(application.resource.uri)

    person_email = person_data.get('email_address')
    resource_name = resource_data.get('name', None)

    message = None
    topic = None

    if application.type == 'single':
        topic = u'Søknad om engangslån'
        message = render_template(
            'email_application_created.txt',
            resource_name=resource_name
        )

    if application.type == 'repeating':
        topic = u'Søknad om fast lån'
        message = render_template(
            'email_application_created.txt',
            resource_name=resource_name
        )

    if not person_email or not topic or not message:
        return

    send_email_task.delay(
        topic,
        u'*****@*****.**',
        [person_email],
        message
    )
def send_email_to_resource(application):

    person_data = get_person_from_web(application.person.uri)
    resource_data = get_resource_from_web(application.resource.uri)

    person_name = get_person_name(person_data)
    resource_name = resource_data.get('name', None)
    slots = generate_slots(application)

    unit_email = resource_data.get('unit_email_address', None)
    unit_name = resource_data.get('unit_name', 'Ukjent enhet')
    org_name = get_organisation_name(application)

    if application.type == 'strotime':
        to_email = unit_email
        topic = u'Strøtime tildelt'
        message = render_template(
            'email_strotime_granted_unit.txt',
            resource_name=resource_name,
            unit_name=unit_name,
            person_name=person_name,
            slots=slots
        )

    message = None
    topic = None
    to_email = None
    if application.type == 'single':
        to_email = unit_email
        topic = u'Søknad om engangslån for %s' % unit_name
        message = render_template(
            'email_single_applied_unit.txt',
            resource_name=resource_name,
            unit_name=unit_name,
            person_name=person_name,
            slots=slots,
            organisation_name=org_name
        )

    if application.type == 'repeating':
        to_email = TK_EMAIL
        topic = u'Søknad om fast lån for %s' % unit_name
        message = render_template(
            'email_repeating_applied_unit.txt',
            resource_name=resource_name,
            unit_name=unit_name,
            person_name=person_name,
            slots=slots,
            organisation_name=org_name
        )

    if not to_email or not topic or not message:
        return

    send_email_task.delay(
        topic,
        u'*****@*****.**',
        [to_email],
        message
    )
def send_email_strotime_granted(application):
    personJSON = get_person_from_web(application.person.uri)
    resourceJSON = get_resource_from_web(application.resource.uri)
    person_name = ""
    if personJSON["first_name"] and personJSON["last_name"]:
        person_name = personJSON["first_name"] + " " + personJSON["last_name"]
    if personJSON["email_address"]:
        application_status = format_application_status_for_email(application.status)

        resource_name = ""
        if resourceJSON["name"]:
            resource_name = resourceJSON["name"]

        slots = []
        for slot in application.slots:
            slots.append(format_slot_for_email(slot))
        message = render_template(
            "email_strotime_granted.txt",
            resource_name=resource_name,
            application_status=application_status,
            slots=slots,
            person_name=person_name,
        )
        resource_email = personJSON["email_address"]
        if message is not None and resource_email is not None:
            send_email_task.delay(u"Strøtime tildelt", u"*****@*****.**", [resource_email], message)
Beispiel #6
0
def if_resource_owner(resource, user):
    if not has_role(user, 'flod_brukere'):
        return False
    # Check if resource is actually a model with a resource property
    # (e.g. Application)
    if hasattr(resource, 'resource'):
        resource = resource.resource

    resource_details = get_resource_from_web(resource.uri)

    resource_id = resource_details.get('id')
    if resource_id is None:
        return False
    return can_user_edit_facility(user['id'], resource_id, request.cookies)
    def send_email_to_affected_applications(self, arrangement,
                                            affected_applications,
                                            message):
        arrangement_slots = []
        for arrangement_slot in arrangement.slots:
            arrangement_slots.append(format_slot_for_email(arrangement_slot))

        for affected_application in affected_applications:
            if affected_application.slots:
                resource_details = get_resource_from_web(affected_application.resource.uri)
                resource_name = resource_details['name']

                person_details = get_person_from_web(affected_application.person.uri)
                email_address = person_details['email_address']

                org_name = None
                if affected_application.organisation is not None:
                    org_details = get_organisation_from_web(affected_application.organisation.uri)
                    org_name = org_details.get('name')

                application_time = affected_application.application_time.strftime("%Y.%m.%d %H:%M:00")

                slots = []
                # Just create human readable text out of slots
                for slot in affected_application.slots:
                    if affected_application.get_type() == "repeating":
                        slots.append(format_repeating_slot_for_email(slot))
                    else:
                        slots.append(format_slot_for_email(slot))

                msg = render_template("email_arrangement_notification.txt",
                                      org_name=org_name,
                                      resource_name=resource_name,
                                      application_time=application_time,
                                      slots=slots,
                                      arrangement_slots=arrangement_slots,
                                      message=message)

                if email_address and msg is not None:
                    send_email_task.delay(u'Arrangement',
                                          u'*****@*****.**',
                                          [email_address],
                                           msg)
def arkiver(application, document):
    resource_details = get_resource_from_web(application.resource.uri)
    if not resource_details:
        abort(404, __error__=[u'Application resource not found'])
    arkiv_client = ArkivDBClient(current_app)

    fesak_sak = current_app.db_session.query(FesakSak).filter(
        FesakSak.application_id == application.id).first()
    if fesak_sak is None:
        ws_sak_model = create_ws_sak(application, resource_details)
        ws_sak = ws_sak_model.build()
        arkiv_client.ny_sak(application.id, ws_sak_model)
    else:
        # If fesak_sak already exists for application, use it
        # Happens when application is processed multiple times
        ws_sak = json.loads(fesak_sak.ws_sak)

    ws_journalpost = create_ws_journalpost(application, resource_details,
                                           document, ws_sak)
    arkiv_client.ny_journalpost(application.id, ws_journalpost)
 def post(self):
     data = request.get_json()        
     start_time = data["start_time"]
     end_time = data["end_time"]             
     if start_time is None or end_time is None:
         abort(400)
     strotime_slots = self.get_strotime_slots(start_time, end_time)
     result = []
     for strotime_slot in strotime_slots:            
         personJSON = get_person_from_web(strotime_slot.application.person.uri)                                            
         resourceJSON = get_resource_from_web(strotime_slot.application.resource.uri)                                    
         result.append({             
             'id': strotime_slot.id,
             'start_time': strotime_slot.start_time,
             'end_time': strotime_slot.end_time,                
             'application_id': strotime_slot.application.id,
             'resource_name': resourceJSON['name'],
             'email_address': personJSON['email_address'],
             'person_name': personJSON['first_name'] + " " + personJSON['last_name']
         })
     return result, 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 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)