def mark_unfilled_fields_empty(interview_metadata_dict):
    """Given an interview metadata dictionary, transform any un-filled fields into DAEmpty()"""
    for field_dict in interview_metadata_dict.get(
            'field_list', []) + interview_metadata_dict.get(
                'built_in_fields_used', []):
        try:
            field = field_dict[
                'variable']  # Our list of fields is a dictionary
        except:
            continue
        # Make sure we don't try to define a method
        # Also, don't set any signatures to DAEmpty
        if not map_names(field).endswith(
                '.signature') and not '(' in map_names(field):
            if not defined(map_names(field)):
                define(map_names(field),
                       '')  # set to special Docassemble empty object
                #define(map_names(field), DAEmpty()) # set to special Docassemble empty object
        # Handle special case of an address that we skipped filling in on the form
        elif map_names(field).endswith('address.on_one_line()'):
            individual_name = map_names(field).partition('.on_one_line')[0]
            if not defined(
                    individual_name + '.address'
            ):  # here we're checking for an empty street address attribute
                define(
                    individual_name, ''
                )  # at this point this should be something like user.address
        elif map_names(field).endswith('address.line_two()'):
            individual_name = map_names(field).partition('.line_two')[0]
            if not defined(individual_name + '.city'):
                define(individual_name, '')
def mark_unfilled_fields_empty(interview_metadata_dict):
    """Sets the listed fields that are not yet defined to an empty string. Requires an interview metadata dictionary
  as input parameter. Aid for filling in a PDF. This will not set ALL fields in the interview empty;
  only ones mentiond in the specific metadata dict."""
    # There are two dictionaries in the interview-specific metadata that list fields
    # fields and built_in_fields used. Some older interviews may use `field_list`
    # We loop over each field and check if it's already defined in the Docassemble interview's namespace
    # If it isn't, we set it to an empty string.
    for field_dict in interview_metadata_dict[
            'field_list'] + interview_metadata_dict[
                'built_in_fields_used'] + interview_metadata_dict['fields']:
        try:
            field = field_dict[
                'variable']  # Our list of fields is a dictionary
        except:
            continue
        # Make sure we don't try to define a method
        # Also, don't set any signatures to DAEmpty
        # This will not work on a method call, other than the 3 we explicitly handle:
        # address.line_two(), address.on_one_line(), and address.block()
        # Empty strings will break this
        if field and not map_names(field).endswith(
                '.signature') and not '(' in map_names(field):
            if not defined(map_names(field)):
                define(map_names(field), '')  # set to an empty string
                #define(map_names(field), 'DAEmpty()') # set to special Docassemble empty object. Should work in DA > 1.1.4
        # Handle special case of an address that we skipped filling in on the form
        elif map_names(field).endswith('address.on_one_line()'):
            address_obj_name = map_names(field).partition('.on_one_line')[0]
            if not defined(
                    address_obj_name + '.address'
            ):  # here we're checking for an empty street address attribute
                # define(individual_name, '') # at this point this should be something like user.address
                try:
                    exec(address_obj_name + "= DAEmpty()")
                except:
                    pass
                # define(address_obj_name, DAEmpty())
        elif map_names(field).endswith('address.line_two()'):
            address_obj_name = map_names(field).partition('.line_two')[0]
            if not defined(address_obj_name + '.city'
                           ):  # We check for an undefined city attribute
                try:
                    exec(address_obj_name + "= DAEmpty()")
                except:
                    pass
        elif map_names(field).endswith('address.block()'):
            address_obj_name = map_names(field).partition('.block')[0]
            if not defined(address_obj_name + '.address'
                           ):  # We check for an undefined street address
                try:
                    exec(address_obj_name + "= DAEmpty()")
                except:
                    pass
def space(var_name, prefix=' ', suffix=''):
  """If the value as a string is defined, return it prefixed/suffixed. Defaults to prefix 
  of a space. Helps build a sentence with less cruft. Equivalent to SPACE function in 
  HotDocs."""
  if defined(var_name):
    return prefix + showifdef(var_name) + suffix
  else:
    return ''
def space(var_name, prefix=' ', suffix=''):
    """If the value as a string is defined, return it prefixed/suffixed. Defaults to prefix
  of a space. Helps build a sentence with less cruft. Equivalent to SPACE function in
  HotDocs."""
    if var_name and isinstance(var_name, str) and re.search(
            r'[A-Za-z][A-Za-z0-9\_]*',
            var_name) and defined(var_name) and value(var_name):
        return prefix + showifdef(var_name) + suffix
    else:
        return ''
def new_entry(name="", court_name="", court_emails=dict(), files=[]) -> str:
    """
  Creates a new upload entry in the database
  
  Args:
    name (str): the name of who is completing the form
    doc_name (str): the name of the document
    court_name (str): the name of the court to file
    file_path (str): the path of the assembled file (on disk)

  Returns (str):
    A unique ID corresponding to the current submission
  """
    if court_name not in court_emails:
        # in our system, this should never happen, but will leave in for debugging
        raise ValueError(f"Court {court_name} does not exist")

    connection = connect(**db_config)
    submission_id = None

    with connection.cursor() as cursor:
        # create a new interview submission
        cursor.execute(
            "INSERT INTO interviews (timestamp, name, court_name, user_id) VALUES (%s, %s, %s, %s) RETURNING id",
            (datetime.now(), name, court_name, get_user_id()))
        submission_id = cursor.fetchone()[0]

        # save the file metadata (NOT the files themselves)
        for file in files:
            sensitive = defined("file.sensitive") and file.sensitive
            cursor.execute(
                "INSERT INTO files (number, filename, mimetype, sensitive, submission_id) VALUES (%s, %s, %s, %s, %s)",
                (file.number, file.filename, file.mimetype, sensitive,
                 submission_id))

    connection.commit()
    connection.close()

    return str(submission_id)
示例#6
0
def optional(field: str):
    """Returns the value of the field, if it exists, otherwise empty"""
    return DAEmpty() if not defined(field) else value(field)
示例#7
0
def set_attribute_to_value(field_list, object_type, attribute, target_value=DAEmpty()):
  """If any item in the list matches object_type, set the specified attribute to DAEmpty() or other value desired"""
  for field in field_list:
    if defined(field) and isinstance(value(field), object_type):
      define(field + '.' + attribute, target_value)
def question_id(message):
    if defined("debug_enabled") and debug_enabled:
        return "[" + message + "] "
    else:
        return ""
def send_attachments(name="",
                     court_name="",
                     court_emails=dict(),
                     files=[],
                     submission_id="") -> bool:
    """
  Sends one or nore non-sensitive applications and submission info to the email of the court, court_name

  The email includes the user's name, submission id, and a list of non-sensitive forms. 
  If there are any sensitive forms in the files list, they will not be sent. 
  Instead, the recipient will be instructed to access the submission on our own site.

  Args:
    name (str): the name of the submitter
    court_name (str): the name of the court that should be receiving this email
    court_emails (dict): a dictionary mapping court names to emails
    files (List[DAFile]): a list of DAFiles (possibly sensitive) to be sent
    submission_id (str): the unique id for this submission

  Raises:
    ValueError if court_name is not in the court_emails dict

  Returns (bool):
    True if the email was sent successfully, false otherwise
  """
    if court_name not in court_emails:
        # in our system, this should never happen, but will leave in for debugging
        raise ValueError(f"Court {court_name} does not exist")

    attachments = [
        file for file in files
        if not defined("file.sensitive") or not file.sensitive
    ]
    court_email = court_emails[court_name]

    filenames = [file.filename for file in attachments]
    filenames_str = "\n".join(filenames)
    submission_url = url_for_submission(id=submission_id)

    if len(attachments) != len(files):
        if len(attachments) == 0:
            body = dedent(f"""
      Dear {court_name}:

      {name} has submitted {len(files)} online. However, these file(s) have sensitive information, and will not be sent over email.
      
      Please access these forms with the following submission id: {submission_url}.
      """)

            attachments = None
        else:
            body = dedent(f"""
      Dear {court_name}:
      
      You are receiving {len(attachments)} files from {name}:
      {filenames_str}

      However, there are also {len(files) - len(attachments)} forms which are sensitive that will not be sent over email.

      Please access these forms with the following submission id: {submission_url}.
      """)
    else:
        body = dedent(f"""
    Dear {court_name}:

    You are receiving {len(attachments)} files from {name}:
    {filenames_str}

    The reference ID for these forms is {submission_url}.
    """)

    return send_email(to=court_email,
                      subject=f"Online form submission {submission_id}",
                      body=body,
                      attachments=attachments)