creme-crm 2.7.3__py3-none-any.whl → 2.7.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
creme/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = '2.7.3'
1
+ __version__ = '2.7.4'
2
2
 
3
3
 
4
4
  def get_version():
@@ -358,6 +358,8 @@ class CustomFieldsBrick(Brick):
358
358
  _ContentTypeWrapper(get_ct(ct_id), ct_cfields)
359
359
  for ct_id, ct_cfields in cfields_per_ct_id.items()
360
360
  ]
361
+ sort_key = collator.sort_key
362
+ ctypes.sort(key=lambda wrp: sort_key(str(wrp.ctype)))
361
363
 
362
364
  return self._render(self.get_template_context(
363
365
  context,
@@ -1598,6 +1598,19 @@ class CustomFormTestCase(BrickTestCaseMixin, CremeTestCase):
1598
1598
  reverse('creme_config__delete_custom_form_cell', args=(cfci.id,)),
1599
1599
  data={'cell_key': cell_to_dell.key},
1600
1600
  )
1601
+ self.assertListEqual(
1602
+ [
1603
+ {
1604
+ 'name': 'General', 'layout': LAYOUT_REGULAR,
1605
+ 'cells': [
1606
+ {'type': 'regular_field', 'value': 'user'},
1607
+ {'type': 'regular_field', 'value': 'name'},
1608
+ ]
1609
+ },
1610
+ {'group_id': FakeAddressGroup.extra_group_id},
1611
+ ],
1612
+ self.refresh(cfci).groups_as_dicts(),
1613
+ )
1601
1614
 
1602
1615
  @parameterized.expand([
1603
1616
  (0, LAYOUT_DUAL_FIRST),
@@ -1,6 +1,6 @@
1
1
  ################################################################################
2
2
  # Creme is a free/open-source Customer Relationship Management software
3
- # Copyright (C) 2020-2025 Hybird
3
+ # Copyright (C) 2020-2026 Hybird
4
4
  #
5
5
  # This program is free software: you can redistribute it and/or modify
6
6
  # it under the terms of the GNU Affero General Public License as published by
@@ -318,8 +318,9 @@ class CustomFormCellDeletion(BaseCustomFormDeletion):
318
318
  desc = self.get_customform_descriptor()
319
319
 
320
320
  groups = []
321
- found = False
321
+ found = False # Found in any group
322
322
  for group in self.get_groups():
323
+ found_in_group = False
323
324
  cells = []
324
325
 
325
326
  # TODO: better API for group.cells ?
@@ -327,11 +328,11 @@ class CustomFormCellDeletion(BaseCustomFormDeletion):
327
328
  if cell.key != cell_key:
328
329
  cells.append(cell)
329
330
  else:
330
- found = True
331
+ found = found_in_group = True
331
332
 
332
333
  groups.append(
333
334
  FieldGroup(name=group.name, cells=cells, layout=group.layout)
334
- if found else
335
+ if found_in_group else
335
336
  group
336
337
  )
337
338
 
@@ -1,6 +1,6 @@
1
1
  ################################################################################
2
2
  # Creme is a free/open-source Customer Relationship Management software
3
- # Copyright (C) 2022-2025 Hybird
3
+ # Copyright (C) 2022-2026 Hybird
4
4
  #
5
5
  # This program is free software: you can redistribute it and/or modify
6
6
  # it under the terms of the GNU Affero General Public License as published by
@@ -260,30 +260,35 @@ class EnumerableSelect(widgets.Select):
260
260
 
261
261
  def get_context(self, name, value, attrs):
262
262
  context = super().get_context(name, value, attrs)
263
- enumerable = self.enumerable
264
-
265
- choices, more = enumerable.groups(
266
- selected_values=[value] if value else None
267
- ) if enumerable is not None else ((), False)
263
+ choices, more = self.get_enum_groups(value)
268
264
 
269
265
  context['widget']['choices'] = choices
270
266
  self.build_enum_attrs(context['widget']['attrs'], more)
271
267
 
272
268
  return context
273
269
 
270
+ def get_enum_groups(self, value):
271
+ enumerable = self.enumerable
272
+
273
+ return enumerable.groups(
274
+ selected_values=[value] if value else None
275
+ ) if enumerable is not None else ((), False)
276
+
274
277
  def build_enum_attrs(self, attrs, more):
278
+ enumerable = self.enumerable
279
+
275
280
  if more:
276
281
  attrs.update({
277
- 'data-enum-url': self.enumerable.url,
278
- 'data-enum-limit': self.enumerable.limit,
282
+ 'data-enum-url': enumerable.url,
283
+ 'data-enum-limit': enumerable.limit,
279
284
  })
280
285
  attrs.setdefault('data-enum-cache', 'true')
281
286
  attrs.setdefault('data-enum-debounce', self.ENUMERABLE_DEFAULT_DEBOUNCE_DELAY)
282
287
 
283
288
  attrs['data-allow-clear'] = str(not self.is_required).lower()
284
289
 
285
- if self.enumerable.empty_label:
286
- attrs['data-placeholder'] = self.enumerable.empty_label
290
+ if enumerable.empty_label:
291
+ attrs['data-placeholder'] = enumerable.empty_label
287
292
 
288
293
  if self.create_url:
289
294
  attrs['data-create-url'] = self.create_url
@@ -294,6 +299,15 @@ class EnumerableSelect(widgets.Select):
294
299
  class EnumerableSelectMultiple(EnumerableSelect):
295
300
  allow_multiple_selected = True
296
301
 
302
+ def get_enum_groups(self, value):
303
+ # The value is already a list here, so we need to override the default
304
+ # behaviour
305
+ enumerable = self.enumerable
306
+
307
+ return enumerable.groups(
308
+ selected_values=value if value else None
309
+ ) if enumerable is not None else ((), False)
310
+
297
311
  def value_from_datadict(self, data, files, name):
298
312
  try:
299
313
  getter = data.getlist
@@ -427,12 +427,11 @@ class FieldsConfig(CremeModel):
427
427
  try:
428
428
  form_fields[field_name].required = True
429
429
  except KeyError:
430
- # TODO: we need the form class for a better message
431
- logger.info(
430
+ logger.warning(
432
431
  'The field "%s" has been configured to be required '
433
- 'but the current form does not use this field ; '
432
+ 'but the form %s does not use this field; '
434
433
  'so we add it.',
435
- field_name,
434
+ field_name, type(form),
436
435
  )
437
436
  # TODO: is it possible that field does not exist any more ?
438
437
  form_fields[field_name] = (
@@ -19,6 +19,7 @@ from creme.creme_core.forms.enumerable import (
19
19
  EnumerableChoice,
20
20
  EnumerableModelChoiceField,
21
21
  EnumerableSelect,
22
+ EnumerableSelectMultiple,
22
23
  FieldEnumerableChoiceSet,
23
24
  )
24
25
  from creme.creme_core.models import (
@@ -451,6 +452,148 @@ class EnumerableSelectTestCase(CremeTestCase):
451
452
  )
452
453
 
453
454
 
455
+ @override_settings(FORM_ENUMERABLE_LIMIT=100)
456
+ class EnumerableSelectMultipleTestCase(CremeTestCase):
457
+ maxDiff = None
458
+
459
+ def test_render_no_url(self):
460
+ farming, industry, software = FakeSector.objects.order_by('pk')[:3]
461
+ sector_A = FakeSector.objects.create(title='Sector A')
462
+ sector_B = FakeSector.objects.create(title='Sector B')
463
+ sector_C = FakeSector.objects.create(title='Sector C')
464
+
465
+ enumerable = FieldEnumerableChoiceSet(FakeContact._meta.get_field('sector'))
466
+ widget = EnumerableSelectMultiple(enumerable)
467
+
468
+ self.assertHTMLEqual(
469
+ f'''
470
+ <select class="ui-creme-input ui-creme-widget ui-creme-dselect widget-auto is-enum"
471
+ widget="ui-creme-dselect"
472
+ name="testfield" autocomplete
473
+ data-allow-clear="true" multiple>
474
+ <option value="{farming.pk}">Farming</option>
475
+ <option selected value="{industry.pk}">Industry</option>
476
+ <option value="{software.pk}">Software</option>
477
+ <option value="{sector_A.pk}">Sector A</option>
478
+ <option value="{sector_B.pk}">Sector B</option>
479
+ <option selected value="{sector_C.pk}">Sector C</option>
480
+ </select>
481
+ ''',
482
+ widget.render('testfield', value=(industry.pk, sector_C.pk)),
483
+ )
484
+
485
+ def test_render_url(self):
486
+ farming, industry, software = FakeSector.objects.order_by('pk')[:3]
487
+
488
+ enumerable = FieldEnumerableChoiceSet(FakeContact._meta.get_field('sector'))
489
+ widget = EnumerableSelectMultiple(enumerable)
490
+ widget.create_url = url = reverse(
491
+ 'creme_config__create_instance_from_widget', args=('creme_core', 'fake_sector'),
492
+ )
493
+
494
+ self.assertHTMLEqual(
495
+ f'''
496
+ <select class="ui-creme-input ui-creme-widget ui-creme-dselect widget-auto is-enum"
497
+ widget="ui-creme-dselect"
498
+ name="testfield" autocomplete
499
+ data-create-url="{url}"
500
+ data-allow-clear="true" multiple>
501
+ <option value="{farming.pk}">Farming</option>
502
+ <option selected value="{industry.pk}">Industry</option>
503
+ <option selected value="{software.pk}">Software</option>
504
+ </select>
505
+ ''',
506
+ widget.render('testfield', value=(industry.pk, software.pk)),
507
+ )
508
+
509
+ def test_render__more(self):
510
+ farming, industry, software = FakeSector.objects.order_by('pk')[:3]
511
+ sector_A = FakeSector.objects.create(title='Sector A')
512
+ FakeSector.objects.create(title='Sector B')
513
+ FakeSector.objects.create(title='Sector C')
514
+
515
+ enumerable = FieldEnumerableChoiceSet(FakeContact._meta.get_field('sector'), limit=4)
516
+ widget = EnumerableSelectMultiple(enumerable)
517
+
518
+ self.assertHTMLEqual(
519
+ f'''
520
+ <select class="ui-creme-input ui-creme-widget ui-creme-dselect widget-auto is-enum"
521
+ widget="ui-creme-dselect"
522
+ name="testfield" autocomplete
523
+ data-allow-clear="true"
524
+ data-enum-url="{enumerable.url}"
525
+ data-enum-limit="{enumerable.limit}"
526
+ data-enum-cache="true"
527
+ data-enum-debounce="300"
528
+ multiple>
529
+ <option value="{farming.pk}">Farming</option>
530
+ <option selected value="{industry.pk}">Industry</option>
531
+ <option value="{software.pk}">Software</option>
532
+ <option selected value="{sector_A.pk}">Sector A</option>
533
+ </select>
534
+ ''',
535
+ widget.render('testfield', value=(industry.pk, sector_A.pk)),
536
+ )
537
+
538
+ def test_render__more__outside_limit(self):
539
+ """Selected values outside the choice limit are added anyway"""
540
+ farming, industry, software = FakeSector.objects.order_by('pk')[:3]
541
+ sector_A = FakeSector.objects.create(title='Sector A')
542
+ FakeSector.objects.create(title='Sector B')
543
+ sector_C = FakeSector.objects.create(title='Sector C')
544
+
545
+ enumerable = FieldEnumerableChoiceSet(FakeContact._meta.get_field('sector'), limit=4)
546
+ widget = EnumerableSelectMultiple(enumerable)
547
+
548
+ self.assertHTMLEqual(
549
+ f'''
550
+ <select class="ui-creme-input ui-creme-widget ui-creme-dselect widget-auto is-enum"
551
+ widget="ui-creme-dselect"
552
+ name="testfield" autocomplete
553
+ data-allow-clear="true"
554
+ data-enum-url="{enumerable.url}"
555
+ data-enum-limit="{enumerable.limit}"
556
+ data-enum-cache="true"
557
+ data-enum-debounce="300"
558
+ multiple>
559
+ <option value="{farming.pk}">Farming</option>
560
+ <option selected value="{industry.pk}">Industry</option>
561
+ <option value="{software.pk}">Software</option>
562
+ <option value="{sector_A.pk}">Sector A</option>
563
+ <option selected value="{sector_C.pk}">Sector C</option>
564
+ </select>
565
+ ''',
566
+ widget.render('testfield', value=(industry.pk, sector_C.pk)),
567
+ )
568
+
569
+ def test_render__more_custom_attrs(self):
570
+ farming, industry, software = FakeSector.objects.order_by('pk')[:3]
571
+
572
+ enumerable = FieldEnumerableChoiceSet(FakeContact._meta.get_field('sector'), limit=2)
573
+ widget = EnumerableSelectMultiple(enumerable, attrs={
574
+ 'data-enum-cache': 'false',
575
+ 'data-enum-debounce': 500,
576
+ })
577
+
578
+ self.assertHTMLEqual(
579
+ f'''
580
+ <select class="ui-creme-input ui-creme-widget ui-creme-dselect widget-auto is-enum"
581
+ widget="ui-creme-dselect"
582
+ name="testfield" autocomplete
583
+ data-allow-clear="true"
584
+ data-enum-url="{enumerable.url}"
585
+ data-enum-limit="{enumerable.limit}"
586
+ data-enum-cache="false"
587
+ data-enum-debounce="500"
588
+ multiple>
589
+ <option value="{farming.pk}">Farming</option>
590
+ <option selected value="{industry.pk}">Industry</option>
591
+ </select>
592
+ ''',
593
+ widget.render('testfield', value=(industry.pk,)),
594
+ )
595
+
596
+
454
597
  @override_settings(FORM_ENUMERABLE_LIMIT=100)
455
598
  class EnumerableModelChoiceFieldTestCase(CremeTestCase):
456
599
  maxDiff = None
@@ -1,4 +1,5 @@
1
1
  import difflib
2
+ from datetime import date
2
3
  from json import loads as json_load
3
4
  from unittest.util import safe_repr
4
5
 
@@ -79,7 +80,7 @@ class CalendarWidgetTestCase(CremeTestCase):
79
80
  def test_render__en(self):
80
81
  name = 'my_calendar'
81
82
  value = self.formfield_value_date(2023, 3, 26)
82
- help_text = _('E.g. {}').format('2025-12-31')
83
+ help_text = _('E.g. {}').format(f'{date.today().year}-12-31')
83
84
  self.assertHTMLEqual(
84
85
  f'<div class="creme-datepicker">'
85
86
  f' <div class="help-text-format">{help_text}</div>'
@@ -96,7 +97,7 @@ class CalendarWidgetTestCase(CremeTestCase):
96
97
  def test_render__fr(self):
97
98
  name = 'calendar'
98
99
  value = self.formfield_value_date(2024, 4, 27)
99
- help_text = _('E.g. {}').format('31/12/2025')
100
+ help_text = _('E.g. {}').format(f'31/12/{date.today().year}')
100
101
  self.assertHTMLEqual(
101
102
  f'<div class="creme-datepicker">'
102
103
  f' <div class="help-text-format">{help_text}</div>'
@@ -8,7 +8,7 @@ msgid ""
8
8
  msgstr ""
9
9
  "Project-Id-Version: Creme Reports 2.7\n"
10
10
  "Report-Msgid-Bugs-To: \n"
11
- "POT-Creation-Date: 2025-07-31 10:52+0200\n"
11
+ "POT-Creation-Date: 2026-01-09 18:30+0100\n"
12
12
  "Last-Translator: Hybird <contact@hybird.org>\n"
13
13
  "Language: fr\n"
14
14
  "MIME-Version: 1.0\n"
@@ -613,6 +613,9 @@ msgstr "Type de graphique"
613
613
  msgid "Download CSV"
614
614
  msgstr "Télécharger CSV"
615
615
 
616
+ msgid "You cannot export this type of entity"
617
+ msgstr "Vous ne pouvez pas exporter ce type de fiche"
618
+
616
619
  msgid "Go to the configuration of Reports' filters"
617
620
  msgstr "Aller à la configuration des filtres de Rapports"
618
621
 
@@ -1,5 +1,5 @@
1
1
  {% extends 'creme_core/bricks/generic/hat-bar.html' %}
2
- {% load i18n creme_bricks creme_widgets %}
2
+ {% load i18n creme_bricks creme_perms creme_widgets %}
3
3
  {% load url from creme_core_tags %}
4
4
 
5
5
  {% block buttons %}
@@ -9,7 +9,11 @@
9
9
  </a>
10
10
  </div>
11
11
  <div class='bar-action'>
12
- {% brick_action id='reports-export' url='reports__export_report_filter'|url:object.id label=_('Download CSV') class='bar-button' icon_size='brick-hat-bar-button' icon='document_csv' display='icon' %}
12
+ {% if user|has_perm_to_export:object.ct %}
13
+ {% brick_bar_button action='reports-export' url='reports__export_report_filter'|url:object.id label=_('Download CSV') icon='document_csv' %}
14
+ {% else %}
15
+ {% brick_bar_button action='reports-export' url='' label=_('Download CSV') icon='document_csv' help_text=_('You cannot export this type of entity') enabled=False %}
16
+ {% endif%}
13
17
  </div>
14
18
  {{block.super}}
15
19
  {% endblock %}
@@ -1,5 +1,6 @@
1
1
  {% extends 'creme_core/detailview.html' %}
2
2
  {% load i18n creme_widgets reports_tags %}
3
+ {% load i18n creme_perms creme_widgets %}{# reports_tags #}
3
4
 
4
5
  {% block page_title %}{% blocktranslate %}Preview {{object}}{% endblocktranslate %} - {% endblock %}
5
6
 
@@ -34,7 +35,11 @@
34
35
  <form>{% include 'reports/frags/report_preview_format.html' %}</form>
35
36
  <div class="report-preview-buttons">
36
37
  <button class="ui-creme-actionbutton" type="button" name="generate">{% translate 'Preview' context 'reports-preview' %}</button>
37
- <button class="ui-creme-actionbutton" type="button" name="download">{% translate 'Download as file' %}</button>
38
+ {% if user|has_perm_to_export:object.ct %}
39
+ <button class="ui-creme-actionbutton" type="button" name="download">{% translate 'Download as file' %}</button>
40
+ {% else %}
41
+ <button disabled class="ui-creme-actionbutton" type="button" name="download" title="{% translate 'You cannot export this type of entity'%}" >{% translate 'Download as file' %}</button>
42
+ {% endif %}
38
43
  </div>
39
44
  </div>
40
45
 
@@ -1545,8 +1545,44 @@ class ReportTestCase(BrickTestCaseMixin, BaseReportsTestCase):
1545
1545
  response.text,
1546
1546
  )
1547
1547
 
1548
+ def test_perms(self):
1549
+ user = self.login_as_standard(
1550
+ allowed_apps=['creme_core'], # 'reports'
1551
+ # exportable_models=[FakeContact],
1552
+ )
1553
+ role = user.role
1554
+ self.add_credentials(role=role, own=['VIEW'])
1555
+
1556
+ report = self._create_contacts_report(user=user, name='trinita')
1557
+ url = self._build_export_url(report)
1558
+ data = {'doc_type': 'csv'}
1559
+
1560
+ # App permission --
1561
+ response1 = self.client.get(url, data=data)
1562
+ self.assertContains(
1563
+ response1,
1564
+ status_code=403,
1565
+ text=_('You are not allowed to access to the app: {}').format(_('Reports')),
1566
+ html=True,
1567
+ )
1568
+
1569
+ # Export permission --
1570
+ role.allowed_apps = ['creme_core', 'reports']
1571
+ role.save()
1572
+ response2 = self.client.get(url, data=data)
1573
+ self.assertContains(
1574
+ response2,
1575
+ status_code=403,
1576
+ text=_('You are not allowed to export: {}').format('Test Contact'),
1577
+ html=True,
1578
+ )
1579
+
1548
1580
  def test_report_csv__no_filter(self):
1549
- user = self.login_as_root_and_get()
1581
+ user = self.login_as_standard(
1582
+ allowed_apps=['creme_core', 'reports'],
1583
+ exportable_models=[FakeContact],
1584
+ )
1585
+ self.add_credentials(role=user.role, own=['VIEW'])
1550
1586
 
1551
1587
  self._create_persons(user=user)
1552
1588
  self.assertEqual(3, FakeContact.objects.count())
@@ -1,6 +1,6 @@
1
1
  ################################################################################
2
2
  # Creme is a free/open-source Customer Relationship Management software
3
- # Copyright (C) 2009-2025 Hybird
3
+ # Copyright (C) 2009-2026 Hybird
4
4
  #
5
5
  # This program is free software: you can redistribute it and/or modify
6
6
  # it under the terms of the GNU Affero General Public License as published by
@@ -123,6 +123,7 @@ class Export(generic.base.EntityRelatedMixin, generic.CheckedView):
123
123
 
124
124
  def check_related_entity_permissions(self, entity, user):
125
125
  user.has_perm_to_view_or_die(entity)
126
+ user.has_perm_to_export_or_die(entity.ct)
126
127
 
127
128
  def get_form(self, *, report, request):
128
129
  form = self.form_class(instance=report, user=request.user, data=request.GET)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: creme-crm
3
- Version: 2.7.3
3
+ Version: 2.7.4
4
4
  Summary: A CRM software using the django web framework
5
5
  Home-page: https://www.cremecrm.com
6
6
  Author: hybird.org
@@ -29,7 +29,7 @@ Classifier: Topic :: Office/Business
29
29
  Requires-Python: >=3.10
30
30
  Description-Content-Type: text/markdown
31
31
  License-File: LICENSE.txt
32
- Requires-Dist: django~=5.2.9
32
+ Requires-Dist: django~=5.2.10
33
33
  Requires-Dist: redis~=6.2.0
34
34
  Requires-Dist: Pillow~=11.3.0
35
35
  Requires-Dist: python-dateutil~=2.8.2
@@ -1,4 +1,4 @@
1
- creme/__init__.py,sha256=-fLXAWytd4GaQAXzOpCEPEGKT2bgV8ZnVgqZsbxQqZU,1078
1
+ creme/__init__.py,sha256=O_PlMR2sO4yyk5-hZtInHBsTaCywaqbBxCrbXWL8Q_I,1078
2
2
  creme/manage.py,sha256=9TahLBSSW_WbL1SZnDw0l1vM69w7MZ7P2BIfLLzquIw,968
3
3
  creme/settings.py,sha256=vFdSBTywLk_rJehLv643xAYJuuwY8nFcaKhUfTEwq-A,62248
4
4
  creme/urls.py,sha256=Dz1YwuwAKPpI3LmI8YdCuS3-2fZtX48xMhJajmqMe5o,2681
@@ -398,7 +398,7 @@ creme/commercial/views/salesman.py,sha256=NpGdoift5OOQl8IIPxi1E1SH8DcQyXffjs41sj
398
398
  creme/commercial/views/strategy.py,sha256=uLiuQVyLJ64TfU74SxE_wrq9nW2hdlszbw_1gK4nNo4,11603
399
399
  creme/creme_config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
400
400
  creme/creme_config/apps.py,sha256=x-JNOK3sbL3syiV0FELoWwG5cdvl41JUp8DxGNrrJuw,5677
401
- creme/creme_config/bricks.py,sha256=lDNVPWILS8mMh_an_A2Wzh4ShVHlShc52xIzun-36wA,54190
401
+ creme/creme_config/bricks.py,sha256=X4d8V62O3QcZO1XeI_zh5cDvRHNducUkEwlE0mKtSDE,54289
402
402
  creme/creme_config/constants.py,sha256=wsFnrmpPHXQIV_OtHU-6PZZXE6zmXzgsNe5bzj9LtTY,894
403
403
  creme/creme_config/menu.py,sha256=I0wTo9Dv0gX9n5210UFNUNL3-Y7MdWKkNzTP7k9zLVg,10344
404
404
  creme/creme_config/models.py,sha256=4vcd-aQDdDv1prId1rzWZ_sAhEQoIbDtlw0MAsi0CiQ,119
@@ -534,7 +534,7 @@ creme/creme_config/tests/test_button_menu.py,sha256=geq3jRGDt4APzjnN5WInw0u699Je
534
534
  creme/creme_config/tests/test_creme_property_type.py,sha256=G_l-z-ODN0nfGDAUGG83XHSLwYZbBuWHx46Wj_jCRqs,6381
535
535
  creme/creme_config/tests/test_custom_entity.py,sha256=OK4PSvxTSId4eL764l309-bkeISGDuuzo2FWrRvLdkQ,18723
536
536
  creme/creme_config/tests/test_custom_field.py,sha256=tj0QLpZZJ50lu5hAdL9iYUQrkRer8qxjVgGMRZMA0A8,53479
537
- creme/creme_config/tests/test_custom_form.py,sha256=PnAPfFxpuxzTvextb2oljaRGnzURoXlrwFS3GzvCv4o,76265
537
+ creme/creme_config/tests/test_custom_form.py,sha256=B0MlxsP9rTdiqUhZu59a1M5P0BNnAb3bPdW1mWvGO5c,76738
538
538
  creme/creme_config/tests/test_entity_filter.py,sha256=PuQKubj-FHngpei9h36Rv-oiKzP29t9yqYhuL8DNsHo,7990
539
539
  creme/creme_config/tests/test_fields.py,sha256=rknpgYv-cy0Jk9icsc2arngxvlQo6KGTislnbK38rV8,45769
540
540
  creme/creme_config/tests/test_fields_config.py,sha256=QHWdHT4A2qzCYxjgboY9_4l1lHHAMyAkhO4W8x2oplI,12250
@@ -565,7 +565,7 @@ creme/creme_config/views/button_menu.py,sha256=QmoLBAgPWLQ6WQglDL62LIlZBmspRxGeR
565
565
  creme/creme_config/views/creme_property_type.py,sha256=k_5HecMK5gPOnTekrYSUyTxRIhKID1zVaejO9MThPjw,2562
566
566
  creme/creme_config/views/custom_entity.py,sha256=B6ZTJSdWVXK1002vRdPhm62Q0roS0hW6EaPZMVQPLCA,12199
567
567
  creme/creme_config/views/custom_field.py,sha256=m2yUatZXgq8JFoYPX5QZ5ssEey41nZzUzntMESGlfFE,11284
568
- creme/creme_config/views/custom_form.py,sha256=XY2HCu8Bc8cqlk9FwPdFVi21E_DUscpov_VR4IxwHYE,15315
568
+ creme/creme_config/views/custom_form.py,sha256=fdxOldQfOqljIORnMX-pHJqa1VU1znHuDNSpUde90Sg,15398
569
569
  creme/creme_config/views/entity_filter.py,sha256=A81rgXhPg0-Do7VWoAjGDG6CfXqQY-maY5oaMK150sU,3575
570
570
  creme/creme_config/views/fields_config.py,sha256=p60cnPymn7iiSpQOfOBVozgOz2cPYDkWm4KckpePrz8,3470
571
571
  creme/creme_config/views/file_ref.py,sha256=I48H3RcEW_Zw6eK52LOeCiydKdzLMmo_1SRWMsX_K3E,1221
@@ -680,7 +680,7 @@ creme/creme_core/forms/__init__.py,sha256=DffGY4x0CW3CY0AJmZQIQ8HtQvawnbpULkHvdE
680
680
  creme/creme_core/forms/base.py,sha256=9YNPWqQsOWXnj2d9vUhkUMlzeSwjpq8munS123A-s24,31857
681
681
  creme/creme_core/forms/batch_process.py,sha256=E48GUXM33XORmF_k0Pft6gRgxeffXyq7CwTuj6sOzLU,9462
682
682
  creme/creme_core/forms/creme_property.py,sha256=_3XO6SRIC6nrS0_NsTYeUq6uEgwcorm0bRU4aZeRJe8,3323
683
- creme/creme_core/forms/enumerable.py,sha256=PBhh0kruwohhgAbbALGaM-fyz1Aeg_did6P_wtS6HFM,14124
683
+ creme/creme_core/forms/enumerable.py,sha256=7f3m7MGh5zL5kXxlteq8eSwRUtzkBRM1DhTDBGOXr-U,14540
684
684
  creme/creme_core/forms/fields.py,sha256=P-2_72s-qZTBK5t_hmM_Hn6RRWRLDhzJGBZy0qWlgDU,76380
685
685
  creme/creme_core/forms/header_filter.py,sha256=XmnVcCLasyNPg5ZKwBvn0JPtVOZPAPcYlU3rG3ZQWwo,25331
686
686
  creme/creme_core/forms/job.py,sha256=tAQFFrgeAYCJ4kpCNg2gx84v3XujVb9VtcXi_RvwOwU,1105
@@ -782,7 +782,7 @@ creme/creme_core/models/deletion.py,sha256=QfkRm8b27mzJK8NOCC5rMz1A8Oy3wLCxU_rYW
782
782
  creme/creme_core/models/entity.py,sha256=hY73BUAXqLYbrbpjfnpJKzyQcJBNZxoiL4TLnN9bXg4,22228
783
783
  creme/creme_core/models/entity_filter.py,sha256=Pc6aUZSdD5IaW_d2VWJ9Y1vtSBfEaIlOcchiW8cQ5cc,41896
784
784
  creme/creme_core/models/fields.py,sha256=PUxRq5LgxexSxOUhMifixkGrFb72dSZP64zN0537fR0,26037
785
- creme/creme_core/models/fields_config.py,sha256=8gCcb4sq3qHiGhsfFHEDZv3iDadISYNbz-470FoIg9Y,16198
785
+ creme/creme_core/models/fields_config.py,sha256=bax6o0XH8PAtty9J21JXuiv2h_wa8dm_bIr-2TBa1qI,16139
786
786
  creme/creme_core/models/file_ref.py,sha256=7YFpTmWcTmWFMmP173TwjUubAl5k4DXo3OaJ0SpqfZ0,2946
787
787
  creme/creme_core/models/header_filter.py,sha256=y_UKiGARQZ0sosd5cWYTruFVbq810Gue9UpKpx6X5rs,10986
788
788
  creme/creme_core/models/history.py,sha256=ijN8wxU9x2njdakGPE1AhtipPSad_9nAW0PkaO_UHjw,46468
@@ -1416,14 +1416,14 @@ creme/creme_core/tests/forms/test_base.py,sha256=yEMNSA59sD2AJJF0mn8h8ZWWEqCVfB6
1416
1416
  creme/creme_core/tests/forms/test_batch_process.py,sha256=UrtshBZS-NEWtN4LDpP0ZOkVUTSFG0k5eawvHck24Aw,6657
1417
1417
  creme/creme_core/tests/forms/test_entity_cell.py,sha256=nVq_feD7iqhOAYkFlHHLI9UBQypZuUfBc8VgLRCZJHc,44861
1418
1418
  creme/creme_core/tests/forms/test_entity_filter.py,sha256=h0uQjX2tXVlR4N1Ai-r-P6bNrtnpoSyBzWidcgsIyLA,126917
1419
- creme/creme_core/tests/forms/test_enumerable.py,sha256=MnYY2JhR-KZNpJeHhI1edBtNnXJxoBcFY8mFvbviFlA,24071
1419
+ creme/creme_core/tests/forms/test_enumerable.py,sha256=0cXiHIt-DZ6XhGOPK2CxRr1z79x9NQUdpE1ISCyg7nI,30500
1420
1420
  creme/creme_core/tests/forms/test_field_block_manager.py,sha256=iMI3Lmw3SC6E5IsWSKtrvvaRMw50IGzSRndcMKP0cPY,19952
1421
1421
  creme/creme_core/tests/forms/test_fields.py,sha256=OdeabNEav7WGnRGKPaXrblxCZUZX9qula9MfSfr4kOs,67607
1422
1422
  creme/creme_core/tests/forms/test_json_fields.py,sha256=l2QrextXbu0DSvEakaHRZtFuaJ4T8HL4w5x3GqdVmrI,107513
1423
1423
  creme/creme_core/tests/forms/test_listview.py,sha256=rBp0jAsO_FGZQS9GLO5TV5W-etOiWVD3BdytVYdFKxs,51278
1424
1424
  creme/creme_core/tests/forms/test_mass_import.py,sha256=9uqDy-df123Ix_EpanlCzL8w30y3l8D3_oQm8agYXDs,19192
1425
1425
  creme/creme_core/tests/forms/test_validators.py,sha256=DIXAScNc63encmGmfQ8gc22LTBFCZiIFpKvG8En-3to,20340
1426
- creme/creme_core/tests/forms/test_widgets.py,sha256=l-155lXqfdxUt0k2VbPhbfWfj0yEKEo7XvHEXIO32GA,61923
1426
+ creme/creme_core/tests/forms/test_widgets.py,sha256=oQ-58ptQMLmukEa6CpJwMKnocVuJlYYMbXDHcvZG4yA,61981
1427
1427
  creme/creme_core/tests/forms/test_workflows.py,sha256=cROnaQ_mQ5etjq0yeygNgWkHXJ92L0huNHQJ2lRayQk,46980
1428
1428
  creme/creme_core/tests/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1429
1429
  creme/creme_core/tests/gui/test_actions.py,sha256=ywx4S8FJclLfUXqJxCu9BP1hh9RpelPCc4qiWlj98Po,40363
@@ -2706,8 +2706,8 @@ creme/reports/forms/bulk.py,sha256=wKFywtkPCDG--o4kbu6WLIYNPn8Cyiqjie9Y3hvKQ0M,5
2706
2706
  creme/reports/forms/entity_filter.py,sha256=t3FYluAudOcZRDEDoa9FS9XMnIAW23NQenLVnt4XszQ,1142
2707
2707
  creme/reports/forms/graph.py,sha256=2Vc_YeNOtJ332DokrGT_US_TbyTsjYmnyt8nipES4MY,26076
2708
2708
  creme/reports/forms/report.py,sha256=oV2OjZANjjCTD5nBDu5U7x2gcrBSn98dqGbMiRIQ1NM,26186
2709
- creme/reports/locale/fr/LC_MESSAGES/django.mo,sha256=Njfe_BHz9i835eIMsiGCuKYZGiQjdHL1g5eBT29Zuo4,16491
2710
- creme/reports/locale/fr/LC_MESSAGES/django.po,sha256=bMcZyPg6KYPRZP4Uaf6pQSQL8AKUHY_D6XIYKPdl6sY,20588
2709
+ creme/reports/locale/fr/LC_MESSAGES/django.mo,sha256=zQyK7YYEntRTFMm2m3dvJJWY8_iohB7iVfws9Z6CAKI,16590
2710
+ creme/reports/locale/fr/LC_MESSAGES/django.po,sha256=TEJ6Q6b6poyyMfldVqreLd4hAgToUe7RUhCixScJZ9k,20689
2711
2711
  creme/reports/locale/fr/LC_MESSAGES/djangojs.mo,sha256=7nlj4So9k-ErHv0mgk82SpHiBQkKmQmLIQnahmdhbfw,449
2712
2712
  creme/reports/locale/fr/LC_MESSAGES/djangojs.po,sha256=eyCK6yLKRSFPciluW5Ws6DiC7L5f_PatH72jsueWdw4,1220
2713
2713
  creme/reports/migrations/0001_initial.py,sha256=w1cZ4Wk_5e3r2hnE-2dem80HW7fj4odBSaqMc8vGzUo,10570
@@ -2727,7 +2727,7 @@ creme/reports/static/reports/js/tests/reports-actions.js,sha256=TowXAbsTbbbExIkO
2727
2727
  creme/reports/static/reports/js/tests/reports-brick.js,sha256=JocsI4VWwjtGWt8NeHYHVup-MiKhVwNcjrgE_ZGkSCo,19412
2728
2728
  creme/reports/static/reports/js/tests/reports-listview.js,sha256=VPsK_ZfGFVT920L31EGQd8CvegNJngQynbOLHL-I0Ek,9161
2729
2729
  creme/reports/static/reports/js/tests/tube-chart.js,sha256=vkqy56Ub_TQaPT7AdGNi0Oaf8QFqLERzX6B6mpk7G-g,3260
2730
- creme/reports/templates/reports/preview_report.html,sha256=2BqIEIlek4sQy55TPkCQ_fUMTHrKfog3eUEo5LUMavI,1715
2730
+ creme/reports/templates/reports/preview_report.html,sha256=eawDGCNGJdkIjZhwN4-Ph3wQngQqeWypU3YnsP2ppeg,2092
2731
2731
  creme/reports/templates/reports/view_graph.html,sha256=qwlC-eJ0A3MkJOHl8Y1Y5JO3FA49AgrWYHukalUgL8Q,731
2732
2732
  creme/reports/templates/reports/view_report.html,sha256=9Z4NGocyzS-77PajoSlQLBQzSFOwrD1GnlIsoub97FA,53
2733
2733
  creme/reports/templates/reports/bricks/entity-filters.html,sha256=ghr9rUFig1qAjq5_uVDEFyKtX5DNxuVuMNu0neNlQgI,1019
@@ -2736,7 +2736,7 @@ creme/reports/templates/reports/bricks/instance-bricks-info.html,sha256=iBAsw-Pr
2736
2736
  creme/reports/templates/reports/bricks/preview.html,sha256=cRdq80WTwq75eS0YwJ9WQJMQAeqWMWzVO1gaRVgnDN0,1230
2737
2737
  creme/reports/templates/reports/bricks/report-chart-list.html,sha256=sYHI7BLRdl3yBWc5eYXvdOj7ngpn5d2Qp9L7mxl2c34,8115
2738
2738
  creme/reports/templates/reports/bricks/report-chart.html,sha256=sJI8xDi_MNuNUwG4fg_7Hg27kjuBGX_b2AESLiXDWto,4527
2739
- creme/reports/templates/reports/bricks/report-hat-bar.html,sha256=aSNGi0Y5FAB4mA4s7UIi1I5HrXBFtPUUUMmW-4MhVy4,740
2739
+ creme/reports/templates/reports/bricks/report-hat-bar.html,sha256=K0x2Z6NOnomV8eTPRW6lR5yEjsQbbXxvP394P7F8eAg,949
2740
2740
  creme/reports/templates/reports/detail/entity-filter.html,sha256=9Co16RLUYRlSuA21Y2Ep-u4SrGKMv7pVK5LOv1pZKrQ,435
2741
2741
  creme/reports/templates/reports/forms/report-export-filter.html,sha256=QjPyjkvHqS7yIL9h3WwboXOPYACbkB8MHovAowKX4xw,639
2742
2742
  creme/reports/templates/reports/forms/widgets/report-hands/custom-aggregates.html,sha256=ejTaJdmGcX5TFEWdT3BjXFslZC0QHfwdw4m5fjN6Vi4,514
@@ -2757,7 +2757,7 @@ creme/reports/tests/test_entity_filter.py,sha256=Bm2WkW5CeeDAoQh2IOFfoG2K6vdbycK
2757
2757
  creme/reports/tests/test_forms.py,sha256=d7Sz3UfsdFW5GspuABA5DNk_Hl5V3IjW6H32Vq713gc,81698
2758
2758
  creme/reports/tests/test_graph.py,sha256=N2896eLl6baw0lG22LmOCWoxrv0Hs50OgwRgGRcTKnc,133541
2759
2759
  creme/reports/tests/test_registries.py,sha256=_BtYECcKIMxAzFZRxeNBD_lWCgY0xRToVEc5d6HOzg0,4992
2760
- creme/reports/tests/test_report.py,sha256=FvJVJq9r4-bAdF3wNOT4M5Z2IbokcxYlzsWNPg0o23s,142764
2760
+ creme/reports/tests/test_report.py,sha256=BAfyEUQgG1Rl2dulsiwqCr11-pcg03_dDblxG_E9mJE,143971
2761
2761
  creme/reports/tests/test_templatetags.py,sha256=Sr0eNuqB2zSwcFZKIj-vEhOXKwMznL1VxDYhv0a6w-Q,3395
2762
2762
  creme/reports/tests/test_utils.py,sha256=3ImrZueMK-xqgXHjlui-zMvQjMQFcwWcX7E27aI6RHc,2512
2763
2763
  creme/reports/tests/test_views.py,sha256=v_PlsSXSMc9RkhWxXY9-s4aIWHoIQSgLVkWWm0leF2U,6333
@@ -2771,7 +2771,7 @@ creme/reports/tests/core/graph/test_hand.py,sha256=LJb6nVwWVK5-49DvBjNnHQ6I6xL1s
2771
2771
  creme/reports/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2772
2772
  creme/reports/views/bricks.py,sha256=MdeUZKFAJaRmb_Sk-Py-ojh1fUgMw6fCjEeJwca8x3Q,2442
2773
2773
  creme/reports/views/entity_filter.py,sha256=4cF2stqj-fQuFs2lvrGUyCeVc5d8Lb5Ua6J6zMT1fYE,2514
2774
- creme/reports/views/export.py,sha256=Ygmgw44lQbDHQ9Z3VKTzWcfMSzg4B4GOdgu3nyaWM8M,5707
2774
+ creme/reports/views/export.py,sha256=eCM29j8nFEXxc-zGgLnWjW-ZJhP7gcD4yzQAQ7xABDQ,5757
2775
2775
  creme/reports/views/graph.py,sha256=0VUTaTAJUOx0LXlPg5mBO2kHOFyL_x9RyiZmNUbpcDI,5581
2776
2776
  creme/reports/views/report.py,sha256=UoZHXekGWWb77Oj1g8TsmXpVf6vmgQY7J6cMjBkNNr4,7853
2777
2777
  creme/sketch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -3822,7 +3822,7 @@ creme/vcfs/vcf_lib/utils.py,sha256=rofX2grUVZLg1qSYrvVLQe832rX9QDDqjqSfq9_rpnA,2
3822
3822
  creme/vcfs/vcf_lib/vcard.py,sha256=EIDdegf8HC5f4j19tfJYQ1NKc_-NZO8NaYinpVwj7vQ,8275
3823
3823
  creme/vcfs/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3824
3824
  creme/vcfs/views/vcf.py,sha256=7rsRCL7U0cgwtYghN6yAAbNN_e5lJVGrLH5IpSOIPYI,3795
3825
- creme_crm-2.7.3.dist-info/licenses/LICENSE.txt,sha256=fvS1_rSUtxH8CO9sMpw9BQFU3nLMK6ssGpyZU6ZVPMU,1130
3825
+ creme_crm-2.7.4.dist-info/licenses/LICENSE.txt,sha256=fvS1_rSUtxH8CO9sMpw9BQFU3nLMK6ssGpyZU6ZVPMU,1130
3826
3826
  mediagenerator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3827
3827
  mediagenerator/api.py,sha256=58FqOcH2NCJVdtKN_MxyW3xydWAYPBexTDa2LQTaMsY,1883
3828
3828
  mediagenerator/base.py,sha256=2zr8DCnL48UgVM1M9LILuHTgT_xvKLMSwVnzGa47zCc,1003
@@ -3853,8 +3853,8 @@ mediagenerator/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQe
3853
3853
  mediagenerator/management/commands/generatemedia.py,sha256=3-uIk3h83F16n2z7vG_xBteWiq7JWoB7d0vWSxVn-po,328
3854
3854
  mediagenerator/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3855
3855
  mediagenerator/templatetags/media.py,sha256=6EeohgP8srqzNRxgGr47BARO6Vx4AMn_dQuHwEQnnHE,1495
3856
- creme_crm-2.7.3.dist-info/METADATA,sha256=bcUWfaNRkn8zw4wyk59NyGjMJlPWumq058ScgddGsLk,12232
3857
- creme_crm-2.7.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
3858
- creme_crm-2.7.3.dist-info/entry_points.txt,sha256=GWm5VHgyz1DROd4UbhrelZ8d581uQNOtbjPz2TWfi_A,47
3859
- creme_crm-2.7.3.dist-info/top_level.txt,sha256=y_WAe0QGma0mhzRFEOIVJsB-xJrvhHV6MEk862EMweA,21
3860
- creme_crm-2.7.3.dist-info/RECORD,,
3856
+ creme_crm-2.7.4.dist-info/METADATA,sha256=PW3EMhddVcgAKsxeoyWs2UpfbK69YCSRgJdEaWEaWTY,12233
3857
+ creme_crm-2.7.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
3858
+ creme_crm-2.7.4.dist-info/entry_points.txt,sha256=GWm5VHgyz1DROd4UbhrelZ8d581uQNOtbjPz2TWfi_A,47
3859
+ creme_crm-2.7.4.dist-info/top_level.txt,sha256=y_WAe0QGma0mhzRFEOIVJsB-xJrvhHV6MEk862EMweA,21
3860
+ creme_crm-2.7.4.dist-info/RECORD,,