package biz.target;
|
|
import java.math.BigDecimal;
|
|
import foundation.data.entity.Entity;
|
import foundation.data.entity.EntityNode;
|
import foundation.data.entity.EntitySet;
|
import foundation.data.entity.EntityTree;
|
import foundation.data.entity.Filter;
|
import foundation.data.entity.GroupBy;
|
import foundation.data.getter.EntityTreeGetter;
|
import foundation.data.object.DataObject;
|
import foundation.json.IJSONProvider;
|
import foundation.json.IJSONWriter;
|
import foundation.persist.NamedSQL;
|
import foundation.persist.SQLRunner;
|
import foundation.preload.Bucket;
|
import foundation.util.ID;
|
import foundation.util.MapList;
|
import foundation.util.Util;
|
|
public class TargetOperator implements IJSONProvider {
|
|
private static DataObject tempTargetHospitalObject = DataObject.getInstance("temp_tgt_project_detail");
|
private static DataObject targetHospitalObject = DataObject.getInstance("tgt_project_detail");
|
private static DataObject tempTargetPositionObject = DataObject.getInstance("temp_tgt_distribution_position");
|
public static BigDecimal TotalTarget = new BigDecimal(100000000);
|
|
private String instanceId;
|
private String state;
|
private EntityTree positionTree;
|
private EntitySet positionSet;
|
private boolean hospitalBuild;
|
private boolean positionBuild;
|
private boolean hospitalSyncDB;
|
private boolean positionSyncDB;
|
private Bucket<PotentialInstance> potentials;
|
private MapList<String, TargetPotentialType> hospitalTargetType;
|
private BigDecimal totalForcaseAmt = BigDecimal.ZERO;
|
|
public TargetOperator (String id, String state){
|
this.instanceId = id;
|
this.potentials = new Bucket<PotentialInstance>();
|
this.hospitalTargetType = new MapList<String, TargetPotentialType>();
|
this.state = state;
|
|
try {
|
loadModel();
|
init();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
|
private void loadModel() throws Exception {
|
DataObject projectObject = DataObject.getInstance("tgt_project");
|
Entity entity = projectObject.getTableEntity(instanceId);
|
TargetModelBucket modelBucket = TargetModelBucket.getInstance();
|
|
String targetModelId = entity.getString("line_id_x");
|
TargetModel targetModelX = modelBucket.get(targetModelId);
|
|
targetModelId = entity.getString("line_id_y");
|
TargetModel targetModelY = modelBucket.get(targetModelId);
|
|
projectObject = DataObject.getInstance("tgt_project_distribution");
|
EntitySet detailSet = projectObject.getTableEntitySet(new Filter("parent_id", instanceId));
|
|
for (Entity detail : detailSet) {
|
TargetPotentialType targetType = new TargetPotentialType();
|
targetType.load(detail);
|
|
String lineId = detail.getString("line_id_x");
|
TargetModelDetail modelLevel = targetModelX.getLevelById(lineId);
|
targetType.addOneModel(modelLevel);
|
|
lineId = detail.getString("line_id_y");
|
modelLevel = targetModelY.getLevelById(lineId);
|
targetType.addOneModel(modelLevel);
|
|
Potential potential = new Potential();
|
potential.load(detail);
|
potential.setTargetType(targetType);
|
PotentialInstance potentialInstance = new PotentialInstance(potential);
|
potentials.loadOne(potentialInstance.getId(), potentialInstance);
|
}
|
}
|
|
private void init() throws Exception {
|
if (Util.isEmpty(state)){
|
buildHospital();
|
}
|
else if ( "预设".equals(state)) {
|
loadHospitalFromTemp();
|
}
|
else {
|
loadHospitalFromFormal();
|
}
|
|
for (PotentialInstance potential : potentials) {
|
potential.setHospitalBuild(true);
|
}
|
}
|
|
public void loadOnePotential(String potentialId) throws Exception {
|
PotentialInstance potential = potentials.get(potentialId);
|
|
potential.syncHospital();
|
potentials.loadOne(potentialId, potential);
|
}
|
|
public PotentialInstance getOnePotential(String potentialId) throws Exception {
|
PotentialInstance potential = potentials.get(potentialId);
|
if (!potential.isHospitalBuild()) {
|
potential.syncHospital();
|
}
|
|
// if (!potential.isPositionBuild()) {
|
// potential.buildPositionTree();
|
// }
|
|
return potential;
|
}
|
|
public void saveHospitalToDB(String state) throws Exception {
|
if (hospitalSyncDB) {
|
return ;
|
}
|
|
for (PotentialInstance potential : potentials) {
|
EntitySet hospitalSet = potential.getHospitalSet();
|
for (Entity hospital : hospitalSet) {
|
BigDecimal currentForecastAmt = hospital.getBigDecimal("current_forecast_amt");
|
hospital.set("current_forecast_rate",Util.divide(currentForecastAmt, currentForecastAmt, 4, BigDecimal.ROUND_HALF_UP));
|
}
|
|
potential.setHospitalSet(hospitalSet);
|
potential.saveHospitalToDB(state);
|
}
|
|
hospitalSyncDB = true;
|
}
|
|
public void buildHospital() throws Exception {
|
if (potentials != null) {
|
//1.获取指标维度
|
NamedSQL namedSQL = NamedSQL.getInstance("getTargetHospital");
|
EntitySet hospitalDimensionSet = SQLRunner.getEntitySet(namedSQL);
|
|
for (Entity hospitalDimension : hospitalDimensionSet) {
|
Entity hospital = tempTargetHospitalObject.createTableEntity(true);
|
String id = ID.newValue();
|
String hospitalId = hospitalDimension.getString("hospital_id");
|
hospital.set("id", id);
|
hospital.set("parent_id", hospitalDimension.getString("parent_id"));
|
hospital.set("bu_id", hospitalDimension.getString("bu_id"));
|
hospital.set("company_id", hospitalDimension.getString("company_id"));
|
hospital.set("region_id", hospitalDimension.getString("region_id"));
|
hospital.set("area_id", hospitalDimension.getString("area_id"));
|
hospital.set("position_id", hospitalDimension.getString("position_id"));
|
hospital.set("position_name", hospitalDimension.getString("position_path"));
|
hospital.set("employee_name", hospitalDimension.getString("employee_name"));
|
hospital.set("province", hospitalDimension.getString("province"));
|
hospital.set("city", hospitalDimension.getString("city"));
|
hospital.set("hospital_id", hospitalId);
|
hospital.set("hospital_code", hospitalDimension.getString("hospital_code"));
|
hospital.set("hospital_name", hospitalDimension.getString("hospital_name"));
|
hospital.set("hospital_attr", hospitalDimension.getString("hospital_attr"));
|
|
// 计算今年预测销售增长= 2024年
|
BigDecimal amtPre3 = hospitalDimension.getBigDecimal("amt_pre3", BigDecimal.ZERO);
|
BigDecimal amtLastPre3 = hospitalDimension.getBigDecimal("amt_last_pre3", BigDecimal.ZERO);
|
BigDecimal amtLastQ4 = hospitalDimension.getBigDecimal("amt_last_q4", BigDecimal.ZERO);
|
BigDecimal historyAmt = amtLastPre3.add(amtLastQ4);
|
BigDecimal rate = Util.divide(amtPre3, amtLastPre3, 4, BigDecimal.ROUND_HALF_UP);
|
BigDecimal currentForecastAmt = amtPre3.add(amtLastQ4.multiply(rate));
|
hospital.set("current_forecast_amt", currentForecastAmt);
|
hospital.set("current_increase_rate", rate);
|
hospital.set("history_amt", historyAmt);
|
|
totalForcaseAmt = totalForcaseAmt.add(currentForecastAmt);
|
//current_forecast_rate 贡献占比
|
|
// 计算医院潜力
|
PotentialInstance potential = calculatePotential(rate.subtract(BigDecimal.ONE), currentForecastAmt.subtract(historyAmt), historyAmt);
|
|
hospital.set("sort_id", potential.getId());
|
hospital.set("sort_name", potential.getName());
|
hospital.set("potential_rate", potential.getRate());
|
hospital.set("potential_amt", potential.getAmt());
|
|
BigDecimal potentialAmt = potential.getAmt();
|
|
hospital.set("target_amt", potentialAmt.add(currentForecastAmt));
|
hospital.set("target_increase_amt", potential.getAmt());
|
hospital.set("project_id", instanceId);
|
|
hospitalTargetType.add(hospitalId, potential.getTargetType());
|
//target_rate_cal, target_rate_actual, target_amt_actual
|
potential.loadOneHospital(hospital);
|
}
|
}
|
|
hospitalSyncDB = false;
|
hospitalBuild = true;
|
}
|
|
private void loadHospitalFromTemp() throws Exception {
|
EntitySet hospitalSet = tempTargetHospitalObject.getTableEntitySet(new Filter("project_id", instanceId));
|
|
for (Entity hospital : hospitalSet) {
|
String hospitalId = hospital.getString("hospital_id");
|
String potentialId = hospital.getString("sort_id");
|
PotentialInstance potential = potentials.get(potentialId);
|
potential.loadOneHospital(hospital);
|
|
hospitalTargetType.add(hospitalId, potential.getTargetType());
|
}
|
|
hospitalSyncDB = true;
|
hospitalBuild = true;
|
}
|
|
private void loadHospitalFromFormal() throws Exception {
|
EntitySet hospitalSet = targetHospitalObject.getTableEntitySet();
|
|
for (Entity hospital : hospitalSet) {
|
String hospitalId = hospital.getString("hospital_id");
|
String potentialId = hospital.getString("sort_id");
|
PotentialInstance potential = potentials.get(potentialId);
|
potential.loadOneHospital(hospital);
|
|
hospitalTargetType.add(hospitalId, potential.getTargetType());
|
}
|
|
hospitalSyncDB = true;
|
hospitalBuild = true;
|
}
|
|
private PotentialInstance calculatePotential(BigDecimal... values) {
|
for (PotentialInstance potential : potentials) {
|
if (potential.isValid(values)) {
|
return potential;
|
}
|
}
|
|
return null;
|
}
|
|
|
public void buildPositionTree() throws Exception {
|
String sum = "sum(target_increase_amt)/(sum(target_amt) -sum(target_increase_amt)) target_rate_cal, "
|
+ "sum(current_forecast_amt) current_forecast_amt, "
|
+ "sum(current_forecast_rate) current_forecast_rate, "
|
+ "sum(target_amt_sum) target_amt_sum, "
|
+ "sum(target_rate_actual) target_rate_actual, "
|
+ "sum(target_amt_actual) target_amt_actual ";
|
GroupBy groupBy = new GroupBy("position_id");
|
EntitySet postionSet = tempTargetHospitalObject.getSummary(sum, "", null, groupBy, null);
|
|
EntityTreeGetter postionTreeGetter = new EntityTreeGetter(postionSet.getEntityMeta());
|
postionTreeGetter.loadData(postionSet);
|
|
positionTree = postionTreeGetter.getEntityTree();
|
|
EntitySet rootSet = positionTree.getRootSet();
|
|
positionSet = tempTargetPositionObject.createTableEntitySet();
|
BigDecimal currentForecastAmt = null, currentForecastRate = null,
|
targetAmt = null, targetIncreaseAmt = null, targetRateCal = null, targetRateActual = null, targetAmtActual = null;
|
int levelNo = 0;
|
creatPositionNode(rootSet, levelNo, currentForecastAmt, currentForecastRate,
|
targetAmt, targetIncreaseAmt, targetRateCal, targetRateActual, targetAmtActual);
|
|
positionSyncDB = false;
|
positionBuild = true;
|
}
|
|
public void creatPositionNode(EntitySet rootSet, int levelNo, BigDecimal currentForecastAmt, BigDecimal currentForecastRate,
|
BigDecimal targetAmt, BigDecimal targetIncreaseAmt, BigDecimal targetRateCal, BigDecimal targetRateActual, BigDecimal targetAmtActual) throws Exception {
|
for (Entity entity: rootSet) {
|
EntityNode node = (EntityNode)entity;
|
currentForecastAmt = currentForecastAmt == null ? entity.getBigDecimal("current_forecast_amt") : currentForecastAmt.add(entity.getBigDecimal("current_forecast_amt"));
|
currentForecastRate = currentForecastRate == null ? entity.getBigDecimal("current_forecast_rate") : currentForecastRate.add(entity.getBigDecimal("current_forecast_rate"));
|
targetAmt = targetAmt == null ? entity.getBigDecimal("target_amt_sum") : targetAmt.add(entity.getBigDecimal("target_amt_sum"));
|
targetIncreaseAmt = targetIncreaseAmt == null ? entity.getBigDecimal("target_increase_amt") : targetIncreaseAmt.add(entity.getBigDecimal("target_increase_amt"));
|
targetRateCal = targetRateCal == null ? entity.getBigDecimal("target_rate_cal") : targetRateCal.add(entity.getBigDecimal("target_rate_cal"));
|
targetRateActual = targetRateActual == null ? entity.getBigDecimal("target_rate_actual") : targetRateActual.add(entity.getBigDecimal("target_rate_actual"));
|
targetAmtActual = targetAmtActual == null ? entity.getBigDecimal("target_amt_actual") : targetAmtActual.add(entity.getBigDecimal("target_amt_actual"));
|
levelNo = node.getLevel() + 1;
|
|
EntitySet children = node.getChildren();
|
|
if (children != null) {
|
creatPositionNode(children, levelNo, currentForecastAmt, currentForecastRate,
|
targetAmt, targetIncreaseAmt, targetRateCal, targetRateActual, targetAmtActual);
|
}
|
}
|
}
|
|
public void savePositionTreeToDB() throws Exception {
|
if (positionSyncDB) {
|
return ;
|
}
|
|
if (!positionBuild) {
|
buildPositionTree();
|
}
|
|
|
//保存至数据库
|
tempTargetPositionObject.emptyTable();
|
tempTargetPositionObject.batchInsertEntitySet(positionSet);
|
|
positionSyncDB = true;
|
}
|
|
public boolean isHospitalBuild() {
|
return hospitalBuild;
|
}
|
|
public boolean isPositionBuild() {
|
return positionBuild;
|
}
|
|
public EntityTree getPositionTree() {
|
return positionTree;
|
}
|
|
public void setPositionTree(EntityTree positionTree) {
|
this.positionTree = positionTree;
|
}
|
|
public Bucket<PotentialInstance> getPotentials() {
|
return potentials;
|
}
|
|
public void setState(String currentState) {
|
this.state = currentState;
|
}
|
|
public String getState() {
|
return state;
|
}
|
|
@Override
|
public void writeJSON(IJSONWriter writer) {
|
writer.beginObject();
|
|
for (PotentialInstance potential : potentials) {
|
writer.beginObject(potential.getId());
|
|
EntitySet hospitalSet = potential.getHospitalSet();
|
|
if (hospitalSet == null) {
|
writer.writeNull("hospitals");
|
}
|
else {
|
writer.beginArray("hospitals");
|
hospitalSet.writeJSONBody(writer);
|
writer.endArray();
|
}
|
|
writer.endObject();
|
}
|
|
//3. position
|
if (positionTree == null) {
|
writer.writeNull("positions");
|
}
|
else {
|
writer.beginArray("positions");
|
positionTree.writeJSONBody(writer);
|
writer.endArray();
|
}
|
|
writer.endObject();
|
}
|
}
|