引入数据时,如何建立与源单的关联关系
仅分享,因涉及到太多东西难以保证所有数据的准确性。 业务背景: 单据通过Excel引入金蝶云中,引入这些数据时,仅仅能够保存单据本身,其与源单的关联关系则不能引入进来,导致没有反写,不支持上下查等。 解决思路: 通过引入单据的保存插件实现。 1.引入模板中,单据体字段 源单编号 必须引入; 2. 编写单据的保存操作插件重载BeforeExecuteOperationTransaction事件; 3.对单据体行进行循环,取每单据体行的源单编号; 4.根据源单编号,批量读取源单; 5.对源单单据体行进行循环,按照源单编号取到源单单据体行内码等信息; 6.重新对目标单单据体行进行循环,判断目标单单据体行"xxxx_Link"子单据体是否有数据; 7.如果"xxxx_Link"子单据体没有数据,则插件新建数据包,并填写源单信息,追加到目标单单据体中。
依赖原理:单据保存时,会根据单据体的"xxxx_Link"子单据体记录的源单信息,与源单进行关联、反写。
【注意】单据关联配置-控制字段 【注意】反写规则-反写条件(不满足条件则不会反写) 【注意】关联关系字段(可以在API查看)
案例:引入销售出库单时,如何与销售订单建立关联
import clr
clr
.AddReference
("System")
clr
.AddReference
("System.Data")
clr
.AddReference
("System.XML")
clr
.AddReference
("System.Web.Extensions")
clr
.AddReference
("Kingdee.BOS")
clr
.AddReference
("Kingdee.BOS.Core")
clr
.AddReference
("Kingdee.BOS.DataEntity")
clr
.AddReference
("Kingdee.BOS.ServiceHelper")
clr
.AddReference
("Newtonsoft.Json")
clr
.AddReference
("Kingdee.BOS.Contracts")
clr
.AddReference
("Kingdee.BOS.App")
clr
.AddReference
("System.Web")
clr
.AddReference
("Kingdee.BOS.App.Core")
import sys
from System
import *
from System
import String
as string
from System
.IO
import *
from System
.Net
import *
from System
.Web
import *
from System
.Text
import *
from System
.Threading
import *
from System
.Globalization
import *
from System
.Security
.Cryptography
import *
from System
.Web
.Script
.Serialization
import *
from System
.Collections
.Generic
import List
as syslist
from System
.Collections
.Generic
import Dictionary
from Newtonsoft
.Json
.Linq
import *
from Kingdee
.BOS
.AppServer
import AppServerObject
from Kingdee
.BOS
.App
.Core
import *
from Kingdee
.BOS
.Contracts
import *
from Kingdee
.BOS
.Core
.List
import *
from Kingdee
.BOS
.Core
.CommonFilter
import *
from Kingdee
.BOS
.Contracts
.Report
import *
from Kingdee
.BOS
.Core
.Report
import ISysReportView
from Kingdee
.BOS
.Core
.Report
import ReportTitles
from Kingdee
.BOS
.App
import ServiceHelper
as ServiceHelperAPP
from Kingdee
.BOS
import *
from Kingdee
.BOS
.Util
import *
from Kingdee
.BOS
.Core
.List
.PlugIn
import *
from Kingdee
.BOS
.Core
.Log
import *
from Kingdee
.BOS
.Core
import *
from Kingdee
.BOS
.Core
.DynamicForm
import *
from Kingdee
.BOS
.Orm
import OperateOption
from Kingdee
.BOS
.Core
import *
from Kingdee
.BOS
.Core
.DynamicForm
import *
from Kingdee
.BOS
.DataEntity
import *
from Kingdee
.BOS
.Orm
.DataEntity
import *
from Kingdee
.BOS
.Core
.Bill
import *
from Kingdee
.BOS
.Core
.Bill
.PlugIn
import *
from Kingdee
.BOS
.ServiceHelper
import *
from Kingdee
.BOS
.Core
.Interaction
import KDInteractionException
from Kingdee
.BOS
.Core
.Metadata
.EntityElement
import *
from Kingdee
.BOS
.Core
.Metadata
import SelectorItemInfo
from Kingdee
.BOS
.Core
.Metadata
import OQLFilter
from Kingdee
.BOS
.Core
.SqlBuilder
import QueryBuilderParemeter
from Kingdee
.BOS
.Core
.DynamicForm
.PlugIn
.ControlModel
import *
reload(sys
)
sys
.setdefaultencoding
('utf-8')
def _Zstr(a
):
return ("" if a
==None else (a
if isinstance(a
,str) else str(a
))).strip
();
def LoadData(BillNos
):
formid
= "SAL_SaleOrder";
fields
=syslist
[SelectorItemInfo
]();
fields
.Add
( SelectorItemInfo
("FID"));
fields
.Add
( SelectorItemInfo
("FSaleOrderEntry_FEntryID"));
fields
.Add
( SelectorItemInfo
("FBillNo"));
fields
.Add
( SelectorItemInfo
("FBFLowId"));
fields
.Add
( SelectorItemInfo
("FMaterialId"));
fields
.Add
( SelectorItemInfo
("FBaseCanOutQty"));
fields
.Add
( SelectorItemInfo
("FStockBaseCanOutQty"));
filter = string
.Format
(" FBillNo IN ('{0}') ",string
.Join
("','",BillNos
));
ofilter
= OQLFilter
.CreateHeadEntityFilter
(filter);
objs
=BusinessDataServiceHelper
.Load
(this
.Context
,formid
,fields
,ofilter
);
return objs
;
def BuildDictionary(DDObjs
):
dctAllBills
=Dictionary
[string
, Dictionary
[string
, DynamicObject
]]();
for DDObj
in DDObjs
:
billNo
= Convert
.ToString
(DDObj
["BillNo"]);
dctOneBill
=Dictionary
[string
, DynamicObject
]();
entryRows
= DDObj
["SaleOrderEntry"]
for entryRow
in entryRows
:
Seq
= Convert
.ToString
(entryRow
["Seq"]);
dctOneBill
[Seq
] = entryRow
;
dctAllBills
.Add
(billNo
, dctOneBill
);
return dctAllBills
;
def FillLinkRow(srcRow
,toRow
,linkRow
):
linkRow
["FlowId"] = srcRow
["FBFLowId_Id"];
linkRow
["FlowLineId"] = 0;
linkRow
["RuleId"] = "SaleOrder-OutStock";
linkRow
["SBillId"] = (srcRow
.Parent
)[0];
linkRow
["SId"] = srcRow
[0];
BaseCanOutQty
= Convert
.ToDecimal
(srcRow
["BaseCanOutQty"]);
StockBaseCanOutQty
= Convert
.ToDecimal
(srcRow
["StockBaseCanOutQty"]);
linkRow
["BaseUnitQtyOld"] =BaseCanOutQty
;
linkRow
["SALBASEQTYOld"] =StockBaseCanOutQty
;
linkRow
["BaseUnitQty"] = toRow
["BaseUnitQty"];
linkRow
["SALBASEQTY"] = toRow
["SALBASEQTY"];
toRow
["BaseMustQty"]=BaseCanOutQty
toRow
["MustQty"]=BaseCanOutQty
toRow
["SrcType"]="SAL_SaleOrder"
def OnPreparePropertys(e
):
e
.FieldKeys
.Add
("F_LYP_Text");
e
.FieldKeys
.Add
("F_LYP_Text1");
def BeforeExecuteOperationTransaction(e
):
try:
for billObj
in e
.SelectedRows
:
BillNos
=syslist
[str]();
entryRows
=billObj
.DataEntity
["SAL_OUTSTOCKENTRY"]
for entryRow
in entryRows
:
FSrcBillNo
=entryRow
["F_LYP_Text"]
if FSrcBillNo
=="":
continue
if (BillNos
.Contains
(FSrcBillNo
)):
continue
BillNos
.Add
(FSrcBillNo
);
DDObjs
=LoadData
(BillNos
)
FsrcTableNumber
= BusinessFlowServiceHelper
.LoadTableDefine
(this
.Context
, "SAL_SaleOrder", "FSaleOrderEntry").TableNumber
;
dctAllBills
=BuildDictionary
(DDObjs
);
allNewLinkRows
=syslist
[DynamicObject
]();
for billObj
in e
.SelectedRows
:
entryRows
=billObj
.DataEntity
["SAL_OUTSTOCKENTRY"]
for entryRow
in entryRows
:
linkRows
=entryRow
["FEntity_Link"]
linkRow
=DynamicObject
(this
.BusinessInfo
.GetEntity
("FEntity_Link").DynamicObjectType
);
linkRow
["STableName"] = FsrcTableNumber
;
FSrcBillNo
=entryRow
["F_LYP_Text"]
if (FSrcBillNo
==""):
continue;
dctOneBill
=dctAllBills
[FSrcBillNo
]
Seq
=entryRow
["F_LYP_Text1"]
if (Seq
==""):
continue;
srcRow
=dctOneBill
[Seq
]
FillLinkRow
(srcRow
,entryRow
,linkRow
);
if (linkRows
.Count
>0):
continue;
linkRows
.Add
(linkRow
);
allNewLinkRows
.Add
(linkRow
);
_SequenceReader
=SequenceReader
(this
.Context
)
_SequenceReader
.AutoSetPrimaryKey
(allNewLinkRows
.ToArray
(),this
.BusinessInfo
.GetEntity
("FEntity_Link").DynamicObjectType
);
except Exception
as e
:
raise Exception
("BeforeExecuteOperationTransaction:"+e
.ToString
());
结果展示