From 394ec8ab9d3ea9f181bae8a651074290ef9ddfef Mon Sep 17 00:00:00 2001
From: Serghei Mihai <smihai@entrouvert.com>
Date: Sun, 25 Nov 2018 20:09:25 +0100
Subject: [PATCH] lingo: add default values for TIPI reference fields (#26057)

Make fields readonly if default value defined.
---
 .../migrations/0033_auto_20181204_2241.py     | 44 +++++++++++++++++++
 combo/apps/lingo/models.py                    | 28 +++++++++++-
 .../apps/lingo/templates/lingo/tipi_form.html | 15 +++----
 combo/manager/static/js/combo.manager.js      | 38 ++++++++++++++++
 tests/test_lingo_cells.py                     |  8 ++++
 tests/test_lingo_manager.py                   | 19 +++++++-
 6 files changed, 142 insertions(+), 10 deletions(-)
 create mode 100644 combo/apps/lingo/migrations/0033_auto_20181204_2241.py

diff --git a/combo/apps/lingo/migrations/0033_auto_20181204_2241.py b/combo/apps/lingo/migrations/0033_auto_20181204_2241.py
new file mode 100644
index 00000000..9326248d
--- /dev/null
+++ b/combo/apps/lingo/migrations/0033_auto_20181204_2241.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('lingo', '0032_basketitem_capture_date'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='tipipaymentformcell',
+            name='exer',
+            field=models.CharField(help_text='Default value to be used in form', max_length=4, verbose_name='Exer', blank=True),
+        ),
+        migrations.AddField(
+            model_name='tipipaymentformcell',
+            name='idligne',
+            field=models.CharField(help_text='Default value to be used in form', max_length=6, verbose_name='IDLIGNE', blank=True),
+        ),
+        migrations.AddField(
+            model_name='tipipaymentformcell',
+            name='idpce',
+            field=models.CharField(help_text='Default value to be used in form', max_length=8, verbose_name='IDPCE', blank=True),
+        ),
+        migrations.AddField(
+            model_name='tipipaymentformcell',
+            name='roldeb',
+            field=models.CharField(help_text='Default value to be used in form', max_length=2, verbose_name='ROLDEB', blank=True),
+        ),
+        migrations.AddField(
+            model_name='tipipaymentformcell',
+            name='roldet',
+            field=models.CharField(help_text='Default value to be used in form', max_length=13, verbose_name='ROLDET', blank=True),
+        ),
+        migrations.AddField(
+            model_name='tipipaymentformcell',
+            name='rolrec',
+            field=models.CharField(help_text='Default value to be used in form', max_length=2, verbose_name='ROLREC', blank=True),
+        ),
+    ]
diff --git a/combo/apps/lingo/models.py b/combo/apps/lingo/models.py
index 5cdf143c..7ac1767c 100644
--- a/combo/apps/lingo/models.py
+++ b/combo/apps/lingo/models.py
@@ -712,6 +712,12 @@ class TipiPaymentFormCell(CellBase):
     url = models.URLField(_('TIPI payment service URL'), default='https://www.tipi.budget.gouv.fr/tpa/paiement.web')
     regies = models.CharField(_('Regies'), help_text=_('separated by commas'), max_length=256)
     control_protocol = models.CharField(_('Control protocol'), max_length=8, choices=TIPI_CONTROL_PROCOTOLS, default='pesv2')
+    exer = models.CharField('Exer', max_length=4, blank=True, help_text=_('Default value to be used in form'))
+    idpce = models.CharField('IDPCE', max_length=8, blank=True, help_text=_('Default value to be used in form'))
+    idligne = models.CharField('IDLIGNE', max_length=6, blank=True, help_text=_('Default value to be used in form'))
+    rolrec = models.CharField('ROLREC', max_length=2, blank=True, help_text=_('Default value to be used in form'))
+    roldeb = models.CharField('ROLDEB', max_length=2, blank=True, help_text=_('Default value to be used in form'))
+    roldet = models.CharField('ROLDET', max_length=13, blank=True, help_text=_('Default value to be used in form'))
     test_mode = models.BooleanField(_('Test mode'), default=False)
     template_name = 'lingo/tipi_form.html'
 
@@ -723,11 +729,31 @@ class TipiPaymentFormCell(CellBase):
 
     def get_cell_extra_context(self, context):
         extra_context = super(TipiPaymentFormCell, self).get_cell_extra_context(context)
+        form_fields = self.get_default_form_class().base_fields
+        field_definitions = ({'protocol': 'any', 'fields': ['exer']},
+                  {'protocol': 'pesv2', 'fields': ['idligne', 'idpce']},
+                  {'protocol': 'rolmre', 'fields': ['rolrec', 'roldeb', 'roldet']}
+        )
+        reference_fields = []
+        for definition in field_definitions:
+            for field in definition['fields']:
+                field_pattern = '[0-9]+'
+                # special pattern for rolrec
+                if field == 'rolrec':
+                    field_pattern = '[A-Z0-9]+'
+                reference_fields.append({'name': field, 'length': form_fields[field].max_length,
+                                         'placeholder': '0'*form_fields[field].max_length,
+                                         'pattern': field_pattern,
+                                         'protocol': definition['protocol']})
         context['title'] = self.title
         context['url'] = self.url
         context['mode'] = 'T' if self.test_mode else 'M'
-        context['pesv2'] = (self.control_protocol == 'pesv2')
+        context['control_protocol'] = self.control_protocol
         context['regies'] = []
+        for field in reference_fields:
+            if getattr(self, field['name']):
+                field['default'] = getattr(self, field['name'])
+        context['reference_fields'] = reference_fields
         for regie in self.regies.split(','):
             regie_id = regie.strip()
             if not regie_id:
diff --git a/combo/apps/lingo/templates/lingo/tipi_form.html b/combo/apps/lingo/templates/lingo/tipi_form.html
index 98dfc575..d0f87bc4 100644
--- a/combo/apps/lingo/templates/lingo/tipi_form.html
+++ b/combo/apps/lingo/templates/lingo/tipi_form.html
@@ -24,15 +24,14 @@
     </ul>
     <p>
       <label>{% trans "Reference" %}</label>
-      <input type="text" id="exer" required pattern="[0-9]+" maxlength="4" size="4" placeholder="0000" /> -
-      {% if pesv2 %}
-      <input type="text" id="idpce" required pattern="[0-9]+" maxlength="8" size="8" placeholder="00000000" /> -
-      <input type="text" id="idligne" required pattern="[0-9]+" maxlength="6" size="6" placeholder="000000" />
-      {% else %}
-      <input type="text" id="rolrec" required pattern="[A-Z0-9]+" maxlength="2" size="2" placeholder="00" /> -
-      <input type="text" id="roldeb" required pattern="[0-9]+" maxlength="2" size="2" placeholder="00" /> -
-      <input type="text" id="roldet" required pattern="[0-9]+" maxlength="13" size="13" placeholder="0000000000000" />
+      {% regroup reference_fields by protocol as fields %}
+      {% for field in fields %}
+      {% for f in field.list %}
+      {% if field.grouper == control_protocol or field.grouper == 'any' %}
+      <input type="text" id="{{ f.name }}" required pattern="{{ f.pattern }}" maxlength="{{ f.length }}" size="{{ f.length }}" placeholder="{{ f.placeholder }}" {% if f.default %}value="{{ f.default }}" readonly {% endif %}/>{% if field.grouper == 'any' or not forloop.last %} - {% endif %}
       {% endif %}
+      {% endfor %}
+      {% endfor %}
     </p>
     <ul class="errorlist" id="montant_error" style="display: none">
       <li>{% trans "invalid amount" %}</li>
diff --git a/combo/manager/static/js/combo.manager.js b/combo/manager/static/js/combo.manager.js
index 559f7463..cdaaeb95 100644
--- a/combo/manager/static/js/combo.manager.js
+++ b/combo/manager/static/js/combo.manager.js
@@ -230,6 +230,44 @@ $(function() {
     $(style).appendTo('head');
   }
 
+  function handle_tipi_form(element) {
+    var prefix_components = element.attr('name').split('-');
+    /* remove field name and keep only prefix */
+    prefix_components.pop();
+    var prefix = prefix_components.join('-');
+    function hide_fields(fields) {
+        fields.forEach(function(f) {
+            $("[name="+prefix+"-"+f+"]").parent().hide();
+        });
+    }
+    function show_fields(fields) {
+        fields.forEach(function(f) {
+            $("[name="+prefix+"-"+f+"]").parent().show();
+        })
+    }
+    if (element.val() == 'pesv2') {
+        show_fields(['idpce', 'idligne']);
+        hide_fields(['rolrec', 'roldeb', 'roldet']);
+    } else {
+        show_fields(['rolrec', 'roldeb', 'roldet']);
+        hide_fields(['idpce', 'idligne']);
+    }
+  }
+
+  $('.cell.tipipaymentformcell select').on('change', function() {
+      handle_tipi_form($(this));
+      compute_max_height($(this).parents('div.cell'));
+  });
+  $('.cell.tipipaymentformcell select').trigger('change');
+
+  $('.cell.tipipaymentformcell').on('combo:cellform-reloaded', function() {
+      var $select = $(this).find('select');
+      $select.on('change', function() {
+          handle_tipi_form($select);
+      });
+      $select.trigger('change');
+  });
+
   $('div.cell').each(function(i, x) {
     $(this).attr('id', 'div-cell-'+i);
     compute_max_height($(this));
diff --git a/tests/test_lingo_cells.py b/tests/test_lingo_cells.py
index 9f525b22..e7ed268a 100644
--- a/tests/test_lingo_cells.py
+++ b/tests/test_lingo_cells.py
@@ -199,3 +199,11 @@ def test_tipi_cell():
     html = cell.render({})
     assert "Community identifier" in html
     assert '<select id="numcli">' in html
+
+    # set reference default values and check they are filled and readonly
+    cell.exer = '1234'
+    cell.rolrec = '00'
+    cell.save()
+    html = cell.render({})
+    assert 'value="1234" readonly' in html
+    assert 'value="00" readonly' in html
diff --git a/tests/test_lingo_manager.py b/tests/test_lingo_manager.py
index af81c1e6..24f963ce 100644
--- a/tests/test_lingo_manager.py
+++ b/tests/test_lingo_manager.py
@@ -10,7 +10,7 @@ import pytest
 
 import eopayment
 from combo.data.models import Page
-from combo.apps.lingo.models import Regie, BasketItem, Transaction, ActiveItems
+from combo.apps.lingo.models import Regie, BasketItem, Transaction, ActiveItems, TipiPaymentFormCell
 from decimal import Decimal
 
 pytestmark = pytest.mark.django_db
@@ -155,6 +155,23 @@ def test_transactions_search(app, admin_user):
     assert resp.text.count('<tr') == 0
     assert 'No transactions found matching' in resp.text
 
+def test_configure_tipi_cell(app, admin_user):
+    page = Page(title='tipi', slug='tipi', template_name='standard')
+    page.save()
+
+    app = login(app)
+    resp = app.get('/manage/pages/%s/' % page.id, status=200)
+
+    cell = TipiPaymentFormCell(title='Test payment', page=page, placeholder='content', order=0)
+    cell.save()
+    resp = app.get('/manage/pages/%s/' % page.id, status=200)
+    assert resp.text.count('Exer:') == 1
+    assert resp.text.count('IDPCE:') == 1
+    assert resp.text.count('IDLIGNE:') == 1
+    assert resp.text.count('ROLREC:') == 1
+    assert resp.text.count('ROLDEB:') == 1
+    assert resp.text.count('ROLDET:') == 1
+
 def test_configure_invoices_cell(app, admin_user):
     page = Page(title='xxx', slug='test', template_name='standard')
     page.save()
-- 
2.20.1

