use of com.rebuild.core.metadata.easymeta.EasyField in project rebuild by getrebuild.
the class GroupAggregationController method getTargetFields.
@RequestMapping("group-aggregation-fields")
public JSON getTargetFields(@EntityParam(name = "target") Entity targetEntity) {
// 目标-分组字段
List<String[]> targetGroupFields = new ArrayList<>();
// 目标字段
List<String[]> targetFields = new ArrayList<>();
for (Field field : MetadataSorter.sortFields(targetEntity)) {
EasyField easyField = EasyMetaFactory.valueOf(field);
String[] build = buildIfGroupField(easyField);
if (build != null)
targetGroupFields.add(build);
DisplayType dt = easyField.getDisplayType();
if (dt == DisplayType.NUMBER || dt == DisplayType.DECIMAL) {
targetFields.add(buildField(field));
}
}
return JSONUtils.toJSONObject(new String[] { "targetGroupFields", "targetFields" }, new Object[] { targetGroupFields, targetFields });
}
use of com.rebuild.core.metadata.easymeta.EasyField in project rebuild by getrebuild.
the class FieldWriteback method buildTargetRecordData.
private Record buildTargetRecordData() {
final Record targetRecord = EntityHelper.forNew(targetEntity.getEntityCode(), UserService.SYSTEM_USER, false);
final JSONArray items = ((JSONObject) actionContext.getActionContent()).getJSONArray("items");
final Set<String> fieldVars = new HashSet<>();
for (Object o : items) {
JSONObject item = (JSONObject) o;
String sourceField = item.getString("sourceField");
String updateMode = item.getString("updateMode");
// fix: v2.2
if (updateMode == null) {
updateMode = sourceField.contains(DATE_EXPR) ? "FORMULA" : "FIELD";
}
if ("FIELD".equalsIgnoreCase(updateMode)) {
fieldVars.add(sourceField);
} else if ("FORMULA".equalsIgnoreCase(updateMode)) {
if (sourceField.contains(DATE_EXPR) && !sourceField.startsWith(CODE_PREFIX)) {
fieldVars.add(sourceField.split(DATE_EXPR)[0]);
} else {
Set<String> matchsVars = ContentWithFieldVars.matchsVars(sourceField);
for (String field : matchsVars) {
if (MetadataHelper.getLastJoinField(sourceEntity, field) == null) {
throw new MissingMetaExcetion(field, sourceEntity.getName());
}
fieldVars.add(field);
}
}
}
}
// 变量值
Record useSourceData = null;
if (!fieldVars.isEmpty()) {
String sql = String.format("select %s from %s where %s = '%s'", StringUtils.join(fieldVars, ","), sourceEntity.getName(), sourceEntity.getPrimaryField().getName(), actionContext.getSourceRecord());
useSourceData = Application.createQueryNoFilter(sql).record();
}
for (Object o : items) {
JSONObject item = (JSONObject) o;
String targetField = item.getString("targetField");
if (!MetadataHelper.checkAndWarnField(targetEntity, targetField)) {
continue;
}
EasyField targetFieldEasy = EasyMetaFactory.valueOf(targetEntity.getField(targetField));
String updateMode = item.getString("updateMode");
String sourceAny = item.getString("sourceField");
// 置空
if ("VNULL".equalsIgnoreCase(updateMode)) {
targetRecord.setNull(targetField);
} else // 固定值
if ("VFIXED".equalsIgnoreCase(updateMode)) {
RecordVisitor.setValueByLiteral(targetField, sourceAny, targetRecord);
} else // 字段
if ("FIELD".equalsIgnoreCase(updateMode)) {
Field sourceFieldMeta = MetadataHelper.getLastJoinField(sourceEntity, sourceAny);
if (sourceFieldMeta == null)
continue;
Object value = Objects.requireNonNull(useSourceData).getObjectValue(sourceAny);
if (value != null) {
if (targetFieldEasy.getDisplayType() == DisplayType.N2NREFERENCE) {
value = N2NReferenceSupport.items(sourceFieldMeta, actionContext.getSourceRecord());
}
Object newValue = EasyMetaFactory.valueOf(sourceFieldMeta).convertCompatibleValue(value, targetFieldEasy);
targetRecord.setObjectValue(targetField, newValue);
}
} else // 公式
if ("FORMULA".equalsIgnoreCase(updateMode)) {
if (useSourceData == null) {
log.warn("[useSourceData] is null, Set to empty");
useSourceData = new StandardRecord(sourceEntity, null);
}
// 高级公式代码
final boolean useCode = sourceAny.startsWith(CODE_PREFIX);
// 日期兼容 fix: v2.2
if (sourceAny.contains(DATE_EXPR) && !useCode) {
String fieldName = sourceAny.split(DATE_EXPR)[0];
Field sourceField2 = MetadataHelper.getLastJoinField(sourceEntity, fieldName);
if (sourceField2 == null)
continue;
Object value = useSourceData.getObjectValue(fieldName);
Object newValue = value == null ? null : ((EasyDateTime) EasyMetaFactory.valueOf(sourceField2)).convertCompatibleValue(value, targetFieldEasy, sourceAny);
if (newValue != null) {
targetRecord.setObjectValue(targetField, newValue);
}
} else // 高级公式(会涉及各种类型的运算)
// @see AggregationEvaluator#evalFormula
{
String clearFormual = useCode ? sourceAny.substring(4, sourceAny.length() - 4) : sourceAny.replace("×", "*").replace("÷", "/").replace("`", // compatible: v2.4
"\"");
Map<String, Object> envMap = new HashMap<>();
for (String fieldName : fieldVars) {
String replace = "{" + fieldName + "}";
String replaceWhitQuote = "\"" + replace + "\"";
String replaceWhitQuoteSingle = "'" + replace + "'";
boolean forceUseQuote = false;
if (clearFormual.contains(replaceWhitQuote)) {
clearFormual = clearFormual.replace(replaceWhitQuote, fieldName);
forceUseQuote = true;
} else if (clearFormual.contains(replaceWhitQuoteSingle)) {
clearFormual = clearFormual.replace(replaceWhitQuoteSingle, fieldName);
forceUseQuote = true;
} else if (clearFormual.contains(replace)) {
clearFormual = clearFormual.replace(replace, fieldName);
} else {
continue;
}
Object value = useSourceData.getObjectValue(fieldName);
if (value instanceof Date) {
value = CalendarUtils.getUTCDateTimeFormat().format(value);
} else if (value == null) {
// 数字字段置 `0`
Field isNumberField = MetadataHelper.getLastJoinField(sourceEntity, fieldName);
if (isNumberField != null && (isNumberField.getType() == FieldType.LONG || isNumberField.getType() == FieldType.DECIMAL)) {
value = 0;
} else {
value = StringUtils.EMPTY;
}
} else if (forceUseQuote) {
value = value.toString();
}
envMap.put(fieldName, value);
}
Object newValue = AviatorUtils.eval(clearFormual, envMap, false);
if (newValue != null) {
DisplayType dt = targetFieldEasy.getDisplayType();
if (dt == DisplayType.NUMBER) {
targetRecord.setLong(targetField, CommonsUtils.toLongHalfUp(newValue));
} else if (dt == DisplayType.DECIMAL) {
targetRecord.setDouble(targetField, ObjectUtils.toDouble(newValue));
} else if (dt == DisplayType.DATE || dt == DisplayType.DATETIME) {
targetRecord.setDate(targetField, (Date) newValue);
} else {
newValue = checkoutFieldValue(newValue, targetFieldEasy);
if (newValue != null) {
targetRecord.setObjectValue(targetField, newValue);
}
}
}
}
}
}
return targetRecord;
}
use of com.rebuild.core.metadata.easymeta.EasyField in project rebuild by getrebuild.
the class GroupAggregation method prepare.
@Override
public void prepare(OperatingContext operatingContext) throws TriggerException {
// 已经初始化
if (sourceEntity != null)
return;
final JSONObject actionContent = (JSONObject) actionContext.getActionContent();
sourceEntity = actionContext.getSourceEntity();
targetEntity = MetadataHelper.getEntity(actionContent.getString("targetEntity"));
// 0.分组字段关联 <Source, Target>
Map<String, String> groupFieldsMapping = new HashMap<>();
for (Object o : actionContent.getJSONArray("groupFields")) {
JSONObject item = (JSONObject) o;
String sourceField = item.getString("sourceField");
String targetField = item.getString("targetField");
if (MetadataHelper.getLastJoinField(sourceEntity, sourceField) == null) {
throw new MissingMetaExcetion(sourceField, sourceEntity.getName());
}
if (!targetEntity.containsField(targetField)) {
throw new MissingMetaExcetion(targetField, targetEntity.getName());
}
groupFieldsMapping.put(sourceField, targetField);
}
// 1.源记录数据
String ql = String.format("select %s from %s where %s = ?", StringUtils.join(groupFieldsMapping.keySet().iterator(), ","), sourceEntity.getName(), sourceEntity.getPrimaryField().getName());
Record sourceRecord = Application.getQueryFactory().createQueryNoFilter(ql).setParameter(1, actionContext.getSourceRecord()).record();
// 2.找到目标记录
List<String> qFields = new ArrayList<>();
List<String> qFieldsFollow = new ArrayList<>();
for (Map.Entry<String, String> e : groupFieldsMapping.entrySet()) {
String sourceField = e.getKey();
String targetField = e.getValue();
Object val = sourceRecord.getObjectValue(sourceField);
if (val != null) {
EasyField sourceFieldEasy = EasyMetaFactory.valueOf(Objects.requireNonNull(MetadataHelper.getLastJoinField(sourceEntity, sourceField)));
EasyField targetFieldEasy = EasyMetaFactory.valueOf(Objects.requireNonNull(MetadataHelper.getLastJoinField(targetEntity, targetField)));
// 日期分组
if (sourceFieldEasy.getDisplayType() == DisplayType.DATE || sourceFieldEasy.getDisplayType() == DisplayType.DATETIME) {
String formatKey = sourceFieldEasy.getDisplayType() == DisplayType.DATE ? EasyFieldConfigProps.DATE_FORMAT : EasyFieldConfigProps.DATETIME_FORMAT;
int sourceFieldLength = StringUtils.defaultIfBlank(sourceFieldEasy.getExtraAttr(formatKey), sourceFieldEasy.getDisplayType().getDefaultFormat()).length();
// 目标字段仅日期
int targetFieldLength = StringUtils.defaultIfBlank(targetFieldEasy.getExtraAttr(EasyFieldConfigProps.DATE_FORMAT), targetFieldEasy.getDisplayType().getDefaultFormat()).length();
// 目标格式(长度)必须小于等于源格式
Assert.isTrue(targetFieldLength <= sourceFieldLength, Language.L("日期字段格式不兼容") + String.format(" (%d,%d)", targetFieldLength, sourceFieldLength));
if (targetFieldLength == 4) {
// 'Y'
sourceField = String.format("DATE_FORMAT(%s,'%s')", sourceField, "%Y");
targetField = String.format("DATE_FORMAT(%s,'%s')", targetField, "%Y");
val = CalendarUtils.format("yyyy", (Date) val);
} else if (targetFieldLength == 7) {
// 'M'
sourceField = String.format("DATE_FORMAT(%s,'%s')", sourceField, "%Y-%m");
targetField = String.format("DATE_FORMAT(%s,'%s')", targetField, "%Y-%m");
val = CalendarUtils.format("yyyy-MM", (Date) val);
} else {
// 'D' is default
sourceField = String.format("DATE_FORMAT(%s,'%s')", sourceField, "%Y-%m-%d");
targetField = String.format("DATE_FORMAT(%s,'%s')", targetField, "%Y-%m-%d");
val = CalendarUtils.format("yyyy-MM-dd", (Date) val);
}
} else // 分类分组
if (sourceFieldEasy.getDisplayType() == DisplayType.CLASSIFICATION) {
int sourceFieldLevel = ClassificationManager.instance.getOpenLevel(MetadataHelper.getLastJoinField(sourceEntity, sourceField));
int targetFieldLevel = ClassificationManager.instance.getOpenLevel(MetadataHelper.getLastJoinField(targetEntity, targetField));
// 目标等级必须小于等于源等级
Assert.isTrue(targetFieldLevel <= sourceFieldLevel, Language.L("分类字段等级不兼容") + String.format(" (%d,%d)", targetFieldLevel, sourceFieldLevel));
// 需要匹配等级的值
if (sourceFieldLevel != targetFieldLevel) {
ID parent = getItemWithLevel((ID) val, targetFieldLevel);
if (parent == null) {
log.error("Bad source value of classification (Maybe levels?) : {}", val);
return;
}
val = parent;
sourceRecord.setID(sourceField, (ID) val);
for (int i = 0; i < sourceFieldLevel - targetFieldLevel; i++) {
// noinspection StringConcatenationInLoop
sourceField += ".parent";
}
}
}
qFields.add(String.format("%s = '%s'", targetField, val));
qFieldsFollow.add(String.format("%s = '%s'", sourceField, val));
}
}
if (qFields.isEmpty()) {
log.warn("Value(s) of group-field not specified");
return;
}
this.followSourceWhere = StringUtils.join(qFieldsFollow.iterator(), " and ");
ql = String.format("select %s from %s where ( %s )", targetEntity.getPrimaryField().getName(), targetEntity.getName(), StringUtils.join(qFields.iterator(), " and "));
Object[] targetRecord = Application.getQueryFactory().createQueryNoFilter(ql).unique();
if (targetRecord != null) {
targetRecordId = (ID) targetRecord[0];
return;
}
// 是否自动创建记录
if (!actionContent.getBoolean("autoCreate"))
return;
// 不必担心必填字段,必填只是前端约束
// 还可以通过设置字段默认值来完成必填字段的自动填写
// 0425 需要业务规则,譬如自动编号、默认值等
Record newTargetRecord = EntityHelper.forNew(targetEntity.getEntityCode(), UserService.SYSTEM_USER);
for (Map.Entry<String, String> e : groupFieldsMapping.entrySet()) {
String sourceField = e.getKey();
String targetField = e.getValue();
Object val = sourceRecord.getObjectValue(sourceField);
if (val != null) {
newTargetRecord.setObjectValue(targetField, val);
}
}
PrivilegesGuardContextHolder.setSkipGuard(EntityHelper.UNSAVED_ID);
try {
Application.getEntityService(targetEntity.getEntityCode()).create(newTargetRecord);
} finally {
PrivilegesGuardContextHolder.getSkipGuardOnce();
}
RobotTriggerObserver.forceTriggerSelf();
targetRecordId = newTargetRecord.getPrimary();
}
use of com.rebuild.core.metadata.easymeta.EasyField in project rebuild by getrebuild.
the class RecordTransfomer method transformRecord.
private ID transformRecord(Entity sourceEntity, Entity targetEntity, JSONObject fieldsMapping, ID sourceRecordId, Map<String, Object> defaultValue) {
Record target = EntityHelper.forNew(targetEntity.getEntityCode(), getUser());
if (defaultValue != null) {
for (Map.Entry<String, Object> e : defaultValue.entrySet()) {
target.setObjectValue(e.getKey(), e.getValue());
}
}
List<String> validFields = checkAndWarnFields(sourceEntity, fieldsMapping.values());
if (validFields.isEmpty()) {
log.warn("No fields for transform");
return null;
}
String querySource = String.format("select %s from %s where %s = '%s'", StringUtils.join(validFields, ","), sourceEntity.getName(), sourceEntity.getPrimaryField().getName(), sourceRecordId);
Record source = Application.createQueryNoFilter(querySource).record();
for (Map.Entry<String, Object> e : fieldsMapping.entrySet()) {
if (e.getValue() == null)
continue;
String targetField = e.getKey();
String sourceField = (String) e.getValue();
Object sourceValue = source.getObjectValue(sourceField);
if (sourceValue != null) {
EasyField targetFieldEasy = EasyMetaFactory.valueOf(targetEntity.getField(targetField));
EasyField sourceFieldEasy = EasyMetaFactory.valueOf(Objects.requireNonNull(MetadataHelper.getLastJoinField(sourceEntity, sourceField)));
if (targetFieldEasy.getDisplayType() == DisplayType.N2NREFERENCE) {
sourceValue = N2NReferenceSupport.items(sourceFieldEasy.getRawMeta(), sourceRecordId);
}
Object targetValue = sourceFieldEasy.convertCompatibleValue(sourceValue, targetFieldEasy);
target.setObjectValue(targetField, targetValue);
}
}
GeneralEntityServiceContextHolder.setRepeatedCheckMode(GeneralEntityServiceContextHolder.RCM_CHECK_MAIN);
try {
target = Application.getEntityService(targetEntity.getEntityCode()).createOrUpdate(target);
return target.getPrimary();
} finally {
GeneralEntityServiceContextHolder.getRepeatedCheckModeOnce();
}
}
use of com.rebuild.core.metadata.easymeta.EasyField in project rebuild by getrebuild.
the class FormsBuilder method wrapFieldValue.
/**
* 封装表单/布局所用的字段值
*
* @param data
* @param field
* @param user4Desensitized 不传则不脱敏
* @return
* @see FieldValueHelper#wrapFieldValue(Object, EasyField)
* @see com.rebuild.core.support.general.DataListWrapper#wrapFieldValue(Object, Field)
*/
public Object wrapFieldValue(Record data, EasyField field, ID user4Desensitized) {
Object value = data.getObjectValue(field.getName());
// 特殊字段
if (field.getDisplayType() == DisplayType.BARCODE || (field.getDisplayType() == DisplayType.N2NREFERENCE && FieldValueHelper.hasLength(value))) {
value = data.getPrimary();
}
// 处理日期格式
if (field.getDisplayType() == DisplayType.REFERENCE && value instanceof ID && ((ID) value).getLabelRaw() != null) {
Field nameField = field.getRawMeta().getReferenceEntity().getNameField();
if (nameField.getType() == FieldType.DATE || nameField.getType() == FieldType.TIMESTAMP) {
Object newLabel = EasyMetaFactory.valueOf(nameField).wrapValue(((ID) value).getLabelRaw());
((ID) value).setLabel(newLabel);
}
}
value = FieldValueHelper.wrapFieldValue(value, field);
if (value != null && FieldValueHelper.isUseDesensitized(field, user4Desensitized)) {
value = FieldValueHelper.desensitized(field, value);
}
return value;
}
Aggregations