Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…low-ai into FWF-3718-workflow-migration
  • Loading branch information
auslin-aot committed Nov 7, 2024
2 parents 6dd55c2 + 519544a commit b32ace0
Show file tree
Hide file tree
Showing 37 changed files with 1,672 additions and 1,771 deletions.
2 changes: 1 addition & 1 deletion forms-flow-api/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ exceptiongroup==1.2.2
flask-jwt-oidc==0.7.0
flask-marshmallow==1.2.1
flask-restx==1.3.0
formsflow_api_utils @ git+https://github.com/auslin-aot/forms-flow-ai.git@fwf-3769-form-validation-changes#subdirectory=forms-flow-api-utils
formsflow_api_utils @ git+https://github.com/AOT-Technologies/forms-flow-ai.git@develop#subdirectory=forms-flow-api-utils
gunicorn==23.0.0
h11==0.14.0
h2==4.1.0
Expand Down
2 changes: 1 addition & 1 deletion forms-flow-api/requirements/prod.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ markupsafe
PyJWT
redis
lxml
git+https://github.com/auslin-aot/forms-flow-ai.git@fwf-3769-form-validation-changes#subdirectory=forms-flow-api-utils
git+https://github.com/AOT-Technologies/forms-flow-ai.git@develop#subdirectory=forms-flow-api-utils
2 changes: 1 addition & 1 deletion forms-flow-api/src/formsflow_api/constants/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class BusinessErrorCode(ErrorCodeMixin, Enum):
HTTPStatus.BAD_REQUEST,
)
PROCESS_EXISTS = (
"The BPMN name or ID already exists. It must be unique.",
"The Process name or ID already exists. It must be unique.",
HTTPStatus.BAD_REQUEST,
)
INVALID_PROCESS_VALIDATION_INPUT = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,14 +389,9 @@ def find_all_active_forms(
@classmethod
def find_forms_by_title(cls, form_title, exclude_id) -> FormProcessMapper:
"""Find all form process mapper that matches the provided form title."""
query = cls.query.filter(
and_(
FormProcessMapper.form_name == form_title,
FormProcessMapper.deleted.is_(False),
)
)
query = cls.query.filter(FormProcessMapper.form_name == form_title)
if exclude_id is not None:
query = query.filter(FormProcessMapper.id != exclude_id)
query = query.filter(FormProcessMapper.parent_form_id != exclude_id)
query = cls.tenant_authorization(query=query)
return query.all()

Expand Down
3 changes: 2 additions & 1 deletion forms-flow-api/src/formsflow_api/resources/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from flask_restx import Namespace, Resource, fields
from formsflow_api_utils.utils import (
CREATE_DESIGNS,
VIEW_DESIGNS,
auth,
cors_preflight,
profiletime,
Expand Down Expand Up @@ -408,7 +409,7 @@ class ProcessResourceByProcessKey(Resource):
"""Resource for managing process by process key."""

@staticmethod
@auth.has_one_of_roles([CREATE_DESIGNS])
@auth.has_one_of_roles([CREATE_DESIGNS, VIEW_DESIGNS])
@profiletime
@API.doc(
responses={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class Meta: # pylint: disable=too-few-public-methods
process_name = fields.Str(data_key="processName")
comments = fields.Str(data_key="comments")
is_anonymous = fields.Bool(data_key="anonymous")
status = fields.Str(data_key="status") # active/inactive
status = fields.Str(data_key="status", allow_none=True) # active/inactive
created_by = fields.Str(data_key="createdBy")
created = fields.Str(data_key="created")
modified_by = fields.Str(data_key="modifiedBy")
Expand Down
104 changes: 71 additions & 33 deletions forms-flow-api/src/formsflow_api/services/form_process_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ def mark_inactive_and_delete(form_process_mapper_id: int, **kwargs) -> None:
@staticmethod
def mark_unpublished(form_process_mapper_id):
"""Mark form process mapper as inactive."""
mapper = FormProcessMapper.find_form_by_id_active_status(
mapper = FormProcessMapper.find_form_by_id(
form_process_mapper_id=form_process_mapper_id
)
if mapper:
Expand Down Expand Up @@ -302,6 +302,7 @@ def validate_process_and_update_mapper(name, mapper):
@staticmethod
def mapper_create(mapper_json):
"""Service to handle mapper create."""
current_app.logger.debug("Creating mapper..")
mapper_json["taskVariables"] = json.dumps(
mapper_json.get("taskVariables") or []
)
Expand Down Expand Up @@ -343,64 +344,101 @@ def create_default_process(cls, process_name, status=ProcessStatus.DRAFT, **kwar
return process

@staticmethod
def create_form(data, is_designer):
def create_form(data, is_designer): # pylint:disable=too-many-locals
"""Service to handle form create."""
current_app.logger.info("Creating form..")
# Initialize formio service and get formio token to create the form
formio_service = FormioService()
form_io_token = formio_service.get_formio_access_token()
# creating form and get response from formio
response = formio_service.create_form(data, form_io_token)
form_id = response.get("_id")
parent_form_id = data.get("parentFormId", form_id)
# create default data form mapper table
process_name = response.get("name")
# process key/Id doesn't support numbers & special characters at start
# special characters anywhere so clean them before setting as process key
process_name = ProcessService.clean_form_name(process_name)
# is_new_form=True if creating a new form, False if creating a new version
is_new_form = parent_form_id == form_id
process_key = None
anonymous = False
description = data.get("description", "")
task_variable = []
current_app.logger.info(f"Creating new form {is_new_form}")
# If creating new version for a existing form, fetch process key, name from mapper
if not is_new_form:
current_app.logger.debug("Fetching details from mapper")
mapper = FormProcessMapper.get_latest_by_parent_form_id(parent_form_id)
process_name = mapper.process_name
process_key = mapper.process_key
anonymous = mapper.is_anonymous
description = mapper.description
task_variable = json.loads(mapper.task_variable)
else:
# if new form, form name is kept as process_name & process key
process_name = response.get("name")
# process key/Id doesn't support numbers & special characters at start
# special characters anywhere so clean them before setting as process key
process_name = ProcessService.clean_form_name(process_name)

mapper_data = {
"formId": form_id,
"formName": response.get("title"),
"description": data.get("description", ""),
"description": description,
"formType": response.get("type"),
"processKey": process_name,
"processName": process_name,
"processName": process_key if process_key else process_name,
"formTypeChanged": True,
"parentFormId": parent_form_id,
"titleChanged": True,
"formRevisionNumber": "V1",
"status": FormProcessMapperStatus.INACTIVE.value,
"anonymous": anonymous,
"task_variable": task_variable,
}
# create default data for authorization of the resource
authorization_data = {
"application": {
"resourceId": parent_form_id,
"resourceDetails": {},
"roles": [],
},
"designer": {
"resourceId": parent_form_id,
"resourceDetails": {},
"roles": [],
},
"form": {"resourceId": parent_form_id, "resourceDetails": {}, "roles": []},
}

mapper = FormProcessMapperService.mapper_create(mapper_data)
AuthorizationService.create_or_update_resource_authorization(
authorization_data, is_designer=is_designer
)
# validate process key already exists, if exists append mapper id to process_key.
FormProcessMapperService.validate_process_and_update_mapper(
process_name, mapper
)
current_app.logger.debug("Creating form log with clone..")
FormHistoryService.create_form_log_with_clone(
data={
**response,
"parentFormId": data.get("parentFormId", form_id),
"parentFormId": parent_form_id,
"newVersion": True,
"componentChanged": True,
}
)
# create entry in process with default flow.
FormProcessMapperService.create_default_process(process_name)
if is_new_form:
# create default data for authorization of the resource
authorization_data = {
"application": {
"resourceId": parent_form_id,
"resourceDetails": {},
"roles": [],
},
"designer": {
"resourceId": parent_form_id,
"resourceDetails": {},
"roles": [],
},
"form": {
"resourceId": parent_form_id,
"resourceDetails": {},
"roles": [],
},
}
current_app.logger.debug(
"Creating default data for authorization of the resource.."
)
AuthorizationService.create_or_update_resource_authorization(
authorization_data, is_designer=is_designer
)
# validate process key already exists, if exists append mapper id to process_key.
updated_process_name = (
FormProcessMapperService.validate_process_and_update_mapper(
process_name, mapper
)
)
process_name = (
updated_process_name if updated_process_name else process_name
)
# create entry in process with default flow.
FormProcessMapperService.create_default_process(process_name)
return response

def _get_form( # pylint: disable=too-many-arguments, too-many-positional-arguments
Expand Down
6 changes: 4 additions & 2 deletions forms-flow-api/src/formsflow_api/services/import_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,9 @@ def validate_form_title(self, title, mapper):
"""Validate form tile in the form_process_mapper table."""
# Exclude the current mapper from the query
current_app.logger.info(f"Validation for form title...{title}")
mappers = FormProcessMapper.find_forms_by_title(title, exclude_id=mapper.id)
mappers = FormProcessMapper.find_forms_by_title(
title, exclude_id=mapper.parent_form_id
)
if mappers:
current_app.logger.debug(f"Other mappers matching the title- {mappers}")
raise BusinessException(BusinessErrorCode.FORM_EXISTS)
Expand Down Expand Up @@ -417,7 +419,7 @@ def import_form(
"description": mapper.description if form_only else description,
}
FormProcessMapperService.mapper_create(mapper_data)
FormProcessMapperService.mark_inactive_and_delete(mapper.id)
FormProcessMapperService.mark_unpublished(mapper.id)
else:
current_app.logger.info("Form import minor version inprogress...")
form_id = mapper.form_id
Expand Down
2 changes: 1 addition & 1 deletion forms-flow-api/tests/unit/api/test_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ def test_process_validation_invalid(self, app, client, session, jwt):
assert response.status_code == 400
assert (
response.json.get("message")
== "The BPMN name or ID already exists. It must be unique."
== "The Process name or ID already exists. It must be unique."
)

def test_process_validate_missing_params(app, client, session, jwt):
Expand Down
Loading

0 comments on commit b32ace0

Please sign in to comment.