التكامل مع SAP ERP ، باستخدام Django-python كمثال ، باستخدام بروتوكول oData (rest)

مساء الخير يا هبر!

كان موضوع دمج الأنظمة الكبيرة مثل SAP مع الأنظمة الصغيرة ، ولكن الأكثر مرونة ، إذا جاز التعبير ، هو الاستفادة القصوى من كليهما.

على وجه الخصوص ، سوف يصف المثال الخاص بي تكامل SAP ERP مع Django.

التحدي


نظرًا للعديد من أنظمة التحكم المختلفة التي قدمتها دولتنا الحبيبة: Egais و Mercury وغير ذلك الكثير ، بدأت العديد من الشركات في تكييف أنظمةها الثقيلة ووضعها في أنظمة خرقاء بشكل معتدل (للشركات الكبيرة) للظروف الجديدة. لن أقول أيها قمت بتكييفها على وجه الخصوص ، لكن الفكرة كانت تدور دائمًا في رأسي - لإنشاء نظام تتبع موحد لكل شيء على أساس نظام أساسي منفصل.

يعني


لم أستغرق وقتًا طويلاً لاختيار الأدوات التي يجب اتخاذها ، اخترت: لغة برمجة Python - نظرًا لوفرة المكتبات مع كل شيء وكل شيء ، منصة Django ، لا تسأل لماذا Django ، وليس Flask أو Odoo. لقد أخذت Odoo بالفعل للمنصة وأردت أن أدرس أحدها ، وأخذت الأولى ، حسنًا ، لا أعرف لماذا ، ربما بسبب بساطتها الأكبر. نظام ERP لتطوير SAP- حسنًا ، هنا لم يكن لدي خيار حقًا ، أنا أعمل في شركة تكامل SAP ، لذا لديّ معرفة وإمكانية الوصول إلى وضع الحماية لهذا النظام ، حتى أحصل على جميع الشروط لأقوم بعملي بهدوء دون عوائق.

الواجهة جانغو


أول شيء بدأت به هو صياغة مهمة محددة وكتابتها على قطعة من الورق ، وعمومًا أنصح الجميع قبل ترميز شيء ما ، ووصف العملية ، ومن المهم جدًا إذا قمت بتغييره أثناء التنقل ، فقم بتغييره في الوصف أيضًا.

فيما يلي أول نسخة أولية من وصف البرنامج.
عملية صادرة

1) يتم إنشاء التسليم للخارج.

2) عند تمرير المنصات عبر البوابة - التشغيل التلقائي والتشغيل شبه التلقائي

أ. التشغيل التلقائي / عندما تمر منصة نقالة عبر البوابة ، يطلب البرنامج بواسطة RFC في معلومات نظام WMS حول نوع التسليم ، ورقمه ويرسل رد تعريف التسليم إلى نظام WMS (ربما يؤكد مهام المستودع (مهام الانتقاء) لهذا البليت وجميع الاستثمارات). يتحقق أيضًا من جميع طوابع المكوس مع المعلومات في نظام WMS

ب. التشغيل شبه الأوتوماتيكي / يدخل المشغل رقم التسليم / الآلة في نظام البوابة ويدفع المنصات عبر البوابة ، ويرسل نظام البوابة طلبًا لكل منصة نقالة إلى نظام WMS لفحص طوابع المكوس بالداخل.

3) يتم إرسال تكوين التسليم إلى نظام المحاسبة

عملية الوارد

1) يتم إنشاء التسليم للداخل.

2) مرور البليت عبر البوابة

3) يتم إرسال طلب إلى النظام المحاسبي حول تكوين المستحقات في المستودع الحالي

4) يتم التحقق من التركيب الداخلي لبليت طوابع المكوس على أساس هذا النظام المحاسبي

5) يتم إرسال إشارة إلى نظام WMS لتفريغ المنصات.

الجداول المطلوبة :

البوابة:
المعرف
مستودع:
الوصف
رسالة المرور :

العنوان:
الوقت ، النظام ، رقم المستودع ، معرف البوابة.
المنصب:
ختم المكوس ، ووقت التسجيل ، وملزمة العنوان
رسالة تكوين تخطيط موارد المؤسسات (التسليم الداخلي)

العنوان:
الوقت ، النظام ، رقم التسليم ،
المنصب:
المادة ، ختم المكوس ، رقم المنصة (إن وجد)

رسالة مجمعة (بناءً على بيانات من 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 نفسه ، حيث إن Reds هي المعرفات التي لم يتم فحصها بعد ، والأصفر هي المعرفات التي تم مسحها ضوئيًا ، ولكنها لم تكن في رسالة EGAIS ، والمعرفات الخضراء هي تلك التي تم إرسالها بواسطة EGAIS وتم مسحها ضوئيًا
  2. عند إدخال المعرّفات ، يوجد هنا أيضًا زر "+" ، وهو ضروري لظهور حقل آخر ، وما إلى ذلك.
  3. عرض رسائل الخطأ ، إن وجدت.

تنفيذ التكامل:


بالنسبة للتكامل من Django ، كل شيء واضح "الراحة" سهلة التنفيذ ، ولكن من SAP ERP ، كان علي أن أقرأ قليلاً).

فكيف يتم ذلك ، وكيف أنه ليس من الصعب للغاية

1) من الضروري إنشاء فئة تكامل للتنفيذ ، على التوالي حزمة تطوير لها. يتم ذلك في المعاملة SEGW



2) بعد إنشاء الصف ، تحتاج إلى تحديد نموذج البيانات ، وهناك العديد من الخيارات ، أو إنشاء الحقول الخاصة بك ، أو النقر فوق SAP من الجدول. هذا يعني أنه قبل إنشاء نموذج بيانات للتكامل ، تحتاج إلى إنشاء جدول للبيانات ، ويتم ذلك في المعاملة SE11 وكيفية القيام بذلك يمكن العثور عليه على الإنترنت. لذا ، مثل الهيكل ،



أنا أحب هيكل الجدول الذي قمت بإنشائه بالفعل



3) هذا هو العمل الذي قمنا به:



انقر فوق "إنشاء" ، حيث قام الفصل بإنشاء البنية اللازمة للتكامل ، وسنعمل معها.

4) بعد ذلك ، في علامة تبويب تنفيذ الخدمة ، يظهر هيكلنا مع جميع الطرق المتاحة لها ، على وجه الخصوص:

أ. إنشاء - طريقة لإنشاء سجل في جدولنا وفقًا للبيانات المرسلة من الخارج
ب. حذف - طريقة حذف السجلات حسب المعرف
ج. GetEntity - طريقة طلب سجل واحد
د. GetEntitySet - طريقة للحصول على سجلات متعددة حسب المعايير
ه. تحديث - طريقة تغيير التسجيل
في الواقع ، كل هذه الأساليب مجردة تمامًا ، ولكن بالطبع هناك اختلافات

5) بعد إنشاء الفصل ، ننشئ قائمة بالفئات في فرع Runtime Artifacts ، ونختار الصف الذي به DPC_EXT في النهاية


انقر نقرًا مزدوجًا للدخول إلى الفصل نفسه

6) بعد الدخول في قائمة طرق الفصل ، في النهاية تشاهد قائمة بجميع الطرق ، تأكد من إعادة تعريفها ، وإلا بعد التغيير التالي في نموذج البيانات ، سيتم محو كل شيء ، لقد صادفت هذا ، كان مهينًا ...


على سبيل المثال ، سوف أعرض تنفيذ طريقة الإنشاء



كل شيء بسيط للغاية ، IT_KEY_TAB يتم إدخاله في الإدخال واستناداً إلى هذه البيانات ، نقوم بتنفيذ بعض الإجراءات ، في هذا الرمز ، سجل عادي في الجدول ، أو إخراج خطأ ، والذي سيتم نقله بعد ذلك إلى Django. تتم كتابة إخراج الإنشاء الناجح إلى بنية ER_ENTITY.

7) اختبار واجهتنا في المعاملة / IWFND / MAINT_SERVICE ، واحدة طويلة. نذهب إلى ذلك ، والعثور على فصلنا والنقر على "عميل بوابة SAP"



لقد تم فتحنا بشكل أساسي باستخدام أداة محاكاة طلبات الويب GET \ POST \ PUT \ DELETE ، فقط من SAP ،

ملاحظة: يمكنك اختبار الخدمة التي تم إنشاؤها في أي شيء. أنا أختبر في برنامج ساعي البريد



هذا ما يبدو عليه طلب الحصول على "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
الآن نحن بحاجة إلى إحياء كل شيء ، ومن جانب جانغو نكتب الأساليب:

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). بعد نقل البيانات إلى نظام تخطيط موارد المؤسسات ، يحفظ النظام أيضًا جميع البيانات إلى المستودع ، والمعرف الذي جاء ، ونوع المعرف ، ومن قبله ، وما إلى ذلك.

نتيجة لذلك ، لدينا برنامج لمعالجة معرّفات المنتجات الواردة والصادرة في الشركة ، في حين يتم تنفيذ 90٪ من جميع الأعمال بدقة في نظام خارجي متكامل مع النظام الرئيسي.

في المستقبل ، يحتاج الأمر إلى وضع اللمسات الأخيرة لصيانة الدُفعات الواردة والأرقام التسلسلية وأشياء أخرى ، وحتى أقرب للتكامل مع SAP ، على سبيل المثال ، لإنشاء معاملة استلام من هذه الواجهة ، حسنًا هذه فكرة للتطوير :)

ملاحظة: لم أرسم رمز ABAP أو python-django لحل العمل هذا ، ولم أرسم إعدادات قالب Django أو html ، ولكني ركزت على التكامل مع SAP ERP لإظهار أن إنشاء وحدة للاتصال بمثل هذا النظام الكبير مثل SAP ليس أمرًا صعبًا ذهبت إلى مثل هذا النظام ، إذا أدرجنا دراسة Django لحوالي 4 أمسيات.

شكرا لكم جميعا على اهتمامكم ، وسأكون ممتنا للنقد البناء!

Source: https://habr.com/ru/post/ar426611/


All Articles