单据转换.变通方案.通过日期单位计算日期服务不会校验前提条件(增加新的表单服务)
【场景】单据转换,表单服务策略,通过日期单位计算日期服务,不会执行前提条件校验
历史设计这个服务就是不走的,目前不能随意增加校验,导致影响历史转换规则
【方案】通过实现一个新的支持校验的服务实现
参考:[二开案例.表单服务.服务端表单服务](https://wenku.my7c.com/article/383612987648954624?productLineId=1&isKnowledge=2)
【案例】仅支持私有云增加表单服务,公有云的建议通过计算表达式变通处理
<1>通过sql注册新的表单服务
```sql
declare @actId int;
set @actId = 1000099;
IF NOT EXISTS(SELECT 1 FROM T_MDL_FORMBUSINESS WHERE FACTIONID = @actId)
BEGIN
--<0>表单服务
INSERT INTO T_MDL_FORMBUSINESS(FACTIONID,FNAME,FTYPE,FSETCOMPONENT,FRUNCOMPONENT,FDESIGNERVISIBLE,FREVERSEACTIONCLASS,FPUSHCOMPONENT,FDEFAULTRAISETYPE,FAPPSCENARIOTYPE)
VALUES (@actId,'CalcDateTimeValidate',23,'Kingdee.BOS.DomainModelDesigner.ServiceDesigner.BusinessServiceCalDateTime','Kingdee.BOS.Business.DynamicForm.BusinessService.CalDateTime, Kingdee.BOS.Business.DynamicForm',1, 'Kingdee.BOS.Business.DynamicForm.BusinessService.CalDateTime, Kingdee.BOS.Business.DynamicForm','Tmp.BusinessFlow.Tool.PushBusinessService.CalcDateTimeValidate, Tmp.BusinessFlow.Tool',41,1) ;
--<1>多语言描述
DELETE FROM T_MDL_FORMBUSINESS_L WHERE FACTIONID = @actId AND FLOCALEID = 2052;
INSERT INTO T_MDL_FORMBUSINESS_L(FPKID,FACTIONID,FLOCALEID,FDESC,FSYNTAX,FPARAMETER)
VALUES ((select isnull(max(fpkid), 0) + 1 from T_MDL_FORMBUSINESS_l where fpkid < 10000),@actId,2052,N'通过日期单位计算日期(下推校验)',N'CalDateTime()',N'请指定输入参数字段和输出字段') ;
END;
```
<2>将组件放到WebSite\Bin目录下,或者自行根据此案例调整先关代码
(代码仅供参考,不确定是否完全覆盖)
```chsarp
using Kingdee.BOS.App.Core.Convertible.BusinessService;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.Bill;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.EntityElement;
using Kingdee.BOS.Core.Metadata.FieldElement;
using Kingdee.BOS.Core.Metadata.FormElement;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Util;
using System;
using System.Collections.Generic;
namespace Tmp.BusinessFlow.Tool.PushBusinessService
{
/// <summary>
/// 根据日期计算日期 仅支持原日期、计算单位、计算值和目标日期在同一实体的场景
/// </summary>
[System.ComponentModel.Description("根据日期计算日期 (逐行校验)")]
public class CalcDateTimeValidate : PushFormBusinessService
{
/*
* 计算日期逻辑,支持按照逐行验证
*/
public override bool RequestBatchProcess
{
//不支持1
get { return false; }
}
public override Entity GetLoopEntity(BusinessInfo info, FormBusinessService serviceElement)
{
string[] paramenters = serviceElement.GetParameters();
if (paramenters.Length <= 0)
{
return info.Entrys[0];
}
string strExpression = paramenters[0]; //参数应只有1个
if (string.IsNullOrWhiteSpace(strExpression))
{
return info.Entrys[0];
}
Dictionary<string, string> dictField = GetFieldDict(strExpression);
//目标日期字段
var tfield = info.GetField(dictField["FTargetDate"]);
if (tfield == null)
{
return info.Entrys[0];
}
return tfield.Entity;
}
public override void DoAction(PushBusinessServiceArgs e)
{
#region 验证传入参数逻辑
string[] paramenters = e.FormBusinessService.GetParameters();
if (paramenters.Length <= 0)
{
return;
}
string strExpression = paramenters[0]; //参数应只有1个
if (string.IsNullOrWhiteSpace(strExpression))
{
return;
}
Dictionary<string, string> dictField = GetFieldDict(strExpression);
//源日期字段
var tupleSkeyField = this.GetField(e.BusinessInfo, dictField["FSourceDate"]);
if (tupleSkeyField.Item2 == null)
{
return;
}
//日期单位字段
var tupleUnitkeyField = this.GetField(e.BusinessInfo, dictField["FDateUnitId"]);
if (tupleUnitkeyField.Item2 == null)
{
return;
}
//日期增量字段
var tupleDatekeyField = this.GetField(e.BusinessInfo, dictField["FDateValue"]);
if (tupleDatekeyField.Item2 == null)
{
return;
}
//目标日期字段
var tfield = e.BusinessInfo.GetField(dictField["FTargetDate"]);
if (tfield == null)
{
return;
}
#endregion
var targetdatePty = tfield.DynamicProperty;
string tEntityKey = tfield.Entity.Key;
var row = e.DataEntity;
ExtendedDataEntity[] rows = new ExtendedDataEntity[] { row };
#region 实现逻辑
//循环实体计算目标日期
foreach (ExtendedDataEntity entity in rows)
{
bool isSameEntity = tupleSkeyField.Item2.Entity.Key.EqualsIgnoreCase(tEntityKey);
object objValue = this.GetValue(tupleSkeyField, e.DataEntitySet, entity.DataEntity, isSameEntity);
if (objValue.IsNullOrEmptyOrWhiteSpace())
{
continue;
}
DateTime sourceDateTime = Convert.ToDateTime(objValue);
isSameEntity = tupleUnitkeyField.Item2.Entity.Key.EqualsIgnoreCase(tEntityKey);
objValue = this.GetValue(tupleUnitkeyField, e.DataEntitySet, entity.DataEntity, isSameEntity);
if (objValue.IsNullOrEmptyOrWhiteSpace())
{
continue;
}
string dateUnit = objValue.ToString();
isSameEntity = tupleDatekeyField.Item2.Entity.Key.EqualsIgnoreCase(tEntityKey);
objValue = this.GetValue(tupleDatekeyField, e.DataEntitySet, entity.DataEntity, isSameEntity);
if (objValue.IsNullOrEmptyOrWhiteSpace())
{
continue;
}
int dateValue = Convert.ToInt32(objValue);
DateTime targetValue = sourceDateTime;
string CustomerValue = dictField["FCustomData"];
string[] strCustomItem = CustomerValue.Split('|');
foreach (string item in strCustomItem)
{
string[] factor = item.Split(':');
int dir = 1;
if (factor.Length == 5)
{
dir = Convert.ToInt32(factor[4]);
}
if (factor.Length >= 2)
{
if (factor[1] == dateUnit)
{
if (factor[0] == "C")
{
targetValue = GetNewDateByUnit(sourceDateTime, factor[2], dateValue * dir, Convert.ToInt32(factor[3]));
}
else
{
targetValue = GetNewDateByUnit(sourceDateTime, dateUnit, dateValue * dir, 1);
}
}
}
}
targetValue = CalOffsetDate(e.DataEntitySet, e.BusinessInfo, entity.DataEntity, dictField, targetValue, tEntityKey);
targetdatePty.SetValue(entity.DataEntity, targetValue);
}
#endregion
}
#region 辅助实现函数
/// <summary>
/// 得到字段
/// </summary>
/// <param name="busInfo"></param>
/// <param name="fieldKey"></param>
/// <returns></returns>
private Tuple<string, Field> GetField(BusinessInfo bInfo, string fieldKey)
{
var keyItems = fieldKey.Split('.'); //兼容使用基础资料属性情况
var field = bInfo.GetField(keyItems[0]);
return new Tuple<string, Field>(fieldKey, field);
}
/// <summary>
/// 得到字段值
/// </summary>
/// <param name="row"></param>
/// <param name="keyField"></param>
/// <returns></returns>
private object GetValue(Tuple<string, Field> keyField, ExtendedDataEntitySet dataSet, DynamicObject tDynData, bool isSameEntity)
{
//得到顶级字段值
var topDynamicProperty = keyField.Item2.DynamicProperty;
object topFieldValue;
if (isSameEntity)
{
topFieldValue = topDynamicProperty.GetValue(tDynData);
}
else
{
var fieldEntityKey = keyField.Item2.Entity.Key;
ExtendedDataEntity[] entitys = dataSet.FindByEntityKey(fieldEntityKey);
if (entitys == null || entitys.Length == 0)
{
return null;
}
topFieldValue = topDynamicProperty.GetValue(entitys[0].DataEntity);
}
// 得到字段值
string[] keys = keyField.Item1.Split('.');
if (keys.Length == 1)
{
return topFieldValue;
}
//存在组合的情况
var obj = topFieldValue as DynamicObject;
if (obj == null) return null;
if (keys.Length == 2)
{
return obj[keys[1]];
}
else if (keys.Length == 3)
{
DynamicObjectCollection dym = obj[keys[1]] as DynamicObjectCollection;
if (dym != null && dym.Count > 0)
{
return dym[0][keys[2]];
}
}
return null;
}
/// <summary>
/// 构造参数字典
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
private Dictionary<string, string> GetFieldDict(string param)
{
Dictionary<string, string> dictField = new Dictionary<string, string>();
string[] paramItem = param.Split(',');
foreach (string factor in paramItem)
{
string[] paramFactor = factor.Split('=');
if (paramFactor.Length == 2)
{
dictField[paramFactor[0]] = paramFactor[1];
}
}
return dictField;
}
/// <summary>
/// 进行日期计算
/// </summary>
/// <param name="sourceDateTime"></param>
/// <param name="DateUnit"></param>
/// <param name="DateValue"></param>
/// <param name="unitQty"></param>
/// <returns></returns>
private DateTime GetNewDateByUnit(DateTime sourceDateTime, string DateUnit, int DateValue, int unitQty)
{
DateValue = DateValue * unitQty;
DateTime targetValue = sourceDateTime;
switch (DateUnit)
{
case "Y":
targetValue = sourceDateTime.AddYears(DateValue);
break;
case "M":
targetValue = sourceDateTime.AddMonths(DateValue);
break;
case "D":
targetValue = sourceDateTime.AddDays(DateValue);
break;
case "H":
targetValue = sourceDateTime.AddHours(DateValue);
break;
case "N":
targetValue = sourceDateTime.AddMinutes(DateValue);
break;
case "S":
targetValue = sourceDateTime.AddSeconds(DateValue);
break;
default:
targetValue = sourceDateTime.AddDays(DateValue);
break;
}
return targetValue;
}
/// <summary>
/// 计算偏移日期
/// </summary>
/// <param name="dictField"></param>
/// <param name="targetValue"></param>
/// <returns></returns>
private DateTime CalOffsetDate(ExtendedDataEntitySet dataSet, BusinessInfo bInfo, DynamicObject row, Dictionary<string, string> dictField, DateTime targetValue, string tEntityKey)
{
if (!dictField.ContainsKey("FIsUseOffset"))
{
return targetValue;
}
//是否启用偏移
bool isUseOffset = Convert.ToBoolean(dictField["FIsUseOffset"]);
if (isUseOffset)
{
//获取偏移日前单位
string strOffsetDateUnit = null;
//获取偏移值
int strOffsetValue = 0;
//根据偏移类型来获取常量或变量
string strOffsetDateUnitType = dictField.ContainsKey("FOffsetDateUnitType") ? dictField["FOffsetDateUnitType"] : CalDateTimeType.CL;
string strOffsetValueType = dictField.ContainsKey("FOffsetValueType") ? dictField["FOffsetValueType"] : CalDateTimeType.CL;
switch (strOffsetDateUnitType)
{
case CalDateTimeType.CL:
strOffsetDateUnit = dictField.ContainsKey("FOffsetDateUnit") ? dictField["FOffsetDateUnit"] : null;
break;
case CalDateTimeType.BL:
var tupleFiled = GetField(bInfo, dictField["FOffsetDateUnit2"]);
var isSameEntity = tupleFiled.Item2.Entity.Key.EqualsIgnoreCase(tEntityKey);
var fieldValue = GetValue(tupleFiled, dataSet, row, isSameEntity);
strOffsetDateUnit = dictField.ContainsKey("FOffsetDateUnit2") ? ObjectUtils.Object2String(fieldValue) : null;
break;
}
switch (strOffsetValueType)
{
case CalDateTimeType.CL:
strOffsetValue = dictField.ContainsKey("FOffsetValue") ? Convert.ToInt32(dictField["FOffsetValue"]) : 0;
break;
case CalDateTimeType.BL:
var tupleFiled = GetField(bInfo, dictField["FOffsetValue2"]);
var isSameEntity = tupleFiled.Item2.Entity.Key.EqualsIgnoreCase(tEntityKey);
var fieldValue = GetValue(tupleFiled, dataSet, row, isSameEntity);
if (dictField.ContainsKey("FOffsetValue2") && !Int32.TryParse(ObjectUtils.Object2String(fieldValue), out strOffsetValue))
{
strOffsetValue = 0;
}
break;
}
if (!string.IsNullOrWhiteSpace(strOffsetDateUnit) && strOffsetValue != 0)
{
//修改目标值
targetValue = GetNewDateByUnit(targetValue, strOffsetDateUnit, strOffsetValue, 1);
}
}
return targetValue;
}
#endregion
/// <summary>
/// 通过日期计算偏移值类型
/// </summary>
class CalDateTimeType
{
/// <summary>
/// 常量
/// </summary>
public const string CL = "CL";
/// <summary>
/// 变量
/// </summary>
public const string BL = "BL";
}
}
}
```
【效果】
<1>原服务不会走下推校验
![Image_20230117194510.webp](/download/0100ad986e7533d840f9b8a9aba091007ab4.webp)
![Image_20230117194535.webp](/download/0100e5917fbe73c34dffb2a40d20e5eb801c.webp)
<2>新服务会下推校验
![1673958000576.webp](/download/010017d6277f8bbd47c69f95fa80e58bf2a9.webp)
![1673958027862.webp](/download/01007eb74e565c9e430f9aba371ba0596408.webp)
单据转换.变通方案.通过日期单位计算日期服务不会校验前提条件(增加新的表单服务)
【场景】单据转换,表单服务策略,通过日期单位计算日期服务,不会执行前提条件校验历史设计这个服务就是不走的,目前不能随意增加校验,导...
点击下载文档
本文2024-09-16 18:32:53发表“云星空知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-k3cloud-22864.html
您需要登录后才可以发表评论, 登录登录 或者 注册
最新文档
热门文章