975 lines
34 KiB
Python
975 lines
34 KiB
Python
import datetime
|
|
from urllib.parse import urlparse
|
|
|
|
import pytest
|
|
from django.contrib.auth.models import Group
|
|
from django.urls import reverse
|
|
from django.utils.formats import date_format
|
|
from django.utils.timezone import localtime
|
|
|
|
from lingo.agendas.models import Agenda
|
|
from lingo.invoicing.models import (
|
|
Campaign,
|
|
Counter,
|
|
DraftInvoiceLine,
|
|
InjectedLine,
|
|
Invoice,
|
|
InvoiceLine,
|
|
InvoicePayment,
|
|
Payment,
|
|
Pool,
|
|
Regie,
|
|
)
|
|
from tests.utils import login
|
|
|
|
pytestmark = pytest.mark.django_db
|
|
|
|
|
|
def test_manager_invoicing_regie_list_title(app, admin_user):
|
|
app = login(app)
|
|
resp = app.get(reverse('lingo-manager-invoicing-regie-list'))
|
|
h2 = resp.pyquery('div#appbar h2')
|
|
assert h2.text() == 'Regies'
|
|
|
|
|
|
def test_manager_invoicing_regie_list_empty(app, admin_user):
|
|
app = login(app)
|
|
resp = app.get(reverse('lingo-manager-invoicing-regie-list'))
|
|
msg_info = resp.pyquery('div#content div.big-msg-info')
|
|
assert (
|
|
msg_info.text()
|
|
== "This site doesn't have any regie yet. Click on the \"New\" button in the top right of the page to add a first one."
|
|
)
|
|
|
|
|
|
def test_manager_invoicing_regie_list_add_button(app, admin_user):
|
|
app = login(app)
|
|
resp = app.get(reverse('lingo-manager-invoicing-regie-list'))
|
|
add_button = resp.pyquery('span.actions a[href="%s"]' % reverse('lingo-manager-invoicing-regie-add'))
|
|
assert add_button.text() == 'New regie'
|
|
|
|
|
|
def test_manager_invoicing_regie_list_show_objetcs(app, admin_user):
|
|
app = login(app)
|
|
regie = Regie.objects.create(label='Foo')
|
|
resp = app.get(reverse('lingo-manager-invoicing-regie-list'))
|
|
href = resp.pyquery(
|
|
'div#content div ul li a[href="%s"]'
|
|
% reverse('lingo-manager-invoicing-regie-detail', kwargs={'pk': regie.pk})
|
|
)
|
|
assert href.text() == 'Foo [identifier: foo]'
|
|
|
|
|
|
def test_manager_invoicing_regie_add(app, admin_user):
|
|
app = login(app)
|
|
assert Regie.objects.count() == 0
|
|
group = Group.objects.create(name='role-foo')
|
|
resp = app.get(reverse('lingo-manager-invoicing-regie-add'))
|
|
h2 = resp.pyquery('div#appbar h2')
|
|
assert h2.text() == 'New regie'
|
|
form = resp.form
|
|
form.set('label', 'Foo')
|
|
form.set('description', 'foo description')
|
|
form.set('cashier_role', group.id)
|
|
response = form.submit().follow()
|
|
assert Regie.objects.count() == 1
|
|
regie = Regie.objects.first()
|
|
assert regie.label == 'Foo'
|
|
assert regie.slug == 'foo'
|
|
assert regie.description == 'foo description'
|
|
assert regie.cashier_role == group
|
|
assert urlparse(response.request.url).path == reverse(
|
|
'lingo-manager-invoicing-regie-detail', kwargs={'pk': regie.pk}
|
|
)
|
|
|
|
|
|
def test_manager_invoicing_regie_detail(app, admin_user):
|
|
app = login(app)
|
|
group = Group.objects.create(name='role-foo')
|
|
regie = Regie.objects.create(label='Foo', description='foo description', cashier_role=group)
|
|
resp = app.get(reverse('lingo-manager-invoicing-regie-detail', kwargs={'pk': regie.pk}))
|
|
h2 = resp.pyquery('div#appbar h2')
|
|
assert h2.text() == 'Regie - Foo'
|
|
descr = resp.pyquery('div#panel-settings p')[0]
|
|
assert descr.text == 'foo description'
|
|
slug = resp.pyquery('div#panel-settings ul li')[0]
|
|
assert slug.text == 'Identifier: foo'
|
|
cashier_role = resp.pyquery('div#panel-settings ul li')[1]
|
|
assert cashier_role.text == 'Cashier role: role-foo'
|
|
usage = resp.pyquery('div#panel-usage div')[0]
|
|
assert 'This Regie is not used yet.' in usage.text
|
|
edit_button = resp.pyquery(
|
|
'span.actions a[href="%s"]' % reverse('lingo-manager-invoicing-regie-edit', kwargs={'pk': regie.pk})
|
|
)
|
|
assert edit_button.text() == 'Edit'
|
|
delete_button = resp.pyquery(
|
|
'span.actions a[href="%s"]' % reverse('lingo-manager-invoicing-regie-delete', kwargs={'pk': regie.pk})
|
|
)
|
|
assert delete_button.text() == 'Delete'
|
|
|
|
agenda1 = Agenda.objects.create(label='Foo Bar', regie=regie)
|
|
agenda2 = Agenda.objects.create(label='Foo Bar 2', regie=regie)
|
|
agenda3 = Agenda.objects.create(label='Foo Bar 3')
|
|
resp = app.get(reverse('lingo-manager-invoicing-regie-detail', kwargs={'pk': regie.pk}))
|
|
assert '/manage/pricing/agenda/%s/' % agenda1.pk in resp
|
|
assert '/manage/pricing/agenda/%s/' % agenda2.pk in resp
|
|
assert '/manage/pricing/agenda/%s/' % agenda3.pk not in resp
|
|
|
|
campaign = Campaign.objects.create(
|
|
regie=regie,
|
|
date_start=datetime.date(2022, 9, 1),
|
|
date_end=datetime.date(2022, 10, 1),
|
|
date_publication=datetime.date(2022, 10, 1),
|
|
date_payment_deadline=datetime.date(2022, 10, 31),
|
|
date_issue=datetime.date(2022, 10, 31),
|
|
date_debit=datetime.date(2022, 11, 15),
|
|
)
|
|
resp = app.get(reverse('lingo-manager-invoicing-regie-detail', kwargs={'pk': regie.pk}))
|
|
href = resp.pyquery(
|
|
'div#panel-campaigns ul li a[href="%s"]'
|
|
% reverse('lingo-manager-invoicing-campaign-detail', kwargs={'regie_pk': regie.pk, 'pk': campaign.pk})
|
|
)
|
|
assert href.text() == '(01/09/2022 - 01/10/2022) [issue date: 31/10/2022]'
|
|
|
|
campaign.finalized = True
|
|
campaign.save()
|
|
resp = app.get(reverse('lingo-manager-invoicing-regie-detail', kwargs={'pk': regie.pk}))
|
|
href = resp.pyquery(
|
|
'div#panel-campaigns ul li a[href="%s"]'
|
|
% reverse('lingo-manager-invoicing-campaign-detail', kwargs={'regie_pk': regie.pk, 'pk': campaign.pk})
|
|
)
|
|
assert href.text() == '(01/09/2022 - 01/10/2022) [issue date: 31/10/2022] finalized'
|
|
|
|
|
|
def test_manager_invoicing_regie_edit(app, admin_user):
|
|
app = login(app)
|
|
group_foo = Group.objects.create(name='role-foo')
|
|
group_bar = Group.objects.create(name='role-bar')
|
|
regie = Regie.objects.create(label='Foo', description='foo description', cashier_role=group_foo)
|
|
resp = app.get(reverse('lingo-manager-invoicing-regie-edit', kwargs={'pk': regie.pk}))
|
|
h2 = resp.pyquery('div#appbar h2')
|
|
assert h2.text() == 'Edit regie - Foo'
|
|
form = resp.form
|
|
form.set('label', 'Foo bar')
|
|
form.set('slug', 'foo-bar')
|
|
form.set('description', 'foo new description')
|
|
form.set('cashier_role', group_bar.id)
|
|
response = form.submit().follow()
|
|
assert Regie.objects.count() == 1
|
|
regie = Regie.objects.first()
|
|
assert regie.label == 'Foo bar'
|
|
assert regie.slug == 'foo-bar'
|
|
assert regie.description == 'foo new description'
|
|
assert regie.cashier_role == group_bar
|
|
assert urlparse(response.request.url).path == reverse(
|
|
'lingo-manager-invoicing-regie-detail', kwargs={'pk': regie.pk}
|
|
)
|
|
|
|
Regie.objects.create(label='Foo', description='foo description', cashier_role=group_foo)
|
|
resp = app.get(reverse('lingo-manager-invoicing-regie-edit', kwargs={'pk': regie.pk}))
|
|
form = resp.form
|
|
form.set('slug', 'foo')
|
|
response = form.submit()
|
|
assert response.context['form'].errors['slug'] == ['Another regie exists with the same identifier.']
|
|
|
|
|
|
def test_manager_invoicing_regie_delete(app, admin_user):
|
|
app = login(app)
|
|
group = Group.objects.create(name='role-foo')
|
|
regie = Regie.objects.create(label='Foo', description='foo description', cashier_role=group)
|
|
assert Regie.objects.count() == 1
|
|
resp = app.get(reverse('lingo-manager-invoicing-regie-delete', kwargs={'pk': regie.pk}))
|
|
response = resp.form.submit().follow()
|
|
assert Regie.objects.count() == 0
|
|
assert urlparse(response.request.url).path == reverse('lingo-manager-invoicing-regie-list')
|
|
|
|
# can not delete regie containing campaign
|
|
regie.save()
|
|
campaign = Campaign.objects.create(
|
|
regie=regie,
|
|
date_start=datetime.date(2022, 9, 1),
|
|
date_end=datetime.date(2022, 10, 1),
|
|
date_publication=datetime.date(2022, 10, 1),
|
|
date_payment_deadline=datetime.date(2022, 10, 31),
|
|
date_issue=datetime.date(2022, 10, 31),
|
|
date_debit=datetime.date(2022, 11, 15),
|
|
)
|
|
resp = app.get(reverse('lingo-manager-invoicing-regie-detail', kwargs={'pk': regie.pk}))
|
|
assert reverse('lingo-manager-invoicing-regie-delete', kwargs={'pk': regie.pk}) not in resp
|
|
resp = app.get(reverse('lingo-manager-invoicing-regie-delete', kwargs={'pk': regie.pk}), status=404)
|
|
|
|
campaign.delete()
|
|
|
|
# can not delete regie containing injected line
|
|
injected_line = InjectedLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 1),
|
|
quantity=1,
|
|
unit_amount=1,
|
|
total_amount=1,
|
|
regie=regie,
|
|
)
|
|
resp = app.get(reverse('lingo-manager-invoicing-regie-detail', kwargs={'pk': regie.pk}))
|
|
assert reverse('lingo-manager-invoicing-regie-delete', kwargs={'pk': regie.pk}) not in resp
|
|
resp = app.get(reverse('lingo-manager-invoicing-regie-delete', kwargs={'pk': regie.pk}), status=404)
|
|
|
|
injected_line.delete()
|
|
|
|
# check counters are deleted
|
|
Counter.get_count(regie=regie, name='bar')
|
|
assert Counter.objects.count() == 1
|
|
resp = app.get(reverse('lingo-manager-invoicing-regie-delete', kwargs={'pk': regie.pk}))
|
|
response = resp.form.submit().follow()
|
|
assert Regie.objects.count() == 0
|
|
assert Counter.objects.count() == 0
|
|
|
|
|
|
def test_non_invoiced_line_list(app, admin_user):
|
|
regie = Regie.objects.create(label='Regie')
|
|
other_regie = Regie.objects.create(label='Other Regie')
|
|
|
|
campaign = Campaign.objects.create(
|
|
regie=regie,
|
|
date_start=datetime.date(2022, 9, 1),
|
|
date_end=datetime.date(2022, 10, 1),
|
|
date_publication=datetime.date(2022, 10, 1),
|
|
date_payment_deadline=datetime.date(2022, 10, 31),
|
|
date_issue=datetime.date(2022, 10, 31),
|
|
date_debit=datetime.date(2022, 11, 15),
|
|
)
|
|
pool = Pool.objects.create(
|
|
campaign=campaign,
|
|
draft=True,
|
|
)
|
|
campaign2 = Campaign.objects.create(
|
|
regie=regie,
|
|
date_start=datetime.date(2022, 9, 1),
|
|
date_end=datetime.date(2022, 10, 1),
|
|
date_publication=datetime.date(2022, 10, 1),
|
|
date_payment_deadline=datetime.date(2022, 10, 31),
|
|
date_issue=datetime.date(2022, 10, 31),
|
|
date_debit=datetime.date(2022, 11, 15),
|
|
)
|
|
pool2 = Pool.objects.create(
|
|
campaign=campaign2,
|
|
draft=False,
|
|
)
|
|
|
|
other_campaign = Campaign.objects.create(
|
|
regie=other_regie,
|
|
date_start=datetime.date(2022, 9, 1),
|
|
date_end=datetime.date(2022, 10, 1),
|
|
date_publication=datetime.date(2022, 10, 1),
|
|
date_payment_deadline=datetime.date(2022, 10, 31),
|
|
date_issue=datetime.date(2022, 10, 31),
|
|
date_debit=datetime.date(2022, 11, 15),
|
|
)
|
|
other_pool = Pool.objects.create(
|
|
campaign=other_campaign,
|
|
draft=True,
|
|
)
|
|
other_campaign2 = Campaign.objects.create(
|
|
regie=other_regie,
|
|
date_start=datetime.date(2022, 9, 1),
|
|
date_end=datetime.date(2022, 10, 1),
|
|
date_publication=datetime.date(2022, 10, 1),
|
|
date_payment_deadline=datetime.date(2022, 10, 31),
|
|
date_issue=datetime.date(2022, 10, 31),
|
|
date_debit=datetime.date(2022, 11, 15),
|
|
)
|
|
other_pool2 = Pool.objects.create(
|
|
campaign=other_campaign2,
|
|
draft=False,
|
|
)
|
|
|
|
# not invoiced
|
|
InjectedLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 1),
|
|
slug='event-2022-09-01',
|
|
label='Event 2022-09-01',
|
|
quantity=2,
|
|
unit_amount=1.5,
|
|
total_amount=3,
|
|
user_external_id='user:1',
|
|
payer_external_id='payer:1',
|
|
regie=regie,
|
|
)
|
|
# not invoiced but in another regie
|
|
InjectedLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 1),
|
|
slug='other-event-2022-09-01',
|
|
label='Other Event 2022-09-01',
|
|
quantity=2,
|
|
unit_amount=1.5,
|
|
total_amount=3,
|
|
user_external_id='user:1',
|
|
payer_external_id='payer:1',
|
|
regie=other_regie,
|
|
)
|
|
# not invoiced, but linked in a DraftInvoiceLine
|
|
injected_line2 = InjectedLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 2),
|
|
slug='event-2022-09-02',
|
|
label='Event 2022-09-02',
|
|
quantity=2,
|
|
unit_amount=1.5,
|
|
total_amount=3,
|
|
user_external_id='user:1',
|
|
payer_external_id='payer:1',
|
|
regie=regie,
|
|
)
|
|
DraftInvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 2),
|
|
slug='event-2022-09-02',
|
|
label='Event 2022-09-02',
|
|
quantity=2,
|
|
unit_amount=1.5,
|
|
total_amount=3,
|
|
pool=pool,
|
|
from_injected_line=injected_line2,
|
|
)
|
|
# not invoiced, but linked in a DraftInvoiceLine, but in another regie
|
|
other_injected_line2 = InjectedLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 2),
|
|
slug='other-event-2022-09-02',
|
|
label='Other Event 2022-09-02',
|
|
quantity=2,
|
|
unit_amount=1.5,
|
|
total_amount=3,
|
|
user_external_id='user:1',
|
|
payer_external_id='payer:1',
|
|
regie=other_regie,
|
|
)
|
|
DraftInvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 2),
|
|
slug='other-event-2022-09-02',
|
|
label='Other Event 2022-09-02',
|
|
quantity=2,
|
|
unit_amount=1.5,
|
|
total_amount=3,
|
|
pool=other_pool,
|
|
from_injected_line=other_injected_line2,
|
|
)
|
|
# invoiced, as linked in a non draft pool
|
|
injected_line3 = InjectedLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 3),
|
|
slug='event-2022-09-03',
|
|
label='Event 2022-09-03',
|
|
quantity=2,
|
|
unit_amount=1.5,
|
|
total_amount=3,
|
|
user_external_id='user:1',
|
|
payer_external_id='payer:1',
|
|
regie=regie,
|
|
)
|
|
InvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 3),
|
|
slug='event-2022-09-03',
|
|
label='Event 2022-09-03',
|
|
quantity=2,
|
|
unit_amount=1.5,
|
|
total_amount=3,
|
|
pool=pool2,
|
|
from_injected_line=injected_line3,
|
|
)
|
|
|
|
# non fixed error
|
|
InvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 4),
|
|
slug='event-2022-09-04',
|
|
label='Event 2022-09-04',
|
|
quantity=0,
|
|
unit_amount=0,
|
|
total_amount=0,
|
|
pool=pool2,
|
|
status='error',
|
|
)
|
|
# non fixed error, but in another regie
|
|
InvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 4),
|
|
slug='other-event-2022-09-04',
|
|
label='Other Event 2022-09-04',
|
|
quantity=0,
|
|
unit_amount=0,
|
|
total_amount=0,
|
|
pool=other_pool2,
|
|
status='error',
|
|
)
|
|
# fixed or ignored errors
|
|
InvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 5),
|
|
slug='event-2022-09-05',
|
|
label='Event 2022-09-05',
|
|
quantity=0,
|
|
unit_amount=0,
|
|
total_amount=0,
|
|
pool=pool2,
|
|
status='error',
|
|
error_status='fixed',
|
|
)
|
|
InvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 6),
|
|
slug='event-2022-09-06',
|
|
label='Event 2022-09-06',
|
|
quantity=0,
|
|
unit_amount=0,
|
|
total_amount=0,
|
|
pool=pool2,
|
|
status='error',
|
|
error_status='ignored',
|
|
)
|
|
# not errors
|
|
InvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 7),
|
|
slug='event-2022-09-07',
|
|
label='Event 2022-09-07',
|
|
quantity=0,
|
|
unit_amount=0,
|
|
total_amount=0,
|
|
pool=pool2,
|
|
status='success',
|
|
)
|
|
InvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 8),
|
|
slug='event-2022-09-08',
|
|
label='Event 2022-09-08',
|
|
quantity=0,
|
|
unit_amount=0,
|
|
total_amount=0,
|
|
pool=pool2,
|
|
status='warning',
|
|
)
|
|
|
|
app = login(app)
|
|
resp = app.get('/manage/invoicing/regie/%s/non-invoiced-lines/' % regie.pk)
|
|
assert 'event-2022-09-01' in resp
|
|
assert 'other-event-2022-09-01' not in resp
|
|
assert 'event-2022-09-02' in resp
|
|
assert 'other-event-2022-09-02' not in resp
|
|
assert 'event-2022-09-03' not in resp
|
|
assert 'event-2022-09-04' in resp
|
|
assert 'other-event-2022-09-04' not in resp
|
|
assert 'event-2022-09-05' not in resp
|
|
assert 'event-2022-09-06' not in resp
|
|
assert 'event-2022-09-07' not in resp
|
|
assert 'event-2022-09-08' not in resp
|
|
|
|
|
|
def test_non_invoiced_line_link(app, admin_user, settings):
|
|
settings.KNOWN_SERVICES = {}
|
|
|
|
regie = Regie.objects.create(label='Regie')
|
|
campaign = Campaign.objects.create(
|
|
regie=regie,
|
|
date_start=datetime.date(2022, 9, 1),
|
|
date_end=datetime.date(2022, 10, 1),
|
|
date_publication=datetime.date(2022, 10, 1),
|
|
date_payment_deadline=datetime.date(2022, 10, 31),
|
|
date_issue=datetime.date(2022, 10, 31),
|
|
date_debit=datetime.date(2022, 11, 15),
|
|
)
|
|
pool = Pool.objects.create(
|
|
campaign=campaign,
|
|
draft=False,
|
|
)
|
|
|
|
line = InvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 4),
|
|
slug='event-2022-09-04',
|
|
label='Event 2022-09-04',
|
|
quantity=0,
|
|
unit_amount=0,
|
|
total_amount=0,
|
|
pool=pool,
|
|
status='error',
|
|
)
|
|
|
|
app = login(app)
|
|
resp = app.get('/manage/invoicing/regie/%s/non-invoiced-lines/' % regie.pk)
|
|
assert 'see agenda' not in resp
|
|
assert 'see event' not in resp
|
|
|
|
line.event = {
|
|
'agenda': 'foobar',
|
|
}
|
|
line.save()
|
|
resp = app.get('/manage/invoicing/regie/%s/non-invoiced-lines/' % regie.pk)
|
|
assert '<a href="/manage/pricing/agenda/foobar/">see agenda</a>' in resp
|
|
assert 'see event' not in resp
|
|
|
|
line.event['slug'] = 'bazbaz'
|
|
line.save()
|
|
resp = app.get('/manage/invoicing/regie/%s/non-invoiced-lines/' % regie.pk)
|
|
assert '<a href="/manage/pricing/agenda/foobar/">see agenda</a>' in resp
|
|
assert 'see event' not in resp
|
|
|
|
settings.KNOWN_SERVICES['chrono'] = {'default': {'url': 'https://chrono.dev/'}}
|
|
resp = app.get('/manage/invoicing/regie/%s/non-invoiced-lines/' % regie.pk)
|
|
assert '<a href="/manage/pricing/agenda/foobar/">see agenda</a>' in resp
|
|
assert '<a href="https://chrono.dev/manage/agendas/foobar/events/bazbaz/">see event</a>' in resp
|
|
|
|
|
|
@pytest.mark.parametrize('orphan', [True, False])
|
|
def test_regie_invoices(app, admin_user, orphan):
|
|
regie = Regie.objects.create(label='Foo')
|
|
if not orphan:
|
|
campaign1 = Campaign.objects.create(
|
|
regie=regie,
|
|
date_start=datetime.date(2022, 9, 1),
|
|
date_end=datetime.date(2022, 10, 1),
|
|
date_publication=datetime.date(2022, 10, 1),
|
|
date_payment_deadline=datetime.date(2022, 10, 31),
|
|
date_issue=datetime.date(2022, 10, 31),
|
|
date_debit=datetime.date(2022, 11, 15),
|
|
)
|
|
pool1 = Pool.objects.create(
|
|
campaign=campaign1,
|
|
draft=False,
|
|
status='completed',
|
|
)
|
|
campaign2 = Campaign.objects.create(
|
|
regie=regie,
|
|
date_start=datetime.date(2022, 9, 1),
|
|
date_end=datetime.date(2022, 10, 1),
|
|
date_publication=datetime.date(2022, 10, 1),
|
|
date_payment_deadline=datetime.date(2022, 10, 31),
|
|
date_issue=datetime.date(2022, 10, 31),
|
|
date_debit=datetime.date(2022, 11, 15),
|
|
)
|
|
pool2 = Pool.objects.create(
|
|
campaign=campaign2,
|
|
draft=False,
|
|
status='completed',
|
|
)
|
|
invoice1 = Invoice.objects.create(
|
|
date_publication=datetime.date(2022, 10, 1),
|
|
date_payment_deadline=datetime.date(2022, 10, 31),
|
|
date_issue=datetime.date(2022, 10, 31),
|
|
regie=regie,
|
|
pool=pool1 if not orphan else None,
|
|
payer_external_id='payer:1',
|
|
payer_first_name='First1',
|
|
payer_last_name='Name1',
|
|
payer_demat=True,
|
|
payer_direct_debit=False,
|
|
)
|
|
invoice1.set_number()
|
|
invoice1.save()
|
|
invoice2 = Invoice.objects.create(
|
|
date_publication=datetime.date(2022, 10, 1),
|
|
date_payment_deadline=datetime.date(2022, 10, 31),
|
|
date_issue=datetime.date(2022, 10, 31),
|
|
date_debit=datetime.date(2022, 11, 15),
|
|
regie=regie,
|
|
pool=pool2 if not orphan else None,
|
|
payer_external_id='payer:2',
|
|
payer_first_name='First2',
|
|
payer_last_name='Name2',
|
|
payer_demat=False,
|
|
payer_direct_debit=True,
|
|
)
|
|
invoice2.set_number()
|
|
invoice2.save()
|
|
invoice3 = Invoice.objects.create(
|
|
date_publication=datetime.date(2022, 10, 1),
|
|
date_payment_deadline=datetime.date(2022, 10, 31),
|
|
date_issue=datetime.date(2022, 10, 31),
|
|
date_debit=datetime.date(2022, 11, 15),
|
|
regie=regie,
|
|
pool=pool2 if not orphan else None,
|
|
payer_external_id='payer:3',
|
|
payer_first_name='First3',
|
|
payer_last_name='Name3',
|
|
payer_demat=False,
|
|
payer_direct_debit=True,
|
|
)
|
|
invoice3.set_number()
|
|
invoice3.save()
|
|
|
|
line11 = InvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 1),
|
|
invoice=invoice1,
|
|
quantity=1,
|
|
unit_amount=1,
|
|
total_amount=1,
|
|
status='success',
|
|
pool=pool1 if not orphan else None,
|
|
label='Label 11',
|
|
user_external_id='user:1',
|
|
user_first_name='User1',
|
|
user_last_name='Name1',
|
|
)
|
|
line12 = InvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 2),
|
|
invoice=invoice1,
|
|
quantity=1,
|
|
unit_amount=2,
|
|
total_amount=2,
|
|
status='success',
|
|
pool=pool1 if not orphan else None,
|
|
label='Label 12',
|
|
user_external_id='user:2',
|
|
user_first_name='User2',
|
|
user_last_name='Name2',
|
|
)
|
|
line13 = InvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 3),
|
|
invoice=invoice1,
|
|
quantity=1,
|
|
unit_amount=3,
|
|
total_amount=3,
|
|
status='success',
|
|
pool=pool1 if not orphan else None,
|
|
label='Label 13',
|
|
user_external_id='user:1',
|
|
user_first_name='User1',
|
|
user_last_name='Name1',
|
|
)
|
|
payment1 = Payment.objects.create(
|
|
regie=regie,
|
|
amount=1,
|
|
payment_type='cash',
|
|
)
|
|
invoice_payment1 = InvoicePayment.objects.create(
|
|
payment=payment1,
|
|
invoice=invoice1,
|
|
amount=1,
|
|
)
|
|
invoice1.refresh_from_db()
|
|
assert invoice1.remaining_amount == 5
|
|
assert invoice1.paid_amount == 1
|
|
|
|
orphan_line = InvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 1),
|
|
quantity=1,
|
|
unit_amount=42,
|
|
total_amount=42,
|
|
status='failed',
|
|
pool=pool1 if not orphan else None,
|
|
label='Label 14',
|
|
user_external_id='user:1',
|
|
user_first_name='User1',
|
|
user_last_name='Name1',
|
|
)
|
|
|
|
line21 = InvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 1),
|
|
invoice=invoice2,
|
|
quantity=1,
|
|
unit_amount=1,
|
|
total_amount=1,
|
|
status='success',
|
|
pool=pool2 if not orphan else None,
|
|
label='Label 21',
|
|
user_external_id='user:1',
|
|
user_first_name='User1',
|
|
user_last_name='Name1',
|
|
)
|
|
payment2 = Payment.objects.create(
|
|
regie=regie,
|
|
amount=1,
|
|
payment_type='cash',
|
|
)
|
|
invoice_payment2 = InvoicePayment.objects.create(
|
|
payment=payment2,
|
|
invoice=invoice2,
|
|
amount=1,
|
|
)
|
|
invoice2.refresh_from_db()
|
|
assert invoice2.remaining_amount == 0
|
|
assert invoice2.paid_amount == 1
|
|
|
|
line31 = InvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 1),
|
|
invoice=invoice3,
|
|
quantity=1,
|
|
unit_amount=1,
|
|
total_amount=1,
|
|
status='success',
|
|
pool=pool2 if not orphan else None,
|
|
label='Label 31',
|
|
user_external_id='user:1',
|
|
user_first_name='User1',
|
|
user_last_name='Name1',
|
|
)
|
|
invoice3.refresh_from_db()
|
|
assert invoice3.remaining_amount == 1
|
|
assert invoice3.paid_amount == 0
|
|
|
|
app = login(app)
|
|
resp = app.get('/manage/invoicing/regie/%s/invoices/' % regie.pk)
|
|
assert '#%s' % orphan_line.pk not in resp
|
|
assert resp.pyquery(
|
|
'li[data-invoice-id="%s"]' % invoice1.pk
|
|
).text() == 'Partially paid Invoice F%02d-%s-0000001 addressed to First1 Name1 (payer:1), amount 6.00€, demat: yes, direct debit: no - download' % (
|
|
regie.pk,
|
|
invoice1.created_at.strftime('%y-%m'),
|
|
)
|
|
if orphan:
|
|
assert len(resp.pyquery('li[data-invoice-id="%s"] a' % invoice1.pk)) == 2
|
|
else:
|
|
assert len(resp.pyquery('li[data-invoice-id="%s"] a' % invoice1.pk)) == 3
|
|
lines_url = resp.pyquery('li[data-invoice-id="%s"]' % invoice1.pk).attr('data-invoice-lines-url')
|
|
assert lines_url == '/manage/invoicing/ajax/regie/%s/invoice/%s/lines/' % (
|
|
regie.pk,
|
|
invoice1.pk,
|
|
)
|
|
lines_resp = app.get(lines_url)
|
|
assert len(lines_resp.pyquery('li')) == 6
|
|
assert (
|
|
lines_resp.pyquery('li:nth-child(1)').text()
|
|
== '#%s User1 Name1 (user:1) - 01/09/2022 - Label 11 (1.00)' % line11.pk
|
|
)
|
|
assert (
|
|
lines_resp.pyquery('li:nth-child(2)').text()
|
|
== '#%s User1 Name1 (user:1) - 03/09/2022 - Label 13 (3.00)' % line13.pk
|
|
)
|
|
assert (
|
|
lines_resp.pyquery('li:nth-child(3)').text()
|
|
== '#%s User2 Name2 (user:2) - 02/09/2022 - Label 12 (2.00)' % line12.pk
|
|
)
|
|
assert lines_resp.pyquery(
|
|
'li:nth-child(4)'
|
|
).text() == '%s - Payment type: Cash - Amount: 1.00€' % date_format(
|
|
localtime(invoice_payment1.created_at), 'DATETIME_FORMAT'
|
|
)
|
|
assert lines_resp.pyquery('li:nth-child(5)').text() == 'Paid amount: 1.00€'
|
|
assert lines_resp.pyquery('li:nth-child(6)').text() == 'Remaining amount: 5.00€'
|
|
assert resp.pyquery(
|
|
'li[data-invoice-id="%s"]' % invoice2.pk
|
|
).text() == 'Paid Invoice F%02d-%s-0000002 addressed to First2 Name2 (payer:2), amount 1.00€, demat: no, direct debit: yes - download' % (
|
|
regie.pk,
|
|
invoice2.created_at.strftime('%y-%m'),
|
|
)
|
|
lines_url = resp.pyquery('li[data-invoice-id="%s"]' % invoice2.pk).attr('data-invoice-lines-url')
|
|
assert lines_url == '/manage/invoicing/ajax/regie/%s/invoice/%s/lines/' % (
|
|
regie.pk,
|
|
invoice2.pk,
|
|
)
|
|
lines_resp = app.get(lines_url)
|
|
assert len(lines_resp.pyquery('li')) == 3
|
|
assert (
|
|
lines_resp.pyquery('li:nth-child(1)').text()
|
|
== '#%s User1 Name1 (user:1) - 01/09/2022 - Label 21 (1.00)' % line21.pk
|
|
)
|
|
assert lines_resp.pyquery(
|
|
'li:nth-child(2)'
|
|
).text() == '%s - Payment type: Cash - Amount: 1.00€' % date_format(
|
|
localtime(invoice_payment2.created_at), 'DATETIME_FORMAT'
|
|
)
|
|
assert lines_resp.pyquery('li:nth-child(3)').text() == 'Paid amount: 1.00€'
|
|
assert resp.pyquery(
|
|
'li[data-invoice-id="%s"]' % invoice3.pk
|
|
).text() == 'Invoice F%02d-%s-0000003 addressed to First3 Name3 (payer:3), amount 1.00€, demat: no, direct debit: yes - download' % (
|
|
regie.pk,
|
|
invoice3.created_at.strftime('%y-%m'),
|
|
)
|
|
lines_url = resp.pyquery('li[data-invoice-id="%s"]' % invoice3.pk).attr('data-invoice-lines-url')
|
|
assert lines_url == '/manage/invoicing/ajax/regie/%s/invoice/%s/lines/' % (
|
|
regie.pk,
|
|
invoice3.pk,
|
|
)
|
|
lines_resp = app.get(lines_url)
|
|
assert len(lines_resp.pyquery('li')) == 2
|
|
assert (
|
|
lines_resp.pyquery('li:nth-child(1)').text()
|
|
== '#%s User1 Name1 (user:1) - 01/09/2022 - Label 31 (1.00)' % line31.pk
|
|
)
|
|
assert lines_resp.pyquery('li:nth-child(2)').text() == 'Remaining amount: 1.00€'
|
|
|
|
# test filters
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'number': invoice1.formatted_number},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 1
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'number': invoice1.created_at.strftime('%y-%m')},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 3
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'payer_external_id': 'payer:1'},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 1
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'payer_external_id': 'payer:2'},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 1
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'payer_first_name': 'first'},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 3
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'payer_first_name': 'first1'},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 1
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'payer_last_name': 'name'},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 3
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'payer_last_name': 'name1'},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 1
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'payer_demat': True},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 1
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'payer_direct_debit': True},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 2
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'user_external_id': 'user:1'},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 3
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'user_external_id': 'user:2'},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 1
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'user_first_name': 'user'},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 3
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'user_first_name': 'user2'},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 1
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'user_last_name': 'name'},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 3
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'user_last_name': 'name1'},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 3
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'paid': 'yes'},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 1
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'paid': 'partially'},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 1
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoices/' % regie.pk,
|
|
params={'paid': 'no'},
|
|
)
|
|
assert len(resp.pyquery('li.invoice')) == 1
|
|
|
|
|
|
def test_regie_invoice_pdf(app, admin_user):
|
|
regie = Regie.objects.create(label='Foo')
|
|
campaign = Campaign.objects.create(
|
|
regie=regie,
|
|
date_start=datetime.date(2022, 9, 1),
|
|
date_end=datetime.date(2022, 10, 1),
|
|
date_publication=datetime.date(2022, 10, 1),
|
|
date_payment_deadline=datetime.date(2022, 10, 31),
|
|
date_issue=datetime.date(2022, 10, 31),
|
|
date_debit=datetime.date(2022, 11, 15),
|
|
)
|
|
pool = Pool.objects.create(
|
|
campaign=campaign,
|
|
draft=False,
|
|
status='completed',
|
|
)
|
|
invoice = Invoice.objects.create(
|
|
date_publication=campaign.date_publication,
|
|
date_payment_deadline=campaign.date_payment_deadline,
|
|
date_issue=campaign.date_issue,
|
|
regie=regie,
|
|
pool=pool,
|
|
payer_external_id='payer:1',
|
|
payer_first_name='First1',
|
|
payer_last_name='Name1',
|
|
payer_demat=True,
|
|
payer_direct_debit=False,
|
|
)
|
|
invoice.set_number()
|
|
invoice.save()
|
|
|
|
InvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 1),
|
|
invoice=invoice,
|
|
quantity=1,
|
|
unit_amount=1,
|
|
total_amount=1,
|
|
status='success',
|
|
pool=pool,
|
|
label='Label 11',
|
|
user_external_id='user:1',
|
|
user_first_name='User1',
|
|
user_last_name='Name1',
|
|
)
|
|
InvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 2),
|
|
invoice=invoice,
|
|
quantity=1,
|
|
unit_amount=2,
|
|
total_amount=2,
|
|
status='success',
|
|
pool=pool,
|
|
label='Label 12',
|
|
user_external_id='user:2',
|
|
user_first_name='User2',
|
|
user_last_name='Name2',
|
|
)
|
|
InvoiceLine.objects.create(
|
|
event_date=datetime.date(2022, 9, 3),
|
|
invoice=invoice,
|
|
quantity=1,
|
|
unit_amount=3,
|
|
total_amount=3,
|
|
status='success',
|
|
pool=pool,
|
|
label='Label 13',
|
|
user_external_id='user:1',
|
|
user_first_name='User1',
|
|
user_last_name='Name1',
|
|
)
|
|
|
|
app = login(app)
|
|
resp = app.get('/manage/invoicing/regie/%s/invoice/%s/pdf/?html' % (regie.pk, invoice.pk))
|
|
assert resp.pyquery('address#from').text() == 'Foo'
|
|
assert resp.pyquery('address#to').text() == 'First1 Name1'
|
|
assert resp.pyquery('dl#informations').text() == 'Invoice number\nF%02d-%s-0000001\nDate\n%s' % (
|
|
regie.pk,
|
|
invoice.created_at.strftime('%y-%m'),
|
|
date_format(localtime(invoice.created_at), 'DATE_FORMAT'),
|
|
)
|
|
assert len(resp.pyquery('table#lines tbody tr')) == 3
|
|
assert (
|
|
resp.pyquery('table#lines tbody tr:nth-child(1)').text() == 'Label 11\nUser1 Name1\n1.00\n1.0\n1.00'
|
|
)
|
|
assert (
|
|
resp.pyquery('table#lines tbody tr:nth-child(2)').text() == 'Label 13\nUser1 Name1\n3.00\n1.0\n3.00'
|
|
)
|
|
assert (
|
|
resp.pyquery('table#lines tbody tr:nth-child(3)').text() == 'Label 12\nUser2 Name2\n2.00\n1.0\n2.00'
|
|
)
|
|
assert resp.pyquery('table#total tbody').text() == 'Oct. 31, 2022\n6.00'
|
|
|
|
resp = app.get('/manage/invoicing/regie/%s//invoice/%s/pdf/?html' % (0, invoice.pk), status=404)
|
|
resp = app.get('/manage/invoicing/regie/%s//invoice/%s/pdf/?html' % (regie.pk, 0), status=404)
|
|
other_regie = Regie.objects.create(label='Foo')
|
|
resp = app.get(
|
|
'/manage/invoicing/regie/%s/invoice/%s/pdf/?html' % (other_regie.pk, invoice.pk), status=404
|
|
)
|