0003-pricing-import-export-agenda-config-65361.patch
lingo/pricing/templates/lingo/pricing/manager_agenda_detail.html | ||
---|---|---|
11 | 11 |
<span class="identifier">[{% trans "identifier:" %} {{ agenda.slug }}]</span> |
12 | 12 |
</h2> |
13 | 13 |
<span class="actions"> |
14 |
<a href="{% url 'lingo-manager-agenda-export' pk=agenda.pk %}">{% trans 'Export' %}</a> |
|
14 | 15 |
<a rel="popup" href="{% url 'lingo-manager-agenda-pricing-add' pk=agenda.pk %}">{% trans 'New pricing' %}</a> |
15 | 16 |
</span> |
16 | 17 |
{% endblock %} |
lingo/pricing/urls.py | ||
---|---|---|
138 | 138 |
staff_member_required(views.agenda_detail), |
139 | 139 |
name='lingo-manager-agenda-detail', |
140 | 140 |
), |
141 |
url( |
|
142 |
r'^agenda/(?P<pk>\d+)/export/$', |
|
143 |
staff_member_required(views.agenda_export), |
|
144 |
name='lingo-manager-agenda-export', |
|
145 |
), |
|
141 | 146 |
url( |
142 | 147 |
r'^agenda/(?P<pk>\d+)/pricing/add/$', |
143 | 148 |
staff_member_required(views.agenda_pricing_add), |
lingo/pricing/views.py | ||
---|---|---|
142 | 142 |
global_noop = False |
143 | 143 |
count = len(obj_results['created']) |
144 | 144 |
if not count: |
145 |
message1 = import_messages[obj_name]['create_noop']
|
|
145 |
message1 = import_messages[obj_name].get('create_noop')
|
|
146 | 146 |
else: |
147 | 147 |
message1 = import_messages[obj_name]['create'](count) % {'count': count} |
148 | 148 | |
... | ... | |
154 | 154 | |
155 | 155 |
obj_results['messages'] = "%s %s" % (message1, message2) |
156 | 156 | |
157 |
pc_count, pm_count = ( |
|
157 |
a_count, pc_count, pm_count = ( |
|
158 |
len(results['agendas']['all']), |
|
158 | 159 |
len(results['pricing_categories']['all']), |
159 | 160 |
len(results['pricing_models']['all']), |
160 | 161 |
) |
161 |
if (pc_count, pm_count) == (1, 0): |
|
162 |
if (a_count, pc_count, pm_count) == (1, 0, 0): |
|
163 |
# only one agenda imported, redirect to agenda page |
|
164 |
return HttpResponseRedirect( |
|
165 |
reverse( |
|
166 |
'lingo-manager-agenda-detail', |
|
167 |
kwargs={'pk': results['agendas']['all'][0].pk}, |
|
168 |
) |
|
169 |
) |
|
170 |
if (a_count, pc_count, pm_count) == (0, 1, 0): |
|
162 | 171 |
# only one criteria category imported, redirect to criteria page |
163 | 172 |
return HttpResponseRedirect(reverse('lingo-manager-pricing-criteria-list')) |
164 |
if (pc_count, pm_count) == (0, 1):
|
|
173 |
if (a_count, pc_count, pm_count) == (0, 0, 1):
|
|
165 | 174 |
# only one pricing imported, redirect to pricing page |
166 | 175 |
return HttpResponseRedirect( |
167 | 176 |
reverse( |
... | ... | |
619 | 628 |
agenda_detail = AgendaDetailView.as_view() |
620 | 629 | |
621 | 630 | |
631 |
class AgendaExport(AgendaMixin, DetailView): |
|
632 |
model = Agenda |
|
633 | ||
634 |
def get(self, request, *args, **kwargs): |
|
635 |
response = HttpResponse(content_type='application/json') |
|
636 |
today = datetime.date.today() |
|
637 |
response['Content-Disposition'] = 'attachment; filename="export_pricing_agenda_{}_{}.json"'.format( |
|
638 |
self.get_object().slug, today.strftime('%Y%m%d') |
|
639 |
) |
|
640 |
json.dump({'agendas': [self.get_object().export_json()]}, response, indent=2) |
|
641 |
return response |
|
642 | ||
643 | ||
644 |
agenda_export = AgendaExport.as_view() |
|
645 | ||
646 | ||
622 | 647 |
class AgendaPricingAddView(AgendaMixin, CreateView): |
623 | 648 |
template_name = 'lingo/pricing/manager_agenda_pricing_form.html' |
624 | 649 |
model = AgendaPricing |
tests/pricing/test_manager.py | ||
---|---|---|
697 | 697 |
assert mock_refresh.call_args_list == [mock.call()] |
698 | 698 | |
699 | 699 | |
700 |
@pytest.mark.freeze_time('2021-07-08') |
|
701 |
def test_import_agenda(app, admin_user): |
|
702 |
agenda = Agenda.objects.create(label='Foo Bar') |
|
703 | ||
704 |
app = login(app) |
|
705 |
resp = app.get('/manage/pricing/agenda/%s/' % agenda.pk) |
|
706 |
resp = resp.click('Export') |
|
707 |
assert resp.headers['content-type'] == 'application/json' |
|
708 |
assert ( |
|
709 |
resp.headers['content-disposition'] |
|
710 |
== 'attachment; filename="export_pricing_agenda_foo-bar_20210708.json"' |
|
711 |
) |
|
712 |
agenda_export = resp.text |
|
713 | ||
714 |
# existing agenda |
|
715 |
resp = app.get('/manage/pricing/', status=200) |
|
716 |
resp = resp.click('Import') |
|
717 |
resp.form['config_json'] = Upload('export.json', agenda_export.encode('utf-8'), 'application/json') |
|
718 |
resp = resp.form.submit() |
|
719 |
assert resp.location.endswith('/manage/pricing/agenda/%s/' % agenda.pk) |
|
720 |
resp = resp.follow() |
|
721 |
assert 'An agenda has been updated.' not in resp.text |
|
722 |
assert Agenda.objects.count() == 1 |
|
723 | ||
724 |
# unknown agenda |
|
725 |
Agenda.objects.all().delete() |
|
726 |
resp = app.get('/manage/pricing/', status=200) |
|
727 |
resp = resp.click('Import') |
|
728 |
resp.form['config_json'] = Upload('export.json', agenda_export.encode('utf-8'), 'application/json') |
|
729 |
resp = resp.form.submit() |
|
730 |
assert resp.context['form'].errors['config_json'] == ['Missing "foo-bar" agenda'] |
|
731 | ||
732 |
# multiple pricing |
|
733 |
Agenda.objects.create(label='Foo Bar') |
|
734 |
Agenda.objects.create(label='Foo Bar 2') |
|
735 |
agendas = json.loads(agenda_export) |
|
736 |
agendas['agendas'].append(copy.copy(agendas['agendas'][0])) |
|
737 |
agendas['agendas'][1]['slug'] = 'foo-bar-2' |
|
738 | ||
739 |
resp = app.get('/manage/pricing/', status=200) |
|
740 |
resp = resp.click('Import') |
|
741 |
resp.form['config_json'] = Upload('export.json', json.dumps(agendas).encode('utf-8'), 'application/json') |
|
742 |
resp = resp.form.submit() |
|
743 |
assert resp.location.endswith('/manage/pricing/') |
|
744 |
resp = resp.follow() |
|
745 |
assert '2 agendas have been updated.' in resp.text |
|
746 |
assert Agenda.objects.count() == 2 |
|
747 | ||
748 | ||
700 | 749 |
def test_add_agenda_pricing(app, admin_user): |
701 | 750 |
agenda = Agenda.objects.create(label='Foo Bar') |
702 | 751 |
pricing = Pricing.objects.create(label='Model') |
703 |
- |