From ec4b2d1822f553f618936d0bdda6019f27482dfd Mon Sep 17 00:00:00 2001 From: Francesco Filicetti Date: Fri, 16 Oct 2020 10:15:47 +0200 Subject: [PATCH] ticket competence transfer refactor --- .coverage | Bin 53248 -> 53248 bytes organizational_area/admin.py | 8 ++- ...rganizationalstructureoffice_is_private.py | 18 +++++ organizational_area/models.py | 1 + tests/test_04_management.py | 6 +- uni_ticket/admin_actions.py | 14 ++-- uni_ticket/forms.py | 11 ++- uni_ticket/views/management.py | 63 ++++++++---------- .../management/add_ticket_competence.html | 18 ++--- .../templates/manager/office_detail.html | 12 ++++ .../templates/manager/offices_list.html | 9 +++ .../templates/operator/offices_list.html | 9 +++ 12 files changed, 110 insertions(+), 59 deletions(-) create mode 100644 organizational_area/migrations/0032_organizationalstructureoffice_is_private.py diff --git a/.coverage b/.coverage index 1239eb9c42ba8e021d7512636b5e3dca7876d496..e34678dec57c69bad12b1e6b8b9ba9e5bb7a28cd 100644 GIT binary patch delta 824 zcmW+zU1$_%6g^+2GA6n+Y7|m*v++ShL3cx{iJ8!C--3uMv=sHhpFHS;l*9^I>ze&W z7owszmAsfLCiq~$QVj$|yX?+FXnj#)3A9vFciVz%{F{kuoHaW;*Bd{$50~$rbM86U z98t^>W$b!bYmRJc-rCe0X>V?6-_kZd7XD^e<4x$h^|0QkJ=Gp-ceGntuVw@;2X-#q zTlZ_-&GF^S`s<{oeIjZbwSD(RPM$QM%TzG1NYwVX2j=B@bsJvK;_jSOa|ty^6Qw?^ z!L)y7GLANs-D)iVFKPJr3V`K|+8UgC=Me>QQtkAH^*EeF)<9Wig$6%G6|w>vtsVw$%*o>}nFnh7OO9bL-T zNOcW%UHDGEnyim3?x{iYa&lgSDV$$`!netWnm5HcukzmM2BMsSe65=yV27PY!4@zp zXo3^Xg#1>Hgx%B=9is~8g6-(YEDW)|q*P4fo^)IV=Up)R$bpFQjvrQtdfPY_e(DBr_IvfzI_VkXyg9E)AGpi2#?mj&5&h5T5EA4Rh e=R+;&@HLL4`9)j#4+Vml9)!FE!A}WG{3Zf+HQAud}S@&Ku^1*%# zUyO>CUW#54gw|zsXC%QMDg_^;GH0V;lW1o)w;bJ>Io+l6aN%&i?>pza9~%(ZfH3%M zw-jpF6{_8~r*>a$XkVydXmIzb<6B>Vd|D34ij(D41S6hK z`8uB?c1uv=VxdT2GdOg)8S25n_?*n!Onfd3h63r6C9NA8hni&YwSc%IhG9ECyfkg5 z1wge!;b?%il1IK!-=vO?aeZC}0sq=4SHVBrrSm+|4kLV$0LaJ>_g5dQ2iEFQ)eVEa zIGqqV+x}Y60L=U$WtKp+bF5^9-^87D@CA(C;9rR|-?*QNpI^ATKJVE==atnwj;@P+ zEqAX_WP2k}ky#0D$eRxXlo^Q?z!FOrR=thSELhn$Isq5BVp4?|KxmW-Ocw!i0^@fU zVvfnLLn0_Ekm4)>jZaCK*(Ki^T;?|El0x@NJ*din8PuE)c3 WkxR2Zt);}!e-lnS)T(~g8~F#Mn|i?j diff --git a/organizational_area/admin.py b/organizational_area/admin.py index 8c732ae7..b4d7c870 100644 --- a/organizational_area/admin.py +++ b/organizational_area/admin.py @@ -33,12 +33,14 @@ class OrganizationalStructureAdmin(AbstractAdmin): @admin.register(OrganizationalStructureOffice) class OrganizationalStructureOfficeAdmin(AbstractAdmin): prepopulated_fields = {'slug': ('name',)} - list_display = ('name', 'organizational_structure', 'is_active') + list_display = ('name', 'organizational_structure', + 'is_default', 'is_private', 'is_active') list_filter = ('organizational_structure', - 'is_active') + 'is_active', + 'is_private') - list_editable = ('is_active',) + list_editable = ('is_active', 'is_private') inlines = [OrganizationalStructureOfficeEmployeeInline, OrganizationalStructureOfficeLocationInline,] diff --git a/organizational_area/migrations/0032_organizationalstructureoffice_is_private.py b/organizational_area/migrations/0032_organizationalstructureoffice_is_private.py new file mode 100644 index 00000000..51b5e208 --- /dev/null +++ b/organizational_area/migrations/0032_organizationalstructureoffice_is_private.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.2 on 2020-10-16 07:14 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('organizational_area', '0031_auto_20200702_1126'), + ] + + operations = [ + migrations.AddField( + model_name='organizationalstructureoffice', + name='is_private', + field=models.BooleanField(default=False), + ), + ] diff --git a/organizational_area/models.py b/organizational_area/models.py index de77e27a..ec3a6622 100644 --- a/organizational_area/models.py +++ b/organizational_area/models.py @@ -183,6 +183,7 @@ class OrganizationalStructureOffice(models.Model): on_delete=models.CASCADE) description = models.TextField(max_length=1024, null=True,blank=True) is_default = models.BooleanField(default=False) + is_private = models.BooleanField(default=False) is_active = models.BooleanField(default=False) class Meta: diff --git a/tests/test_04_management.py b/tests/test_04_management.py index f8a00136..25c6f38d 100644 --- a/tests/test_04_management.py +++ b/tests/test_04_management.py @@ -179,9 +179,9 @@ def test_add_ticket_competence_and_manage(self): self.ticket.refresh_from_db() assert response.status_code == 200 - # Assign ticket to Category_3 (Structure 2) + # Assign ticket to Office (Structure 2) # Follow and continue to manage ticket (staff_1, manager of Structure 1) - params = {'category_slug': self.category_1_str_2.slug, + params = {'office_slug': self.office_1_str_2.slug, 'follow': 'on', # 'readonly': False, } @@ -290,7 +290,7 @@ def test_add_ticket_competence_and_readonly(self): # Assign ticket to Category_3 (Structure 2) # Follow and continue to manage ticket (staff_1, manager of Structure 1) - params = {'category_slug': self.category_1_str_2.slug, + params = {'office_slug': self.office_1_str_2.slug, 'follow': 'on', 'readonly': True, } diff --git a/uni_ticket/admin_actions.py b/uni_ticket/admin_actions.py index 5c72f0d5..b5721f6f 100644 --- a/uni_ticket/admin_actions.py +++ b/uni_ticket/admin_actions.py @@ -12,6 +12,8 @@ from django.utils import timezone from django.utils.html import strip_tags +from django_form_builder.utils import format_field_name + from . models import * @@ -29,6 +31,7 @@ def _download_report_csv(modeladmin, delimiter='$' quotechar='"' + dialect='excel' for cat in queryset: @@ -39,21 +42,23 @@ def _download_report_csv(modeladmin, file_name = "{}_MOD_{}_{}.csv".format(cat.name.replace('/','_'), module.name.replace('/','_'), - module.created.strftime('%d-%m-%Y')) + module.created.strftime('%d-%m-%Y_%H-%M-%S')) head = ['created', 'user', 'status', 'subject', 'description'] - + custom_head = [] fields = TicketCategoryInputList.objects.filter(category_module=module) for field in fields: + custom_head.append(field.name) head.append(field.name) csv_file = HttpResponse(content_type='text/csv') csv_file['Content-Disposition'] = 'attachment; filename="{}"'.format(file_name) writer = csv.writer(csv_file, + dialect=dialect, delimiter = delimiter, quotechar = quotechar) @@ -71,8 +76,9 @@ def _download_report_csv(modeladmin, status, richiesta.subject, richiesta.description] - for k,v in content.items(): - row.append(v) + # for k,v in content.items(): + for column in custom_head: + row.append(content.get(format_field_name(column), '')) writer.writerow(row) f.writestr(file_name, csv_file.content) diff --git a/uni_ticket/forms.py b/uni_ticket/forms.py index a141da94..2dbc10dd 100644 --- a/uni_ticket/forms.py +++ b/uni_ticket/forms.py @@ -168,9 +168,13 @@ class OfficeForm(ModelForm): """ class Meta: model = OrganizationalStructureOffice - fields = ['name', 'description'] + fields = ['name', 'description', 'is_private'] labels = {'name': _('Nome'), - 'description': _('Descrizione'),} + 'description': _('Descrizione'), + 'is_private': _('Ad uso interno')} + help_texts = {'is_private': _("Visibile esclusivamente all'interno " + "della struttura quando si effettua " + "un trasferimento di competenza")} widgets = {'description': forms.Textarea(attrs={'rows':2})} class Media: @@ -284,7 +288,8 @@ class TicketCompetenceSchemeForm(forms.Form): (rendered manually to have js behaviour) """ # structure_slug = forms.CharField(label=_('Struttura'), required=True) - category_slug = forms.CharField(label=_('Categoria'), required=True) + # category_slug = forms.CharField(label=_('Categoria'), required=True) + office_slug = forms.CharField(label=_('Ufficio'), required=True) follow = forms.BooleanField(label=_('Continua a seguire'), required=False) readonly = forms.BooleanField(label=_('Sola lettura'), required=False) selected_office = forms.CharField(label=_('Ufficio selezionato'), required=False) diff --git a/uni_ticket/views/management.py b/uni_ticket/views/management.py index da06888d..7e6bc8ae 100644 --- a/uni_ticket/views/management.py +++ b/uni_ticket/views/management.py @@ -900,26 +900,33 @@ def ticket_competence_add_final(request, structure_slug, ticket_id, new_structure = get_object_or_404(OrganizationalStructure, slug=new_structure_slug, is_active=True) - categorie = TicketCategory.objects.filter(organizational_structure=new_structure.pk, - is_active=True) + offices = OrganizationalStructureOffice.objects.filter(organizational_structure=new_structure, + is_active=True) + + # exclude private offices if not in same structure + if new_structure != structure: + offices = offices.exclude(is_private=True) + if request.method == 'POST': form = TicketCompetenceSchemeForm(data=request.POST) if form.is_valid(): - category_slug = form.cleaned_data['category_slug'] + office_slug = form.cleaned_data['office_slug'] follow = form.cleaned_data['follow'] readonly = form.cleaned_data['readonly'] selected_office_slug = form.cleaned_data['selected_office'] - # Refactor - # follow_value = form.cleaned_data['follow'] - # readonly_value = form.cleaned_data['readonly'] - # follow = True if follow_value == 'on' else False - # readonly = True if readonly_value == 'on' else False - - # La categoria passata in POST esiste? - categoria = get_object_or_404(TicketCategory, - slug=category_slug, - organizational_structure=new_structure, - is_active=True) + + # L'ufficio passato in POST esiste? + new_office = get_object_or_404(OrganizationalStructureOffice, + slug=office_slug, + organizational_structure=new_structure, + is_active=True) + + # se viene forzato il POST con un ufficio privato! + if new_structure != structure and new_office.is_private: + return custom_message(request, + _("Impossibile assegnare la richiesta " + "all'ufficio selezionato"), + structure_slug=structure.slug) selected_office = None if selected_office_slug: @@ -928,28 +935,11 @@ def ticket_competence_add_final(request, structure_slug, ticket_id, organizational_structure=structure, is_active=True) - # Se alla categoria non è associato alcun ufficio, - # all'utente viene mostrato il messaggio di errore - # Perchè l'ufficio speciale Help-Desk è già competente sul ticket - if not categoria.organizational_office: - messages.add_message(request, messages.ERROR, - _("La richiesta è già di competenza" - " dell'ufficio speciale {}," - " responsabile della tipologia di richiesta " - "{}").format(settings.DEFAULT_ORGANIZATIONAL_STRUCTURE_OFFICE, - categoria)) - return redirect('uni_ticket:manage_ticket_url_detail', - structure_slug=structure_slug, - ticket_id=ticket_id) - - new_office = categoria.organizational_office - if new_office in ticket_offices: messages.add_message(request, messages.ERROR, _("La richiesta è già di competenza" - " dell'ufficio {}, responsabile" - " della tipologia di richiesta {}" - "").format(new_office, categoria)) + " dell'ufficio {}" + "").format(new_office)) return redirect('uni_ticket:manage_ticket_url_detail', structure_slug=structure_slug, ticket_id=ticket_id) @@ -995,9 +985,8 @@ def ticket_competence_add_final(request, structure_slug, ticket_id, user=request.user) ticket.update_log(user=request.user, note= _("Nuova competenza: {} - {}" - " - Categoria: {}".format(new_structure, - new_office, - categoria))) + "").format(new_structure, + new_office)) # log action logger.info('[{}] {} added new competence to' @@ -1020,7 +1009,7 @@ def ticket_competence_add_final(request, structure_slug, ticket_id, title = _('Trasferisci competenza richiesta') sub_title = '{} ({})'.format(ticket.subject, ticket_id) d = {'can_manage': can_manage, - 'categorie': categorie, + 'offices': offices, 'operator_offices': operator_offices_list, 'structure': structure, 'structure_slug': new_structure_slug, diff --git a/uni_ticket_bootstrap_italia_template/templates/management/add_ticket_competence.html b/uni_ticket_bootstrap_italia_template/templates/management/add_ticket_competence.html index ada70003..4267f9ab 100644 --- a/uni_ticket_bootstrap_italia_template/templates/management/add_ticket_competence.html +++ b/uni_ticket_bootstrap_italia_template/templates/management/add_ticket_competence.html @@ -13,7 +13,7 @@ {% endblock top_buttons %} {% block page_content %} - {% if categorie %} + {% if offices %}
{% endif %} @@ -38,14 +38,14 @@
- + {% if not structure_slug %} - {% elif not categorie %} + {% elif not offices %} {% else %} {% comment %} @@ -55,12 +55,12 @@
@@ -95,7 +95,7 @@ {% endif %}
- {% if categorie %} + {% if offices %}
diff --git a/uni_ticket_bootstrap_italia_template/templates/manager/office_detail.html b/uni_ticket_bootstrap_italia_template/templates/manager/office_detail.html index bc11aaef..20b62e96 100644 --- a/uni_ticket_bootstrap_italia_template/templates/manager/office_detail.html +++ b/uni_ticket_bootstrap_italia_template/templates/manager/office_detail.html @@ -97,6 +97,18 @@ {% else %}-{% endif %} + + {% trans 'Ad uso interno' %} + + + {% if office.is_private %} + + {% else %} + + {% endif %} + + + {% trans 'Tipologie di competenza' %} diff --git a/uni_ticket_bootstrap_italia_template/templates/manager/offices_list.html b/uni_ticket_bootstrap_italia_template/templates/manager/offices_list.html index 504fa463..7acc13c7 100644 --- a/uni_ticket_bootstrap_italia_template/templates/manager/offices_list.html +++ b/uni_ticket_bootstrap_italia_template/templates/manager/offices_list.html @@ -50,6 +50,15 @@
{{ office.name }}
{% trans 'Operatori' %}: {{ office.organizationalstructureofficeemployee_set.all|length }}
+ {% trans 'Ad uso interno' %}: + + {% if office.is_private %} + + {% else %} + + {% endif %} + +
{% trans 'Richieste assegnate' %}: {{ office.ticketassignment_set.all|length }}
diff --git a/uni_ticket_bootstrap_italia_template/templates/operator/offices_list.html b/uni_ticket_bootstrap_italia_template/templates/operator/offices_list.html index cc497d99..590cbc16 100644 --- a/uni_ticket_bootstrap_italia_template/templates/operator/offices_list.html +++ b/uni_ticket_bootstrap_italia_template/templates/operator/offices_list.html @@ -28,6 +28,15 @@
{{ office.name }}

{% trans 'Operatori' %}: {{ office.organizationalstructureofficeemployee_set.all|length }} +
+ {% trans 'Ad uso interno' %}: + + {% if office.is_private %} + + {% else %} + + {% endif %} +
{% trans 'Categorie di competenza' %}: {% if office.ticketcategory_set.all %}