Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
amos-boot-biz
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
项目统一框架
amos-boot-biz
Commits
711c7322
Commit
711c7322
authored
Mar 08, 2023
by
zhangsen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
竣工结项相关业务提交
parent
26e75f49
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
292 additions
and
5 deletions
+292
-5
OverProjectFlowEnum.java
...in/amos/boot/module/ugp/api/Enum/OverProjectFlowEnum.java
+36
-0
OverProjectDto.java
.../yeejoin/amos/boot/module/ugp/api/dto/OverProjectDto.java
+38
-0
IProjectInitiationService.java
...oot/module/ugp/api/service/IProjectInitiationService.java
+12
-0
ProjectMapper.xml
...odule-ugp-api/src/main/resources/mapper/ProjectMapper.xml
+1
-1
ProjectOverFlowController.java
.../module/ugp/biz/controller/ProjectOverFlowController.java
+112
-0
ProjectInitiationServiceImpl.java
...le/ugp/biz/service/impl/ProjectInitiationServiceImpl.java
+93
-4
No files found.
amos-boot-system-ugp/amos-boot-module-ugp-api/src/main/java/com/yeejoin/amos/boot/module/ugp/api/Enum/OverProjectFlowEnum.java
0 → 100644
View file @
711c7322
package
com
.
yeejoin
.
amos
.
boot
.
module
.
ugp
.
api
.
Enum
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
import
java.util.HashMap
;
import
java.util.Map
;
@Getter
@AllArgsConstructor
public
enum
OverProjectFlowEnum
{
竣工资料上传确认
(
"1"
,
"竣工资料上传确认"
,
"ZLSCQR"
,
""
),
上传竣工资料
(
"2"
,
"上传竣工资料"
,
"SCJGZL"
,
"竣工资料待上传"
),
竣工资料审核
(
"3"
,
"竣工资料审核"
,
"JGZLSH"
,
"竣工资料待审核"
),
填写审核意见
(
"4"
,
"填写审核意见"
,
"TXSHYJ"
,
"审核意见待填写"
);
private
final
String
status
;
private
final
String
name
;
private
final
String
code
;
private
final
String
taskDetailStatus
;
public
static
Map
<
String
,
String
>
getNameByStatusMap
=
new
HashMap
<
String
,
String
>();
public
static
Map
<
String
,
String
>
getStatusByNameMap
=
new
HashMap
<
String
,
String
>();
public
static
Map
<
String
,
String
>
getCodeByNameMap
=
new
HashMap
<
String
,
String
>();
public
static
Map
<
String
,
String
>
getTaskDetailStatusMap
=
new
HashMap
<
String
,
String
>();
static
{
for
(
OverProjectFlowEnum
projectInitiationEnum
:
OverProjectFlowEnum
.
values
())
{
getNameByStatusMap
.
put
(
projectInitiationEnum
.
status
,
projectInitiationEnum
.
name
);
getStatusByNameMap
.
put
(
projectInitiationEnum
.
name
,
projectInitiationEnum
.
status
);
getCodeByNameMap
.
put
(
projectInitiationEnum
.
name
,
projectInitiationEnum
.
code
);
getTaskDetailStatusMap
.
put
(
projectInitiationEnum
.
name
,
projectInitiationEnum
.
taskDetailStatus
);
}
}
}
amos-boot-system-ugp/amos-boot-module-ugp-api/src/main/java/com/yeejoin/amos/boot/module/ugp/api/dto/OverProjectDto.java
0 → 100644
View file @
711c7322
package
com
.
yeejoin
.
amos
.
boot
.
module
.
ugp
.
api
.
dto
;
import
lombok.Data
;
@Data
public
class
OverProjectDto
{
/**
* 项目主键Id
*/
private
Long
projectId
;
/**
* 是否同意 1-通过、0-驳回
* {@link com.yeejoin.amos.boot.module.ugp.api.Enum.WhetherItPassEnum}
*/
private
String
isAgree
;
/**
* 竣工资料
*/
private
String
completeFile
;
/**
* 审核意见
*/
private
String
auditOpinion
;
/**
* 是否同意 1-通过、0-驳回、2-仅保存
* {@link com.yeejoin.amos.boot.module.ugp.api.Enum.WhetherItPassEnum}
*/
private
String
condition
;
/**
* 流程实例ID
*/
private
String
instanceId
;
}
amos-boot-system-ugp/amos-boot-module-ugp-api/src/main/java/com/yeejoin/amos/boot/module/ugp/api/service/IProjectInitiationService.java
View file @
711c7322
package
com
.
yeejoin
.
amos
.
boot
.
module
.
ugp
.
api
.
service
;
package
com
.
yeejoin
.
amos
.
boot
.
module
.
ugp
.
api
.
service
;
import
com.alibaba.fastjson.JSONObject
;
import
com.alibaba.fastjson.JSONObject
;
import
com.yeejoin.amos.boot.module.ugp.api.dto.OverProjectDto
;
import
com.yeejoin.amos.boot.module.ugp.api.entity.Project
;
import
com.yeejoin.amos.boot.module.ugp.api.entity.Project
;
import
org.typroject.tyboot.core.restful.utils.ResponseModel
;
import
org.typroject.tyboot.core.restful.utils.ResponseModel
;
...
@@ -17,4 +18,15 @@ public interface IProjectInitiationService {
...
@@ -17,4 +18,15 @@ public interface IProjectInitiationService {
*/
*/
void
execute
(
String
instanceId
,
Object
object
,
String
option
);
void
execute
(
String
instanceId
,
Object
object
,
String
option
);
/**
* 竣工结项流程启动
* @param overProjectDto 结项相关信息
*/
void
overProjectFlowStart
(
OverProjectDto
overProjectDto
);
/**
* 竣工结项流程执行
* @param overProjectDto 结项相关信息
*/
void
overProjectFlowExecute
(
OverProjectDto
overProjectDto
);
}
}
amos-boot-system-ugp/amos-boot-module-ugp-api/src/main/resources/mapper/ProjectMapper.xml
View file @
711c7322
...
@@ -24,7 +24,7 @@
...
@@ -24,7 +24,7 @@
pg.context AS context
pg.context AS context
FROM
FROM
tz_ugp_project pt
tz_ugp_project pt
LEFT JOIN ( SELECT * FROM tz_ugp_
project_
initiation_log GROUP BY
LEFT JOIN ( SELECT * FROM tz_ugp_initiation_log GROUP BY
instance_id ) pg ON pt.instance_id = pg.instance_id
instance_id ) pg ON pt.instance_id = pg.instance_id
<where>
<where>
<if
test=
"roleName == '建设单位'"
>
<if
test=
"roleName == '建设单位'"
>
...
...
amos-boot-system-ugp/amos-boot-module-ugp-biz/src/main/java/com/yeejoin/amos/boot/module/ugp/biz/controller/ProjectOverFlowController.java
0 → 100644
View file @
711c7322
package
com
.
yeejoin
.
amos
.
boot
.
module
.
ugp
.
biz
.
controller
;
import
com.alibaba.fastjson.JSON
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.toolkit.ObjectUtils
;
import
com.baomidou.mybatisplus.core.toolkit.StringUtils
;
import
com.yeejoin.amos.boot.biz.common.controller.BaseController
;
import
com.yeejoin.amos.boot.module.ugp.api.Enum.ProcessTypeEnum
;
import
com.yeejoin.amos.boot.module.ugp.api.Enum.WhetherItPassEnum
;
import
com.yeejoin.amos.boot.module.ugp.api.dto.OverProjectDto
;
import
com.yeejoin.amos.boot.module.ugp.api.entity.Project
;
import
com.yeejoin.amos.boot.module.ugp.api.entity.ProjectInitiation
;
import
com.yeejoin.amos.boot.module.ugp.api.service.IProjectInitiationService
;
import
com.yeejoin.amos.boot.module.ugp.biz.service.impl.ProjectInitiationServiceImpl
;
import
com.yeejoin.amos.boot.module.ugp.biz.service.impl.ProjectServiceImpl
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
org.springframework.web.bind.annotation.*
;
import
org.typroject.tyboot.core.foundation.context.RequestContext
;
import
org.typroject.tyboot.core.foundation.enumeration.UserType
;
import
org.typroject.tyboot.core.restful.doc.TycloudOperation
;
import
org.typroject.tyboot.core.restful.utils.ResponseHelper
;
import
org.typroject.tyboot.core.restful.utils.ResponseModel
;
import
javax.annotation.Resource
;
/**
* 小您过目结项流程相关API
*
* @author system_generator
* @date 2022-09-22
*/
@RestController
@Api
(
tags
=
"项目结项流程Api"
)
@RequestMapping
(
value
=
"/projectOver"
)
public
class
ProjectOverFlowController
extends
BaseController
{
@Resource
private
ProjectServiceImpl
projectServiceImpl
;
@Resource
private
IProjectInitiationService
iProjectInitiationService
;
@Resource
private
ProjectInitiationServiceImpl
projectInitiationServiceImpl
;
/**
* 项目结项流程启动API
*
* @param dto 项目结项信息
*/
@PostMapping
(
value
=
"/flowStart"
)
@ApiOperation
(
value
=
"项目竣工结项(竣工结项确认)- 结项项目结项流程启动API"
,
notes
=
"项目竣工结项(竣工结项确认)- 项目结项流程启动API"
)
@TycloudOperation
(
ApiLevel
=
UserType
.
AGENCY
,
needAuth
=
false
)
public
ResponseModel
<
Object
>
overProjectFlowStart
(
@RequestBody
OverProjectDto
dto
)
{
String
token
=
RequestContext
.
getToken
();
String
appKey
=
RequestContext
.
getAppKey
();
String
product
=
RequestContext
.
getProduct
();
//分支线程执行流程
Thread
t1
=
new
Thread
(
new
Runnable
()
{
@Override
public
void
run
()
{
RequestContext
.
setToken
(
token
);
RequestContext
.
setAppKey
(
appKey
);
RequestContext
.
setProduct
(
product
);
iProjectInitiationService
.
overProjectFlowStart
(
dto
);
}
});
t1
.
start
();
return
ResponseHelper
.
buildResponse
(
dto
);
}
/**
* 项目结项执行流程
*
* @param dto 项目结项信息
*/
@PostMapping
(
value
=
"/flowExecute"
)
@ApiOperation
(
value
=
"项目结项流程执行通用API"
,
notes
=
"项目结项流程执行通用API"
)
@TycloudOperation
(
ApiLevel
=
UserType
.
AGENCY
,
needAuth
=
false
)
public
ResponseModel
<
Object
>
overProjectFlowExecute
(
@RequestBody
OverProjectDto
dto
)
{
iProjectInitiationService
.
overProjectFlowExecute
(
dto
);
return
ResponseHelper
.
buildResponse
(
null
);
}
/**
* 根据sequenceNbr查询
*
* @param sequenceNbr 主键
*/
@GetMapping
(
value
=
"/{sequenceNbr}"
)
@ApiOperation
(
value
=
"根据项目表sequenceNbr查询结项流程相关信息"
,
notes
=
"根据项目表sequenceNbr查询结项流程相关信息"
)
@TycloudOperation
(
ApiLevel
=
UserType
.
AGENCY
)
public
ResponseModel
<
OverProjectDto
>
selectOne
(
@PathVariable
Long
sequenceNbr
)
{
Project
project
=
projectServiceImpl
.
getById
(
sequenceNbr
);
LambdaQueryWrapper
<
ProjectInitiation
>
wrapper
=
new
LambdaQueryWrapper
<>();
wrapper
.
eq
(
ProjectInitiation:
:
getInstanceId
,
project
.
getInstanceId
());
wrapper
.
eq
(
ProjectInitiation:
:
getType
,
ProcessTypeEnum
.
项目结项
.
getType
());
wrapper
.
orderByDesc
(
ProjectInitiation:
:
getRecDate
);
wrapper
.
last
(
" limit 1"
);
ProjectInitiation
one
=
projectInitiationServiceImpl
.
getOne
(
wrapper
);
if
(
ObjectUtils
.
isNotEmpty
(
one
)
&&
StringUtils
.
isNotEmpty
(
one
.
getContext
()))
{
OverProjectDto
overProjectDto
=
JSON
.
parseObject
(
one
.
getContext
(),
OverProjectDto
.
class
);
if
((
StringUtils
.
isNotEmpty
(
overProjectDto
.
getAuditOpinion
())
&&
WhetherItPassEnum
.
REJECT
.
getCode
().
equals
(
overProjectDto
.
getCondition
()))
||
(
StringUtils
.
isNotEmpty
(
overProjectDto
.
getIsAgree
())
&&
WhetherItPassEnum
.
REJECT
.
getCode
().
equals
(
overProjectDto
.
getIsAgree
())))
{
return
ResponseHelper
.
buildResponse
(
new
OverProjectDto
());
}
return
ResponseHelper
.
buildResponse
(
overProjectDto
);
}
return
ResponseHelper
.
buildResponse
(
new
OverProjectDto
());
}
}
amos-boot-system-ugp/amos-boot-module-ugp-biz/src/main/java/com/yeejoin/amos/boot/module/ugp/biz/service/impl/ProjectInitiationServiceImpl.java
View file @
711c7322
...
@@ -10,19 +10,19 @@ import com.mao.expertSystem.material.MyWps;
...
@@ -10,19 +10,19 @@ import com.mao.expertSystem.material.MyWps;
import
com.yeejoin.amos.boot.biz.common.service.impl.WorkflowExcuteServiceImpl
;
import
com.yeejoin.amos.boot.biz.common.service.impl.WorkflowExcuteServiceImpl
;
import
com.yeejoin.amos.boot.biz.common.utils.DateUtils
;
import
com.yeejoin.amos.boot.biz.common.utils.DateUtils
;
import
com.yeejoin.amos.boot.module.common.biz.service.impl.OrgUsrServiceImpl
;
import
com.yeejoin.amos.boot.module.common.biz.service.impl.OrgUsrServiceImpl
;
import
com.yeejoin.amos.boot.module.ugp.api.Enum.AuditEnum
;
import
com.yeejoin.amos.boot.module.ugp.api.Enum.*
;
import
com.yeejoin.amos.boot.module.ugp.api.Enum.ProjectInitiationEnum
;
import
com.yeejoin.amos.boot.module.ugp.api.Enum.SMSEnum
;
import
com.yeejoin.amos.boot.module.ugp.api.Enum.TaskTypeEnum
;
import
com.yeejoin.amos.boot.module.ugp.api.constants.XJConstant
;
import
com.yeejoin.amos.boot.module.ugp.api.constants.XJConstant
;
import
com.yeejoin.amos.boot.module.ugp.api.dto.OverProjectDto
;
import
com.yeejoin.amos.boot.module.ugp.api.dto.ProjectInitiationDto
;
import
com.yeejoin.amos.boot.module.ugp.api.dto.ProjectInitiationDto
;
import
com.yeejoin.amos.boot.module.ugp.api.entity.*
;
import
com.yeejoin.amos.boot.module.ugp.api.entity.*
;
import
com.yeejoin.amos.boot.module.ugp.api.mapper.ProjectInitiationMapper
;
import
com.yeejoin.amos.boot.module.ugp.api.mapper.ProjectInitiationMapper
;
import
com.yeejoin.amos.boot.module.ugp.api.service.IProcessRelationService
;
import
com.yeejoin.amos.boot.module.ugp.api.service.IProjectInitiationService
;
import
com.yeejoin.amos.boot.module.ugp.api.service.IProjectInitiationService
;
import
com.yeejoin.amos.feign.workflow.Workflow
;
import
com.yeejoin.amos.feign.workflow.Workflow
;
import
com.yeejoin.amos.feign.workflow.model.ActWorkflowStartDTO
;
import
com.yeejoin.amos.feign.workflow.model.ActWorkflowStartDTO
;
import
com.yeejoin.amos.feign.workflow.model.AjaxResult
;
import
com.yeejoin.amos.feign.workflow.model.AjaxResult
;
import
com.yeejoin.amos.feign.workflow.model.TaskResultDTO
;
import
com.yeejoin.amos.feign.workflow.model.TaskResultDTO
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.ibatis.type.LocalDateTypeHandler
;
import
org.apache.ibatis.type.LocalDateTypeHandler
;
import
org.joda.time.LocalDateTime
;
import
org.joda.time.LocalDateTime
;
...
@@ -31,15 +31,18 @@ import org.slf4j.LoggerFactory;
...
@@ -31,15 +31,18 @@ import org.slf4j.LoggerFactory;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.ObjectUtils
;
import
org.typroject.tyboot.core.foundation.utils.DateUtil
;
import
org.typroject.tyboot.core.foundation.utils.DateUtil
;
import
org.typroject.tyboot.core.foundation.utils.ValidationUtil
;
import
org.typroject.tyboot.core.foundation.utils.ValidationUtil
;
import
org.typroject.tyboot.core.rdbms.service.BaseService
;
import
org.typroject.tyboot.core.rdbms.service.BaseService
;
import
javax.annotation.Resource
;
import
java.time.LocalDate
;
import
java.time.LocalDate
;
import
java.time.LocalTime
;
import
java.time.LocalTime
;
import
java.util.*
;
import
java.util.*
;
@Service
@Service
@Slf4j
public
class
ProjectInitiationServiceImpl
extends
BaseService
<
ProjectInitiationDto
,
ProjectInitiation
,
ProjectInitiationMapper
>
implements
IProjectInitiationService
{
public
class
ProjectInitiationServiceImpl
extends
BaseService
<
ProjectInitiationDto
,
ProjectInitiation
,
ProjectInitiationMapper
>
implements
IProjectInitiationService
{
@Autowired
@Autowired
...
@@ -80,6 +83,16 @@ public class ProjectInitiationServiceImpl extends BaseService<ProjectInitiationD
...
@@ -80,6 +83,16 @@ public class ProjectInitiationServiceImpl extends BaseService<ProjectInitiationD
@Value
(
"${params.work.flow.processDefinitionKey}"
)
@Value
(
"${params.work.flow.processDefinitionKey}"
)
private
String
processDefinitionKey
;
private
String
processDefinitionKey
;
/**
* 竣工结项流程key
*/
@Value
(
"${params.work.flow.completedProjectDefinitionKey:jungongjiexiangliucheng}"
)
private
String
completedProjectDefinitionKey
;
@Resource
private
IProcessRelationService
processRelationService
;
@Override
@Override
public
void
start
(
Project
project
)
{
public
void
start
(
Project
project
)
{
String
instanceId
=
null
;
String
instanceId
=
null
;
...
@@ -370,4 +383,80 @@ public class ProjectInitiationServiceImpl extends BaseService<ProjectInitiationD
...
@@ -370,4 +383,80 @@ public class ProjectInitiationServiceImpl extends BaseService<ProjectInitiationD
}
}
@Override
public
void
overProjectFlowStart
(
OverProjectDto
overProjectDto
)
{
String
instanceId
=
""
;
//启动流程
try
{
ActWorkflowStartDTO
dto
=
new
ActWorkflowStartDTO
();
dto
.
setProcessDefinitionKey
(
completedProjectDefinitionKey
);
dto
.
setBusinessKey
(
"1"
);
HashMap
<
String
,
Object
>
dtoMap
=
new
HashMap
<>();
dtoMap
.
put
(
"condition"
,
"1"
);
dto
.
setVariables
(
dtoMap
);
AjaxResult
ajaxResult
=
Workflow
.
taskClient
.
startByVariable
(
dto
);
instanceId
=
((
Map
)
ajaxResult
.
get
(
"data"
)).
get
(
"id"
).
toString
();
//修改project表的流程状态
Project
project
=
projectService
.
getById
(
overProjectDto
.
getProjectId
());
project
.
setInstanceId
(
instanceId
);
project
.
setStatus
(
getFlowTaskName
(
instanceId
));
projectService
.
updateById
(
project
);
processRelationService
.
savePR
(
instanceId
,
project
.
getSequenceNbr
(),
ProcessTypeEnum
.
项目结项
.
getName
());
ProjectInitiation
projectInitiation
=
new
ProjectInitiation
();
projectInitiation
.
setInstanceId
(
instanceId
);
projectInitiation
.
setTaskName
(
"流程启动!"
);
projectInitiationService
.
save
(
projectInitiation
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
log
.
info
(
"流程启动失败:{}"
,
e
.
getMessage
());
}
//执行项目竣工结项流程
overProjectDto
.
setInstanceId
(
instanceId
);
overProjectFlowExecute
(
overProjectDto
);
}
@Override
public
void
overProjectFlowExecute
(
OverProjectDto
overProjectDto
)
{
try
{
AjaxResult
ajaxResult
=
Workflow
.
taskClient
.
getTask
(
overProjectDto
.
getInstanceId
());
JSONObject
dataObject
=
JSON
.
parseObject
(
JSON
.
toJSONString
(
ajaxResult
.
get
(
"data"
)));
String
taskId
=
dataObject
.
getString
(
"id"
);
LambdaQueryWrapper
<
ProjectInitiation
>
wrapper
=
new
LambdaQueryWrapper
<>();
wrapper
.
eq
(
ProjectInitiation:
:
getInstanceId
,
overProjectDto
.
getInstanceId
());
wrapper
.
eq
(
ProjectInitiation:
:
getTaskId
,
taskId
);
wrapper
.
eq
(
ProjectInitiation:
:
getType
,
ProcessTypeEnum
.
项目结项
.
getType
());
ProjectInitiation
one
=
projectInitiationService
.
getOne
(
wrapper
);
if
(!
ObjectUtils
.
isEmpty
(
one
))
{
//将所要的数据存为context格式
one
.
setContext
(
JSON
.
toJSONString
(
overProjectDto
));
projectInitiationService
.
updateById
(
one
);
}
else
{
ProjectInitiation
projectInitiation
=
new
ProjectInitiation
();
//如果不是保存,走工作流; 如果只是保存,只需要保存业务数据
projectInitiation
.
setInstanceId
(
overProjectDto
.
getInstanceId
());
//将所要的数据存为context格式
projectInitiation
.
setContext
(
JSON
.
toJSONString
(
overProjectDto
));
projectInitiation
.
setTaskId
(
taskId
);
projectInitiation
.
setTaskName
(
dataObject
.
getString
(
"name"
));
projectInitiation
.
setType
(
ProcessTypeEnum
.
项目结项
.
getType
());
projectInitiationService
.
save
(
projectInitiation
);
}
if
(!
WhetherItPassEnum
.
SAVE
.
getCode
().
equals
(
overProjectDto
.
getCondition
()))
{
//组装信息
TaskResultDTO
dto
=
new
TaskResultDTO
();
dto
.
setResult
(
overProjectDto
.
getCondition
());
dto
.
setResultCode
(
"condition"
);
dto
.
setTaskId
(
taskId
);
//执行流程
Workflow
.
taskClient
.
completeByTask
(
taskId
,
dto
);
processRelationService
.
updateState
(
overProjectDto
.
getInstanceId
());
//更新project种的status字段,表示当前流程下一个执行的任务
updateProjectFlowStatus
(
overProjectDto
.
getInstanceId
());
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
log
.
error
(
"竣工结项流程执行失败:{}"
,
e
.
getMessage
());
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment