panier: pouvoir lier une ligne de facturation à un agenda et à un event (#88544) #175

Merged
lguerin merged 2 commits from wip/88544-basket-activity into main 2024-03-29 08:24:56 +01:00
13 changed files with 394 additions and 41 deletions

View File

@ -514,6 +514,9 @@ class BasketLineSerializer(serializers.ModelSerializer):
class BasketLineItemSerializer(serializers.ModelSerializer):
slug = serializers.CharField(required=False, max_length=250)
activity_label = serializers.CharField(required=False, max_length=250)
Review

Du détail, j’avais le souvenir que pour un ModelSerializer, DRF gérait automatiquement la taille limite des champs en fonction de la définition du modèle (la colonne activity_label du modèle est déjà définie de longueur maximale 250), auquel cas il n’y aurait pas besoin de la redéfinir ici.

Du détail, j’avais le souvenir que pour un ModelSerializer, DRF gérait automatiquement la taille limite des champs en fonction de la définition du modèle (la colonne activity_label du modèle est déjà définie de longueur maximale 250), auquel cas il n’y aurait pas besoin de la redéfinir ici.
Review

c'était pour avoir un champ not required :)

c'était pour avoir un champ not required :)
class Meta:
model = BasketLineItem
fields = [
@ -522,6 +525,8 @@ class BasketLineItemSerializer(serializers.ModelSerializer):
'details',
'quantity',
'unit_amount',
'slug',
'activity_label',
]

View File

@ -135,7 +135,19 @@ class BasketLineItemsView(APIView):
if not serializer.is_valid():
raise APIErrorBadRequest(N_('invalid payload'), errors=serializer.errors)
item = BasketLineItem.objects.create(line=line, **serializer.validated_data)
event_slug = serializer.validated_data.pop('slug', '')
event_label = ''
agenda_slug = ''
if '@' in event_slug:
agenda_slug = event_slug.split('@')[0]
event_label = serializer.validated_data['label']
item = BasketLineItem.objects.create(
line=line,
event_slug=event_slug,
event_label=event_label,
agenda_slug=agenda_slug,
**serializer.validated_data,
)
return Response({'data': {'item_id': str(item.uuid)}})
@ -165,12 +177,26 @@ class BasketLineCloseView(APIView):
return Response({'data': {'line_id': str(self.line.uuid), 'closed': True}})
def generate_invoice_lines(self):
for slug, label, description, quantity, unit_amount, dummy in self.line.formatted_items:
for (
slug,
label,
description,
quantity,
unit_amount,
dummy,
event_slug,
event_label,
agenda_slug,
activity_label,
) in self.line.formatted_items:
DraftInvoiceLine.objects.create(
invoice=self.line.basket.draft_invoice,
event_date=datetime.date.today(),
slug=slug,
event_slug=slug,
event_slug=event_slug,
event_label=event_label,
agenda_slug=agenda_slug,
activity_label=activity_label,
label=label,
description=description,
payer_external_id=self.line.basket.payer_external_id,

View File

@ -0,0 +1,34 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('basket', '0007_information_messages'),
]
operations = [
migrations.AddField(
model_name='basketlineitem',
name='activity_label',
field=models.CharField(default='', max_length=250),
preserve_default=False,
),
migrations.AddField(
model_name='basketlineitem',
name='agenda_slug',
field=models.CharField(default='', max_length=250),
preserve_default=False,
),
migrations.AddField(
model_name='basketlineitem',
name='event_label',
field=models.CharField(default='', max_length=260),
preserve_default=False,
),
migrations.AddField(
model_name='basketlineitem',
name='event_slug',
field=models.CharField(default='', max_length=250),
preserve_default=False,
),
]

View File

@ -249,6 +249,10 @@ class BasketLine(models.Model):
item.quantity,
item.unit_amount,
item.quantity * item.unit_amount,
item.event_slug,
item.event_label,
item.agenda_slug,
item.activity_label,
)
)
return sorted(result, key=lambda a: a[0])
@ -257,7 +261,15 @@ class BasketLine(models.Model):
keys = [] # to keep ordering from line items
items = {} # group items
for item in self.items.all().order_by('pk'):
key = (item.unit_amount, item.label, item.subject)
key = (
item.unit_amount,
item.label,
item.subject,
item.event_slug,
item.event_label,
item.agenda_slug,
item.activity_label,
)
if key not in keys:
keys.append(key)
items[key] = {'details': [], 'quantity': decimal.Decimal('0')}
@ -284,6 +296,10 @@ class BasketLine(models.Model):
item['quantity'],
key[0],
item['quantity'] * key[0],
key[3],
key[4],
key[5],
key[6],
)
)
return sorted(result, key=lambda a: a[0])
@ -315,6 +331,11 @@ class BasketLineItem(models.Model):
subject = models.CharField(max_length=200, blank=True)
details = models.TextField(blank=True)
event_slug = models.CharField(max_length=250)
event_label = models.CharField(max_length=260)
agenda_slug = models.CharField(max_length=250)
activity_label = models.CharField(max_length=250)
quantity = models.DecimalField(max_digits=9, decimal_places=2)
unit_amount = models.DecimalField(max_digits=9, decimal_places=2)

View File

@ -19,7 +19,7 @@
{% endfor %}
<ul class="basket">
{% for line in basket.lines %}
{% for slug, label, description, quantity, unit_amount, total_amount in line.formatted_items %}
{% for slug, label, description, quantity, unit_amount, total_amount, dummy, dummy, dummy, dummy in line.formatted_items %}
<li class="basket-item">
<a class="basket-item--label" {% if line.form_url %}href="{{ line.form_url }}{% endif %}">{{ line.user_name }} - {{ label }}{% if description %} - {{ description }}{% endif %}</a>
<span class="basket-item--total-amount">{% blocktrans with amount=total_amount|floatformat:"2" %}{{ amount }}€{% endblocktrans %}</span>

View File

@ -205,10 +205,10 @@ class CampaignDatesForm(forms.ModelForm):
class AgendaFieldsFilterSetMixin:
def _init_agenda_fields(self, line_model, invoice_queryset):
def _init_agenda_fields(self, line_model, invoice_queryset, invoice_field='invoice'):
# get agendas from slugs
agenda_slugs = set(
line_model.objects.filter(invoice__in=invoice_queryset)
line_model.objects.filter(**{f'{invoice_field}__in': invoice_queryset})
.exclude(agenda_slug='')
.values_list('agenda_slug', flat=True)
)
@ -217,7 +217,7 @@ class AgendaFieldsFilterSetMixin:
self.filters['agenda'].field.choices = [(a.slug, a.label) for a in agendas]
# get line details to build event filter choices
agenda_labels_by_slug = {a.slug: a.label for a in agendas}
lines = line_model.objects.filter(invoice__in=invoice_queryset).values(
lines = line_model.objects.filter(**{f'{invoice_field}__in': invoice_queryset}).values(
'slug', 'event_label', 'event_slug', 'agenda_slug'
)
events = set()
@ -805,7 +805,7 @@ class RegiePaymentFilterSet(AgendaFieldsFilterSetMixin, django_filters.FilterSet
return queryset.filter(pk__in=InvoiceLinePayment.objects.filter(line__in=lines).values('payment'))
class RegieCreditFilterSet(django_filters.FilterSet):
class RegieCreditFilterSet(AgendaFieldsFilterSetMixin, django_filters.FilterSet):
number = django_filters.CharFilter(
label=_('Credit number'),
field_name='formatted_number',
@ -873,11 +873,26 @@ class RegieCreditFilterSet(django_filters.FilterSet):
],
method='filter_assigned',
)
agenda = django_filters.ChoiceFilter(
label=_('Activity'),
empty_label=_('all'),
method='filter_agenda',
)
event = django_filters.ChoiceFilter(
label=_('Event'),
empty_label=_('all'),
method='filter_event',
)
class Meta:
model = Credit
fields = []
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._init_agenda_fields(CreditLine, self.queryset, invoice_field='credit')
def filter_payment_number(self, queryset, name, value):
assignment_queryset = CreditAssignment.objects.filter(
payment__formatted_number__contains=value
@ -911,6 +926,18 @@ class RegieCreditFilterSet(django_filters.FilterSet):
return queryset.filter(assigned_amount=0)
return queryset
def filter_agenda(self, queryset, name, value):
if not value:
return queryset
lines = CreditLine.objects.filter(agenda_slug=value).values('credit')
return queryset.filter(pk__in=lines)
def filter_event(self, queryset, name, value):
if not value:
return queryset
lines = CreditLine.objects.filter(event_slug=value).values('credit')
return queryset.filter(pk__in=lines)
class RegieRefundFilterSet(django_filters.FilterSet):
number = django_filters.CharFilter(

View File

@ -0,0 +1,34 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('invoicing', '0082_invoice_colour'),
]
operations = [
migrations.AddField(
model_name='creditline',
name='activity_label',
field=models.CharField(default='', max_length=250),
preserve_default=False,
),
migrations.AddField(
model_name='creditline',
name='agenda_slug',
field=models.CharField(default='', max_length=250),
preserve_default=False,
),
migrations.AddField(
model_name='creditline',
name='event_label',
field=models.CharField(default='', max_length=260),
preserve_default=False,
),
migrations.AddField(
model_name='creditline',
name='event_slug',
field=models.CharField(default='', max_length=250),
preserve_default=False,
),
]

View File

@ -1112,18 +1112,22 @@ class Credit(AbstractInvoiceObject):
self.formatted_number = self.regie.format_number(self.created_at, self.number, 'credit')
def get_grouped_and_ordered_lines(self):
lines = [
(
line,
# sort by user
line.user_external_id,
# by slug
line.slug,
# and pk
line.pk,
lines = []
for line in self.lines.all():
lines.append(
(
line,
# sort by user
line.user_external_id,
# by activity
line.activity_label or 'z' * 5000,
# by slugs
line.event_slug,
line.slug,
# and pk
line.pk,
)
)
for line in self.lines.all()
]
lines = sorted(
lines,
key=lambda li: li[1:],
@ -1153,6 +1157,10 @@ class AbstractInvoiceLineObject(models.Model):
unit_amount = models.DecimalField(max_digits=9, decimal_places=2)
total_amount = models.DecimalField(max_digits=9, decimal_places=2)
description = models.CharField(max_length=500)
event_slug = models.CharField(max_length=250)
event_label = models.CharField(max_length=260)
agenda_slug = models.CharField(max_length=250)
activity_label = models.CharField(max_length=250)
user_external_id = models.CharField(max_length=250)
user_first_name = models.CharField(max_length=250)
@ -1175,10 +1183,6 @@ class AbstractInvoiceLine(AbstractInvoiceLineObject):
payer_demat = models.BooleanField(default=False)
payer_direct_debit = models.BooleanField(default=False)
details = models.JSONField(default=dict, encoder=DjangoJSONEncoder)
event_slug = models.CharField(max_length=250)
event_label = models.CharField(max_length=260)
agenda_slug = models.CharField(max_length=250)
activity_label = models.CharField(max_length=250)
pool = models.ForeignKey(Pool, on_delete=models.PROTECT, null=True)

View File

@ -26,7 +26,14 @@
{% endifchanged %}
<tr {% if not line.details %}class="new-event"{% else %}{% ifchanged line.label %}class="new-event"{% endifchanged %}{% endif %}>
<td class="description">
{{ line.label }}
{% ifchanged line.user_external_id line.label %}
{{ line.label }}
<br />
{% if line.activity_label %}
<i>{{ line.activity_label }}</i>
<br />
{% endif %}
{% endifchanged %}
</td>
<td class="details">
{{ line.description }}

View File

@ -14,6 +14,13 @@
<td></td>
</tr>
{% endifchanged %}
{% ifchanged line.user_external_id line.activity_label %}
{% if line.activity_label or not forloop.first %}
<tr class="line" data-related-invoicing-element-id="{{ credit.pk }}">
<td colspan="6" class="activity">{{ line.activity_label|default:"&nbsp;" }}</td>
</tr>
{% endif %}
{% endifchanged %}
<tr class="line untoggled {% if pool.draft and forloop.last %}last-line{% endif %}" data-related-invoicing-element-id="{{ credit.pk }}" data-invoicing-element-id="{{ credit.pk }}-{{ line.pk }}">
<td class="event">
{{ line.label }}

View File

@ -397,6 +397,10 @@ def test_add_item(app, user):
assert item.details == 'Lun 06/11, Mar 07/11'
assert item.quantity == 2
assert item.unit_amount == 3
assert item.event_slug == ''
assert item.event_label == ''
assert item.agenda_slug == ''
assert item.activity_label == ''
basket.refresh_from_db()
assert basket.expiry_at == old_expiry_at
assert invoice.lines.count() == 0
@ -412,6 +416,10 @@ def test_add_item(app, user):
assert item.details == 'Lun 06/11, Mar 07/11'
assert item.quantity == 2
assert item.unit_amount == 3
assert item.event_slug == ''
assert item.event_label == ''
assert item.agenda_slug == ''
assert item.activity_label == ''
# add a negative item
params = {
@ -420,6 +428,9 @@ def test_add_item(app, user):
'details': 'Jeu 09/11',
'quantity': -1,
'unit_amount': 3,
# related to agenda and event
'slug': 'agenda@bar-foo',
'activity_label': 'Activity Label !',
}
resp = app.post('/api/regie/foo/basket/%s/line/%s/items/' % (basket.uuid, line.uuid), params=params)
assert BasketLineItem.objects.count() == 3
@ -431,6 +442,10 @@ def test_add_item(app, user):
assert item.details == 'Jeu 09/11'
assert item.quantity == -1
assert item.unit_amount == 3
assert item.event_slug == 'agenda@bar-foo'
assert item.event_label == 'Repas'
assert item.agenda_slug == 'agenda'
assert item.activity_label == 'Activity Label !'
def test_close_line(app, user):
@ -482,6 +497,10 @@ def test_close_line(app, user):
details='Lun 6/11, Mar 7/11',
quantity=2,
unit_amount=3,
event_slug='agenda@repas',
event_label='Repas',
agenda_slug='agenda',
activity_label='Activity Label !',
)
BasketLineItem.objects.create(
line=line,
@ -490,6 +509,10 @@ def test_close_line(app, user):
details='Jeu 9/11',
quantity=-1,
unit_amount=3,
event_slug='agenda@repas',
event_label='Repas',
agenda_slug='agenda',
activity_label='Activity Label !',
)
BasketLineItem.objects.create(
line=line,
@ -498,14 +521,22 @@ def test_close_line(app, user):
details='Lun 13/11',
quantity=1,
unit_amount=3,
event_slug='agenda@repas',
event_label='Repas',
agenda_slug='agenda',
activity_label='Activity Label !',
)
BasketLineItem.objects.create(
basket_item = BasketLineItem.objects.create(
line=line,
label='Repas',
subject='Annulation',
details='Jeu 16/11',
quantity=-1,
unit_amount=3,
event_slug='agenda@repas',
event_label='Repas',
agenda_slug='agenda',
activity_label='Activity Label !',
)
BasketLineItem.objects.create(
line=line,
@ -514,6 +545,10 @@ def test_close_line(app, user):
details='Mer 8/11',
quantity=1,
unit_amount=5,
event_slug='agenda@mercredi',
event_label='Mercredi',
agenda_slug='agenda',
activity_label='Activity Label !',
)
BasketLineItem.objects.create(
line=line,
@ -522,6 +557,10 @@ def test_close_line(app, user):
details='Mer 15/11',
quantity=-0.5, # for decimal testing
unit_amount=5,
event_slug='agenda@mercredi',
event_label='Mercredi',
agenda_slug='agenda',
activity_label='Activity Label !',
)
# no grouping
resp = app.post('/api/regie/foo/basket/%s/line/%s/close/' % (basket.uuid, line.uuid))
@ -533,7 +572,10 @@ def test_close_line(app, user):
line1, line2, line3, line4, line5, line6 = invoice.lines.all().order_by('pk')
assert line1.event_date == datetime.date.today()
assert line1.slug == 'mercredi-annulation-mer-1511'
assert line1.event_slug == 'mercredi-annulation-mer-1511'
assert line1.event_slug == 'agenda@mercredi'
assert line1.event_label == 'Mercredi'
assert line1.agenda_slug == 'agenda'
assert line1.activity_label == 'Activity Label !'
assert line1.label == 'Mercredi'
assert line1.description == 'Annulation Mer 15/11'
assert line1.quantity == -decimal.Decimal('0.5')
@ -551,7 +593,10 @@ def test_close_line(app, user):
assert line1.details == {}
assert line1.pool is None
assert line2.slug == 'mercredi-reservation-mer-811'
assert line2.event_slug == 'mercredi-reservation-mer-811'
assert line2.event_slug == 'agenda@mercredi'
assert line2.event_label == 'Mercredi'
assert line2.agenda_slug == 'agenda'
assert line2.activity_label == 'Activity Label !'
assert line2.label == 'Mercredi'
assert line2.description == 'Réservation Mer 8/11'
assert line2.quantity == 1
@ -561,7 +606,10 @@ def test_close_line(app, user):
assert line2.user_first_name == 'First1'
assert line2.user_last_name == 'Last1'
assert line3.slug == 'repas-annulation-jeu-1611'
assert line3.event_slug == 'repas-annulation-jeu-1611'
assert line3.event_slug == 'agenda@repas'
assert line3.event_label == 'Repas'
assert line3.agenda_slug == 'agenda'
assert line3.activity_label == 'Activity Label !'
assert line3.label == 'Repas'
assert line3.description == 'Annulation Jeu 16/11'
assert line3.quantity == -1
@ -571,7 +619,10 @@ def test_close_line(app, user):
assert line3.user_first_name == 'First1'
assert line3.user_last_name == 'Last1'
assert line4.slug == 'repas-annulation-jeu-911'
assert line4.event_slug == 'repas-annulation-jeu-911'
assert line4.event_slug == 'agenda@repas'
assert line4.event_label == 'Repas'
assert line4.agenda_slug == 'agenda'
assert line4.activity_label == 'Activity Label !'
assert line4.label == 'Repas'
assert line4.description == 'Annulation Jeu 9/11'
assert line4.quantity == -1
@ -581,7 +632,10 @@ def test_close_line(app, user):
assert line4.user_first_name == 'First1'
assert line4.user_last_name == 'Last1'
assert line5.slug == 'repas-reservation-lun-1311'
assert line5.event_slug == 'repas-reservation-lun-1311'
assert line5.event_slug == 'agenda@repas'
assert line5.event_label == 'Repas'
assert line5.agenda_slug == 'agenda'
assert line5.activity_label == 'Activity Label !'
assert line5.label == 'Repas'
assert line5.description == 'Réservation Lun 13/11'
assert line5.quantity == 1
@ -591,7 +645,10 @@ def test_close_line(app, user):
assert line5.user_first_name == 'First1'
assert line5.user_last_name == 'Last1'
assert line6.slug == 'repas-reservation-lun-611-mar-711'
assert line6.event_slug == 'repas-reservation-lun-611-mar-711'
assert line6.event_slug == 'agenda@repas'
assert line6.event_label == 'Repas'
assert line6.agenda_slug == 'agenda'
assert line6.activity_label == 'Activity Label !'
assert line6.label == 'Repas'
assert line6.description == 'Réservation Lun 6/11, Mar 7/11'
assert line6.quantity == 2
@ -614,7 +671,10 @@ def test_close_line(app, user):
assert invoice.lines.count() == 4
line1, line2, line3, line4 = invoice.lines.all().order_by('pk')
assert line1.slug == 'mercredi-annulation-mer-1511'
assert line1.event_slug == 'mercredi-annulation-mer-1511'
assert line1.event_slug == 'agenda@mercredi'
assert line1.event_label == 'Mercredi'
assert line1.agenda_slug == 'agenda'
assert line1.activity_label == 'Activity Label !'
assert line1.label == 'Mercredi'
assert line1.description == 'Annulation Mer 15/11'
assert line1.quantity == -decimal.Decimal('0.5')
@ -624,7 +684,10 @@ def test_close_line(app, user):
assert line1.user_first_name == 'First1'
assert line1.user_last_name == 'Last1'
assert line2.slug == 'mercredi-reservation-mer-811'
assert line2.event_slug == 'mercredi-reservation-mer-811'
assert line2.event_slug == 'agenda@mercredi'
assert line2.event_label == 'Mercredi'
assert line2.agenda_slug == 'agenda'
assert line2.activity_label == 'Activity Label !'
assert line2.label == 'Mercredi'
assert line2.description == 'Réservation Mer 8/11'
assert line2.quantity == 1
@ -634,7 +697,10 @@ def test_close_line(app, user):
assert line2.user_first_name == 'First1'
assert line2.user_last_name == 'Last1'
assert line3.slug == 'repas-annulation-jeu-911-jeu-1611'
assert line3.event_slug == 'repas-annulation-jeu-911-jeu-1611'
assert line3.event_slug == 'agenda@repas'
assert line3.event_label == 'Repas'
assert line3.agenda_slug == 'agenda'
assert line3.activity_label == 'Activity Label !'
assert line3.label == 'Repas'
assert line3.description == 'Annulation Jeu 9/11, Jeu 16/11'
assert line3.quantity == -2
@ -644,7 +710,10 @@ def test_close_line(app, user):
assert line3.user_first_name == 'First1'
assert line3.user_last_name == 'Last1'
assert line4.slug == 'repas-reservation-lun-611-mar-711-lun-1311'
assert line4.event_slug == 'repas-reservation-lun-611-mar-711-lun-1311'
assert line4.event_slug == 'agenda@repas'
assert line4.event_label == 'Repas'
assert line4.agenda_slug == 'agenda'
assert line4.activity_label == 'Activity Label !'
assert line4.label == 'Repas'
assert line4.description == 'Réservation Lun 6/11, Mar 7/11, Lun 13/11'
assert line4.quantity == 3
@ -653,3 +722,85 @@ def test_close_line(app, user):
assert line4.user_external_id == 'user:1'
assert line4.user_first_name == 'First1'
assert line4.user_last_name == 'Last1'
# grouping but event_slug are not the same
basket_item.event_slug = 'agenda2@repas2'
basket_item.event_label = 'Repas2'
basket_item.agenda_slug = 'agenda2'
basket_item.activity_label = 'Activity Label !'
basket_item.save()
line.closed = False
line.save()
invoice.lines.all().delete()
resp = app.post('/api/regie/foo/basket/%s/line/%s/close/' % (basket.uuid, line.uuid))
assert resp.json == {'err': 0, 'data': {'line_id': str(line.uuid), 'closed': True}}
line.refresh_from_db()
assert line.closed is True
basket.refresh_from_db()
assert invoice.lines.count() == 5
line1, line2, line3, line4, line5 = invoice.lines.all().order_by('pk')
assert line1.slug == 'mercredi-annulation-mer-1511'
assert line1.event_slug == 'agenda@mercredi'
assert line1.event_label == 'Mercredi'
assert line1.agenda_slug == 'agenda'
assert line1.activity_label == 'Activity Label !'
assert line1.label == 'Mercredi'
assert line1.description == 'Annulation Mer 15/11'
assert line1.quantity == -decimal.Decimal('0.5')
assert line1.unit_amount == 5
assert line1.total_amount == -decimal.Decimal('2.5')
assert line1.user_external_id == 'user:1'
assert line1.user_first_name == 'First1'
assert line1.user_last_name == 'Last1'
assert line2.slug == 'mercredi-reservation-mer-811'
assert line2.event_slug == 'agenda@mercredi'
assert line2.event_label == 'Mercredi'
assert line2.agenda_slug == 'agenda'
assert line2.activity_label == 'Activity Label !'
assert line2.label == 'Mercredi'
assert line2.description == 'Réservation Mer 8/11'
assert line2.quantity == 1
assert line2.unit_amount == 5
assert line2.total_amount == 5
assert line2.user_external_id == 'user:1'
assert line2.user_first_name == 'First1'
assert line2.user_last_name == 'Last1'
assert line3.slug == 'repas-annulation-jeu-1611'
assert line3.event_slug == 'agenda2@repas2'
assert line3.event_label == 'Repas2'
assert line3.agenda_slug == 'agenda2'
assert line3.activity_label == 'Activity Label !'
assert line3.label == 'Repas'
assert line3.description == 'Annulation Jeu 16/11'
assert line3.quantity == -1
assert line3.unit_amount == 3
assert line3.total_amount == -3
assert line3.user_external_id == 'user:1'
assert line3.user_first_name == 'First1'
assert line3.user_last_name == 'Last1'
assert line4.slug == 'repas-annulation-jeu-911'
assert line4.event_slug == 'agenda@repas'
assert line4.event_label == 'Repas'
assert line4.agenda_slug == 'agenda'
assert line4.activity_label == 'Activity Label !'
assert line4.label == 'Repas'
assert line4.description == 'Annulation Jeu 9/11'
assert line4.quantity == -1
assert line4.unit_amount == 3
assert line4.total_amount == -3
assert line4.user_external_id == 'user:1'
assert line4.user_first_name == 'First1'
assert line4.user_last_name == 'Last1'
assert line5.slug == 'repas-reservation-lun-611-mar-711-lun-1311'
assert line5.event_slug == 'agenda@repas'
assert line5.event_label == 'Repas'
assert line5.agenda_slug == 'agenda'
assert line5.activity_label == 'Activity Label !'
assert line5.label == 'Repas'
assert line5.description == 'Réservation Lun 6/11, Mar 7/11, Lun 13/11'
assert line5.quantity == 3
assert line5.unit_amount == 3
assert line5.total_amount == 9
assert line5.user_external_id == 'user:1'
assert line5.user_first_name == 'First1'
assert line5.user_last_name == 'Last1'

View File

@ -708,6 +708,10 @@ def test_basket_validate_generate_credit(app, simple_user):
user_external_id='user:1',
user_first_name='First1',
user_last_name='Last1',
event_slug='agenda@repas',
event_label='Repas',
agenda_slug='agenda',
activity_label='Activity Label !',
)
draft_invoice.refresh_from_db()
assert draft_invoice.total_amount == -1
@ -766,6 +770,10 @@ def test_basket_validate_generate_credit(app, simple_user):
assert line1.user_first_name == 'First1'
assert line1.user_last_name == 'Last1'
assert line1.description == 'A description'
assert line1.event_slug == 'agenda@repas'
assert line1.event_label == 'Repas'
assert line1.agenda_slug == 'agenda'
assert line1.activity_label == 'Activity Label !'
assert Invoice.objects.count() == 0
# check callback

View File

@ -2213,6 +2213,9 @@ def test_regie_credits(app, admin_user):
user_external_id='user:1',
user_first_name='User1',
user_last_name='Name1',
event_slug='agenda-a@event-a',
agenda_slug='agenda-a',
activity_label='Agenda A',
)
CreditLine.objects.create(
slug='event-b-foo-bar',
@ -2224,6 +2227,9 @@ def test_regie_credits(app, admin_user):
user_external_id='user:2',
user_first_name='User2',
user_last_name='Name2',
event_slug='agenda-b@event-b',
agenda_slug='agenda-b',
activity_label='Agenda B',
)
CreditLine.objects.create(
slug='event-a-foo-bar',
@ -2235,6 +2241,9 @@ def test_regie_credits(app, admin_user):
user_external_id='user:1',
user_first_name='User1',
user_last_name='Name1',
event_slug='agenda-a@event-a',
agenda_slug='agenda-a',
activity_label='Agenda A',
)
payment1 = Payment.objects.create(
regie=regie,
@ -2274,6 +2283,9 @@ def test_regie_credits(app, admin_user):
user_external_id='user:1',
user_first_name='User1',
user_last_name='Name1',
event_slug='agenda-a@event-aa',
agenda_slug='agenda-a',
activity_label='Agenda A',
)
CreditAssignment.objects.create(
invoice=invoice,
@ -2317,14 +2329,16 @@ def test_regie_credits(app, admin_user):
credit1.pk,
)
lines_resp = app.get(lines_url)
assert len(lines_resp.pyquery('tr')) == 12
assert len(lines_resp.pyquery('tr')) == 14
assert [PyQuery(tr).text() for tr in lines_resp.pyquery('tr')] == [
'User1 Name1',
'Description\nAmount\nQuantity\nSubtotal',
'Agenda A',
'Event A\nA description\n1.00€\n1.2\n1.20€',
'Event A\n3.00€\n1\n3.00€',
'User2 Name2',
'Description\nAmount\nQuantity\nSubtotal',
'Agenda B',
'Event B\n2.00€\n1\n2.00€',
'Assignments',
'Payment\nDate\nAmount',
@ -2372,10 +2386,11 @@ def test_regie_credits(app, admin_user):
credit2.pk,
)
lines_resp = app.get(lines_url)
assert len(lines_resp.pyquery('tr')) == 8
assert len(lines_resp.pyquery('tr')) == 9
assert [PyQuery(tr).text() for tr in lines_resp.pyquery('tr')] == [
'User1 Name1',
'Description\nAmount\nQuantity\nSubtotal',
'Agenda A',
'Event AA\n1.00€\n1\n1.00€',
'Assignments',
'Payment\nDate\nAmount',
@ -2468,6 +2483,11 @@ def test_regie_credits(app, admin_user):
({'assigned': 'yes'}, 1),
({'assigned': 'partially'}, 1),
({'assigned': 'no'}, 1),
({'agenda': 'agenda-a'}, 2),
({'agenda': 'agenda-b'}, 1),
({'event': 'agenda-a@event-a'}, 1),
({'event': 'agenda-a@event-aa'}, 1),
({'event': 'agenda-b@event-b'}, 1),
]
for param, result in params:
resp = app.get(
@ -2500,6 +2520,9 @@ def test_regie_credit_pdf(app, admin_user):
user_external_id='user:1',
user_first_name='User1',
user_last_name='Name1',
event_slug='agenda-a@event-a',
agenda_slug='agenda-a',
activity_label='Agenda A',
)
CreditLine.objects.create(
event_date=datetime.date(2022, 9, 2),
@ -2510,6 +2533,9 @@ def test_regie_credit_pdf(app, admin_user):
user_external_id='user:2',
user_first_name='User2',
user_last_name='Name2',
event_slug='agenda-a@event-a',
agenda_slug='agenda-a',
activity_label='Agenda A',
)
CreditLine.objects.create(
event_date=datetime.date(2022, 9, 3),
@ -2520,6 +2546,9 @@ def test_regie_credit_pdf(app, admin_user):
user_external_id='user:1',
user_first_name='User1',
user_last_name='Name1',
event_slug='agenda-b@event-b',
agenda_slug='agenda-b',
activity_label='Agenda B',
)
app = login(app)
@ -2536,11 +2565,11 @@ def test_regie_credit_pdf(app, admin_user):
assert [PyQuery(tr).text() for tr in resp.pyquery('table#lines tr')] == [
'User1 Name1',
'Services\nDetails\nUA\nQTY\nTA',
'Label 11\nA description\n1.00€\n1.2\n1.20€',
'Label 13\n3.00€\n1\n3.00€',
'Label 11\nAgenda A\n\nA description\n1.00€\n1.2\n1.20€',
'Label 13\nAgenda B\n\n3.00€\n1\n3.00€',
'User2 Name2',
'Services\nDetails\nUA\nQTY\nTA',
'Label 12\n2.00€\n1\n2.00€',
'Label 12\nAgenda A\n\n2.00€\n1\n2.00€',
'Total amount:\n6.20€',
]