listing des factures et de leurs lignes (#73514) #17
|
@ -0,0 +1,23 @@
|
|||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('invoicing', '0008_injected_line'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='draftinvoiceline',
|
||||
name='user_name',
|
||||
field=models.CharField(default='', max_length=250),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='invoiceline',
|
||||
name='user_name',
|
||||
field=models.CharField(default='', max_length=250),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
|
@ -0,0 +1,25 @@
|
|||
import datetime
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('invoicing', '0009_user_name'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='draftinvoiceline',
|
||||
name='event_date',
|
||||
field=models.DateField(default=datetime.date.today),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='invoiceline',
|
||||
name='event_date',
|
||||
field=models.DateField(default=datetime.date.today),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
|
@ -152,11 +152,9 @@ class Pool(models.Model):
|
|||
# get agendas with pricing corresponding to the period
|
||||
agendas = utils.get_agendas(pool=self)
|
||||
# get subscribed users for each agenda, for the period
|
||||
user_external_ids = utils.get_users_from_subscriptions(agendas=agendas, pool=self)
|
||||
users = utils.get_users_from_subscriptions(agendas=agendas, pool=self)
|
||||
# get invoice lines for all subscribed users, for each agenda in the corresponding period
|
||||
lines = utils.get_all_invoice_lines(
|
||||
agendas=agendas, user_external_ids=user_external_ids, pool=self
|
||||
)
|
||||
lines = utils.get_all_invoice_lines(agendas=agendas, users=users, pool=self)
|
||||
# and generate invoices
|
||||
utils.generate_invoices_from_lines(agendas=agendas, all_lines=lines, pool=self)
|
||||
except (RegieNotConfigured, ChronoError) as e:
|
||||
|
@ -208,6 +206,7 @@ class InjectedLine(models.Model):
|
|||
|
||||
|
||||
class AbstractInvoiceLine(models.Model):
|
||||
event_date = models.DateField()
|
||||
slug = models.SlugField(max_length=250)
|
||||
label = models.CharField(max_length=260)
|
||||
quantity = models.FloatField()
|
||||
|
@ -215,6 +214,7 @@ class AbstractInvoiceLine(models.Model):
|
|||
total_amount = models.DecimalField(max_digits=9, decimal_places=2)
|
||||
|
||||
user_external_id = models.CharField(max_length=250)
|
||||
user_name = models.CharField(max_length=250)
|
||||
payer_external_id = models.CharField(max_length=250)
|
||||
event = JSONField(default=dict)
|
||||
pricing_data = JSONField(default=dict, encoder=DjangoJSONEncoder)
|
||||
|
|
|
@ -13,76 +13,28 @@
|
|||
{% if pool.error_count %}<span class="tag tag-error">{{ pool.error_count }}</span>{% endif %}
|
||||
{{ pool.created_at|date:"DATETIME_FORMAT" }}
|
||||
</h2>
|
||||
{% if pool.draft and pool.status != 'registered' and pool.status != 'running' %}
|
||||
<span class="actions">
|
||||
<span class="actions">
|
||||
<a href="{% url 'lingo-manager-invoicing-pool-journal' pk=object.pk pool_pk=pool.pk %}">{% trans "Journal" %}</a>
|
||||
{% if pool.draft and pool.status != 'registered' and pool.status != 'running' %}
|
||||
<a href="{% url 'lingo-manager-invoicing-pool-delete' pk=object.pk pool_pk=pool.pk %}" rel="popup">{% trans "Delete" %}</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</span>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if pool.status == 'failed' %}
|
||||
<div class="pk-error">
|
||||
<p>{% trans "Error while running pool." %}</p>
|
||||
{% if pool.exception %}<pre>{{ pool.exception }}</pre>{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<table class="main pools">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "PK" %}</th>
|
||||
<th>{% trans "Invoice PK" %}</th>
|
||||
<th>{% trans "Label" %}</th>
|
||||
<th>{% trans "Slug" %}</th>
|
||||
<th>{% trans "Quantity" %}</th>
|
||||
<th>{% trans "Unit amount" %}</th>
|
||||
<th>{% trans "Total amount" %}</th>
|
||||
<th>{% trans "User" %}</th>
|
||||
<th>{% trans "Payer" %}</th>
|
||||
<th>{% trans "Status" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for line in lines %}
|
||||
<tr data-line-id="{{ line.pk }}">
|
||||
<td class="line_id">{{ line.pk }}</td>
|
||||
<td>{{ line.invoice_id|default:'' }}</td>
|
||||
<td>{{ line.label }}</td>
|
||||
<td>{{ line.slug }}</td>
|
||||
<td>{{ line.quantity }}</td>
|
||||
<td>{{ line.unit_amount }}</td>
|
||||
<td>{{ line.total_amount }}</td>
|
||||
<td>{{ line.user_external_id }}</td>
|
||||
<td>{{ line.payer_external_id }}</td>
|
||||
<td class="status">
|
||||
<span class="tag tag-{{ line.status }}">{{ line.get_status_display }}</span>
|
||||
{% if line.status != 'success' %}({{ line.get_error_display }}){% endif %}
|
||||
{% if line.from_injected_line_id %}({% trans "Injected" %}){% endif %}
|
||||
</td>
|
||||
<td><a class="details-toggle">{% trans "see details" %}</a></td>
|
||||
</tr>
|
||||
<tr data-details-for-line-id="{{ line.pk }}" style="display: none">
|
||||
<td colspan="10">
|
||||
<pre>{{ line.pricing_data|pprint }}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<script>
|
||||
$(function() {
|
||||
$('a.details-toggle').on('click', function() {
|
||||
var line_id = $(this).parents('tr').data('line-id');
|
||||
var $details = $('tr[data-details-for-line-id=' + line_id + ']');
|
||||
if ($details.is(':visible')) {
|
||||
$(this).text('{% trans "see details" %}');
|
||||
$details.hide();
|
||||
} else {
|
||||
$(this).text('{% trans "hide details" %}');
|
||||
$details.show();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<div>
|
||||
{% for line in lines %}
|
||||
{% ifchanged line.invoice_id %}
|
||||
{% if not forloop.first %}</ul>{% endif %}
|
||||
<h3 data-invoice-id="{{ line.invoice_id }}">
|
||||
{% blocktrans with number=line.invoice_id payer=line.invoice.payer amount=line.invoice.total_amount %}Invoice #{{ number }} addressed to {{ payer }}, amount {{ amount }}€{% endblocktrans %}
|
||||
</h3>
|
||||
<ul class="objects-list" data-invoice-id="{{ line.invoice_id }}">
|
||||
{% endifchanged %}
|
||||
<li>
|
||||
#{{ line.pk }} {{ line.user_name }} - {{ line.event_date|date:"d/m/Y" }} - {{ line.label }} ({{ line.total_amount }})
|
||||
</li>
|
||||
{% if forloop.last %}</ul>{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
{% extends "lingo/invoicing/manager_pool_detail.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block breadcrumb %}
|
||||
{{ block.super }}
|
||||
<a href="{% url 'lingo-manager-invoicing-pool-journal' pk=object.pk pool_pk=pool.pk %}">{% trans "Journal" %}</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block appbar %}
|
||||
<h2 id="pool-title">
|
||||
{% if pool.success_count %}<span class="tag tag-success">{{ pool.success_count }}</span>{% endif %}
|
||||
{% if pool.warning_count %}<span class="tag tag-warning">{{ pool.warning_count }}</span>{% endif %}
|
||||
{% if pool.error_count %}<span class="tag tag-error">{{ pool.error_count }}</span>{% endif %}
|
||||
{{ pool.created_at|date:"DATETIME_FORMAT" }}
|
||||
</h2>
|
||||
{% if pool.draft and pool.status != 'registered' and pool.status != 'running' %}
|
||||
<span class="actions">
|
||||
<a href="{% url 'lingo-manager-invoicing-pool-delete' pk=object.pk pool_pk=pool.pk %}" rel="popup">{% trans "Delete" %}</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if pool.status == 'failed' %}
|
||||
<div class="pk-error">
|
||||
<p>{% trans "Error while running pool." %}</p>
|
||||
{% if pool.exception %}<pre>{{ pool.exception }}</pre>{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<table class="main pools">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "PK" %}</th>
|
||||
<th>{% trans "Invoice PK" %}</th>
|
||||
<th>{% trans "Event" %}</th>
|
||||
<th>{% trans "Quantity" %}</th>
|
||||
<th>{% trans "Unit amount" %}</th>
|
||||
<th>{% trans "Total amount" %}</th>
|
||||
<th>{% trans "User" %}</th>
|
||||
<th>{% trans "Payer" %}</th>
|
||||
<th>{% trans "Status" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for line in lines %}
|
||||
<tr data-line-id="{{ line.pk }}">
|
||||
<td class="line_id">{{ line.pk }}</td>
|
||||
<td>{{ line.invoice_id|default:'' }}</td>
|
||||
<td>
|
||||
{{ line.event_date|date:"d/m/Y" }} - {{ line.label }}
|
||||
<br />
|
||||
({{ line.slug }})
|
||||
</td>
|
||||
<td>{{ line.quantity }}</td>
|
||||
<td>{{ line.unit_amount }}</td>
|
||||
<td>{{ line.total_amount }}</td>
|
||||
<td>{{ line.user_name }} ({{ line.user_external_id }})</td>
|
||||
<td>{{ line.payer_external_id }}</td>
|
||||
<td class="status">
|
||||
<span class="tag tag-{{ line.status }}">{{ line.get_status_display }}</span>
|
||||
{% if line.status != 'success' %}({{ line.get_error_display }}){% endif %}
|
||||
{% if line.from_injected_line_id %}({% trans "Injected" %}){% endif %}
|
||||
</td>
|
||||
<td><a class="details-toggle">{% trans "see details" %}</a></td>
|
||||
</tr>
|
||||
<tr data-details-for-line-id="{{ line.pk }}" style="display: none">
|
||||
<td colspan="10">
|
||||
{% trans "Pricing data:" %}
|
||||
<pre>{{ line.pricing_data|pprint }}</pre>
|
||||
{% trans "Event:" %}
|
||||
<pre>{{ line.event|pprint }}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<script>
|
||||
$(function() {
|
||||
$('a.details-toggle').on('click', function() {
|
||||
var line_id = $(this).parents('tr').data('line-id');
|
||||
var $details = $('tr[data-details-for-line-id=' + line_id + ']');
|
||||
if ($details.is(':visible')) {
|
||||
$(this).text('{% trans "see details" %}');
|
||||
$details.hide();
|
||||
} else {
|
||||
$(this).text('{% trans "hide details" %}');
|
||||
$details.show();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -74,6 +74,11 @@ urlpatterns = [
|
|||
views.pool_detail,
|
||||
name='lingo-manager-invoicing-pool-detail',
|
||||
),
|
||||
path(
|
||||
'campaign/<int:pk>/pool/<int:pool_pk>/journal/',
|
||||
views.pool_journal,
|
||||
name='lingo-manager-invoicing-pool-journal',
|
||||
),
|
||||
path(
|
||||
'campaign/<int:pk>/pool/<int:pool_pk>/delete/',
|
||||
views.pool_delete,
|
||||
|
|
|
@ -35,7 +35,7 @@ def get_agendas(pool):
|
|||
|
||||
|
||||
def get_users_from_subscriptions(agendas, pool):
|
||||
user_external_ids = set()
|
||||
users = {}
|
||||
for agenda in agendas:
|
||||
subscriptions = get_subscriptions(
|
||||
agenda_slug=agenda.slug,
|
||||
|
@ -43,11 +43,15 @@ def get_users_from_subscriptions(agendas, pool):
|
|||
date_end=pool.campaign.date_end,
|
||||
)
|
||||
for subscription in subscriptions:
|
||||
user_external_ids.add(subscription['user_external_id'])
|
||||
return user_external_ids
|
||||
user_external_id = subscription['user_external_id']
|
||||
if user_external_id in users:
|
||||
continue
|
||||
user_name = '%s %s' % (subscription['user_first_name'], subscription['user_last_name'])
|
||||
users[user_external_id] = user_name.strip()[:250] or user_external_id
|
||||
return [(user_id, user_name) for user_id, user_name in users.items()]
|
||||
|
||||
|
||||
def get_invoice_lines_for_user(agendas, agendas_pricings, user_external_id, pool):
|
||||
def get_invoice_lines_for_user(agendas, agendas_pricings, user_external_id, user_name, pool):
|
||||
def get_agenda_pricing(agendas_pricings_for_agenda, date_event):
|
||||
# same logic as AgendaPricing.get_agenda_pricing
|
||||
for agenda_pricing in agendas_pricings_for_agenda:
|
||||
|
@ -104,12 +108,14 @@ def get_invoice_lines_for_user(agendas, agendas_pricings, user_external_id, pool
|
|||
}
|
||||
lines.append(
|
||||
DraftInvoiceLine(
|
||||
event_date=event_date,
|
||||
slug=event_slug,
|
||||
label=serialized_event['label'],
|
||||
quantity=0,
|
||||
unit_amount=0,
|
||||
total_amount=0,
|
||||
user_external_id=user_external_id,
|
||||
user_name=user_name,
|
||||
payer_external_id=user_external_id, # XXX
|
||||
event=serialized_event,
|
||||
pricing_data=pricing_error,
|
||||
|
@ -121,12 +127,14 @@ def get_invoice_lines_for_user(agendas, agendas_pricings, user_external_id, pool
|
|||
# XXX log all context !
|
||||
lines.append(
|
||||
DraftInvoiceLine(
|
||||
event_date=event_date,
|
||||
slug=event_slug,
|
||||
label=serialized_event['label'],
|
||||
quantity=1,
|
||||
unit_amount=pricing_data['pricing'],
|
||||
total_amount=pricing_data['pricing'],
|
||||
user_external_id=user_external_id,
|
||||
user_name=user_name,
|
||||
payer_external_id=user_external_id, # XXX
|
||||
event=serialized_event,
|
||||
pricing_data=pricing_data,
|
||||
|
@ -157,12 +165,14 @@ def get_invoice_lines_for_user(agendas, agendas_pricings, user_external_id, pool
|
|||
for injected_line in injected_lines:
|
||||
lines.append(
|
||||
DraftInvoiceLine(
|
||||
event_date=injected_line.event_date,
|
||||
slug=injected_line.slug,
|
||||
label=injected_line.label,
|
||||
quantity=injected_line.quantity,
|
||||
unit_amount=injected_line.unit_amount,
|
||||
total_amount=injected_line.total_amount,
|
||||
user_external_id=injected_line.user_external_id,
|
||||
user_external_id=user_external_id,
|
||||
user_name=user_name,
|
||||
payer_external_id=injected_line.user_external_id,
|
||||
status='success',
|
||||
pool=pool,
|
||||
|
@ -175,7 +185,7 @@ def get_invoice_lines_for_user(agendas, agendas_pricings, user_external_id, pool
|
|||
return lines
|
||||
|
||||
|
||||
def get_all_invoice_lines(agendas, user_external_ids, pool):
|
||||
def get_all_invoice_lines(agendas, users, pool):
|
||||
agendas_pricings = (
|
||||
AgendaPricing.objects.filter(flat_fee_schedule=False)
|
||||
.extra(
|
||||
|
@ -186,12 +196,13 @@ def get_all_invoice_lines(agendas, user_external_ids, pool):
|
|||
)
|
||||
|
||||
lines = []
|
||||
for user_external_id in user_external_ids:
|
||||
for user_external_id, user_name in users:
|
||||
# generate lines for each user
|
||||
lines += get_invoice_lines_for_user(
|
||||
agendas=agendas,
|
||||
agendas_pricings=agendas_pricings,
|
||||
user_external_id=user_external_id,
|
||||
user_name=user_name,
|
||||
pool=pool,
|
||||
)
|
||||
return lines
|
||||
|
|
|
@ -297,6 +297,39 @@ class PoolDetailView(DetailView):
|
|||
model = Pool
|
||||
pk_url_kwarg = 'pool_pk'
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.campaign = get_object_or_404(Campaign, pk=kwargs['pk'])
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_queryset(self):
|
||||
return self.campaign.pool_set.all()
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
kwargs['object'] = self.campaign
|
||||
kwargs['pool'] = self.object
|
||||
line_model = InvoiceLine
|
||||
if self.object.draft:
|
||||
line_model = DraftInvoiceLine
|
||||
all_lines = line_model.objects.filter(pool=self.object)
|
||||
self.object.error_count = len([line for line in all_lines if line.status == 'error'])
|
||||
self.object.warning_count = len([line for line in all_lines if line.status == 'warning'])
|
||||
self.object.success_count = len([line for line in all_lines if line.status == 'success'])
|
||||
kwargs['lines'] = (
|
||||
all_lines.filter(invoice__isnull=False)
|
||||
.select_related('invoice')
|
||||
.order_by('invoice__pk', 'user_external_id', 'pk')
|
||||
)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
pool_detail = PoolDetailView.as_view()
|
||||
|
||||
|
||||
class PoolJournalView(DetailView):
|
||||
template_name = 'lingo/invoicing/manager_pool_journal.html'
|
||||
model = Pool
|
||||
pk_url_kwarg = 'pool_pk'
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.campaign = get_object_or_404(Campaign, pk=kwargs['pk'])
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
@ -317,7 +350,7 @@ class PoolDetailView(DetailView):
|
|||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
pool_detail = PoolDetailView.as_view()
|
||||
pool_journal = PoolJournalView.as_view()
|
||||
|
||||
|
||||
class PoolAddView(FormView):
|
||||
|
|
|
@ -120,6 +120,7 @@ def test_detail_campaign(app, admin_user):
|
|||
assert '/manage/invoicing/campaign/%s/pool/add/' % (campaign.pk) not in resp
|
||||
|
||||
line = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
quantity=1,
|
||||
unit_amount=1,
|
||||
total_amount=1,
|
||||
|
@ -149,6 +150,7 @@ def test_detail_campaign(app, admin_user):
|
|||
assert 'tag-error' not in resp
|
||||
|
||||
line = InvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
quantity=1,
|
||||
unit_amount=1,
|
||||
total_amount=1,
|
||||
|
@ -264,6 +266,7 @@ def test_delete_campaign(app, admin_user):
|
|||
regie = Regie.objects.create(label='Foo')
|
||||
invoice = DraftInvoice.objects.create(date_issue=datetime.date.today(), regie=regie, pool=pool)
|
||||
DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
invoice=invoice,
|
||||
quantity=1,
|
||||
unit_amount=1,
|
||||
|
@ -386,6 +389,7 @@ def test_detail_pool(app, admin_user):
|
|||
assert '/manage/invoicing/campaign/%s/pool/%s/delete/' % (campaign.pk, pool.pk) in resp
|
||||
|
||||
line = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
quantity=1,
|
||||
unit_amount=1,
|
||||
total_amount=1,
|
||||
|
@ -417,6 +421,7 @@ def test_detail_pool(app, admin_user):
|
|||
pool.draft = False
|
||||
pool.save()
|
||||
line = InvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
quantity=1,
|
||||
unit_amount=1,
|
||||
total_amount=1,
|
||||
|
@ -441,7 +446,223 @@ def test_detail_pool(app, admin_user):
|
|||
assert 'tag-error' not in resp
|
||||
|
||||
|
||||
def test_detail_pool_lines(app, admin_user):
|
||||
def test_detail_pool_invoices(app, admin_user):
|
||||
campaign = Campaign.objects.create(
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
date_issue=datetime.date(2022, 10, 31),
|
||||
)
|
||||
pool = Pool.objects.create(
|
||||
campaign=campaign,
|
||||
draft=True,
|
||||
status='completed',
|
||||
)
|
||||
regie = Regie.objects.create(label='Foo')
|
||||
invoice1 = DraftInvoice.objects.create(
|
||||
date_issue=datetime.date.today(), regie=regie, pool=pool, payer='payer:1'
|
||||
)
|
||||
invoice2 = DraftInvoice.objects.create(
|
||||
date_issue=datetime.date.today(), regie=regie, pool=pool, payer='payer:2'
|
||||
)
|
||||
|
||||
line11 = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
invoice=invoice1,
|
||||
quantity=1,
|
||||
unit_amount=1,
|
||||
total_amount=1,
|
||||
status='success',
|
||||
pool=pool,
|
||||
label='Label 11',
|
||||
user_external_id='user:1',
|
||||
user_name='User1 Name1',
|
||||
)
|
||||
line12 = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 2),
|
||||
invoice=invoice1,
|
||||
quantity=1,
|
||||
unit_amount=2,
|
||||
total_amount=2,
|
||||
status='success',
|
||||
pool=pool,
|
||||
label='Label 12',
|
||||
user_external_id='user:2',
|
||||
user_name='User2 Name2',
|
||||
)
|
||||
line13 = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 3),
|
||||
invoice=invoice1,
|
||||
quantity=1,
|
||||
unit_amount=3,
|
||||
total_amount=3,
|
||||
status='success',
|
||||
pool=pool,
|
||||
label='Label 13',
|
||||
user_external_id='user:1',
|
||||
user_name='User1 Name1',
|
||||
)
|
||||
|
||||
orphan_line = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
quantity=1,
|
||||
unit_amount=42,
|
||||
total_amount=42,
|
||||
status='failed',
|
||||
pool=pool,
|
||||
label='Label 14',
|
||||
user_external_id='user:1',
|
||||
user_name='User1 Name1',
|
||||
)
|
||||
|
||||
line21 = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
invoice=invoice2,
|
||||
quantity=1,
|
||||
unit_amount=1,
|
||||
total_amount=1,
|
||||
status='success',
|
||||
pool=pool,
|
||||
label='Label 21',
|
||||
user_external_id='user:1',
|
||||
user_name='User1 Name1',
|
||||
)
|
||||
|
||||
app = login(app)
|
||||
resp = app.get('/manage/invoicing/campaign/%s/pool/%s/' % (campaign.pk, pool.pk))
|
||||
assert '#%s' % orphan_line.pk not in resp
|
||||
assert (
|
||||
resp.pyquery('h3[data-invoice-id="%s"]' % invoice1.pk).text()
|
||||
== 'Invoice #%s addressed to payer:1, amount 6.00€' % invoice1.pk
|
||||
)
|
||||
assert len(resp.pyquery('ul[data-invoice-id="%s"] li' % invoice1.pk)) == 3
|
||||
assert (
|
||||
resp.pyquery('ul[data-invoice-id="%s"] li:nth-child(1)' % invoice1.pk).text()
|
||||
== '#%s User1 Name1 - 01/09/2022 - Label 11 (1.00)' % line11.pk
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('ul[data-invoice-id="%s"] li:nth-child(2)' % invoice1.pk).text()
|
||||
== '#%s User1 Name1 - 03/09/2022 - Label 13 (3.00)' % line13.pk
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('ul[data-invoice-id="%s"] li:nth-child(3)' % invoice1.pk).text()
|
||||
== '#%s User2 Name2 - 02/09/2022 - Label 12 (2.00)' % line12.pk
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('h3[data-invoice-id="%s"]' % invoice2.pk).text()
|
||||
== 'Invoice #%s addressed to payer:2, amount 1.00€' % invoice2.pk
|
||||
)
|
||||
assert len(resp.pyquery('ul[data-invoice-id="%s"] li' % invoice2.pk)) == 1
|
||||
assert (
|
||||
resp.pyquery('ul[data-invoice-id="%s"] li:nth-child(1)' % invoice2.pk).text()
|
||||
== '#%s User1 Name1 - 01/09/2022 - Label 21 (1.00)' % line21.pk
|
||||
)
|
||||
|
||||
|
||||
def test_journal_pool(app, admin_user):
|
||||
campaign = Campaign.objects.create(
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
date_issue=datetime.date(2022, 10, 31),
|
||||
)
|
||||
campaign2 = Campaign.objects.create(
|
||||
date_start=datetime.date(2022, 10, 1),
|
||||
date_end=datetime.date(2022, 11, 1),
|
||||
date_issue=datetime.date(2022, 11, 30),
|
||||
)
|
||||
pool = Pool.objects.create(
|
||||
campaign=campaign,
|
||||
draft=True,
|
||||
status='completed',
|
||||
)
|
||||
|
||||
app = login(app)
|
||||
resp = app.get('/manage/invoicing/campaign/%s/pool/%s/journal/' % (campaign.pk, pool.pk))
|
||||
assert '/manage/invoicing/campaign/%s/pool/%s/delete/' % (campaign.pk, pool.pk) in resp
|
||||
|
||||
app.get('/manage/invoicing/campaign/%s/pool/%s/journal/' % (0, pool.pk), status=404)
|
||||
app.get('/manage/invoicing/campaign/%s/pool/%s/journal/' % (campaign2.pk, pool.pk), status=404)
|
||||
app.get('/manage/invoicing/campaign/%s/pool/%s/journal/' % (campaign.pk, 0), status=404)
|
||||
|
||||
pool.draft = False
|
||||
pool.save()
|
||||
resp = app.get('/manage/invoicing/campaign/%s/pool/%s/journal/' % (campaign.pk, pool.pk))
|
||||
assert '/manage/invoicing/campaign/%s/pool/%s/delete/' % (campaign.pk, pool.pk) not in resp
|
||||
|
||||
pool.draft = True
|
||||
pool.status = 'registered'
|
||||
pool.save()
|
||||
resp = app.get('/manage/invoicing/campaign/%s/pool/%s/journal/' % (campaign.pk, pool.pk))
|
||||
assert '/manage/invoicing/campaign/%s/pool/%s/delete/' % (campaign.pk, pool.pk) not in resp
|
||||
|
||||
pool.status = 'running'
|
||||
pool.save()
|
||||
resp = app.get('/manage/invoicing/campaign/%s/pool/%s/journal/' % (campaign.pk, pool.pk))
|
||||
assert '/manage/invoicing/campaign/%s/pool/%s/delete/' % (campaign.pk, pool.pk) not in resp
|
||||
|
||||
pool.status = 'failed'
|
||||
pool.save()
|
||||
resp = app.get('/manage/invoicing/campaign/%s/pool/%s/journal/' % (campaign.pk, pool.pk))
|
||||
assert '/manage/invoicing/campaign/%s/pool/%s/delete/' % (campaign.pk, pool.pk) in resp
|
||||
|
||||
line = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
quantity=1,
|
||||
unit_amount=1,
|
||||
total_amount=1,
|
||||
status='success',
|
||||
pool=pool,
|
||||
)
|
||||
resp = app.get('/manage/invoicing/campaign/%s/pool/%s/journal/' % (campaign.pk, pool.pk))
|
||||
assert '<span class="tag tag-success">1</span>' in resp
|
||||
assert 'tag-warning' not in resp
|
||||
assert 'tag-error' not in resp
|
||||
line.status = 'error'
|
||||
line.save()
|
||||
resp = app.get('/manage/invoicing/campaign/%s/pool/%s/journal/' % (campaign.pk, pool.pk))
|
||||
assert 'tag-success' not in resp
|
||||
assert 'tag-warning' not in resp
|
||||
assert '<span class="tag tag-error">1</span>' in resp
|
||||
line.status = 'warning'
|
||||
line.save()
|
||||
resp = app.get('/manage/invoicing/campaign/%s/pool/%s/journal/' % (campaign.pk, pool.pk))
|
||||
assert 'tag-success' not in resp
|
||||
assert '<span class="tag tag-warning">1</span>' in resp
|
||||
assert 'tag-error' not in resp
|
||||
line.delete()
|
||||
resp = app.get('/manage/invoicing/campaign/%s/pool/%s/journal/' % (campaign.pk, pool.pk))
|
||||
assert 'tag-success' not in resp
|
||||
assert 'tag-warning' not in resp
|
||||
assert 'tag-error' not in resp
|
||||
|
||||
pool.draft = False
|
||||
pool.save()
|
||||
line = InvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
quantity=1,
|
||||
unit_amount=1,
|
||||
total_amount=1,
|
||||
status='success',
|
||||
pool=pool,
|
||||
)
|
||||
resp = app.get('/manage/invoicing/campaign/%s/pool/%s/journal/' % (campaign.pk, pool.pk))
|
||||
assert '<span class="tag tag-success">1</span>' in resp
|
||||
assert 'tag-warning' not in resp
|
||||
assert 'tag-error' not in resp
|
||||
line.status = 'error'
|
||||
line.save()
|
||||
resp = app.get('/manage/invoicing/campaign/%s/pool/%s/journal/' % (campaign.pk, pool.pk))
|
||||
assert 'tag-success' not in resp
|
||||
assert 'tag-warning' not in resp
|
||||
assert '<span class="tag tag-error">1</span>' in resp
|
||||
line.status = 'warning'
|
||||
line.save()
|
||||
resp = app.get('/manage/invoicing/campaign/%s/pool/%s/journal/' % (campaign.pk, pool.pk))
|
||||
assert 'tag-success' not in resp
|
||||
assert '<span class="tag tag-warning">1</span>' in resp
|
||||
assert 'tag-error' not in resp
|
||||
|
||||
|
||||
def test_journal_pool_lines(app, admin_user):
|
||||
campaign = Campaign.objects.create(
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
|
@ -457,6 +678,7 @@ def test_detail_pool_lines(app, admin_user):
|
|||
|
||||
lines = [
|
||||
DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
invoice=invoice,
|
||||
quantity=1,
|
||||
unit_amount=1,
|
||||
|
@ -464,6 +686,7 @@ def test_detail_pool_lines(app, admin_user):
|
|||
status='success',
|
||||
pool=pool,
|
||||
pricing_data={'foo': 'bar'},
|
||||
event={'event': 'foobar'},
|
||||
)
|
||||
]
|
||||
errors = [
|
||||
|
@ -493,6 +716,7 @@ def test_detail_pool_lines(app, admin_user):
|
|||
for error, error_details in errors:
|
||||
lines.append(
|
||||
DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
invoice=invoice,
|
||||
quantity=1,
|
||||
unit_amount=1,
|
||||
|
@ -503,6 +727,7 @@ def test_detail_pool_lines(app, admin_user):
|
|||
'error': error,
|
||||
'error_details': error_details,
|
||||
},
|
||||
event={'event': 'foobar'},
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -510,11 +735,11 @@ def test_detail_pool_lines(app, admin_user):
|
|||
return (' '.join([v.strip() for v in value.split('\n')])).strip()
|
||||
|
||||
app = login(app)
|
||||
resp = app.get('/manage/invoicing/campaign/%s/pool/%s/' % (campaign.pk, pool.pk))
|
||||
resp = app.get('/manage/invoicing/campaign/%s/pool/%s/journal/' % (campaign.pk, pool.pk))
|
||||
assert format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[0].pk).text()) == 'Success'
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[0].pk).text().strip()
|
||||
== "{'foo': 'bar'}"
|
||||
== "{'foo': 'bar'} {'event': 'foobar'}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[1].pk).text())
|
||||
|
@ -522,7 +747,7 @@ def test_detail_pool_lines(app, admin_user):
|
|||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[1].pk).text().strip()
|
||||
== "{'error': 'AgendaPricingNotFound', 'error_details': {}}"
|
||||
== "{'error': 'AgendaPricingNotFound', 'error_details': {}} {'event': 'foobar'}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[2].pk).text())
|
||||
|
@ -530,7 +755,7 @@ def test_detail_pool_lines(app, admin_user):
|
|||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[2].pk).text().strip()
|
||||
== "{'error': 'CriteriaConditionNotFound', 'error_details': {'category': 'cat-foo'}}"
|
||||
== "{'error': 'CriteriaConditionNotFound', 'error_details': {'category': 'cat-foo'}} {'event': 'foobar'}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[3].pk).text())
|
||||
|
@ -538,7 +763,7 @@ def test_detail_pool_lines(app, admin_user):
|
|||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[3].pk).text().strip()
|
||||
== "{'error': 'MultipleDefaultCriteriaCondition', 'error_details': {'category': 'cat-foo'}}"
|
||||
== "{'error': 'MultipleDefaultCriteriaCondition', 'error_details': {'category': 'cat-foo'}} {'event': 'foobar'}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[4].pk).text())
|
||||
|
@ -546,7 +771,7 @@ def test_detail_pool_lines(app, admin_user):
|
|||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[4].pk).text().strip()
|
||||
== "{'error': 'PricingDataError', 'error_details': {'criterias': {'foo': 'bar', 'qf': 'qf-1'}}}"
|
||||
== "{'error': 'PricingDataError', 'error_details': {'criterias': {'foo': 'bar', 'qf': 'qf-1'}}} {'event': 'foobar'}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[5].pk).text())
|
||||
|
@ -554,7 +779,7 @@ def test_detail_pool_lines(app, admin_user):
|
|||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[5].pk).text().strip()
|
||||
== "{'error': 'PricingDataFormatError', 'error_details': {'pricing': 'foobar', 'wanted': 'decimal'}}"
|
||||
== "{'error': 'PricingDataFormatError', 'error_details': {'pricing': 'foobar', 'wanted': 'decimal'}} {'event': 'foobar'}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[6].pk).text())
|
||||
|
@ -562,7 +787,7 @@ def test_detail_pool_lines(app, admin_user):
|
|||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[6].pk).text().strip()
|
||||
== "{'error': 'PricingUnknownCheckStatusError', 'error_details': {'status': 'unknown'}}"
|
||||
== "{'error': 'PricingUnknownCheckStatusError', 'error_details': {'status': 'unknown'}} {'event': 'foobar'}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[7].pk).text())
|
||||
|
@ -570,7 +795,7 @@ def test_detail_pool_lines(app, admin_user):
|
|||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[7].pk).text().strip()
|
||||
== "{'error': 'PricingEventNotCheckedError', 'error_details': {}}"
|
||||
== "{'error': 'PricingEventNotCheckedError', 'error_details': {}} {'event': 'foobar'}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[8].pk).text())
|
||||
|
@ -578,7 +803,7 @@ def test_detail_pool_lines(app, admin_user):
|
|||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[8].pk).text().strip()
|
||||
== "{'error': 'PricingBookingNotCheckedError', 'error_details': {}}"
|
||||
== "{'error': 'PricingBookingNotCheckedError', 'error_details': {}} {'event': 'foobar'}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[9].pk).text())
|
||||
|
@ -586,7 +811,7 @@ def test_detail_pool_lines(app, admin_user):
|
|||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[9].pk).text().strip()
|
||||
== "{'error': 'PricingMultipleBookingError', 'error_details': {}}"
|
||||
== "{'error': 'PricingMultipleBookingError', 'error_details': {}} {'event': 'foobar'}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[10].pk).text())
|
||||
|
@ -594,7 +819,7 @@ def test_detail_pool_lines(app, admin_user):
|
|||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[10].pk).text().strip()
|
||||
== "{'error': 'PricingBookingCheckTypeError', 'error_details': {'reason': 'not-found'}}"
|
||||
== "{'error': 'PricingBookingCheckTypeError', 'error_details': {'reason': 'not-found'}} {'event': 'foobar'}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[11].pk).text())
|
||||
|
@ -602,7 +827,7 @@ def test_detail_pool_lines(app, admin_user):
|
|||
)
|
||||
assert resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[11].pk).text().strip() == (
|
||||
"{'error': 'PricingBookingCheckTypeError', 'error_details': {'check_type': 'foo-reason', "
|
||||
"'check_type_group': 'foo-bar', 'reason': 'not-configured'}}"
|
||||
"'check_type_group': 'foo-bar', 'reason': 'not-configured'}} {'event': 'foobar'}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[12].pk).text())
|
||||
|
@ -610,7 +835,7 @@ def test_detail_pool_lines(app, admin_user):
|
|||
)
|
||||
assert resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[12].pk).text().strip() == (
|
||||
"{'error': 'PricingBookingCheckTypeError', 'error_details': {'check_type': 'foo-reason', "
|
||||
"'check_type_group': 'foo-bar', 'reason': 'wrong-kind'}}"
|
||||
"'check_type_group': 'foo-bar', 'reason': 'wrong-kind'}} {'event': 'foobar'}"
|
||||
)
|
||||
|
||||
|
||||
|
@ -633,6 +858,7 @@ def test_delete_pool(app, admin_user):
|
|||
regie = Regie.objects.create(label='Foo')
|
||||
invoice = DraftInvoice.objects.create(date_issue=datetime.date.today(), regie=regie, pool=pool)
|
||||
DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
invoice=invoice,
|
||||
quantity=1,
|
||||
unit_amount=1,
|
||||
|
|
|
@ -130,12 +130,12 @@ def test_get_users_from_subscriptions(mock_subscriptions):
|
|||
)
|
||||
|
||||
# no agendas
|
||||
assert utils.get_users_from_subscriptions(agendas=[], pool=pool) == set()
|
||||
assert utils.get_users_from_subscriptions(agendas=[], pool=pool) == []
|
||||
assert mock_subscriptions.call_args_list == []
|
||||
|
||||
# no subscriptions
|
||||
mock_subscriptions.return_value = []
|
||||
assert utils.get_users_from_subscriptions(agendas=[agenda1, agenda2], pool=pool) == set()
|
||||
assert utils.get_users_from_subscriptions(agendas=[agenda1, agenda2], pool=pool) == []
|
||||
assert mock_subscriptions.call_args_list == [
|
||||
mock.call(
|
||||
agenda_slug='agenda-1', date_start=datetime.date(2022, 9, 1), date_end=datetime.date(2022, 10, 1)
|
||||
|
@ -151,16 +151,22 @@ def test_get_users_from_subscriptions(mock_subscriptions):
|
|||
[
|
||||
{
|
||||
'user_external_id': 'user:1',
|
||||
'user_first_name': 'User1',
|
||||
'user_last_name': 'Name1',
|
||||
'date_start': '2022-08-01',
|
||||
'date_end': '2022-09-02',
|
||||
},
|
||||
{
|
||||
'user_external_id': 'user:1',
|
||||
'user_first_name': 'Foo Bar',
|
||||
'user_last_name': '',
|
||||
'date_start': '2022-09-02',
|
||||
'date_end': '2022-09-03',
|
||||
},
|
||||
{
|
||||
'user_external_id': 'user:2',
|
||||
'user_first_name': '',
|
||||
'user_last_name': '',
|
||||
'date_start': '2022-09-02',
|
||||
'date_end': '2022-09-03',
|
||||
},
|
||||
|
@ -168,12 +174,17 @@ def test_get_users_from_subscriptions(mock_subscriptions):
|
|||
[
|
||||
{
|
||||
'user_external_id': 'user:1',
|
||||
'user_first_name': 'User1 Name1',
|
||||
'user_last_name': '',
|
||||
'date_start': '2022-08-01',
|
||||
'date_end': '2022-10-01',
|
||||
},
|
||||
],
|
||||
]
|
||||
assert utils.get_users_from_subscriptions(agendas=[agenda1, agenda2], pool=pool) == {'user:1', 'user:2'}
|
||||
assert utils.get_users_from_subscriptions(agendas=[agenda1, agenda2], pool=pool) == [
|
||||
('user:1', 'User1 Name1'),
|
||||
('user:2', 'user:2'),
|
||||
]
|
||||
assert mock_subscriptions.call_args_list == [
|
||||
mock.call(
|
||||
agenda_slug='agenda-1', date_start=datetime.date(2022, 9, 1), date_end=datetime.date(2022, 10, 1)
|
||||
|
@ -202,6 +213,7 @@ def test_get_invoice_lines_for_user_check_status_error(mock_status):
|
|||
agendas=[agenda],
|
||||
agendas_pricings=[],
|
||||
user_external_id='user:1',
|
||||
user_name='User1 Name1',
|
||||
pool=pool,
|
||||
)
|
||||
|
||||
|
@ -267,6 +279,7 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
)
|
||||
# ok, same campaign
|
||||
DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
quantity=0,
|
||||
unit_amount=0,
|
||||
total_amount=0,
|
||||
|
@ -319,6 +332,7 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
)
|
||||
# nok, already invoiced
|
||||
InvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 15),
|
||||
quantity=0,
|
||||
unit_amount=0,
|
||||
total_amount=0,
|
||||
|
@ -338,6 +352,7 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
)
|
||||
# nok, other campaign
|
||||
DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 16),
|
||||
quantity=0,
|
||||
unit_amount=0,
|
||||
total_amount=0,
|
||||
|
@ -351,6 +366,7 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
agendas=[],
|
||||
agendas_pricings=[agenda_pricing],
|
||||
user_external_id='user:1',
|
||||
user_name='User1 Name1',
|
||||
pool=pool,
|
||||
)
|
||||
== []
|
||||
|
@ -364,6 +380,7 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
agendas=[agenda1, agenda2],
|
||||
agendas_pricings=[agenda_pricing],
|
||||
user_external_id='user:1',
|
||||
user_name='User1 Name1',
|
||||
pool=pool,
|
||||
)
|
||||
assert len(lines) == 2 # injected lines
|
||||
|
@ -433,6 +450,7 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
agendas=[agenda1, agenda2],
|
||||
agendas_pricings=[agenda_pricing],
|
||||
user_external_id='user:1',
|
||||
user_name='User1 Name1',
|
||||
pool=pool,
|
||||
)
|
||||
assert mock_pricing_data_event.call_args_list == [
|
||||
|
@ -493,12 +511,14 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
line1, line2, line3, line4, line5, line6 = lines
|
||||
assert isinstance(line1, DraftInvoiceLine)
|
||||
assert line1.invoice is None
|
||||
assert line1.event_date == datetime.date(2022, 9, 1)
|
||||
assert line1.slug == 'agenda-1@event-1'
|
||||
assert line1.label == 'Event 1'
|
||||
assert line1.quantity == 1
|
||||
assert line1.unit_amount == 1
|
||||
assert line1.total_amount == 1
|
||||
assert line1.user_external_id == 'user:1'
|
||||
assert line1.user_name == 'User1 Name1'
|
||||
assert line1.payer_external_id == 'user:1'
|
||||
assert line1.event == {
|
||||
'agenda': 'agenda-1',
|
||||
|
@ -512,12 +532,14 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
assert line1.from_injected_line is None
|
||||
assert isinstance(line2, DraftInvoiceLine)
|
||||
assert line2.invoice is None
|
||||
assert line2.event_date == datetime.date(2022, 9, 2)
|
||||
assert line2.slug == 'agenda-1@event-2'
|
||||
assert line2.label == 'Event 2'
|
||||
assert line2.quantity == 1
|
||||
assert line2.unit_amount == 2
|
||||
assert line2.total_amount == 2
|
||||
assert line2.user_external_id == 'user:1'
|
||||
assert line2.user_name == 'User1 Name1'
|
||||
assert line2.payer_external_id == 'user:1'
|
||||
assert line2.event == {
|
||||
'agenda': 'agenda-1',
|
||||
|
@ -531,12 +553,14 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
assert line2.from_injected_line is None
|
||||
assert isinstance(line3, DraftInvoiceLine)
|
||||
assert line3.invoice is None
|
||||
assert line3.event_date == datetime.date(2022, 9, 1)
|
||||
assert line3.slug == 'agenda-2@eveeent-1'
|
||||
assert line3.label == 'Eveeent 1'
|
||||
assert line3.quantity == 1
|
||||
assert line3.unit_amount == 3
|
||||
assert line3.total_amount == 3
|
||||
assert line3.user_external_id == 'user:1'
|
||||
assert line3.user_name == 'User1 Name1'
|
||||
assert line3.payer_external_id == 'user:1'
|
||||
assert line3.event == {
|
||||
'agenda': 'agenda-2',
|
||||
|
@ -550,12 +574,14 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
assert line3.from_injected_line is None
|
||||
assert isinstance(line4, DraftInvoiceLine)
|
||||
assert line4.invoice is None
|
||||
assert line4.event_date == datetime.date(2022, 9, 2)
|
||||
assert line4.slug == 'agenda-2@eveeent-2'
|
||||
assert line4.label == 'Eveeent 2'
|
||||
assert line4.quantity == 1
|
||||
assert line4.unit_amount == 4
|
||||
assert line4.total_amount == 4
|
||||
assert line4.user_external_id == 'user:1'
|
||||
assert line4.user_name == 'User1 Name1'
|
||||
assert line4.payer_external_id == 'user:1'
|
||||
assert line4.event == {
|
||||
'agenda': 'agenda-2',
|
||||
|
@ -569,12 +595,14 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
assert line4.from_injected_line is None
|
||||
assert isinstance(line5, DraftInvoiceLine)
|
||||
assert line5.invoice is None
|
||||
assert line5.event_date == injected_line2.event_date
|
||||
assert line5.slug == 'event-2022-09-01'
|
||||
assert line5.label == 'Event 2022-09-01'
|
||||
assert line5.quantity == 2
|
||||
assert line5.unit_amount == 1.5
|
||||
assert line5.total_amount == 3
|
||||
assert line5.user_external_id == 'user:1'
|
||||
assert line5.user_name == 'User1 Name1'
|
||||
assert line5.payer_external_id == 'user:1'
|
||||
assert line5.event == {}
|
||||
assert line5.pricing_data == {}
|
||||
|
@ -583,12 +611,14 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
assert line5.from_injected_line == injected_line2
|
||||
assert isinstance(line6, DraftInvoiceLine)
|
||||
assert line6.invoice is None
|
||||
assert line6.event_date == injected_line4.event_date
|
||||
assert line6.slug == 'event-2022-09-30'
|
||||
assert line6.label == 'Event 2022-09-30'
|
||||
assert line6.quantity == 3
|
||||
assert line6.unit_amount == 1.5
|
||||
assert line6.total_amount == 4.5
|
||||
assert line6.user_external_id == 'user:1'
|
||||
assert line6.user_name == 'User1 Name1'
|
||||
assert line6.payer_external_id == 'user:1'
|
||||
assert line6.event == {}
|
||||
assert line6.pricing_data == {}
|
||||
|
@ -652,6 +682,7 @@ def test_get_invoice_lines_for_user_check_status_agenda_pricing_dates(mock_statu
|
|||
agendas=[agenda],
|
||||
agendas_pricings=AgendaPricing.objects.all(),
|
||||
user_external_id='user:1',
|
||||
user_name='User1 Name1',
|
||||
pool=pool,
|
||||
)
|
||||
assert len(lines) == 1
|
||||
|
@ -677,6 +708,7 @@ def test_get_invoice_lines_for_user_check_status_agenda_pricing_dates(mock_statu
|
|||
agendas=[agenda],
|
||||
agendas_pricings=AgendaPricing.objects.all(),
|
||||
user_external_id='user:1',
|
||||
user_name='User1 Name1',
|
||||
pool=pool,
|
||||
)
|
||||
assert len(lines) == 1
|
||||
|
@ -701,6 +733,7 @@ def test_get_invoice_lines_for_user_check_status_agenda_pricing_dates(mock_statu
|
|||
agendas=[agenda],
|
||||
agendas_pricings=AgendaPricing.objects.all(),
|
||||
user_external_id='user:1',
|
||||
user_name='User1 Name1',
|
||||
pool=pool,
|
||||
)
|
||||
assert len(lines) == 1
|
||||
|
@ -713,6 +746,7 @@ def test_get_invoice_lines_for_user_check_status_agenda_pricing_dates(mock_statu
|
|||
assert line.unit_amount == 0
|
||||
assert line.total_amount == 0
|
||||
assert line.user_external_id == 'user:1'
|
||||
assert line.user_name == 'User1 Name1'
|
||||
assert line.payer_external_id == 'user:1'
|
||||
assert line.event == {
|
||||
'agenda': 'agenda',
|
||||
|
@ -788,18 +822,21 @@ def test_get_invoice_lines_for_user_check_status_pricing_error(mock_pricing_data
|
|||
agendas=[agenda],
|
||||
agendas_pricings=[agenda_pricing],
|
||||
user_external_id='user:1',
|
||||
user_name='User1 Name1',
|
||||
pool=pool,
|
||||
)
|
||||
assert len(lines) == 3
|
||||
line1, line2, line3 = lines
|
||||
assert isinstance(line1, DraftInvoiceLine)
|
||||
assert line1.invoice is None
|
||||
assert line1.event_date == datetime.date(2022, 9, 1)
|
||||
assert line1.slug == 'agenda@event-1'
|
||||
assert line1.label == 'Event 1'
|
||||
assert line1.quantity == 1
|
||||
assert line1.unit_amount == 1
|
||||
assert line1.total_amount == 1
|
||||
assert line1.user_external_id == 'user:1'
|
||||
assert line1.user_name == 'User1 Name1'
|
||||
assert line1.payer_external_id == 'user:1'
|
||||
assert line1.event == {
|
||||
'agenda': 'agenda',
|
||||
|
@ -812,12 +849,14 @@ def test_get_invoice_lines_for_user_check_status_pricing_error(mock_pricing_data
|
|||
assert line1.pool == pool
|
||||
assert isinstance(line2, DraftInvoiceLine)
|
||||
assert line2.invoice is None
|
||||
assert line2.event_date == datetime.date(2022, 9, 2)
|
||||
assert line2.slug == 'agenda@event-2'
|
||||
assert line2.label == 'Event 2'
|
||||
assert line2.quantity == 0
|
||||
assert line2.unit_amount == 0
|
||||
assert line2.total_amount == 0
|
||||
assert line2.user_external_id == 'user:1'
|
||||
assert line2.user_name == 'User1 Name1'
|
||||
assert line2.payer_external_id == 'user:1'
|
||||
assert line2.event == {
|
||||
'agenda': 'agenda',
|
||||
|
@ -830,12 +869,14 @@ def test_get_invoice_lines_for_user_check_status_pricing_error(mock_pricing_data
|
|||
assert line2.pool == pool
|
||||
assert isinstance(line3, DraftInvoiceLine)
|
||||
assert line3.invoice is None
|
||||
assert line3.event_date == datetime.date(2022, 9, 3)
|
||||
assert line3.slug == 'agenda@event-3'
|
||||
assert line3.label == 'Event 3'
|
||||
assert line3.quantity == 1
|
||||
assert line3.unit_amount == 3
|
||||
assert line3.total_amount == 3
|
||||
assert line3.user_external_id == 'user:1'
|
||||
assert line3.user_name == 'User1 Name1'
|
||||
assert line3.payer_external_id == 'user:1'
|
||||
assert line3.event == {
|
||||
'agenda': 'agenda',
|
||||
|
@ -864,18 +905,21 @@ def test_get_all_invoice_lines(mock_user_lines):
|
|||
)
|
||||
|
||||
line1 = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
quantity=0,
|
||||
unit_amount=0,
|
||||
total_amount=0,
|
||||
pool=pool,
|
||||
)
|
||||
line2 = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
quantity=0,
|
||||
unit_amount=0,
|
||||
total_amount=0,
|
||||
pool=pool,
|
||||
)
|
||||
line3 = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
quantity=0,
|
||||
unit_amount=0,
|
||||
total_amount=0,
|
||||
|
@ -888,7 +932,7 @@ def test_get_all_invoice_lines(mock_user_lines):
|
|||
assert (
|
||||
utils.get_all_invoice_lines(
|
||||
agendas=[agenda1, agenda2],
|
||||
user_external_ids=[],
|
||||
users=[],
|
||||
pool=pool,
|
||||
)
|
||||
== []
|
||||
|
@ -898,7 +942,7 @@ def test_get_all_invoice_lines(mock_user_lines):
|
|||
# with subscribed users
|
||||
assert utils.get_all_invoice_lines(
|
||||
agendas=[agenda1, agenda2],
|
||||
user_external_ids=['user:1', 'user:2'],
|
||||
users=[('user:1', 'User1 Name1'), ('user:2', 'User2 Name2')],
|
||||
pool=pool,
|
||||
) == [line1, line2, line3]
|
||||
assert mock_user_lines.call_args_list == [
|
||||
|
@ -906,12 +950,14 @@ def test_get_all_invoice_lines(mock_user_lines):
|
|||
agendas=[agenda1, agenda2],
|
||||
agendas_pricings=mock.ANY,
|
||||
user_external_id='user:1',
|
||||
user_name='User1 Name1',
|
||||
pool=pool,
|
||||
),
|
||||
mock.call(
|
||||
agendas=[agenda1, agenda2],
|
||||
agendas_pricings=mock.ANY,
|
||||
user_external_id='user:2',
|
||||
user_name='User2 Name2',
|
||||
pool=pool,
|
||||
),
|
||||
]
|
||||
|
@ -1018,7 +1064,7 @@ def test_get_all_invoice_lines_queryset(mock_status):
|
|||
with CaptureQueriesContext(connection) as ctx:
|
||||
lines = utils.get_all_invoice_lines(
|
||||
agendas=[agenda1, agenda2],
|
||||
user_external_ids=['user:1', 'user:2'],
|
||||
users=[('user:1', 'User1 Name1'), ('user:2', 'User2 Name2')],
|
||||
pool=pool,
|
||||
)
|
||||
assert lines
|
||||
|
@ -1044,6 +1090,7 @@ def test_generate_invoices_from_lines():
|
|||
)
|
||||
|
||||
line_error = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
event={'agenda': 'agenda-1'},
|
||||
quantity=0,
|
||||
unit_amount=0,
|
||||
|
@ -1054,6 +1101,7 @@ def test_generate_invoices_from_lines():
|
|||
pool=pool,
|
||||
)
|
||||
line1 = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
event={'agenda': 'agenda-1'},
|
||||
quantity=1,
|
||||
unit_amount=1,
|
||||
|
@ -1064,6 +1112,7 @@ def test_generate_invoices_from_lines():
|
|||
pool=pool,
|
||||
)
|
||||
line2 = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
event={'agenda': 'agenda-1'},
|
||||
quantity=1,
|
||||
unit_amount=2,
|
||||
|
@ -1074,6 +1123,7 @@ def test_generate_invoices_from_lines():
|
|||
pool=pool,
|
||||
)
|
||||
line3 = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
event={'agenda': 'agenda-2'},
|
||||
quantity=1,
|
||||
unit_amount=3,
|
||||
|
@ -1084,6 +1134,7 @@ def test_generate_invoices_from_lines():
|
|||
pool=pool,
|
||||
)
|
||||
line4 = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
event={'agenda': 'agenda-2'},
|
||||
quantity=1,
|
||||
unit_amount=4,
|
||||
|
@ -1094,6 +1145,7 @@ def test_generate_invoices_from_lines():
|
|||
pool=pool,
|
||||
)
|
||||
line5 = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
event={'agenda': 'agenda-3'},
|
||||
quantity=1,
|
||||
unit_amount=5,
|
||||
|
@ -1104,6 +1156,7 @@ def test_generate_invoices_from_lines():
|
|||
pool=pool,
|
||||
)
|
||||
DraftInvoiceLine.objects.create( # not used for generation
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
event={'agenda': 'agenda-3'},
|
||||
quantity=1,
|
||||
unit_amount=5,
|
||||
|
@ -1114,6 +1167,7 @@ def test_generate_invoices_from_lines():
|
|||
pool=pool,
|
||||
)
|
||||
line6 = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
event={'agenda': 'agenda-4'}, # regie not configured
|
||||
quantity=1,
|
||||
unit_amount=6,
|
||||
|
@ -1135,6 +1189,7 @@ def test_generate_invoices_from_lines():
|
|||
regie=regie1,
|
||||
)
|
||||
line7 = DraftInvoiceLine.objects.create(
|
||||
event_date=datetime.date(2022, 9, 1),
|
||||
quantity=1,
|
||||
unit_amount=7,
|
||||
total_amount=7,
|
||||
|
@ -1232,7 +1287,7 @@ def test_generate_invoices(mock_generate, mock_lines, mock_users, mock_agendas):
|
|||
assert mock_lines.call_args_list == [
|
||||
mock.call(
|
||||
agendas=[agenda1, agenda2],
|
||||
user_external_ids=['foo', 'bar'],
|
||||
users=['foo', 'bar'],
|
||||
pool=pool,
|
||||
)
|
||||
]
|
||||
|
|
|
@ -30,6 +30,7 @@ def test_invoice_total_amount(draft):
|
|||
|
||||
# line with error status, ignored
|
||||
line = line_model.objects.create(
|
||||
event_date=datetime.date.today(),
|
||||
invoice=invoice, # with invoice
|
||||
quantity=0,
|
||||
unit_amount=0,
|
||||
|
@ -80,6 +81,7 @@ def test_invoice_total_amount(draft):
|
|||
|
||||
# create line with invoice, status success
|
||||
line2 = line_model.objects.create(
|
||||
event_date=datetime.date.today(),
|
||||
invoice=invoice,
|
||||
quantity=1,
|
||||
unit_amount=20,
|
||||
|
@ -109,6 +111,7 @@ def test_invoice_total_amount(draft):
|
|||
|
||||
# create line without invoice, status success
|
||||
line3 = line_model.objects.create(
|
||||
event_date=datetime.date.today(),
|
||||
quantity=1,
|
||||
unit_amount=20,
|
||||
total_amount=20,
|
||||
|
|
Loading…
Reference in New Issue