approveflow/app/provider/flow_definition/service.go

281 lines
9.1 KiB
Go

package flow_definition
import (
"approveflow/app/provider/abstract/connect"
"context"
"fmt"
"github.com/Superdanda/hade/framework"
"github.com/Superdanda/hade/framework/contract"
"github.com/pkg/errors"
)
type FlowDefinitionService struct {
container framework.Container
}
func (f *FlowDefinitionService) CreateFlow(ctx context.Context, flow *ApprovalFlow) error {
return f.GetFlowRepository().SaveFlow(ctx, flow)
}
func (f *FlowDefinitionService) GetFlow(ctx context.Context, flowID int64) (*ApprovalFlow, error) {
return f.GetFlowRepository().GetFlowByID(ctx, flowID)
}
func (f *FlowDefinitionService) GetFlowPage(ctx context.Context, pageNum, pageSize int, flow *ApprovalFlow) ([]*ApprovalFlow, int64, error) {
return f.GetFlowRepository().ListFlows(ctx, pageNum, pageSize, flow)
}
func (f *FlowDefinitionService) UpdateFlow(ctx context.Context, flow *ApprovalFlow) error {
return f.GetFlowRepository().SaveFlow(ctx, flow)
}
func (f *FlowDefinitionService) DeleteFlow(ctx context.Context, flowID int64) error {
flowById, err := f.GetFlowRepository().GetFlowByID(ctx, flowID)
if err != nil {
return err
}
flowById.Delete()
return f.GetFlowRepository().SaveFlow(ctx, flowById)
}
func (f *FlowDefinitionService) AddStepWithPosition(ctx context.Context, flowID int64, step *ApprovalStep, fromStepId string, toStepKey string) error {
return f.handlerFlow(ctx, flowID, func(ctx context.Context, flow *ApprovalFlow) error {
fromStep, err := flow.GetStepByKey(fromStepId)
toStep, err := flow.GetStepByKey(toStepKey)
if err != nil {
return err
}
err = connect.InsertNodeBetween(flow, fromStep, toStep, step)
return err
})
}
func (f *FlowDefinitionService) AddStep(ctx context.Context, flowID int64, step *ApprovalStep) error {
flowById, err := f.GetFlowRepository().GetFlowByID(ctx, flowID)
if err != nil {
return err
}
err = flowById.AddStep(step)
if err != nil {
return err
}
return f.GetFlowRepository().SaveFlow(ctx, flowById)
}
func (f *FlowDefinitionService) GetSteps(ctx context.Context, flowID int64) ([]*ApprovalStep, error) {
flowById, err := f.GetFlowRepository().GetFlowByID(ctx, flowID)
if err != nil {
return nil, err
}
return flowById.Steps, nil
}
func (f *FlowDefinitionService) UpdateStep(ctx context.Context, flowID int64, step *ApprovalStep) error {
flowById, err := f.GetFlowRepository().GetFlowByID(ctx, flowID)
if err != nil {
return err
}
steps := flowById.Steps
for index, stepExist := range steps {
if stepExist.ID == step.ID {
steps[index] = step
}
}
return nil
}
func (f *FlowDefinitionService) DeleteStep(ctx context.Context, flowID int64, stepID int64) error {
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
step.Delete()
return nil
})
}
func (f *FlowDefinitionService) AddRule(ctx context.Context, flowID int64, stepID int64, rule *ApprovalRule) error {
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
step.Rules = append(step.Rules, rule)
return nil
})
}
func (f *FlowDefinitionService) GetRules(ctx context.Context, flowID int64, stepID int64) ([]*ApprovalRule, error) {
_, id, err := f.findStepByStepId(ctx, flowID, stepID)
if err != nil {
return nil, err
}
return id.Rules, nil
}
func (f *FlowDefinitionService) UpdateRule(ctx context.Context, flowID int64, stepID int64, rule *ApprovalRule) error {
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
existingRule, err := step.GetRuleById(rule.ID)
if err != nil {
return err
}
// Update the fields of the existing rule
existingRule.Name = rule.Name
existingRule.Action = rule.Action
existingRule.Priority = rule.Priority
existingRule.ConditionExpression = rule.ConditionExpression
return nil
})
}
func (f *FlowDefinitionService) DeleteRule(ctx context.Context, flowID int64, stepID int64, ruleID int64) error {
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
rule, err := step.GetRuleById(ruleID)
if err != nil {
return err
}
rule.Delete()
return nil
})
}
func (f *FlowDefinitionService) AddDynamicStepConfig(ctx context.Context, flowID int64, stepID int64, config *DynamicApprovalStepConfig) error {
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
step.AddDynamicConfig(config)
return nil
})
}
func (f *FlowDefinitionService) GetDynamicStepConfigs(ctx context.Context, flowID int64) ([]*DynamicApprovalStepConfig, error) {
// Retrieve dynamic configurations for the flow
flowByID, err := f.GetFlowRepository().GetFlowByID(ctx, flowID)
if err != nil {
return nil, err
}
configs := make([]*DynamicApprovalStepConfig, 0, len(flowByID.Steps))
for _, step := range flowByID.Steps {
configs = append(configs, step.DynamicConfig)
}
return configs, nil
}
func (f *FlowDefinitionService) UpdateDynamicStepConfig(ctx context.Context, flowID int64, stepID int64, config *DynamicApprovalStepConfig) error {
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
dynamicConfig := step.DynamicConfig
// Update the fields of the existing dynamicConfig
dynamicConfig.Name = config.Name
dynamicConfig.Action = config.Action
dynamicConfig.Priority = config.Priority
dynamicConfig.ConditionExpression = config.ConditionExpression
return nil
})
}
func (f *FlowDefinitionService) DeleteDynamicStepConfig(ctx context.Context, flowID int64, stepID int64) error {
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
step.DynamicConfig.Delete()
return nil
})
}
func (f *FlowDefinitionService) AddPathConfig(ctx context.Context, flowID int64, stepID int64, config *ApprovalPathConfig) error {
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
return step.AddPathConfig(config)
})
}
func (f *FlowDefinitionService) GetPathConfigs(ctx context.Context, flowID int64) ([]*ApprovalPathConfig, error) {
// Retrieve dynamic configurations for the flow
flowByID, err := f.GetFlowRepository().GetFlowByID(ctx, flowID)
if err != nil {
return nil, err
}
// Extract PathConfigs from each step in the flow
var configs []*ApprovalPathConfig
for _, step := range flowByID.Steps {
configs = append(configs, step.PathConfigs...)
}
return configs, nil
}
func (f *FlowDefinitionService) UpdatePathConfig(ctx context.Context, flowID int64, stepID int64, config *ApprovalPathConfig) error {
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
pathById, err := step.GetPathById(config.ID)
if err != nil {
return err
}
pathById.ToNodeKey = config.ToNodeKey
pathById.IsParallel = config.IsParallel
pathById.ConditionExpression = config.ConditionExpression
return nil
})
}
func (f *FlowDefinitionService) DeletePathConfig(ctx context.Context, flowID int64, stepID int64, pathID int64) error {
return f.handlerStep(ctx, flowID, stepID, func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error {
pathById, err := step.GetPathById(pathID)
if err != nil {
return err
}
pathById.Delete()
return nil
})
}
func (f *FlowDefinitionService) handlerStep(
ctx context.Context,
flowID int64,
stepID int64,
handler func(ctx context.Context, flow *ApprovalFlow, step *ApprovalStep) error,
) error {
flowById, step, err := f.findStepByStepId(ctx, flowID, stepID)
if err != nil {
return err
}
if step == nil {
return fmt.Errorf("step with ID %d not found in flow %d", stepID, flowID)
}
err = handler(ctx, flowById, step)
if err != nil {
return err
}
return f.GetFlowRepository().SaveFlow(ctx, flowById)
}
func (f *FlowDefinitionService) handlerFlow(ctx context.Context,
flowID int64,
handler func(ctx context.Context, flow *ApprovalFlow) error,
) error {
flowById, err := f.GetFlowRepository().GetFlowByID(ctx, flowID)
if err != nil {
return err
}
err = handler(ctx, flowById)
if err != nil {
return err
}
return f.GetFlowRepository().SaveFlow(ctx, flowById)
}
func (f *FlowDefinitionService) findStepByStepId(ctx context.Context, flowID int64, stepID int64) (*ApprovalFlow, *ApprovalStep, error) {
// Retrieve the flow to confirm it exists
flowByID, err := f.GetFlowRepository().GetFlowByID(ctx, flowID)
if err != nil {
return nil, nil, err
}
var step *ApprovalStep
for _, s := range flowByID.Steps {
if s.ID == stepID {
step = s
break
}
}
if step == nil {
return nil, nil, errors.New("step not found")
}
return flowByID, step, nil
}
func NewFlowDefinitionService(params ...interface{}) (interface{}, error) {
container := params[0].(framework.Container)
return &FlowDefinitionService{container: container}, nil
}
func (f *FlowDefinitionService) GetFlowRepository() FlowRepository {
infrastructureService := f.container.MustMake(contract.InfrastructureKey).(contract.InfrastructureService)
return infrastructureService.GetModuleOrmRepository(FlowRepositoryKey).(FlowRepository)
}