docassemble.AssemblyLine 2.28.0__tar.gz → 2.28.1__tar.gz

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.
Files changed (87) hide show
  1. {docassemble_assemblyline-2.28.0/docassemble.AssemblyLine.egg-info → docassemble_assemblyline-2.28.1}/PKG-INFO +1 -1
  2. docassemble_assemblyline-2.28.1/docassemble/AssemblyLine/__init__.py +1 -0
  3. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/al_courts.py +15 -3
  4. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/al_document.py +6 -2
  5. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/al_general.py +83 -33
  6. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/ql_baseline.yml +7 -9
  7. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1/docassemble.AssemblyLine.egg-info}/PKG-INFO +1 -1
  8. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/setup.py +1 -1
  9. docassemble_assemblyline-2.28.0/docassemble/AssemblyLine/__init__.py +0 -1
  10. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/LICENSE +0 -0
  11. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/MANIFEST.in +0 -0
  12. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/README.md +0 -0
  13. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/al_code.yml +0 -0
  14. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/al_document.yml +0 -0
  15. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/al_language.yml +0 -0
  16. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/al_package.yml +0 -0
  17. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/al_package_unstyled.yml +0 -0
  18. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/al_question_test.yml +0 -0
  19. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/al_reminders.yml +0 -0
  20. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/al_saved_sessions.yml +0 -0
  21. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/al_saved_sessions_store.yml +0 -0
  22. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/al_settings.yml +0 -0
  23. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/al_terms_of_use.yml +0 -0
  24. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/al_visual.yml +0 -0
  25. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/assembly_line.yml +0 -0
  26. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/assembly_line_unstyled.yml +0 -0
  27. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/feedback.yml +0 -0
  28. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/interview_list.yml +0 -0
  29. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/ql_catchall.yml +0 -0
  30. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/reserved_words.yml +0 -0
  31. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/test_al_table_document.yml +0 -0
  32. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/test_aladdendum.yml +0 -0
  33. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/test_alcourts.yml +0 -0
  34. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/test_aldocument.yml +0 -0
  35. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/test_alexhibit.yml +0 -0
  36. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/test_alexhibit_maxsize.yml +0 -0
  37. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/test_bundle_parity.yml +0 -0
  38. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/questions/test_question_library.yml +0 -0
  39. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/sources/README.md +0 -0
  40. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/sources/es-words.yml +0 -0
  41. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/sources/languages.yml +0 -0
  42. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/sources/test_aldocument.feature +0 -0
  43. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/sources/test_alexhibit_docx_1.docx +0 -0
  44. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/sources/test_alexhibit_jpg_1.jpg +0 -0
  45. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/sources/test_alexhibit_pdf_1.pdf +0 -0
  46. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/sources/test_alexhibit_png_1.png +0 -0
  47. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/sources/test_question_library.feature +0 -0
  48. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/sources/translation_es.xlsx +0 -0
  49. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/sources/translation_ht.xlsx +0 -0
  50. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/sources/translation_pt.xlsx +0 -0
  51. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/static/README.md +0 -0
  52. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/static/al_audio.css +0 -0
  53. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/static/al_audio.js +0 -0
  54. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/static/aldocument.css +0 -0
  55. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/static/aldocument.js +0 -0
  56. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/static/interview_list.css +0 -0
  57. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/static/limit_upload_size.js +0 -0
  58. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/static/lt1-pullout-10-getting-organized.pdf +0 -0
  59. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/static/ma_logo.png +0 -0
  60. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/static/placeholder.png +0 -0
  61. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/static/seal.jpg +0 -0
  62. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/static/styles.css +0 -0
  63. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/templates/README.md +0 -0
  64. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/templates/al_basic_addendum.docx +0 -0
  65. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/templates/exhibit_cover_sheet.docx +0 -0
  66. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/templates/exhibit_table_of_contents.docx +0 -0
  67. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/templates/general_cover_sheet.docx +0 -0
  68. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/templates/sample_word_template.docx +0 -0
  69. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/templates/test_aldocument_docx_1.docx +0 -0
  70. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/data/templates/test_aldocument_pdf_1.pdf +0 -0
  71. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/language.py +0 -0
  72. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/project_maintenance.py +0 -0
  73. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/py.typed +0 -0
  74. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/requirements.txt +0 -0
  75. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/sessions.py +0 -0
  76. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/test_al_document.py +0 -0
  77. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/test_al_general.py +0 -0
  78. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/AssemblyLine/test_language.py +0 -0
  79. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble/__init__.py +0 -0
  80. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble.AssemblyLine.egg-info/SOURCES.txt +0 -0
  81. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble.AssemblyLine.egg-info/dependency_links.txt +0 -0
  82. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble.AssemblyLine.egg-info/namespace_packages.txt +0 -0
  83. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble.AssemblyLine.egg-info/not-zip-safe +0 -0
  84. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble.AssemblyLine.egg-info/requires.txt +0 -0
  85. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/docassemble.AssemblyLine.egg-info/top_level.txt +0 -0
  86. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/pyproject.toml +0 -0
  87. {docassemble_assemblyline-2.28.0 → docassemble_assemblyline-2.28.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: docassemble.AssemblyLine
3
- Version: 2.28.0
3
+ Version: 2.28.1
4
4
  Home-page: https://courtformsonline.org
5
5
  Author: Suffolk Legal Innovation and Technology Lab
6
6
  Author-email: qsteenhuis@suffolk.edu
@@ -0,0 +1 @@
1
+ __version__ = '2.28.1'
@@ -3,7 +3,7 @@ Package for a very simple / MVP list of courts that is mostly signature compatib
3
3
  """
4
4
 
5
5
  import os
6
- from typing import Any, Dict, List, Optional, Union, Set
6
+ from typing import Any, Callable, Dict, List, Mapping, Optional, Union, Set
7
7
  import pandas as pd
8
8
  import docassemble.base.functions
9
9
  from docassemble.base.util import (
@@ -205,6 +205,7 @@ class ALCourtLoader(DAObject):
205
205
 
206
206
  Attributes:
207
207
  filename (str): Path to the file containing court information.
208
+ converters (Dict[str, Callable]): A dictionary of functions to apply to columns in the dataframe.
208
209
  """
209
210
 
210
211
  def init(self, *pargs, **kwargs):
@@ -413,6 +414,8 @@ class ALCourtLoader(DAObject):
413
414
 
414
415
  The method determines the file type (.csv, .xlsx, or .json) based on its extension and reads it accordingly.
415
416
 
417
+ If the "callable" attribute is defined on the instance, it will be used to convert the data in the dataframe.
418
+
416
419
  Returns:
417
420
  pd.DataFrame: A dataframe containing the list of courts.
418
421
 
@@ -429,11 +432,20 @@ class ALCourtLoader(DAObject):
429
432
  else:
430
433
  load_path = str(self.filename)
431
434
 
435
+ def convert_zip(z: Any) -> str:
436
+ return str(z).zfill(5)
437
+
438
+ merged_converters: Dict[str, Callable[[object], object]] = {
439
+ "address_zip": convert_zip
440
+ }
441
+ if hasattr(self, "converters") and self.converters:
442
+ assert isinstance(self.converters, dict)
443
+ merged_converters.update(self.converters)
432
444
  to_load = path_and_mimetype(load_path)[0]
433
445
  if self.filename.lower().endswith(".xlsx"):
434
- df = pd.read_excel(to_load)
446
+ df = pd.read_excel(to_load, converters=merged_converters) # type: ignore
435
447
  elif self.filename.lower().endswith(".csv"):
436
- df = pd.read_csv(to_load)
448
+ df = pd.read_csv(to_load, converters=merged_converters) # type: ignore
437
449
  elif self.filename.lower().endswith(".json"):
438
450
  # TODO: we may need to normalize a JSON file
439
451
  df = pd.read_json(to_load)
@@ -2244,8 +2244,12 @@ class ALDocumentBundle(DAList):
2244
2244
  return send_email(
2245
2245
  to=to,
2246
2246
  template=template,
2247
- attachments=set(
2248
- self.as_editable_list(key=key) + self.as_pdf_list(key=key)
2247
+ # Add both DOCX and PDF versions, but if it's not possible to be a DOCX don't add the PDF
2248
+ # twice
2249
+ attachments=list(
2250
+ dict.fromkeys(
2251
+ self.as_editable_list(key=key) + self.as_pdf_list(key=key)
2252
+ )
2249
2253
  ),
2250
2254
  **kwargs,
2251
2255
  )
@@ -425,7 +425,13 @@ class ALAddress(Address):
425
425
  else:
426
426
  output += ", " + str(self.state)
427
427
  if hasattr(self, "zip") and self.zip:
428
- output += " " + str(self.zip)
428
+ current_country = (
429
+ self.country if hasattr(self, "country") else get_country()
430
+ )
431
+ if current_country == "US":
432
+ output += " " + str(self.zip).zfill(5)
433
+ else:
434
+ output += " " + str(self.zip)
429
435
  elif hasattr(self, "postal_code") and self.postal_code:
430
436
  output += " " + str(self.postal_code)
431
437
  if (
@@ -508,7 +514,13 @@ class ALAddress(Address):
508
514
  else:
509
515
  output += ", " + str(self.state)
510
516
  if hasattr(self, "zip") and self.zip:
511
- output += " " + str(self.zip)
517
+ current_country = (
518
+ self.country if hasattr(self, "country") else get_country()
519
+ )
520
+ if current_country == "US":
521
+ output += " " + str(self.zip).zfill(5)
522
+ else:
523
+ output += " " + str(self.zip)
512
524
  elif hasattr(self, "postal_code") and self.postal_code:
513
525
  output += " " + str(self.postal_code)
514
526
  return output
@@ -576,7 +588,13 @@ class ALAddress(Address):
576
588
  else:
577
589
  output += ", " + str(self.state)
578
590
  if hasattr(self, "zip") and self.zip:
579
- output += " " + str(self.zip)
591
+ current_country = (
592
+ self.country if hasattr(self, "country") else get_country()
593
+ )
594
+ if current_country == "US":
595
+ output += " " + str(self.zip).zfill(5)
596
+ else:
597
+ output += " " + str(self.zip)
580
598
  elif hasattr(self, "postal_code") and self.postal_code:
581
599
  output += " " + str(self.postal_code)
582
600
  if (
@@ -1267,9 +1285,13 @@ class ALIndividual(Individual):
1267
1285
 
1268
1286
  If the individual has selected the "self-described" option, it will use their custom input.
1269
1287
 
1288
+ Can be formatted however the author likes.
1289
+
1270
1290
  Returns:
1271
1291
  set: A set of strings representing the individual's pronouns.
1272
1292
  """
1293
+ if hasattr(self, "pronouns") and isinstance(self.pronouns, str):
1294
+ return {self.pronouns}
1273
1295
  if self.pronouns.all_false():
1274
1296
  return {str(self.pronoun_prefer_not_to_say_label)}
1275
1297
  pronouns = set(self.pronouns.true_values()) - {"self-described"}
@@ -1277,6 +1299,16 @@ class ALIndividual(Individual):
1277
1299
  pronouns = pronouns.union(self.pronouns_self_described.splitlines())
1278
1300
  return pronouns
1279
1301
 
1302
+ def list_pronouns(self) -> str:
1303
+ """
1304
+ Retrieve a formatted string of the individual's pronouns, arranged with
1305
+ the comma_list() function.
1306
+
1307
+ Returns:
1308
+ str: A formatted string of the individual's pronouns.
1309
+ """
1310
+ return comma_list(sorted(self.get_pronouns()))
1311
+
1280
1312
  def language_fields(
1281
1313
  self,
1282
1314
  choices: Optional[List[Dict[str, str]]] = None,
@@ -1500,32 +1532,38 @@ class ALIndividual(Individual):
1500
1532
  Returns:
1501
1533
  str: The appropriate pronoun.
1502
1534
  """
1535
+ # Developers can do funky things; be a little flexible
1536
+ if hasattr(self, "pronouns") and isinstance(self.pronouns, str):
1537
+ pronouns = DADict(elements={self.pronouns.lower(): True})
1538
+ else:
1539
+ pronouns = self.pronouns
1540
+
1503
1541
  if self == this_thread.global_vars.user:
1504
1542
  output = word("you", **kwargs)
1505
1543
  elif (
1506
1544
  hasattr(self, "pronouns")
1507
- and isinstance(self.pronouns, DADict)
1508
- and len(self.pronouns.true_values()) == 1
1545
+ and isinstance(pronouns, DADict)
1546
+ and len(pronouns.true_values()) == 1
1509
1547
  and (
1510
1548
  (
1511
- self.pronouns.true_values()[0]
1549
+ pronouns.true_values()[0]
1512
1550
  in ["she/her/hers", "he/him/his", "they/them/theirs", "ze/zir/zirs"]
1513
1551
  )
1514
1552
  or (
1515
- self.pronouns.get("self-described")
1553
+ pronouns.get("self-described")
1516
1554
  and has_parsable_pronouns(self.pronouns_self_described)
1517
1555
  )
1518
1556
  )
1519
1557
  ):
1520
- if self.pronouns["she/her/hers"]:
1558
+ if pronouns.get("she/her/hers"):
1521
1559
  output = word("her", **kwargs)
1522
- elif self.pronouns["he/him/his"]:
1560
+ elif pronouns.get("he/him/his"):
1523
1561
  output = word("him", **kwargs)
1524
- elif self.pronouns["they/them/theirs"]:
1562
+ elif pronouns.get("they/them/theirs"):
1525
1563
  output = word("them", **kwargs)
1526
- elif self.pronouns["ze/zir/zirs"]:
1564
+ elif pronouns.get("ze/zir/zirs"):
1527
1565
  output = word("zir", **kwargs)
1528
- elif self.pronouns.get("self-described"):
1566
+ elif pronouns.get("self-described"):
1529
1567
  output = parse_custom_pronouns(self.pronouns_self_described)["o"]
1530
1568
  elif hasattr(self, "person_type") and self.person_type in [
1531
1569
  "business",
@@ -1567,34 +1605,39 @@ class ALIndividual(Individual):
1567
1605
  Returns:
1568
1606
  str: The appropriate possessive phrase.
1569
1607
  """
1608
+ if hasattr(self, "pronouns") and isinstance(self.pronouns, str):
1609
+ pronouns = DADict(elements={self.pronouns.lower(): True})
1610
+ else:
1611
+ pronouns = self.pronouns
1612
+
1570
1613
  if self == this_thread.global_vars.user and (
1571
1614
  "thirdperson" not in kwargs or not kwargs["thirdperson"]
1572
1615
  ):
1573
1616
  output = your(target, **kwargs)
1574
1617
  elif (
1575
1618
  hasattr(self, "pronouns")
1576
- and isinstance(self.pronouns, DADict)
1577
- and len(self.pronouns.true_values()) == 1
1619
+ and isinstance(pronouns, DADict)
1620
+ and len(pronouns.true_values()) == 1
1578
1621
  and (
1579
1622
  (
1580
- self.pronouns.true_values()[0]
1623
+ pronouns.true_values()[0]
1581
1624
  in ["she/her/hers", "he/him/his", "they/them/theirs", "ze/zir/zirs"]
1582
1625
  )
1583
1626
  or (
1584
- self.pronouns.get("self-described")
1627
+ pronouns.get("self-described")
1585
1628
  and has_parsable_pronouns(self.pronouns_self_described)
1586
1629
  )
1587
1630
  )
1588
1631
  ):
1589
- if self.pronouns["she/her/hers"]:
1632
+ if pronouns.get("she/her/hers"):
1590
1633
  output = her(target, **kwargs)
1591
- elif self.pronouns["he/him/his"]:
1634
+ elif pronouns.get("he/him/his"):
1592
1635
  output = his(target, **kwargs)
1593
- elif self.pronouns["they/them/theirs"]:
1636
+ elif pronouns.get("they/them/theirs"):
1594
1637
  output = their(target, **kwargs)
1595
- elif self.pronouns["ze/zir/zirs"]:
1638
+ elif pronouns.get("ze/zir/zirs"):
1596
1639
  output = word("zir", **kwargs) + " " + target
1597
- elif self.pronouns.get("self-described"):
1640
+ elif pronouns.get("self-described"):
1598
1641
  output = (
1599
1642
  parse_custom_pronouns(self.pronouns_self_described)["p"]
1600
1643
  + " "
@@ -1628,34 +1671,39 @@ class ALIndividual(Individual):
1628
1671
  Returns:
1629
1672
  str: The appropriate subjective pronoun.
1630
1673
  """
1674
+ if hasattr(self, "pronouns") and isinstance(self.pronouns, str):
1675
+ pronouns = DADict(elements={self.pronouns.lower(): True})
1676
+ else:
1677
+ pronouns = self.pronouns
1678
+
1631
1679
  if self == this_thread.global_vars.user and (
1632
1680
  "thirdperson" not in kwargs or not kwargs["thirdperson"]
1633
1681
  ):
1634
1682
  output = word("you", **kwargs)
1635
1683
  elif (
1636
1684
  hasattr(self, "pronouns")
1637
- and isinstance(self.pronouns, DADict)
1638
- and len(self.pronouns.true_values()) == 1
1685
+ and isinstance(pronouns, DADict)
1686
+ and len(pronouns.true_values()) == 1
1639
1687
  and (
1640
1688
  (
1641
- self.pronouns.true_values()[0]
1689
+ pronouns.true_values()[0]
1642
1690
  in ["she/her/hers", "he/him/his", "they/them/theirs", "ze/zir/zirs"]
1643
1691
  )
1644
1692
  or (
1645
- self.pronouns.get("self-described")
1693
+ pronouns.get("self-described")
1646
1694
  and has_parsable_pronouns(self.pronouns_self_described)
1647
1695
  )
1648
1696
  )
1649
1697
  ):
1650
- if self.pronouns["she/her/hers"]:
1698
+ if pronouns.get("she/her/hers"):
1651
1699
  output = word("she", **kwargs)
1652
- elif self.pronouns["he/him/his"]:
1700
+ elif pronouns.get("he/him/his"):
1653
1701
  output = word("he", **kwargs)
1654
- elif self.pronouns["they/them/theirs"]:
1702
+ elif pronouns.get("they/them/theirs"):
1655
1703
  output = word("they", **kwargs)
1656
- elif self.pronouns["ze/zir/zirs"]:
1704
+ elif pronouns.get("ze/zir/zirs"):
1657
1705
  output = word("ze", **kwargs)
1658
- elif self.pronouns.get("self-described"):
1706
+ elif pronouns.get("self-described"):
1659
1707
  output = parse_custom_pronouns(self.pronouns_self_described)["s"]
1660
1708
  elif hasattr(self, "person_type") and self.person_type in [
1661
1709
  "business",
@@ -2078,7 +2126,7 @@ def get_visible_al_nav_items(
2078
2126
 
2079
2127
  # For dictionaries at top level
2080
2128
  item_copy = deepcopy(item)
2081
- if not item_copy.pop("hidden", False): # if not hidden
2129
+ if not str(item_copy.pop("hidden", "False")).lower() == "true": # if not hidden
2082
2130
  for key, val in item_copy.items():
2083
2131
  if isinstance(val, list): # if value of a key is a list
2084
2132
  new_sublist: List[Union[str, dict]] = []
@@ -2087,8 +2135,10 @@ def get_visible_al_nav_items(
2087
2135
  if isinstance(subitem, str):
2088
2136
  new_sublist.append(subitem)
2089
2137
  # Add dictionaries if not hidden
2090
- elif isinstance(subitem, dict) and not subitem.pop(
2091
- "hidden", False
2138
+ elif (
2139
+ isinstance(subitem, dict)
2140
+ and not str(subitem.pop("hidden", "False")).lower()
2141
+ == "true"
2092
2142
  ):
2093
2143
  new_sublist.append(subitem)
2094
2144
  item_copy[key] = new_sublist
@@ -71,19 +71,17 @@ subquestion: |
71
71
  fields:
72
72
  - note: |
73
73
  ${ display_template(al_terms_of_use, scrollable=True) }
74
- - To continue, you must accept our terms of use: acknowledged_information_use
75
- datatype: checkboxes
76
- none of the above: False
77
- minlength: 1
78
- choices:
79
- - I accept the terms of use.
80
- validation messages:
81
- minlength: |
82
- You cannot continue unless you agree to the terms of use.
74
+ To continue, you must accept our terms of use
75
+ - I accept the terms of use: acknowledged_information_use
76
+ datatype: yesnowide
77
+ grid: 8
83
78
  continue button field: al_intro_screen
84
79
  terms:
85
80
  green words: |
86
81
  Green words are legal terms or a short way of referring to something that needs more explanation. The definition or explanation pops up when you tap the green words.
82
+ validation code: |
83
+ if not acknowledged_information_use:
84
+ validation_error("You must accept the terms of use to continue.", field="acknowledged_information_use")
87
85
  ---
88
86
  ##### Backwards compatibility #####
89
87
  code: |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: docassemble.AssemblyLine
3
- Version: 2.28.0
3
+ Version: 2.28.1
4
4
  Home-page: https://courtformsonline.org
5
5
  Author: Suffolk Legal Innovation and Technology Lab
6
6
  Author-email: qsteenhuis@suffolk.edu
@@ -44,7 +44,7 @@ def find_package_data(where='.', package='', exclude=standard_exclude, exclude_d
44
44
  return out
45
45
 
46
46
  setup(name='docassemble.AssemblyLine',
47
- version='2.28.0',
47
+ version='2.28.1',
48
48
  description=(''),
49
49
  long_description='# Suffolk LIT Lab Document Assembly Line\r\n\r\n[![PyPI version](https://badge.fury.io/py/docassemble-AssemblyLine.svg)](https://badge.fury.io/py/docassemble-AssemblyLine)\r\n\r\n<img src="https://user-images.githubusercontent.com/7645641/142245862-c2eb02ab-3090-4e97-9653-bb700bf4c54d.png" alt="drawing" width="300" alt="work together" style="align: center;"/>\r\n\r\nThe Assembly Line Project is a collection of volunteers, students, and institutions who joined together\r\nduring the COVID-19 pandemic to help increase access to the court system. Our vision is mobile-friendly,\r\neasy to use **guided** online forms that help empower litigants to access the court remotely.\r\n\r\nOur signature project is [CourtFormsOnline.org](https://courtformsonline.org).\r\n\r\nWe designed a step-by-step, assembly line style process for automating court forms on top of Docassemble\r\nand built several tools along the way that **you** can use in your home jurisdiction.\r\n\r\nThis package contains **runtime code** and **pre-written questions** to support authoring robust, \r\nconsistent, and attractive Docassemble interviews that help complete court forms.\r\n\r\nRead more on our [documentation page](https://suffolklitlab.org/docassemble-AssemblyLine-documentation/).\r\n\r\n\r\n# Related repositories\r\n\r\n* https://github.com/SuffolkLitLab/docassemble-ALWeaver\r\n* https://github.com/SuffolkLitLab/docassemble-ALMassachusetts\r\n* https://github.com/SuffolkLitLab/docassemble-MassAccess\r\n* https://github.com/SuffolkLitLab/docassemble-ALThemeTemplate\r\n* https://github.com/SuffolkLitLab/EfileProxyServer\r\n\r\n# Documentation\r\n\r\nhttps://suffolklitlab.org/docassemble-AssemblyLine-documentation/\r\n\r\n# Installation\r\n\r\n## Menu-driven installation\r\n\r\nThe recommended installation method is with the [guided installation script](https://suffolklitlab.org/docassemble-AssemblyLine-documentation/docs/installation).\r\n\r\n## Manual installation\r\n\r\nNormally you do not need to manually install the Assembly Line. Use the [installation script](https://suffolklitlab.org/docassemble-AssemblyLine-documentation/docs/installation)\r\nif you can. The instructions below are for your optional reference.\r\n\r\nThis package depends on the following configuration changes on your Docassemble server:\r\n\r\n* Ensure that [font-awesome](https://docassemble.org/docs/config.html#default%20icons) is enabled (this may be on by default:\r\n```yaml\r\ndefault icons: font awesome\r\n```\r\n* Add a [Google API key](https://docassemble.org/docs/config.html#google) that has access to:\r\n * Google Places API\r\n * Google Geocoding API\r\n* Add a [VoiceRSS API key](https://docassemble.org/docs/config.html#voicerss)\r\n* Add a [Twilio API key](https://docassemble.org/docs/config.html#twilio) for SMS support\r\n* Add an email account: [Mailgun](https://docassemble.org/docs/config.html#mailgun%20api) or [SendGrid](https://docassemble.org/docs/config.html#sendgrid%20api) recommended for email support\r\n* To show package update time and to enable the feedback form, add a GitHub Private Access token to your config.yml file, like this:\r\n```yaml\r\n# Needs access to create new issues on repositories\r\ngithub issues:\r\n username: "suffolklitlab-issues"\r\n token: "12345"\r\n# Does not need any special access to public repositories \r\ngithub readonly:\r\n username: "suffolklitlab-issues"\r\n password: "45678"\r\n type: "basic"\r\n```\r\n* If you are also using the [Assembly Line Weaver](https://github.com/SuffolkLITLab/docassemble-assemblylinewizard), you may want to set up a [Docassemble API key](https://docassemble.org/docs/api.html#manage_api) in your config.yml file to allow you to install packages automatically, like this:\r\n```yaml\r\ninstall packages api key: 12345\r\n```\r\n\r\n# Migration\r\n\r\nSee [discussion here](https://github.com/SuffolkLITLab/docassemble-AssemblyLine/issues/69)\r\n\r\n\r\n# ALDocument class\r\n\r\n## Purpose\r\n\r\nThe ALDocument class is a small utility library that makes it simpler to use the following features in an interview:\r\n\r\n* Conditional assembly of multiple, optional documents that are triggered in different ways in your interview\r\n* An addendum for PDF files that makes it simple to deal with overflow text\r\n* A customizable download screen that lists the documents in a neat table\r\n* A customizable "send" button that allows the user to email the final forms to a location of their choice\r\n\r\nHere is a small snippet that you can copy and modify that shows how to use the most important features of the ALDocument class.\r\n\r\n```\r\n---\r\nobjects:\r\n - CRA_Motion_to_Dismiss_attachment: ALDocument.using(filename="CRA_Motion_to_Dismiss", title="Motion to Dismiss CRA", enabled=True, has_addendum=True, default_overflow_message="[See addendum]") \r\n---\r\nobjects:\r\n - al_user_bundle: ALDocumentBundle.using(elements=[CRA_Motion_to_Dismiss_attachment], title="Forms to download and deliver to court", filename="motion_to_dismiss_CRA.pdf")\r\n - al_court_bundle: ALDocumentBundle.using(elements=[CRA_Motion_to_Dismiss_attachment], title="Forms to download and deliver to court", filename="motion_to_dismiss_CRA.pdf")\r\n---\r\ngeneric object: ALDocument\r\nattachment:\r\n variable name: x.addendum\r\n docx template file: docx_addendum.docx\r\n---\r\ncode: |\r\n CRA_Motion_to_Dismiss_attachment.overflow_fields[\'reasons_for_request\'].overflow_trigger = 640\r\n CRA_Motion_to_Dismiss_attachment.overflow_fields[\'reasons_for_request\'].label = "Reasons for request"\r\n CRA_Motion_to_Dismiss_attachment.overflow_fields.gathered = True\r\n \r\n---\r\nattachment:\r\n variable name: CRA_Motion_to_Dismiss_attachment[i]\r\n name: CRA Motion to Dismiss\r\n filename: CRA_Motion_to_Dismiss\r\n skip undefined: True\r\n pdf template file: CRA_Motion_to_Dismiss.pdf\r\n fields: \r\n - "court_county": ${ trial_court.address.county }\r\n - "docket_number": ${ docket_number }\r\n - "user_signature": ${ users[0].signature_if_final(i) }\r\n - "signature_date": ${ signature_date }\r\n```\r\n\r\nIt is very common to have a *contingent* document in ALDocument. If your document is contingent, remove the `enabled=True` from the object declaration, and use\r\nsome other method to "turn on" the attachment.\r\n\r\nE.g.,\r\n\r\n```\r\ncode: |\r\n CRA_Motion_to_Dismiss_attachment.enabled = condition1 and condition2\r\n```\r\n\r\n# Changelog\r\n\r\nSee [CHANGELOG.MD](https://github.com/SuffolkLITLab/docassemble-AssemblyLine/blob/main/CHANGELOG.md)\r\n',
50
50
  long_description_content_type='text/markdown',
@@ -1 +0,0 @@
1
- __version__ = '2.28.0'