如何将损耗纳入用料清单的在制消耗数量原创
6人赞赏了该文章
1818次浏览
编辑于2019年07月02日 16:25:33
1、经常有项目需要将损耗纳入到在制材料的消耗当中,我们不建议业务这样处理,标准产品的在制消耗数量有固定的计算公式
2、这种需求我们建议生产入库单反写消耗数量之后通过更新报废数量和重算在制材料数量来解决该业务场景,下面是二开参考实例:
2.1: 绑定反写插件
2.2:代码开发实例 [Description("生产入库单重算消耗数量之后,计算报废数量")] public class UpdateSrapQty : AbstractMfgBusinessFlowServicePlugIn { /// <summary> /// 待反写生产订单分录内码 /// </summary> private List<long> moEntryIds { get; set; } private bool IsNeedWriteBack = true; /// <summary> /// 获取是否跟新wip和已消耗数参数 /// </summary> /// <param name="e"></param> public override void BeforeTrackBusinessFlow(BeforeTrackBusinessFlowEventArgs e) { base.BeforeTrackBusinessFlow(e); base.GetIsUpdateWipConsume(); //判断库存更新时机 } public override void BeforeCreateArticulationRow(BeforeCreateArticulationRowEventArgs e) { var inStockBill = e.ActiveRow.Parent as DynamicObject; if (inStockBill.GetDynamicObjectItemValue<long>("EntrustInStockId") > 0) { //跨组织入库不处理 IsNeedWriteBack = false; } } /// <summary> /// 重载此事件用于收集MO分录ID /// </summary> /// <param name="e"></param> public override void AfterCommitAmount(AfterCommitAmountEventArgs e) { base.AfterCommitAmount(e); if (!base.IsUpdateWipConsume) return; //判断库存更新时机 if (moEntryIds.IsEmpty()) moEntryIds = new List<long>(); if (string.CompareOrdinal(e.Rule.SourceFormId, MFGFormIdConst.SubSys_PRD.MOBill) == 0) { long moEntryId = e.SourceActiveRow.GetDynamicObjectItemValue<long>("Id"); if (!moEntryIds.Contains(moEntryId)) { moEntryIds.Add(moEntryId); } } } public override void FinishWriteBack(FinishWriteBackEventArgs e) { if (!IsNeedWriteBack) return; base.FinishWriteBack(e); if (moEntryIds.IsEmpty()) return; //通过生产订单找到生产用料清单的消耗数量*变动损耗(如需考虑固定损耗,请自行修改数据),写入报废数量 //(不适用于手工做补料的情况,手工做补料,要先获取补料单的报废数量,在判断是加上消耗数量*变动损耗(审核),还是减去消耗数量*变动损耗(反审核)) string mergeSql = string.Format(@"MERGE INTO T_PRD_PPBOMENTRY_Q U1 USING (SELECT T1.FENTRYID,T1.FCONSUMEQTY,T1.FBASECONSUMEQTY,T2.FSCRAPRATE FROM T_PRD_PPBOMENTRY_Q T1 INNER JOIN T_PRD_PPBOMENTRY T2 ON T1.FENTRYID=T2.FENTRYIDINNER JOIN {0} TT ON T2.FMOENTRYID=TT.FID)U2 ON (U1.FENTRYID=U2.FENTRYID) WHEN MATCHED THENUPDATE SET U1.FSCRAPQTY=U2.FCONSUMEQTY*U2.FSCRAPRATE/100,U1.FBASESCRAPQTY=U2.FBASECONSUMEQTY*U2.FSCRAPRATE/100{1}", StringUtils.GetSqlWithCardinality(moEntryIds.Distinct().Count(), "@MOENTRYID", 1), this.Context.DatabaseType == DatabaseType.MS_SQL_Server ? ";" : ""); List<SqlParam> sqlParams = new List<SqlParam>(); sqlParams.Add(new SqlParam("@MOENTRYID", KDDbType.udt_inttable, moEntryIds.Distinct().ToArray())); AppServiceContext.DbUtils.Execute(this.Context, mergeSql, sqlParams); //重新计算在制材料数量 string sql = string.Format("SELECT T.FENTRYID FROM T_PRD_PPBOMENTRY T INNER JOIN {0} TT ON T.FMOENTRYID=TT.FID", StringUtils.GetSqlWithCardinality(moEntryIds.Distinct().Count(), "@MOENTRYID", 1)); DynamicObjectCollection dyObjs = AppServiceContext.DbUtils.ExecuteDynamicObject(this.Context, sql, sqlParams.ToArray()); List<long> UpdatePpbomEntryIds = dyObjs.Select(s => s.GetDynamicValue<long>("FENTRYID")).ToList(); AppServiceContext.PRDService.PRDWipService.UpdateWipMem(this.Context, UpdatePpbomEntryIds); } } }
推荐阅读