​快递100及快递管家编写并调试简单的Python插件原创
金蝶云社区-文安根
文安根
18人赞赏了该文章 2036次浏览 未经作者许可,禁止转载编辑于2023年07月27日 11:04:19

    金蝶云星空供应链领域销售模块对接的快递100和快递管家只能满足部分客户的需求,对于一些客户的特定需求,如果不是比较通用,通版一般不会纳入后续的补丁中,客户可以参考以下快递100及快递管家二开相关的帖子:https://vip.kingdee.com/article/167297791734694912 ,https://vip.kingdee.com/article/173521351129519360 ,https://vip.kingdee.com/article/216286725399032576 ,https://vip.kingdee.com/article/223033855618894592  如果以上二开帖子的内容满足不了客户,或者客户不想写C#插件代码(C#二开插件代码有个明显的缺点,那就是必须先编写C#代码,然后编译成.dll动态链接库文件并上传到金蝶星空系统安装目录中,目录一般为X:\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin,对于公有云客户来说上传比较繁琐,对于多租户来说更是不可用),亦或想通过BOSIDE扩展并输入一些简单的Python代码,则本文是一个可以参考的例子。

      如标题所示,本文主要介绍编写并调试Python插件。由于本文是以调试寄宿在IIS下的星空环境为背景,因此首先要有几个前提条件,那就是本机安装了IIS,安装了金蝶云星空,安装了工作负荷包含Python开发的Visual Studio(注意这里必须是Python文件与IIS在同一机器上)。如果是寄宿在ASP.NET Development Server或IIS Express下也是可以类似地附加进程并调试,如下图1-1和图1-2所示:

image.png

图1-1


image.png

图1-2


    打开Visual Studio,创建一个Python应用程序项目,在项目中添加一个Python类,文件命名为KingdeeGalaxy.py,在文件中输入以下Python代码:

import clr
clr.AddReference('System')
clr.AddReference('Newtonsoft.Json')
clr.AddReference('Kingdee.BOS.Core')

from Newtonsoft.Json.Linq import *
from Kingdee.BOS.Core import *
from System import *

def BarItemClick(e):
    if e.BarItemKey.Equals("tbManualnputLogistics", StringComparison.OrdinalIgnoreCase):
        this.View.ShowMessage("Python Test from KingdeeGalaxy.py File")
        
def DataChanged(e):
    if e.Field.Key.Equals("FItems", StringComparison.OrdinalIgnoreCase):
        stringifyItems = Convert.ToString(this.View.Model.GetValue("FItems", e.Row))
        if(len(stringifyItems) > 0):
            items = JArray.Parse(stringifyItems);
            materialNames = ""
            for item in items:
                itemName = str(item["itemName"])
                if not materialNames.__contains__(itemName):
                    materialNames = materialNames + " " + itemName
            this.View.Model.SetValue("FComment", materialNames.strip(), e.Row)

    注意不要复制以上代码,因为HTML网页会转义空格,下文的Python代码类似,都不要直接复制,文章后面附件有相关代码,可直接下载附件。上面的python代码如果要带出物料和数量且数量强制转整数,for循环语句里面可替换为:

itemName = str(item["itemName"]) + " " + str(Math.Round(Convert.ToDecimal(str(item["itemCount"])), 0))
materialNames =  (materialNames if materialNames  == "" else  (materialNames + ", ")) + itemName 

。附件中带Convert后缀的文件也模拟了一个单据转换Python插件,有兴趣的可以看看,代码如下图1-3所示:

image.png

    图1-3


    打开BOS IDE,扩展'获取电子面单'动态表单,修改字段'快递管家属性&物料清单'(比较老的星空版本中的名称可能只有'物料清单',没有&前面的),勾选即时触发值更新事件,如下图2-1所示:

image.png

图2-1


    然后在表单插件列表中注册Python插件(此插件只是调试用,真正做逻辑的是代码里面的KingdeeGalaxy.py 文件,调试无问题事要用KingdeeGalaxy.py文件中的内容替换),如下图2-2所示:

image.png

图2-2


    Python脚本如下:

import clr
clr.AddReference('IronPython')
from IronPython.Hosting import Python

def wrap_d(f):
    func_name = f.__name__
    del f
    
    def wrapper(e):
        engine = Python.CreateEngine({'Debug': True})
        scope = engine.CreateScope()
        g = globals()
        for v in ('this',):
            scope.SetVariable(v, g[v])
        engine.CreateScriptSourceFromFile('E:\Codes\DemoSln\PythonApplication\KingdeeGalaxy.py').Execute(scope)
        return getattr(scope, func_name)(e)
    return wrapper
    
@wrap_d
def BarItemClick(e):
    pass
    
@wrap_d
def DataChanged(e):
    pass

    注意上面的语句engine.CreateScriptSourceFromFile()要与真实环境路径一致,且调试完毕后也要替换成KingdeeGalaxy.py中的内容,BOSIDE保存后,打开命令提示符,输入cd C:\windows\system32\inetsrv,再输入appcmd list wp,如下图2-3所示:

image.png

图2-3


    默认情况下,applicatoinPool为K3Cloud的进程ID就是我们要附加的(注意,不同机器ID不一样),然后在Visual Studio中通过菜单'调试->附加到进程'进行附加调试(要以管理员打开Visual Studio),如下图2-4所示:

image.png

图2-4


    在Python文件中的DataChanged方法打上断点,然后打开金蝶星空业务系统,在'获取电子面单'中选中一个单据,如下图2-5所示:

image.png

图2-5


    选择一个单据后,Python断点命中,调试示意图如下图2-6所示:

image.png

图2-6


    上文中的Python代码是应相关客户提单需求模拟编写的,主要逻辑是在'物料清单'字段有值后(此字段通版在选择单据后就会包含物料名称,物料数量,物料单位的JSON字符串),仅提取其中的物料名称,并将物料名称去重后按空格分隔并赋值给'备注'字段。界面效果如下图2-7所示:

image.png

图2-7


    最后,如果调试没有问题,则可以修改图2-2所示的Python插件代码,用KingdeeGalaxy.py中的内容替换原来的Python代码,要记得删除代码段BarItemClick(e): 方法里面的内容,因为试例仅是用来在单击'手工输入'按钮时弹出一个提示并演示可以重写并调试多个方法而已,由于本人对IronPython了解不深,图2-2中的源代码只能大致猜测为用另一py文件代替执行,星空系统中的Python插件内部解析使用了IronPython,其中的大部分代码还是通过Python跨言调用.NET框架代码,因此可以看到很多方法或类库还是C#形式,原文可参阅我同事帖子:https://vip.kingdee.com/article/274477865100148480 。客户也可以通过类似方法,对其它单据或动态表单进行Python二开插件编写并调试。如果客户不会编写Python且对星空供应链销售模块下的快递100及快递管家相关功能有比较简单的需求调整,则可以提单到本人(提单备注转工号45234)帮忙编写相关Python插件。另外要注意的一个地方那就是相同Python代码有可能通过VisualStudio调试时与在星空上挂的Python代码执行效果可能会有区别。比如单据转换插件使用全局变量时,在Visual Studio里面调试Python脚本会无效,但如果把Python代码直接复制到星空单据转换Python插件中又是可行的,详情可参阅论坛:https://vip.kingdee.com/article/317320373123503872?productLineId=1 中偏后的内容。

    以上介绍是以补丁号PT-146903 [8.0.0.202202]为背景编写的,在此之前的版本都可通过这种方法编写Python调试代码,但由于后续星空通版安全要求的提升会导致此帖子不适用,如下图3-1为版本PT-146915 [8.0.0.202206]下的注册Python脚本时的提示,可以看到此版本由于安全性不能注册成功,二开客户需要注意下(如果出现如下图不能注册的情况则可以通过bos修改xml强制输入)。

image.png

图3-1

  



赞 18