invoicing: compute and set accounting code on journal lines (#89025)
This commit is contained in:
parent
cfc2ff7b70
commit
f7b4199846
|
@ -767,6 +767,7 @@ class AbstractJournalLine(models.Model):
|
|||
'Effort rate target is not a %(wanted)s: %(effort_rate_target)s'
|
||||
),
|
||||
'PricingEffortRateTargetValueError': _('Effort rate target bad value: %(effort_rate_target)s'),
|
||||
'PricingAccountingCodeError': _('Impossible to determine an accounting code'),
|
||||
'PricingUnknownCheckStatusError': _('Unknown check status: %(status)s'),
|
||||
'PricingEventNotCheckedError': _('Event is not checked'),
|
||||
'PricingBookingNotCheckedError': _('Booking is not checked'),
|
||||
|
|
|
@ -177,6 +177,7 @@ def get_invoice_lines_for_user(
|
|||
'booking': serialized_booking,
|
||||
'status': 'success',
|
||||
'pool': pool,
|
||||
'accounting_code': pricing_data.get('accounting_code') or '',
|
||||
}
|
||||
booking_details = pricing_data.get('booking_details') or {}
|
||||
if agenda.partial_bookings and booking_details.get('status') in ['absence', 'presence']:
|
||||
|
|
|
@ -80,6 +80,10 @@ class PricingEffortRateTargetValueError(PricingError):
|
|||
pass
|
||||
|
||||
|
||||
class PricingAccountingCodeError(PricingError):
|
||||
pass
|
||||
|
||||
|
||||
class PricingUnknownCheckStatusError(PricingError):
|
||||
pass
|
||||
|
||||
|
@ -476,6 +480,12 @@ class Pricing(WithApplicationMixin, models.Model):
|
|||
user_external_id=user_external_id,
|
||||
payer_external_id=payer_external_id,
|
||||
)
|
||||
accounting_code = self.compute_accounting_code(
|
||||
request=request,
|
||||
original_context=context,
|
||||
user_external_id=user_external_id,
|
||||
payer_external_id=payer_external_id,
|
||||
)
|
||||
return {
|
||||
'pricing': pricing,
|
||||
'calculation_details': {
|
||||
|
@ -485,6 +495,7 @@ class Pricing(WithApplicationMixin, models.Model):
|
|||
'effort_rate': effort_rate,
|
||||
'context': context,
|
||||
},
|
||||
'accounting_code': accounting_code,
|
||||
}
|
||||
|
||||
def get_pricing_data_for_event(
|
||||
|
@ -518,6 +529,12 @@ class Pricing(WithApplicationMixin, models.Model):
|
|||
payer_external_id=payer_external_id,
|
||||
)
|
||||
modifier = self.get_booking_modifier(agenda=agenda, check_status=check_status)
|
||||
accounting_code = self.compute_accounting_code(
|
||||
request=request,
|
||||
original_context=context,
|
||||
user_external_id=user_external_id,
|
||||
payer_external_id=payer_external_id,
|
||||
)
|
||||
return self.aggregate_pricing_data(
|
||||
pricing=pricing,
|
||||
criterias=criterias,
|
||||
|
@ -525,9 +542,12 @@ class Pricing(WithApplicationMixin, models.Model):
|
|||
effort_rate=effort_rate,
|
||||
context=context,
|
||||
modifier=modifier,
|
||||
accounting_code=accounting_code,
|
||||
)
|
||||
|
||||
def aggregate_pricing_data(self, pricing, criterias, reduction_rate, effort_rate, context, modifier):
|
||||
def aggregate_pricing_data(
|
||||
self, pricing, criterias, reduction_rate, effort_rate, context, modifier, accounting_code
|
||||
):
|
||||
if modifier['modifier_type'] == 'fixed':
|
||||
pricing_amount = modifier['modifier_fixed']
|
||||
else:
|
||||
|
@ -542,6 +562,7 @@ class Pricing(WithApplicationMixin, models.Model):
|
|||
'context': context,
|
||||
},
|
||||
'booking_details': modifier,
|
||||
'accounting_code': accounting_code,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
|
@ -633,7 +654,7 @@ class Pricing(WithApplicationMixin, models.Model):
|
|||
return round(pricing, 4), criterias
|
||||
return round(pricing, 2), criterias
|
||||
|
||||
def compute_reduction_rate(self, request, original_context, user_external_id, payer_external_id):
|
||||
def _compute_template(self, request, original_context, user_external_id, payer_external_id, template):
|
||||
context = RequestContext(request)
|
||||
context.push(original_context)
|
||||
context.push({'user_external_id': user_external_id, 'payer_external_id': payer_external_id})
|
||||
|
@ -641,8 +662,13 @@ class Pricing(WithApplicationMixin, models.Model):
|
|||
context['user_external_raw_id'] = user_external_id.split(':')[1]
|
||||
if ':' in payer_external_id:
|
||||
context['payer_external_raw_id'] = payer_external_id.split(':')[1]
|
||||
return Template(template).render(context)
|
||||
|
||||
def compute_reduction_rate(self, request, original_context, user_external_id, payer_external_id):
|
||||
try:
|
||||
reduction_rate = Template(self.reduction_rate).render(context)
|
||||
reduction_rate = self._compute_template(
|
||||
request, original_context, user_external_id, payer_external_id, self.reduction_rate
|
||||
)
|
||||
except (TemplateSyntaxError, VariableDoesNotExist):
|
||||
raise PricingReductionRateError()
|
||||
|
||||
|
@ -683,15 +709,10 @@ class Pricing(WithApplicationMixin, models.Model):
|
|||
}
|
||||
|
||||
def compute_effort_rate_target(self, request, original_context, user_external_id, payer_external_id):
|
||||
context = RequestContext(request)
|
||||
context.push(original_context)
|
||||
context.push({'user_external_id': user_external_id, 'payer_external_id': payer_external_id})
|
||||
if ':' in user_external_id:
|
||||
context['user_external_raw_id'] = user_external_id.split(':')[1]
|
||||
if ':' in payer_external_id:
|
||||
context['payer_external_raw_id'] = payer_external_id.split(':')[1]
|
||||
try:
|
||||
effort_rate_target = Template(self.effort_rate_target).render(context)
|
||||
effort_rate_target = self._compute_template(
|
||||
request, original_context, user_external_id, payer_external_id, self.effort_rate_target
|
||||
)
|
||||
except (TemplateSyntaxError, VariableDoesNotExist):
|
||||
raise PricingEffortRateTargetError()
|
||||
|
||||
|
@ -734,6 +755,14 @@ class Pricing(WithApplicationMixin, models.Model):
|
|||
'bounded_pricing': adjusted_pricing,
|
||||
}
|
||||
|
||||
def compute_accounting_code(self, request, original_context, user_external_id, payer_external_id):
|
||||
try:
|
||||
return self._compute_template(
|
||||
request, original_context, user_external_id, payer_external_id, self.accounting_code
|
||||
)
|
||||
except (TemplateSyntaxError, VariableDoesNotExist):
|
||||
raise PricingAccountingCodeError()
|
||||
|
||||
def get_booking_modifier(self, agenda, check_status):
|
||||
status = check_status['status']
|
||||
if status not in ['error', 'not-booked', 'cancelled', 'presence', 'absence']:
|
||||
|
|
|
@ -2524,6 +2524,7 @@ def test_journal_pool_lines(app, admin_user, draft):
|
|||
('PricingEffortRateTargetError', {}),
|
||||
('PricingEffortRateTargetFormatError', {'effort_rate_target': 'foo', 'wanted': 'decimal'}),
|
||||
('PricingEffortRateTargetValueError', {'effort_rate_target': 42}),
|
||||
('PricingAccountingCodeError', {}),
|
||||
('PricingUnknownCheckStatusError', {'status': 'unknown'}),
|
||||
('PricingEventNotCheckedError', {}),
|
||||
('PricingBookingNotCheckedError', {}),
|
||||
|
@ -2642,7 +2643,7 @@ def test_journal_pool_lines(app, admin_user, draft):
|
|||
resp = app.get(
|
||||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk)
|
||||
)
|
||||
assert len(resp.pyquery('td.status')) == 29
|
||||
assert len(resp.pyquery('td.status')) == 30
|
||||
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()
|
||||
|
@ -2749,156 +2750,165 @@ def test_journal_pool_lines(app, admin_user, draft):
|
|||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[12].pk).text())
|
||||
== 'Error (Unknown check status: unknown) ignore - mark as fixed'
|
||||
== 'Error (Impossible to determine an accounting code) ignore - mark as fixed'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[12].pk).text().strip()
|
||||
== "{'error': 'PricingUnknownCheckStatusError', 'error_details': {'status': 'unknown'}} "
|
||||
== "{'error': 'PricingAccountingCodeError', 'error_details': {}} "
|
||||
"{'agenda': 'agenda-a', 'primary_event': 'event-aa', 'slug': 'event-aa--date'} {}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[13].pk).text())
|
||||
== 'Error (Event is not checked) ignore - mark as fixed'
|
||||
== 'Error (Unknown check status: unknown) ignore - mark as fixed'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[13].pk).text().strip()
|
||||
== "{'error': 'PricingEventNotCheckedError', 'error_details': {}} "
|
||||
== "{'error': 'PricingUnknownCheckStatusError', 'error_details': {'status': 'unknown'}} "
|
||||
"{'agenda': 'agenda-a', 'primary_event': 'event-aa', 'slug': 'event-aa--date'} {}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[14].pk).text())
|
||||
== 'Error (Booking is not checked) ignore - mark as fixed'
|
||||
== 'Error (Event is not checked) ignore - mark as fixed'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[14].pk).text().strip()
|
||||
== "{'error': 'PricingBookingNotCheckedError', 'error_details': {}} "
|
||||
== "{'error': 'PricingEventNotCheckedError', 'error_details': {}} "
|
||||
"{'agenda': 'agenda-a', 'primary_event': 'event-aa', 'slug': 'event-aa--date'} {}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[15].pk).text())
|
||||
== 'Error (Multiple booking found) ignore - mark as fixed'
|
||||
== 'Error (Booking is not checked) ignore - mark as fixed'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[15].pk).text().strip()
|
||||
== "{'error': 'PricingMultipleBookingError', 'error_details': {}} "
|
||||
== "{'error': 'PricingBookingNotCheckedError', 'error_details': {}} "
|
||||
"{'agenda': 'agenda-a', 'primary_event': 'event-aa', 'slug': 'event-aa--date'} {}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[16].pk).text())
|
||||
== 'Error (Check type error: not found) ignore - mark as fixed'
|
||||
== 'Error (Multiple booking found) ignore - mark as fixed'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[16].pk).text().strip()
|
||||
== "{'error': 'PricingBookingCheckTypeError', 'error_details': {'reason': 'not-found'}} "
|
||||
== "{'error': 'PricingMultipleBookingError', 'error_details': {}} "
|
||||
"{'agenda': 'agenda-a', 'primary_event': 'event-aa', 'slug': 'event-aa--date'} {}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[17].pk).text())
|
||||
== 'Error (Check type error: pricing not configured (group: foo-bar, check type: foo-reason)) ignore - mark as fixed'
|
||||
== 'Error (Check type error: not found) ignore - mark as fixed'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[17].pk).text().strip()
|
||||
== "{'error': 'PricingBookingCheckTypeError', 'error_details': {'reason': 'not-found'}} "
|
||||
"{'agenda': 'agenda-a', 'primary_event': 'event-aa', 'slug': 'event-aa--date'} {}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[18].pk).text())
|
||||
== 'Error (Check type error: pricing not configured (group: foo-bar, check type: foo-reason)) ignore - mark as fixed'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[18].pk).text().strip()
|
||||
== "{'error': 'PricingBookingCheckTypeError', 'error_details': {'check_type': 'foo-reason', "
|
||||
"'check_type_group': 'foo-bar', 'reason': 'not-configured'}} "
|
||||
"{'agenda': 'agenda-a', 'primary_event': 'event-aa', 'slug': 'event-aa--date'} {}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[18].pk).text())
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[19].pk).text())
|
||||
== 'Error (Check type error: wrong kind (group: foo-bar, check type: foo-reason)) ignore - mark as fixed'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[18].pk).text().strip()
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[19].pk).text().strip()
|
||||
== "{'error': 'PricingBookingCheckTypeError', 'error_details': {'check_type': 'foo-reason', "
|
||||
"'check_type_group': 'foo-bar', 'reason': 'wrong-kind'}} "
|
||||
"{'agenda': 'agenda-a', 'primary_event': 'event-aa', 'slug': 'event-aa--date'} {}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[19].pk).text())
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[20].pk).text())
|
||||
== 'Error (Impossible to determine payer: template is empty) ignore - mark as fixed'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[19].pk).text().strip()
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[20].pk).text().strip()
|
||||
== "{'error': 'PayerError', 'error_details': {'reason': 'empty-template'}} "
|
||||
"{'agenda': 'agenda-a', 'primary_event': 'event-aa', 'slug': 'event-aa--date'} {}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[20].pk).text())
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[21].pk).text())
|
||||
== 'Error (Impossible to determine payer: result is empty) ignore - mark as fixed'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[20].pk).text().strip()
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[21].pk).text().strip()
|
||||
== "{'error': 'PayerError', 'error_details': {'reason': 'empty-result'}} "
|
||||
"{'agenda': 'agenda-a', 'primary_event': 'event-aa', 'slug': 'event-aa--date'} {}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[21].pk).text())
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[22].pk).text())
|
||||
== 'Error (Impossible to determine payer: syntax error) ignore - mark as fixed'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[21].pk).text().strip()
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[22].pk).text().strip()
|
||||
== "{'error': 'PayerError', 'error_details': {'reason': 'syntax-error'}} "
|
||||
"{'agenda': 'agenda-a', 'primary_event': 'event-aa', 'slug': 'event-aa--date'} {}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[22].pk).text())
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[23].pk).text())
|
||||
== 'Error (Impossible to determine payer: variable error) ignore - mark as fixed'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[22].pk).text().strip()
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[23].pk).text().strip()
|
||||
== "{'error': 'PayerError', 'error_details': {'reason': 'variable-error'}} "
|
||||
"{'agenda': 'agenda-a', 'primary_event': 'event-aa', 'slug': 'event-aa--date'} {}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[23].pk).text())
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[24].pk).text())
|
||||
== 'Error (Impossible to determine payer: card model is not configured) ignore - mark as fixed'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[23].pk).text().strip()
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[24].pk).text().strip()
|
||||
== "{'error': 'PayerError', 'error_details': {'reason': 'missing-card-model'}} "
|
||||
"{'agenda': 'agenda-a', 'primary_event': 'event-aa', 'slug': 'event-aa--date'} {}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[24].pk).text())
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[25].pk).text())
|
||||
== 'Error (Impossible to determine payer: payer is not configured on regie) ignore - mark as fixed'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[24].pk).text().strip()
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[25].pk).text().strip()
|
||||
== "{'error': 'PayerError', 'error_details': {'reason': 'missing-payer'}} "
|
||||
"{'agenda': 'agenda-a', 'primary_event': 'event-aa', 'slug': 'event-aa--date'} {}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[25].pk).text())
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[26].pk).text())
|
||||
== 'Error (Impossible to get payer foo: mapping not defined) ignore - mark as fixed'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[25].pk).text().strip()
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[26].pk).text().strip()
|
||||
== "{'error': 'PayerDataError', 'error_details': {'key': 'foo', 'reason': 'not-defined'}} "
|
||||
"{'agenda': 'agenda-a', 'primary_event': 'event-aa', 'slug': 'event-aa--date'} {}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[26].pk).text())
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[27].pk).text())
|
||||
== 'Fixed (Impossible to get payer foo: result is empty) reset'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[26].pk).text().strip()
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[27].pk).text().strip()
|
||||
== "{'error': 'PayerDataError', 'error_details': {'key': 'foo', 'reason': 'empty-result'}} "
|
||||
"{'agenda': 'agenda-a', 'primary_event': 'event-aa', 'slug': 'event-aa--date'} {}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[27].pk).text())
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[28].pk).text())
|
||||
== 'Ignored (Impossible to get payer foo: result is not a boolean) reset'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[27].pk).text().strip()
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[28].pk).text().strip()
|
||||
== "{'error': 'PayerDataError', 'error_details': {'key': 'foo', 'reason': 'not-a-boolean'}} "
|
||||
"{'agenda': 'agenda-a', 'primary_event': 'event-aa', 'slug': 'event-aa--date'} {}"
|
||||
)
|
||||
assert (
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[28].pk).text())
|
||||
format_status(resp.pyquery('tr[data-line-id="%s"] td.status' % lines[29].pk).text())
|
||||
== 'Success (Injected)'
|
||||
)
|
||||
assert (
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[28].pk).text().strip()
|
||||
resp.pyquery('tr[data-details-for-line-id="%s"] td pre' % lines[29].pk).text().strip()
|
||||
== "{'foo': 'bar'} {} {}"
|
||||
)
|
||||
|
||||
|
@ -2934,12 +2944,12 @@ def test_journal_pool_lines(app, admin_user, draft):
|
|||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'payer_external_id': 'payer:2'},
|
||||
)
|
||||
assert len(resp.pyquery('tr td.status')) == 28
|
||||
assert len(resp.pyquery('tr td.status')) == 29
|
||||
resp = app.get(
|
||||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'payer_first_name': 'first'},
|
||||
)
|
||||
assert len(resp.pyquery('tr td.status')) == 29
|
||||
assert len(resp.pyquery('tr td.status')) == 30
|
||||
resp = app.get(
|
||||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'payer_first_name': 'first1'},
|
||||
|
@ -2949,7 +2959,7 @@ def test_journal_pool_lines(app, admin_user, draft):
|
|||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'payer_last_name': 'last'},
|
||||
)
|
||||
assert len(resp.pyquery('tr td.status')) == 29
|
||||
assert len(resp.pyquery('tr td.status')) == 30
|
||||
resp = app.get(
|
||||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'payer_last_name': 'last1'},
|
||||
|
@ -2964,12 +2974,12 @@ def test_journal_pool_lines(app, admin_user, draft):
|
|||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'payer_direct_debit': True},
|
||||
)
|
||||
assert len(resp.pyquery('tr td.status')) == 28
|
||||
assert len(resp.pyquery('tr td.status')) == 29
|
||||
resp = app.get(
|
||||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'user_external_id': 'user:1'},
|
||||
)
|
||||
assert len(resp.pyquery('tr td.status')) == 28
|
||||
assert len(resp.pyquery('tr td.status')) == 29
|
||||
resp = app.get(
|
||||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'user_external_id': 'user:2'},
|
||||
|
@ -2979,27 +2989,27 @@ def test_journal_pool_lines(app, admin_user, draft):
|
|||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'user_first_name': 'first'},
|
||||
)
|
||||
assert len(resp.pyquery('tr td.status')) == 29
|
||||
assert len(resp.pyquery('tr td.status')) == 30
|
||||
resp = app.get(
|
||||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'user_first_name': 'first1'},
|
||||
)
|
||||
assert len(resp.pyquery('tr td.status')) == 28
|
||||
assert len(resp.pyquery('tr td.status')) == 29
|
||||
resp = app.get(
|
||||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'user_last_name': 'last'},
|
||||
)
|
||||
assert len(resp.pyquery('tr td.status')) == 29
|
||||
assert len(resp.pyquery('tr td.status')) == 30
|
||||
resp = app.get(
|
||||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'user_last_name': 'last1'},
|
||||
)
|
||||
assert len(resp.pyquery('tr td.status')) == 28
|
||||
assert len(resp.pyquery('tr td.status')) == 29
|
||||
resp = app.get(
|
||||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'agenda': 'agenda-a'},
|
||||
)
|
||||
assert len(resp.pyquery('tr td.status')) == 27
|
||||
assert len(resp.pyquery('tr td.status')) == 28
|
||||
resp = app.get(
|
||||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'agenda': 'agenda-b'},
|
||||
|
@ -3014,7 +3024,7 @@ def test_journal_pool_lines(app, admin_user, draft):
|
|||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'event': 'agenda-a@event-aa'},
|
||||
)
|
||||
assert len(resp.pyquery('tr td.status')) == 26
|
||||
assert len(resp.pyquery('tr td.status')) == 27
|
||||
resp = app.get(
|
||||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'event': 'agenda-b@event-b'},
|
||||
|
@ -3039,12 +3049,12 @@ def test_journal_pool_lines(app, admin_user, draft):
|
|||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'status': 'error'},
|
||||
)
|
||||
assert len(resp.pyquery('tr td.status')) == 26
|
||||
assert len(resp.pyquery('tr td.status')) == 27
|
||||
resp = app.get(
|
||||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'status': 'error_todo'},
|
||||
)
|
||||
assert len(resp.pyquery('tr td.status')) == 24
|
||||
assert len(resp.pyquery('tr td.status')) == 25
|
||||
resp = app.get(
|
||||
'/manage/invoicing/regie/%s/campaign/%s/pool/%s/journal/' % (regie.pk, campaign.pk, pool.pk),
|
||||
params={'status': 'error_ignored'},
|
||||
|
|
|
@ -437,10 +437,10 @@ def test_get_invoice_lines_for_user_check_status(
|
|||
|
||||
# correct data
|
||||
mock_pricing_data_event.side_effect = [
|
||||
{'foo1': 'bar1', 'pricing': 1},
|
||||
{'foo2': 'bar2', 'pricing': 2},
|
||||
{'foo3': 'bar3', 'pricing': 3},
|
||||
{'foo4': 'bar4', 'pricing': 4},
|
||||
{'foo1': 'bar1', 'pricing': 1, 'accounting_code': '414141'},
|
||||
{'foo2': 'bar2', 'pricing': 2, 'accounting_code': '424242'},
|
||||
{'foo3': 'bar3', 'pricing': 3, 'accounting_code': '434343'},
|
||||
{'foo4': 'bar4', 'pricing': 4, 'accounting_code': '444444'},
|
||||
]
|
||||
mock_payer.return_value = 'payer:1'
|
||||
mock_status.return_value = [
|
||||
|
@ -591,7 +591,8 @@ def test_get_invoice_lines_for_user_check_status(
|
|||
'label': 'Event 1',
|
||||
}
|
||||
assert line1.booking == {'foo': 'baz1'}
|
||||
assert line1.pricing_data == {'foo1': 'bar1', 'pricing': 1}
|
||||
assert line1.pricing_data == {'foo1': 'bar1', 'pricing': 1, 'accounting_code': '414141'}
|
||||
assert line1.accounting_code == '414141'
|
||||
assert line1.status == 'success'
|
||||
assert line1.pool == pool
|
||||
assert line1.from_injected_line is None
|
||||
|
@ -617,7 +618,8 @@ def test_get_invoice_lines_for_user_check_status(
|
|||
'label': 'Event 2',
|
||||
}
|
||||
assert line2.booking == {'foo': 'baz2'}
|
||||
assert line2.pricing_data == {'foo2': 'bar2', 'pricing': 2}
|
||||
assert line2.pricing_data == {'foo2': 'bar2', 'pricing': 2, 'accounting_code': '424242'}
|
||||
assert line2.accounting_code == '424242'
|
||||
assert line2.status == 'success'
|
||||
assert line2.pool == pool
|
||||
assert line2.from_injected_line is None
|
||||
|
@ -643,7 +645,8 @@ def test_get_invoice_lines_for_user_check_status(
|
|||
'label': 'Eveeent 1',
|
||||
}
|
||||
assert line3.booking == {'foo': 'bazzz1'}
|
||||
assert line3.pricing_data == {'foo3': 'bar3', 'pricing': 3}
|
||||
assert line3.pricing_data == {'foo3': 'bar3', 'pricing': 3, 'accounting_code': '434343'}
|
||||
assert line3.accounting_code == '434343'
|
||||
assert line3.status == 'success'
|
||||
assert line3.pool == pool
|
||||
assert line3.from_injected_line is None
|
||||
|
@ -669,7 +672,8 @@ def test_get_invoice_lines_for_user_check_status(
|
|||
'label': 'Eveeent 2',
|
||||
}
|
||||
assert line4.booking == {'foo': 'bazzz2'}
|
||||
assert line4.pricing_data == {'foo4': 'bar4', 'pricing': 4}
|
||||
assert line4.pricing_data == {'foo4': 'bar4', 'pricing': 4, 'accounting_code': '444444'}
|
||||
assert line4.accounting_code == '444444'
|
||||
assert line4.status == 'success'
|
||||
assert line4.pool == pool
|
||||
assert line4.from_injected_line is None
|
||||
|
@ -693,6 +697,7 @@ def test_get_invoice_lines_for_user_check_status(
|
|||
assert line5.event == {}
|
||||
assert line5.booking == {}
|
||||
assert line5.pricing_data == {}
|
||||
assert line5.accounting_code == ''
|
||||
assert line5.status == 'success'
|
||||
assert line5.pool == pool
|
||||
assert line5.from_injected_line == injected_line1
|
||||
|
@ -714,6 +719,7 @@ def test_get_invoice_lines_for_user_check_status(
|
|||
assert line6.event == {}
|
||||
assert line6.booking == {}
|
||||
assert line6.pricing_data == {}
|
||||
assert line6.accounting_code == ''
|
||||
assert line6.status == 'success'
|
||||
assert line6.pool == pool
|
||||
assert line6.from_injected_line == injected_line2
|
||||
|
@ -735,6 +741,7 @@ def test_get_invoice_lines_for_user_check_status(
|
|||
assert line7.event == {}
|
||||
assert line7.booking == {}
|
||||
assert line7.pricing_data == {}
|
||||
assert line7.accounting_code == ''
|
||||
assert line7.status == 'success'
|
||||
assert line7.pool == pool
|
||||
assert line7.from_injected_line == injected_line4
|
||||
|
@ -768,9 +775,9 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings(
|
|||
)
|
||||
|
||||
mock_pricing_data_event.side_effect = [
|
||||
{'foo1': 'bar1', 'pricing': 1},
|
||||
{'foo2': 'bar2', 'pricing': 2},
|
||||
{'foo3': 'bar3', 'pricing': 3},
|
||||
{'foo1': 'bar1', 'pricing': 1, 'accounting_code': '414141'},
|
||||
{'foo2': 'bar2', 'pricing': 2, 'accounting_code': '424242'},
|
||||
{'foo3': 'bar3', 'pricing': 3, 'accounting_code': '434343'},
|
||||
]
|
||||
mock_payer.return_value = 'payer:1'
|
||||
mock_status.return_value = [
|
||||
|
@ -888,7 +895,8 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings(
|
|||
'label': 'Event 1',
|
||||
}
|
||||
assert line1.booking == {'foo': 'baz1'}
|
||||
assert line1.pricing_data == {'foo1': 'bar1', 'pricing': 1}
|
||||
assert line1.pricing_data == {'foo1': 'bar1', 'pricing': 1, 'accounting_code': '414141'}
|
||||
assert line1.accounting_code == '414141'
|
||||
assert line1.status == 'success'
|
||||
assert line1.pool == pool
|
||||
assert line1.from_injected_line is None
|
||||
|
@ -915,7 +923,8 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings(
|
|||
'label': 'Event 2',
|
||||
}
|
||||
assert line2.booking == {'foo': 'baz2', 'computed_duration': 45}
|
||||
assert line2.pricing_data == {'foo2': 'bar2', 'pricing': 2}
|
||||
assert line2.pricing_data == {'foo2': 'bar2', 'pricing': 2, 'accounting_code': '424242'}
|
||||
assert line2.accounting_code == '424242'
|
||||
assert line2.status == 'success'
|
||||
assert line2.pool == pool
|
||||
assert line2.from_injected_line is None
|
||||
|
@ -942,7 +951,8 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings(
|
|||
'label': 'Event 2',
|
||||
}
|
||||
assert line3.booking == {'foo': 'baz3', 'computed_duration': 70}
|
||||
assert line3.pricing_data == {'foo3': 'bar3', 'pricing': 3}
|
||||
assert line3.pricing_data == {'foo3': 'bar3', 'pricing': 3, 'accounting_code': '434343'}
|
||||
assert line3.accounting_code == '434343'
|
||||
assert line3.status == 'success'
|
||||
assert line3.pool == pool
|
||||
assert line3.from_injected_line is None
|
||||
|
@ -977,7 +987,12 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings_without_bookin
|
|||
|
||||
# presence but no booking, and no check_type
|
||||
mock_pricing_data_event.side_effect = [
|
||||
{'foo1': 'bar1', 'pricing': 1, 'booking_details': {'status': 'presence'}},
|
||||
{
|
||||
'foo1': 'bar1',
|
||||
'pricing': 1,
|
||||
'booking_details': {'status': 'presence'},
|
||||
'accounting_code': '414141',
|
||||
},
|
||||
]
|
||||
mock_payer.return_value = 'payer:1'
|
||||
mock_status.return_value = [
|
||||
|
@ -1036,7 +1051,13 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings_without_bookin
|
|||
assert line1.quantity == 120
|
||||
assert line1.quantity_type == 'minutes'
|
||||
assert line1.booking == {'foo': 'baz1', 'computed_duration': 120}
|
||||
assert line1.pricing_data == {'foo1': 'bar1', 'pricing': 1, 'booking_details': {'status': 'presence'}}
|
||||
assert line1.pricing_data == {
|
||||
'foo1': 'bar1',
|
||||
'pricing': 1,
|
||||
'booking_details': {'status': 'presence'},
|
||||
'accounting_code': '414141',
|
||||
}
|
||||
assert line1.accounting_code == '414141'
|
||||
assert line1.status == 'success'
|
||||
|
||||
# presence but no booking, and check_type
|
||||
|
@ -1047,11 +1068,13 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings_without_bookin
|
|||
'foo1': 'bar1',
|
||||
'pricing': 2,
|
||||
'booking_details': {'status': 'presence', 'check_type': 'foo', 'check_type_group': 'foobar'},
|
||||
'accounting_code': '414141',
|
||||
},
|
||||
{
|
||||
'foo1': 'bar1',
|
||||
'pricing': 1,
|
||||
'booking_details': {'status': 'presence'},
|
||||
'accounting_code': '414141',
|
||||
}, # second call to get normal pricing
|
||||
]
|
||||
mock_pricing_data_event.reset_mock()
|
||||
|
@ -1116,7 +1139,9 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings_without_bookin
|
|||
'foo1': 'bar1',
|
||||
'pricing': 2,
|
||||
'booking_details': {'status': 'presence', 'check_type': 'foo', 'check_type_group': 'foobar'},
|
||||
'accounting_code': '414141',
|
||||
}
|
||||
assert line1.accounting_code == '414141'
|
||||
assert line1.status == 'success'
|
||||
|
||||
|
||||
|
@ -1149,7 +1174,12 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings_with_booking(
|
|||
|
||||
# presence, and no check_type, no overtaking
|
||||
mock_pricing_data_event.side_effect = [
|
||||
{'foo1': 'bar1', 'pricing': 1, 'booking_details': {'status': 'presence'}},
|
||||
{
|
||||
'foo1': 'bar1',
|
||||
'pricing': 1,
|
||||
'booking_details': {'status': 'presence'},
|
||||
'accounting_code': '414141',
|
||||
},
|
||||
]
|
||||
mock_payer.return_value = 'payer:1'
|
||||
mock_status.return_value = [
|
||||
|
@ -1207,12 +1237,23 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings_with_booking(
|
|||
assert line1.quantity == 120
|
||||
assert line1.quantity_type == 'minutes'
|
||||
assert line1.booking == {'foo': 'baz1', 'computed_duration': 120, 'adjusted_duration': 120}
|
||||
assert line1.pricing_data == {'foo1': 'bar1', 'pricing': 1, 'booking_details': {'status': 'presence'}}
|
||||
assert line1.pricing_data == {
|
||||
'foo1': 'bar1',
|
||||
'pricing': 1,
|
||||
'booking_details': {'status': 'presence'},
|
||||
'accounting_code': '414141',
|
||||
}
|
||||
assert line1.accounting_code == '414141'
|
||||
assert line1.status == 'success'
|
||||
|
||||
# presence, and no check_type, with overtaking
|
||||
mock_pricing_data_event.side_effect = [
|
||||
{'foo1': 'bar1', 'pricing': 1, 'booking_details': {'status': 'presence'}},
|
||||
{
|
||||
'foo1': 'bar1',
|
||||
'pricing': 1,
|
||||
'booking_details': {'status': 'presence'},
|
||||
'accounting_code': '414141',
|
||||
},
|
||||
]
|
||||
mock_pricing_data_event.reset_mock()
|
||||
mock_status.return_value = [
|
||||
|
@ -1273,7 +1314,13 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings_with_booking(
|
|||
assert line1.quantity_type == 'minutes'
|
||||
assert line1.event['primary_event'] == 'event-1'
|
||||
assert line1.booking == {'foo': 'baz1', 'computed_duration': 120, 'adjusted_duration': 90}
|
||||
assert line1.pricing_data == {'foo1': 'bar1', 'pricing': 1, 'booking_details': {'status': 'presence'}}
|
||||
assert line1.pricing_data == {
|
||||
'foo1': 'bar1',
|
||||
'pricing': 1,
|
||||
'booking_details': {'status': 'presence'},
|
||||
'accounting_code': '414141',
|
||||
}
|
||||
assert line1.accounting_code == '414141'
|
||||
assert line1.status == 'success'
|
||||
assert line2.event_date == datetime.date(2022, 9, 1)
|
||||
assert line2.slug == 'agenda@event-1'
|
||||
|
@ -1284,16 +1331,28 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings_with_booking(
|
|||
assert line2.quantity_type == 'minutes'
|
||||
assert line2.event['primary_event'] == 'event-1::overtaking'
|
||||
assert line2.booking == {'foo': 'baz1', 'computed_duration': 120, 'adjusted_duration': 90}
|
||||
assert line2.pricing_data == {'foo1': 'bar1', 'pricing': 1, 'booking_details': {'status': 'presence'}}
|
||||
assert line2.pricing_data == {
|
||||
'foo1': 'bar1',
|
||||
'pricing': 1,
|
||||
'booking_details': {'status': 'presence'},
|
||||
'accounting_code': '414141',
|
||||
}
|
||||
assert line2.accounting_code == '414141'
|
||||
assert line2.status == 'success'
|
||||
|
||||
# absence, and no check_type
|
||||
mock_pricing_data_event.side_effect = [
|
||||
{'foo1': 'bar1', 'pricing': 0, 'booking_details': {'status': 'absence'}},
|
||||
{
|
||||
'foo1': 'bar1',
|
||||
'pricing': 0,
|
||||
'booking_details': {'status': 'absence'},
|
||||
'accounting_code': '414141',
|
||||
},
|
||||
{
|
||||
'foo1': 'bar1',
|
||||
'pricing': 1,
|
||||
'booking_details': {'status': 'presence'},
|
||||
'accounting_code': '414141',
|
||||
}, # second call to get normal pricing
|
||||
]
|
||||
mock_pricing_data_event.reset_mock()
|
||||
|
@ -1370,7 +1429,13 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings_with_booking(
|
|||
assert line1.quantity_type == 'minutes'
|
||||
assert line1.event['primary_event'] == 'event-1'
|
||||
assert line1.booking == {'foo': 'baz1', 'computed_duration': 120, 'adjusted_duration': 120}
|
||||
assert line1.pricing_data == {'foo1': 'bar1', 'pricing': 1, 'booking_details': {'status': 'presence'}}
|
||||
assert line1.pricing_data == {
|
||||
'foo1': 'bar1',
|
||||
'pricing': 1,
|
||||
'booking_details': {'status': 'presence'},
|
||||
'accounting_code': '414141',
|
||||
}
|
||||
assert line1.accounting_code == '414141'
|
||||
assert line1.status == 'success'
|
||||
assert line2.event_date == datetime.date(2022, 9, 1)
|
||||
assert line2.slug == 'agenda@event-1'
|
||||
|
@ -1381,7 +1446,13 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings_with_booking(
|
|||
assert line2.quantity_type == 'minutes'
|
||||
assert line2.event['primary_event'] == 'event-1:absence:'
|
||||
assert line2.booking == {'foo': 'baz1', 'computed_duration': 120, 'adjusted_duration': 120}
|
||||
assert line2.pricing_data == {'foo1': 'bar1', 'pricing': 0, 'booking_details': {'status': 'absence'}}
|
||||
assert line2.pricing_data == {
|
||||
'foo1': 'bar1',
|
||||
'pricing': 0,
|
||||
'booking_details': {'status': 'absence'},
|
||||
'accounting_code': '414141',
|
||||
}
|
||||
assert line2.accounting_code == '414141'
|
||||
assert line2.status == 'success'
|
||||
|
||||
# presence, and check_type, with overtaking
|
||||
|
@ -1392,11 +1463,13 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings_with_booking(
|
|||
'foo1': 'bar1',
|
||||
'pricing': 1.5,
|
||||
'booking_details': {'status': 'presence', 'check_type': 'foo', 'check_type_group': 'foobar'},
|
||||
'accounting_code': '414141',
|
||||
},
|
||||
{
|
||||
'foo1': 'bar1',
|
||||
'pricing': 1,
|
||||
'booking_details': {'status': 'presence'},
|
||||
'accounting_code': '414141',
|
||||
}, # second call to get normal pricing
|
||||
]
|
||||
mock_pricing_data_event.reset_mock()
|
||||
|
@ -1473,7 +1546,13 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings_with_booking(
|
|||
assert line1.quantity_type == 'minutes'
|
||||
assert line1.event['primary_event'] == 'event-1'
|
||||
assert line1.booking == {'foo': 'baz1', 'computed_duration': 120, 'adjusted_duration': 90}
|
||||
assert line1.pricing_data == {'foo1': 'bar1', 'pricing': 1, 'booking_details': {'status': 'presence'}}
|
||||
assert line1.pricing_data == {
|
||||
'foo1': 'bar1',
|
||||
'pricing': 1,
|
||||
'booking_details': {'status': 'presence'},
|
||||
'accounting_code': '414141',
|
||||
}
|
||||
assert line1.accounting_code == '414141'
|
||||
assert line1.status == 'success'
|
||||
assert line2.event_date == datetime.date(2022, 9, 1)
|
||||
assert line2.slug == 'agenda@event-1'
|
||||
|
@ -1484,7 +1563,13 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings_with_booking(
|
|||
assert line2.quantity_type == 'minutes'
|
||||
assert line2.event['primary_event'] == 'event-1::overtaking'
|
||||
assert line2.booking == {'foo': 'baz1', 'computed_duration': 120, 'adjusted_duration': 90}
|
||||
assert line2.pricing_data == {'foo1': 'bar1', 'pricing': 1, 'booking_details': {'status': 'presence'}}
|
||||
assert line2.pricing_data == {
|
||||
'foo1': 'bar1',
|
||||
'pricing': 1,
|
||||
'booking_details': {'status': 'presence'},
|
||||
'accounting_code': '414141',
|
||||
}
|
||||
assert line2.accounting_code == '414141'
|
||||
assert line2.status == 'success'
|
||||
assert line3.event_date == datetime.date(2022, 9, 1)
|
||||
assert line3.slug == 'agenda@event-1'
|
||||
|
@ -1499,7 +1584,9 @@ def test_get_invoice_lines_for_user_check_status_partial_bookings_with_booking(
|
|||
'foo1': 'bar1',
|
||||
'pricing': 1.5,
|
||||
'booking_details': {'status': 'presence', 'check_type': 'foo', 'check_type_group': 'foobar'},
|
||||
'accounting_code': '414141',
|
||||
}
|
||||
assert line3.accounting_code == '414141'
|
||||
assert line3.status == 'success'
|
||||
|
||||
|
||||
|
@ -1731,6 +1818,7 @@ def test_get_invoice_lines_for_user_get_payer_id_error(mock_payer, mock_status):
|
|||
}
|
||||
assert line.booking == {'foo': 'baz'}
|
||||
assert line.pricing_data == {'error': 'PayerError', 'error_details': {'foo': 'bar'}}
|
||||
assert line.accounting_code == ''
|
||||
assert line.status == 'error'
|
||||
assert line.pool == pool
|
||||
assert line.from_injected_line is None
|
||||
|
@ -2332,6 +2420,7 @@ def test_get_invoice_lines_for_user_check_status_pricing_error(
|
|||
}
|
||||
assert line1.booking == {'foo': 'baz'}
|
||||
assert line1.pricing_data == {'foo1': 'bar1', 'pricing': '1'}
|
||||
assert line1.accounting_code == ''
|
||||
assert line1.status == 'success'
|
||||
assert line1.pool == pool
|
||||
assert line2.event_date == datetime.date(2022, 9, 2)
|
||||
|
@ -2355,6 +2444,7 @@ def test_get_invoice_lines_for_user_check_status_pricing_error(
|
|||
}
|
||||
assert line2.booking == {'foo': 'baz'}
|
||||
assert line2.pricing_data == {'error': 'PricingError', 'error_details': {'foo': 'bar'}}
|
||||
assert line2.accounting_code == ''
|
||||
assert line2.status == 'error'
|
||||
assert line2.pool == pool
|
||||
assert line3.event_date == datetime.date(2022, 9, 3)
|
||||
|
@ -2378,6 +2468,7 @@ def test_get_invoice_lines_for_user_check_status_pricing_error(
|
|||
}
|
||||
assert line3.booking == {'foo': 'baz'}
|
||||
assert line3.pricing_data == {'foo3': 'bar3', 'pricing': '3'}
|
||||
assert line3.accounting_code == ''
|
||||
assert line3.status == 'success'
|
||||
assert line3.pool == pool
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ from lingo.pricing.models import (
|
|||
CriteriaConditionNotFound,
|
||||
MultipleDefaultCriteriaCondition,
|
||||
Pricing,
|
||||
PricingAccountingCodeError,
|
||||
PricingBookingCheckTypeError,
|
||||
PricingBookingNotCheckedError,
|
||||
PricingCriteriaCategory,
|
||||
|
@ -58,8 +59,14 @@ class MockedRequestResponse(mock.Mock):
|
|||
|
||||
def mocked_requests_send(request, **kwargs):
|
||||
data = [
|
||||
{'id': 1, 'fields': {'foo': 'bar', 'bar': False, 'rate': 42, 'target': 2000}},
|
||||
{'id': 2, 'fields': {'foo': 'baz', 'bar': True, 'rate': 35, 'target': 3000}},
|
||||
{
|
||||
'id': 1,
|
||||
'fields': {'foo': 'bar', 'bar': False, 'rate': 42, 'target': 2000, 'accounting_code': '424242'},
|
||||
},
|
||||
{
|
||||
'id': 2,
|
||||
'fields': {'foo': 'baz', 'bar': True, 'rate': 35, 'target': 3000, 'accounting_code': '353535'},
|
||||
},
|
||||
] # fake result
|
||||
return MockedRequestResponse(content=json.dumps({'data': data}))
|
||||
|
||||
|
@ -1101,6 +1108,82 @@ def test_apply_effort_rate_target(context):
|
|||
)
|
||||
|
||||
|
||||
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
||||
def test_compute_accounting_code(mock_send, context, nocache):
|
||||
pricing = Pricing.objects.create(
|
||||
date_start=datetime.date(year=2021, month=9, day=1),
|
||||
date_end=datetime.date(year=2021, month=10, day=1),
|
||||
)
|
||||
|
||||
# empty template
|
||||
assert pricing.accounting_code == ''
|
||||
assert (
|
||||
pricing.compute_accounting_code(
|
||||
request=context['request'],
|
||||
original_context={},
|
||||
user_external_id='child:42',
|
||||
payer_external_id='parent:35',
|
||||
)
|
||||
== ''
|
||||
)
|
||||
|
||||
for value in ['{% for %}', '{{ "foo"|add:user.email }}']:
|
||||
pricing.accounting_code = value
|
||||
pricing.save()
|
||||
with pytest.raises(PricingAccountingCodeError):
|
||||
pricing.compute_accounting_code(
|
||||
request=context['request'],
|
||||
original_context={},
|
||||
user_external_id='child:42',
|
||||
payer_external_id='parent:35',
|
||||
)
|
||||
|
||||
for value in [
|
||||
'424242',
|
||||
'{{ foo }}',
|
||||
'{{ cards|objects:"foo"|first|get:"fields"|get:"accounting_code" }}',
|
||||
]:
|
||||
pricing.accounting_code = value
|
||||
pricing.save()
|
||||
assert (
|
||||
pricing.compute_accounting_code(
|
||||
request=context['request'],
|
||||
original_context={'foo': '424242'},
|
||||
user_external_id='child:42',
|
||||
payer_external_id='parent:35',
|
||||
)
|
||||
== '424242'
|
||||
)
|
||||
|
||||
# user_external_id and payer_external_id can be used
|
||||
pricing.accounting_code = {
|
||||
'qf': '{{ cards|objects:"qf"|filter_by:"foo"|filter_value:user_external_id|filter_by:"bar"|filter_value:payer_external_id|list }}',
|
||||
}
|
||||
pricing.save()
|
||||
mock_send.reset_mock()
|
||||
pricing.compute_accounting_code(
|
||||
request=context['request'],
|
||||
original_context={},
|
||||
user_external_id='child:42',
|
||||
payer_external_id='parent:35',
|
||||
)
|
||||
assert 'filter-foo=child%3A42&' in mock_send.call_args_list[0][0][0].url
|
||||
assert 'filter-bar=parent%3A35&' in mock_send.call_args_list[0][0][0].url
|
||||
pricing.accounting_code = {
|
||||
'qf': '{{ cards|objects:"qf"|filter_by:"foo"|filter_value:user_external_raw_id|filter_by:"bar"|filter_value:payer_external_raw_id|list }}',
|
||||
}
|
||||
pricing.save()
|
||||
mock_send.reset_mock()
|
||||
pricing.compute_accounting_code(
|
||||
request=context['request'],
|
||||
original_context={},
|
||||
user_external_id='child:42',
|
||||
payer_external_id='parent:35',
|
||||
)
|
||||
assert 'filter-foo=42&' in mock_send.call_args_list[0][0][0].url
|
||||
assert 'filter-bar=35&' in mock_send.call_args_list[0][0][0].url
|
||||
|
||||
|
||||
def test_format_pricing_data():
|
||||
agenda = Agenda.objects.create(label='Foo bar')
|
||||
pricing = Pricing.objects.create(
|
||||
|
@ -1435,6 +1518,7 @@ def test_get_pricing_data(context):
|
|||
pricing_data={
|
||||
'foo:bar': 42,
|
||||
},
|
||||
accounting_code='{{ 424240|add:2 }}',
|
||||
)
|
||||
pricing.criterias.add(criteria)
|
||||
pricing.categories.add(category, through_defaults={'order': 1})
|
||||
|
@ -1453,6 +1537,7 @@ def test_get_pricing_data(context):
|
|||
'effort_rate': {},
|
||||
'context': {'domicile': 'commune', 'qf': '2'},
|
||||
},
|
||||
'accounting_code': '424242',
|
||||
}
|
||||
|
||||
|
||||
|
@ -1470,6 +1555,7 @@ def test_get_pricing_data_for_event(context):
|
|||
pricing_data={
|
||||
'foo:bar': 42,
|
||||
},
|
||||
accounting_code='424242',
|
||||
)
|
||||
pricing.criterias.add(criteria)
|
||||
pricing.categories.add(category, through_defaults={'order': 1})
|
||||
|
@ -1495,6 +1581,7 @@ def test_get_pricing_data_for_event(context):
|
|||
'modifier_type': 'rate',
|
||||
'modifier_rate': 0,
|
||||
},
|
||||
'accounting_code': '424242',
|
||||
}
|
||||
|
||||
|
||||
|
@ -1638,6 +1725,7 @@ def test_aggregate_pricing_data(modifier, pricing_amount):
|
|||
effort_rate={'foo': 'bazz'},
|
||||
context={'domicile': 'commune', 'qf': 2},
|
||||
modifier=modifier,
|
||||
accounting_code='424242',
|
||||
) == {
|
||||
'pricing': pricing_amount,
|
||||
'calculation_details': {
|
||||
|
@ -1648,6 +1736,7 @@ def test_aggregate_pricing_data(modifier, pricing_amount):
|
|||
'context': {'domicile': 'commune', 'qf': 2},
|
||||
},
|
||||
'booking_details': modifier,
|
||||
'accounting_code': '424242',
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue