以Django-python为例,使用oData(rest)协议与SAP ERP集成

下午好,哈伯!

可以说,将大型系统(例如SAP)与小型但更灵活的系统集成在一起的话题是要充分利用两者。

特别是,我的示例将描述SAP ERP与Django的集成。

挑战赛


由于我们心爱的州引入了许多不同的控制系统:Egais,Mercury等,许多公司已开始调整其笨重的系统,并将(对于大型公司)适度笨拙的系统适应新的条件。 我不会说我特别适应了哪一种,但是这种想法始终在我的脑海中盘旋-在一个单独的平台的基础上为所有事物创建一个统一的跟踪系统。

均值


我花了很短的时间来选择使用哪种工具,我选择了:Python编程语言-鉴于Django平台中包含了无所不包的库,请不要问为什么选择Django,而不是Flask或Odoo。 我已经将Odoo用作该平台,并想研究其中一个,第一个,我不知道为什么,可能是因为它更简单。 用于SAP开发的ERP系统-在这里,我真的没有选择,因为 我在一家SAP集成商公司工作,因此我既了解又可以使用该系统的沙箱,因此我有充分的条件可以平静地完成自己的工作。

前端Django


我首先要做的是制定一个特定的任务并将其写在纸上,通常我会在编码或描述过程之前建议所有人,如果您随时随地进行更改,也请在说明中进行更改,这非常重要。

这是程序说明的第一个非常原始版本。
寄出过程

1)创建外向交货。

2)将托盘通过门时-自动操作和半自动操作

一个 自动操作/当托盘通过门时,程序会通过RFC在WMS系统中请求有关其交付方式,编号的信息,并将对交付的识别响应发送回WMS系统(可能为此确认仓库任务(拣配任务))托盘和所有投资)。 同时在WMS系统中使用信息检查所有消费税邮票

b。 半自动操作/操作员在门系统中输入交货/机器编号,并通过门驱动托盘,门系统将每个托盘的请求发送到WMS系统,以检查内部的消费税邮票。

3)交货的组成部分发送到会计系统

入库流程

1)创建收货。

2)托盘通过大门

3)向会计系统发送有关当前仓库中应收款构成的请求

4)在此会计系统的基础上检查消费邮票托盘的内部组成

5)信号被发送到WMS系统以卸载托盘。

所需表

门:
识别码
仓库:
内容描述
段落消息

职称:
时间,系统,仓库编号,登机口ID。
职位:
消费税,注册时间,标题绑定
ERP组成消息(内向交货)

职称:
时间,系统,交货编号,
职位:
材料,消费税印章,托盘编号(如果有)

汇总消息(基于来自ERP的数据)

职称:

时间,系统,仓库编号,登机口标识符,记帐系统中的交货编号,方向标志(收货外出),验证脚本标志,机器编号,仓库登机口编号,

位置:消费税,货盘编号(可选),物料(可选),交货编号,机器编号,文件中的物料编号,批次(可选),包装(可选)
接下来,我开始学习Django并绘制过程和数据库模式。
在Django中,创建表模型非常容易和方便,看起来像这样:

class SapOptions(models.Model): name = models.CharField(verbose_name=' ', max_length=50) baseurl = models.CharField(max_length=500, verbose_name='Url  ', help_text = 'URL  ,  ,  :"https://moses1005:44300/sap/opu/odata/sap/ZLS_SUPPLYCHAIN_SRV/"')#  URL sapset = models.CharField(default='Enter Sapset', max_length=100, verbose_name=' ()') mandt = models.CharField(max_length=3, verbose_name='') user = models.CharField(max_length=15, verbose_name='       ') passwd = models.CharField(max_length=15, verbose_name='') verify = models.BooleanField(default=False, help_text = '   ') def __str__(self): return ': '+self.name + ',  : '+self.mandt class Gates(models.Model): from mainAPP.sap_connector import get_lgorts_fromsap ident = models.CharField(verbose_name='', max_length=10, help_text='',unique=True) wh = models.CharField(verbose_name='  ', default='',max_length=10, help_text='   WMS') help = models.CharField(verbose_name='', default='',max_length= 500,help_text=' , ,  ,   ') try: lgorts = get_lgorts_fromsap() except: lgorts = [('No Connect', 'No Connect'),] lgort = models.CharField(verbose_name='',default='0000', max_length=20, choices=lgorts) def __str__(self): return self.ident +' : '+self.wh+' : '+self.help 

之后,我已经了解了如何从SAP中提取目录,从而使集成看起来完全“无缝”,关键字“似乎”,但稍后会介绍更多。

因此,在学习了Django(今天晚上被杀死)后,我编写了一个界面,用于输入信息,然后将其发送到SAP ERP。

输入接受信息的第一个屏幕如下所示:



  • 仓库-简要说明与SAP ERP的直接集成,
  • ERP交付-输入来自SAP ERP的交付,输入后对其进行验证(向SAP发出是否存在这样的交付请求,
  • TTN-一切都清楚了(运单),
  • 合作伙伴编号-这是SAP ERP的合作伙伴编号,该字段是可选的,是为了将来查找交货而创建的,
  • 包装标识符-这是最重要的字段之一;这是货盘或包装的编号。

而且,该接口适用于移动终端(TSD)



这些字段的制作方式是,每次按ENTER键后,光标就会跳到下一个输入字段,这样可以方便地扫描来自TTN,Gate,Pallet的所有信息。

然后,在扫描完最后一个字段或单击“保存”后,屏幕转到用于输入每个产品标识符的对话框:



栏位:

  1. 这是由EGAIS系统本身发送的标识符列表的屏幕,红色是尚未扫描的标识符,黄色是已扫描但不在EGAIS消息中的标识符,绿色是由EGAIS发送并已扫描的标识符
  2. 输入标识符,这里也是“ +”按钮,用于显示其他字段等。
  3. 显示错误消息(如果有)。

集成实施:


对于来自Django的集成,一切都很明显,“ rest”易于实现,但是从SAP ERP中,我不得不读一点。

那么这是怎么做的,这不是很困难

1)有必要创建一个用于实现的集成类,或者为其创建一个开发包。 这是在事务SEGW中完成的



2)创建类后,需要定义数据模型,有几个选项,创建自己的字段,或从表中单击SAP。 这意味着,在创建用于集成的数据模型之前,您需要为数据创建一个表,这是在事务SE11中完成的,如何在Internet上找到该方法。 因此,就像结构一样



我喜欢我已经创建的表结构



3)这是我们已经完成的工作:



单击“生成”,该类生成了集成所需的结构,我们将使用它。

4)接下来,在我们的“服务实现”选项卡中,我们的结构将显示所有可用的方法,尤其是:

一个 创建-根据外部发送的数据在我们的表中创建记录的方法
b。 删除-按标识符删除记录的方法
c。 GetEntity-单记录请求方法
d。 GetEntitySet-通过条件获取多个记录的方法
e。 更新-记录修改方法
实际上,所有这些方法都非常抽象,但是当然存在差异

5)生成类之后,我们在Runtime Artifacts分支中创建一个类列表,最后选择带有DPC_EXT的类


双击进入类本身

6)进入类方法列表后,最后您会看到所有方法的列表,请务必重新定义它,否则在数据模型的下一次更改之后,所有内容都会被删除,我碰到了这一点,这很侮辱...


例如,我将展示Create方法的实现



一切都非常简单,将IT_KEY_TAB输入到输入中,并根据此数据执行一些操作,在此代码中,表中的常规记录或错误输出将被转移到Django。 成功创建的输出将写入ER_ENTITY结构。

7)在事务/ IWFND / MAINT_SERVICE中测试我们的接口,很长。 我们进入它,找到我们创建的类,然后单击“ SAP Gateway Client”



从本质上讲,我们仅使用SAP的GET \ POST \ PUT \ DELETE Web请求模拟器打开

PS。您可以在任何情况下测试创建的服务。我正在邮递员计划中进行测试



这就是get请求的样子,“ GetEntitySet”
/ sap / opu / odata / sap / ZLS_SUPPLYCHAIN_SRV / ZLS_INBOUND_HEADSet?$ format = json
其中:
/ ZLS_SUPPLYCHAIN_SRV / -这是我们创建的类
/ ZLS_INBOUND_HEADSet是我们的数据模型,
format = json是我们获得的数据格式,选择xml还是json,我选择json,因为这就是为什么它对我来说更方便。

8)同样,我们编写方法

我们所拥有的,在Django上创建了前端,在SAP端创建了一个接口
现在我们需要恢复所有这些,并且在Django方面,我们编写了方法:

1)创建会话的方法,以便登录,获取scrf令牌并且已经更进一步
使用我们配置的界面从数据库中提取必要的信息或创建一个新的界面
记录。 为此,请在Django中创建一个单独的文件,将其命名为Sap_connector.py并进行描述
其中是主要方法。

 def sap_createSession(): #     oDATA from scanner.models import SapOptions #   SAP sap_opt = SapOptions.objects.all()[0] #       s = requests.Session() s.headers.update({'Connection': 'keep-alive', 'X-CSRF-TOKEN': 'Fetch'}) auth = (sap_opt.user, sap_opt.passwd) try: r = s.get(sap_opt.baseurl, auth=auth,verify=sap_opt.verify) except: message = "    %s %s"%(sap_opt.mandt, sap_opt.name) return ('NO TOKEN', 'NoSession', message) token = r.headers['x-csrf-token'] session = s sess = (token, session, None) return sess 

2)SAP ERP中的交货验证方法

 def sap_delivery_verify(token, session, delivery): #      ERP from scanner.models import SapOptions, Gates sap_opt = SapOptions.objects.all()[0] s = session format = '?$format=json' set = 'likpSet' url = sap_opt.baseurl + set + "('"+delivery+"')"+format headers = {'Content-type': 'application/json;charset=utf-8', 'X-CSRF-TOKEN': token} #      auth = (sap_opt.user, sap_opt.passwd) # auth get = s.get(url, headers=headers, auth=auth,verify=sap_opt.verify)#   if get.status_code ==200: delivery_out = json.loads(get.text).get('d').get('Vbeln') return (True, 'OK') else: error_text = json.loads(get.text).get('error').get('message').get('value') return (False, error_text) 

3)将SAP仓库与Django集成的方法

 def get_lgorts_fromsap(): from scanner.models import SapOptions session = sap_createSession() #   token = session[0] session = session[1] sap_opt = SapOptions.objects.all()[0] #   s = session format = '?$format=json' set = 't001lSet' url = sap_opt.baseurl + set +format headers = {'Content-type': 'application/json;charset=utf-8', 'X-CSRF-TOKEN': token} #      auth = (sap_opt.user, sap_opt.passwd) # auth get = s.get(url, headers=headers, auth=auth,verify=sap_opt.verify)#   jdata = json.loads(get.text) lgorts = [] for l in jdata.get('d').get('results'): l.get('lgort') lgorts.append((l.get('Lgort'),l.get('Lgort'))) return lgorts 

模型部分的第二部分:

 class Gates(models.Model): from mainAPP.sap_connector import get_lgorts_fromsap ident = models.CharField(verbose_name='', max_length=10, help_text='',unique=True) wh = models.CharField(verbose_name='  ', default='',max_length=10, help_text='   WMS') help = models.CharField(verbose_name='', default='',max_length= 500,help_text=' , ,  ,   ') try: #   SAP lgorts = get_lgorts_fromsap() except: lgorts = [('No Connect', 'No Connect'),] lgort = models.CharField(verbose_name='',default='0000', max_length=20, choices=lgorts) def __str__(self): return self.ident +' : '+self.wh+' : '+self.help 

集成如下所示:当我在Django设置中创建新仓库时,系统会在仓库字段中显示SAP ERP中当前创建的仓库。



4)在SAP ERP中创建新记录的方法

 def sap_connect(token, session, data): from scanner.models import SapOptions, Gates #      SAP ERP sap_opt = SapOptions.objects.all()[0] s = session delivery = data.get('delivery') url = sap_opt.baseurl + sap_opt.sapset #  URL +    headers = {'Content-type': 'application/json;charset=utf-8', 'X-CSRF-TOKEN': token} #      auth = (sap_opt.user, sap_opt.passwd) # auth data =json.dumps({"d":{ "Mandt": sap_opt.mandt, "Lgort": Gates.objects.get(id=data.get('gates')).wh, "Vbeln":data.get('delivery'), "Mark": data.get('mark'), "Matnr": "", "Posnr": "", "Mbl": "", "InbDicid":"AAAAAAAAAAAAAAAAAAAAAA==", "DocExt": data.get('ttn'), "Exidv": data.get('pack') }}) try: r2 = s.post(url, data=data, headers=headers, auth=auth) except: return (False, '   ') if r2.status_code ==201: print(' %s   '%(delivery)) return (True, '  %s : '%delivery) else: print('  %s   '%(delivery)) text = r2.text SO = soup(text) s = SO.find_all("message")[0].text return (False, s) 

实际上,我们只是发出POST请求,然后以json格式写入数据

结论


我们创建了一个与SAP ERP集成的程序,它的场景很简单,
汽车到达后,我们在界面上的每个货盘上输入信息,程序会为我们检查所有数据是否正确输入,并提供有关应该输入什么和已经输入什么的信息。 输入数据后,它将报告已完成的操作,并将数据传输到SAP ERP。 此外,此接口还适用于移动数据输入接口,这对于具有数据收集终端(TSD)的仓库非常重要。 在将数据传输到ERP之后,系统还将所有数据保存到哪个仓库,哪个标识符来,什么类型的标识符,谁接受它,等等。

结果,我们有了一个用于处理公司内传入和传出产品标识符的程序,而所有工作的90%都是在与主系统集成的外部系统中精确进行的。

将来,需要对它进行定稿,以维护传入的批次,序列号等,甚至与SAP集成得更紧密,例如,通过此接口创建收据交易,这是一个发展思路:)

PS:我没有绘制此工作解决方案的ABAP或python-django代码,我没有绘制Django或html模板设置,但专注于与SAP ERP集成以显示创建连接至SAP这样大系统的模块并不难如果包括大约4个晚上的Django学习,我就去了这样的系统。

谢谢大家的关注,我将感谢您的建设性批评!

Source: https://habr.com/ru/post/zh-CN426611/


All Articles