invoicing: configure injected lines on campaign (#73742)
gitea-wip/lingo/pipeline/pr-main This commit looks good
Details
gitea-wip/lingo/pipeline/pr-main This commit looks good
Details
This commit is contained in:
parent
36d54f8b2c
commit
6dee6eb4dc
|
@ -25,7 +25,7 @@ from lingo.invoicing.models import Campaign, DraftInvoiceLine, InvoiceLine, Regi
|
|||
class CampaignForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Campaign
|
||||
fields = ['date_start', 'date_end', 'date_issue']
|
||||
fields = ['date_start', 'date_end', 'date_issue', 'injected_lines']
|
||||
widgets = {
|
||||
'date_start': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
|
||||
'date_end': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('invoicing', '0014_error_status'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='campaign',
|
||||
name='injected_lines',
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
('no', 'No'),
|
||||
('period', 'Yes, only for the period'),
|
||||
('all', 'Yes, all injected lines before the end of the period'),
|
||||
],
|
||||
default='no',
|
||||
max_length=10,
|
||||
verbose_name='Integrate injected lines',
|
||||
),
|
||||
),
|
||||
]
|
|
@ -134,6 +134,16 @@ class Campaign(models.Model):
|
|||
date_start = models.DateField(_('Start date'))
|
||||
date_end = models.DateField(_('End date'))
|
||||
date_issue = models.DateField(_('Issue date'))
|
||||
injected_lines = models.CharField(
|
||||
_('Integrate injected lines'),
|
||||
choices=[
|
||||
('no', _('No')),
|
||||
('period', _('Yes, only for the period')),
|
||||
('all', _('Yes, all injected lines before the end of the period')),
|
||||
],
|
||||
default='no',
|
||||
max_length=10,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return _('From %(start)s to %(end)s') % {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
<li>{% trans "Start date:" %} {{ object.date_start|date:'d/m/Y' }}</li>
|
||||
<li>{% trans "End date:" %} {{ object.date_end|date:'d/m/Y' }}</li>
|
||||
<li>{% trans "Issue date:" %} {{ object.date_issue|date:'d/m/Y' }}</li>
|
||||
<li>{% trans "Integrate injected lines:" %} {{ object.get_injected_lines_display }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -143,42 +143,47 @@ def get_invoice_lines_for_user(agendas, agendas_pricings, user_external_id, user
|
|||
)
|
||||
)
|
||||
|
||||
# fetch injected lines
|
||||
injected_lines = (
|
||||
InjectedLine.objects.filter(
|
||||
event_date__gte=pool.campaign.date_start,
|
||||
event_date__lt=pool.campaign.date_end,
|
||||
user_external_id=user_external_id,
|
||||
)
|
||||
.exclude(
|
||||
# exclude already invoiced lines
|
||||
invoiceline__isnull=False
|
||||
)
|
||||
.exclude(
|
||||
# exclude lines used in another campaign
|
||||
pk__in=DraftInvoiceLine.objects.filter(from_injected_line__isnull=False)
|
||||
.exclude(pool__campaign=pool.campaign)
|
||||
.values('from_injected_line')
|
||||
)
|
||||
)
|
||||
|
||||
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,
|
||||
if pool.campaign.injected_lines != 'no':
|
||||
# fetch injected lines
|
||||
injected_lines = (
|
||||
InjectedLine.objects.filter(
|
||||
event_date__lt=pool.campaign.date_end,
|
||||
user_external_id=user_external_id,
|
||||
user_name=user_name,
|
||||
payer_external_id=injected_line.user_external_id,
|
||||
status='success',
|
||||
pool=pool,
|
||||
from_injected_line=injected_line,
|
||||
)
|
||||
.exclude(
|
||||
# exclude already invoiced lines
|
||||
invoiceline__isnull=False
|
||||
)
|
||||
.exclude(
|
||||
# exclude lines used in another campaign
|
||||
pk__in=DraftInvoiceLine.objects.filter(from_injected_line__isnull=False)
|
||||
.exclude(pool__campaign=pool.campaign)
|
||||
.values('from_injected_line')
|
||||
)
|
||||
.order_by('event_date')
|
||||
)
|
||||
if pool.campaign.injected_lines == 'period':
|
||||
injected_lines = injected_lines.filter(
|
||||
event_date__gte=pool.campaign.date_start,
|
||||
)
|
||||
|
||||
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=user_external_id,
|
||||
user_name=user_name,
|
||||
payer_external_id=injected_line.user_external_id,
|
||||
status='success',
|
||||
pool=pool,
|
||||
from_injected_line=injected_line,
|
||||
)
|
||||
)
|
||||
|
||||
DraftInvoiceLine.objects.bulk_create(lines)
|
||||
|
||||
|
|
|
@ -198,6 +198,7 @@ regies_import = RegiesImportView.as_view()
|
|||
class CampaignListView(ListView):
|
||||
template_name = 'lingo/invoicing/manager_campaign_list.html'
|
||||
model = Campaign
|
||||
ordering = '-date_start'
|
||||
|
||||
|
||||
campaign_list = CampaignListView.as_view()
|
||||
|
|
|
@ -222,9 +222,10 @@ def test_get_invoice_lines_for_user_check_status_error(mock_status):
|
|||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('injected_lines', ['no', 'period', 'all'])
|
||||
@mock.patch('lingo.invoicing.utils.get_check_status')
|
||||
@mock.patch('lingo.pricing.models.AgendaPricing.get_pricing_data_for_event')
|
||||
def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_status):
|
||||
def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_status, injected_lines):
|
||||
regie = Regie.objects.create(label='Regie')
|
||||
agenda1 = Agenda.objects.create(label='Agenda 1')
|
||||
agenda2 = Agenda.objects.create(label='Agenda 2')
|
||||
|
@ -239,6 +240,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),
|
||||
date_issue=datetime.date(2022, 10, 31),
|
||||
injected_lines=injected_lines,
|
||||
)
|
||||
old_pool = Pool.objects.create(
|
||||
campaign=campaign,
|
||||
|
@ -259,8 +261,8 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
)
|
||||
|
||||
# create some injected lines
|
||||
InjectedLine.objects.create(
|
||||
event_date=datetime.date(2022, 8, 31), # too soon
|
||||
injected_line1 = InjectedLine.objects.create(
|
||||
event_date=datetime.date(2022, 8, 31), # before the period
|
||||
slug='event-2022-08-31',
|
||||
label='Event 2022-08-31',
|
||||
quantity=2,
|
||||
|
@ -387,7 +389,12 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
user_name='User1 Name1',
|
||||
pool=pool,
|
||||
)
|
||||
assert len(lines) == 2 # injected lines
|
||||
if injected_lines == 'no':
|
||||
assert len(lines) == 0
|
||||
elif injected_lines == 'period':
|
||||
assert len(lines) == 2 # injected lines
|
||||
else:
|
||||
assert len(lines) == 3 # injected lines
|
||||
assert mock_status.call_args_list == [
|
||||
mock.call(
|
||||
agenda_slugs=['agenda-1', 'agenda-2'],
|
||||
|
@ -511,8 +518,15 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
adult_external_id='user:1',
|
||||
),
|
||||
]
|
||||
assert len(lines) == 6
|
||||
line1, line2, line3, line4, line5, line6 = lines
|
||||
if injected_lines == 'no':
|
||||
assert len(lines) == 4
|
||||
line1, line2, line3, line4 = lines
|
||||
elif injected_lines == 'period':
|
||||
assert len(lines) == 6
|
||||
line1, line2, line3, line4, line6, line7 = lines
|
||||
else:
|
||||
assert len(lines) == 7
|
||||
line1, line2, line3, line4, line5, line6, line7 = lines
|
||||
assert isinstance(line1, DraftInvoiceLine)
|
||||
assert line1.invoice is None
|
||||
assert line1.event_date == datetime.date(2022, 9, 1)
|
||||
|
@ -597,38 +611,56 @@ def test_get_invoice_lines_for_user_check_status(mock_pricing_data_event, mock_s
|
|||
assert line4.status == 'success'
|
||||
assert line4.pool == pool
|
||||
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 == {}
|
||||
assert line5.status == 'success'
|
||||
assert line5.pool == pool
|
||||
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 == {}
|
||||
assert line6.status == 'success'
|
||||
assert line6.pool == pool
|
||||
assert line6.from_injected_line == injected_line4
|
||||
if injected_lines != 'no':
|
||||
if injected_lines == 'all':
|
||||
assert isinstance(line5, DraftInvoiceLine)
|
||||
assert line5.invoice is None
|
||||
assert line5.event_date == injected_line1.event_date
|
||||
assert line5.slug == 'event-2022-08-31'
|
||||
assert line5.label == 'Event 2022-08-31'
|
||||
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 == {}
|
||||
assert line5.status == 'success'
|
||||
assert line5.pool == pool
|
||||
assert line5.from_injected_line == injected_line1
|
||||
assert isinstance(line6, DraftInvoiceLine)
|
||||
assert line6.invoice is None
|
||||
assert line6.event_date == injected_line2.event_date
|
||||
assert line6.slug == 'event-2022-09-01'
|
||||
assert line6.label == 'Event 2022-09-01'
|
||||
assert line6.quantity == 2
|
||||
assert line6.unit_amount == 1.5
|
||||
assert line6.total_amount == 3
|
||||
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 == {}
|
||||
assert line6.status == 'success'
|
||||
assert line6.pool == pool
|
||||
assert line6.from_injected_line == injected_line2
|
||||
assert isinstance(line7, DraftInvoiceLine)
|
||||
assert line7.invoice is None
|
||||
assert line7.event_date == injected_line4.event_date
|
||||
assert line7.slug == 'event-2022-09-30'
|
||||
assert line7.label == 'Event 2022-09-30'
|
||||
assert line7.quantity == 3
|
||||
assert line7.unit_amount == 1.5
|
||||
assert line7.total_amount == 4.5
|
||||
assert line7.user_external_id == 'user:1'
|
||||
assert line7.user_name == 'User1 Name1'
|
||||
assert line7.payer_external_id == 'user:1'
|
||||
assert line7.event == {}
|
||||
assert line7.pricing_data == {}
|
||||
assert line7.status == 'success'
|
||||
assert line7.pool == pool
|
||||
assert line7.from_injected_line == injected_line4
|
||||
|
||||
|
||||
@mock.patch('lingo.invoicing.utils.get_check_status')
|
||||
|
@ -1016,6 +1048,7 @@ def test_get_all_invoice_lines_queryset(mock_status):
|
|||
date_start=datetime.date(2022, 9, 1),
|
||||
date_end=datetime.date(2022, 11, 1),
|
||||
date_issue=datetime.date(2022, 11, 30),
|
||||
injected_lines='all',
|
||||
)
|
||||
pool = Pool.objects.create(
|
||||
campaign=campaign,
|
||||
|
|
Loading…
Reference in New Issue