feat(contracts): add column sorting by code and dates to contracts list
This commit is contained in:
parent
0732f89274
commit
a6378eee90
4 changed files with 97 additions and 8 deletions
|
|
@ -60,6 +60,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
const url = new URL(window.location.href);
|
const url = new URL(window.location.href);
|
||||||
url.searchParams.set('page_size', this.value);
|
url.searchParams.set('page_size', this.value);
|
||||||
url.searchParams.delete('page');
|
url.searchParams.delete('page');
|
||||||
|
url.searchParams.delete('contracts_page');
|
||||||
window.location.href = url.toString();
|
window.location.href = url.toString();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -394,12 +394,37 @@
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width: 48px;"></th>
|
<th style="width: 48px;"></th>
|
||||||
<th>{% translate "Numéro" %}</th>
|
<th class="sortable">
|
||||||
<th>{% translate "Description" %}</th>
|
<a href="{{ contracts_sort_urls.code }}" class="sort-link">
|
||||||
|
<span>{% translate "Numéro" %}</span>
|
||||||
|
<i class="bi {% if contracts_sort_field == 'code' %}{% if contracts_sort_dir == 'asc' %}bi-sort-up text-primary{% else %}bi-sort-down text-primary{% endif %}{% else %}bi-arrow-down-up text-muted opacity-50{% endif %}"></i>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th class="sortable">
|
||||||
|
<a href="{{ contracts_sort_urls.description }}" class="sort-link">
|
||||||
|
<span>{% translate "Description" %}</span>
|
||||||
|
<i class="bi {% if contracts_sort_field == 'description' %}{% if contracts_sort_dir == 'asc' %}bi-sort-up text-primary{% else %}bi-sort-down text-primary{% endif %}{% else %}bi-arrow-down-up text-muted opacity-50{% endif %}"></i>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
<th>{% translate "Thématiques" %}</th>
|
<th>{% translate "Thématiques" %}</th>
|
||||||
<th>{% translate "Prestataire" %}</th>
|
<th class="sortable">
|
||||||
<th>{% translate "Début" %}</th>
|
<a href="{{ contracts_sort_urls.company }}" class="sort-link">
|
||||||
<th>{% translate "Fin" %}</th>
|
<span>{% translate "Prestataire" %}</span>
|
||||||
|
<i class="bi {% if contracts_sort_field == 'company' %}{% if contracts_sort_dir == 'asc' %}bi-sort-up text-primary{% else %}bi-sort-down text-primary{% endif %}{% else %}bi-arrow-down-up text-muted opacity-50{% endif %}"></i>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th class="sortable">
|
||||||
|
<a href="{{ contracts_sort_urls.start_date }}" class="sort-link">
|
||||||
|
<span>{% translate "Début" %}</span>
|
||||||
|
<i class="bi {% if contracts_sort_field == 'start_date' or contracts_sort_field == 'date' %}{% if contracts_sort_dir == 'asc' %}bi-sort-up text-primary{% else %}bi-sort-down text-primary{% endif %}{% else %}bi-arrow-down-up text-muted opacity-50{% endif %}"></i>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th class="sortable">
|
||||||
|
<a href="{{ contracts_sort_urls.end_date }}" class="sort-link">
|
||||||
|
<span>{% translate "Fin" %}</span>
|
||||||
|
<i class="bi {% if contracts_sort_field == 'end_date' %}{% if contracts_sort_dir == 'asc' %}bi-sort-up text-primary{% else %}bi-sort-down text-primary{% endif %}{% else %}bi-arrow-down-up text-muted opacity-50{% endif %}"></i>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
|
||||||
|
|
@ -915,6 +915,22 @@ class ContractsIndexViewTests(TestCase):
|
||||||
# Premier élément doit être CMD-002 car CMD-001 est cancelled
|
# Premier élément doit être CMD-002 car CMD-001 est cancelled
|
||||||
self.assertEqual(resp.context['orders_page'][0].order_code, 'CMD-002')
|
self.assertEqual(resp.context['orders_page'][0].order_code, 'CMD-002')
|
||||||
|
|
||||||
|
def test_contracts_index_contracts_sorting_code_asc(self):
|
||||||
|
url = reverse('contracts:contracts_index')
|
||||||
|
resp = self.client.get(url, {'tab': 'contracts', 'contracts_sort': 'code', 'contracts_dir': 'asc'})
|
||||||
|
self.assertEqual(resp.status_code, 200)
|
||||||
|
contracts_page = resp.context['contracts_page']
|
||||||
|
self.assertEqual(contracts_page[0].contract_number, self.contract_green.contract_number)
|
||||||
|
self.assertEqual(contracts_page[1].contract_number, self.contract_roads.contract_number)
|
||||||
|
|
||||||
|
def test_contracts_index_contracts_sorting_code_desc(self):
|
||||||
|
url = reverse('contracts:contracts_index')
|
||||||
|
resp = self.client.get(url, {'tab': 'contracts', 'contracts_sort': 'code', 'contracts_dir': 'desc'})
|
||||||
|
self.assertEqual(resp.status_code, 200)
|
||||||
|
contracts_page = resp.context['contracts_page']
|
||||||
|
self.assertEqual(contracts_page[0].contract_number, self.contract_roads.contract_number)
|
||||||
|
self.assertEqual(contracts_page[1].contract_number, self.contract_green.contract_number)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,30 @@ def contracts_index(request):
|
||||||
orders_page = orders_paginator.get_page(orders_page_num)
|
orders_page = orders_paginator.get_page(orders_page_num)
|
||||||
orders_elided_range = orders_paginator.get_elided_page_range(orders_page.number, on_each_side=2, on_ends=1)
|
orders_elided_range = orders_paginator.get_elided_page_range(orders_page.number, on_each_side=2, on_ends=1)
|
||||||
|
|
||||||
|
# Tri des marchés
|
||||||
|
contracts_sort_field = request.GET.get('contracts_sort', '')
|
||||||
|
if not contracts_sort_field and active_tab == 'contracts':
|
||||||
|
contracts_sort_field = request.GET.get('sort', '')
|
||||||
|
if not contracts_sort_field:
|
||||||
|
contracts_sort_field = 'start_date'
|
||||||
|
|
||||||
|
contracts_sort_dir = request.GET.get('contracts_dir', '')
|
||||||
|
if not contracts_sort_dir and active_tab == 'contracts':
|
||||||
|
contracts_sort_dir = request.GET.get('dir', '')
|
||||||
|
if contracts_sort_dir not in ('asc', 'desc'):
|
||||||
|
contracts_sort_dir = 'desc' if contracts_sort_field in ('start_date', 'date', 'end_date') else 'asc'
|
||||||
|
|
||||||
|
contracts_sort_mapping = {
|
||||||
|
'code': 'contract_number',
|
||||||
|
'description': 'description',
|
||||||
|
'company': 'company__name',
|
||||||
|
'start_date': 'start_date',
|
||||||
|
'date': 'start_date',
|
||||||
|
'end_date': 'end_date',
|
||||||
|
}
|
||||||
|
db_contracts_sort_col = contracts_sort_mapping.get(contracts_sort_field, 'start_date')
|
||||||
|
contracts_order_by_arg = db_contracts_sort_col if contracts_sort_dir == 'asc' else f"-{db_contracts_sort_col}"
|
||||||
|
|
||||||
# Construction de la requête marchés/contrats
|
# Construction de la requête marchés/contrats
|
||||||
contracts_qs = contracts
|
contracts_qs = contracts
|
||||||
if search_query:
|
if search_query:
|
||||||
|
|
@ -159,9 +183,9 @@ def contracts_index(request):
|
||||||
Q(thematics__id__in=selected_thematics) |
|
Q(thematics__id__in=selected_thematics) |
|
||||||
Q(thematics__code__in=selected_thematics)
|
Q(thematics__code__in=selected_thematics)
|
||||||
)
|
)
|
||||||
contracts_qs = contracts_qs.distinct().order_by('-start_date')
|
contracts_qs = contracts_qs.distinct().order_by(contracts_order_by_arg, '-id')
|
||||||
|
|
||||||
contracts_paginator = Paginator(contracts_qs, 25)
|
contracts_paginator = Paginator(contracts_qs, page_size)
|
||||||
contracts_page_num = request.GET.get('contracts_page', 1)
|
contracts_page_num = request.GET.get('contracts_page', 1)
|
||||||
contracts_page = contracts_paginator.get_page(contracts_page_num)
|
contracts_page = contracts_paginator.get_page(contracts_page_num)
|
||||||
contracts_elided_range = contracts_paginator.get_elided_page_range(contracts_page.number, on_each_side=2, on_ends=1)
|
contracts_elided_range = contracts_paginator.get_elided_page_range(contracts_page.number, on_each_side=2, on_ends=1)
|
||||||
|
|
@ -229,11 +253,12 @@ def contracts_index(request):
|
||||||
orders_querystring = p_orders.urlencode()
|
orders_querystring = p_orders.urlencode()
|
||||||
|
|
||||||
p_contracts = request.GET.copy()
|
p_contracts = request.GET.copy()
|
||||||
|
p_contracts['tab'] = 'contracts'
|
||||||
if 'contracts_page' in p_contracts:
|
if 'contracts_page' in p_contracts:
|
||||||
del p_contracts['contracts_page']
|
del p_contracts['contracts_page']
|
||||||
contracts_querystring = p_contracts.urlencode()
|
contracts_querystring = p_contracts.urlencode()
|
||||||
|
|
||||||
# Générateur d'URLs de tri
|
# Générateur d'URLs de tri des commandes
|
||||||
def build_sort_url(col):
|
def build_sort_url(col):
|
||||||
next_dir = 'asc' if (sort_field == col and sort_dir == 'desc') else 'desc'
|
next_dir = 'asc' if (sort_field == col and sort_dir == 'desc') else 'desc'
|
||||||
p = request.GET.copy()
|
p = request.GET.copy()
|
||||||
|
|
@ -245,6 +270,25 @@ def contracts_index(request):
|
||||||
|
|
||||||
sort_urls = {col: build_sort_url(col) for col in ('code', 'description', 'date', 'status', 'contract', 'amount')}
|
sort_urls = {col: build_sort_url(col) for col in ('code', 'description', 'date', 'status', 'contract', 'amount')}
|
||||||
|
|
||||||
|
# Générateur d'URLs de tri des marchés
|
||||||
|
def build_contracts_sort_url(col):
|
||||||
|
if contracts_sort_field == col:
|
||||||
|
next_dir = 'desc' if contracts_sort_dir == 'asc' else 'asc'
|
||||||
|
else:
|
||||||
|
next_dir = 'desc' if col in ('start_date', 'end_date', 'date') else 'asc'
|
||||||
|
p = request.GET.copy()
|
||||||
|
p['tab'] = 'contracts'
|
||||||
|
p['contracts_sort'] = col
|
||||||
|
p['contracts_dir'] = next_dir
|
||||||
|
if 'contracts_page' in p:
|
||||||
|
del p['contracts_page']
|
||||||
|
return f"?{p.urlencode()}"
|
||||||
|
|
||||||
|
contracts_sort_urls = {
|
||||||
|
col: build_contracts_sort_url(col)
|
||||||
|
for col in ('code', 'description', 'company', 'start_date', 'end_date')
|
||||||
|
}
|
||||||
|
|
||||||
# Vérification des droits pour voir les prix
|
# Vérification des droits pour voir les prix
|
||||||
can_view_prices = False
|
can_view_prices = False
|
||||||
if request.user.is_superuser:
|
if request.user.is_superuser:
|
||||||
|
|
@ -279,6 +323,9 @@ def contracts_index(request):
|
||||||
'sort_field': sort_field,
|
'sort_field': sort_field,
|
||||||
'sort_dir': sort_dir,
|
'sort_dir': sort_dir,
|
||||||
'sort_urls': sort_urls,
|
'sort_urls': sort_urls,
|
||||||
|
'contracts_sort_field': contracts_sort_field,
|
||||||
|
'contracts_sort_dir': contracts_sort_dir,
|
||||||
|
'contracts_sort_urls': contracts_sort_urls,
|
||||||
'active_tab': active_tab,
|
'active_tab': active_tab,
|
||||||
'active_filters_list': active_filters_list,
|
'active_filters_list': active_filters_list,
|
||||||
'active_filters_count': active_filters_count,
|
'active_filters_count': active_filters_count,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue