summaryrefslogtreecommitdiff
path: root/ishtar_common
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common')
-rw-r--r--ishtar_common/data_importer.py9
-rw-r--r--ishtar_common/locale/django.pot742
-rw-r--r--ishtar_common/models.py30
-rw-r--r--ishtar_common/templates/blocks/JQueryJqGrid.html19
-rw-r--r--ishtar_common/templates/ishtar/blocks/advanced_shortcut_menu.html2
-rw-r--r--ishtar_common/templates/ishtar/blocks/shortcut_menu.html2
-rw-r--r--ishtar_common/templates/ishtar/wizard/validation_bar.html8
-rw-r--r--ishtar_common/tests.py66
-rw-r--r--ishtar_common/utils.py20
-rw-r--r--ishtar_common/views.py51
-rw-r--r--ishtar_common/wizards.py92
11 files changed, 583 insertions, 458 deletions
diff --git a/ishtar_common/data_importer.py b/ishtar_common/data_importer.py
index 426d32a7a..34394341c 100644
--- a/ishtar_common/data_importer.py
+++ b/ishtar_common/data_importer.py
@@ -450,10 +450,11 @@ class TypeFormater(StrChoiceFormater):
self.match_table = {}
self.new_keys = {}
self.import_instance = import_instance
- for item in model.objects.all():
- self.choices.append((item.pk, unicode(item)))
- for key in item.get_keys(importer_id=import_instance.pk):
- self.equiv_dict[key] = item
+ if self.import_instance:
+ for item in model.objects.all():
+ self.choices.append((item.pk, unicode(item)))
+ for key in item.get_keys(importer_id=import_instance.pk):
+ self.equiv_dict[key] = item
def prepare(self, value):
return slugify(unicode(value).strip())
diff --git a/ishtar_common/locale/django.pot b/ishtar_common/locale/django.pot
index 7efeabbef..207642972 100644
--- a/ishtar_common/locale/django.pot
+++ b/ishtar_common/locale/django.pot
@@ -25,121 +25,125 @@ msgstr ""
msgid "Export selected as CSV file"
msgstr ""
-#: data_importer.py:183
+#: data_importer.py:186
#, python-format
msgid "\"%(value)s\" is too long. The max length is %(length)d characters."
msgstr ""
-#: data_importer.py:200
+#: data_importer.py:203
#, python-format
msgid "\"%(value)s\" not equal to yes or no"
msgstr ""
-#: data_importer.py:212
+#: data_importer.py:215
#, python-format
msgid "\"%(value)s\" is not a float"
msgstr ""
-#: data_importer.py:225 data_importer.py:239 data_importer.py:483
+#: data_importer.py:228 data_importer.py:242 data_importer.py:495
#, python-format
msgid "\"%(value)s\" is not a valid date"
msgstr ""
-#: data_importer.py:252
+#: data_importer.py:255
#, python-format
msgid "\"%(value)s\" is not an integer"
msgstr ""
-#: data_importer.py:303 data_importer.py:546
+#: data_importer.py:312 data_importer.py:560
#, python-format
msgid "Choice for \"%s\" is not available. Which one is relevant?\n"
msgstr ""
-#: data_importer.py:310
+#: data_importer.py:319
#, python-format
msgid "%d. None of the above - create new"
msgstr ""
-#: data_importer.py:313
+#: data_importer.py:322
#, python-format
msgid "%d. None of the above - skip"
msgstr ""
-#: data_importer.py:509
+#: data_importer.py:521
#, python-format
msgid "\"%(value)s\" is not a valid path for the given archive"
msgstr ""
-#: data_importer.py:623
+#: data_importer.py:637
msgid ""
"The given file is not correct. Check the file format. If you use a CSV file: "
"check that column separator and encoding are similar to the ones used by the "
"reference file."
msgstr ""
-#: data_importer.py:627
+#: data_importer.py:641
#, python-format
msgid "Too many cols (%(user_col)d) when maximum is %(ref_col)d"
msgstr ""
-#: data_importer.py:629
+#: data_importer.py:643
msgid "No data provided"
msgstr ""
-#: data_importer.py:630
+#: data_importer.py:644
msgid "Value is required"
msgstr ""
-#: data_importer.py:631
+#: data_importer.py:645
#, python-format
msgid "At least %d columns must be filled"
msgstr ""
-#: data_importer.py:632
+#: data_importer.py:646
msgid "The regexp doesn't match."
msgstr ""
-#: data_importer.py:634
+#: data_importer.py:648
msgid ""
"Forced creation is set for model {} but this model is not in the list of "
"models allowed to be created."
msgstr ""
-#: data_importer.py:636
+#: data_importer.py:650
msgid ""
"{} with values {} doesn't exist in the database. Create it first or fix your "
"source file."
msgstr ""
-#: data_importer.py:1089
+#: data_importer.py:1103
msgid "Not imported"
msgstr ""
-#: data_importer.py:1522
+#: data_importer.py:1240
+msgid "Importer configuration error: field \"{}\" does not exist for {}."
+msgstr ""
+
+#: data_importer.py:1548
msgid "line"
msgstr ""
-#: data_importer.py:1522
+#: data_importer.py:1548
msgid "col"
msgstr ""
-#: data_importer.py:1522
+#: data_importer.py:1548
msgid "error"
msgstr ""
-#: data_importer.py:1528
+#: data_importer.py:1554
msgid "field"
msgstr ""
-#: data_importer.py:1528
+#: data_importer.py:1554
msgid "source"
msgstr ""
-#: data_importer.py:1528
+#: data_importer.py:1554
msgid "result"
msgstr ""
-#: data_importer.py:1544
+#: data_importer.py:1570
#, python-format
msgid "\"%(value)s\" not in %(values)s"
msgstr ""
@@ -148,7 +152,7 @@ msgstr ""
msgid "Enter a valid name consisting of letters, spaces and hyphens."
msgstr ""
-#: forms.py:89 forms_common.py:618
+#: forms.py:89 forms_common.py:626
msgid "Confirm"
msgstr ""
@@ -172,12 +176,12 @@ msgstr ""
msgid "Add a new item"
msgstr ""
-#: forms.py:262 models.py:1475
+#: forms.py:262 models.py:1482
msgid "Template"
msgstr ""
-#: forms_common.py:41 forms_common.py:59 forms_common.py:182
-#: forms_common.py:406 models.py:1541 models.py:2953
+#: forms_common.py:41 forms_common.py:59 forms_common.py:184
+#: forms_common.py:408 models.py:1548 models.py:2977
#: templates/blocks/JQueryAdvancedTown.html:19
#: templates/ishtar/sheet_organization.html:13
msgid "Town"
@@ -193,8 +197,8 @@ msgid ""
"french town Saint-Denis in the Seine-Saint-Denis department.</p>"
msgstr ""
-#: forms_common.py:68 forms_common.py:855 ishtar_menu.py:47 models.py:2577
-#: models.py:2759 models.py:2821 templates/ishtar/sheet_person.html:4
+#: forms_common.py:68 forms_common.py:863 ishtar_menu.py:47 models.py:2599
+#: models.py:2781 models.py:2845 templates/ishtar/sheet_person.html:4
msgid "Person"
msgstr ""
@@ -204,64 +208,64 @@ msgid ""
"possible."
msgstr ""
-#: forms_common.py:170 forms_common.py:327 forms_common.py:451
-#: ishtar_menu.py:75 models.py:2460 models.py:2551
+#: forms_common.py:172 forms_common.py:329 forms_common.py:453
+#: ishtar_menu.py:75 models.py:2482 models.py:2573
#: templates/ishtar/sheet_organization.html:4
msgid "Organization"
msgstr ""
-#: forms_common.py:173 forms_common.py:210 forms_common.py:322
-#: forms_common.py:376 forms_common.py:446 models.py:1096 models.py:1474
-#: models.py:1742 models.py:1758 models.py:1984 models.py:2454 models.py:2563
-#: models.py:2939 templates/ishtar/sheet_organization.html:8
+#: forms_common.py:175 forms_common.py:212 forms_common.py:324
+#: forms_common.py:378 forms_common.py:448 models.py:1103 models.py:1481
+#: models.py:1749 models.py:1765 models.py:1993 models.py:2476 models.py:2585
+#: models.py:2963 templates/ishtar/sheet_organization.html:8
#: templates/ishtar/sheet_organization.html:21
msgid "Name"
msgstr ""
-#: forms_common.py:174 models.py:1696 models.py:2115
+#: forms_common.py:176 models.py:1703 models.py:2124
msgid "Organization type"
msgstr ""
-#: forms_common.py:176 forms_common.py:400 models.py:1536
+#: forms_common.py:178 forms_common.py:402 models.py:1543
#: templates/ishtar/sheet_organization.html:10
msgid "Address"
msgstr ""
-#: forms_common.py:178 forms_common.py:403 models.py:1537
+#: forms_common.py:180 forms_common.py:405 models.py:1544
#: templates/ishtar/sheet_organization.html:11
msgid "Address complement"
msgstr ""
-#: forms_common.py:180 forms_common.py:404 models.py:1539
+#: forms_common.py:182 forms_common.py:406 models.py:1546
#: templates/ishtar/sheet_organization.html:12
msgid "Postal code"
msgstr ""
-#: forms_common.py:183 forms_common.py:407 models.py:1542
+#: forms_common.py:185 forms_common.py:409 models.py:1549
msgid "Country"
msgstr ""
-#: forms_common.py:185 forms_common.py:324 forms_common.py:380
-#: forms_common.py:448 forms_common.py:572 models.py:1569
+#: forms_common.py:187 forms_common.py:326 forms_common.py:382
+#: forms_common.py:450 forms_common.py:574 models.py:1576
msgid "Email"
msgstr ""
-#: forms_common.py:186 forms_common.py:383 models.py:1554
+#: forms_common.py:188 forms_common.py:385 models.py:1561
#: templates/ishtar/sheet_organization.html:14
#: templates/ishtar/sheet_person.html:19
#: templates/ishtar/wizard/wizard_person.html:17
msgid "Phone"
msgstr ""
-#: forms_common.py:187 forms_common.py:392 models.py:1566
+#: forms_common.py:189 forms_common.py:394 models.py:1573
#: templates/ishtar/sheet_organization.html:15
#: templates/ishtar/sheet_person.html:37
#: templates/ishtar/wizard/wizard_person.html:35
msgid "Mobile phone"
msgstr ""
-#: forms_common.py:211 forms_common.py:325 forms_common.py:449 models.py:2151
-#: models.py:2456 models.py:2874 templates/sheet_ope.html:85
+#: forms_common.py:213 forms_common.py:327 forms_common.py:451 models.py:2160
+#: models.py:2478 models.py:2898 templates/sheet_ope.html:85
#: templates/sheet_ope.html.py:105 templates/sheet_ope.html:126
#: templates/ishtar/import_list.html:13
#: templates/ishtar/sheet_organization.html:23
@@ -269,241 +273,241 @@ msgstr ""
msgid "Type"
msgstr ""
-#: forms_common.py:220 views.py:146
+#: forms_common.py:222 views.py:147
msgid "Organization search"
msgstr ""
-#: forms_common.py:244
+#: forms_common.py:246
msgid "At least two items have to be selected."
msgstr ""
-#: forms_common.py:262
+#: forms_common.py:264
msgid "Merge all items into"
msgstr ""
-#: forms_common.py:296
+#: forms_common.py:298
msgid "Organization to merge"
msgstr ""
-#: forms_common.py:323 forms_common.py:374 forms_common.py:447 models.py:2561
+#: forms_common.py:325 forms_common.py:376 forms_common.py:449 models.py:2583
#: templates/ishtar/sheet_organization.html:22
msgid "Surname"
msgstr ""
-#: forms_common.py:339 forms_common.py:434 views.py:111
+#: forms_common.py:341 forms_common.py:436 views.py:112
msgid "Person search"
msgstr ""
-#: forms_common.py:351
+#: forms_common.py:353
msgid "Person to merge"
msgstr ""
-#: forms_common.py:368 templates/ishtar/sheet_person.html:7
+#: forms_common.py:370 templates/ishtar/sheet_person.html:7
#: templates/ishtar/wizard/wizard_person.html:6
msgid "Identity"
msgstr ""
-#: forms_common.py:371 forms_common.py:773 forms_common.py:822 models.py:2116
-#: models.py:2555 models.py:2557 models.py:2871 templates/sheet_ope.html:104
+#: forms_common.py:373 forms_common.py:781 forms_common.py:830 models.py:2125
+#: models.py:2577 models.py:2579 models.py:2895 templates/sheet_ope.html:104
#: templates/ishtar/blocks/window_tables/documents.html:7
msgid "Title"
msgstr ""
-#: forms_common.py:372 models.py:2559
+#: forms_common.py:374 models.py:2581
msgid "Salutation"
msgstr ""
-#: forms_common.py:378 models.py:2565
+#: forms_common.py:380 models.py:2587
msgid "Raw name"
msgstr ""
-#: forms_common.py:381 models.py:1555
+#: forms_common.py:383 models.py:1562
msgid "Phone description"
msgstr ""
-#: forms_common.py:384 models.py:1557 models.py:1559
+#: forms_common.py:386 models.py:1564 models.py:1566
msgid "Phone description 2"
msgstr ""
-#: forms_common.py:386
+#: forms_common.py:388
msgid "Phone 2"
msgstr ""
-#: forms_common.py:388 models.py:1563
+#: forms_common.py:390 models.py:1570
msgid "Phone description 3"
msgstr ""
-#: forms_common.py:390 models.py:1561
+#: forms_common.py:392 models.py:1568
msgid "Phone 3"
msgstr ""
-#: forms_common.py:395
+#: forms_common.py:397
msgid "Current organization"
msgstr ""
-#: forms_common.py:409 models.py:1544
+#: forms_common.py:411 models.py:1551
msgid "Other address: address"
msgstr ""
-#: forms_common.py:412 models.py:1547
+#: forms_common.py:414 models.py:1554
msgid "Other address: address complement"
msgstr ""
-#: forms_common.py:414 models.py:1548
+#: forms_common.py:416 models.py:1555
msgid "Other address: postal code"
msgstr ""
-#: forms_common.py:416 models.py:1550
+#: forms_common.py:418 models.py:1557
msgid "Other address: town"
msgstr ""
-#: forms_common.py:418 models.py:1552
+#: forms_common.py:420 models.py:1559
msgid "Other address: country"
msgstr ""
-#: forms_common.py:430
+#: forms_common.py:432
msgid "Already has an account"
msgstr ""
-#: forms_common.py:445
+#: forms_common.py:447
msgid "Username"
msgstr ""
-#: forms_common.py:463
+#: forms_common.py:465
msgid "Account search"
msgstr ""
-#: forms_common.py:510 forms_common.py:550 forms_common.py:554 models.py:2508
+#: forms_common.py:512 forms_common.py:552 forms_common.py:556 models.py:2530
msgid "Person type"
msgstr ""
-#: forms_common.py:566 forms_common.py:571 ishtar_menu.py:32
+#: forms_common.py:568 forms_common.py:573 ishtar_menu.py:32
msgid "Account"
msgstr ""
-#: forms_common.py:575 wizards.py:1281
+#: forms_common.py:577 wizards.py:1305
msgid "New password"
msgstr ""
-#: forms_common.py:578
+#: forms_common.py:580
msgid "New password (confirmation)"
msgstr ""
-#: forms_common.py:599
+#: forms_common.py:607
msgid "Your password and confirmation password do not match."
msgstr ""
-#: forms_common.py:604
+#: forms_common.py:612
msgid "You must provide a correct password."
msgstr ""
-#: forms_common.py:612
+#: forms_common.py:620
msgid "This username already exists."
msgstr ""
-#: forms_common.py:619
+#: forms_common.py:627
msgid "Send the new password by email?"
msgstr ""
-#: forms_common.py:628 forms_common.py:641 models.py:2954
+#: forms_common.py:636 forms_common.py:649 models.py:2978
msgid "Towns"
msgstr ""
-#: forms_common.py:638
+#: forms_common.py:646
msgid "There are identical towns."
msgstr ""
-#: forms_common.py:722
+#: forms_common.py:730
msgid "Only one choice can be checked."
msgstr ""
-#: forms_common.py:770
+#: forms_common.py:778
msgid "Documentation informations"
msgstr ""
-#: forms_common.py:775 forms_common.py:823 models.py:2117 models.py:2846
+#: forms_common.py:783 forms_common.py:831 models.py:2126 models.py:2870
msgid "Source type"
msgstr ""
-#: forms_common.py:777 forms_common.py:824 templates/sheet_ope.html:84
+#: forms_common.py:785 forms_common.py:832 templates/sheet_ope.html:84
msgid "Reference"
msgstr ""
-#: forms_common.py:780 forms_common.py:825
+#: forms_common.py:788 forms_common.py:833
msgid "Internal reference"
msgstr ""
-#: forms_common.py:783 models.py:2885
+#: forms_common.py:791 models.py:2909
msgid "Numerical ressource (web address)"
msgstr ""
-#: forms_common.py:784 models.py:2887
+#: forms_common.py:792 models.py:2911
msgid "Receipt date"
msgstr ""
-#: forms_common.py:786 models.py:2283 models.py:2889
+#: forms_common.py:794 models.py:2292 models.py:2913
msgid "Creation date"
msgstr ""
-#: forms_common.py:789 models.py:2892
+#: forms_common.py:797 models.py:2916
msgid "Receipt date in documentation"
msgstr ""
-#: forms_common.py:791 forms_common.py:827 models.py:377 models.py:689
-#: models.py:2011 models.py:2569 models.py:2899
+#: forms_common.py:799 forms_common.py:835 models.py:379 models.py:696
+#: models.py:2020 models.py:2591 models.py:2923
msgid "Comment"
msgstr ""
-#: forms_common.py:793 forms_common.py:826 models.py:1098 models.py:1762
-#: models.py:1943 models.py:1985 models.py:2898 templates/sheet_ope.html:128
+#: forms_common.py:801 forms_common.py:834 models.py:1105 models.py:1769
+#: models.py:1952 models.py:1994 models.py:2922 templates/sheet_ope.html:128
msgid "Description"
msgstr ""
-#: forms_common.py:796 models.py:2900
+#: forms_common.py:804 models.py:2924
msgid "Additional information"
msgstr ""
-#: forms_common.py:798 forms_common.py:830 models.py:2902
+#: forms_common.py:806 forms_common.py:838 models.py:2926
msgid "Has a duplicate"
msgstr ""
-#: forms_common.py:801
+#: forms_common.py:809
msgid "Image"
msgstr ""
-#: forms_common.py:802
+#: forms_common.py:810
#, python-format
msgid ""
"<p>Heavy images are resized to: %(width)dx%(height)d (ratio is preserved).</"
"p>"
msgstr ""
-#: forms_common.py:819 forms_common.py:848 forms_common.py:882 models.py:2826
+#: forms_common.py:827 forms_common.py:856 forms_common.py:890 models.py:2850
#: templates/ishtar/wizard/wizard_person_deletion.html:124
msgid "Author"
msgstr ""
-#: forms_common.py:829
+#: forms_common.py:837
msgid "Additional informations"
msgstr ""
-#: forms_common.py:840
+#: forms_common.py:848
msgid "Would you like to delete this documentation?"
msgstr ""
-#: forms_common.py:856 models.py:2118 models.py:2813 models.py:2823
+#: forms_common.py:864 models.py:2127 models.py:2837 models.py:2847
msgid "Author type"
msgstr ""
-#: forms_common.py:875
+#: forms_common.py:883
msgid "Author selection"
msgstr ""
-#: forms_common.py:889
+#: forms_common.py:897
msgid "There are identical authors."
msgstr ""
-#: forms_common.py:893 models.py:2827 models.py:2881
+#: forms_common.py:901 models.py:2851 models.py:2905
#: templates/sheet_ope.html:106
#: templates/ishtar/blocks/window_tables/documents.html:9
msgid "Authors"
@@ -521,7 +525,7 @@ msgstr ""
msgid "Deletion"
msgstr ""
-#: ishtar_menu.py:39 models.py:1270 views.py:1549
+#: ishtar_menu.py:39 models.py:1277 views.py:1574
msgid "Global variables"
msgstr ""
@@ -549,278 +553,278 @@ msgstr ""
msgid "Manual merge"
msgstr ""
-#: ishtar_menu.py:109 models.py:2294
+#: ishtar_menu.py:109 models.py:2303
msgid "Imports"
msgstr ""
-#: ishtar_menu.py:112 views.py:1557
+#: ishtar_menu.py:112 views.py:1582
msgid "New import"
msgstr ""
-#: ishtar_menu.py:116 views.py:1571
+#: ishtar_menu.py:116 views.py:1596
msgid "Current imports"
msgstr ""
-#: ishtar_menu.py:120 views.py:1607
+#: ishtar_menu.py:120 views.py:1632
msgid "Old imports"
msgstr ""
-#: models.py:184
+#: models.py:186
msgid "Not a valid item."
msgstr ""
-#: models.py:197
+#: models.py:199
msgid "A selected item is not a valid item."
msgstr ""
-#: models.py:208
+#: models.py:210
msgid "This item already exists."
msgstr ""
-#: models.py:373 models.py:688 models.py:1509 models.py:1521 models.py:1940
+#: models.py:375 models.py:695 models.py:1516 models.py:1528 models.py:1949
msgid "Label"
msgstr ""
-#: models.py:375
+#: models.py:377
msgid "Textual ID"
msgstr ""
-#: models.py:378 models.py:691 models.py:1478
+#: models.py:380 models.py:698 models.py:1485
msgid "Available"
msgstr ""
-#: models.py:715 models.py:2057
+#: models.py:722 models.py:2066
msgid "Key"
msgstr ""
-#: models.py:721
+#: models.py:728
msgid "Specific key to an import"
msgstr ""
-#: models.py:813
+#: models.py:820
msgid "Last editor"
msgstr ""
-#: models.py:816
+#: models.py:823
msgid "Creator"
msgstr ""
-#: models.py:958 models.py:2965 models.py:3021
+#: models.py:965 models.py:2989 models.py:3045
msgid "Order"
msgstr ""
-#: models.py:959
+#: models.py:966
msgid "Symmetrical"
msgstr ""
-#: models.py:960
+#: models.py:967
msgid "Tiny label"
msgstr ""
-#: models.py:974
+#: models.py:981
msgid "Cannot have symmetrical and an inverse_relation"
msgstr ""
-#: models.py:1090
+#: models.py:1097
msgid "Euro"
msgstr ""
-#: models.py:1091
+#: models.py:1098
msgid "US dollar"
msgstr ""
-#: models.py:1097 models.py:1760
+#: models.py:1104 models.py:1767
msgid "Slug"
msgstr ""
-#: models.py:1100
+#: models.py:1107
msgid "CSS color code for base module"
msgstr ""
-#: models.py:1102
+#: models.py:1109
msgid "Files module"
msgstr ""
-#: models.py:1104
+#: models.py:1111
msgid "CSS color code for files module"
msgstr ""
-#: models.py:1106
+#: models.py:1113
msgid "Context records module"
msgstr ""
-#: models.py:1109
+#: models.py:1116
msgid "CSS color code for context record module"
msgstr ""
-#: models.py:1111
+#: models.py:1118
msgid "Finds module"
msgstr ""
-#: models.py:1112
+#: models.py:1119
msgid "Need context records module"
msgstr ""
-#: models.py:1114
+#: models.py:1121
msgid "CSS color code for find module"
msgstr ""
-#: models.py:1117
+#: models.py:1124
msgid "Warehouses module"
msgstr ""
-#: models.py:1118
+#: models.py:1125
msgid "Need finds module"
msgstr ""
-#: models.py:1120
+#: models.py:1127
msgid "CSS code for warehouse module"
msgstr ""
-#: models.py:1122
+#: models.py:1129
msgid "Mapping module"
msgstr ""
-#: models.py:1124
+#: models.py:1131
msgid "CSS code for mapping module"
msgstr ""
-#: models.py:1127
+#: models.py:1134
msgid "Home page"
msgstr ""
-#: models.py:1128
+#: models.py:1135
#, python-brace-format
msgid ""
"Homepage of Ishtar - if not defined a default homepage will appear. Use the "
"markdown syntax. {random_image} can be used to display a random image."
msgstr ""
-#: models.py:1132
+#: models.py:1139
msgid "File external id"
msgstr ""
-#: models.py:1134
+#: models.py:1141
msgid ""
"Formula to manage file external ID. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
"be destructive."
msgstr ""
-#: models.py:1139
+#: models.py:1146
msgid "Parcel external id"
msgstr ""
-#: models.py:1142
+#: models.py:1149
msgid ""
"Formula to manage parcel external ID. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
"be destructive."
msgstr ""
-#: models.py:1147
+#: models.py:1154
msgid "Context record external id"
msgstr ""
-#: models.py:1149
+#: models.py:1156
msgid ""
"Formula to manage context record external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
"data can be destructive."
msgstr ""
-#: models.py:1154
+#: models.py:1161
msgid "Base find external id"
msgstr ""
-#: models.py:1156
+#: models.py:1163
msgid ""
"Formula to manage base find external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
"data can be destructive."
msgstr ""
-#: models.py:1161
+#: models.py:1168
msgid "Find external id"
msgstr ""
-#: models.py:1163
+#: models.py:1170
msgid ""
"Formula to manage find external ID. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
"be destructive."
msgstr ""
-#: models.py:1168
+#: models.py:1175
msgid "Container external id"
msgstr ""
-#: models.py:1170
+#: models.py:1177
msgid ""
"Formula to manage container external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
"data can be destructive."
msgstr ""
-#: models.py:1175
+#: models.py:1182
msgid "Warehouse external id"
msgstr ""
-#: models.py:1177
+#: models.py:1184
msgid ""
"Formula to manage warehouse external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
"data can be destructive."
msgstr ""
-#: models.py:1182
+#: models.py:1189
msgid "Raw name for person"
msgstr ""
-#: models.py:1184
+#: models.py:1191
msgid ""
"Formula to manage person raw_name. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
"be destructive."
msgstr ""
-#: models.py:1188
+#: models.py:1195
msgid "Current active"
msgstr ""
-#: models.py:1189
+#: models.py:1196
msgid "Currency"
msgstr ""
-#: models.py:1193
+#: models.py:1200
msgid "Ishtar site profile"
msgstr ""
-#: models.py:1194
+#: models.py:1201
msgid "Ishtar site profiles"
msgstr ""
-#: models.py:1263
+#: models.py:1270
msgid "Variable name"
msgstr ""
-#: models.py:1264
+#: models.py:1271
msgid "Description of the variable"
msgstr ""
-#: models.py:1266 models.py:2058
+#: models.py:1273 models.py:2067
msgid "Value"
msgstr ""
-#: models.py:1269
+#: models.py:1276
msgid "Global variable"
msgstr ""
-#: models.py:1379 models.py:1409
+#: models.py:1386 models.py:1416
msgid "Total"
msgstr ""
-#: models.py:1386 models.py:1510 models.py:1522
+#: models.py:1393 models.py:1517 models.py:1529
#: templates/ishtar/sheet_person.html:22
#: templates/ishtar/dashboards/dashboard_main_detail.html:141
#: templates/ishtar/dashboards/dashboard_main_detail_users.html:26
@@ -828,750 +832,750 @@ msgstr ""
msgid "Number"
msgstr ""
-#: models.py:1473
+#: models.py:1480
msgid "Administrative Act"
msgstr ""
-#: models.py:1477
+#: models.py:1484
msgid "Associated object"
msgstr ""
-#: models.py:1481
+#: models.py:1488
msgid "Document template"
msgstr ""
-#: models.py:1482
+#: models.py:1489
msgid "Document templates"
msgstr ""
-#: models.py:1513 models.py:1523 models.py:2278
+#: models.py:1520 models.py:1530 models.py:2287
msgid "State"
msgstr ""
-#: models.py:1527 templates/blocks/JQueryAdvancedTown.html:12
+#: models.py:1534 templates/blocks/JQueryAdvancedTown.html:12
msgid "Department"
msgstr ""
-#: models.py:1528
+#: models.py:1535
msgid "Departments"
msgstr ""
-#: models.py:1565
+#: models.py:1572
msgid "Raw phone"
msgstr ""
-#: models.py:1571
+#: models.py:1578
msgid "Alternative address is prefered"
msgstr ""
-#: models.py:1610
+#: models.py:1617
msgid "Tel: "
msgstr ""
-#: models.py:1614
+#: models.py:1621
msgid "Mobile: "
msgstr ""
-#: models.py:1618
+#: models.py:1625
msgid "Email: "
msgstr ""
-#: models.py:1623
+#: models.py:1630
msgid "Merge key"
msgstr ""
-#: models.py:1697
+#: models.py:1704
msgid "Organization types"
msgstr ""
-#: models.py:1743
+#: models.py:1750
msgid "Class name"
msgstr ""
-#: models.py:1746
+#: models.py:1753
msgid "Importer - Model"
msgstr ""
-#: models.py:1747
+#: models.py:1754
msgid "Importer - Models"
msgstr ""
-#: models.py:1764 templates/ishtar/dashboards/dashboard_main.html:25
+#: models.py:1771 templates/ishtar/dashboards/dashboard_main.html:25
msgid "Users"
msgstr ""
-#: models.py:1767
+#: models.py:1774
msgid "Associated model"
msgstr ""
-#: models.py:1770
+#: models.py:1777
msgid "Models that can accept new items"
msgstr ""
-#: models.py:1771
+#: models.py:1778
msgid "Leave blank for no restrictions"
msgstr ""
-#: models.py:1773
+#: models.py:1780
msgid "Is template"
msgstr ""
-#: models.py:1774
+#: models.py:1781
msgid "Unicity keys (separator \";\")"
msgstr ""
-#: models.py:1778
+#: models.py:1785
msgid "Importer - Type"
msgstr ""
-#: models.py:1779
+#: models.py:1786
msgid "Importer - Types"
msgstr ""
-#: models.py:1872
+#: models.py:1881
msgid "Importer - Default"
msgstr ""
-#: models.py:1873
+#: models.py:1882
msgid "Importer - Defaults"
msgstr ""
-#: models.py:1908
+#: models.py:1917
msgid "Importer - Default value"
msgstr ""
-#: models.py:1909
+#: models.py:1918
msgid "Importer - Default values"
msgstr ""
-#: models.py:1942
+#: models.py:1951
msgid "Column number"
msgstr ""
-#: models.py:1945
+#: models.py:1954
msgid "Required"
msgstr ""
-#: models.py:1948
+#: models.py:1957
msgid "Importer - Column"
msgstr ""
-#: models.py:1949
+#: models.py:1958
msgid "Importer - Columns"
msgstr ""
-#: models.py:1969
+#: models.py:1978
msgid "Field name"
msgstr ""
-#: models.py:1971 models.py:2005
+#: models.py:1980 models.py:2014
msgid "Force creation of new items"
msgstr ""
-#: models.py:1973 models.py:2007
+#: models.py:1982 models.py:2016
msgid "Concatenate with existing"
msgstr ""
-#: models.py:1975 models.py:2009
+#: models.py:1984 models.py:2018
msgid "Concatenate character"
msgstr ""
-#: models.py:1979
+#: models.py:1988
msgid "Importer - Duplicate field"
msgstr ""
-#: models.py:1980
+#: models.py:1989
msgid "Importer - Duplicate fields"
msgstr ""
-#: models.py:1987
+#: models.py:1996
msgid "Regular expression"
msgstr ""
-#: models.py:1990
+#: models.py:1999
msgid "Importer - Regular expression"
msgstr ""
-#: models.py:1991
+#: models.py:2000
msgid "Importer - Regular expressions"
msgstr ""
-#: models.py:2014
+#: models.py:2023
msgid "Importer - Target"
msgstr ""
-#: models.py:2015
+#: models.py:2024
msgid "Importer - Targets"
msgstr ""
-#: models.py:2039 views.py:545
+#: models.py:2048 views.py:549
msgid "True"
msgstr ""
-#: models.py:2040 views.py:547
+#: models.py:2049 views.py:551
msgid "False"
msgstr ""
-#: models.py:2059
+#: models.py:2068
msgid "Is set"
msgstr ""
-#: models.py:2066
+#: models.py:2075
msgid "Importer - Target key"
msgstr ""
-#: models.py:2067
+#: models.py:2076
msgid "Importer - Targets keys"
msgstr ""
-#: models.py:2119 models.py:2877
+#: models.py:2128 models.py:2901
msgid "Format"
msgstr ""
-#: models.py:2120 models.py:2969
+#: models.py:2129 models.py:2993
msgid "Operation type"
msgstr ""
-#: models.py:2121
+#: models.py:2130
msgid "Period"
msgstr ""
-#: models.py:2122
+#: models.py:2131
msgid "Report state"
msgstr ""
-#: models.py:2123
+#: models.py:2132
msgid "Remain type"
msgstr ""
-#: models.py:2124
+#: models.py:2133
msgid "Unit"
msgstr ""
-#: models.py:2125
+#: models.py:2134
msgid "Activity type"
msgstr ""
-#: models.py:2126
+#: models.py:2135
msgid "Material"
msgstr ""
-#: models.py:2128
+#: models.py:2137
msgid "Conservatory state"
msgstr ""
-#: models.py:2129
+#: models.py:2138
msgid "Container type"
msgstr ""
-#: models.py:2130
+#: models.py:2139
msgid "Preservation type"
msgstr ""
-#: models.py:2131
+#: models.py:2140
msgid "Object type"
msgstr ""
-#: models.py:2132
+#: models.py:2141
msgid "Integrity type"
msgstr ""
-#: models.py:2133
+#: models.py:2142
msgid "Remarkability type"
msgstr ""
-#: models.py:2134
+#: models.py:2143
msgid "Batch type"
msgstr ""
-#: models.py:2136
+#: models.py:2145
msgid "Identification type"
msgstr ""
-#: models.py:2138
+#: models.py:2147
msgid "Context record relation type"
msgstr ""
-#: models.py:2139 models.py:3027
+#: models.py:2148 models.py:3051
msgid "Spatial reference system"
msgstr ""
-#: models.py:2140 models.py:2855
+#: models.py:2149 models.py:2879
msgid "Support type"
msgstr ""
-#: models.py:2141 models.py:2520
+#: models.py:2150 models.py:2542
msgid "Title type"
msgstr ""
-#: models.py:2147
+#: models.py:2156
msgid "Integer"
msgstr ""
-#: models.py:2148
+#: models.py:2157
msgid "Float"
msgstr ""
-#: models.py:2149
+#: models.py:2158
msgid "String"
msgstr ""
-#: models.py:2150 templates/sheet_ope.html:86
+#: models.py:2159 templates/sheet_ope.html:86
msgid "Date"
msgstr ""
-#: models.py:2152 templates/sheet_ope.html:61 templates/sheet_ope.html.py:83
+#: models.py:2161 templates/sheet_ope.html:61 templates/sheet_ope.html.py:83
#: templates/ishtar/dashboards/dashboard_main_detail.html:126
msgid "Year"
msgstr ""
-#: models.py:2153
+#: models.py:2162
msgid "String to boolean"
msgstr ""
-#: models.py:2154
+#: models.py:2163
msgctxt "filesystem"
msgid "File"
msgstr ""
-#: models.py:2155
+#: models.py:2164
msgid "Unknow type"
msgstr ""
-#: models.py:2171
+#: models.py:2180
msgid "4 digit year. e.g.: \"2015\""
msgstr ""
-#: models.py:2172
+#: models.py:2181
msgid "4 digit year/month/day. e.g.: \"2015/02/04\""
msgstr ""
-#: models.py:2173
+#: models.py:2182
msgid "Day/month/4 digit year. e.g.: \"04/02/2015\""
msgstr ""
-#: models.py:2183
+#: models.py:2192
msgid "Options"
msgstr ""
-#: models.py:2185
+#: models.py:2194
msgid "Split character(s)"
msgstr ""
-#: models.py:2189
+#: models.py:2198
msgid "Importer - Formater type"
msgstr ""
-#: models.py:2190
+#: models.py:2199
msgid "Importer - Formater types"
msgstr ""
-#: models.py:2242 templates/ishtar/dashboards/dashboard_main_detail.html:63
+#: models.py:2251 templates/ishtar/dashboards/dashboard_main_detail.html:63
msgid "Created"
msgstr ""
-#: models.py:2243
+#: models.py:2252
msgid "Analyse in progress"
msgstr ""
-#: models.py:2244
+#: models.py:2253
msgid "Analysed"
msgstr ""
-#: models.py:2245
+#: models.py:2254
msgid "Import pending"
msgstr ""
-#: models.py:2246
+#: models.py:2255
msgid "Import in progress"
msgstr ""
-#: models.py:2247
+#: models.py:2256
msgid "Finished with errors"
msgstr ""
-#: models.py:2248
+#: models.py:2257
msgid "Finished"
msgstr ""
-#: models.py:2249
+#: models.py:2258
msgid "Archived"
msgstr ""
-#: models.py:2262
+#: models.py:2271
msgid "Imported file"
msgstr ""
-#: models.py:2264
+#: models.py:2273
msgid "Associated images (zip file)"
msgstr ""
-#: models.py:2266
+#: models.py:2275
msgid "Encoding"
msgstr ""
-#: models.py:2268
+#: models.py:2277
msgid "Skip lines"
msgstr ""
-#: models.py:2269 templates/ishtar/import_list.html:47
+#: models.py:2278 templates/ishtar/import_list.html:47
msgid "Error file"
msgstr ""
-#: models.py:2272
+#: models.py:2281
msgid "Result file"
msgstr ""
-#: models.py:2275 templates/ishtar/import_list.html:53
+#: models.py:2284 templates/ishtar/import_list.html:53
msgid "Match file"
msgstr ""
-#: models.py:2281
+#: models.py:2290
msgid "Conservative import"
msgstr ""
-#: models.py:2286
+#: models.py:2295
msgid "End date"
msgstr ""
-#: models.py:2288
+#: models.py:2297
msgid "Remaining seconds"
msgstr ""
-#: models.py:2293
+#: models.py:2302
msgid "Import"
msgstr ""
-#: models.py:2310
+#: models.py:2332
msgid "Analyse"
msgstr ""
-#: models.py:2312 models.py:2315
+#: models.py:2334 models.py:2337
msgid "Re-analyse"
msgstr ""
-#: models.py:2313
+#: models.py:2335
msgid "Launch import"
msgstr ""
-#: models.py:2316
+#: models.py:2338
msgid "Re-import"
msgstr ""
-#: models.py:2317
+#: models.py:2339
msgid "Archive"
msgstr ""
-#: models.py:2319
+#: models.py:2341
msgid "Unarchive"
msgstr ""
-#: models.py:2320 widgets.py:130 templates/ishtar/form_delete.html:11
+#: models.py:2342 widgets.py:130 templates/ishtar/form_delete.html:11
msgid "Delete"
msgstr ""
-#: models.py:2461
+#: models.py:2483
msgid "Organizations"
msgstr ""
-#: models.py:2463
+#: models.py:2485
msgid "Can view all Organizations"
msgstr ""
-#: models.py:2464
+#: models.py:2486
msgid "Can view own Organization"
msgstr ""
-#: models.py:2465
+#: models.py:2487
msgid "Can add own Organization"
msgstr ""
-#: models.py:2467
+#: models.py:2489
msgid "Can change own Organization"
msgstr ""
-#: models.py:2469
+#: models.py:2491
msgid "Can delete own Organization"
msgstr ""
-#: models.py:2504
+#: models.py:2526
msgid "Groups"
msgstr ""
-#: models.py:2509
+#: models.py:2531
msgid "Person types"
msgstr ""
-#: models.py:2521
+#: models.py:2543
msgid "Title types"
msgstr ""
-#: models.py:2530
+#: models.py:2552
msgid "Mr"
msgstr ""
-#: models.py:2531
+#: models.py:2553
msgid "Miss"
msgstr ""
-#: models.py:2532
+#: models.py:2554
msgid "Mr and Mrs"
msgstr ""
-#: models.py:2533
+#: models.py:2555
msgid "Mrs"
msgstr ""
-#: models.py:2534
+#: models.py:2556
msgid "Doctor"
msgstr ""
-#: models.py:2567
+#: models.py:2589
msgid "Contact type"
msgstr ""
-#: models.py:2570 models.py:2634
+#: models.py:2592 models.py:2656
msgid "Types"
msgstr ""
-#: models.py:2573
+#: models.py:2595
msgid "Is attached to"
msgstr ""
-#: models.py:2578
+#: models.py:2600
msgid "Persons"
msgstr ""
-#: models.py:2580
+#: models.py:2602
msgid "Can view all Persons"
msgstr ""
-#: models.py:2581
+#: models.py:2603
msgid "Can view own Person"
msgstr ""
-#: models.py:2582
+#: models.py:2604
msgid "Can add own Person"
msgstr ""
-#: models.py:2583
+#: models.py:2605
msgid "Can change own Person"
msgstr ""
-#: models.py:2584
+#: models.py:2606
msgid "Can delete own Person"
msgstr ""
-#: models.py:2762
+#: models.py:2784
msgid "Advanced shortcut menu"
msgstr ""
-#: models.py:2765
+#: models.py:2787
msgid "Ishtar user"
msgstr ""
-#: models.py:2766
+#: models.py:2788
msgid "Ishtar users"
msgstr ""
-#: models.py:2808
+#: models.py:2832
msgid "To modify the password use the form in Auth > User"
msgstr ""
-#: models.py:2814
+#: models.py:2838
msgid "Author types"
msgstr ""
-#: models.py:2847
+#: models.py:2871
msgid "Source types"
msgstr ""
-#: models.py:2856
+#: models.py:2880
msgid "Support types"
msgstr ""
-#: models.py:2863
+#: models.py:2887
msgid "Format type"
msgstr ""
-#: models.py:2864
+#: models.py:2888
msgid "Format types"
msgstr ""
-#: models.py:2872
+#: models.py:2896
msgid "External ID"
msgstr ""
-#: models.py:2875
+#: models.py:2899
msgid "Support"
msgstr ""
-#: models.py:2879
+#: models.py:2903
msgid "Scale"
msgstr ""
-#: models.py:2893
+#: models.py:2917
msgid "Item number"
msgstr ""
-#: models.py:2894
+#: models.py:2918
msgid "Ref."
msgstr ""
-#: models.py:2897
+#: models.py:2921
msgid "Internal ref."
msgstr ""
-#: models.py:2940
+#: models.py:2964
msgid "Surface (m2)"
msgstr ""
-#: models.py:2941 templates/sheet_ope.html:46 templates/sheet_ope.html.py:107
+#: models.py:2965 templates/sheet_ope.html:46 templates/sheet_ope.html.py:107
msgid "Localisation"
msgstr ""
-#: models.py:2966
+#: models.py:2990
msgid "Is preventive"
msgstr ""
-#: models.py:2970
+#: models.py:2994
msgid "Operation types"
msgstr ""
-#: models.py:2999
+#: models.py:3023
msgid "Preventive"
msgstr ""
-#: models.py:3000
+#: models.py:3024
msgid "Research"
msgstr ""
-#: models.py:3023
+#: models.py:3047
msgid "Authority name"
msgstr ""
-#: models.py:3024
+#: models.py:3048
msgid "Authority SRID"
msgstr ""
-#: models.py:3028
+#: models.py:3052
msgid "Spatial reference systems"
msgstr ""
-#: utils.py:84
+#: utils.py:100
msgid " (...)"
msgstr ""
-#: utils.py:130
+#: utils.py:146
msgid "Load another random image?"
msgstr ""
-#: views.py:118
+#: views.py:119
msgid "New person"
msgstr ""
-#: views.py:126
+#: views.py:127
msgid "Person modification"
msgstr ""
-#: views.py:141
+#: views.py:142
msgid "Person deletion"
msgstr ""
-#: views.py:152
+#: views.py:153
msgid "New organization"
msgstr ""
-#: views.py:159
+#: views.py:160
msgid "Organization modification"
msgstr ""
-#: views.py:175
+#: views.py:176
msgid "Organization deletion"
msgstr ""
-#: views.py:182
+#: views.py:183
msgid "Account management"
msgstr ""
-#: views.py:188
+#: views.py:189
msgid "Account deletion"
msgstr ""
-#: views.py:240
+#: views.py:241
msgid "Archaeological file"
msgstr ""
-#: views.py:241
+#: views.py:242
msgid "Operation"
msgstr ""
-#: views.py:243
+#: views.py:244
msgid "Context record"
msgstr ""
-#: views.py:245
+#: views.py:246
msgid "Find"
msgstr ""
-#: views.py:247
+#: views.py:248
msgid "Treatment request"
msgstr ""
-#: views.py:248
+#: views.py:249
msgid "Treatment"
msgstr ""
-#: views.py:1304 views.py:1347
+#: views.py:1329 views.py:1372
msgid "Operation not permitted."
msgstr ""
-#: views.py:1306
+#: views.py:1331
#, python-format
msgid "New %s"
msgstr ""
-#: views.py:1365 views.py:1415
+#: views.py:1390 views.py:1440
msgid "Archaeological files"
msgstr ""
-#: views.py:1366 views.py:1419
+#: views.py:1391 views.py:1444
msgid "Operations"
msgstr ""
-#: views.py:1368 views.py:1423
+#: views.py:1393 views.py:1448
msgid "Context records"
msgstr ""
-#: views.py:1370 views.py:1426
+#: views.py:1395 views.py:1451
msgid "Finds"
msgstr ""
-#: views.py:1619 templates/ishtar/import_list.html:43
+#: views.py:1644 templates/ishtar/import_list.html:43
msgid "Link unmatched items"
msgstr ""
-#: views.py:1634
+#: views.py:1659
msgid "Delete import"
msgstr ""
-#: views.py:1673
+#: views.py:1698
msgid "Merge persons"
msgstr ""
-#: views.py:1697
+#: views.py:1722
msgid "Select the main person"
msgstr ""
-#: views.py:1706
+#: views.py:1731
msgid "Merge organization"
msgstr ""
-#: views.py:1716
+#: views.py:1741
msgid "Select the main organization"
msgstr ""
-#: views.py:1756 views.py:1772
+#: views.py:1781 views.py:1797
msgid "Corporation manager"
msgstr ""
@@ -1591,15 +1595,15 @@ msgstr ""
msgid "Remove"
msgstr ""
-#: wizards.py:343 templates/ishtar/import_delete.html:20
+#: wizards.py:344 templates/ishtar/import_delete.html:20
msgid "Yes"
msgstr ""
-#: wizards.py:345
+#: wizards.py:346
msgid "No"
msgstr ""
-#: wizards.py:1338
+#: wizards.py:1362
#, python-format
msgid "[%(app_name)s] Account creation/modification"
msgstr ""
@@ -1962,7 +1966,7 @@ msgstr ""
msgid "where the magic happens."
msgstr ""
-#: templates/window.html:40 templates/blocks/JQueryJqGrid.html:28
+#: templates/window.html:40 templates/blocks/JQueryJqGrid.html:34
#: templates/ishtar/manage_basket.html:12
msgid "Add"
msgstr ""
@@ -1984,32 +1988,36 @@ msgstr ""
msgid "Search and select an item"
msgstr ""
-#: templates/blocks/JQueryJqGrid.html:17 templates/blocks/JQueryJqGrid.html:23
+#: templates/blocks/JQueryJqGrid.html:13
+msgid "Pinned search:"
+msgstr ""
+
+#: templates/blocks/JQueryJqGrid.html:23 templates/blocks/JQueryJqGrid.html:29
#: templates/ishtar/blocks/window_tables/dynamic_documents.html:9
#: templates/ishtar/blocks/window_tables/dynamic_documents.html:12
msgid "Export as CSV"
msgstr ""
-#: templates/blocks/JQueryJqGrid.html:17 templates/blocks/JQueryJqGrid.html:23
+#: templates/blocks/JQueryJqGrid.html:23 templates/blocks/JQueryJqGrid.html:29
#: templates/ishtar/blocks/window_tables/dynamic_documents.html:9
msgid "CSV"
msgstr ""
-#: templates/blocks/JQueryJqGrid.html:18
+#: templates/blocks/JQueryJqGrid.html:24
#: templates/ishtar/blocks/window_tables/dynamic_documents.html:10
msgid "Export as CSV - full"
msgstr ""
-#: templates/blocks/JQueryJqGrid.html:18
+#: templates/blocks/JQueryJqGrid.html:24
#: templates/ishtar/blocks/window_tables/dynamic_documents.html:10
msgid "CSV full"
msgstr ""
-#: templates/blocks/JQueryJqGrid.html:20
+#: templates/blocks/JQueryJqGrid.html:26
msgid "Export as CSV - "
msgstr ""
-#: templates/blocks/JQueryJqGrid.html:99
+#: templates/blocks/JQueryJqGrid.html:105
#: templates/ishtar/blocks/window_tables/dynamic_documents.html:41
msgid "An error as occured during search. Check your query fields."
msgstr ""
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index 2496e4372..24704dd21 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -489,8 +489,11 @@ class GeneralType(Cached, models.Model):
@classmethod
def get_types(cls, dct={}, instances=False, exclude=[], empty_first=True,
default=None, initial=None, force=False):
- types = cls._pre_get_types(dct, instances, exclude, empty_first,
- default, force)
+ types = []
+ if not instances and empty_first and not default:
+ types = [('', '--')]
+ types += cls._pre_get_types(dct, instances, exclude,
+ default, force)
if not initial:
return types
new_vals = cls._get_initial_types(initial, [idx for idx, lbl in types])
@@ -499,13 +502,13 @@ class GeneralType(Cached, models.Model):
@classmethod
def _pre_get_types(cls, dct={}, instances=False, exclude=[],
- empty_first=True, default=None, force=False):
+ default=None, force=False):
# cache
cache_key = None
if not instances:
keys = ['__get_types']
- keys += [u"{}".format(ex) for ex in exclude] + [
- empty_first and 'empty_first' or ''] + [u"{}".format(default)]
+ keys += [u"{}".format(ex) for ex in exclude] + \
+ [u"{}".format(default)]
keys += [u'{}-{}'.format(unicode(k), dct[k]) for k in dct]
cache_key, value = get_cache(cls, keys)
if value and not force:
@@ -515,28 +518,25 @@ class GeneralType(Cached, models.Model):
if not cache_key:
return cls._get_parent_types(
base_dct, instances, exclude=exclude,
- empty_first=empty_first, default=default)
+ default=default)
vals = [v for v in cls._get_parent_types(
base_dct, instances, exclude=exclude,
- empty_first=empty_first, default=default)]
+ default=default)]
cache.set(cache_key, vals, settings.CACHE_TIMEOUT)
return vals
if not cache_key:
return cls._get_types(base_dct, instances, exclude=exclude,
- empty_first=empty_first, default=default)
+ default=default)
vals = [v for v in cls._get_types(
- base_dct, instances, exclude=exclude, empty_first=empty_first,
+ base_dct, instances, exclude=exclude,
default=default)]
cache.set(cache_key, vals, settings.CACHE_TIMEOUT)
return vals
@classmethod
- def _get_types(cls, dct={}, instances=False, exclude=[], empty_first=True,
- default=None):
+ def _get_types(cls, dct={}, instances=False, exclude=[], default=None):
dct['available'] = True
- if not instances and empty_first and not default:
- yield ('', '--')
if default:
try:
default = cls.objects.get(txt_idx=default)
@@ -606,10 +606,8 @@ class GeneralType(Cached, models.Model):
@classmethod
def _get_parent_types(cls, dct={}, instances=False, exclude=[],
- empty_first=True, default=None):
+ default=None):
dct['available'] = True
- if not instances and empty_first:
- yield ('', '--')
dct['parent'] = None
items = cls.objects.filter(**dct)
if exclude:
diff --git a/ishtar_common/templates/blocks/JQueryJqGrid.html b/ishtar_common/templates/blocks/JQueryJqGrid.html
index 607f81f7d..258082877 100644
--- a/ishtar_common/templates/blocks/JQueryJqGrid.html
+++ b/ishtar_common/templates/blocks/JQueryJqGrid.html
@@ -8,6 +8,12 @@
<h4>{% trans "Search and select an item" %}</h4>
+<h5 id="pinned_search_{{name}}">
+ <i class="fa fa-thumb-tack"></i> &nbsp;
+ <strong>{% trans "Pinned search:" %}</strong>
+ <em><span id="pinned_search_content_{{name}}"></span></em>
+</h5>
+
<table id='grid_{{name}}' class='jqgrid'></table>
<div id='pager_{{name}}'></div>
@@ -97,6 +103,19 @@ jQuery(document).ready(function(){
jsonReader : {repeatitems: false},
loadError: function (jqXHR, textStatus, errorThrown) {
alert("{% trans "An error as occured during search. Check your query fields." %}");
+ },
+ beforeProcessing: function(data, status, xhr){
+ $('#pinned_search_content_{{name}}').html('');
+ for (idx in data){
+ if (idx == 'pinned-search' && data[idx] != ''){
+ $('#pinned_search_content_{{name}}').html(data[idx]);
+ }
+ }
+ if ($('#pinned_search_content_{{name}}').html()){
+ $('#pinned_search_{{name}}').show();
+ } else {
+ $('#pinned_search_{{name}}').hide();
+ }
}
});
{% if multiple %}
diff --git a/ishtar_common/templates/ishtar/blocks/advanced_shortcut_menu.html b/ishtar_common/templates/ishtar/blocks/advanced_shortcut_menu.html
index 2cf80da06..1758bcf54 100644
--- a/ishtar_common/templates/ishtar/blocks/advanced_shortcut_menu.html
+++ b/ishtar_common/templates/ishtar/blocks/advanced_shortcut_menu.html
@@ -13,7 +13,7 @@
</span>
<div class="short-menu-buttons btn-group" role="group">
<button type="button" class="btn" id='short-menu-simple' title="{% trans 'Simple menu limited to your own items. Be careful only the last 100 items are displayed.' %}">{% trans "simple" %}</button>
- <button type="button" class="btn btn-selected" id='short-menu-advanced' title="{% trans 'Advanced menu.' %}">{% trans "advanced" %}</button>
+ <button type="button" class="btn btn-selected" id='short-menu-advanced' title="{% trans 'Advanced menu' %}">{% trans "advanced" %}</button>
</div>
<div id='action_current_items'>
<p><i class="icon fa fa-thumb-tack fa-2x" aria-hidden="true" title="{% trans 'Pin an item in order to constrain default searches with this item. By default only your items are displayed. New created and modified items are auto-pin.' %}"></i></p>
diff --git a/ishtar_common/templates/ishtar/blocks/shortcut_menu.html b/ishtar_common/templates/ishtar/blocks/shortcut_menu.html
index 05aaed6d8..5973eba3f 100644
--- a/ishtar_common/templates/ishtar/blocks/shortcut_menu.html
+++ b/ishtar_common/templates/ishtar/blocks/shortcut_menu.html
@@ -13,7 +13,7 @@
</span>
<div class="short-menu-buttons btn-group" role="group">
<button type="button" class="btn btn-selected" id='short-menu-simple' title="{% trans 'Simple menu limited to your own items. Be careful only the last 100 items are displayed.' %}">{% trans "simple" %}</button>
- <button type="button" class="btn" id='short-menu-advanced' title="{% trans 'Advanced menu.' %}">{% trans "advanced" %}</button>
+ <button type="button" class="btn" id='short-menu-advanced' title="{% trans 'Advanced menu' %}">{% trans "advanced" %}</button>
</div>
<div>
<i class="icon fa fa-thumb-tack fa-2x" aria-hidden="true" title="{% trans 'Pin an item in order to constrain default searches with this item. By default only your items are displayed. New created and modified items are auto-pin.' %}"></i>
diff --git a/ishtar_common/templates/ishtar/wizard/validation_bar.html b/ishtar_common/templates/ishtar/wizard/validation_bar.html
index 09907af67..a1590858f 100644
--- a/ishtar_common/templates/ishtar/wizard/validation_bar.html
+++ b/ishtar_common/templates/ishtar/wizard/validation_bar.html
@@ -1,7 +1,9 @@
{% load i18n %}
{% load url from future %}
<div id='validation-bar'>
- <input type="submit" id="submit_form" name='validate' value="{% trans "Validate" %}"/>
- {% if next_steps %}<input type="submit" id="submit_end_form" name='validate_and_end' value="{% trans "Validate and end" %}"/>{% endif %}
- <a href='{% url 'reset_wizards' %}' id="reset_wizards" class='button'>{% trans "Cancel" %}</a>
+ <input type="submit" id="submit_form" name='validate' value="{% trans 'Validate' %}"/>
+ {% if last_step_is_available and next_steps %}
+ <input type="submit" id="submit_end_form" name='validate_and_end' value="{% trans 'Validate and end' %}"/>
+ {% endif %}
+ <a href="{% url 'reset_wizards' %}" id="reset_wizards" class='button'>{% trans "Cancel" %}</a>
</div>
diff --git a/ishtar_common/tests.py b/ishtar_common/tests.py
index 42bb1860e..a9e92e1f2 100644
--- a/ishtar_common/tests.py
+++ b/ishtar_common/tests.py
@@ -30,8 +30,9 @@ from django.core.files.base import File as DjangoFile
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.management import call_command
from django.core.urlresolvers import reverse
+from django.db import connection, transaction
from django.template.defaultfilters import slugify
-from django.test import TestCase
+from django.test import TestCase as BaseTestCase
from django.test.client import Client
from django.test.simple import DjangoTestSuiteRunner
@@ -39,6 +40,9 @@ from ishtar_common import models
from ishtar_common import forms_common
from ishtar_common.utils import post_save_point
+from archaeological_context_records.models import CRBulkView
+from archaeological_finds.models import BFBulkView, FBulkView, FirstBaseFindView
+
"""
from django.conf import settings
import tempfile, datetime
@@ -82,6 +86,17 @@ def create_user():
return username, password, user
+class TestCase(BaseTestCase):
+ def _pre_setup(self):
+ super(TestCase, self)._pre_setup()
+ if settings.USE_SPATIALITE_FOR_TESTS:
+ return
+ c = connection.cursor()
+ for view in [CRBulkView, FirstBaseFindView, BFBulkView, FBulkView]:
+ c.execute(view.CREATE_SQL)
+ transaction.commit_unless_managed()
+
+
class CommandsTestCase(TestCase):
def test_clean_ishtar(self):
"""
@@ -102,20 +117,30 @@ class WizardTestFormData(object):
"""
Test set to simulate wizard steps
"""
- def __init__(self, name, form_datas, ignored=[], extra_tests=[]):
+ def __init__(self, name, form_datas, ignored=[], pre_tests=[],
+ extra_tests=[]):
"""
:param name: explicit name of the test
:param form_datas: dict with data for each step - dict key are wizard
step name
:param ignored: steps to be ignored in wizard processing
+ :param pre_tests: list of function to be executed before the wizard
:param extra_tests: list of extra tests. Theses tests must be functions
accepting two parameters: the current test object and the final step
response
"""
self.form_datas = form_datas
self.ignored = ignored[:]
+ self.pre_tests = pre_tests
self.extra_tests = extra_tests
+ def inits(self, test_object):
+ """
+ Initialisations before the wizard.
+ """
+ for pre in self.pre_tests:
+ pre(test_object)
+
def tests(self, test_object, final_step_response):
"""
Specific tests for theses datas. Raise Exception if not OK.
@@ -185,6 +210,7 @@ class WizardTest(object):
url = reverse(self.url_name)
self.pre_wizard()
for test_form_data in self.form_datas:
+ test_form_data.inits(self)
form_data = test_form_data.form_datas
ignored = test_form_data.ignored
for idx, step in enumerate(self.steps):
@@ -207,27 +233,27 @@ class WizardTest(object):
for k in d:
data['{}-{}'.format(current_step, k)] = d[k]
- next_idx, next_form = idx + 1, None
- while len(self.steps) > next_idx:
- if self.steps[idx + 1][0] not in ignored:
- next_form = self.steps[idx + 1][0]
- break
- next_idx += 1
- if next_form:
- try:
- response = self.client.post(url, data)
- except ValidationError as e:
- # on ManagementForm data is missing or has been tampered
- # error verify the wizard_name or step name
- raise ValidationError(u"Errors: {} on {}.".format(
- u" - ".join(e.messages), current_step))
- self.check_response(response, current_step)
+ next_form_is_checked = len(self.steps) > idx + 1 and \
+ self.steps[idx + 1][0] not in ignored
+ try:
+ response = self.client.post(url, data,
+ follow=not next_form_is_checked)
+ except ValidationError as e:
+ # on ManagementForm data is missing or has been tampered
+ # error verify the wizard_name or step name
+ raise ValidationError(u"Errors: {} on {}.".format(
+ u" - ".join(e.messages), current_step))
+ self.check_response(response, current_step)
+ if next_form_is_checked:
+ next_form = self.steps[idx + 1][0]
self.assertRedirects(
response,
'/{}/{}'.format(self.url_name, next_form))
- else:
- response = self.client.post(url, data, follow=True)
- self.check_response(response, current_step)
+ if idx == len(self.steps) - 1:
+ # last form
+ self.assertRedirects(
+ response,
+ '/{}/done'.format(self.url_name))
test_form_data.tests(self, response)
self.post_wizard()
diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py
index 83534d93a..f1e2e4b96 100644
--- a/ishtar_common/utils.py
+++ b/ishtar_common/utils.py
@@ -55,10 +55,21 @@ def get_cache(cls, extra_args=[]):
return cache_key, cache.get(cache_key)
+def force_cached_label_changed(sender, **kwargs):
+ if not kwargs.get('instance'):
+ return
+ kwargs['instance']._cached_label_checked = False
+ cached_label_changed(sender, **kwargs)
+
+
def cached_label_changed(sender, **kwargs):
if not kwargs.get('instance'):
return
instance = kwargs.get('instance')
+
+ if hasattr(instance, 'test_obj'):
+ instance.test_obj.reached(sender, **kwargs)
+
if hasattr(instance, '_cached_label_checked') \
and instance._cached_label_checked:
return
@@ -76,15 +87,22 @@ def cached_label_changed(sender, **kwargs):
if hasattr(instance, '_cascade_change') and instance._cascade_change:
instance.skip_history_when_saving = True
instance.save()
- if hasattr(instance, '_get_associated_cached_labels'):
+ updated = False
+ if hasattr(instance, '_cached_labels_bulk_update'):
+ updated = instance._cached_labels_bulk_update()
+ if not updated and hasattr(instance, '_get_associated_cached_labels'):
for item in instance._get_associated_cached_labels():
item._cascade_change = True
+ if hasattr(instance, 'test_obj'):
+ item.test_obj = instance.test_obj
cached_label_changed(item.__class__, instance=item)
SHORTIFY_STR = ugettext(" (...)")
def shortify(lbl, number=20):
+ if not lbl:
+ lbl = ''
if len(lbl) <= number:
return lbl
return lbl[:number - len(SHORTIFY_STR)] + SHORTIFY_STR
diff --git a/ishtar_common/views.py b/ishtar_common/views.py
index c9eb9fec8..a4ad130be 100644
--- a/ishtar_common/views.py
+++ b/ishtar_common/views.py
@@ -58,7 +58,8 @@ from menus import menu
from archaeological_files.models import File
from archaeological_operations.models import Operation
from archaeological_context_records.models import ContextRecord
-from archaeological_finds.models import Find, Treatment, TreatmentFile
+from archaeological_finds.models import Find, Treatment, TreatmentFile, \
+ FindBasket
from archaeological_operations.forms import DashboardForm as DashboardFormOpe
from archaeological_files.forms import DashboardForm as DashboardFormFile
@@ -307,15 +308,18 @@ def shortcut_menu(request):
return render_to_response('ishtar/blocks/shortcut_menu.html', dct,
context_instance=RequestContext(request))
+CURRENT_ITEM_KEYS = (('file', File),
+ ('operation', Operation),
+ ('contextrecord', ContextRecord),
+ ('find', Find),
+ ('treatmentfile', TreatmentFile),
+ ('treatment', Treatment))
+CURRENT_ITEM_KEYS_DICT = dict(CURRENT_ITEM_KEYS)
+
def get_current_items(request):
currents = {}
- for key, model in (('file', File),
- ('operation', Operation),
- ('contextrecord', ContextRecord),
- ('find', Find),
- ('treatmentfile', TreatmentFile),
- ('treatment', Treatment)):
+ for key, model in CURRENT_ITEM_KEYS:
currents[key] = None
if key in request.session and request.session[key]:
try:
@@ -693,6 +697,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
q = Q(**{req_key: val})
reqs |= q
and_reqs.append(reqs)
+ pinned_search = ""
if 'submited' not in request_items and full != 'shortcut':
# default search
# an item is selected in the default menu
@@ -700,17 +705,36 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
request.session[default_name]:
value = request.session[default_name]
if 'basket-' in value:
- dct = {"basket__pk":
- request.session[default_name].split('-')[-1]}
+ try:
+ dct = {"basket__pk":
+ request.session[default_name].split('-')[-1]}
+ pinned_search = unicode(FindBasket.objects.get(
+ pk=dct["basket__pk"]))
+ except FindBasket.DoesNotExist:
+ pass
else:
- dct = {"pk": request.session[default_name]}
+ try:
+ dct = {"pk": request.session[default_name]}
+ pinned_search = unicode(model._meta.verbose_name)\
+ + u" - " + unicode(
+ model.objects.get(pk=dct["pk"]))
+ except model.DoesNotExist:
+ pass
elif dct == (base_request or {}):
# a parent item may be selected in the default menu
for name, key in my_relative_session_names:
if name in request.session and request.session[name] \
- and 'basket-' not in request.session[name]:
- dct.update({key: request.session[name]})
- break
+ and 'basket-' not in request.session[name] \
+ and name in CURRENT_ITEM_KEYS_DICT:
+ up_model = CURRENT_ITEM_KEYS_DICT[name]
+ try:
+ dct.update({key: request.session[name]})
+ pinned_search = unicode(up_model._meta.verbose_name)\
+ + u" - " + unicode(
+ up_model.objects.get(pk=dct[key]))
+ break
+ except up_model.DoesNotExist:
+ pass
if (not dct or data_type == 'csv') \
and func_name in request.session:
dct = request.session[func_name]
@@ -1053,6 +1077,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
data = json.dumps({
"records": items_nb,
"rows": rows,
+ "pinned-search": pinned_search,
"page": page_nb,
"total": (items_nb / row_nb + 1) if row_nb else items_nb,
})
diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py
index 5c4e1d3f9..874b68eae 100644
--- a/ishtar_common/wizards.py
+++ b/ishtar_common/wizards.py
@@ -238,42 +238,70 @@ class Wizard(NamedUrlWizardView):
'previous_step_counter': previous_step_counter})
storage = self.storage
# if modification: show the next steps
- if self.modification:
- next_step = self.steps.first
- current_step_passed = False
- # force rechecking of conditions
- self.get_form_list()
- while next_step:
- # check if the form is initialized otherwise initialize it
- if not storage.get_step_data(next_step):
- values = self.get_form_initial(next_step)
- prefixed_values = MultiValueDict()
- if not isinstance(values, list):
- for key in values:
- form_key = next_step + '-' + key
- if isinstance(values, MultiValueDict):
- prefixed_values.setlist(form_key,
- values.getlist(key))
- else:
- prefixed_values[form_key] = values[key]
+ # if self.modification or True:
+ next_step = self.steps.first
+ current_step_passed, no_next = False, False
+ # force rechecking of conditions
+ self.get_form_list()
+ last_step_is_available = True
+ while next_step:
+ # check if the form is initialized otherwise initialize it
+ if self.modification and not storage.get_step_data(next_step):
+ values = self.get_form_initial(next_step)
+ prefixed_values = MultiValueDict()
+ if not isinstance(values, list):
+ for key in values:
+ form_key = next_step + '-' + key
+ if isinstance(values, MultiValueDict):
+ prefixed_values.setlist(form_key,
+ values.getlist(key))
+ else:
+ prefixed_values[form_key] = values[key]
+ else:
+ for formset_idx, v in enumerate(values):
+ prefix = u"-%d-" % formset_idx
+ for key in v:
+ form_key = next_step + prefix + key
+ prefixed_values[form_key] = v[key]
+ if not prefixed_values and \
+ next_step not in self.get_ignore_init_steps():
+ # simulate a non empty data for form that might be
+ # valid when empty
+ prefixed_values['__non_empty_data'] = ''
+ storage.set_step_data(next_step, prefixed_values)
+ if step == next_step:
+ current_step_passed = True
+ elif current_step_passed:
+ next_steps.append(self.form_list[next_step].form_label)
+
+ # creation
+ if not self.modification:
+ form_obj = self.get_form(step=next_step)
+ if current_step_passed:
+ initialise_data = False
+ # formsets are considered not required
+ if hasattr(form_obj, 'fields'):
+ # display next step until a required field is met
+ if [field_key for field_key in form_obj.fields
+ if form_obj.fields[field_key].required]:
+ no_next = True
+ elif next_step not in self.get_ignore_init_steps():
+ initialise_data = True
else:
- for formset_idx, v in enumerate(values):
- prefix = u"-%d-" % formset_idx
- for key in v:
- form_key = next_step + prefix + key
- prefixed_values[form_key] = v[key]
- if not prefixed_values and \
- next_step not in self.get_ignore_init_steps():
+ initialise_data = True
+ if initialise_data:
# simulate a non empty data for form that might be
# valid when empty
+ prefixed_values = MultiValueDict()
prefixed_values['__non_empty_data'] = ''
- storage.set_step_data(next_step, prefixed_values)
- if step == next_step:
- current_step_passed = True
- elif current_step_passed:
- next_steps.append(self.form_list[next_step].form_label)
- next_step = self.get_next_step(next_step)
- context.update({'next_steps': next_steps})
+ storage.set_step_data(next_step, prefixed_values)
+
+ next_step = self.get_next_step(next_step)
+ if no_next:
+ last_step_is_available = False
+ break
+ context.update({'next_steps': next_steps,
+ 'last_step_is_available': last_step_is_available})
# not last step: validation
if current_step != self.steps.last:
return context