Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 [Bugfix] Fixed issues while creating major version #2332

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -406,7 +407,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 @@ -309,6 +309,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 @@ -350,64 +351,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 = FormProcessMapperService.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 = FormProcessMapperService.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 @@ -381,7 +381,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