131 lines
4.5 KiB
Python
131 lines
4.5 KiB
Python
# lingo - payment and billing system
|
|
# Copyright (C) 2022 Entr'ouvert
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify it
|
|
# under the terms of the GNU Affero General Public License as published
|
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
import django_filters
|
|
from django import forms
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
from lingo.invoicing.models import Campaign, DraftInvoiceLine, InvoiceLine, Regie
|
|
|
|
|
|
class CampaignForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Campaign
|
|
fields = ['date_start', 'date_end', 'date_issue', 'injected_lines']
|
|
widgets = {
|
|
'date_start': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
|
|
'date_end': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
|
|
'date_issue': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
|
|
}
|
|
|
|
def clean(self):
|
|
cleaned_data = super().clean()
|
|
if 'date_start' in cleaned_data and 'date_end' in cleaned_data:
|
|
overlapping_qs = Campaign.objects.extra(
|
|
where=["(date_start, date_end) OVERLAPS (%s, %s)"],
|
|
params=[cleaned_data['date_start'], cleaned_data['date_end']],
|
|
)
|
|
if self.instance.pk:
|
|
overlapping_qs = overlapping_qs.exclude(pk=self.instance.pk)
|
|
if overlapping_qs.exists():
|
|
self.add_error(None, _('Another campaign overlapping this period already exists.'))
|
|
|
|
return cleaned_data
|
|
|
|
|
|
def regie_queryset(request):
|
|
return Regie.objects.all()
|
|
|
|
|
|
class AbstractLineFilterSet(django_filters.FilterSet):
|
|
regie = django_filters.ModelChoiceFilter(
|
|
label=_('Regie'),
|
|
queryset=regie_queryset,
|
|
field_name='invoice__regie',
|
|
)
|
|
invoice_number = django_filters.CharFilter(
|
|
label=_('Invoice number'),
|
|
field_name='invoice__formatted_number',
|
|
lookup_expr='contains',
|
|
)
|
|
invoice_id = django_filters.NumberFilter(
|
|
label=_('Invoice number'),
|
|
)
|
|
pk = django_filters.NumberFilter(
|
|
label=_('PK'),
|
|
)
|
|
payer_external_id = django_filters.CharFilter(
|
|
label=_('Payer (external ID)'),
|
|
)
|
|
user_external_id = django_filters.CharFilter(
|
|
label=_('User (external ID)'),
|
|
)
|
|
status = django_filters.ChoiceFilter(
|
|
label=_('Status'),
|
|
widget=forms.RadioSelect,
|
|
empty_label=_('all'),
|
|
method='filter_status',
|
|
)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.pool = kwargs.pop('pool')
|
|
super().__init__(*args, **kwargs)
|
|
|
|
if self.pool.draft:
|
|
del self.filters['invoice_number']
|
|
else:
|
|
del self.filters['invoice_id']
|
|
|
|
status_choices = [
|
|
('success', _('Success')),
|
|
('success_injected', '%s (%s)' % (_('Success'), _('Injected'))),
|
|
('warning', _('Warning')),
|
|
('error', _('Error')),
|
|
]
|
|
if not self.pool.draft:
|
|
status_choices += [
|
|
('error_todo', _('Error (To treat)')),
|
|
('error_ignored', _('Error (Ignored)')),
|
|
('error_fixed', _('Error (Fixed)')),
|
|
]
|
|
self.filters['status'].field.choices = status_choices
|
|
|
|
def filter_status(self, queryset, name, value):
|
|
if not value:
|
|
return queryset
|
|
if value == 'success_injected':
|
|
return queryset.filter(status='success', from_injected_line__isnull=False)
|
|
if value == 'error_todo':
|
|
return queryset.filter(status='error', error_status='')
|
|
if value == 'error_ignored':
|
|
return queryset.filter(status='error', error_status='ignored')
|
|
if value == 'error_fixed':
|
|
return queryset.filter(status='error', error_status='fixed')
|
|
return queryset.filter(status=value)
|
|
|
|
|
|
class DraftInvoiceLineFilterSet(AbstractLineFilterSet):
|
|
class Meta:
|
|
model = DraftInvoiceLine
|
|
fields = []
|
|
|
|
|
|
class InvoiceLineFilterSet(AbstractLineFilterSet):
|
|
class Meta:
|
|
model = InvoiceLine
|
|
fields = []
|