import csv
from datetime import date
from io import StringIO
from onegov.core.elements import Link
from onegov.core.security import Public, Private
from onegov.form import FieldDependency, WTFormsClassBuilder, move_fields
from onegov.org.views.files import view_get_image_collection
from onegov.winterthur import WinterthurApp, _
from onegov.winterthur.collections import MissionReportCollection
from onegov.winterthur.collections import MissionReportFileCollection
from onegov.winterthur.collections import MissionReportVehicleCollection
from onegov.winterthur.forms import MissionReportForm
from onegov.winterthur.forms import MissionReportVehicleForm
from onegov.winterthur.layout import MissionReportLayout
from onegov.winterthur.models import MissionReport
from onegov.winterthur.models import MissionReportVehicle
from onegov.winterthur.models import MissionReportVehicleUse
from uuid import UUID
from webob import Response
from wtforms.fields import BooleanField
from wtforms.fields import IntegerField
from wtforms.validators import NumberRange
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from webob import Response
from onegov.core.types import JSON_ro, RenderData
from onegov.winterthur.request import WinterthurRequest
@WinterthurApp.html(
model=MissionReportCollection,
permission=Public,
template='mission_reports.pt'
)
[docs]
def view_mission_reports(
self: MissionReportCollection,
request: 'WinterthurRequest'
) -> 'RenderData':
return {
'layout': MissionReportLayout(self, request),
'title': _('Mission Reports'),
'reports': self.batch,
'count': self.mission_count(),
'year': self.year,
}
@WinterthurApp.html(
model=MissionReport,
permission=Public,
template='mission_report.pt'
)
[docs]
def view_mission(
self: MissionReport,
request: 'WinterthurRequest'
) -> 'RenderData':
return {
'title': self.title,
'layout': MissionReportLayout(
self, request,
Link(self.title, '#')
),
'model': self
}
@WinterthurApp.json(
model=MissionReportCollection,
name='json',
permission=Public
)
[docs]
def view_mission_reports_as_json(
self: MissionReportCollection,
request: 'WinterthurRequest'
) -> 'JSON_ro':
query = self.query()
if request.params.get('all', False):
query = self.query_all()
elif request.params.get('year'):
year_param = str(request.params['year'])
if year_param.isdigit():
self.year = int(year_param)
query = self.filter_by_year(self.query())
return {
'name': 'Mission Reports',
'report_count': query.count(),
'reports': [
{
'date': mission.local_date.strftime('%d-%m-%Y'),
'alarm': mission.local_date.strftime('%H:%M'),
'duration': mission.readable_duration,
'nature': mission.nature,
'mission_type': mission.mission_type,
'mission_count': mission.mission_count,
'vehicles': [
use.vehicle.name for use in mission.used_vehicles
for _ in range(use.count)
],
'vehicles_icons': [
request.link(use.vehicle.symbol)
if use.vehicle.symbol else ''
for use in mission.used_vehicles
for _ in range(use.count)
],
'location': mission.location,
'personnel_active': mission.personnel,
'personnel_backup': mission.backup,
'civil_defence_involved': mission.civil_defence,
} for mission in query
]
}
@WinterthurApp.view(
model=MissionReportCollection,
name='csv',
permission=Public
)
[docs]
def view_mission_reports_as_csv(
self: MissionReportCollection,
request: 'WinterthurRequest'
) -> Response:
query = self.query()
if request.params.get('all', False):
query = self.query_all()
elif request.params.get('year'):
year_param = str(request.params['year'])
if year_param.isdigit():
self.year = int(year_param)
query = self.filter_by_year(self.query())
output = StringIO()
writer = csv.writer(output)
# Write CSV header
writer.writerow([
'date', 'alarm', 'duration', 'nature', 'mission_type', 'mission_count',
'vehicles', 'vehicles_icons', 'location', 'personnel_active',
'personnel_backup', 'civil_defence_involved'
])
# Write CSV rows
for mission in query:
writer.writerow([
mission.local_date.strftime('%d-%m-%Y'),
mission.local_date.strftime('%H:%M'),
mission.readable_duration,
mission.nature,
mission.mission_type,
mission.mission_count,
', '.join([
use.vehicle.name for use in mission.used_vehicles for _ in
range(use.count)
]),
', '.join([
request.link(use.vehicle.symbol)
if use.vehicle.symbol else ''
for use in mission.used_vehicles for _ in range(use.count)
]),
mission.location,
mission.personnel,
mission.backup,
mission.civil_defence
])
response = Response(content_type='text/csv')
response.text = output.getvalue()
response.content_disposition = 'attachment; filename="mission_reports.csv"'
return response
@WinterthurApp.html(
model=MissionReportVehicleCollection,
permission=Private,
template='mission_report_vehicles.pt'
)
[docs]
def view_mission_report_vehicles(
self: MissionReportVehicleCollection,
request: 'WinterthurRequest'
) -> 'RenderData':
return {
'layout': MissionReportLayout(
self, request,
Link(_('Vehicles'), request.link(self))
),
'title': _('Vehicles'),
'vehicles': tuple(self.query()),
}
@WinterthurApp.html(
model=MissionReportFileCollection,
template='images.pt',
permission=Private
)
[docs]
def view_mission_report_files(
self: MissionReportFileCollection,
request: 'WinterthurRequest'
) -> 'RenderData':
data = view_get_image_collection(self, request)
data['layout'] = MissionReportLayout(
self, request,
Link(self.report.title, request.link(self.report)),
Link(_('Images'), '#', editbar=False)
)
return data
@WinterthurApp.form(
model=MissionReportCollection,
permission=Private,
form=mission_report_form,
name='new',
template='form.pt'
)
[docs]
def handle_new_mission_report(
self: MissionReportCollection,
request: 'WinterthurRequest',
form: MissionReportForm
) -> 'RenderData | Response':
if form.submitted(request):
mission = self.add(date=form.date, **{
k: v for k, v in form.data.items()
if k not in ('csrf_token', 'day', 'time')
and not k.startswith('vehicles_')
})
form.populate_obj(mission)
if mission.date.year != date.today().year:
request.warning(
_(
'The report was entered in the current year, '
'please verify the date'
))
else:
request.success(_('Successfully added a mission report'))
return request.redirect(request.link(mission))
return {
'title': _('Mission Reports'),
'form': form,
'layout': MissionReportLayout(
self, request,
Link(_('New'), '#', editbar=False)
),
}
@WinterthurApp.form(
model=MissionReport,
permission=Private,
form=mission_report_form,
name='edit',
template='form.pt'
)
[docs]
def handle_edit_mission_report(
self: MissionReport,
request: 'WinterthurRequest',
form: MissionReportForm
) -> 'RenderData | Response':
if form.submitted(request):
form.populate_obj(self)
self.date = form.date
request.success(_('Your changes were saved'))
return request.redirect(request.link(self))
elif not request.POST:
form.process(obj=self)
form.date = self.date
return {
'title': _('Mission Reports'),
'form': form,
'layout': MissionReportLayout(
self, request,
Link(self.title, request.link(self)),
Link(_('Edit'), '#', editbar=False),
)
}
@WinterthurApp.view(
model=MissionReport,
permission=Private,
request_method='DELETE'
)
[docs]
def delete_mission_report(
self: MissionReport,
request: 'WinterthurRequest'
) -> None:
request.assert_valid_csrf_token()
request.session.delete(self)
request.success(_('Successfully deleted mission report'))
@WinterthurApp.form(
model=MissionReportVehicleCollection,
permission=Private,
form=mission_report_vehicle_form,
name='new',
template='form.pt'
)
[docs]
def handle_new_vehicle(
self: MissionReportVehicleCollection,
request: 'WinterthurRequest',
form: MissionReportVehicleForm
) -> 'RenderData | Response':
if form.submitted(request):
vehicle = self.add(
**{k: v for k, v in form.data.items() if k not in (
'csrf_token', 'symbol'
)})
# required for the symbol image
form.populate_obj(vehicle)
request.success(_('Successfully added a vehicle'))
return request.redirect(
request.class_link(MissionReportVehicleCollection))
return {
'title': _('Vehicle'),
'form': form,
'layout': MissionReportLayout(
self, request,
Link(_('Vehicles'), request.link(self)),
Link(_('New'), '#', editbar=False)
),
}
@WinterthurApp.form(
model=MissionReportVehicle,
permission=Private,
form=mission_report_vehicle_form,
name='edit',
template='form.pt'
)
[docs]
def handle_edit_vehicle(
self: MissionReportVehicle,
request: 'WinterthurRequest',
form: MissionReportVehicleForm
) -> 'RenderData | Response':
if form.submitted(request):
form.populate_obj(self)
request.success(_('Your changes were saved'))
return request.redirect(
request.class_link(MissionReportVehicleCollection))
elif not request.POST:
form.process(obj=self)
return {
'title': self.title,
'form': form,
'layout': MissionReportLayout(
self, request,
Link(_('Vehicles'), request.class_link(
MissionReportVehicleCollection)),
Link(self.title, '#')
)
}
@WinterthurApp.view(
model=MissionReportVehicle,
permission=Private,
request_method='DELETE'
)
[docs]
def delete_mission_report_vehicle(
self: MissionReportVehicle,
request: 'WinterthurRequest'
) -> None:
request.assert_valid_csrf_token()
request.session.delete(self)
request.success(_('Successfully deleted vehicle'))