Example #1
0
def cache_field_values(doc: Document,
                       suggested_field_values: Optional[
                           List[DetectedFieldValue]],
                       save: bool = True) -> Dict[str, Any]:
    """
    Loads DocumentFieldValue objects from DB, merges them to get python field values of their fields for the document,
    converts them to the sortable DB-aware form and saves them to Document.field_values.
    :param doc:
    :param save:
    :param suggested_field_values:
    :return:
    """
    document_type = doc.document_type  # type: DocumentType
    # TODO: get/save field value for specific field
    all_fields = list(document_type.fields.all())

    fields_to_field_values = {f: None for f in all_fields}

    for fv in doc.documentfieldvalue_set.all():
        if fv.removed_by_user:
            continue

        field = fv.field
        field_type = FIELD_TYPES_REGISTRY[fv.field.type]  # type: FieldType
        fields_to_field_values[field] = field_type \
            .merge_multi_python_values(fields_to_field_values.get(field), fv.python_value)

    field_uids_to_field_values_db = {}

    for f in all_fields:  # type: DocumentField
        field_type = FIELD_TYPES_REGISTRY[f.type]  # type: FieldType
        v = fields_to_field_values[f]
        field_uids_to_field_values_db[
            f.uid] = field_type.merged_python_value_to_db(v)

    if suggested_field_values:
        field_codes_to_suggested_values = \
            merge_detected_field_values_to_python_value(suggested_field_values)  # type: Dict[str, Any]
    else:
        field_codes_to_suggested_values = None

    for f in all_fields:  # type: DocumentField
        field_type = f.get_field_type()  # type: FieldType
        if f.is_detectable():
            suggested_field_uid = Document.get_suggested_field_uid(f.uid)
            if field_codes_to_suggested_values:
                suggested_value_db = field_type.merged_python_value_to_db(
                    field_codes_to_suggested_values.get(f.code))
            else:
                suggested_value_db = doc.field_values.get(
                    suggested_field_uid) if doc.field_values else None

            field_uids_to_field_values_db[
                suggested_field_uid] = suggested_value_db

    if save:
        doc.field_values = field_uids_to_field_values_db
        doc.save()

    return field_uids_to_field_values_db
Example #2
0
def cache_field_values(doc: Document,
                       suggested_field_values: Optional[
                           List[DetectedFieldValue]],
                       save: bool = True,
                       log: ProcessLogger = None) -> Dict[str, Any]:
    """
    Loads DocumentFieldValue objects from DB, merges them to get python field values of their fields for the document,
    converts them to the sortable DB-aware form and saves them to Document.field_values.
    :param doc:
    :param save:
    :param suggested_field_values:
    :param log
    :return:
    """
    document_type = doc.document_type  # type: DocumentType
    # TODO: get/save field value for specific field
    all_fields = list(document_type.fields.all())

    related_info_field_uids = {
        f.uid
        for f in all_fields if f.is_related_info_field()
    }

    fields_to_field_values = {f: None for f in all_fields}

    for fv in doc.documentfieldvalue_set.all():
        if fv.removed_by_user:
            continue

        field = fv.field
        field_type = FIELD_TYPES_REGISTRY[fv.field.type]  # type: FieldType
        fields_to_field_values[field] = field_type \
            .merge_multi_python_values(fields_to_field_values.get(field), fv.python_value)

    field_uids_to_field_values_db = {}

    for f in all_fields:  # type: DocumentField
        field_type = FIELD_TYPES_REGISTRY[f.type]  # type: FieldType
        v = fields_to_field_values[f]
        field_uids_to_field_values_db[
            f.uid] = field_type.merged_python_value_to_db(v)

    if suggested_field_values:
        field_codes_to_suggested_values = \
            merge_detected_field_values_to_python_value(suggested_field_values)  # type: Dict[str, Any]
    else:
        field_codes_to_suggested_values = None

    for f in all_fields:  # type: DocumentField
        field_type = f.get_field_type()  # type: FieldType
        if f.is_detectable():
            suggested_field_uid = Document.get_suggested_field_uid(f.uid)
            if field_codes_to_suggested_values:
                suggested_value_db = field_type.merged_python_value_to_db(
                    field_codes_to_suggested_values.get(f.code))
            else:
                suggested_value_db = doc.field_values.get(
                    suggested_field_uid) if doc.field_values else None

            field_uids_to_field_values_db[
                suggested_field_uid] = suggested_value_db

    if save:
        doc.field_values = {
            uid: len(value)
            if uid in related_info_field_uids and value is not None else value
            for uid, value in field_uids_to_field_values_db.items()
        }
        doc.save()
        events.on_document_change(
            events.DocumentChangedEvent(
                log=log,
                document=doc,
                system_fields_changed=False,
                generic_fields_changed=False,
                user_fields_changed=True,
                pre_detected_field_values=field_codes_to_suggested_values))

    return field_uids_to_field_values_db
def cache_field_values(doc: Document,
                       suggested_field_values: Optional[List[DetectedFieldValue]],
                       save: bool = True,
                       log: ProcessLogger = None,
                       changed_by_user: User = None,
                       system_fields_changed: bool = False,
                       generic_fields_changed: bool = False,
                       document_initial_load: bool = False) -> Dict[str, Any]:
    """
    Loads DocumentFieldValue objects from DB, merges them to get python field values of their fields for the document,
    converts them to the sortable DB-aware form and saves them to Document.f i eld_values.
    :param doc:
    :param save:
    :param suggested_field_values:
    :param log
    :param changed_by_user
    :param system_fields_changed
    :param generic_fields_changed
    :param document_initial_load
    :return:
    """
    document_type = doc.document_type  # type: DocumentType
    # TODO: get/save field value for specific field
    all_fields = list(document_type.fields.all())

    related_info_field_uids = {f.uid for f in all_fields if f.is_related_info_field()}

    fields_to_field_values = {f: None for f in all_fields}

    for fv in doc.documentfieldvalue_set.all():
        if fv.removed_by_user:
            continue

        field = fv.field
        field_type = fv.field.get_field_type()  # type: FieldType
        fields_to_field_values[field] = field_type \
            .merge_multi_python_values(fields_to_field_values.get(field), fv.python_value)

    field_uids_to_field_values_db = {}

    for f in all_fields:  # type: DocumentField
        field_type = f.get_field_type()  # type: FieldType
        v = fields_to_field_values[f]
        field_uids_to_field_values_db[f.uid] = field_type.merged_python_value_to_db(v)

    if suggested_field_values:
        field_codes_to_suggested_values = \
            merge_detected_field_values_to_python_value(suggested_field_values)  # type: Dict[str, Any]
    else:
        field_codes_to_suggested_values = None

    for f in all_fields:  # type: DocumentField
        field_type = f.get_field_type()  # type: FieldType
        if f.is_detectable():
            suggested_field_uid = Document.get_suggested_field_uid(f.uid)
            if field_codes_to_suggested_values:
                suggested_value_db = field_type.merged_python_value_to_db(field_codes_to_suggested_values.get(f.code))
            else:
                suggested_value_db = field_uids_to_field_values_db.get(suggested_field_uid)

            # suggested_value_db can be list, None or int, Iterable validation should be here
            if isinstance(suggested_value_db, Iterable) and f.is_related_info_field():
                suggested_value_db = len(suggested_value_db)
            field_uids_to_field_values_db[suggested_field_uid] = suggested_value_db

    if save:
        signals.fire_document_changed(sender=cache_field_values,
                                      changed_by_user=changed_by_user,
                                      log=log,
                                      document=doc,
                                      system_fields_changed=system_fields_changed,
                                      generic_fields_changed=generic_fields_changed,
                                      user_fields_changed=True,
                                      pre_detected_field_values=field_codes_to_suggested_values,
                                      document_initial_load=document_initial_load)

    return field_uids_to_field_values_db