Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
service-campaign
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nguyen Ha
service-campaign
Commits
1c1806ef
Commit
1c1806ef
authored
Sep 09, 2019
by
Vu Duy Anh
Browse files
Options
Browse Files
Download
Plain Diff
anhvd accept merge
parents
3154ea4c
7568320c
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
130 additions
and
33 deletions
+130
-33
src/main/java/com/viettel/campaign/repository/ccms_full/CampaignCustomerRepository.java
...aign/repository/ccms_full/CampaignCustomerRepository.java
+8
-12
src/main/java/com/viettel/campaign/repository/ccms_full/CampaignExecuteRepository.java
...paign/repository/ccms_full/CampaignExecuteRepository.java
+2
-0
src/main/java/com/viettel/campaign/repository/ccms_full/ContactCustResultRepository.java
...ign/repository/ccms_full/ContactCustResultRepository.java
+7
-0
src/main/java/com/viettel/campaign/repository/ccms_full/impl/CampaignExecuteRepositoryImp.java
...pository/ccms_full/impl/CampaignExecuteRepositoryImp.java
+29
-4
src/main/java/com/viettel/campaign/service/CampaignExecuteService.java
.../com/viettel/campaign/service/CampaignExecuteService.java
+1
-2
src/main/java/com/viettel/campaign/service/impl/CampaignCfgServiceImpl.java
...viettel/campaign/service/impl/CampaignCfgServiceImpl.java
+6
-4
src/main/java/com/viettel/campaign/service/impl/CampaignExecuteServiceImp.java
...ttel/campaign/service/impl/CampaignExecuteServiceImp.java
+30
-4
src/main/java/com/viettel/campaign/service/impl/CustomerServiceImpl.java
...om/viettel/campaign/service/impl/CustomerServiceImpl.java
+41
-1
src/main/java/com/viettel/campaign/web/dto/ContactCustResultDTO.java
...va/com/viettel/campaign/web/dto/ContactCustResultDTO.java
+1
-0
src/main/java/com/viettel/campaign/web/rest/CampaignExecuteController.java
.../viettel/campaign/web/rest/CampaignExecuteController.java
+5
-6
No files found.
src/main/java/com/viettel/campaign/repository/ccms_full/CampaignCustomerRepository.java
View file @
1c1806ef
...
...
@@ -14,6 +14,14 @@ import java.util.List;
@Transactional
(
DataSourceQualify
.
CCMS_FULL
)
public
interface
CampaignCustomerRepository
extends
JpaRepository
<
CampaignCustomer
,
Long
>,
CampaignCustomerRepositoryCustom
{
CampaignCustomer
findCampaignCustomerByCampaignCustomerId
(
Long
id
);
CampaignCustomer
findCampaignCustomerByCampaignIdAndCompanySiteIdAndCustomerId
(
Long
campaignId
,
Long
companySiteId
,
Long
customerId
);
List
<
CampaignCustomer
>
findCampaignCustomersByCampaignIdAndCompanySiteIdAndCustomerIdAndInCampaignStatus
(
Long
campaignId
,
Long
companySiteId
,
Long
customerId
,
Short
inCampaingStatus
);
CampaignCustomer
findCampaignCustomersByCampaignIdAndCustomerId
(
Long
campaignId
,
Long
customerId
);
@Query
(
value
=
"SELECT COUNT(*) "
+
" FROM CAMPAIGN_CUSTOMER CC "
+
" JOIN CAMPAIGN C ON CC.CAMPAIGN_ID = C.CAMPAIGN_ID "
+
...
...
@@ -34,10 +42,6 @@ public interface CampaignCustomerRepository extends JpaRepository<CampaignCustom
"AND CCC.STATUS = 1 "
,
nativeQuery
=
true
)
Long
getCustomerRecall
(
@Param
(
"campaignId"
)
Long
campaignId
,
@Param
(
"customerId"
)
Long
customerId
);
CampaignCustomer
findCampaignCustomerByCampaignCustomerId
(
Long
id
);
@Query
(
value
=
"select C.NAME, "
+
"C.EMAIL, "
+
"C.PLACE_OF_BIRTH, "
+
...
...
@@ -57,10 +61,6 @@ public interface CampaignCustomerRepository extends JpaRepository<CampaignCustom
,
nativeQuery
=
true
)
Long
searchCustomer
(
@Param
(
"site_id"
)
Long
pSiteId
);
@Query
(
value
=
"SELECT * FROM CAMPAIGN_CUSTOMER CC "
+
"WHERE CC.STATUS = 0 "
+
"AND CC.CAMPAIGN_ID = :campaignId "
+
...
...
@@ -88,10 +88,6 @@ public interface CampaignCustomerRepository extends JpaRepository<CampaignCustom
" and (status = 0 or status in (select * from status_customer))"
,
nativeQuery
=
true
)
List
<
CampaignCustomer
>
findListCustomerToDel
(
@Param
(
"p_company_site_id"
)
Long
companySiteId
,
@Param
(
"p_campaign_id"
)
Long
campaignId
,
@Param
(
"p_cus_list_id"
)
Long
customerListId
);
CampaignCustomer
findCampaignCustomerByCampaignIdAndCompanySiteIdAndCustomerId
(
Long
campaignId
,
Long
companySiteId
,
Long
customerId
);
List
<
CampaignCustomer
>
findCampaignCustomersByCampaignIdAndCompanySiteIdAndCustomerIdAndInCampaignStatus
(
Long
campaignId
,
Long
companySiteId
,
Long
customerId
,
Short
inCampaingStatus
);
@Query
(
value
=
"select complete_value from campaign_complete_code where status = 1 and complete_type = 1"
,
nativeQuery
=
true
)
List
<
Short
>
getStatus
();
}
src/main/java/com/viettel/campaign/repository/ccms_full/CampaignExecuteRepository.java
View file @
1c1806ef
...
...
@@ -21,4 +21,6 @@ public interface CampaignExecuteRepository {
List
<
ContactCustResultDTO
>
getInteractiveResult
(
CampaignRequestDTO
dto
,
Pageable
pageable
);
List
<
ContactCustResultDTO
>
getExcelInteractiveResult
(
CampaignRequestDTO
dto
);
List
<
ContactQuestResultDTO
>
createListContacQuestResult
(
List
<
ContactQuestResultDTO
>
dtoList
);
}
src/main/java/com/viettel/campaign/repository/ccms_full/ContactCustResultRepository.java
View file @
1c1806ef
...
...
@@ -2,8 +2,15 @@ package com.viettel.campaign.repository.ccms_full;
import
com.viettel.campaign.model.ccms_full.ContactCustResult
;
import
org.springframework.data.jpa.repository.JpaRepository
;
import
org.springframework.data.jpa.repository.Query
;
import
org.springframework.data.repository.query.Param
;
import
org.springframework.stereotype.Repository
;
import
java.sql.Date
;
@Repository
public
interface
ContactCustResultRepository
extends
JpaRepository
<
ContactCustResult
,
Long
>
{
@Query
(
value
=
"SELECT MAX(createTime) FROM ContactCustResult WHERE campaignId = :campaignId AND agentId = :agentId AND status = 1"
)
Date
getMaxCreateTime
(
@Param
(
"campaignId"
)
Long
campaignId
,
@Param
(
"agentId"
)
Long
agentId
);
}
src/main/java/com/viettel/campaign/repository/ccms_full/impl/CampaignExecuteRepositoryImp.java
View file @
1c1806ef
...
...
@@ -2,15 +2,13 @@ package com.viettel.campaign.repository.ccms_full.impl;
import
com.viettel.campaign.config.DataSourceQualify
;
import
com.viettel.campaign.repository.ccms_full.CampaignExecuteRepository
;
import
com.viettel.campaign.repository.ccms_full.ContactQuestResultRepository
;
import
com.viettel.campaign.repository.ccms_full.TimeRangeDialModeRepository
;
import
com.viettel.campaign.repository.ccms_full.TimeZoneDialModeRepository
;
import
com.viettel.campaign.utils.Constants
;
import
com.viettel.campaign.utils.DataUtil
;
import
com.viettel.campaign.utils.HibernateUtil
;
import
com.viettel.campaign.web.dto.ApParamDTO
;
import
com.viettel.campaign.web.dto.CampaignDTO
;
import
com.viettel.campaign.web.dto.ContactCustResultDTO
;
import
com.viettel.campaign.web.dto.ResultDTO
;
import
com.viettel.campaign.web.dto.*
;
import
com.viettel.campaign.web.dto.request_dto.CampaignRequestDTO
;
import
org.hibernate.SQLQuery
;
import
org.hibernate.Session
;
...
...
@@ -57,6 +55,9 @@ public class CampaignExecuteRepositoryImp implements CampaignExecuteRepository {
@Autowired
TimeRangeDialModeRepository
rangeDialModeRepository
;
@Autowired
ContactQuestResultRepository
contactQuestResultRepository
;
@Override
public
List
<
ApParamDTO
>
getComboBoxStatus
(
String
companySiteId
,
String
completeType
)
{
List
<
ApParamDTO
>
list
=
new
ArrayList
<>();
...
...
@@ -584,4 +585,28 @@ public class CampaignExecuteRepositoryImp implements CampaignExecuteRepository {
return
result
;
}
@Override
@Transactional
(
DataSourceQualify
.
CCMS_FULL
)
public
List
<
ContactQuestResultDTO
>
createListContacQuestResult
(
List
<
ContactQuestResultDTO
>
dtoList
)
{
ResultDTO
resultDTO
=
new
ResultDTO
();
List
<
ContactQuestResultDTO
>
list
=
new
ArrayList
<>();
SessionFactory
sessionFactory
=
HibernateUtil
.
getSessionFactory
();
Session
session
=
sessionFactory
.
openSession
();
session
.
beginTransaction
();
try
{
// list = contactQuestResultRepository.saveAll(dtoList);
}
catch
(
Exception
e
)
{
logger
.
error
(
e
.
getMessage
(),
e
);
resultDTO
.
setErrorCode
(
Constants
.
ApiErrorCode
.
ERROR
);
resultDTO
.
setDescription
(
Constants
.
ApiErrorDesc
.
ERROR
);
}
finally
{
session
.
close
();
}
return
list
;
}
}
src/main/java/com/viettel/campaign/service/CampaignExecuteService.java
View file @
1c1806ef
...
...
@@ -10,7 +10,6 @@ import org.springframework.stereotype.Service;
import
java.io.IOException
;
import
java.util.List
;
@Service
public
interface
CampaignExecuteService
{
//<editor-fold: hungtt>
ResultDTO
getComboBoxStatus
(
String
companySiteId
,
String
completeType
);
...
...
@@ -37,7 +36,7 @@ public interface CampaignExecuteService {
ResultDTO
getAgentLogout
(
CampaignRequestDTO
dto
);
ResultDTO
callCustomer
(
ContactCustResultDTO
dto
,
UserSession
userSession
);
ResultDTO
updateContactCustResult
(
ContactCustResultDTO
dto
,
UserSession
userSession
);
ResultDTO
recallCustomer
(
ContactCustResultDTO
dto
);
...
...
src/main/java/com/viettel/campaign/service/impl/CampaignCfgServiceImpl.java
View file @
1c1806ef
...
...
@@ -220,16 +220,18 @@ public class CampaignCfgServiceImpl implements CampaignCfgService {
if
(
completeCodeDTO
!=
null
)
{
// update
compCode
=
compCodeMapper
.
toPersistenceBean
(
completeCodeDTO
);
comp
Code
=
comp
leteCodeRepository
.
save
(
compCode
);
completeCodeRepository
.
save
(
compCode
);
resultDTO
.
setErrorCode
(
"0"
);
resultDTO
.
setErrorCode
(
Constants
.
ApiErrorCode
.
SUCCESS
);
resultDTO
.
setDescription
(
"Complete Code: "
+
compCode
.
getCampaignCompleteCodeId
()
+
" updated!"
);
}
else
{
resultDTO
.
setErrorCode
(
"-2"
);
resultDTO
.
setErrorCode
(
Constants
.
ApiErrorCode
.
ERROR
);
resultDTO
.
setDescription
(
"CompleteCodeDTO null"
);
}
}
catch
(
Exception
e
)
{
// e.printStackTrace();
logger
.
error
(
e
.
getMessage
(),
e
);
resultDTO
.
setErrorCode
(
Constants
.
ApiErrorCode
.
ERROR
);
resultDTO
.
setDescription
(
Constants
.
ApiErrorDesc
.
ERROR
);
}
return
resultDTO
;
...
...
src/main/java/com/viettel/campaign/service/impl/CampaignExecuteServiceImp.java
View file @
1c1806ef
...
...
@@ -538,11 +538,36 @@ public class CampaignExecuteServiceImp implements CampaignExecuteService {
}
@Override
public
ResultDTO
callCustomer
(
ContactCustResultDTO
dto
,
UserSession
userSession
)
{
public
ResultDTO
updateContactCustResult
(
ContactCustResultDTO
dto
,
UserSession
userSession
)
{
ResultDTO
result
=
new
ResultDTO
();
ContactCustResult
ccr
=
new
ContactCustResult
();
try
{
ContactCustResult
ccr
=
ccResultRepository
.
save
(
modelMapper
.
map
(
dto
,
ContactCustResult
.
class
));
if
(
dto
.
getEventCall
().
equalsIgnoreCase
(
"call"
))
{
ccr
=
ccResultRepository
.
save
(
modelMapper
.
map
(
dto
,
ContactCustResult
.
class
));
}
else
if
(
dto
.
getContactCustResultId
()
!=
null
)
{
ccr
=
ccResultRepository
.
getOne
(
dto
.
getContactCustResultId
());
if
(
dto
.
getEventCall
().
equalsIgnoreCase
(
"ringing"
))
{
ccr
.
setCallId
(
dto
.
getCallId
());
ccr
.
setUpdateBy
(
userSession
.
getUserId
());
ccr
.
setUpdateTime
(
new
Date
());
ccr
=
ccResultRepository
.
save
(
ccr
);
}
else
if
(
dto
.
getEventCall
().
equalsIgnoreCase
(
"ended"
))
{
ccr
.
setDurationCall
(
dto
.
getDurationCall
());
ccr
.
setStartCall
(
dto
.
getStartCall
());
ccr
.
setReceiveTime
(
dto
.
getReceiveTime
());
//
ccr
.
setPreEndTime
(
ccResultRepository
.
getMaxCreateTime
(
dto
.
getCampaignId
(),
dto
.
getAgentId
()));
ccr
.
setEndTime
(
dto
.
getEndTime
());
ccr
.
setWaitTime
(
dto
.
getWaitTime
());
ccr
=
ccResultRepository
.
save
(
ccr
);
CampaignCustomer
cc
=
campaignCustomerRepository
.
findCampaignCustomersByCampaignIdAndCustomerId
(
dto
.
getCampaignId
(),
dto
.
getCustomerId
());
cc
.
setCallTime
(
dto
.
getStartCall
());
cc
=
campaignCustomerRepository
.
save
(
cc
);
Agents
ag
=
agentsRepository
.
findByAgentId
(
dto
.
getAgentId
().
toString
());
ag
.
setSystemStatus
(
"AVAILABLE"
);
ag
=
agentsRepository
.
save
(
ag
);
}
}
result
.
setErrorCode
(
Constants
.
ApiErrorCode
.
SUCCESS
);
result
.
setDescription
(
Constants
.
ApiErrorDesc
.
SUCCESS
);
...
...
@@ -682,7 +707,7 @@ public class CampaignExecuteServiceImp implements CampaignExecuteService {
}
@Override
@Transactional
@Transactional
(
DataSourceQualify
.
CCMS_FULL
)
public
ResultDTO
createListContacQuestResult
(
List
<
ContactQuestResultDTO
>
dtoList
)
{
ResultDTO
resultDTO
=
new
ResultDTO
();
List
<
ContactQuestResult
>
lstContactQuestResult
=
new
ArrayList
<>();
...
...
@@ -692,7 +717,8 @@ public class CampaignExecuteServiceImp implements CampaignExecuteService {
}
try
{
List
<
ContactQuestResult
>
dataReturn
=
contactQuestResultRepository
.
saveAll
(
lstContactQuestResult
);
List
<
ContactQuestResult
>
dataReturn
=
new
ArrayList
<>();
dataReturn
=
contactQuestResultRepository
.
saveAll
(
lstContactQuestResult
);
resultDTO
.
setErrorCode
(
Constants
.
ApiErrorCode
.
SUCCESS
);
resultDTO
.
setDescription
(
Constants
.
ApiErrorDesc
.
SUCCESS
);
resultDTO
.
setListData
(
dataReturn
);
...
...
src/main/java/com/viettel/campaign/service/impl/CustomerServiceImpl.java
View file @
1c1806ef
...
...
@@ -993,10 +993,26 @@ public class CustomerServiceImpl implements CustomerService {
resultStyle
.
setBorderRight
(
BorderStyle
.
THIN
);
resultStyle
.
setBorderBottom
(
BorderStyle
.
THIN
);
resultStyle
.
setBorderTop
(
BorderStyle
.
THIN
);
resultStyle
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
resultStyle
.
setVerticalAlignment
(
VerticalAlignment
.
CENTER
);
//</editor-fold>
//<editor-fold desc="Kiểm tra header của template" defaultstate="collapsed">
if
(
row
.
getPhysicalNumberOfCells
()
!=
header
.
size
())
{
if
(
row
.
getPhysicalNumberOfCells
()
>
header
.
size
())
{
for
(
int
i
=
0
;
i
<
row
.
getPhysicalNumberOfCells
();
i
++)
{
if
(
isColumnNullOrBlank
(
sheet
,
i
))
{
deleteNullColumn
(
sheet
,
i
);
}
}
for
(
int
i
=
0
;
i
<
header
.
size
();
i
++)
{
Cell
cell
=
row
.
getCell
(
i
);
if
(!
cell
.
getStringCellValue
().
equals
(
header
.
get
(
i
).
getTitle
().
split
(
"#"
)[
0
]))
{
result
.
put
(
"content"
,
Files
.
readAllBytes
(
file
.
toPath
()));
result
.
put
(
"message"
,
"template-invalid"
);
return
result
;
}
}
}
else
if
(
row
.
getPhysicalNumberOfCells
()
<
header
.
size
())
{
result
.
put
(
"content"
,
Files
.
readAllBytes
(
file
.
toPath
()));
result
.
put
(
"message"
,
"template-invalid"
);
return
result
;
...
...
@@ -1396,6 +1412,25 @@ public class CustomerServiceImpl implements CustomerService {
String
regexp
=
"@\"^\\p{L}+$\""
;
return
str
.
matches
(
regexp
);
}
private
boolean
isColumnNullOrBlank
(
Sheet
sheet
,
int
columnIndex
)
{
for
(
Row
row
:
sheet
)
{
if
(
row
.
getRowNum
()
<
3
)
continue
;
Cell
cell
=
row
.
getCell
(
columnIndex
,
Row
.
MissingCellPolicy
.
RETURN_BLANK_AS_NULL
);
if
(
cell
!=
null
)
{
return
false
;
}
}
return
true
;
}
private
void
deleteNullColumn
(
Sheet
sheet
,
int
columnIndex
)
{
for
(
Row
row
:
sheet
)
{
if
(
row
.
getRowNum
()
<
3
)
continue
;
Cell
cell
=
row
.
getCell
(
columnIndex
,
Row
.
MissingCellPolicy
.
RETURN_BLANK_AS_NULL
);
row
.
removeCell
(
cell
);
}
}
//</editor-fold>
@Override
...
...
@@ -1436,10 +1471,14 @@ public class CustomerServiceImpl implements CustomerService {
headerFont
.
setBold
(
true
);
CellStyle
headerStyle
=
workbook
.
createCellStyle
();
CellStyle
importantStyle
=
workbook
.
createCellStyle
();
CellStyle
columnStyle
=
workbook
.
createCellStyle
();
importantStyle
.
setFont
(
importantFont
);
headerStyle
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
headerStyle
.
setVerticalAlignment
(
VerticalAlignment
.
CENTER
);
headerStyle
.
setFont
(
headerFont
);
columnStyle
.
setVerticalAlignment
(
VerticalAlignment
.
CENTER
);
columnStyle
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
columnStyle
.
setWrapText
(
true
);
//</editor-fold>
//<editor-fold desc="Thêm combobox" defaultstate="collapsed">
...
...
@@ -1512,6 +1551,7 @@ public class CustomerServiceImpl implements CustomerService {
cell2
.
setCellStyle
(
importantStyle
);
cell2
.
setCellValue
(
BundleUtils
.
getLangString
(
"customer.notice"
,
locale
));
for
(
int
i
=
0
;
i
<
header
.
size
();
i
++)
{
sheet
.
setDefaultColumnStyle
(
i
,
columnStyle
);
Cell
headerCell
=
row3
.
createCell
(
i
);
headerCell
.
setCellValue
(
header
.
get
(
i
).
getTitle
().
split
(
"#"
)[
0
]);
headerStyle
.
setBorderTop
(
BorderStyle
.
THIN
);
...
...
src/main/java/com/viettel/campaign/web/dto/ContactCustResultDTO.java
View file @
1c1806ef
...
...
@@ -55,4 +55,5 @@ public class ContactCustResultDTO extends BaseDTO {
private
Boolean
enableEdit
;
private
Integer
totalRow
;
private
String
eventCall
;
}
src/main/java/com/viettel/campaign/web/rest/CampaignExecuteController.java
View file @
1c1806ef
package
com.viettel.campaign.web.rest
;
import
com.viettel.campaign.model.ccms_full.ContactQuestResult
;
import
com.viettel.campaign.service.CampaignExecuteService
;
import
com.viettel.campaign.utils.RedisUtil
;
import
com.viettel.campaign.web.dto.*
;
...
...
@@ -25,7 +24,7 @@ import java.util.List;
@RestController
@RequestMapping
(
"/ipcc/campaign/execute"
)
@CrossOrigin
//
@CrossOrigin
public
class
CampaignExecuteController
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
CampaignController
.
class
);
...
...
@@ -136,12 +135,12 @@ public class CampaignExecuteController {
return
new
ResponseEntity
<>(
result
,
HttpStatus
.
OK
);
}
@PostMapping
(
"/
callCustomer
"
)
@PostMapping
(
"/
updateContactCustResult
"
)
@ResponseBody
public
ResponseEntity
<
ResultDTO
>
callCustomer
(
@RequestBody
ContactCustResultDTO
requestDto
,
HttpServletRequest
request
)
{
public
ResponseEntity
<
ResultDTO
>
updateContactCustResult
(
@RequestBody
ContactCustResultDTO
requestDto
,
HttpServletRequest
request
)
{
String
xAuthToken
=
request
.
getHeader
(
"X-Auth-Token"
);
UserSession
userSession
=
(
UserSession
)
RedisUtil
.
getInstance
().
get
(
xAuthToken
);
ResultDTO
result
=
campaignExecuteService
.
callCustomer
(
requestDto
,
userSession
);
ResultDTO
result
=
campaignExecuteService
.
updateContactCustResult
(
requestDto
,
userSession
);
return
new
ResponseEntity
<>(
result
,
HttpStatus
.
OK
);
}
...
...
@@ -166,7 +165,7 @@ public class CampaignExecuteController {
return
new
ResponseEntity
<>(
result
,
HttpStatus
.
OK
);
}
@P
os
tMapping
(
"/createListContactQuestResult"
)
@P
u
tMapping
(
"/createListContactQuestResult"
)
@ResponseBody
public
ResponseEntity
<
ResultDTO
>
createListContactQuestResult
(
@RequestBody
List
<
ContactQuestResultDTO
>
dtoList
)
{
ResultDTO
result
=
null
;
...
...
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