invoicing: add Campaign & Pool models (#71910) #8
|
@ -18,6 +18,7 @@ import datetime
|
|||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from lingo.invoicing.models import Campaign
|
||||
from lingo.invoicing.utils import generate_invoices
|
||||
|
||||
|
||||
|
@ -27,6 +28,8 @@ class Command(BaseCommand):
|
|||
def add_arguments(self, parser):
|
||||
parser.add_argument('date_start')
|
||||
parser.add_argument('date_end')
|
||||
parser.add_argument('--date-issue')
|
||||
parser.add_argument('--draft', action='store_true')
|
||||
|
||||
def handle(self, *args, **options):
|
||||
try:
|
||||
|
@ -37,8 +40,26 @@ class Command(BaseCommand):
|
|||
date_end = datetime.datetime.fromisoformat(options['date_end']).date()
|
||||
except ValueError:
|
||||
raise CommandError('Bad value "%s" for date_end' % options['date_end'])
|
||||
if options.get('date_issue'):
|
||||
try:
|
||||
date_issue = datetime.datetime.fromisoformat(options['date_issue']).date()
|
||||
except ValueError:
|
||||
raise CommandError('Bad value "%s" for date_issue' % options['date_issue'])
|
||||
else:
|
||||
date_issue = date_end
|
||||
|
||||
generate_invoices(date_start=date_start, date_end=date_end)
|
||||
try:
|
||||
campaign = Campaign.objects.get(date_start=date_start, date_end=date_end)
|
||||
except Campaign.DoesNotExist:
|
||||
campaigns = Campaign.objects.extra(
|
||||
where=["(date_start, date_end) OVERLAPS (%s, %s)"], params=[date_start, date_end]
|
||||
)
|
||||
if campaigns.exists():
|
||||
raise CommandError('Overlapping campaigns already exist')
|
||||
campaign = Campaign.objects.create(
|
||||
date_start=date_start, date_end=date_end, date_issue=date_issue
|
||||
)
|
||||
generate_invoices(campaign=campaign, draft=options['draft'])
|
||||
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS('Invoicing generation OK (start: %s, end: %s)' % (date_start, date_end))
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
# Generated by Django 2.2.26 on 2022-12-01 10:38
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('invoicing', '0003_invoice'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Campaign',
|
||||
fields=[
|
||||
(
|
||||
'id',
|
||||
models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
|
||||
),
|
||||
('date_start', models.DateField(verbose_name='Start date')),
|
||||
('date_end', models.DateField(verbose_name='End date')),
|
||||
('date_issue', models.DateField(verbose_name='Issue date')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Pool',
|
||||
fields=[
|
||||
(
|
||||
'id',
|
||||
models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
|
||||
),
|
||||
('draft', models.BooleanField(default=True)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
(
|
||||
'campaign',
|
||||
models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='invoicing.Campaign'),
|
||||
),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='draftinvoice',
|
||||
name='pool',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='invoicing.Pool'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='draftinvoiceline',
|
||||
name='pool',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='invoicing.Pool'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='invoice',
|
||||
name='pool',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='invoicing.Pool'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='invoiceline',
|
||||
name='pool',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='invoicing.Pool'),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
|
@ -87,6 +87,18 @@ class Regie(models.Model):
|
|||
return created, regie
|
||||
|
||||
|
||||
class Campaign(models.Model):
|
||||
date_start = models.DateField(_('Start date'))
|
||||
date_end = models.DateField(_('End date'))
|
||||
date_issue = models.DateField(_('Issue date'))
|
||||
|
||||
|
||||
class Pool(models.Model):
|
||||
campaign = models.ForeignKey(Campaign, on_delete=models.PROTECT)
|
||||
draft = models.BooleanField(default=True)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
|
||||
class AbstractInvoice(models.Model):
|
||||
label = models.CharField(_('Label'), max_length=300)
|
||||
total_amount = models.DecimalField(max_digits=9, decimal_places=2, default=0)
|
||||
|
@ -94,6 +106,8 @@ class AbstractInvoice(models.Model):
|
|||
regie = models.ForeignKey(Regie, on_delete=models.PROTECT)
|
||||
payer = models.CharField(_('Payer'), max_length=300)
|
||||
|
||||
pool = models.ForeignKey(Pool, on_delete=models.PROTECT)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
@ -125,6 +139,8 @@ class AbstractInvoiceLine(models.Model):
|
|||
],
|
||||
)
|
||||
|
||||
pool = models.ForeignKey(Pool, on_delete=models.PROTECT)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
|
|
@ -26,14 +26,15 @@ from lingo.invoicing.models import DraftInvoice, DraftInvoiceLine
|
|||
from lingo.pricing.models import AgendaPricing, AgendaPricingNotFound, PricingError
|
||||
|
||||
|
||||
def get_agendas(date_start, date_end):
|
||||
def get_agendas(pool):
|
||||
agendas_pricings = AgendaPricing.objects.filter(flat_fee_schedule=False).extra(
|
||||
where=["(date_start, date_end) OVERLAPS (%s, %s)"], params=[date_start, date_end]
|
||||
where=["(date_start, date_end) OVERLAPS (%s, %s)"],
|
||||
params=[pool.campaign.date_start, pool.campaign.date_end],
|
||||
)
|
||||
return Agenda.objects.filter(pk__in=agendas_pricings.values('agendas')).order_by('pk')
|
||||
|
||||
|
||||
def get_all_subscriptions(agendas, date_start, date_end):
|
||||
def get_all_subscriptions(agendas, pool):
|
||||
# result:
|
||||
# {
|
||||
# 'user_id': {
|
||||
|
@ -44,7 +45,11 @@ def get_all_subscriptions(agendas, date_start, date_end):
|
|||
# }
|
||||
all_subscriptions = {}
|
||||
for agenda in agendas:
|
||||
subscriptions = get_subscriptions(agenda_slug=agenda.slug, date_start=date_start, date_end=date_end)
|
||||
subscriptions = get_subscriptions(
|
||||
agenda_slug=agenda.slug,
|
||||
date_start=pool.campaign.date_start,
|
||||
date_end=pool.campaign.date_end,
|
||||
)
|
||||
for subscription in subscriptions:
|
||||
if subscription['user_external_id'] not in all_subscriptions:
|
||||
all_subscriptions[subscription['user_external_id']] = {}
|
||||
|
@ -55,9 +60,7 @@ def get_all_subscriptions(agendas, date_start, date_end):
|
|||
return all_subscriptions
|
||||
|
||||
|
||||
def get_invoice_lines_for_user(
|
||||
agendas, agendas_pricings, user_external_id, subscriptions, date_start, date_end
|
||||
):
|
||||
def get_invoice_lines_for_user(agendas, agendas_pricings, user_external_id, subscriptions, 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:
|
||||
|
@ -93,8 +96,8 @@ def get_invoice_lines_for_user(
|
|||
check_status_list = get_check_status(
|
||||
agenda_slugs=list(subscriptions.keys()),
|
||||
user_external_id=user_external_id,
|
||||
date_start=date_start,
|
||||
date_end=date_end,
|
||||
date_start=pool.campaign.date_start,
|
||||
date_end=pool.campaign.date_end,
|
||||
)
|
||||
request = RequestFactory().get('/') # XXX
|
||||
agendas_by_slug = {a.slug: a for a in agendas}
|
||||
|
@ -150,6 +153,7 @@ def get_invoice_lines_for_user(
|
|||
event=serialized_event,
|
||||
pricing_data=pricing_error,
|
||||
status='error',
|
||||
pool=pool,
|
||||
)
|
||||
)
|
||||
else:
|
||||
|
@ -166,16 +170,20 @@ def get_invoice_lines_for_user(
|
|||
event=serialized_event,
|
||||
pricing_data=pricing_data,
|
||||
status='success',
|
||||
pool=pool,
|
||||
)
|
||||
)
|
||||
DraftInvoiceLine.objects.bulk_create(lines)
|
||||
return lines
|
||||
|
||||
|
||||
def get_all_invoice_lines(agendas, subscriptions, date_start, date_end):
|
||||
def get_all_invoice_lines(agendas, subscriptions, pool):
|
||||
agendas_pricings = (
|
||||
AgendaPricing.objects.filter(flat_fee_schedule=False)
|
||||
.extra(where=["(date_start, date_end) OVERLAPS (%s, %s)"], params=[date_start, date_end])
|
||||
.extra(
|
||||
where=["(date_start, date_end) OVERLAPS (%s, %s)"],
|
||||
params=[pool.campaign.date_start, pool.campaign.date_end],
|
||||
)
|
||||
.prefetch_related('agendas', 'pricing__criterias', 'pricing__categories')
|
||||
)
|
||||
|
||||
|
@ -187,13 +195,12 @@ def get_all_invoice_lines(agendas, subscriptions, date_start, date_end):
|
|||
agendas_pricings=agendas_pricings,
|
||||
user_external_id=user_external_id,
|
||||
subscriptions=user_subs,
|
||||
date_start=date_start,
|
||||
date_end=date_end,
|
||||
pool=pool,
|
||||
)
|
||||
return lines
|
||||
|
||||
|
||||
def generate_invoices_from_lines(agendas, all_lines, date_start, date_end):
|
||||
def generate_invoices_from_lines(agendas, all_lines, pool):
|
||||
agendas_by_slug = {a.slug: a for a in agendas}
|
||||
|
||||
# regroup lines by regie, and by payer_external_id (payer)
|
||||
|
@ -222,10 +229,15 @@ def generate_invoices_from_lines(agendas, all_lines, date_start, date_end):
|
|||
for regie_id, regie_subs in lines_by_regie.items():
|
||||
for payer_external_id, adult_lines in regie_subs.items():
|
||||
invoice = DraftInvoice.objects.create(
|
||||
label=_('Invoice from %s to %s') % (date_start, date_end - datetime.timedelta(days=1)),
|
||||
date_issue=date_end, # XXX
|
||||
label=_('Invoice from %s to %s')
|
||||
% (
|
||||
pool.campaign.date_start,
|
||||
pool.campaign.date_end - datetime.timedelta(days=1),
|
||||
),
|
||||
date_issue=pool.campaign.date_issue,
|
||||
regie_id=regie_id,
|
||||
payer=payer_external_id,
|
||||
pool=pool,
|
||||
)
|
||||
DraftInvoiceLine.objects.filter(pk__in=[line.pk for line in adult_lines]).update(invoice=invoice)
|
||||
invoices.append(invoice)
|
||||
|
@ -233,14 +245,13 @@ def generate_invoices_from_lines(agendas, all_lines, date_start, date_end):
|
|||
return invoices
|
||||
|
||||
|
||||
def generate_invoices(date_start, date_end):
|
||||
def generate_invoices(campaign, draft=True):
|
||||
pool = campaign.pool_set.create(draft=draft)
|
||||
# get agendas with pricing corresponding to the period
|
||||
agendas = get_agendas(date_start=date_start, date_end=date_end)
|
||||
agendas = get_agendas(pool=pool)
|
||||
# get subscriptions for each agenda, for the period
|
||||
subscriptions = get_all_subscriptions(agendas=agendas, date_start=date_start, date_end=date_end)
|
||||
subscriptions = get_all_subscriptions(agendas=agendas, pool=pool)
|
||||
# get invoice lines for all subscribed users, for each agenda in the corresponding period
|
||||
lines = get_all_invoice_lines(
|
||||
agendas=agendas, subscriptions=subscriptions, date_start=date_start, date_end=date_end
|
||||
)
|
||||
lines = get_all_invoice_lines(agendas=agendas, subscriptions=subscriptions, pool=pool)
|
||||
# and generate invoices
|
||||
generate_invoices_from_lines(agendas=agendas, all_lines=lines, date_start=date_start, date_end=date_end)
|
||||
generate_invoices_from_lines(agendas=agendas, all_lines=lines, pool=pool)
|
||||
|
|
|
@ -9,7 +9,7 @@ from django.test.utils import CaptureQueriesContext
|
|||
from lingo.agendas.chrono import ChronoError
|
||||
from lingo.agendas.models import Agenda
|
||||
from lingo.invoicing import utils
|
||||
from lingo.invoicing.models import DraftInvoice, DraftInvoiceLine, Regie
|
||||
from lingo.invoicing.models import Campaign, DraftInvoice, DraftInvoiceLine, Pool, Regie
|
||||
from lingo.pricing.models import AgendaPricing, Criteria, CriteriaCategory, Pricing, PricingError
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
@ -21,12 +21,18 @@ def test_get_agendas():
|
|||
agenda3 = Agenda.objects.create(label='Agenda 3')
|
||||
Agenda.objects.create(label='Agenda 4')
|
||||
pricing = Pricing.objects.create(label='Foo bar 1')
|
||||
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,
|
||||
)
|
||||
|
||||
# no agenda pricing defined
|
||||
assert (
|
||||
list(utils.get_agendas(date_start=datetime.date(2022, 9, 1), date_end=datetime.date(2022, 10, 1)))
|
||||
== []
|
||||
)
|
||||
assert list(utils.get_agendas(pool=pool)) == []
|
||||
|
||||
# agenda pricing, but for flat_fee_schedule
|
||||
agenda_pricing = AgendaPricing.objects.create(
|
||||
|
@ -36,10 +42,7 @@ def test_get_agendas():
|
|||
flat_fee_schedule=True, # wrong config
|
||||
)
|
||||
agenda_pricing.agendas.add(agenda1)
|
||||
assert (
|
||||
list(utils.get_agendas(date_start=datetime.date(2022, 9, 1), date_end=datetime.date(2022, 10, 1)))
|
||||
== []
|
||||
)
|
||||
assert list(utils.get_agendas(pool=pool)) == []
|
||||
|
||||
# create some agenda pricing
|
||||
agenda_pricing1 = AgendaPricing.objects.create(
|
||||
|
@ -52,74 +55,77 @@ def test_get_agendas():
|
|||
date_start=datetime.date(year=2022, month=9, day=1),
|
||||
date_end=datetime.date(year=2022, month=10, day=1),
|
||||
)
|
||||
assert (
|
||||
list(utils.get_agendas(date_start=datetime.date(2022, 9, 1), date_end=datetime.date(2022, 10, 1)))
|
||||
== []
|
||||
)
|
||||
assert list(utils.get_agendas(pool=pool)) == []
|
||||
|
||||
# link agendas to agenda pricing
|
||||
agenda_pricing1.agendas.add(agenda1, agenda2)
|
||||
agenda_pricing2.agendas.add(agenda3)
|
||||
|
||||
assert list(
|
||||
utils.get_agendas(date_start=datetime.date(2022, 9, 1), date_end=datetime.date(2022, 10, 1))
|
||||
) == [agenda3]
|
||||
assert list(
|
||||
utils.get_agendas(date_start=datetime.date(2021, 9, 1), date_end=datetime.date(2021, 10, 1))
|
||||
) == [agenda1, agenda2]
|
||||
assert (
|
||||
list(utils.get_agendas(date_start=datetime.date(2022, 8, 31), date_end=datetime.date(2022, 9, 1)))
|
||||
== []
|
||||
)
|
||||
assert list(
|
||||
utils.get_agendas(date_start=datetime.date(2022, 9, 1), date_end=datetime.date(2022, 9, 2))
|
||||
) == [agenda3]
|
||||
assert list(
|
||||
utils.get_agendas(date_start=datetime.date(2022, 9, 30), date_end=datetime.date(2022, 10, 1))
|
||||
) == [agenda3]
|
||||
assert (
|
||||
list(utils.get_agendas(date_start=datetime.date(2022, 10, 1), date_end=datetime.date(2022, 10, 2)))
|
||||
== []
|
||||
)
|
||||
assert list(
|
||||
utils.get_agendas(date_start=datetime.date(2021, 9, 15), date_end=datetime.date(2022, 9, 15))
|
||||
) == [agenda1, agenda2, agenda3]
|
||||
assert list(utils.get_agendas(pool=pool)) == [agenda3]
|
||||
campaign.date_start = datetime.date(2021, 9, 1)
|
||||
campaign.date_end = datetime.date(2021, 10, 1)
|
||||
campaign.save()
|
||||
assert list(utils.get_agendas(pool=pool)) == [agenda1, agenda2]
|
||||
campaign.date_start = datetime.date(2022, 8, 31)
|
||||
campaign.date_end = datetime.date(2022, 9, 1)
|
||||
campaign.save()
|
||||
assert list(utils.get_agendas(pool=pool)) == []
|
||||
campaign.date_start = datetime.date(2022, 9, 1)
|
||||
campaign.date_end = datetime.date(2022, 9, 2)
|
||||
campaign.save()
|
||||
assert list(utils.get_agendas(pool=pool)) == [agenda3]
|
||||
campaign.date_start = datetime.date(2022, 9, 30)
|
||||
campaign.date_end = datetime.date(2022, 10, 1)
|
||||
campaign.save()
|
||||
assert list(utils.get_agendas(pool=pool)) == [agenda3]
|
||||
campaign.date_start = datetime.date(2022, 10, 1)
|
||||
campaign.date_end = datetime.date(2022, 10, 2)
|
||||
campaign.save()
|
||||
assert list(utils.get_agendas(pool=pool)) == []
|
||||
campaign.date_start = datetime.date(2021, 9, 15)
|
||||
campaign.date_end = datetime.date(2022, 9, 15)
|
||||
campaign.save()
|
||||
assert list(utils.get_agendas(pool=pool)) == [agenda1, agenda2, agenda3]
|
||||
|
||||
|
||||
@mock.patch('lingo.invoicing.utils.get_subscriptions')
|
||||
def test_get_all_subscriptions_error(mock_subscriptions):
|
||||
agenda = Agenda.objects.create(label='Agenda')
|
||||
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,
|
||||
)
|
||||
mock_subscriptions.side_effect = ChronoError('foo baz')
|
||||
with pytest.raises(ChronoError):
|
||||
utils.get_all_subscriptions(
|
||||
agendas=[agenda], date_start=datetime.date(2022, 9, 1), date_end=datetime.date(2022, 10, 1)
|
||||
)
|
||||
utils.get_all_subscriptions(agendas=[agenda], pool=pool)
|
||||
|
||||
|
||||
@mock.patch('lingo.invoicing.utils.get_subscriptions')
|
||||
def test_get_all_subscriptions(mock_subscriptions):
|
||||
agenda1 = Agenda.objects.create(label='Agenda 1')
|
||||
agenda2 = Agenda.objects.create(label='Agenda 2')
|
||||
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,
|
||||
)
|
||||
|
||||
# no agendas
|
||||
assert (
|
||||
utils.get_all_subscriptions(
|
||||
agendas=[], date_start=datetime.date(2022, 9, 1), date_end=datetime.date(2022, 10, 1)
|
||||
)
|
||||
== {}
|
||||
)
|
||||
assert utils.get_all_subscriptions(agendas=[], pool=pool) == {}
|
||||
assert mock_subscriptions.call_args_list == []
|
||||
|
||||
# no subscriptions
|
||||
mock_subscriptions.return_value = []
|
||||
assert (
|
||||
utils.get_all_subscriptions(
|
||||
agendas=[agenda1, agenda2],
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
)
|
||||
== {}
|
||||
)
|
||||
assert utils.get_all_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)
|
||||
|
@ -157,9 +163,7 @@ def test_get_all_subscriptions(mock_subscriptions):
|
|||
},
|
||||
],
|
||||
]
|
||||
assert utils.get_all_subscriptions(
|
||||
agendas=[agenda1, agenda2], date_start=datetime.date(2022, 9, 1), date_end=datetime.date(2022, 10, 1)
|
||||
) == {
|
||||
assert utils.get_all_subscriptions(agendas=[agenda1, agenda2], pool=pool) == {
|
||||
'user:1': {
|
||||
'agenda-1': [
|
||||
{
|
||||
|
@ -203,6 +207,15 @@ def test_get_all_subscriptions(mock_subscriptions):
|
|||
|
||||
@mock.patch('lingo.invoicing.utils.get_check_status')
|
||||
def test_get_invoice_lines_for_user_check_status_error(mock_status):
|
||||
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,
|
||||
)
|
||||
mock_status.side_effect = ChronoError('foo baz')
|
||||
with pytest.raises(ChronoError):
|
||||
utils.get_invoice_lines_for_user(
|
||||
|
@ -210,8 +223,7 @@ def test_get_invoice_lines_for_user_check_status_error(mock_status):
|
|||
agendas_pricings=[],
|
||||
user_external_id='user:1',
|
||||
subscriptions={'foo': 'bar'},
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
)
|
||||
|
||||
|
||||
|
@ -227,6 +239,15 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
date_end=datetime.date(year=2022, month=10, day=1),
|
||||
)
|
||||
agenda_pricing.agendas.add(agenda1, agenda2)
|
||||
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,
|
||||
)
|
||||
|
||||
# no agendas
|
||||
assert (
|
||||
|
@ -243,8 +264,7 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
},
|
||||
],
|
||||
},
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
)
|
||||
== []
|
||||
)
|
||||
|
@ -258,8 +278,7 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
agendas_pricings=[agenda_pricing],
|
||||
user_external_id='user:1',
|
||||
subscriptions={},
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
)
|
||||
== []
|
||||
)
|
||||
|
@ -282,8 +301,7 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
},
|
||||
],
|
||||
},
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
)
|
||||
== []
|
||||
)
|
||||
|
@ -323,8 +341,7 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
},
|
||||
],
|
||||
},
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
)
|
||||
== []
|
||||
)
|
||||
|
@ -411,8 +428,7 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
},
|
||||
],
|
||||
},
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
)
|
||||
assert mock_pricing_data_event.call_args_list == [
|
||||
mock.call(
|
||||
|
@ -495,6 +511,7 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
}
|
||||
assert line1.pricing_data == {'foo1': 'bar1', 'pricing': 1}
|
||||
assert line1.status == 'success'
|
||||
assert line1.pool == pool
|
||||
assert isinstance(line2, DraftInvoiceLine)
|
||||
assert line2.invoice is None
|
||||
assert line2.slug == 'agenda-1@event-2'
|
||||
|
@ -512,6 +529,7 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
}
|
||||
assert line2.pricing_data == {'foo2': 'bar2', 'pricing': 2}
|
||||
assert line2.status == 'success'
|
||||
assert line2.pool == pool
|
||||
assert isinstance(line3, DraftInvoiceLine)
|
||||
assert line3.invoice is None
|
||||
assert line3.slug == 'agenda-2@eveeent-1'
|
||||
|
@ -529,6 +547,7 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
}
|
||||
assert line3.pricing_data == {'foo3': 'bar3', 'pricing': 3}
|
||||
assert line3.status == 'success'
|
||||
assert line3.pool == pool
|
||||
assert isinstance(line4, DraftInvoiceLine)
|
||||
assert line4.invoice is None
|
||||
assert line4.slug == 'agenda-2@eveeent-2'
|
||||
|
@ -546,6 +565,7 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
}
|
||||
assert line4.pricing_data == {'foo4': 'bar4', 'pricing': 4}
|
||||
assert line4.status == 'success'
|
||||
assert line4.pool == pool
|
||||
|
||||
|
||||
@mock.patch('lingo.invoicing.utils.get_check_status')
|
||||
|
@ -559,6 +579,15 @@ def test_get_invoice_lines_for_user_check_status_subscriptions_dates(mock_pricin
|
|||
date_end=datetime.date(year=2022, month=10, day=1),
|
||||
)
|
||||
agenda_pricing.agendas.add(agenda)
|
||||
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,
|
||||
)
|
||||
|
||||
mock_pricing_data_event.return_value = {'foo': 'bar', 'pricing': 42}
|
||||
mock_status.return_value = [
|
||||
|
@ -589,8 +618,7 @@ def test_get_invoice_lines_for_user_check_status_subscriptions_dates(mock_pricin
|
|||
},
|
||||
],
|
||||
},
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
)
|
||||
== []
|
||||
)
|
||||
|
@ -611,8 +639,7 @@ def test_get_invoice_lines_for_user_check_status_subscriptions_dates(mock_pricin
|
|||
},
|
||||
],
|
||||
},
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
)
|
||||
== []
|
||||
)
|
||||
|
@ -644,8 +671,7 @@ def test_get_invoice_lines_for_user_check_status_subscriptions_dates(mock_pricin
|
|||
},
|
||||
],
|
||||
},
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
)
|
||||
assert len(lines) == 1
|
||||
assert mock_pricing_data_event.call_args_list == [
|
||||
|
@ -690,6 +716,15 @@ def test_get_invoice_lines_for_user_check_status_agenda_pricing_dates(mock_statu
|
|||
date_end=datetime.date(year=2022, month=11, day=1),
|
||||
)
|
||||
agenda_pricing3.agendas.add(agenda)
|
||||
campaign = Campaign.objects.create(
|
||||
date_start=datetime.date(2022, 1, 1),
|
||||
date_end=datetime.date(2023, 1, 1),
|
||||
date_issue=datetime.date(2023, 1, 31),
|
||||
)
|
||||
pool = Pool.objects.create(
|
||||
campaign=campaign,
|
||||
draft=True,
|
||||
)
|
||||
|
||||
pricing_data_event_patch = mock.patch.object(AgendaPricing, 'get_pricing_data_for_event', autospec=True)
|
||||
|
||||
|
@ -722,8 +757,7 @@ def test_get_invoice_lines_for_user_check_status_agenda_pricing_dates(mock_statu
|
|||
},
|
||||
],
|
||||
},
|
||||
date_start=datetime.date(2022, 1, 1),
|
||||
date_end=datetime.date(2023, 1, 1),
|
||||
pool=pool,
|
||||
)
|
||||
assert len(lines) == 1
|
||||
assert mock_pricing_data_event.call_args_list[0][0][0] == agenda_pricing1
|
||||
|
@ -757,8 +791,7 @@ def test_get_invoice_lines_for_user_check_status_agenda_pricing_dates(mock_statu
|
|||
},
|
||||
],
|
||||
},
|
||||
date_start=datetime.date(2022, 1, 1),
|
||||
date_end=datetime.date(2023, 1, 1),
|
||||
pool=pool,
|
||||
)
|
||||
assert len(lines) == 1
|
||||
assert mock_pricing_data_event.call_args_list[0][0][0] == agenda_pricing3
|
||||
|
@ -791,8 +824,7 @@ def test_get_invoice_lines_for_user_check_status_agenda_pricing_dates(mock_statu
|
|||
},
|
||||
],
|
||||
},
|
||||
date_start=datetime.date(2022, 1, 1),
|
||||
date_end=datetime.date(2023, 1, 1),
|
||||
pool=pool,
|
||||
)
|
||||
assert len(lines) == 0
|
||||
assert mock_pricing_data_event.call_args_list == []
|
||||
|
@ -809,6 +841,15 @@ def test_get_invoice_lines_for_user_check_status_pricing_error(mock_pricing_data
|
|||
date_end=datetime.date(year=2022, month=10, day=1),
|
||||
)
|
||||
agenda_pricing.agendas.add(agenda)
|
||||
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,
|
||||
)
|
||||
|
||||
mock_pricing_data_event.side_effect = [
|
||||
{'foo1': 'bar1', 'pricing': 1},
|
||||
|
@ -860,8 +901,7 @@ def test_get_invoice_lines_for_user_check_status_pricing_error(mock_pricing_data
|
|||
},
|
||||
],
|
||||
},
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
)
|
||||
assert len(lines) == 3
|
||||
line1, line2, line3 = lines
|
||||
|
@ -882,6 +922,7 @@ def test_get_invoice_lines_for_user_check_status_pricing_error(mock_pricing_data
|
|||
}
|
||||
assert line1.pricing_data == {'foo1': 'bar1', 'pricing': 1}
|
||||
assert line1.status == 'success'
|
||||
assert line1.pool == pool
|
||||
assert isinstance(line2, DraftInvoiceLine)
|
||||
assert line2.invoice is None
|
||||
assert line2.slug == 'agenda@event-2'
|
||||
|
@ -899,6 +940,7 @@ def test_get_invoice_lines_for_user_check_status_pricing_error(mock_pricing_data
|
|||
}
|
||||
assert line2.pricing_data == {'error': {}}
|
||||
assert line2.status == 'error'
|
||||
assert line2.pool == pool
|
||||
assert isinstance(line3, DraftInvoiceLine)
|
||||
assert line3.invoice is None
|
||||
assert line3.slug == 'agenda@event-3'
|
||||
|
@ -916,6 +958,7 @@ def test_get_invoice_lines_for_user_check_status_pricing_error(mock_pricing_data
|
|||
}
|
||||
assert line3.pricing_data == {'foo3': 'bar3', 'pricing': 3}
|
||||
assert line3.status == 'success'
|
||||
assert line3.pool == pool
|
||||
|
||||
|
||||
@mock.patch('lingo.invoicing.utils.get_invoice_lines_for_user')
|
||||
|
@ -923,21 +966,33 @@ def test_get_all_invoice_lines(mock_user_lines):
|
|||
agenda1 = Agenda.objects.create(label='Agenda 1')
|
||||
agenda2 = Agenda.objects.create(label='Agenda 2')
|
||||
Agenda.objects.create(label='Agenda 3')
|
||||
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,
|
||||
)
|
||||
|
||||
line1 = DraftInvoiceLine.objects.create(
|
||||
quantity=0,
|
||||
unit_amount=0,
|
||||
total_amount=0,
|
||||
pool=pool,
|
||||
)
|
||||
line2 = DraftInvoiceLine.objects.create(
|
||||
quantity=0,
|
||||
unit_amount=0,
|
||||
total_amount=0,
|
||||
pool=pool,
|
||||
)
|
||||
line3 = DraftInvoiceLine.objects.create(
|
||||
quantity=0,
|
||||
unit_amount=0,
|
||||
total_amount=0,
|
||||
pool=pool,
|
||||
)
|
||||
|
||||
mock_user_lines.side_effect = [[line1, line2], [line3]]
|
||||
|
@ -947,8 +1002,7 @@ def test_get_all_invoice_lines(mock_user_lines):
|
|||
utils.get_all_invoice_lines(
|
||||
agendas=[agenda1, agenda2],
|
||||
subscriptions={},
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
)
|
||||
== []
|
||||
)
|
||||
|
@ -961,8 +1015,7 @@ def test_get_all_invoice_lines(mock_user_lines):
|
|||
'user:1': {'foo': 'bar1'},
|
||||
'user:2': {'foo': 'bar2'},
|
||||
},
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
) == [line1, line2, line3]
|
||||
assert mock_user_lines.call_args_list == [
|
||||
mock.call(
|
||||
|
@ -970,16 +1023,14 @@ def test_get_all_invoice_lines(mock_user_lines):
|
|||
agendas_pricings=mock.ANY,
|
||||
user_external_id='user:1',
|
||||
subscriptions={'foo': 'bar1'},
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
),
|
||||
mock.call(
|
||||
agendas=[agenda1, agenda2],
|
||||
agendas_pricings=mock.ANY,
|
||||
user_external_id='user:2',
|
||||
subscriptions={'foo': 'bar2'},
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
),
|
||||
]
|
||||
|
||||
|
@ -1029,6 +1080,16 @@ def test_get_all_invoice_lines_queryset(mock_status):
|
|||
)
|
||||
agenda_pricing22.agendas.add(agenda2)
|
||||
|
||||
campaign = Campaign.objects.create(
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 11, 1),
|
||||
date_issue=datetime.date(2022, 11, 30),
|
||||
)
|
||||
pool = Pool.objects.create(
|
||||
campaign=campaign,
|
||||
draft=True,
|
||||
)
|
||||
|
||||
mock_status.return_value = [
|
||||
{
|
||||
'event': {
|
||||
|
@ -1109,8 +1170,7 @@ def test_get_all_invoice_lines_queryset(mock_status):
|
|||
],
|
||||
},
|
||||
},
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 11, 1),
|
||||
pool=pool,
|
||||
)
|
||||
assert lines
|
||||
assert len(ctx.captured_queries) == 7
|
||||
|
@ -1124,6 +1184,16 @@ def test_generate_invoices_from_lines():
|
|||
agenda3 = Agenda.objects.create(label='Agenda 3', regie=regie1)
|
||||
agenda4 = Agenda.objects.create(label='Agenda 4') # regie not configured
|
||||
|
||||
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,
|
||||
)
|
||||
|
||||
line_error = DraftInvoiceLine.objects.create(
|
||||
event={'agenda': 'agenda-1'},
|
||||
quantity=0,
|
||||
|
@ -1132,6 +1202,7 @@ def test_generate_invoices_from_lines():
|
|||
user_external_id='user:1',
|
||||
payer_external_id='user:1',
|
||||
status='error',
|
||||
pool=pool,
|
||||
)
|
||||
line1 = DraftInvoiceLine.objects.create(
|
||||
event={'agenda': 'agenda-1'},
|
||||
|
@ -1141,6 +1212,7 @@ def test_generate_invoices_from_lines():
|
|||
user_external_id='user:1',
|
||||
payer_external_id='user:1',
|
||||
status='success',
|
||||
pool=pool,
|
||||
)
|
||||
line2 = DraftInvoiceLine.objects.create(
|
||||
event={'agenda': 'agenda-1'},
|
||||
|
@ -1150,6 +1222,7 @@ def test_generate_invoices_from_lines():
|
|||
user_external_id='user:1',
|
||||
payer_external_id='user:1',
|
||||
status='success',
|
||||
pool=pool,
|
||||
)
|
||||
line3 = DraftInvoiceLine.objects.create(
|
||||
event={'agenda': 'agenda-2'},
|
||||
|
@ -1159,6 +1232,7 @@ def test_generate_invoices_from_lines():
|
|||
user_external_id='user:1',
|
||||
payer_external_id='user:1',
|
||||
status='success',
|
||||
pool=pool,
|
||||
)
|
||||
line4 = DraftInvoiceLine.objects.create(
|
||||
event={'agenda': 'agenda-2'},
|
||||
|
@ -1168,6 +1242,7 @@ def test_generate_invoices_from_lines():
|
|||
user_external_id='user:1',
|
||||
payer_external_id='user:2',
|
||||
status='success',
|
||||
pool=pool,
|
||||
)
|
||||
line5 = DraftInvoiceLine.objects.create(
|
||||
event={'agenda': 'agenda-3'},
|
||||
|
@ -1177,6 +1252,7 @@ def test_generate_invoices_from_lines():
|
|||
user_external_id='user:2',
|
||||
payer_external_id='user:1',
|
||||
status='success',
|
||||
pool=pool,
|
||||
)
|
||||
DraftInvoiceLine.objects.create( # not used for generation
|
||||
event={'agenda': 'agenda-3'},
|
||||
|
@ -1186,6 +1262,7 @@ def test_generate_invoices_from_lines():
|
|||
user_external_id='user:2',
|
||||
payer_external_id='user:1',
|
||||
status='success',
|
||||
pool=pool,
|
||||
)
|
||||
line6 = DraftInvoiceLine.objects.create(
|
||||
event={'agenda': 'agenda-4'}, # regie not configured
|
||||
|
@ -1195,21 +1272,20 @@ def test_generate_invoices_from_lines():
|
|||
user_external_id='user:1',
|
||||
payer_external_id='user:1',
|
||||
status='success',
|
||||
pool=pool,
|
||||
)
|
||||
|
||||
invoices = utils.generate_invoices_from_lines(
|
||||
agendas=[],
|
||||
all_lines=[line_error, line1, line2, line3, line4, line5, line6],
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
)
|
||||
assert len(invoices) == 0
|
||||
|
||||
invoices = utils.generate_invoices_from_lines(
|
||||
agendas=[agenda1, agenda2, agenda3, agenda4],
|
||||
all_lines=[line_error, line1, line2, line3, line4, line5, line6],
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
)
|
||||
assert len(invoices) == 3
|
||||
invoice1, invoice2, invoice3 = invoices
|
||||
|
@ -1220,23 +1296,26 @@ def test_generate_invoices_from_lines():
|
|||
assert isinstance(invoice1, DraftInvoice)
|
||||
assert invoice1.label == 'Invoice from 2022-09-01 to 2022-09-30'
|
||||
assert invoice1.total_amount == 8
|
||||
assert invoice1.date_issue == datetime.date(2022, 10, 1)
|
||||
assert invoice1.date_issue == datetime.date(2022, 10, 31)
|
||||
assert invoice1.regie == regie1
|
||||
assert invoice1.payer == 'user:1'
|
||||
assert invoice1.pool == pool
|
||||
assert list(invoice1.lines.order_by('pk')) == [line1, line2, line5]
|
||||
assert isinstance(invoice2, DraftInvoice)
|
||||
assert invoice2.label == 'Invoice from 2022-09-01 to 2022-09-30'
|
||||
assert invoice2.total_amount == 3
|
||||
assert invoice2.date_issue == datetime.date(2022, 10, 1)
|
||||
assert invoice2.date_issue == datetime.date(2022, 10, 31)
|
||||
assert invoice2.regie == regie2
|
||||
assert invoice2.payer == 'user:1'
|
||||
assert invoice2.pool == pool
|
||||
assert list(invoice2.lines.order_by('pk')) == [line3]
|
||||
assert isinstance(invoice3, DraftInvoice)
|
||||
assert invoice3.label == 'Invoice from 2022-09-01 to 2022-09-30'
|
||||
assert invoice3.total_amount == 4
|
||||
assert invoice3.date_issue == datetime.date(2022, 10, 1)
|
||||
assert invoice3.date_issue == datetime.date(2022, 10, 31)
|
||||
assert invoice3.regie == regie2
|
||||
assert invoice3.payer == 'user:2'
|
||||
assert invoice3.pool == pool
|
||||
assert list(invoice3.lines.order_by('pk')) == [line4]
|
||||
|
||||
|
||||
|
@ -1248,73 +1327,40 @@ def test_generate_invoices(mock_generate, mock_lines, mock_subscriptions, mock_a
|
|||
agenda1 = Agenda.objects.create(label='Agenda 1')
|
||||
agenda2 = Agenda.objects.create(label='Agenda 2')
|
||||
Agenda.objects.create(label='Agenda 3')
|
||||
line1 = DraftInvoiceLine.objects.create(
|
||||
event={'agenda': 'agenda-1'},
|
||||
quantity=1,
|
||||
unit_amount=1,
|
||||
total_amount=1,
|
||||
user_external_id='user:1',
|
||||
payer_external_id='user:1',
|
||||
status='success',
|
||||
)
|
||||
line2 = DraftInvoiceLine.objects.create(
|
||||
event={'agenda': 'agenda-1'},
|
||||
quantity=1,
|
||||
unit_amount=2,
|
||||
total_amount=2,
|
||||
user_external_id='user:1',
|
||||
payer_external_id='user:1',
|
||||
status='success',
|
||||
)
|
||||
line3 = DraftInvoiceLine.objects.create(
|
||||
event={'agenda': 'agenda-2'},
|
||||
quantity=1,
|
||||
unit_amount=3,
|
||||
total_amount=3,
|
||||
user_external_id='user:1',
|
||||
payer_external_id='user:1',
|
||||
status='success',
|
||||
)
|
||||
DraftInvoiceLine.objects.create(
|
||||
event={'agenda': 'agenda-1'},
|
||||
quantity=1,
|
||||
unit_amount=5,
|
||||
total_amount=5,
|
||||
user_external_id='user:2',
|
||||
payer_external_id='user:1',
|
||||
status='success',
|
||||
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),
|
||||
)
|
||||
|
||||
mock_agendas.return_value = [agenda1, agenda2]
|
||||
mock_subscriptions.return_value = {'foo': 'bar'}
|
||||
mock_lines.return_value = [line1, line2, line3]
|
||||
mock_lines.return_value = ['foo', 'bar']
|
||||
|
||||
# check only calls between functions
|
||||
utils.generate_invoices(date_start=datetime.date(2022, 9, 1), date_end=datetime.date(2022, 10, 1))
|
||||
assert mock_agendas.call_args_list == [
|
||||
mock.call(date_start=datetime.date(2022, 9, 1), date_end=datetime.date(2022, 10, 1))
|
||||
]
|
||||
utils.generate_invoices(campaign=campaign, draft=True)
|
||||
pool = Pool.objects.latest('pk')
|
||||
assert pool.campaign == campaign
|
||||
assert pool.draft is True
|
||||
assert mock_agendas.call_args_list == [mock.call(pool=pool)]
|
||||
assert mock_subscriptions.call_args_list == [
|
||||
mock.call(
|
||||
agendas=[agenda1, agenda2],
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
)
|
||||
]
|
||||
assert mock_lines.call_args_list == [
|
||||
mock.call(
|
||||
agendas=[agenda1, agenda2],
|
||||
subscriptions={'foo': 'bar'},
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
pool=pool,
|
||||
)
|
||||
]
|
||||
assert mock_generate.call_args_list == [
|
||||
mock.call(
|
||||
agendas=[agenda1, agenda2],
|
||||
all_lines=[line1, line2, line3],
|
||||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 10, 1),
|
||||
all_lines=['foo', 'bar'],
|
||||
pool=pool,
|
||||
)
|
||||
]
|
||||
|
||||
|
@ -1338,7 +1384,54 @@ def test_generate_invoices_cmd():
|
|||
assert '%s' % excinfo.value == 'Bad value "bad-value" for date_end'
|
||||
assert mock_generate.call_args_list == []
|
||||
|
||||
with pytest.raises(CommandError) as excinfo:
|
||||
call_command('generate_invoices', '2022-09-01', '2022-10-01', '--date-issue=bad-value')
|
||||
assert '%s' % excinfo.value == 'Bad value "bad-value" for date_issue'
|
||||
assert mock_generate.call_args_list == []
|
||||
|
||||
assert Campaign.objects.count() == 0
|
||||
call_command('generate_invoices', '2022-09-01', '2022-10-01')
|
||||
assert mock_generate.call_args_list == [
|
||||
mock.call(date_start=datetime.date(2022, 9, 1), date_end=datetime.date(2022, 10, 1))
|
||||
]
|
||||
assert Campaign.objects.count() == 1
|
||||
campaign = Campaign.objects.latest('pk')
|
||||
assert campaign.date_start == datetime.date(2022, 9, 1)
|
||||
assert campaign.date_end == datetime.date(2022, 10, 1)
|
||||
assert campaign.date_issue == campaign.date_end
|
||||
assert mock_generate.call_args_list == [mock.call(campaign=campaign, draft=False)]
|
||||
mock_generate.reset_mock()
|
||||
|
||||
# again
|
||||
call_command('generate_invoices', '2022-09-01', '2022-10-01')
|
||||
assert Campaign.objects.count() == 1
|
||||
assert mock_generate.call_args_list == [mock.call(campaign=campaign, draft=False)]
|
||||
mock_generate.reset_mock()
|
||||
call_command('generate_invoices', '2022-09-01', '2022-10-01', '--draft')
|
||||
assert Campaign.objects.count() == 1
|
||||
assert mock_generate.call_args_list == [mock.call(campaign=campaign, draft=True)]
|
||||
mock_generate.reset_mock()
|
||||
|
||||
# with overlapping
|
||||
with pytest.raises(CommandError) as excinfo:
|
||||
call_command('generate_invoices', '2022-08-31', '2022-09-02')
|
||||
assert '%s' % excinfo.value == 'Overlapping campaigns already exist'
|
||||
assert mock_generate.call_args_list == []
|
||||
with pytest.raises(CommandError) as excinfo:
|
||||
call_command('generate_invoices', '2022-09-30', '2022-10-02')
|
||||
assert '%s' % excinfo.value == 'Overlapping campaigns already exist'
|
||||
assert mock_generate.call_args_list == []
|
||||
|
||||
# no overlapping
|
||||
call_command('generate_invoices', '2022-08-01', '2022-09-01', '--date-issue=2022-10-31')
|
||||
assert Campaign.objects.count() == 2
|
||||
campaign = Campaign.objects.latest('pk')
|
||||
assert mock_generate.call_args_list == [mock.call(campaign=campaign, draft=False)]
|
||||
assert campaign.date_start == datetime.date(2022, 8, 1)
|
||||
assert campaign.date_end == datetime.date(2022, 9, 1)
|
||||
assert campaign.date_issue == datetime.date(2022, 10, 31)
|
||||
mock_generate.reset_mock()
|
||||
call_command('generate_invoices', '2022-10-01', '2022-11-01')
|
||||
assert Campaign.objects.count() == 3
|
||||
campaign = Campaign.objects.latest('pk')
|
||||
assert mock_generate.call_args_list == [mock.call(campaign=campaign, draft=False)]
|
||||
assert campaign.date_start == datetime.date(2022, 10, 1)
|
||||
assert campaign.date_end == datetime.date(2022, 11, 1)
|
||||
assert campaign.date_issue == campaign.date_end
|
||||
|
|
|
@ -2,7 +2,7 @@ import datetime
|
|||
|
||||
import pytest
|
||||
|
||||
from lingo.invoicing.models import DraftInvoice, DraftInvoiceLine, Invoice, InvoiceLine, Regie
|
||||
from lingo.invoicing.models import Campaign, DraftInvoice, DraftInvoiceLine, Invoice, InvoiceLine, Pool, Regie
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
@ -13,9 +13,19 @@ def test_invoice_total_amount(draft):
|
|||
invoice_model = DraftInvoice if draft else Invoice
|
||||
line_model = DraftInvoiceLine if draft else InvoiceLine
|
||||
|
||||
invoice = invoice_model.objects.create(date_issue=datetime.date.today(), regie=regie)
|
||||
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=draft,
|
||||
)
|
||||
|
||||
invoice = invoice_model.objects.create(date_issue=datetime.date.today(), regie=regie, pool=pool)
|
||||
assert invoice.total_amount == 0
|
||||
invoice2 = invoice_model.objects.create(date_issue=datetime.date.today(), regie=regie)
|
||||
invoice2 = invoice_model.objects.create(date_issue=datetime.date.today(), regie=regie, pool=pool)
|
||||
assert invoice2.total_amount == 0
|
||||
|
||||
# line with error status, ignored
|
||||
|
@ -25,6 +35,7 @@ def test_invoice_total_amount(draft):
|
|||
unit_amount=0,
|
||||
total_amount=0,
|
||||
status='error',
|
||||
pool=pool,
|
||||
)
|
||||
invoice.refresh_from_db()
|
||||
assert invoice.total_amount == 0
|
||||
|
@ -73,6 +84,7 @@ def test_invoice_total_amount(draft):
|
|||
unit_amount=20,
|
||||
total_amount=20,
|
||||
status='success',
|
||||
pool=pool,
|
||||
)
|
||||
invoice.refresh_from_db()
|
||||
assert invoice.total_amount == 32
|
||||
|
@ -100,6 +112,7 @@ def test_invoice_total_amount(draft):
|
|||
unit_amount=20,
|
||||
total_amount=20,
|
||||
status='success',
|
||||
pool=pool,
|
||||
)
|
||||
invoice.refresh_from_db()
|
||||
assert invoice.total_amount == 12
|
||||
|
|
Loading…
Reference in New Issue