本段文本提出了一种在生产订单系统中记录并生成下级订单编号的解决方案,以及实现这一功能的具体步骤和代码实现。简述如下: 在成品订单上记录生成下级订单的次数,并生成时通过添加前缀“_”和生成次数来命名下级订单编号。具体步骤包括增加生产订单分录字段、开发插件继承并重写操作前和操作后事务的方法来实现编号的生成和次数更新。最终确保了下级订单编号的唯一性和顺序性,防止编号跳号问题。
1、解决方案:
在成品订单上记录生成下级订单的次数,生成下级订单时,引用成品订单编号+“_”+ (记录的生成次数+1),下级订单生成成功后,更新成品订单上的生成次数+1。例如成品订单为MO2019.05.17000320,如果生成下级新订单的次数为3,则成品订单上记录的生成次数为3,再次生成任意一个下级订单时,订单编号则是:MO2019.05.17000320_4,成品订单上的生成次数更新为4。
2、具体步骤:
2.1、在生产订单的分录上增加字段:生成下级订单次数
2.2、在生产订单的保存操作上增加插件
2.3、保存插件具体二开实现:
(1)二开插件继承AbstractMfgOperationPlugIn
(2)重写BeforeExecuteOperationTransaction:根据源单类型为“PRD_MO”,确定生成的是下级订单,根据源单分录内码获取成品订单的生成下级订单次数,成功拼接出下级订单的单据编号,并且记录源单分录内码和新的生成下级订单次数
(3)重写AfterExecuteOperationTransaction:更新成品订单的生成下级订单的次数
(4)组件引用:
备注:
如果需要更新编码的流水号,则在BeginOperationTransaction ,不会产生跳号;
如果不需要更新单据编码的流水号,则在BeforeExecuteOperationTransaction,会出现跳号;
2.4、具体代码可见(供参考):
using System.Text;
using System.Threading.Tasks;
using Kingdee.K3.Core.MFG.EntityHelper;
using Kingdee.BOS;
using Kingdee.K3.MFG.App;
using Kingdee.BOS.Util;
using System.Data;
using Kingdee.BOS.App.Data;
namespace Kingdee.K3.MFG.PRD.EK.App.ServicePlugIn
{
[Description("生产订单-保存")]
public class Save : AbstractMfgOperationPlugIn
{
Dictionary<long, int> updateTimeDic = new Dictionary<long, int>();
public override void BeforeExecuteOperationTransaction(BOS.Core.DynamicForm.PlugIn.Args.BeforeExecuteOperationTransaction e)
{
base.BeforeExecuteOperationTransaction(e);
List<long> srcBillEntryIds = new List<long>();
DynamicObject[] dataEntitys = null;
//处理下级生产订单的编号:原生产订单编号 + _ + 生成下级订单次数 + 1
if (!e.SelectedRows.IsEmpty())
{
dataEntitys = e.SelectedRows.Select(s => s.DataEntity).ToArray();
}
if (dataEntitys.IsEmpty()) return;
foreach (var dataEntity in dataEntitys)
{
DynamicObjectCollection entrys = dataEntity.GetDynamicValue<DynamicObjectCollection>("TreeEntity");
string documentStatus = dataEntity.GetDynamicValue<string>("DocumentStatus");
if (documentStatus.Equals("Z"))
{
foreach (var entry in entrys)
{
long srcBillEntryId = entry.GetDynamicValue<long>("SrcBillEntryId");
string srcBillType = entry.GetDynamicValue<string>("SrcBillType");
if (srcBillType.Equals("PRD_MO"))
{
srcBillEntryIds.Add(srcBillEntryId);
}
}
}
}
if (srcBillEntryIds.IsEmpty()) return;
//根据源单分录Id,从数据库获取源单分录上生成下级订单的次数(认为生成下级订单的分录,都是来源于同一个生产订单)
var times = this.GetNextMoTimeByEntryIds(this.Context, srcBillEntryIds);
foreach (var dataEntity in dataEntitys)
{
DynamicObjectCollection entrys = dataEntity.GetDynamicValue<DynamicObjectCollection>("TreeEntity");
long srcBillEntryId = entrys[0].GetDynamicValue<long>("SrcBillEntryId");
int nextMoTime = times.Where(f => f.GetDynamicValue<long>("FENTRYID") == srcBillEntryId).FirstOrDefault().GetDynamicValue<int>("FNEXTMOTIME");
string srcBillNo = entrys[0].GetDynamicValue<string>("SrcBillNo");
string billNo = string.Format("{0}{1}{2}", srcBillNo, '_', nextMoTime + 1);
int tmp = 0;
if (updateTimeDic.TryGetValue(srcBillEntryId, out tmp))
{
if (tmp >= nextMoTime + 1) continue;
updateTimeDic.Remove(srcBillEntryId);
updateTimeDic.Add(srcBillEntryId, nextMoTime + 1);
}
else
{
updateTimeDic.Add(srcBillEntryId, nextMoTime + 1);
}
dataEntity.SetDynamicObjectItemValue("BillNo", billNo);
}
}
public override void AfterExecuteOperationTransaction(BOS.Core.DynamicForm.PlugIn.Args.AfterExecuteOperationTransaction e)
{
base.AfterExecuteOperationTransaction(e);
//更新生产订单生成下级订单的次数,记录在生产订单分录上
if (updateTimeDic.IsEmpty()) return;
this.UpdateNextMoTimeByEntryIds(this.Context, updateTimeDic);
}
/// <summary>
/// 根据成品订单分录ID获取对应的下级订单生成次数
/// </summary>
public DynamicObjectCollection GetNextMoTimeByEntryIds(Context ctx, List<long> entryIds)
{
StringBuilder sbSql = new StringBuilder();
sbSql.AppendLine(" SELECT T1.FNEXTMOTIME, T1.FENTRYID ");
sbSql.AppendLine(" FROM T_PRD_MOENTRY T1 ");
sbSql.AppendLine(" INNER JOIN table(fn_StrSplit(@FID,',',1)) TMP ON T1.FENTRYID=TMP.FID");
DynamicObjectCollection dynamicObjes = AppServiceContext.DBService.ExecuteDynamicObject(ctx, sbSql.ToString(),
paramList: new SqlParam[] { new SqlParam("@FID", KDDbType.udt_inttable, entryIds.Distinct().ToArray()) });
return dynamicObjes;
}
/// <summary>
/// 根据成品订单分录ID,更新下级订单生成次数
/// </summary>
public void UpdateNextMoTimeByEntryIds(Context ctx, Dictionary<long, int> result)
{
if (result.IsEmpty()) return;
DataTable dt = new DataTable();
dt.Columns.Add("FENTRYID", typeof(Int64));
dt.Columns.Add("FNEXTMOTIME", typeof(int));
DataRow dr = null;
foreach (KeyValuePair<long, int> pair in result)
{
dr = dt.NewRow();
dr["FENTRYID"] = pair.Key;
dr["FNEXTMOTIME"] = pair.Value;
dt.Rows.Add(dr);
}
if (dt.Rows.Count <= 0) return;
string updateTableName = "T_PRD_MOENTRY";
BatchSqlParam batchParam = new BatchSqlParam(updateTableName, dt);
batchParam.AddSetExpression("FNEXTMOTIME", KDDbType.Int32, "FNEXTMOTIME");
batchParam.AddWhereExpression("FENTRYID", KDDbType.Int64, "FENTRYID");
DBUtils.BatchUpdate(ctx, batchParam);
}
}
}
2.5、执行结果
推荐阅读