Commit e8919827 authored by Vu Duy Anh's avatar Vu Duy Anh

anhvd commit for merge

parents 645b312d 3c9f41ef
......@@ -173,6 +173,20 @@
<!--<executable>true</executable>-->
<!--</configuration>-->
</plugin>
<!--<plugin>-->
<!--<groupId>org.sonarsource.scanner.maven</groupId>-->
<!--<artifactId>sonar-maven-plugin</artifactId>-->
<!--<version>3.3.0.603</version>-->
<!--<executions>-->
<!--<execution>-->
<!--<phase>verify</phase>-->
<!--<goals>-->
<!--<goal>sonar</goal>-->
<!--</goals>-->
<!--</execution>-->
<!--</executions>-->
<!--</plugin>-->
</plugins>
</build>
<repositories>
......
......@@ -48,33 +48,34 @@ public class JobConfig implements SchedulingConfigurer {
// taskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
// }
private void job1(TaskScheduler scheduler) {
job1 = scheduler.schedule(() -> {
log.info("processing job1 ...");
log.info(Thread.currentThread().getName() + " The Task1 executed at " + new Date());
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}, triggerContext -> {
String cronExp = "0/5 * * * * ?";// Can be pulled from a db .
return new CronTrigger(cronExp).nextExecutionTime(triggerContext);
});
}
private void job2(TaskScheduler scheduler) {
job2 = scheduler.schedule(() -> {
log.info(Thread.currentThread().getName() + " The Job executed at " + new Date());
campaignJob().process();
// private void job1(TaskScheduler scheduler) {
// job1 = scheduler.schedule(() -> {
// log.info("processing job1 ...");
// log.info(Thread.currentThread().getName() + " The Task1 executed at " + new Date());
// try {
// Thread.sleep(10000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
//// e.printStackTrace();
// log.error("Interrupted! ...${}", e);
// }
// }, triggerContext -> {
//
// String cronExp = "0/5 * * * * ?";// Can be pulled from a db .
// return new CronTrigger(cronExp).nextExecutionTime(triggerContext);
// });
// }
}, triggerContext -> {
String cronExp = "0/1 * * * * ?";// Can be pulled from a db . This will run every minute
return new CronTrigger(cronExp).nextExecutionTime(triggerContext);
});
}
// private void job2(TaskScheduler scheduler) {
// job2 = scheduler.schedule(() -> {
// log.info(Thread.currentThread().getName() + " The Job executed at " + new Date());
// campaignJob().process();
//
// }, triggerContext -> {
// String cronExp = "0/1 * * * * ?";// Can be pulled from a db . This will run every minute
// return new CronTrigger(cronExp).nextExecutionTime(triggerContext);
// });
// }
......
......@@ -19,7 +19,7 @@ import java.util.List;
@Slf4j
public class CampaignJob {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
private SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
private static final String CUSTOMER_INACTIVE_DUARATION = "CUSTOMER_INACTIVE_DUARATION";
private static final String CRON_EXPRESSION_CHECK_START = "CRON_EXPRESSION_CHECK_START";
private static final String CRON_EXPRESSION_CHECK_END = "CRON_EXPRESSION_CHECK_END";
......
......@@ -15,7 +15,7 @@ import java.util.Date;
public class CustomerContact implements Serializable {
@Id
@Basic(optional = false)
@GeneratedValue(generator = "customer_contact_seq", strategy = GenerationType.IDENTITY)
@GeneratedValue(generator = "customer_contact_seq")
@SequenceGenerator(name = "customer_contact_seq", sequenceName = "customer_contact_seq", allocationSize = 1)
@NotNull
@Column(name = "CONTACT_ID")
......
package com.viettel.campaign.model.ccms_full;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.*;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
......@@ -67,8 +64,10 @@ public class CustomizeFields implements Serializable {
@Column(name = "ACTIVE")
private Long active;
public CustomizeFields(String type, String title) {
public CustomizeFields(@NotNull String type, @NotNull String title) {
this.type = type;
this.title = title;
}
}
......@@ -301,9 +301,9 @@ public class CampaignExecuteRepositoryImp implements CampaignExecuteRepository {
if (!"AGENT".equals(dto.getRoleUser())) { // ko phải nhân viên
ContactCustResultDTO.setEnableEdit(true);
} else {
if ("2".equals(ContactCustResultDTO.getRecordStatus())) {// là nhân viên thường
if (2 == ContactCustResultDTO.getRecordStatus()) {// là nhân viên thường
ContactCustResultDTO.setEnableEdit(true);
} else if ("1".equals(ContactCustResultDTO.getRecordStatus()) && isLower24Hour(ContactCustResultDTO.getCreateTime())) {
} else if (1 == ContactCustResultDTO.getRecordStatus() && isLower24Hour(ContactCustResultDTO.getCreateTime())) {
ContactCustResultDTO.setEnableEdit(true);
} else {
ContactCustResultDTO.setEnableEdit(false);
......@@ -439,8 +439,8 @@ public class CampaignExecuteRepositoryImp implements CampaignExecuteRepository {
logger.error(e.getMessage(), e);
} finally {
session.close();
return list;
}
return list;
}
@Override
......
......@@ -57,8 +57,7 @@ public class CampaignRepositoryImpl implements CampaignRepositoryCustom {
ResultDTO result = new ResultDTO();
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Session session = null;
if (DataUtil.isNullOrEmpty(requestDto.getCompanySiteId())) {
result.setErrorCode(Constants.ApiErrorCode.ERROR);
......@@ -66,6 +65,9 @@ public class CampaignRepositoryImpl implements CampaignRepositoryCustom {
return result;
}
try {
session = sessionFactory.openSession();
session.beginTransaction();
StringBuilder sb = new StringBuilder();
sb.append(" SELECT");
......@@ -256,8 +258,10 @@ public class CampaignRepositoryImpl implements CampaignRepositoryCustom {
result.setDescription(Constants.ApiErrorDesc.ERROR);
logger.error(ex.getMessage(), ex);
} finally {
if(null != session) {
session.close();
}
}
return result;
}
......@@ -267,8 +271,7 @@ public class CampaignRepositoryImpl implements CampaignRepositoryCustom {
ResultDTO result = new ResultDTO();
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Session session = null;
if (DataUtil.isNullOrEmpty(requestDto.getCompanySiteId())) {
result.setErrorCode(Constants.ApiErrorCode.ERROR);
......@@ -276,6 +279,8 @@ public class CampaignRepositoryImpl implements CampaignRepositoryCustom {
return result;
}
try {
session = sessionFactory.openSession();
session.beginTransaction();
StringBuilder sb = new StringBuilder();
// sb.append(" SELECT CAMPAIGN_ID campaignId, " +
// " CAMPAIGN_CODE campaignCode, " +
......@@ -343,7 +348,7 @@ public class CampaignRepositoryImpl implements CampaignRepositoryCustom {
result.setErrorCode(Constants.ApiErrorCode.ERROR);
result.setDescription(Constants.ApiErrorDesc.ERROR);
} finally {
session.close();
if(session != null) session.close();
}
return result;
}
......@@ -353,9 +358,10 @@ public class CampaignRepositoryImpl implements CampaignRepositoryCustom {
logger.info("Start search max campaign code index::");
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Session session = null;
try {
session = sessionFactory.openSession();
session.beginTransaction();
//StringBuilder sb = new StringBuilder();
//sb.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "get-max-campaign-code-index"));
StringBuilder sb = new StringBuilder();
......@@ -373,6 +379,8 @@ public class CampaignRepositoryImpl implements CampaignRepositoryCustom {
}
} catch (Exception ex) {
logger.error(ex.getMessage(), ex);
}finally {
if(session != null) session.close();
}
return null;
}
......@@ -779,8 +787,8 @@ public class CampaignRepositoryImpl implements CampaignRepositoryCustom {
resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
} finally {
session.close();
return resultDTO;
}
return resultDTO;
}
@Override
......
......@@ -6,6 +6,7 @@ import com.viettel.econtact.filter.UserSession;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.List;
@Service
......@@ -17,7 +18,7 @@ public interface CampaignExecuteService {
ResultDTO searchInteractiveResult(CampaignRequestDTO dto);
XSSFWorkbook exportInteractiveResult(CampaignRequestDTO dto);
XSSFWorkbook exportInteractiveResult(CampaignRequestDTO dto) throws IOException;
List<ContactCustResultDTO> getContactCustById(CampaignRequestDTO dto);
//</editor-fold>
......
......@@ -11,6 +11,7 @@ import com.viettel.campaign.web.dto.request_dto.CustomizeRequestDTo;
import com.viettel.campaign.web.dto.request_dto.SearchCustomerRequestDTO;
import com.viettel.econtact.filter.UserSession;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
......@@ -76,9 +77,9 @@ public interface CustomerService {
List<CustomizeFields> getDynamicHeader(Long companySiteId);
byte[] buildTemplate(Long companySiteId);
byte[] buildTemplate(Long companySiteId) throws IOException;
Map<String, Object> readAndValidateCustomer(String path, List<CustomizeFields> headerDTOS, UserSession userSession, Long customerListId);
Map<String, Object> readAndValidateCustomer(String path, List<CustomizeFields> headerDTOS, UserSession userSession, Long customerListId) throws IOException;
List<CustomizeFieldObject> getCustomizeField(Long customerId);
......
......@@ -6,6 +6,7 @@ import com.viettel.econtact.filter.UserSession;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.RequestParam;
import java.io.IOException;
import java.util.List;
import java.util.Map;
......@@ -24,7 +25,7 @@ public interface ScenarioService {
ResultDTO saveContacQuestResult(ContactQuestResultDTO dto);
XSSFWorkbook buildTemplate();
XSSFWorkbook buildTemplate() throws IOException;
Map<String, Object> readAndValidateCustomer(String path, Long scenarioId, Long campaignId, Long companySiteId);
Map<String, Object> readAndValidateCustomer(String path, Long scenarioId, Long campaignId, Long companySiteId) throws IOException;
}
......@@ -66,8 +66,7 @@ public class AgentsServiceImpl implements AgentsService {
ResultDTO resultDTO = new ResultDTO();
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Session session = null;
if (DataUtil.isNullOrZero(companySiteId)) {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
......@@ -76,6 +75,8 @@ public class AgentsServiceImpl implements AgentsService {
}
try {
session = sessionFactory.openSession();
session.beginTransaction();
// StringBuilder sb = new StringBuilder();
// sb.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "campaign-agents-by-params"));
......@@ -136,7 +137,7 @@ public class AgentsServiceImpl implements AgentsService {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
} finally {
session.close();
if(session != null) session.close();
}
return resultDTO;
......@@ -147,8 +148,7 @@ public class AgentsServiceImpl implements AgentsService {
ResultDTO resultDTO = new ResultDTO();
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Session session = null;
if (DataUtil.isNullOrZero(companySiteId)) {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
......@@ -157,6 +157,8 @@ public class AgentsServiceImpl implements AgentsService {
}
try {
session = sessionFactory.openSession();
session.beginTransaction();
// StringBuilder sb = new StringBuilder();
// sb.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "campaign-agents-by-params"));
StringBuilder sb = new StringBuilder();
......@@ -214,7 +216,7 @@ public class AgentsServiceImpl implements AgentsService {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
} finally {
session.close();
if(session != null) session.close();
}
return resultDTO;
......@@ -278,8 +280,7 @@ public class AgentsServiceImpl implements AgentsService {
ResultDTO resultDTO = new ResultDTO();
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Session session = null;
if (DataUtil.isNullOrZero(companySiteId)) {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
......@@ -288,6 +289,8 @@ public class AgentsServiceImpl implements AgentsService {
}
try {
session = sessionFactory.openSession();
session.beginTransaction();
// StringBuilder sqlStrBuilder = new StringBuilder();
// sqlStrBuilder.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "campaign-agents-by-params"));
StringBuilder sqlStrBuilder = new StringBuilder();
......@@ -372,7 +375,7 @@ public class AgentsServiceImpl implements AgentsService {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
} finally {
session.close();
if(session != null) session.close();
}
return resultDTO;
......@@ -383,8 +386,10 @@ public class AgentsServiceImpl implements AgentsService {
ResultDTO resultDTO = new ResultDTO();
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
// Session session = sessionFactory.openSession();
// session.beginTransaction();
Session session = null;
if (DataUtil.isNullOrZero(companySiteId)) {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
......@@ -393,6 +398,8 @@ public class AgentsServiceImpl implements AgentsService {
}
try {
session = sessionFactory.openSession();
session.beginTransaction();
// StringBuilder sb = new StringBuilder();
// sb.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "campaign-agents-by-params"));
StringBuilder sb = new StringBuilder();
......@@ -477,8 +484,10 @@ public class AgentsServiceImpl implements AgentsService {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
} finally {
if(null != session){
session.close();
}
}
return resultDTO;
}
......
......@@ -44,8 +44,7 @@ public class CampaignCfgServiceImpl implements CampaignCfgService {
ResultDTO resultDTO = new ResultDTO();
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Session session = null;
if (DataUtil.isNullOrZero(companySiteId)) {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
......@@ -54,6 +53,8 @@ public class CampaignCfgServiceImpl implements CampaignCfgService {
}
try {
session = sessionFactory.openSession();
session.beginTransaction();
// StringBuilder sqlStrBuilder = new StringBuilder();
// sqlStrBuilder.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_STATUS_MNG, "findAll-CampaignCompleteCode"));
StringBuilder sb = new StringBuilder();
......@@ -132,7 +133,7 @@ public class CampaignCfgServiceImpl implements CampaignCfgService {
resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
logger.error(e.getMessage(), e);
} finally {
session.close();
if(session != null) session.close();
}
return resultDTO;
......@@ -278,8 +279,7 @@ public class CampaignCfgServiceImpl implements CampaignCfgService {
ResultDTO resultDTO = new ResultDTO();
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Session session = null;
if (DataUtil.isNullOrZero(completeCodeDTO.getCompanySiteId())) {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
......@@ -288,6 +288,8 @@ public class CampaignCfgServiceImpl implements CampaignCfgService {
}
try {
session = sessionFactory.openSession();
session.beginTransaction();
// StringBuilder sqlStrBuilder = new StringBuilder();
// sqlStrBuilder.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_STATUS_MNG, "get-max-value-completevalue"));
StringBuilder sb = new StringBuilder();
......@@ -323,9 +325,9 @@ public class CampaignCfgServiceImpl implements CampaignCfgService {
resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
logger.error(e.getMessage(), e);
} finally {
session.close();
return resultDTO;
if(session != null) session.close();
}
return resultDTO;
}
@Override
......@@ -367,8 +369,7 @@ public class CampaignCfgServiceImpl implements CampaignCfgService {
ResultDTO resultDTO = new ResultDTO();
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Session session = null;
if (DataUtil.isNullOrZero(campaignCompleteCodeId)) {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
......@@ -377,6 +378,8 @@ public class CampaignCfgServiceImpl implements CampaignCfgService {
}
try {
session = sessionFactory.openSession();
session.beginTransaction();
// StringBuilder sqlStrBuilder = new StringBuilder();
// sqlStrBuilder.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_STATUS_MNG,"findCampaignCodeById"));
......@@ -437,7 +440,7 @@ public class CampaignCfgServiceImpl implements CampaignCfgService {
resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
logger.error(e.getMessage(), e);
} finally {
session.close();
if(session != null) session.close();
}
return resultDTO;
......
......@@ -24,6 +24,9 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.*;
......@@ -33,6 +36,8 @@ public class CampaignExecuteServiceImp implements CampaignExecuteService {
private static final Logger logger = LoggerFactory.getLogger(CampaignExecuteServiceImp.class);
private SimpleDateFormat formatter = new SimpleDateFormat(Constants.DATE_FORMAT.FOMART_DATE_TYPE_1);
private Random rand = SecureRandom.getInstanceStrong();
@Autowired
ModelMapper modelMapper;
......@@ -66,6 +71,9 @@ public class CampaignExecuteServiceImp implements CampaignExecuteService {
@Autowired
CampaignCustomerListColumnRepository campaignCustomerListColumnRepository;
public CampaignExecuteServiceImp() throws NoSuchAlgorithmException {
}
//<editor-fold: hungtt>
@Override
@Transactional(DataSourceQualify.CCMS_FULL)
......@@ -119,14 +127,15 @@ public class CampaignExecuteServiceImp implements CampaignExecuteService {
@Override
@Transactional(DataSourceQualify.CCMS_FULL)
public XSSFWorkbook exportInteractiveResult(CampaignRequestDTO dto) {
public XSSFWorkbook exportInteractiveResult(CampaignRequestDTO dto) throws IOException {
Locale locale = Locale.forLanguageTag("vi");
List<ContactCustResultDTO> list = campaignExecuteRepository.getExcelInteractiveResult(dto);
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFWorkbook workbook = null;
Sheet sheet;
try {
// create font style
workbook = new XSSFWorkbook();
Font defaultFont = workbook.createFont();
defaultFont.setFontHeightInPoints((short) 13);
defaultFont.setFontName("Times New Roman");
......@@ -217,6 +226,12 @@ public class CampaignExecuteServiceImp implements CampaignExecuteService {
++rowIndex;
++count;
}
}catch (Exception e){
}finally {
if (workbook != null) workbook.close();
}
return workbook;
}
......@@ -493,13 +508,13 @@ public class CampaignExecuteServiceImp implements CampaignExecuteService {
@Override
public ResultDTO getCallStatus(CampaignRequestDTO dto) {
ResultDTO result = new ResultDTO();
Random r = new Random();
// Random r = new Random();
String[] arr = {"ACCEPT", "REJECT", "MISSING"};
if (dto != null) {
result.setErrorCode(Constants.ApiErrorCode.SUCCESS);
result.setDescription(Constants.ApiErrorDesc.SUCCESS);
result.setData(arr[r.nextInt(arr.length)]);
result.setData(arr[this.rand.nextInt(arr.length)]);
} else {
result.setErrorCode(Constants.ApiErrorCode.ERROR);
result.setDescription(Constants.ApiErrorDesc.ERROR);
......
......@@ -596,7 +596,7 @@ public class CampaignServiceImpl implements CampaignService {
// Cap nhat cac truong da co san
for (FieldsToShowDTO fieldsToShowDTO : list) {
if (fieldsToShowDTO.getId() != null) {
listColumns.removeIf(p -> p.getCampaignCusListColId() == fieldsToShowDTO.getId());
listColumns.removeIf(p -> p.getCampaignCusListColId().equals(fieldsToShowDTO.getId()));
CampaignCustomerListColumn entity = campaignCustomerListColumnRepository.findByCampaignCusListColId(fieldsToShowDTO.getId());
entity.setOrderIndex((long) (list.indexOf(fieldsToShowDTO) + 1));
campaignCustomerListColumnRepository.save(entity);
......
......@@ -46,6 +46,7 @@ import javax.persistence.criteria.CriteriaQuery;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
......@@ -103,8 +104,7 @@ public class CustomerServiceImpl implements CustomerService {
ResultDTO resultDTO = new ResultDTO();
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Session session = null;
if (DataUtil.isNullOrZero(companySiteId)) {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
......@@ -113,6 +113,8 @@ public class CustomerServiceImpl implements CustomerService {
}
try {
session = sessionFactory.openSession();
session.beginTransaction();
// StringBuilder sqlStrBuilder = new StringBuilder();
// sqlStrBuilder.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "campaign-customer-detail-by-params"));
......@@ -193,7 +195,7 @@ public class CustomerServiceImpl implements CustomerService {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
} finally {
session.close();
if(session != null) session.close();
}
return resultDTO;
......@@ -224,8 +226,7 @@ public class CustomerServiceImpl implements CustomerService {
ResultDTO resultDTO = new ResultDTO();
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Session session = null;
if (DataUtil.isNullOrZero(companySiteId)) {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
......@@ -234,6 +235,8 @@ public class CustomerServiceImpl implements CustomerService {
}
try {
session = sessionFactory.openSession();
session.beginTransaction();
// StringBuilder sqlStrBuilder = new StringBuilder();
// sqlStrBuilder.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "campaign-customer-detail-by-params"));
......@@ -339,7 +342,7 @@ public class CustomerServiceImpl implements CustomerService {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
} finally {
session.close();
if(session != null) session.close();
}
return resultDTO;
......@@ -429,8 +432,7 @@ public class CustomerServiceImpl implements CustomerService {
ResultDTO resultDTO = new ResultDTO();
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Session session = null;
if (DataUtil.isNullOrZero(companySiteId)) {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
......@@ -439,6 +441,8 @@ public class CustomerServiceImpl implements CustomerService {
}
try {
session = sessionFactory.openSession();
session.beginTransaction();
// StringBuilder sqlStrBuilder = new StringBuilder();
// sqlStrBuilder.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "get-customer-detail-by-id"));
StringBuilder sb = new StringBuilder();
......@@ -494,7 +498,7 @@ public class CustomerServiceImpl implements CustomerService {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
} finally {
session.close();
if(session != null) session.close();
}
return resultDTO;
......@@ -522,8 +526,7 @@ public class CustomerServiceImpl implements CustomerService {
ResultDTO resultDTO = new ResultDTO();
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Session session = null;
if (DataUtil.isNullOrZero(companySiteId)) {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
......@@ -532,6 +535,8 @@ public class CustomerServiceImpl implements CustomerService {
}
try {
session = sessionFactory.openSession();
session.beginTransaction();
// StringBuilder sb = new StringBuilder();
// sb.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "search-campaign-customer-by-params"));
......@@ -594,7 +599,7 @@ public class CustomerServiceImpl implements CustomerService {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
} finally {
session.close();
if(session != null) session.close();
}
return resultDTO;
......@@ -759,8 +764,7 @@ public class CustomerServiceImpl implements CustomerService {
ResultDTO resultDTO = new ResultDTO();
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Session session = null;
if (DataUtil.isNullOrEmpty(searchCustomerRequestDTO.getCompanySiteId())) {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
......@@ -769,6 +773,8 @@ public class CustomerServiceImpl implements CustomerService {
}
try {
session = sessionFactory.openSession();
session.beginTransaction();
// StringBuilder sb = new StringBuilder();
// sb.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "search-campaign-customer-by-params"));
StringBuilder sb = new StringBuilder();
......@@ -865,7 +871,7 @@ public class CustomerServiceImpl implements CustomerService {
resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
} finally {
session.close();
if(session != null) session.close();
}
return resultDTO;
......@@ -885,16 +891,11 @@ public class CustomerServiceImpl implements CustomerService {
try {
List<CustomerContact> data = customerContactRepository.findByCustomerIdAndAndContactTypeAndContact(customer.getCustomerId(), customer.getContactType(), customer.getContact(), SQLBuilder.buildPageable(customer));
if (customer != null) {
result.setErrorCode(Constants.ApiErrorCode.SUCCESS);
result.setDescription("customer contact data");
result.setListData(data);
result.setTotalRow(customerContactRepository.findByCustomerIdAndAndContactTypeAndContact(customer.getCustomerId(), customer.getContactType(), customer.getContact(), null).size());
} else {
result.setErrorCode(Constants.ApiErrorCode.ERROR);
result.setDescription("customer contact data null");
}
} catch (Exception e) {
e.printStackTrace();
}
......@@ -940,7 +941,7 @@ public class CustomerServiceImpl implements CustomerService {
@Override
@Transactional(DataSourceQualify.CCMS_FULL)
public Map<String, Object> readAndValidateCustomer(String path, List<CustomizeFields> dynamicHeader, UserSession userSession, Long customerListId) {
public Map<String, Object> readAndValidateCustomer(String path, List<CustomizeFields> dynamicHeader, UserSession userSession, Long customerListId) throws IOException{
LOGGER.info("------------READ AND VALIDATE--------------");
Locale locale = new Locale("vi", "VN");
DataFormatter dataFormat = new DataFormatter();
......@@ -948,6 +949,7 @@ public class CustomerServiceImpl implements CustomerService {
Map<String, Object> result = new HashMap<>();
StringBuilder sb = new StringBuilder();
int failedCount = 0;
XSSFWorkbook workbook = null;
try {
//<editor-fold desc="Khởi tạo mảng header tĩnh" defaultstate="collapsed">
......@@ -971,7 +973,7 @@ public class CustomerServiceImpl implements CustomerService {
File file = new File(path);
FileInputStream fis = new FileInputStream(file);
XSSFWorkbook workbook = new XSSFWorkbook(fis);
workbook = new XSSFWorkbook(fis);
ByteArrayOutputStream os = new ByteArrayOutputStream();
Sheet sheet = workbook.getSheetAt(0);
Row row = sheet.getRow(3);
......@@ -1056,11 +1058,11 @@ public class CustomerServiceImpl implements CustomerService {
&& rawDataList.get(i)[4] != null
&& !rawDataList.get(i)[4].toString().trim().equals("")) {
String str = validatePhone(rawDataList.get(i)[2].toString().trim(), locale);
str.concat(validateLength(BundleUtils.getLangString("customer.secondPhone", locale).split("#")[0], rawDataList.get(i)[3].toString(), 50, locale));
str += (validateLength(BundleUtils.getLangString("customer.secondPhone", locale).split("#")[0], rawDataList.get(i)[3].toString(), 50, locale));
if (!validateEmail(rawDataList.get(i)[4].toString().trim())) {
str.concat(BundleUtils.getLangString("customer.emailInvalid", locale));
str += (BundleUtils.getLangString("customer.emailInvalid", locale));
} else {
str.concat(validateDuplicateEmail(rawDataList.get(i)[4].toString().trim(), locale));
str += (validateDuplicateEmail(rawDataList.get(i)[4].toString().trim(), locale));
}
sb.append(validateLength(BundleUtils.getLangString("customer.email", locale).split("#")[0], rawDataList.get(i)[4].toString(), 50, locale));
sb.append(str);
......@@ -1249,7 +1251,7 @@ public class CustomerServiceImpl implements CustomerService {
os.close();
workbook.close();
result.put("content", os.toByteArray());
result.put("message", "");
result.put("message", "import-success");
} else {
workbook.write(os);
os.flush();
......@@ -1265,6 +1267,8 @@ public class CustomerServiceImpl implements CustomerService {
LOGGER.info(e.getMessage());
result.put("message", "validate-error");
return result;
}finally {
if (workbook != null) workbook.close();
}
}
......@@ -1335,11 +1339,12 @@ public class CustomerServiceImpl implements CustomerService {
@Override
@Transactional(DataSourceQualify.CCMS_FULL)
public byte[] buildTemplate(Long companySiteId) {
public byte[] buildTemplate(Long companySiteId) throws IOException {
LOGGER.info("-----------BUILD TEMPLATE-----------");
Locale locale = new Locale("vi", "VN");
XSSFWorkbook workbook = null;
try {
XSSFWorkbook workbook = new XSSFWorkbook();
workbook = new XSSFWorkbook();
CreationHelper creationHelper = workbook.getCreationHelper();
ByteArrayOutputStream os = new ByteArrayOutputStream();
Sheet sheet = workbook.createSheet("IMPORT");
......@@ -1478,11 +1483,12 @@ public class CustomerServiceImpl implements CustomerService {
workbook.write(os);
os.flush();
os.close();
workbook.close();
return os.toByteArray();
} catch (Exception e) {
LOGGER.error(e.getMessage());
return null;
}finally {
if (workbook != null) workbook.close();
}
}
......@@ -1818,70 +1824,32 @@ public class CustomerServiceImpl implements CustomerService {
@Override
public ResultDTO listCustomizeFields(CustomizeFieldsDTO customizeFields) {
ResultDTO resultDTO = new ResultDTO();
Map<String, String> params = new HashMap<>();
List<CustomizeFielObjectDTO> list;
StringBuilder stringBuilder = new StringBuilder();
try {
List<CustomizeFields> lstCustomizeFields = customizeFieldsRepository.findByFunctionCodeAndActiveAndStatusAndSiteId(customizeFields.getFunctionCode(), customizeFields.getActive(), customizeFields.getStatus(), customizeFields.getSiteId());
List<CustomizeFields> lstCustomizeFields = customizeFieldsRepository.findByFunctionCodeAndActiveAndStatusAndSiteId("CUSTOMER", 1L, 1L, customizeFields.getSiteId());
String cf[][] = {
{"-1", "Mã Khách Hàng", "number"},
{"-1", "Mã Khách Hàng", "text"},
{"-2", "Tên khách hàng", "text"},
{"-3", "Tên công ty", "text"},
{"-4", "Giới tính", "number"},
{"-4", "Giới tính", "combobox"},
{"-5", "Địa chỉ", "text"},
{"-6", "Nơi sinh", "text"},
{"-7", "Ngày sinh", "date"},
{"-8", "Số điện thoại", "number"},
{"-8", "Số điện thoại", "text"},
{"-9", "email", "text"},
{"-10", "Tên đăng nhập", "text"},
{"-11", "Loại Khách hàng", "number"},
{"-11", "Loại Khách hàng", "combobox"},
};
for (int x = 0; x < 11; x++) {
CustomizeFields datafill = new CustomizeFields();
datafill.setCustomizeFieldId(Long.parseLong(cf[x][0]));
datafill.setTitle(cf[x][1]);
datafill.setType(cf[x][2]);
lstCustomizeFields.add(datafill);
}
// try {
// stringBuilder.append(" with column_name_temp as (");
// stringBuilder.append(" select 'CUSTOMER_ID customerId' , from user_tab_columns, dual");
// stringBuilder.append(" union all");
// stringBuilder.append(" select 'CUSTOMER_NAME customerName' , from user_tab_columns, dual");
// stringBuilder.append(" union all");
// stringBuilder.append(" select 'CUSTOMER_TYPE customerType' , from user_tab_columns, dual");
// stringBuilder.append(" union all");
// stringBuilder.append(" select 'NAME name' , from user_tab_columns, dual");
// stringBuilder.append(" union all");
// stringBuilder.append(" select 'CURRENT_ADDRESS currentAddress', from user_tab_columns, dual");
// stringBuilder.append(" union all");
// stringBuilder.append(" select 'PLACE_OF_BIRTH placeOfBirth', from user_tab_columns, dual");
// stringBuilder.append(" union all");
// stringBuilder.append(" select 'DATE_OF_BIRTH dateOfBirth', from user_tab_columns, dual");
// stringBuilder.append(" union all");
// stringBuilder.append(" select 'MOBILE_NUMBER mobileNumber', from user_tab_columns, dual");
// stringBuilder.append(" union all");
// stringBuilder.append(" select 'EMAIL email', from user_tab_columns, dual");
// stringBuilder.append(" union all");
// stringBuilder.append(" select 'USERNAME username', from user_tab_columns, dual");
// stringBuilder.append(" union all");
// stringBuilder.append(" select 'CUSTOMER_TYPE customerType', from user_tab_columns, dual");
// stringBuilder.append(" where table_name = 'CUSTOMER'");
// stringBuilder.append(" )");
//
// stringBuilder.append(" select * from column_name_temp");
// stringBuilder.append(" union all");
// stringBuilder.append(" select title columnName, 0 isFix ");
// stringBuilder.append(" from customize_fields, dual");
// stringBuilder.append(" where function_code = 'CUSTOMER'");
// stringBuilder.append(" and site_id = :p_company_site_id");
// stringBuilder.append(" and STATUS = 1");
// stringBuilder.append(" and active = 1 ");
// params.put("p_company_site_id", customizeFields.getSiteId());
// params.put("p_customer_id", customizeFields.getCustomerId());
// LOGGER.info("SQL statement: " + stringBuilder);
// list = namedParameterJdbcTemplate.query(stringBuilder.toString(), params, BeanPropertyRowMapper.newInstance(CustomizeFielObjectDTO.class));
resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
resultDTO.setListData(lstCustomizeFields);
......@@ -1934,9 +1902,9 @@ public class CustomerServiceImpl implements CustomerService {
sb.append(" INNER JOIN CUSTOMIZE_FIELD_OBJECT CFO ON C.CUSTOMER_ID = CFO.OBJECT_ID");
sb.append(" INNER JOIN CUSTOMIZE_FIELDS CF ON CF.CUSTOMIZE_FIELD_ID = CFO.CUSTOMIZE_FIELDS_ID\n" +
" WHERE 1 = 1");
sb.append(" and CFO.STATUS = 1");
sb.append(" and active = 1 ");
sb.append(" and CF.FUNCTION_CODE = 'CUSTOMER' ");
sb.append(" AND CFO.STATUS = 1");
sb.append(" AND ACTIVE = 1 ");
sb.append(" AND CF.FUNCTION_CODE = 'CUSTOMER' ");
List<CustomerQueryDTO> customerDTOList = campaignCustomerDTO.getListQuery();
// sb.append(
......@@ -1949,17 +1917,42 @@ public class CustomerServiceImpl implements CustomerService {
// + campaignCustomerDTO.getListQuery().get(i).getOperator() + " "
// + campaignCustomerDTO.getListQuery().get(i).getCondition() + " ");
for (CustomerQueryDTO query : customerDTOList) {
if (query.getJoin() == null) {
sb.append("AND ");
} else {
sb.append(query.getJoin() + " ");
}
sb.append(query.getField() + " ");
sb.append(query.getOperator() + " ");
if ("like".equals(query.getOperator()) || "not like".equals(query.getOperator())) {
sb.append("%"+ query.getCondition() + "% ");
} else {
sb.append(query.getCondition());
// if (query.getJoin() == null) {
// sb.append("AND ");
// } else {
// sb.append(query.getJoin() + " ");
// }
// sb.append(query.getField() + " ");
// sb.append(query.getOperator() + " ");
// if ("like".equals(query.getOperator()) || "not like".equals(query.getOperator())) {
// sb.append("%"+ query.getCondition() + "% ");
// } else {
// sb.append(query.getCondition());
// }
// LIKE NOT
if (query.getField() == -1) {
sb.append(query.getJoin() + " C.CUSTOMER_ID " + query.getOperator() + " %" + query.getCondition() + "% ");
} else if (query.getField() == -2) {
sb.append(query.getJoin() + "C.NAME " + query.getOperator() + " '%" + query.getCondition() + "% ");
} else if (query.getField() == -3) {
sb.append(query.getJoin() + " C.COMPANY_NAME " + query.getOperator() + " %" + query.getCondition() + "% ");
} else if (query.getField() == -4) {
sb.append(query.getJoin() + " C.GENDER " + query.getOperator() + " %" + query.getCondition() + "% ");
} else if (query.getField() == -5) {
sb.append(query.getJoin() + " C.CURRENT_ADDRESS " + query.getOperator() + " %" + query.getCondition() + "% ");
} else if (query.getField() == -6) {
sb.append(query.getJoin() + " C.PLACE_OF_BIRTH " + query.getOperator() + " %" + query.getCondition() + "% ");
} else if (query.getField() == -7) {
sb.append(query.getJoin() + " C.DATE_OF_BIRTH " + query.getOperator() + " %" + query.getCondition() + "% ");
} else if (query.getField() == -8) {
sb.append(query.getJoin() + " C.MOBILE_NUMBER " + query.getOperator() + " %" + query.getCondition() + "% ");
} else if (query.getField() == -9) {
sb.append(query.getJoin() + " C.EMAIL " + query.getOperator() + " %" + query.getCondition() + "%' ");
} else if (query.getField() == -10) {
sb.append(query.getJoin() + " C.USER_NAME " + query.getOperator() + " %" + query.getCondition() + "%' ");
} else if (query.getField() == -11) {
sb.append(query.getJoin() + " C.CUSTOMER_TYPE " + query.getOperator() + " %" + query.getCondition() + "% ");
}
}
......@@ -2006,8 +1999,13 @@ public class CustomerServiceImpl implements CustomerService {
}
return resultDTO;
}
private String getCodition(String join, String operator, String codition) {
// if (operator.equalsIgnoreCase("LIKE") || operator.equalsIgnoreCase("NOT_LIKE")) {
// } else {
// return " " + join + " " + operator + " " + codition + " ";
// }
return null;
}
}
......@@ -22,6 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.*;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
......@@ -161,12 +162,13 @@ public class ScenarioServiceImpl implements ScenarioService {
@Override
@Transactional(DataSourceQualify.CCMS_FULL)
public XSSFWorkbook buildTemplate() {
public XSSFWorkbook buildTemplate() throws IOException {
Locale locale = new Locale("vi", "VN");
XSSFWorkbook workbook = null;
try {
XSSFWorkbook workbook = new XSSFWorkbook();
Sheet sheet;
Sheet sheet;
workbook = new XSSFWorkbook();
CellStyle styleTitle = WorkBookBuilder.buildDefaultStyleTitle(workbook);
CellStyle styleRowHeader = WorkBookBuilder.buildDefaultStyleRowHeader(workbook);
CellStyle styleRow = WorkBookBuilder.buildDefaultStyleRow(workbook);
......@@ -237,17 +239,20 @@ public class ScenarioServiceImpl implements ScenarioService {
} catch (Exception e) {
logger.error(e.getMessage());
return null;
}finally {
if (workbook != null) workbook.close();
}
}
@Override
@Transactional(DataSourceQualify.CCMS_FULL)
public Map<String, Object> readAndValidateCustomer(String path, Long scenarioId, Long campaignId, Long companySiteId) {
public Map<String, Object> readAndValidateCustomer (String path, Long scenarioId, Long campaignId, Long companySiteId) throws IOException{
Locale locale = new Locale("vi", "VN");
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
Map<String, Object> result = new HashMap<>();
StringBuilder sb = new StringBuilder();
boolean isValid = true;
XSSFWorkbook workbook = null;
try {
List<String> fileHeaderList = new ArrayList<>();
fileHeaderList.add(BundleUtils.getLangString("scenario.template.questionCode", locale));
......@@ -261,7 +266,8 @@ public class ScenarioServiceImpl implements ScenarioService {
File file = new File(path);
FileInputStream fis = new FileInputStream(file);
XSSFWorkbook workbook = new XSSFWorkbook(fis);
workbook = new XSSFWorkbook(fis);
workbook = new XSSFWorkbook(fis);
ByteArrayOutputStream os = new ByteArrayOutputStream();
Sheet sheet = workbook.getSheetAt(0);
Row row = sheet.getRow(2);
......@@ -440,13 +446,16 @@ public class ScenarioServiceImpl implements ScenarioService {
}
} catch (Exception ex) {
logger.info(ex.getMessage(), ex);
result.put("message", BundleUtils.getLangString("customer.errorValidate", locale));
}finally {
if (workbook != null) workbook.close();
result.put("code", Constants.FILE_UPLOAD_RESP_CODE.ERROR);
}
return result;
}
private boolean validateMappingQuestion(String mappingQuestion, String currentQuestionCode, List<String> lstQuestionCode) {
if (mappingQuestion == currentQuestionCode) return false;
if (mappingQuestion != null && mappingQuestion.equals(currentQuestionCode)) return false;
String duplicateCode = lstQuestionCode.stream().
filter(p -> (p.equals(mappingQuestion) && p.equals(currentQuestionCode))).
......
......@@ -12,7 +12,7 @@ import java.util.ResourceBundle;
*/
public class BundleUtils {
protected static final Logger logger = LoggerFactory.getLogger(BundleUtils.class);
private static volatile ResourceBundle rsConfig = null;
private static ResourceBundle rsConfig = null;
private static final String GLOBAL_CONFIG = "config/globalConfig";
public static String getLangString(String key, Locale... locale) {
......
......@@ -127,17 +127,10 @@ public class DataUtil {
}
public static boolean safeEqual(Long obj1, Long obj2) {
if (obj1 == obj2) {
if (obj1.equals(obj2)) {
return true;
}
return ((obj1 != null) && (obj2 != null) && (obj1.compareTo(obj2) == 0));
}
public static boolean safeEqual(String obj1, String obj2) {
if (obj1 == obj2) {
return true;
}
return ((obj1 != null) && (obj2 != null) && obj1.equals(obj2));
return obj2 != null && obj1.compareTo(obj2) == 0;
}
public static String convertDateToStringDDMMYYYYHHMISS(Date datetime) {
......
......@@ -16,7 +16,8 @@ public class RedisUtil {
private static final Logger logger = Logger.getLogger(RedisUtil.class);
private static volatile RedisUtil INSTANCE = null;
// private static volatile RedisUtil INSTANCE = null;
private static RedisUtil INSTANCE = null;
private JedisCluster jedisCluster;
private String redisAddress;
private int redisTimeout;
......
......@@ -4,7 +4,7 @@ import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
* @author anhvd_itsol
* @author anhvd_itsol 0ad5d5fb7aa141b4ac383bcb096e2ec3faba0b1b
*/
public class WorkBookBuilder {
public static Font buildDefaultFont(XSSFWorkbook workbook) {
......
......@@ -8,7 +8,7 @@ import lombok.Setter;
@Setter
public class CustomerQueryDTO extends BaseDTO {
String join ;
String field;
Long field;
String operator;
String condition;
......
......@@ -30,7 +30,10 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@Controller
@RequestMapping("/ipcc/customer")
......@@ -194,7 +197,6 @@ public class CustomerController {
@RequestPart("customerListId") String customerListId,
HttpServletRequest request) {
LOGGER.info("------------IMPORT FILE TEMPLATE--------------");
Locale locale = new Locale("vi", "VN");
try {
UserSession userSession = (UserSession) RedisUtil.getInstance().get(request.getHeader("X-Auth-Token"));
if (file.isEmpty()) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment