Skip to content

Commit

Permalink
feat: add reason/note for ticket resolve (#114)
Browse files Browse the repository at this point in the history
* feat: add reason/note for ticket resolve

* feat: add reason/note for ticket resolve
  • Loading branch information
kennedykori committed Aug 23, 2021
1 parent 73a68ba commit 1f169ff
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 33 deletions.
25 changes: 24 additions & 1 deletion fahari/ops/forms.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from django.forms.widgets import DateTimeInput, Select, TextInput
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from django import forms
from django.forms.widgets import DateTimeInput, Select, Textarea, TextInput

from fahari.common.dashboard import get_fahari_facilities_queryset
from fahari.common.forms import BaseModelForm
Expand Down Expand Up @@ -75,9 +78,29 @@ class Meta(BaseModelForm.Meta):
"disabled": True,
}
),
"resolve_note": Textarea(
attrs={
"disabled": True,
}
),
}


class FacilitySystemTicketResolveForm(forms.Form):
resolve_note = forms.CharField(
label="Resolve Comments/Notes", required=False, widget=forms.Textarea
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.form_method = "post"
self.helper.form_action = ""
self.helper.add_input(Submit("submit", "Resolve"))
self.helper.html5_required = True
self.helper.form_id = "facility_system_ticket_resolve_form"


class StockReceiptVerificationForm(BaseModelForm):
field_order = (
"facility",
Expand Down
18 changes: 18 additions & 0 deletions fahari/ops/migrations/0018_facilitysystemticket_resolve_note.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.6 on 2021-08-20 11:10

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('ops', '0017_weeklyprogramupdate_notes'),
]

operations = [
migrations.AddField(
model_name='facilitysystemticket',
name='resolve_note',
field=models.TextField(blank=True, null=True),
),
]
1 change: 1 addition & 0 deletions fahari/ops/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ class FacilitySystemTicket(AbstractBase):
raised_by = models.TextField()
resolved = models.DateTimeField(null=True, blank=True)
resolved_by = models.TextField(null=True, blank=True)
resolve_note = models.TextField(null=True, blank=True)

model_validators = ["validate_resolved"]

Expand Down
37 changes: 26 additions & 11 deletions fahari/ops/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from fahari.ops.views import (
CommoditiesListView,
FacilitySystemsView,
FacilitySystemTicketResolveView,
FacilitySystemTicketsView,
TimeSheetApproveView,
)
Expand Down Expand Up @@ -106,23 +105,39 @@ def test_timesheet_approve_view_error_case(request_with_user):
assert resp.status_code == 200 # page re-rendered with an error


def test_ticket_resolve_view_happy_case(request_with_user):
assert request_with_user.user is not None
def test_ticket_resolve_view_get(user_with_all_permissions, client):
client.force_login(user_with_all_permissions)
open_ticket = baker.make(FacilitySystemTicket, resolved=None, resolved_by=None)
view = FacilitySystemTicketResolveView()
resp = view.post(request_with_user, pk=open_ticket.pk)
assert resp.status_code == 302
url = reverse("ops:ticket_resolve", args=[open_ticket.pk])
response = client.get(url, format="json")
assert response.status_code == 200


def test_ticket_resolve_view_post(user_with_all_permissions, client):
client.force_login(user_with_all_permissions)
open_ticket = baker.make(FacilitySystemTicket, resolved=None, resolved_by=None)
url = reverse("ops:ticket_resolve", args=[open_ticket.pk])
response = client.post(url, None, format="json")
assert response.status_code == 302

open_ticket.refresh_from_db()
assert open_ticket.resolved is not None
assert open_ticket.resolved_by is not None
assert open_ticket.resolve_note == ""


def test_ticket_resolve_view_error_case(request_with_user):
fake_pk = uuid.uuid4()
view = FacilitySystemTicketResolveView()
resp = view.post(request_with_user, pk=fake_pk)
assert resp.status_code == 200 # page re-rendered with an error
def test_ticket_resolve_view_post_with_note(user_with_all_permissions, client):
client.force_login(user_with_all_permissions)
open_ticket = baker.make(FacilitySystemTicket, resolved=None, resolved_by=None)
url = reverse("ops:ticket_resolve", args=[open_ticket.pk])
data = {"resolve_note": "All issues solved ..."}
response = client.post(url, data, format="json")
assert response.status_code == 302

open_ticket.refresh_from_db()
assert open_ticket.resolved is not None
assert open_ticket.resolved_by is not None
assert open_ticket.resolve_note == data["resolve_note"]


def test_commodities_context_data():
Expand Down
41 changes: 30 additions & 11 deletions fahari/ops/views.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
from typing import cast

from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import ValidationError
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse_lazy
from django.utils import timezone
from django.views.generic import CreateView, DeleteView, TemplateView, UpdateView
from django.views.generic.detail import SingleObjectMixin, SingleObjectTemplateResponseMixin
from django.views.generic.edit import FormMixin, ProcessFormView

from fahari.common.views import ApprovedMixin, BaseFormMixin, BaseView

Expand All @@ -25,6 +29,7 @@
DailyUpdateForm,
FacilitySystemForm,
FacilitySystemTicketForm,
FacilitySystemTicketResolveForm,
SiteMentorshipForm,
StockReceiptVerificationForm,
TimeSheetForm,
Expand Down Expand Up @@ -140,21 +145,35 @@ class FacilitySystemTicketDeleteView(FacilitySystemTicketContextMixin, DeleteVie

class FacilitySystemTicketResolveView(
FacilitySystemTicketContextMixin,
TemplateView,
ProcessFormView,
FormMixin,
SingleObjectMixin,
SingleObjectTemplateResponseMixin,
):
form_class = FacilitySystemTicketResolveForm
model = FacilitySystemTicket
template_name = "ops/ticket_resolve.html"
success_url = reverse_lazy("ops:tickets")

def post(self, request, *args, **kwargs):
try:
pk = kwargs["pk"]
ticket = FacilitySystemTicket.objects.get(pk=pk)
ticket.resolved_by = str(request.user)
ticket.resolved = timezone.now()
ticket.save()
return HttpResponseRedirect(self.success_url)
except (FacilitySystemTicket.DoesNotExist, ValidationError, KeyError) as e:
return render(request, self.template_name, {"errors": [e]})
def form_valid(self, form):
ticket: FacilitySystemTicket = cast(FacilitySystemTicket, self.get_object())
ticket.resolved_by = str(self.request.user)
ticket.resolved = timezone.now()
ticket.resolve_note = form.cleaned_data["resolve_note"]
ticket.save()
return super().form_valid(form)

def get(self, request, *args, **kwargs):
# noinspection PyAttributeOutsideInit
self.object = self.get_object()
context = self.get_context_data(object=self.object)
return self.render_to_response(context)

def get_initial(self):
initial = super().get_initial()
ticket: FacilitySystemTicket = cast(FacilitySystemTicket, self.get_object())
initial.update({"resolve_note": ticket.resolve_note})
return initial


class FacilitySystemTicketViewSet(BaseView):
Expand Down
4 changes: 2 additions & 2 deletions fahari/static/js/vendors.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions fahari/static/js/vendors.min.js

Large diffs are not rendered by default.

8 changes: 2 additions & 6 deletions fahari/templates/ops/ticket_resolve.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Resolve Ticket
{% endblock title %}
{% block content %}
<a href="{% url 'ops:tickets' %}">&larr; Back</a>
<a href="{% url 'ops:ticket_update' object.pk %}">&larr; Back</a>
{% if errors %}
<div class="alert alert-error">
<ul>
Expand All @@ -27,11 +27,7 @@
<div class="text-left">
<h1 class="h4 text-gray-900 mb-4">Confirm Resolve</h1>
</div>
<form method="post">
{% csrf_token %}
<p>Are you sure you want to resolve this ticket?</p>
<input class="btn btn-outline-primary btn-lg" type="submit" value="Resolve">
</form>
{% crispy form %}
</div>
</div>
</div>
Expand Down

0 comments on commit 1f169ff

Please sign in to comment.