dobe_comic8/main/java/shkd/repc/repmd/formplugin/TotalAssignmentPlugin.java

504 lines
24 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package shkd.repc.repmd.formplugin;
import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.utils.StringUtils;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.entity.datamodel.RowDataEntity;
import kd.bos.entity.datamodel.events.AfterAddRowEventArgs;
import kd.bos.entity.datamodel.events.BeforeImportEntryEventArgs;
import kd.bos.entity.datamodel.events.ImportDataEventArgs;
import kd.bos.entity.datamodel.events.PropertyChangedArgs;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.entity.plugin.ImportLogger;
import kd.bos.form.container.Tab;
import kd.bos.form.control.Control;
import kd.bos.form.control.EntryGrid;
import kd.bos.form.control.Label;
import kd.bos.form.control.Toolbar;
import kd.bos.form.control.events.BeforeItemClickEvent;
import kd.bos.form.control.events.ItemClickEvent;
import kd.bos.form.control.events.RowClickEvent;
import kd.bos.form.control.events.RowClickEventListener;
import kd.bos.form.events.ClientCallBackEvent;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.form.plugin.importentry.resolving.ImportEntryData;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.sdk.plugin.Plugin;
import kd.tsc.tsrbs.business.domain.oprecord.service.helper.OprecordHelper;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
/**
* 位置:【项目主数据】-【项目建立】-表单插件
* 功能:面积数据合计赋值
* 时间2024/12/16
*/
public class TotalAssignmentPlugin extends AbstractFormPlugin implements RowClickEventListener, Plugin {
private static final String BILL_NAME="billname";
private static final String RENTAL_AREA="qeug_decimalfield5";
private static final String RENTAL_AREA_ENTRY="qeug_productentry_saleare";
private static final String ENTRY_VALUE = "qeug_jrgsbsz";
private static final String PRODUCT_ENTRY = "productentry";
private static final String PRODUCT_TYPE = "productentry_producttype";
private static final String PRODUCT_TYPE_NUMBER = "productentry_producttype.longnumber";
private static final String SUB_ENTRY = "qeug_subentryentity";
// 控件缓存
private Label publicAmountLabel;
private Label watertightAmountLabel;
private Label hardcoverAmountLabel;
@Override
public void registerListener(EventObject e) {
super.registerListener(e);
this.addItemClickListeners("tbmain");
this.addItemClickListeners("advcontoolbarap");
this.addItemClickListeners("qeug_advcontoolbarap");
EntryGrid entryGrid = this.getControl(PRODUCT_ENTRY);
entryGrid.addRowClickListener(this);
// 缓存控件,减少重复调用
publicAmountLabel = (Label) this.getControl("qeug_publicamount");
watertightAmountLabel = (Label) this.getControl("qeug_watertightamount");
hardcoverAmountLabel = (Label) this.getControl("qeug_hardcoveramount");
}
@Override
public void clientCallBack(ClientCallBackEvent e) {
super.clientCallBack(e);
String name = e.getName();
if ("auto_save".equals(name)) {
this.getView().invokeOperation("save");
}
}
@Override
public void entryRowClick(RowClickEvent evt) {
EntryGrid entryGrid = (EntryGrid) evt.getSource();
if (PRODUCT_ENTRY.equals(entryGrid.getKey())) {
// 业务逻辑
DynamicObjectCollection subEntryEntity = (DynamicObjectCollection) this.getModel().getValue(SUB_ENTRY);
if (subEntryEntity != null) {
onlyCalculateArea(subEntryEntity);
}
this.getView().updateView(SUB_ENTRY);
}
}
@Override
public void propertyChanged(PropertyChangedArgs e) {
super.propertyChanged(e);
publicAmountLabel = (Label) this.getControl("qeug_publicamount");
watertightAmountLabel = (Label) this.getControl("qeug_watertightamount");
hardcoverAmountLabel = (Label) this.getControl("qeug_hardcoveramount");
String fieldKey = e.getProperty().getName();
switch (fieldKey){
case ENTRY_VALUE:
DynamicObjectCollection collections = (DynamicObjectCollection) this.getModel().getValue(SUB_ENTRY);
DynamicObject parent = (DynamicObject) collections.get(0).getParent();
Long id = parent.getLong("id");
if (id != 0L) {
//更新指标信息数据
Object pkValue = this.getModel().getValue("id");
Long typeId = parent.getLong("productentry_producttype.id");
this.updateMetricInfo(collections, typeId, pkValue);
//更新产品构成数据(不切换标签也能生效)
DynamicObjectCollection productEntry = this.getModel().getEntryEntity(PRODUCT_ENTRY);
this.setProductEntryValue(productEntry,collections,id);
}
break;
case BILL_NAME:
String value = (String) this.getModel().getValue("billno");
if (value != null) {
this.getView().addClientCallBack("auto_save", 0);
}
break;
case RENTAL_AREA_ENTRY:
BigDecimal canSaleArea=BigDecimal.ZERO;
DynamicObjectCollection productEntry = this.getModel().getEntryEntity(PRODUCT_ENTRY);
if (null!=productEntry){
for (DynamicObject dynamicObject : productEntry) {
BigDecimal area = dynamicObject.getBigDecimal(RENTAL_AREA_ENTRY);
if (area.compareTo(BigDecimal.ZERO)!=0){
canSaleArea=canSaleArea.add(area);
}
}
this.getModel().setValue(RENTAL_AREA,canSaleArea);
}
break;
}
}
@Override
public void afterBindData(EventObject e) {
super.afterBindData(e);
DynamicObjectCollection productEntry = this.getModel().getEntryEntity(PRODUCT_ENTRY);
if (null != productEntry && productEntry.size() != 0) {
//选中第一条数据
EntryGrid entryGrid = this.getControl("productentry");
entryGrid.selectRows(0);
//查询是否有未保存数据id==0L
boolean exitNoSaveData = false;
for (int i = 0; i < productEntry.size(); i++) {
Long id = productEntry.get(i).getLong("id");
if (id == 0L) {
exitNoSaveData = true;
break;
}
}
if (exitNoSaveData) {
DynamicObjectCollection subEntryEntity = (DynamicObjectCollection) this.getModel().getValue(SUB_ENTRY);
if (null != subEntryEntity && subEntryEntity.size() != 0) {
//获取产品构成分录父数据实体类型
DynamicObject parent = (DynamicObject) ((DynamicObject) subEntryEntity.getParent()).getParent();
DynamicObjectCollection productParent = parent.getDynamicObjectCollection(PRODUCT_ENTRY);
for (int i = 0; i < productParent.size(); i++) {
//获取产品构成分录相关联的面积数据分录
DynamicObjectCollection collections = productParent.get(i).getDynamicObjectCollection(SUB_ENTRY);
//先清空计入估算表数值再赋值,触发保存
for (int j = 0; j < collections.size(); j++) {
this.getModel().setValue("qeug_jrgsbsz", BigDecimal.ZERO, j, i);
BigDecimal hjs = collections.get(j).getBigDecimal("qeug_hjs");
BigDecimal tzz = collections.get(j).getBigDecimal("qeug_tzz");
this.getModel().setValue("qeug_jrgsbsz", hjs.add(tzz), j, i);
}
}
this.getView().addClientCallBack("auto_save", 0);
}
}
}
}
@Override
public void itemClick(ItemClickEvent evt) {
super.itemClick(evt);
if (StringUtils.equals("qeug_advconbaritemap7", evt.getItemKey())) {
//表单id
Object pkValue = this.getModel().getValue("id");
DynamicObjectCollection productEntry = this.getModel().getEntryEntity(PRODUCT_ENTRY);
if (null != productEntry && productEntry.size() != 0) {
for (int i = 0; i < productEntry.size(); i++) {
if (productEntry.get(i).getBigDecimal("productentry_buildingarea").compareTo(BigDecimal.ZERO) == 0) {
DynamicObjectCollection collections = productEntry.get(i).getDynamicObjectCollection(SUB_ENTRY);
//防水面积赋值
BigDecimal waterproofArea = collections.stream()
.filter(collection -> "防水".equals(collection.getString("qeug_fl"))) // 排除 "防水" 类型
.map(collection -> {
BigDecimal hjs = collection.getBigDecimal("qeug_hjs");
BigDecimal tzz = collection.getBigDecimal("qeug_tzz");
return hjs.add(tzz);
})
.reduce(BigDecimal.ZERO, BigDecimal::add);
this.getModel().setValue("qeug_waterproofarea",waterproofArea,i);
//指标信息赋值
Long typeId = productEntry.get(i).getLong("productentry_producttype.id");
this.updateMetricInfo(collections, typeId, pkValue);
}
}
Tab tab = this.getView().getControl("tabap");
tab.activeTab("indexpage_tab");
}
} else if (StringUtils.equals("deleteproductentry", evt.getItemKey())) {
//保存表单
this.getView().addClientCallBack("auto_save", 0);
//清空标签控件
updateLabel(publicAmountLabel, BigDecimal.ZERO);
updateLabel(watertightAmountLabel, BigDecimal.ZERO);
updateLabel(hardcoverAmountLabel, BigDecimal.ZERO);
}
}
@Override
public void beforeImportEntry(BeforeImportEntryEventArgs e) {
super.beforeImportEntry(e);
Set<String> existCodes = new HashSet<>();
DynamicObjectCollection orderFormEntry = (DynamicObjectCollection) this.getModel().getValue(PRODUCT_ENTRY);
if (null != orderFormEntry && orderFormEntry.size() != 0) {
for (DynamicObject dynamicObject : orderFormEntry) {
String number = dynamicObject.getString(PRODUCT_TYPE_NUMBER);
existCodes.add(number);
}
}
Set<Map.Entry<String, List<ImportEntryData>>> entries = ((HashMap) e.getSource()).entrySet();
for (Map.Entry<String, List<ImportEntryData>> entry : entries) {
String entryName = entry.getKey();
List<ImportEntryData> entryEntityImportDataList = entry.getValue();
if (CollectionUtils.isEmpty(entryEntityImportDataList)) {
return;
}
Map<Integer, String> indexVsMsgMap = validateEntry(entryEntityImportDataList, existCodes);
Set<Integer> indexSet = indexVsMsgMap.keySet();
Map<String, List<Object>> logMap = e.getEntryDataMap();
ImportLogger importLogger = (ImportLogger) logMap.get(entryName).get(0);
for (Map.Entry<Integer, String> indexVsMsgEntry : indexVsMsgMap.entrySet()) {
Integer index = indexVsMsgEntry.getKey();
importLogger.log(index, indexVsMsgEntry.getValue());
importLogger.fail();
importLogger.setTotal(importLogger.getTotal() + 1);
}
Iterator<ImportEntryData> iterator = entryEntityImportDataList.iterator();
while (iterator.hasNext()) {
ImportEntryData entryData = iterator.next();
Integer rowNum = (Integer) entryData.getData().get("rowNum");
if (indexSet.contains(rowNum)) {
iterator.remove();
}
}
// **合并相同编码的 qeug_subentryentity**
Map<String, List<ImportEntryData>> groupedByNumber = new HashMap<>();
// 将 entryEntityImportDataList 按照 number 分组
for (ImportEntryData entryData : entryEntityImportDataList) {
String number = entryData.getData().getJSONObject("productentry_producttype").getString("number");
groupedByNumber.putIfAbsent(number, new ArrayList<>());
groupedByNumber.get(number).add(entryData);
}
// 遍历按 number 分组的条目并合并 qeug_subentryentity
List<ImportEntryData> mergedEntries = new ArrayList<>();
for (List<ImportEntryData> groupedEntries : groupedByNumber.values()) {
ImportEntryData firstEntry = groupedEntries.get(0);
JSONArray mergedSubEntryEntities = firstEntry.getData().getJSONArray("qeug_subentryentity");
// 合并相同 number 的所有 qeug_subentryentity
for (int i = 1; i < groupedEntries.size(); i++) {
ImportEntryData currentEntry = groupedEntries.get(i);
JSONArray currentSubEntryEntities = currentEntry.getData().getJSONArray("qeug_subentryentity");
// 将当前的 qeug_subentryentity 加入到 mergedSubEntryEntities
mergedSubEntryEntities.addAll(currentSubEntryEntities);
}
// 更新第一个条目的 qeug_subentryentity 为合并后的结果
firstEntry.getData().put("qeug_subentryentity", mergedSubEntryEntities);
// 将合并后的条目添加到结果列表中
mergedEntries.add(firstEntry);
}
// 更新 entryEntityImportDataList 为合并后的条目
entryEntityImportDataList.clear();
entryEntityImportDataList.addAll(mergedEntries);
}
}
private Map<Integer, String> validateEntry(List<ImportEntryData> entryEntityImportDataList, Set<String> existCodes) {
Map<Integer, String> indexVsMsgMap = new HashMap<>();
for (int i = 0; i < entryEntityImportDataList.size(); i++) {
ImportEntryData entryData = entryEntityImportDataList.get(i);
// 获取当前行的 JSONObject 数据
JSONObject data = entryData.getData();
Map<String, Object> map = data.toJavaObject(Map.class);
JSONObject productType = (JSONObject) map.get(PRODUCT_TYPE);
// 获取编码
String number = productType.getString("number");
// 获取当前行号
Integer rowNum = (Integer) entryData.getData().get("rowNum");
// 校验物料编码和物料单位
if (number == null || number.trim().isEmpty()) {
indexVsMsgMap.put(rowNum, "" + (i + 1) + "行:产品类型编码不能为空或空字符串");
}
// 校验物料编码是否已经存在于当前页面的表格中
if (existCodes.contains(number)) {
indexVsMsgMap.put(rowNum, "" + (i + 1) + "行:产品类型编码已存在表单分录,不能重复导入");
}
}
return indexVsMsgMap;
}
private void onlyCalculateArea(DynamicObjectCollection subEntryEntity) {
if (subEntryEntity == null || subEntryEntity.isEmpty()) {
return; // 防止空集合
}
// 合计值
BigDecimal publicArea = BigDecimal.ZERO;
BigDecimal publicAndInside = BigDecimal.ZERO;
BigDecimal watertight = BigDecimal.ZERO;
BigDecimal hardcover = BigDecimal.ZERO;
// 分类处理
for (DynamicObject entry : subEntryEntity) {
String type = entry.getString("qeug_fl");
BigDecimal value = entry.getBigDecimal(ENTRY_VALUE);
if (StringUtils.isNotEmpty(type)) {
switch (type) {
case "公区":
publicArea = publicArea.add(value);
publicAndInside = publicAndInside.add(value);
break;
case "套内":
publicAndInside = publicAndInside.add(value);
hardcover = hardcover.add(value);
break;
case "防水":
watertight = watertight.add(value);
break;
case "非标":
break;
default:
this.getView().showMessage("无效的分类: " + type + ", 请重新选择!");
break;
}
}
}
// 更新控件显示
updateLabel(publicAmountLabel, publicArea);
updateLabel(watertightAmountLabel, watertight);
updateLabel(hardcoverAmountLabel, hardcover);
}
private void updateLabel(Label label, BigDecimal value) {
// 设置值并确保格式化保留两位小数
if (label != null && value != null) {
label.setText(value.setScale(2, RoundingMode.HALF_UP).toString());
}
}
/**
* 更新指标信息
*
* @param collections 面积数据分录数据
* @param productTypeId 产品构成产品类型
* @param pkValue 表单id
*/
private void updateMetricInfo(DynamicObjectCollection collections, Long productTypeId, Object pkValue) {
// 获取地下面积汇总值
BigDecimal groundFloorSummary = collections.stream()
.map(collection -> {
// 获取两个 BigDecimal 值,如果为 null则使用 BigDecimal.ZERO
BigDecimal b1f = collection.getBigDecimal("qeug_b1f") != null ? collection.getBigDecimal("qeug_b1f") : BigDecimal.ZERO;
BigDecimal b2f = collection.getBigDecimal("qeug_b2f") != null ? collection.getBigDecimal("qeug_b2f") : BigDecimal.ZERO;
return b1f.add(b2f); // 返回 b1f 和 b2f 的和
})
.reduce(BigDecimal.ZERO, BigDecimal::add); // 累加所有的和
// 获取地上面积汇总值
BigDecimal allArea = collections.stream()
.map(collection -> {
// 获取 BigDecimal 值,如果为 null则使用 BigDecimal.ZERO
BigDecimal hjs = collection.getBigDecimal("qeug_hjs") != null ? collection.getBigDecimal("qeug_hjs") : BigDecimal.ZERO;
BigDecimal tzz = collection.getBigDecimal("qeug_tzz") != null ? collection.getBigDecimal("qeug_tzz") : BigDecimal.ZERO;
return hjs.add(tzz);
})
.reduce(BigDecimal.ZERO, BigDecimal::add); // 累加所有的面积
//获取防水面积
BigDecimal waterproofArea = collections.stream()
.filter(collection -> "防水".equals(collection.getString("qeug_fl"))) // 排除 "防水" 类型
.map(collection -> {
BigDecimal hjs = collection.getBigDecimal("qeug_hjs");
BigDecimal tzz = collection.getBigDecimal("qeug_tzz");
return hjs.add(tzz);
})
.reduce(BigDecimal.ZERO, BigDecimal::add);
// 获取地上面积 - 地下面积 - 防水面积
BigDecimal groundSummary = allArea.subtract(groundFloorSummary).subtract(waterproofArea);
// 获取精装面积汇总值
BigDecimal hardcoverSummary = collections.stream()
.filter(collection -> "套内".equals(collection.getString("qeug_fl"))) // 筛选 "套内" 类型
.map(collection -> {
// 获取 BigDecimal 值,如果为 null则使用 BigDecimal.ZERO
BigDecimal hjs = collection.getBigDecimal("qeug_hjs") != null ? collection.getBigDecimal("qeug_hjs") : BigDecimal.ZERO;
BigDecimal tzz = collection.getBigDecimal("qeug_tzz") != null ? collection.getBigDecimal("qeug_tzz") : BigDecimal.ZERO;
return hjs.add(tzz);
})
.reduce(BigDecimal.ZERO, BigDecimal::add); // 累加所有的 "套内" 面积
QFilter qFilter = new QFilter("mainprojectid", QCP.equals, pkValue);
DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle("repmd_index_products", qFilter.toArray());
if (null != dynamicObject) {
DynamicObjectCollection buildingEntry = dynamicObject.getDynamicObjectCollection("buildingindexentry");
if (buildingEntry != null && buildingEntry.size() != 0) {
for (DynamicObject entry : buildingEntry) {
Long typeId = entry.getLong("buildentry_producttype.id");
if (typeId.compareTo(productTypeId) == 0) {
entry.set("buildentry_allbuildarea", groundSummary.add(groundFloorSummary));
entry.set("buildentry_onbuildarea", groundSummary);
entry.set("buildentry_downbuildarea", groundFloorSummary);
entry.set("buildentry_finedecortarea", hardcoverSummary);
SaveServiceHelper.update(dynamicObject);
break;
}
}
}
}
}
/**
* 产品构成分录赋值
*
* @param productEntry 产品构成分录
* @param collections 面积数据分录
* @param id 产品构成分录id
*/
private void setProductEntryValue(DynamicObjectCollection productEntry, DynamicObjectCollection collections, Long id) {
//公区面积汇总
BigDecimal publicArea = collections.stream()
.filter(collection -> "公区".equals(collection.getString("qeug_fl"))) // 排除 "防水" 类型
.map(collection -> {
BigDecimal hjs = collection.getBigDecimal("qeug_hjs");
BigDecimal tzz = collection.getBigDecimal("qeug_tzz");
return hjs.add(tzz);
})
.reduce(BigDecimal.ZERO, BigDecimal::add);
//套内面积汇总
BigDecimal hardcoverArea = collections.stream()
.filter(collection -> "套内".equals(collection.getString("qeug_fl"))) // 排除 "防水" 类型
.map(collection -> {
BigDecimal hjs = collection.getBigDecimal("qeug_hjs");
BigDecimal tzz = collection.getBigDecimal("qeug_tzz");
return hjs.add(tzz);
})
.reduce(BigDecimal.ZERO, BigDecimal::add);
//防水面积汇总
BigDecimal waterproofArea = collections.stream()
.filter(collection -> "防水".equals(collection.getString("qeug_fl"))) // 排除 "防水" 类型
.map(collection -> {
BigDecimal hjs = collection.getBigDecimal("qeug_hjs");
BigDecimal tzz = collection.getBigDecimal("qeug_tzz");
return hjs.add(tzz);
})
.reduce(BigDecimal.ZERO, BigDecimal::add);
for (int i = 0; i < productEntry.size(); i++) {
DynamicObject dynamicObject = productEntry.get(i);
Long id1 = dynamicObject.getLong("id");
if (id1.compareTo(id) == 0) {
dynamicObject.set("productentry_buildingarea", publicArea.add(hardcoverArea));
dynamicObject.set("qeug_waterproofarea",waterproofArea);
this.getView().updateView("productentry_buildingarea",i);
this.getView().updateView("qeug_waterproofarea",i);
break;
}
}
// 更新控件显示
updateLabel(publicAmountLabel, publicArea);
updateLabel(watertightAmountLabel, waterproofArea);
updateLabel(hardcoverAmountLabel, hardcoverArea);
}
}