采购订单下推采购入库二次开发问题
金蝶云社区-云社区用户l6231922
云社区用户l6231922
1人赞赏了该文章 4,251次浏览 未经作者许可,禁止转载编辑于2016年09月26日 00:11:21

今天做了一个采购订单下推采购入库的二次开发。
基本思路是建立空操作,空操作引用服务器插件。
客户端通过webapi调用空操作
result = client.Execute("Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExcuteOperation", new object[] { "PUR_PurchaseOrder", "空操作id", t2 });//t2是我要传到服务器的数据,包含了采购订单的单号、行号,入库仓库、数量这些内容。
整个插件调试能够通过,但是最后数据保存的时候会报错,说是仓库id没有录入。可是我明明已经给仓库Id赋值了啊。以前做生产订单下推完工入库的时候也是这样给仓库赋值都没有问题啊。//item["StockId"]赋值比较复杂,我直接给StockId_Id赋的值
仓库赋值代码:item["StockId_Id"] = int.Parse(dt.Rows[行号]["StockId_Id"].ToString());
DataTable dt表头, DataTable dt表体 是我通过客户端参数传上来的数据,分别是入库单表头和入库单表体需要的那些数据。
1\请大神帮我看看为什么会提示仓库没有值呢?
2\请大神提示一下如何才能只下推采购订单中的某一行,而不是整单下推。现在我整单下推,然后要用代码去把不要的明细删掉,有点麻烦。
3\如何实现一个采购订单的同一行,推两次,在同一张采购入库单里面产生两行(因为可能仓位不同)。以前我用复制行的方式可以,现在复制行保存的时候会报错。

服务器端插件基本代码如下:
public class 采购订单下推外购入库 : AbstractOperationServicePlugIn
{
public override void EndOperationTransaction(EndOperationTransactionArgs e)//调用操作成功之后触发
{
base.EndOperationTransaction(e); //此参数是获取由系统集成调用客户端给的数据
var parameters = this.Option.GetVariableValue("Parameters");//获得用户提交的参数,json格式,内含两个DATATABLE,
string t = parameters.ToString()";
string[] tt = t.Split(new string[] { ".表格分割." }, StringSplitOptions.None);//把自己传上来的表格解析出来
DataTable dt表头 = StringToDataTable(tt[0]); DataTable dt表体 = StringToDataTable(tt[1]);//StringToDataTable 省略了,这个是自己的表格解析程序
IOperationResult result = this.Invoke(dt表头, dt表体); //下推单据的主程序
this.OperationResult.OperateResult = result.OperateResult;
this.OperationResult.IsSuccess = result.IsSuccess;
this.OperationResult.ValidationErrors = result.ValidationErrors;
this.OperationResult.OperateResult = result.OperateResult;
}

private IOperationResult Invoke(DataTable dt表头, DataTable dt表体)//下推单据的主代码
{
string source; string target; string sargetBillTypeId; string t = ""; int m;
source = "PUR_PurchaseOrder";//采购订单
target = "STK_InStock";//外购入库
sargetBillTypeId = dt表头.rows[0]["入库单据类型id"].ToString();//入库单类型
IOperationResult result = new OperationResult(); //获取单据转换规则
ConvertRuleElement ruleElement = ServiceHelper.GetService().GetConvertRules(this.Context, source, target).FirstOrDefault();
ListSelectedRowCollection rows = new ListSelectedRowCollection(); t = ",";
t = ",";
for (int i = 0; i < dt表体.Rows.Count; i++)
{
if (t.IndexOf("," + dt表体.Rows[i]["POORDERENTRYID"].ToString() + ",") < 0)
{
t = t + dt表体.Rows[i]["POORDERENTRYID"].ToString() + ",";
ListSelectedRow row = new ListSelectedRow(dt表体.Rows[i]["POOrderId"].ToString(), dt表体.Rows[i]["POORDERENTRYID"].ToString(), 0, source);//关键,把生产订单追加到选择行
row.EntryEntityKey = "FEntity";//只下推一行
rows.Add(row);//这里找出需要下推的采购订单,有点小问题,一个订单有多行,但是我只想选择某行,虽然我传入了订单明细id,系统还是选择的整单
}
}
PushArgs pushArgs = new PushArgs(ruleElement, rows.ToArray());//下推服务接受的参数
pushArgs.TargetBillTypeId = sargetBillTypeId;
ConvertOperationResult convertResult = ServiceHelper.GetService().Push(this.Context, pushArgs); //转换生成目标单
result.MergeResult(convertResult);//合并转换操作结果 //目标单据数据集合
DynamicObject[] destObjs = convertResult.TargetDataEntities.Select(r => r.DataEntity).ToArray();
destObjs[0]["Date"] = DateTime.Parse(dt表头.Rows[0]["Date"].ToString());
destObjs[0]["BillNo"] = dt表头.Rows[0]["BillNo"].ToString();
DynamicObjectCollection 外购入库行明细集合 = destObjs[0]["InStockEntry"] as DynamicObjectCollection;
m = 外购入库行明细集合.Count - 1;
while (m >= 0)//因为前面无法按照采购订单明细id来下推单据,这里我不得不做了一个循环,把同一张订单里面我不要的那些明细删掉
{
bool 下推结果符合入库清单要求 = false;
for (int i = 0; i < dt表体.Rows.Count; i++)
{
if (外购入库行明细集合[m]["POORDERENTRYID"].ToString() == dt表体.Rows[i]["POORDERENTRYID"].ToString())
{
下推结果符合入库清单要求 = true;
}
}
if (下推结果符合入库清单要求 == false)
{
外购入库行明细集合.RemoveAt(m);
}
m--;
}
m = 0;
while (m < 外购入库行明细集合.Count)//循环数据集,把上传的仓库、数量等数据赋值给数据集
{
DynamicObject item = 外购入库行明细集合[m];
for (int i = 0; i < 外购入库行明细集合.Count; i++)//找到采购订单明细id相同的行,赋值
{
if (item["POORDERENTRYID"].ToString() == dt表体.Rows[i]["POORDERENTRYID"].ToString())//源单明细id
{
DynamicObject赋值(item, dt表体, i);
dt表体.Rows.RemoveAt(i);//赋值之后,就把上传的原始数据行删掉。
break;
}
}
m++;
}
for (int i = 0; i < dt表体.Rows.Count; i++)//dt表体 剩下来的数据,都是不能下推的,因为系统限制下推的时候,一个订单明细行只能下推一行入库。
{//这里因为我有可能同一行采购订单,因为仓位或者其他某个信息不同,需要推为两行采购入库(在同一入库单上),所以我这里准备手工给采购入库单增加行
m = 0;
while (m < 外购入库行明细集合.Count)
{
DynamicObject item = 外购入库行明细集合[m];
if (item["POORDERENTRYID"].ToString() == dt表体.Rows[i]["POORDERENTRYID"].ToString())//源单明细id
{
DynamicObject itemnew = (DynamicObject)item.Clone(false, true);//找到我需要的订单明细id推出来的那一行入库,把他复制一份。8月份打补丁前我可以这样操作,8月份之后就不行了。
DynamicObject赋值(itemnew, dt表体, i); //给新行赋值
外购入库行明细集合.Add(itemnew);
break;
}
m++;
}
}

//采购入库单的目标数据处理好了
FormMetadata destFormMetadata = null;
try
{
destFormMetadata = ServiceHelper.GetService().Load(this.Context, target) as FormMetadata;
}
catch (Exception ex)
{
}
//准备保存目标单据
IOperationResult saveResult = null;
try
{
saveResult = ServiceHelper.GetService().Save(this.Context, destFormMetadata.BusinessInfo, destObjs, OperateOption.Create());
}
catch (Exception ex)
{
}
try
{
result.MergeResult(saveResult);
}
catch (Exception ex)
{
}
//根据操作结果构造返回结果
if (result.ValidationErrors != null && result.ValidationErrors.Count > 0)
{
result.IsSuccess = false;
}
else
{ result.IsSuccess = true; }
return result;//最后每行都返回错误信息:"FieldName":"FStockId","Message":"单据体实体【明细信息】第【3】行分录,【仓库】字段必录","DIndex":0
}

private void DynamicObject赋值(DynamicObject item, DataTable dt, int 行号)//自己写的给一行采购入库赋值的代码
{//给每一行采购入库单信息赋值
item["BOMId_Id"] = int.Parse(dt.Rows[行号]["BOMId_Id"].ToString());//BOM版本
item["Note"] = dt.Rows[行号]["Note"].ToString();//备注
item["StockId_Id"] = int.Parse(dt.Rows[行号]["StockId_Id"].ToString());//仓库//以前做完工入库时,仓库就这样赋值,可以正常使用,但是外购入库这样赋值,最后保存的时候就会报错。
item["AuxpropId_Id"] = int.Parse(dt.Rows[行号]["AuxpropId_Id"].ToString());//辅助属性
item["F_szw_Qty"] = double.Parse(dt.Rows[行号]["RealQty"].ToString());//剩余数量(应付)
item["RealQty"] = double.Parse(dt.Rows[行号]["RealQty"].ToString());//实收数量
item["APNotJoinQty"] = double.Parse(dt.Rows[行号]["RealQty"].ToString());//未关联应付数量(计价单位)
item["BaseUnitQty"] = double.Parse(dt.Rows[行号]["RealQty"].ToString());//库存基本数量
item["PriceBaseQty"] = double.Parse(dt.Rows[行号]["RealQty"].ToString());//计价基本数量
item["PriceUnitQty"] = double.Parse(dt.Rows[行号]["RealQty"].ToString());//计价数量
item["RemainInStockBaseQty"] = double.Parse(dt.Rows[行号]["RealQty"].ToString());//采购基本数量
item["RemainInStockQty"] = double.Parse(dt.Rows[行号]["RealQty"].ToString());//采购数量
double danjia = double.Parse(item["Price"].ToString());//单价
item["Amount"] = double.Parse(dt.Rows[行号]["RealQty"].ToString()) * danjia;//金额
item["Amount_LC"] = double.Parse(dt.Rows[行号]["RealQty"].ToString()) * danjia;//金额(本位币)
danjia = double.Parse(item["F_szw_Price"].ToString());//结算单价
item["F_szw_Amount"] = double.Parse(dt.Rows[行号]["RealQty"].ToString()) * danjia;//结算金额
danjia = double.Parse(item["TaxPrice"].ToString());//含税单价
item["AllAmount"] = double.Parse(dt.Rows[行号]["RealQty"].ToString()) * danjia;//价税合计
item["AllAmount_LC"] = double.Parse(dt.Rows[行号]["RealQty"].ToString()) * danjia;//价税合计(本位币)
item["TaxAmount"] = double.Parse(item["AllAmount"].ToString()) - double.Parse(item["Amount"].ToString());//税额
item["TaxAmount_LC"] = double.Parse(item["TaxAmount"].ToString());//税额(本位币)
item["KeeperTypeID"] = dt.Rows[行号]["KeeperTypeID"].ToString() ;// 保管者类型
item["KeeperID_Id"] = int.Parse(dt.Rows[行号]["KeeperID_Id"].ToString());//保管者
item["OWNERTYPEID"] = dt.Rows[行号]["OWNERTYPEID"].ToString( );// 货主类型
item["OWNERID_Id"] = int.Parse(dt.Rows[行号]["OWNERID_Id"].ToString());// 货主
//MaterialCosts 材料成本 ProcessFee 加工费 //暂时还未用上
item["Seq"] = int.Parse(dt.Rows[行号]["Seq"].ToString());
item["StockStatusId_Id"] = 10000;
}
}
[/i][/i][/i][/i][/i][/i][/i]