EcnManagerImpl.java
package com.mycim.server.ecn.manager.impl;
import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.exception.SystemIllegalArgumentException;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.jdbc.Page;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.framework.utils.lang.math.NumberUtils;
import com.mycim.framework.utils.lang.time.DateUtils;
import com.mycim.server.base.manager.NamedObjectManager;
import com.mycim.server.base.manager.TransactionLogManager;
import com.mycim.server.ecn.dao.EcnDAO;
import com.mycim.server.edc.manager.EcnManager;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.bas.NamedObject;
import com.mycim.valueobject.bas.TransactionLog;
import com.mycim.valueobject.consts.TransactionNames;
import com.mycim.valueobject.consts.VersionStatus;
import com.mycim.valueobject.prp.Ecn;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* ecn
*
* @author Johnson.Wang
* @version 6.0.0
* @date 2019/8/31
**/
@Service
@Transactional
public class EcnManagerImpl implements EcnManager {
private static final String DATE_FORMAT_YYYY_MM_DD = "yyyyMMdd";
private static final String SUFFIX_PATTERN = "0000";
private static final String SUFFIX_PLACEHOLDER = "____";
private static final Integer ECN_ID_LENGTH = 15;
private static final Integer PREFIX_LENGTH = 11;
private static final Integer MAX_SEQUENCE = 9999;
private static final Integer MAX_UPGRADE_COUNT = 99999;
@Autowired
private EcnDAO ecnDAO;
@Autowired
private NamedObjectManager namedObjectManager;
@Autowired
private TransactionLogManager transactionLogManager;
@Override
public Ecn generateUnFrozenEcn(Long userRrn, String type) {
return generateUnFrozenEcn(userRrn, type, type);
}
@Override
public Ecn generateUnFrozenEcn(Long requestBy, String type, String subType) {
return generateEcn(requestBy, type, subType, VersionStatus.UNFROZEN_KEY);
}
@Override
public Ecn generateActiveEcn(Long requestBy, String type, String subType) {
return generateEcn(requestBy, type, subType, VersionStatus.ACTIVE_KEY);
}
@Override
public Ecn generateActiveEcn(Long userRrn, String type) {
return generateActiveEcn(userRrn, type, type);
}
@Override
public Ecn getEcn(String ecnId) {
return getEcn(namedObjectManager.getNamedObjectRrn(ecnId, LocalContext.getFacilityRrn(), ObjectList.ECN_KEY));
}
@Override
public Ecn getEcn(long ecnRrn) {
NamedObject namedObject = namedObjectManager.getNamedObject(ecnRrn);
if (namedObject == null) {
return null;
}
Ecn ecn = ecnDAO.getEcn(ecnRrn);
ecn.setRequestById(namedObjectManager.getNamedObjectId(ecn.getRequestBy()));
ecn.copyNamedObject(namedObject);
if (ecn.getObjectType() == null) {
ecn.setObjects(ecnDAO.getEcnObjectVersions(ecnRrn));
} else {
if (ecn.getObjectType().equalsIgnoreCase(ObjectList.CONTEXT_KEY)) {
ecn.setObjects(ecnDAO.getEcnContextValues(ecnRrn));
} else {
ecn.setObjects(ecnDAO.getEcnObjectVersions(ecnRrn));
}
}
return ecn;
}
@Override
public void updateEcnStatus(String status, long ecnRrn) {
updateEcnStatus(status, status, ecnRrn);
}
@Override
public void updateEcnStatus(String status, String comments, long ecnRrn) {
Ecn ecn = getEcn(ecnRrn);
Assert.state(ecn != null,
Errors.create().key(MessageIdList.ECN_MISSING).content("The ECN is not found").build());
// 1. 更改ecn状态
ecnDAO.updateEcnStatus(status, comments, ecnRrn);
// 2. 更改ecn关联对象状态
if (ObjectList.CONTEXT_KEY.equals(ecn.getObjectType())) {
ecnDAO.updateStatusForContext(status, ecnRrn);
} else {
ecnDAO.updateStatusForObjectVersion(status, ecnRrn);
}
}
@Override
public long insertEcn(Ecn ecn) {
TransactionLog transactionLog = transactionLogManager
.startTransactionLog(ecn.getTransPerformedby(), ecn.getTransId());
long transRrn = transactionLog.getTransRrn();
long instanceRrn;
try {
instanceRrn = namedObjectManager.insertNamedObject(ecn, transRrn);
} catch (SystemIllegalArgumentException e) {
throw new SystemIllegalArgumentException(Errors.create().key(MessageIdList.ECN_MAX_UPGRADE_COUNT).content("The maximum number of daily update has been reached. Please try again tomorrow!").build());
}
// main or history table handle
ecn.setInstanceRrn(instanceRrn);
ecnDAO.insertEcn(ecn);
ecnDAO.insertEcnHistory(transRrn, 1, transactionLog.getTransId(), ecn.getInstanceRrn(),
ecn.getCreatedTimestamp());
ecnDAO.insertEcnHistoryComment(ecn, transRrn);
// mark transaction end flag
transactionLogManager.markTransactionLog(transactionLog);
return instanceRrn;
}
@Override
public Ecn generateUnFrozenEcnForProcessPlan(long requestBy) {
return generateUnFrozenEcn(requestBy, "PROCESSPLAN");
}
@Override
public Ecn generateUnFrozenEcnForContext(long requestBy) {
return generateUnFrozenEcn(requestBy, ObjectList.CONTEXT_KEY);
}
@Override
public long getEcnSignOffRrn(String ecnType, String refNamedSpace, String tNamedSpace) {
return ecnDAO.getEcnSignOffRrn(ecnType, refNamedSpace, tNamedSpace);
}
@Override
public boolean isEcnControled(String object, String namedSpace) {
return ecnDAO.isEcnControled(object, namedSpace);
}
@Override
public Ecn generateActiveEcnForContext(long requestBy) {
return generateActiveEcn(requestBy, ObjectList.CONTEXT_KEY);
}
@Override
public Ecn activateEcn(Long ecnRrn, String userId) {
Ecn ecn = getEcn(ecnRrn);
ecn.setEcnStatus(VersionStatus.ACTIVE_KEY);
ecn.setEffectiveDateFrom(getEffectiveDateFrom());
ecn.setEffectiveDateTo(getEffectiveDateTo());
ecn.setComments(TransactionNames.ACTIVE_KEY);
ecn.setTransId(TransactionNames.ACTIVE_KEY);
ecn.setTransPerformedby(userId);
TransactionLog transactionLog = transactionLogManager
.startTransactionLog(ecn.getTransPerformedby(), ecn.getTransId());
long transRrn = transactionLog.getTransRrn();
// update ecn
updateEcnForStatus(ecn);
// make ecn transhisory
ecnDAO.insertEcnHistory(transRrn, 1, transactionLog.getTransId(), ecn.getInstanceRrn(),
transactionLog.getTransStartTimestamp());
ecnDAO.insertEcnHistoryComment(ecn, transRrn);
transactionLogManager.markTransactionLog(transactionLog);
return ecn;
}
@Override
public String generateECNID() {
String ecnId;
Calendar now = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String today = sdf.format(now.getTime());
String maxEcnNum = ecnDAO.getMaxEcnNo(today);
int nextSeq = 1;
if (StringUtils.isEmpty(maxEcnNum)) {
ecnId = "F" + today + ".00001";
} else {
String maxStr = StringUtils.substringAfter(maxEcnNum, ".");
nextSeq += Integer.parseInt(maxStr);
Assert.isFalse(nextSeq > MAX_UPGRADE_COUNT, Errors.create().key(MessageIdList.ECN_MAX_UPGRADE_COUNT).content(
"The maximum number of daily update has been reached. Please try again tomorrow!").build());
if (!NumberUtils.isParsable(maxStr)) {
ecnId = "F" + today + ".00001";
} else {
int max = NumberUtils.toInt(maxStr) + 1;
String format = String.format("%05d", max);
ecnId = "F" + today + "." + format;
}
}
return ecnId;
}
@Override
public Ecn generateUnFrozenECNForRunCard(long requestBy, String type, String idType) {
String ecnId = generateECNIDFromRunCard(idType);
Ecn ecn = new Ecn(ecnId, namedObjectManager.getNamedSpace(LocalContext.getFacilityRrn(), ObjectList.ECN_KEY),
ObjectList.ECN_KEY);
ecn.setObject(ObjectList.ECN_KEY);
ecn.setTransId(TransactionNames.CREATE_KEY);
ecn.setInstanceDesc("Automatic schema generation for split run card");
ecn.setEffectiveDateFrom(getEffectiveDateFrom());
ecn.setEffectiveDateTo(getEffectiveDateTo());
ecn.setEcnStatus(VersionStatus.DRAFT_KEY);
ecn.setObject(ObjectList.ECN_KEY);
ecn.setObjectType(type);
ecn.setObjectSubtype(type);
ecn.setRequestBy(requestBy);
ecn.setTransId(TransactionNames.CREATE_KEY);
ecn.setTransPerformedby(LocalContext.getUserId());
ecn.setInstanceRrn(insertEcn(ecn));
return ecn;
}
@Override
public Ecn generateUnFrozenEcnForProduct(long requestBy) {
return generateUnFrozenEcn(requestBy, "PRODUCT");
}
@Override
public void updateRunCardStatus(Long runCardRrn, Timestamp effectiveDateFrom, Timestamp effectiveDateTo,
String status) {
ecnDAO.updateRunCardStatus(runCardRrn, effectiveDateFrom, effectiveDateTo, status);
}
@Override
public void insertEcnHistory(Long transRrn, Integer transSequence, String transId, Long ecnRrn) {
ecnDAO.insertEcnHistory(transRrn, transSequence, transId, ecnRrn, new Timestamp(System.currentTimeMillis()));
}
@Override
public Page getEcnHistoryPage(int pageNo, int pageSize, Long ecnRrn) {
return ecnDAO.getEcnHistoryPage(pageNo, pageSize, ecnRrn);
}
public void updateEcnForStatus(Ecn ecn) {
ecnDAO.updateEcnForStatus(ecn);
if (ObjectList.CONTEXT_KEY.equals(ecn.getObjectType())) {
ecnDAO.updateContextValueForEcn(ecn);
} else {
ecnDAO.updateObjectVersionForEcn(ecn);
}
}
private Ecn generateEcn(Long requestBy, String type, String subType, String ecnStatus) {
Ecn ecn = buildBaseEcnInfo();
ecn.setObjectType(type);
ecn.setObjectSubtype(subType);
ecn.setRequestBy(requestBy);
String userId = namedObjectManager.getInstanceId(requestBy);
userId = StringUtils.isEmpty(userId) ? "SYSTEM" : userId;
ecn.setTransPerformedby(userId);
ecn.setEffectiveDateFrom(DateUtils.formatDate(new Date()));
ecn.setEffectiveDateTo(getEffectiveDateTo());
ecn.setEcnStatus(ecnStatus);
ecn.setObject(ObjectList.ECN_KEY);
ecn.setTransId(TransactionNames.CREATE_KEY);
ecn.setInstanceRrn(insertEcn(ecn));
return ecn;
}
private String generateECNIDFromRunCard(String idType) {
StringBuilder prefix = buildPrefix(idType);
String maxEcnId = ecnDAO.getMaxEcnIdFromHistory(prefix.toString() + SUFFIX_PLACEHOLDER);
int nextSeq = 1;
if (StringUtils.isNotEmpty(maxEcnId)) {
nextSeq += substringForSeq(maxEcnId);
Assert.isFalse(nextSeq > MAX_SEQUENCE, Errors.create().content(
"The generated serial number has reached the " + "maximum serial number of the day. Please " +
"apply again tomorrow.").build());
}
return prefix.append(new DecimalFormat(SUFFIX_PATTERN).format(nextSeq)).toString();
}
private int substringForSeq(String maxEcnId) {
return Integer.parseInt(maxEcnId.substring(PREFIX_LENGTH, ECN_ID_LENGTH));
}
private StringBuilder buildPrefix(String idType) {
Calendar now = Calendar.getInstance();
String today = new SimpleDateFormat(DATE_FORMAT_YYYY_MM_DD).format(now.getTime());
return new StringBuilder(ECN_ID_LENGTH).append(idType).append(today);
}
/**
* 设置新ECN的基本信息
*/
private Ecn buildBaseEcnInfo() {
String ecnId = generateECNID();
Ecn ecn = new Ecn(ecnId, namedObjectManager.getNamedSpace(LocalContext.getFacilityRrn(), ObjectList.ECN_KEY),
ObjectList.ECN_KEY);
ecn.setInstanceDesc("Automatic schema generation");
ecn.setObject(ObjectList.ECN_KEY);
ecn.setTransId(TransactionNames.CREATE_KEY);
return ecn;
}
/**
* 生效时间: 当前时间
*
* @return
*/
private String getEffectiveDateFrom() {
return DateUtils.formatDate(new Date());
}
/**
* 失效时间: 100年后时间
*
* @return
*/
private String getEffectiveDateTo() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) + 100);
return DateUtils.formatDate(cal.getTime());
}
}