Projet

Général

Profil

0001-invoicing-link-between-Regie-and-Agenda-71074.patch

Lauréline Guérin, 21 novembre 2022 16:38

Télécharger (12,3 ko)

Voir les différences:

Subject: [PATCH] invoicing: link between Regie and Agenda (#71074)

 lingo/agendas/migrations/0004_regie.py        | 24 +++++++++
 lingo/agendas/models.py                       |  7 +++
 .../lingo/invoicing/manager_regie_detail.html | 51 +++++++++++++++----
 lingo/invoicing/views.py                      |  7 +--
 .../lingo/pricing/manager_agenda_detail.html  | 10 ++++
 lingo/pricing/urls.py                         |  5 ++
 lingo/pricing/views.py                        | 16 ++++++
 tests/invoicing/test_manager.py               | 23 ++++++---
 tests/pricing/manager/test_agenda.py          | 15 ++++++
 9 files changed, 140 insertions(+), 18 deletions(-)
 create mode 100644 lingo/agendas/migrations/0004_regie.py
lingo/agendas/migrations/0004_regie.py
1
import django.db.models.deletion
2
from django.db import migrations, models
3

  
4

  
5
class Migration(migrations.Migration):
6

  
7
    dependencies = [
8
        ('invoicing', '0001_initial'),
9
        ('agendas', '0003_check_type_group'),
10
    ]
11

  
12
    operations = [
13
        migrations.AddField(
14
            model_name='agenda',
15
            name='regie',
16
            field=models.ForeignKey(
17
                blank=True,
18
                null=True,
19
                on_delete=django.db.models.deletion.SET_NULL,
20
                to='invoicing.Regie',
21
                verbose_name='Regie',
22
            ),
23
        ),
24
    ]
lingo/agendas/models.py
36 36
        null=True,
37 37
        on_delete=models.SET_NULL,
38 38
    )
39
    regie = models.ForeignKey(
40
        'invoicing.Regie',
41
        verbose_name=_('Regie'),
42
        blank=True,
43
        null=True,
44
        on_delete=models.SET_NULL,
45
    )
39 46

  
40 47
    def __str__(self):
41 48
        return self.label
lingo/invoicing/templates/lingo/invoicing/manager_regie_detail.html
15 15
{% endblock %}
16 16

  
17 17
{% block content %}
18
  {% if regie.description %}
19
    <div class="bo-block">{{regie.description}}</div>
20
  {% endif %}
21
  <div class="bo-block">
22
    <h3>{% trans "Parameters" %}</h3>
23
    <ul>
24
      <li>{% trans "slug" %}&nbsp;: {{regie.slug}}</li>
25
      <li>{% trans "cashier role" %}&nbsp;: {{regie.cashier_role}}</li>
26
    </ul>
18
  <div class="section">
19
    <div class="pk-tabs">
20
      <div class="pk-tabs--tab-list" role="tablist">
21
        <button aria-controls="panel-settings" aria-selected="true" id="tab-settings" role="tab" tabindex="0">{% trans "Settings" %}</button>
22
        <button aria-controls="panel-usage" aria-selected="false" id="tab-usage" role="tab" tabindex="-1">{% trans "Used in agendas" %}</button>
23
      </div>
24
      <div class="pk-tabs--container">
25

  
26
        <div aria-labelledby="tab-settings" id="panel-settings" role="tabpanel" tabindex="0">
27
          {% if regie.description %}
28
            <h3>{% trans "Description" %}</h3>
29
            <p>{{ regie.description|linebreaksbr }}</p>
30
          {% endif %}
31
          <h3>{% trans "Parameters" %}</h3>
32
          <ul>
33
            <li>{% trans "Identifier:" %} {{ regie.slug }}</li>
34
            <li>{% trans "Cashier role:" %} {{ regie.cashier_role }}</li>
35
          </ul>
36
        </div>
37

  
38
        <div aria-labelledby="tab-usage" hidden="" id="panel-usage" role="tabpanel" tabindex="0">
39
          {% if agendas %}
40
            <ul class="objects-list single-links">
41
              {% for agenda in agendas %}
42
                <li>
43
                  <a href="{% url 'lingo-manager-agenda-detail' pk=agenda.pk %}">
44
                    {{ agenda.label }}
45
                  </a>
46
                </li>
47
              {% endfor %}
48
            </ul>
49
          {% else %}
50
            <div class="big-msg-info">
51
              {% blocktrans trimmed %}
52
                This Regie is not used yet.
53
              {% endblocktrans %}
54
            </div>
55
          {% endif %}
56
        </div>
57

  
58
      </div>
59
    </div>
27 60
  </div>
28 61
{% endblock %}
lingo/invoicing/views.py
34 34
    UpdateView,
35 35
)
36 36

  
37
from lingo.agendas.models import Agenda
37 38
from lingo.invoicing.models import Regie, RegieImportError
38 39
from lingo.pricing.forms import ImportForm
39 40

  
......
83 84
    model = Regie
84 85

  
85 86
    def get_context_data(self, **kwargs):
86
        context = super().get_context_data(**kwargs)
87
        context['regie'] = self.object
88
        return context
87
        kwargs['regie'] = self.object
88
        kwargs['agendas'] = Agenda.objects.filter(regie=self.object)
89
        return super().get_context_data(**kwargs)
89 90

  
90 91

  
91 92
regie_detail = RegieDetailView.as_view()
lingo/pricing/templates/lingo/pricing/manager_agenda_detail.html
22 22
      <div class="pk-tabs--tab-list" role="tablist">
23 23
        <button aria-controls="panel-pricings" aria-selected="true" id="tab-pricings" role="tab" tabindex="0">{% trans "Pricings" context 'agenda pricing' %}</button>
24 24
        <button aria-controls="panel-check" aria-selected="false" id="tab-check" role="tab" tabindex="-1">{% trans "Booking check options" %}</button>
25
        <button aria-controls="panel-invoicing" aria-selected="false" id="tab-invoicing" role="tab" tabindex="-1">{% trans "Invoicing options" %}</button>
25 26
      </div>
26 27
      <div class="pk-tabs--container">
27 28

  
......
96 97
          </div>
97 98
        </div>
98 99

  
100
        <div aria-labelledby="tab-invoicing" hidden="" id="panel-invoicing" role="tabpanel" tabindex="0">
101
          <ul>
102
            <li>{% trans "Regie:" %} {{ object.regie|default:"" }}</li>
103
          </ul>
104
          <div class="panel--buttons">
105
            <a rel="popup" class="button" href="{% url 'lingo-manager-agenda-invoicing-settings' pk=object.pk %}">{% trans 'Configure' %}</a>
106
          </div>
107
        </div>
108

  
99 109
      </div>
100 110
    </div>
101 111
  </div>
lingo/pricing/urls.py
153 153
        views.agenda_booking_check_settings,
154 154
        name='lingo-manager-agenda-booking-check-settings',
155 155
    ),
156
    path(
157
        'agenda/<int:pk>/invoicing-options/',
158
        views.agenda_invoicing_settings,
159
        name='lingo-manager-agenda-invoicing-settings',
160
    ),
156 161
    path(
157 162
        'agenda-pricings/',
158 163
        views.agenda_pricing_list,
lingo/pricing/views.py
747 747
agenda_booking_check_settings = AgendaBookingCheckSettingsView.as_view()
748 748

  
749 749

  
750
class AgendaInvoicingSettingsView(AgendaMixin, UpdateView):
751
    template_name = 'lingo/pricing/manager_agenda_form.html'
752
    model = Agenda
753
    fields = ['regie']
754
    tab_anchor = 'invoicing'
755

  
756
    def get_context_data(self, **kwargs):
757
        context = super().get_context_data(**kwargs)
758
        context['form_url'] = reverse('lingo-manager-agenda-invoicing-settings', args=[self.agenda.pk])
759
        context['title'] = _("Configure invoicing options")
760
        return context
761

  
762

  
763
agenda_invoicing_settings = AgendaInvoicingSettingsView.as_view()
764

  
765

  
750 766
class AgendaPricingListView(ListView):
751 767
    template_name = 'lingo/pricing/manager_agenda_pricing_list.html'
752 768
    model = AgendaPricing
tests/invoicing/test_manager.py
6 6
from django.urls import reverse
7 7
from webtest import Upload
8 8

  
9
from lingo.agendas.models import Agenda
9 10
from lingo.invoicing.models import Regie
10 11
from tests.utils import login
11 12

  
......
95 96
    resp = app.get(reverse('lingo-manager-invoicing-regie-detail', kwargs={'pk': regie.pk}))
96 97
    h2 = resp.pyquery('div#appbar h2')
97 98
    assert h2.text() == 'Regie - Foo'
98
    descr = resp.pyquery('div#content div.bo-block')[0]
99
    descr = resp.pyquery('div#panel-settings p')[0]
99 100
    assert descr.text == 'foo description'
100
    slug = resp.pyquery('div#content div.bo-block ul li')[0]
101
    assert slug.text == 'slug\xa0: foo'
102
    cashier_role = resp.pyquery('div#content div.bo-block ul li')[1]
103
    assert cashier_role.text == 'cashier role\xa0: role-foo'
101
    slug = resp.pyquery('div#panel-settings ul li')[0]
102
    assert slug.text == 'Identifier: foo'
103
    cashier_role = resp.pyquery('div#panel-settings ul li')[1]
104
    assert cashier_role.text == 'Cashier role: role-foo'
105
    usage = resp.pyquery('div#panel-usage div')[0]
106
    assert 'This Regie is not used yet.' in usage.text
104 107
    edit_button = resp.pyquery(
105 108
        'span.actions a[href="%s"]' % reverse('lingo-manager-invoicing-regie-edit', kwargs={'pk': regie.pk})
106 109
    )
......
110 113
    )
111 114
    assert delete_button.text() == 'Delete'
112 115

  
116
    agenda1 = Agenda.objects.create(label='Foo Bar', regie=regie)
117
    agenda2 = Agenda.objects.create(label='Foo Bar 2', regie=regie)
118
    agenda3 = Agenda.objects.create(label='Foo Bar 3')
119
    resp = app.get(reverse('lingo-manager-invoicing-regie-detail', kwargs={'pk': regie.pk}))
120
    assert '/manage/pricing/agenda/%s/' % agenda1.pk in resp
121
    assert '/manage/pricing/agenda/%s/' % agenda2.pk in resp
122
    assert '/manage/pricing/agenda/%s/' % agenda3.pk not in resp
123

  
113 124

  
114 125
def test_manager_invoicing_regie_edit(app, admin_user):
115 126
    app = login(app)
......
151 162
    app = login(app)
152 163
    group = Group.objects.create(name='role-foo')
153 164
    regie1 = Regie.objects.create(label='Foo', description='foo description', cashier_role=group)
154
    regie2 = Regie.objects.create(label='Bar', description='bar description', cashier_role=group)
165
    Regie.objects.create(label='Bar', description='bar description', cashier_role=group)
155 166
    response = app.get(reverse('lingo-manager-invoicing-regie-export'))
156 167
    assert response.headers['content-type'] == 'application/json'
157 168
    assert response.headers['content-disposition'] == 'attachment; filename="export_regies_20200615.json"'
tests/pricing/manager/test_agenda.py
3 3
import pytest
4 4

  
5 5
from lingo.agendas.models import Agenda, CheckTypeGroup
6
from lingo.invoicing.models import Regie
6 7
from tests.utils import login
7 8

  
8 9
pytestmark = pytest.mark.django_db
......
59 60
    agenda.refresh_from_db()
60 61
    assert agenda.check_type_group == group
61 62
    assert 'Check type group: Foo bar' in resp
63

  
64

  
65
def test_edit_agenda_invoicing_settings(app, admin_user):
66
    agenda = Agenda.objects.create(label='Foo bar')
67
    regie = Regie.objects.create(label='Foo bar')
68

  
69
    app = login(app)
70
    resp = app.get('/manage/pricing/agenda/%s/' % agenda.pk)
71
    resp = resp.click(href='/manage/pricing/agenda/%s/invoicing-options' % agenda.pk)
72
    resp.form['regie'] = regie.pk
73
    resp = resp.form.submit().follow()
74
    agenda.refresh_from_db()
75
    assert agenda.regie == regie
76
    assert 'Regie: Foo bar' in resp
62
-