关于crm:SAP-数据库表CRMDORDERADMI字段OBJECTTYPE的计算逻辑

In order to resolve one issue I need to figure out the logic how field OBJECT_TYPE is populated in table CRMD_ORDERADM_I.For example, I have the following opportunity line item: In table this field is marked as BUS20000130. How this value is determined? First of all, the item category OPPT is determined by the following customizing: In my example, my opportunity type is OPPT and item category configured in product “JerryWang” is NORM, so OPPT is determined as customizing.for item category OPPT, BUS20000130 is configured as item object type here: ...

August 24, 2020 · 1 min · jiezi

关于crm:无法添加某个relationship给SAP-CRM-Product-category的一个可能原因

For example, I would like to test relationship type STRSET and then I plan to add it to product category 00001. However, in available drop down list, I could not see relationship type STRSET. Why? When debugging the backend logic to render relationship type drop down list entries, I found there is a check implemented by the function module below, to avoid a relationship is assigned more than once. ...

August 24, 2020 · 3 min · jiezi

关于crm:如何找到ABAP里被动态调用的update-function-module

In this SCN discussion,Find a Function Module in Update Task dynamically called,a question is asked. For example, if the update function module CRM_PRODUCT_I_UPDATE_DU is called statically as:CALL FUNCTION ‘CRM_PRODUCT_I_UPDATE_DU’ … Then we can easily find all calling places where this function module is called.On the other hand, if the function module name is determined dynamicall in the runtime, for example: CALL FUNCTION lv_func_name, the where used list will not work.In this case, even though I have already set the breakpoint in update function module itself and the breakpoint is triggered in the runtime, I still could not figure out which programs calls this update function module. ...

August 24, 2020 · 1 min · jiezi

关于crm:SAP-CRM-Product-hierarchyCategory和Application的三个问题

All of these three questions are raised regarding the customizing below via tcode COMM_PRAPPLCAT: Question1: Product search supports “search by category id”. However, we can assign different categories with same id on different product hierarchies. See example below: Question 1: the category id search will only touch categories assigned to a specific hierarchy, or will simply touch all categories with id “ZJERRY” regardless of their assigned hierarchies? ...

August 24, 2020 · 2 min · jiezi

关于crm:SAP-CRM-One-Order-header-extension的缓存机制设计原理

In one of my previous blog A small tip to analyze code by code and export to markdown format it is introduced that the following header extension are supported in One order read function module CRM_ORDER_READ. When the given header extension is read via CRM_ORDER_READ, take OPPORT_H for example: DATA: lt_header_guid TYPE crmt_object_guid_tab, lv_guid TYPE crmt_object_guid, lv_object_id TYPE CRMT_OBJECT_ID_DB value '21', lt_oppt TYPE CRMT_OPPORT_H_WRKT, lt_partner TYPE crmt_partner_external_wrkt.START-OF-SELECTION.CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT' EXPORTING input = lv_object_id IMPORTING output = lv_object_id. SELECT SINGLE guid INTO lv_guid FROM crmd_orderadm_h WHERE object_id = lv_object_id AND process_type = 'CXOP'. CHECK sy-subrc = 0. APPEND lv_guid TO lt_header_guid. CALL FUNCTION 'CRM_ORDER_READ' EXPORTING it_header_guid = lt_header_guid IMPORTING* et_partner = lt_partner et_opport_h = lt_oppt.The calling hierarchy could be found from below: ...

August 24, 2020 · 2 min · jiezi

关于crm:SAP-CRM-One-Order函数CRMObjectFILLOW的设计原理

题目:SAP CRM One Order函数CRM_<Object>_FILL_OW的设计原理There are totally 60 function modules in One order with naming convention CRM_<Object>_FILL_OW: They are NOT used in read scenario but in modify scenario. For example once you change the Closing Date of a given opportunity in WebUI ( from 2017-02-15 to 2017-02-16 ) The function module for Opportunity header extension, CRM_ORDERADM_H_FILL_OW, is called with the following callstack: As its name FILL_OW indicates, it is responsible to FILL the latest input by consumer into so called object work area( OW ) for later use.In order to make the research life easier I write the following report to trigger this FILL_OW function module call from backend: ...

August 24, 2020 · 3 min · jiezi

关于crm:SAP-CRM-One-Order函数SAVEEC的设计原理

In previous blogs the READ and UPDATE logic of Opportunity header field Closing Date are explained: Buffer logic in One Order header extension readLogic of FILL_OW function module in One OrderLogic of CHANGE_OW function module in One OrderIn this blog we will research what happens when end user clicks save button after Closing Date is changed in WebClient UI.This time we use naming convention CRMSAVE_EC to list the function modules which will be responsible to trigger the persistence of the change into corresponding database table. ...

August 24, 2020 · 3 min · jiezi

关于crm:SAP-CRM-One-Order函数CREATEOW的设计原理

In the previous series of blogs the read and update on Opportunity header fields are discussed. In this blog another scenario will be explained: create scenario on Opportunity header fields. I will again use Closing Date ( and description field ) for example.Execute the following report: REPORT ZORDER_CREATE.DATA: lt_input_fields TYPE crmt_input_field_tab, ls_input_field LIKE LINE OF lt_input_fields, ls_field_name LIKE LINE OF ls_input_field-field_names, lv_guid TYPE guid_16, lt_orderadm_h_com TYPE crmt_orderadm_h_comt, ls_orderadm_h_com LIKE LINE OF lt_orderadm_h_com, ls_com_structure TYPE string, lv_selection_needed TYPE crmt_boolean, lt_save TYPE crmt_object_guid_tab, lt_saved TYPE crmt_return_objects, lt_opp_h TYPE CRMT_OPPORT_H_COMT, ls_opp_h LIKE LINE OF lt_opp_h, ls_saved LIKE LINE OF lt_saved.START-OF-SELECTION. CALL FUNCTION 'GUID_CREATE' IMPORTING ev_guid_16 = lv_guid. PERFORM call_order_maintain. PERFORM call_order_save.FORM call_order_maintain. CLEAR: ls_orderadm_h_com, ls_input_field, lt_input_fields. ls_orderadm_h_com-guid = lv_guid. ls_orderadm_h_com-description = 'created by code on:' && sy-timlo. ls_orderadm_h_com-process_type = 'OPPT'. ls_orderadm_h_com-mode = 'A'. APPEND ls_orderadm_h_com TO lt_orderadm_h_com. ls_input_field-ref_guid = lv_guid. ls_input_field-ref_kind = 'A'. ls_input_field-objectname = 'ORDERADM_H'. ls_field_name-fieldname = 'DESCRIPTION'. APPEND ls_field_name TO ls_input_field-field_names. ls_field_name-fieldname = 'MODE'. APPEND ls_field_name TO ls_input_field-field_names. ls_field_name-fieldname = 'PROCESS_TYPE'. APPEND ls_field_name TO ls_input_field-field_names. APPEND ls_input_field TO lt_input_fields. ls_opp_h-ref_guid = lv_guid. ls_opp_h-expect_end = '20170401'. APPEND ls_opp_h TO lt_opp_h. CLEAR: ls_input_field. ls_input_field-ref_guid = lv_guid. ls_input_field-ref_kind = 'A'. ls_input_field-objectname = 'OPPORT_H'. APPEND 'EXPECT_END' TO ls_input_field-field_names. APPEND 'STARTDATE' TO ls_input_field-field_names. INSERT ls_input_field INTO TABLE lt_input_fields. CALL FUNCTION 'CRM_ORDER_MAINTAIN' EXPORTING IT_OPPORT_H = lt_opp_h CHANGING ct_orderadm_h = lt_orderadm_h_com ct_input_fields = lt_input_fields EXCEPTIONS OTHERS = 99. IF sy-subrc = 0. WRITE:/ 'Order maintain function is done successfully.'. ENDIF.ENDFORM.FORM call_order_save. INSERT lv_guid INTO TABLE lt_save. CALL FUNCTION 'CRM_ORDER_SAVE' EXPORTING it_objects_to_save = lt_save iv_update_task_local = abap_true iv_no_bdoc_send = abap_true IMPORTING et_saved_objects = lt_saved EXCEPTIONS document_not_saved = 1. IF sy-subrc <> 0. WRITE: / 'Opportunity created failed'. ELSE. READ TABLE lt_saved INTO ls_saved INDEX 1. WRITE: / 'Opportunity created successfully, id: ' , ls_saved-object_id. ENDIF. COMMIT WORK AND WAIT.ENDFORM.Once executed, a new Opportunity will be created. ...

August 24, 2020 · 4 min · jiezi

关于crm:显示SAP-CRM-Product-hierarchy的一个小工具

Recently I start to study SD and I found the product hierarchy in transaction code V/76 could not be viewed in tree style and it is not so convenient to check: So I wrote a simple report to retrieve hierarchy data from table T179 and display the data in a tree as below: The source code of report is listed below: REPORT zdisplay_hierarchy.DATA: g_alv_tree TYPE REF TO cl_gui_alv_tree, gt_data TYPE STANDARD TABLE OF zcl_alv_tool=>ty_displayed_node, ok_code LIKE sy-ucomm, save_ok LIKE sy-ucomm, ls_data LIKE LINE OF gt_data.END-OF-SELECTION. DATA(lo_tool) = NEW zcl_alv_tool( ). DATA(lt_fieldcat) = lo_tool->get_fieldcat_by_data( ls_data ). PERFORM change_label. CALL SCREEN 100.MODULE pbo OUTPUT. SET PF-STATUS 'MAIN100'. SET TITLEBAR 'MAINTITLE'. IF g_alv_tree IS INITIAL. PERFORM init_tree. CALL METHOD cl_gui_cfw=>flush EXCEPTIONS cntl_system_error = 1 cntl_error = 2. ASSERT sy-subrc = 0. ENDIF.ENDMODULE. " PBO OUTPUTMODULE pai INPUT. save_ok = ok_code. CLEAR ok_code. CASE save_ok. WHEN 'EXIT' OR 'BACK' OR 'CANC'. PERFORM exit_program. WHEN OTHERS. CALL METHOD cl_gui_cfw=>dispatch. ENDCASE. CALL METHOD cl_gui_cfw=>flush.ENDMODULE. " PAI INPUTFORM change_label. READ TABLE lt_fieldcat ASSIGNING FIELD-SYMBOL(<id>) INDEX 1. <id>-seltext = <id>-reptext = <id>-scrtext_m = <id>-scrtext_s = <id>-scrtext_l = 'Hierarchy ID'. <id>-outputlen = 20. READ TABLE lt_fieldcat ASSIGNING FIELD-SYMBOL(<text>) INDEX 2. <text>-seltext = <text>-reptext = <text>-scrtext_m = <text>-scrtext_l = 'Description'. <text>-scrtext_s = 'Text'. <text>-outputlen = 40.ENDFORM.FORM init_tree. g_alv_tree = lo_tool->get_tree( ). DATA l_hierarchy_header TYPE treev_hhdr. PERFORM build_hierarchy_header CHANGING l_hierarchy_header. CALL METHOD g_alv_tree->set_table_for_first_display EXPORTING is_hierarchy_header = l_hierarchy_header CHANGING it_fieldcatalog = lt_fieldcat it_outtab = gt_data. PERFORM create_tree. g_alv_tree->frontend_update( ). lo_tool->expand( ).ENDFORM.FORM create_tree. DATA(lt_data) = lo_tool->get_hierarchy_data( ). lo_tool->draw_tree( lt_data ).ENDFORM. " init_treeFORM build_hierarchy_header CHANGING p_hierarchy_header TYPE treev_hhdr. p_hierarchy_header-heading = 'Material hierarchy'. p_hierarchy_header-width = 30. p_hierarchy_header-width_pix = ' '.ENDFORM. " build_hierarchy_headerFORM exit_program. LEAVE PROGRAM.ENDFORM. " exit_programIn order to use the report, all you need is to just create a new screen : ...

August 23, 2020 · 2 min · jiezi

关于crm:SAP-CLCRMBOLENTITY单元测试方法

In SAP standard development it is very important to use unit test to cover those changes on legacy code to try to avoid side effect. As type reference CL_CRM_BOL_ENTITY is widely used in UI component code, I would like to find a way to construct its reference by sample data. The normal way we get instance of CL_CRM_BOL_ENTITY is, to use query or dquery method provided in class CL_CRM_BOL_CORE, which return a BOL collection list and then we can get each bol entity from by iterating that collection. However, both of these methods will perform database scan and return found data – such behavior is not appropriate for unit test.I have gone through all public methods in CL_CRM_BOL_CORE and do not find a useful method to construct bol entity based on sample data, so I write a small piece of code: ...

August 23, 2020 · 2 min · jiezi

关于crm:SAP-CRM状态字段下拉列表里数据的填充原理

In my previous blog How is status drop down list entry generated in Order detail page I research how the status drop down list entries are generated without any status profile assigned to transaction type. In this blog let’s take things one step further, to figure out the logic of drop down list where the status profile is assigned. I copy a standard transaction type SRVO into ZSRV and assign a profile CRMOPPOR to it. ...

August 23, 2020 · 4 min · jiezi

关于crm:SAP-CRM订单状态管理的一些重要的数据库表

I record down my self study notes here in order to be used in the future. TJ01: Business Transactions definitionTJ02: System status definition. For some of entries in this table, the corresponding constants are defined in include CRM_STATUS_CON TJ03: status object type definition. Storage table for tcode BS12, see screenshot below: TJ04: define initial status for system object. For example, I1002 ( open ) is defined as initial status for status object COH ( CRM Order Header ). Due to this setting, every time you create an order, it always has open as initial status. ...

August 23, 2020 · 3 min · jiezi

关于crm:如何使用UI-Configuration将WebClient-UI的隐藏字段放出来

In Service order detail page some fields are by default hidden in standard UI configuration, for example fields belonging to pricing set ( backend storage table: CRMD_SHIPPING ). Here below is step by step how to create a new UI configuration and make those hidden fields visible there. (1) Create a new business role by copying from existing one: (2) Create a new Role Configuration Key: ...

August 23, 2020 · 1 min · jiezi

关于crm:如何使用ABAP-open-SQL的locator

Recently I learned a new approach to access database table content without having to transport the column data into ABAP program using locator. There is a sample program provided in SAP help. I make modifications on this sample. The modified one: REPORT demo_db_locator.DATA: otr_text_locator TYPE REF TO cl_abap_db_c_locator, length TYPE i.DATA: pattern TYPE string VALUE 'ABAP', lv_index TYPE int4 VALUE 1.zcl_abap_benchmark_tool=>start_timer( ).TRY. SELECT text FROM sotr_textu WHERE langu = @sy-langu INTO @otr_text_locator. length = length + otr_text_locator->get_length( ). IF otr_text_locator->find( start_offset = 0 pattern = pattern ) <> -1. lv_index = lv_index + 1. ENDIF. otr_text_locator->close( ). ENDSELECT. CATCH cx_lob_sql_error. WRITE 'Exception in locator' COLOR = 6. RETURN.ENDTRY.zcl_abap_benchmark_tool=>stop_timer( ).WRITE: / 'total length:', length, ' matched for ABAP:', lv_index.zcl_abap_benchmark_tool=>print_used_memory( ).CLEAR: otr_text_locator.zcl_abap_benchmark_tool=>gc( ).zcl_abap_benchmark_tool=>print_used_memory( ).So this report just calculates the total number of records in table sotr_textu in which the data of column “text” ( type String in ABAP dictionary ) has a substring of “ABAP”, and meantime calculate the total length of text fields from all table records. ...

August 23, 2020 · 4 min · jiezi

关于crm:给SAP-WebClient-UI的表格行项目增添PDF预览功能

In CRM UI by default the PDF preview is only available in document header level. For example once PDF Fact Sheet is clicked, the PDF is displayed in a popup window. Suppose there are lots of document to be previewed as a PDF, you have to enter to overview page of each and preview there. A more efficient way is the preview functionality can be directly available in search result table as “One Click Action(OCA)”. This blog will explain the main required steps. ...

August 23, 2020 · 3 min · jiezi

关于crm:SAP-CRM订单模型CRMDSHIPPING的单元测试方法

For example the following shipping fields of One order document are stored in Database table CRMD_SHIPPING. The data could be read out via function module CRM_SHIPPING_READ_OB. This blog introduces the step how to generate fake data which will be returned by function module CRM_SHIPPING_READ_OB for unit test purpose. Step1. Create fake data in Shipping object buffer DATA: ls_shipping TYPE crmt_shipping_wrk.DATA: lv_order_guid TYPE crmt_object_guid, lv_ship_guid LIKE lv_order_guid, lt_link_com TYPE crmt_link_comt, ls_link_com LIKE LINE OF lt_link_com.CALL FUNCTION 'GUID_CREATE' IMPORTING ev_guid_16 = lv_order_guid.CALL FUNCTION 'GUID_CREATE' IMPORTING ev_guid_16 = lv_ship_guid.ls_shipping-incoterms1 = 'FOB'.ls_shipping-incoterms2 = 'Jerry Fake incoterms'.ls_shipping-guid = lv_ship_guid.CALL FUNCTION 'CRM_SHIPPING_PUT_OB' EXPORTING is_shipping_wrk = ls_shipping.Step2. Create a link between Order and shipping data via function module CRM_LINK_CREATE_OW ...

August 23, 2020 · 1 min · jiezi

关于crm:SAP-CRM服务订单页面显示组织结构管理区域的实现逻辑

题目:Why I could not see Organizational management assignment block in Service Order Overview Page For example I can see this assignment block for Sales order: However in service order overview page, this assignment block is missing: I checked the configuration in UI component BT116H_SRVO and this assignment block is already there: Unfortunately it still does not appear in the Available Assignment Blocks list when personalization button is clicked. So this view must be filtered out in the runtime based on some rules. ...

August 23, 2020 · 2 min · jiezi

关于crm:SAP-CRM索引数据库表CRMDORDERINDEX的更新原理

For project reason I need to figure out the logic how fields in index table CRM_ORDER_INDEX are updated.For example, I have an opportunity with ID 21 and closing date 2017.03.25. I get its guid 6C0B84B759DF1ED6BDF05763B3DC8841 from CRMD_ORDERADM_H and query CRM_ORDER_INDEX with this guid against field HEADER, 2 records found: Most of the fields in these two records have the same value except fields like PARTNER_NO, which represent the two involved parties as found in WebUI: ...

August 23, 2020 · 3 min · jiezi

关于crm:如何使用代码修改SAP-CRM-One-Order-CUMULATH对象的值

In Logic of CRMD_CUMULAT_H I learned the fact that gross weight of an order is calculated based on all its line item. Recently in my project I have the requirement to modify the gross weight of an order directly via ABAP code. I check the importing parameter of FM and don’t find the corresponding parameter for CUMULAT_H. After research I have written the below report: REPORT zchange_cumulat_h.PARAMETERS: quantity TYPE int4 OBLIGATORY DEFAULT 1, item TYPE crmd_orderadm_i-number_int OBLIGATORY DEFAULT 20, srvo_id TYPE crmd_orderadm_h-object_id OBLIGATORY DEFAULT '5700000242'.CONSTANTS: cv_sales_item TYPE crmt_subobject_category_db VALUE 'BUS2000131'.DATA: lv_srvo_guid TYPE crmd_orderadm_h-guid, lt_to_save TYPE crmt_object_guid_tab, lt_saved TYPE crmt_return_objects, lv_schedule_guid TYPE crmt_object_guid, lt_schedule_line TYPE crmt_schedlin_i_comt, lt_schedule_detail TYPE crmt_schedlin_extdt, ls_schedule_detail LIKE LINE OF lt_schedule_detail, ls_schedule_line LIKE LINE OF lt_schedule_line, lt_changed_fields TYPE crmt_input_field_tab, ls_changed_fields LIKE LINE OF lt_changed_fields, lt_orderadm_i TYPE TABLE OF crmd_orderadm_i.START-OF-SELECTION.SELECT SINGLE * INTO @DATA(ls_header) FROM crmd_orderadm_h WHERE object_id = @srvo_id.CHECK sy-subrc = 0.SELECT SINGLE * INTO @DATA(ls_cum_h) FROM crmd_cumulat_h WHERE guid = @ls_header-guid.CHECK sy-subrc = 0.lv_srvo_guid = ls_header-guid.WRITE:/ 'Old gross weight', ls_cum_h-gross_weight COLOR COL_GROUP.PERFORM print_gross_weight_detail.SELECT * INTO TABLE lt_orderadm_i FROM crmd_orderadm_i WHERE header = lv_srvo_guid AND object_type = cv_sales_item.CHECK sy-subrc = 0.READ TABLE lt_orderadm_i ASSIGNING FIELD-SYMBOL(<sales_item>) with key number_int = item.IF sy-subrc <> 0. WRITE:/ 'Cannot find line item for item id:', item. RETURN.ENDIF.SELECT SINGLE guid INTO lv_schedule_guid FROM crmd_schedlin WHERE item_guid = <sales_item>-guid.CHECK lv_schedule_guid IS NOT INITIAL.ls_schedule_line-ref_guid = <sales_item>-guid.ls_schedule_detail-guid = ls_schedule_detail-logical_key = lv_schedule_guid.ls_schedule_detail-item_guid = <sales_item>-guid.ls_schedule_detail-mode = 'B'.ls_schedule_detail-quantity = quantity.APPEND ls_schedule_detail TO ls_schedule_line-schedlines.APPEND ls_schedule_line TO lt_schedule_line.ls_changed_fields-ref_guid = <sales_item>-guid.ls_changed_fields-ref_kind = 'B'.ls_changed_fields-objectname = 'SCHEDLIN'.ls_changed_fields-logical_key = lv_schedule_guid.APPEND 'QUANTITY' TO ls_changed_fields-field_names.APPEND ls_changed_fields TO lt_changed_fields.CALL FUNCTION 'CRM_ORDER_MAINTAIN' EXPORTING it_schedlin_i = lt_schedule_line CHANGING ct_input_fields = lt_changed_fields EXCEPTIONS error_occurred = 1 document_locked = 2 no_change_allowed = 3 no_authority = 4.IF sy-subrc <> 0. WRITE: / 'error during quantity change'. RETURN.ENDIF.APPEND lv_srvo_guid TO lt_to_save.CALL FUNCTION 'CRM_ORDER_SAVE' EXPORTING it_objects_to_save = lt_to_save iv_update_task_local = abap_true IMPORTING et_saved_objects = lt_saved EXCEPTIONS document_not_saved = 1.IF sy-subrc <> 0. WRITE:/ 'Save failed'. RETURN.ENDIF.COMMIT WORK AND WAIT.SELECT SINGLE * INTO ls_cum_h FROM crmd_cumulat_h WHERE guid = ls_header-guid.CHECK sy-subrc = 0.WRITE: / 'New Gross weight after change:' COLOR COL_NEGATIVE, ls_cum_h-gross_weight.PERFORM print_gross_weight_detail.FORM print_gross_weight_detail. DATA: lt_product TYPE TABLE OF crmd_product_i, lt_item TYPE TABLE OF crmd_orderadm_i. SELECT * INTO TABLE lt_item FROM crmd_orderadm_i where header = lv_srvo_guid. CHECK lt_item IS NOT INITIAL. SELECT * INTO TABLE lt_product FROM crmd_product_i FOR ALL ENTRIES IN lt_item WHERE guid = lt_item-guid. LOOP AT lt_item ASSIGNING FIELD-SYMBOL(<item>). WRITE: / 'Item id:' COLOR COL_POSITIVE, <item>-number_int COLOR COL_HEADING. READ TABLE lt_product ASSIGNING FIELD-SYMBOL(<prod>) WITH KEY guid = <item>-guid. CHECK sy-subrc = 0. WRITE: / 'Item Gross Weight:' COLOR COL_POSITIVE, <prod>-gross_weight COLOR COL_GROUP. ENDLOOP.ENDFORM.How to use this report ...

August 23, 2020 · 3 min · jiezi

关于crm:SAP-CRM订单抬头级别的组织架构数据是如何自动拷贝到行项目的

Standard behavior: I have maintained Organizational management data in Service Order Header: And if we add a product to this service order as line item, the header organization data will automatically be copied to item. How this automatic data flow is achieved? Once the product IMU is maintained in item level, function module CRM_ORDER_MAINTAIN is triggered with following input: Within the callstack there is an event AFTER_CREATE raised against object ORDERADM_I: ...

August 22, 2020 · 2 min · jiezi

关于crm:使用SAP-CRM中间件从ERP下载plant到CRM

Requirement: You have performed initial download in CRM to download plants from ERP. Now you have made some further change on a given plant in ERP. You would like to synchronize those change back to CRM.You can maintain plant information in ERP: (1) create new download request in CRM via tcode R3AR2. In Low field, maintain plant ID in ERP as value: (2) perform request download via tcode R3AR4. ...

August 20, 2020 · 1 min · jiezi

关于crm:使用SAP-CRM中间件从ERP下载Customer的关于分销渠道的错误消息

Distribution channel is not allowed for sales organization I try to download customer material info record from ERP via request download.This is my download request created in tcode R3AR2: This is my customer material info record created in ERP: When I perform request download, I receive this error message in CRM tcode SMW01: I debug and found that the error message is raised in FM below, due to the failure match of Sales organization 50040102 and distribution chain 01: ...

August 20, 2020 · 1 min · jiezi

关于crm:使用SAP-CRM中间件从ERP下载Customer的错误消息

After I create a customer in ERP via tcode VD01 and try to download it into CRM via request download, I meet with the following error message:“Customer classification 06 does not exist” Through debugging I found this issue is raised in line 22 due to a missing configuration in table crmc_classif. The configuration for classification in CRM is done in this activity: In my CRM system, there is no corresponding entry for 06, as a result error message is raised. ...

August 20, 2020 · 1 min · jiezi

关于crm:使用SAP-CRM中间件从ERP下载plant到CRM

Requirement: You have performed initial download in CRM to download plants from ERP. Now you have made some further change on a given plant in ERP. You would like to synchronize those change back to CRM.You can maintain plant information in ERP: (1) create new download request in CRM via tcode R3AR2. In Low field, maintain plant ID in ERP as value: (2) perform request download via tcode R3AR4. ...

August 20, 2020 · 1 min · jiezi

关于crm:CRM如何与业务部门结合帮助企业建立良好的客户关系

CRM对企业来说比以往任何时候都重要,因为它能帮你播种新客户,保留现有客户。 胜利施行的CRM不仅能让公司洞察与每位客户倒退业务的机会,而且还能提供掂量机会价值的办法。 当一种新的产品进入市场,只有几个月,这个产品或服务就会忽然变成一种商品,这就意味着转换公司非常容易。在当今竞争强烈的环境中,客户忠诚度仿佛曾经成为过来。 在这样的状况下,CRM有助于在应答不同客户群体时确定销售和市场营销工作的优先程序。 此外,CRM能帮忙企业更好地了解客户须要和需要,改善产品组合的提供形式。你对客户、客户购买偏好和购买行为的理解越深,你的产品就越有可能感动客户。 CRM软件如何帮忙企业建设良好的客户关系? 1、反对以客户为核心的策略 CRM零碎反对这样一种策略,即客户是你所做所有事件的核心。这种以客户为核心的策略必须基于明确的指标以及对于什么是有意义的客户体验的愿景。有价值的客户体验是CRM不可或缺的一部分。客户每接触一个机构,不论是通过什么渠道,它都有机会造成好的、坏的或中立的观点。随着工夫的推移,这种客户体验的汇合在客户脑海中造成一幅画面,进而造成品牌形象及价值。 蹩脚的客户体验会导致客户散失,良好的客户体验会激励客户忠诚度,因而要慎重对待CRM的机构设计和放弃高质量的客户体验。 2、集中所有客户数据 CRM软件将所有销售、市场营销和客户服务的信息都整合到一个地方数据库中。 CRM收集的潜在客户及其相干数据包含但不限于电话号码、地址和最初一次接触,还记录探讨的内容,下一次随访日期,甚至是凋谢我的项目的状态。 这些信息随后可用于治理、掂量和跟踪与客户相干的市场营销、销售和客户服务流动。总的来说,CRM能够建设更高的客户忠诚度和营造更好的客户体验。 因为CRM零碎集中所有客户间接服务方面的信息,层级阻碍和相互指责大大降低。 销售部无奈指摘市场营销部没有与他们沟通。市场营销部无奈指摘销售部没有执行他们的营销流动,客户服务部不能指摘销售部不能让客户称心。 每个人都能获取雷同的客户信息,让你全方位地理解客户,因而有助于实现以客户为核心。 3、自动化客户间接服务业务流程 企业领有面向业务的流程和客户间接服务流程。 面向业务的流程是那些能使企业更无效运行的流程,如估算和打算。客户间接服务流程包含销售、市场营销和客户服务。 CRM策略次要关注客户间接服务流程,在满足客户需要的根底上优化流程。 (1)CRM业务流程改良 整个CRM流程从潜在客户开始。 一旦潜在客户输进零碎,CRM软件就会将其带入销售流程。例如,CRM零碎会揭示销售人员在约定的工夫打电话。每次你与潜在客户沟通时,都将其记录到CRM零碎中。这同样实用于其他人与潜在客户交谈的状况。 简而言之,CRM跟踪所有与潜在客户相干的口头。 与此同时,CRM是个会集文件、电话和电子邮件的图书馆。当你开始与潜在客户进行沟通,你会失去即时主动的沟通跟踪。这些信息位于核心地位,所以公司中任何人都能帮忙潜在客户摆脱困境。 无论你从事销售、市场营销还是客户反对,CRM零碎都能帮你实现特定业务流程的自动化,以及每个流程与其余流程合作形式的自动化。但毫无疑问,为了让公司获得良好的问题,每个业务流程都必须明确定义且有效率。 (2)客户间接服务流程自动化 潜在客户治理: 在潜在客户变成客户之前有一个残缺的流程。你须要辨认潜在客户,对其进行限定,而后能力将其转化为销售。 潜在客户来自多种渠道,你必须分明由谁负责这些潜在客户,并确认如何发送潜在客户信息以及如何跟踪潜在客户。 如果没有明确定义的流程(工作流),潜在客户可能会散失或被忘记,进而引发挫败感、销售生产力失落,甚至带来蹩脚的客户体验。 客户反对: 对于如何治理客户服务申请,应该有明确的规定。 这些规定规定了申请是转到一线反对还是二线反对,什么资源将用于解决客户问题,以及如何通过共享状态更新来确保问题失去解决。 一旦定义了工作流和规定,CRM零碎就能实现整个流程的自动化。 与此同时,CRM零碎保留所有联系人的历史记录,客户服务团队可随时查看,从而更好地理解如何帮忙客户,有利于进步客户满意度。 为了不便企业管理者治理销售和客户,8MSaaS CRM零碎实现全方位客户信息管理及精确营销,更短时间内达成更多交易。 零碎反对360° 客户视图,随时随地查看客户信息,还能够智能剖析客户偏好,精确投放营销信息。 作为销售团队的成员,零碎可帮忙你主动调配适合的销售代表,实时追踪商机跟进状况及掌控订单执行,实现销售治理自动化,团队成员的绩效与理论业务挂钩。 作为管理者,零碎为你提供一个全面的业务视图,智能治理产品,捕捉和存储不同类型的信息,深层剖析,理智决策。 为企业客户业务量身打造的8MSaaS CRM零碎能全方位治理客户,爱护企业资源不失落,疾速拓展业务。

August 20, 2020 · 1 min · jiezi

关于crm:科创人独家纷享销客林松创业是格局与思维的放大器

— 文| babayage 编辑 |笑    笑 **硅谷-深圳 ** 从后端到治理 从代码到市场 科创人:2002年的时候,您为何抉择回国倒退? 林松:当年在硅谷工作的华人工程师中,对于是否要回国倒退探讨得很强烈,显著分成了两派:抉择留在硅谷,比拟适宜纯技术向的敌人,工作稳固、前景明确,在美国大龄程序员遍地都是,“写代码写到老”又是很多技术人幻想中的生存模式;抉择归国,要面临诸多不确定性,齐全不同的工作气氛、更生疏的市场,以及一个微小的未知:中国的发展潜力到底有几许? 感动我回国的因素有两个,许多中央政府都出台了海归政策,尤其对于有肯定工作教训的技术型海归待遇堪称优厚,但这不是重点,更重要的是甲骨文中国研发核心设在了北京和深圳,我恰好是深圳人,还是心愿离家近点。 科创人:绝对于在硅谷的工作状态,回国后产生了哪些变动? 林松:我在硅谷时供职于甲骨文技术平台部,是一个偏后端的开发岗位,习惯了自定布局、自定周期的工作节奏,过后咱们一个中间件产品均匀迭代周期是1年半到两年。 归国后,成为了研发团队的管理者,要染指产品布局,频繁约见客户采集需要成了很重要的日常工作。很多客户对于本身的需要只有含糊认知,解决方案不是问题,帮忙客户精确了解本人的需要、精确匹配解决方案,反而须要更多的工夫。在客户的不确定性背后,业务周期、产品布局都展现出了不可控性,这是第一个挑战,更贴近业务、直面市场、更强调应变的布局。 另外,管理工作成为了重要的工作,尽管我之前也带过小团队,但一下从治理四五个人到二三十人,变动还是挺大。好在甲骨文的培训体系十分给力,一年下大略有六次承受来自寰球的专家封闭式培训的机会。在学习过程和实际中我逐步意识到,技术人员转型治理最重要的是调整思维,要丢掉对细节的执念,管指标、管进度、管绩效,还有尤为重要的一点:要有赋能团队的意识,这一点对我集体倒退影响微小。 最初,迟早也要谈到,回国之后与腾讯产生了交加,甲骨文的办公地点在深圳飞亚达大厦的16楼,这个大厦的3~10楼就是腾讯。 甲骨文-腾讯 TAPD之父,见证SOSO分合 科创人:您供职于甲骨文这样的国际级巨头期间,是如何对待腾讯这样的国内互联网企业的? 林松:年老、有暮气、娱乐化,产品绝对比较简单。在生存层面大家交加很多,坐电梯、吃饭都能遇到一起,但说实话很长一段时间里都感觉这些空间间隔很近的敌人,在某些方面却是最边远的,没想过能在事业上有交加。 起初机缘巧合,和腾讯的几位创始人深刻交换了几次,发现腾讯的将来布局清晰明确,并且极度求实,对腾讯的印象有了翻天覆地的改观。我逐步意识到,中国互联网企业在战术格调上与甲骨文们有着根本性的不同,但不存在高下之分,是在策略层面各有偏重。在2006年前后有些事件根本曾经造成了广泛共识:国内互联网企业在中国市场没有方法与国内互联网公司竞争,后者唯快不破,从idea到产品推向市场只有一个月,并且十分善于在市场侧采集需要倒逼产品迭代,要晓得对东方企业来说一个月还不够实现纸面上的产品构建。 科创人:从甲骨文加盟腾讯,单从字面来看,仿佛就有很多须要适应的货色? 林松:不开玩笑的说,光适应就用了大略半年。甲骨文强调的是谋定而后动,在布局层面充沛粗疏、周到、谨严,一旦推向市场就要在绝对较长的一段时间内稳固提供服务。而腾讯恰好相反,快想快做快试,快错了就快改,所有都强调速度。 科创人:在腾讯度过了大概9年的工夫,您认为这9年中本人成长最大的是什么? 林松:只提一点的话,应该是对治理有了更粗浅的理解,尤其是赋能与治理的关系。 加盟腾讯之初,本意是想退出到某个业务团队中,但随后被几位高层劝服,在腾讯外部搭建了项目管理部,负责晋升5个事业部的研发治理能力。我思考了一下,这份工作有机会把我所善于的先进治理办法付诸实践,还能多接触不同的我的项目、不同的人,挑战与趣味并举,决定试一试。 科创人:《科创人》采访过的嘉宾中,有几位已经表演过外部平台搭建者、服务者的角色,私下里都会反馈,这个工作比拟得罪人,五湖四海都是锅。腾讯高层决定让您去搭建这支团队,是否是看准了您在沟通交流方面的短处? 林松:这是一方面起因,决定任命我之后,顶层给我最大的反对就是带我挨个跟各个事业部的负责人吃饭(笑)。另外一个起因是我后面提过的,强调管控还是重视赋能,强制他人适应你还是低侵入感的帮忙对方晋升,都能实现近似的目标,但单干顺畅度而言天差地别。 我在腾讯研发管理部期间制订了4P治理策略,核心理念就是以赋能提效,不是以管控提效: Process,在腾讯外部建设对立的项目管理模式,引进麻利理念,还造就了一只项目管理参谋团队,以轮岗的模式一直打磨治理实际,帮忙各个团队赋能治理——这也是被挖角最狠的一只队伍(笑); Platform,我牵头制作了一款项目管理工具——TAPD,这是我很骄傲的一件作品,10多年过来了仍然是企业微信上的第一大利用,还有一个叫Knowledge Manager的社区,在企业外部时单日访问量破万,现在也在企业微信上凋谢了; People,配合内部征询参谋建设起了腾讯的职级布局,将集体的倒退布局与企业的员工造就联合为一; Patent,专利参谋,腾讯直到明天为止都是互联网公司中专利意识最强、专利数量最多的企业,因为外部有一只业余团队去帮忙各个事业部提炼、整顿、申请专利,建设知识产权层面的竞争劣势。 这三年工夫对我集体而言是成长速度最快的三年,接触到了全公司各个业务单元和简直全副的高级管理层,尽管挑战很大,但播种和成长也很大。这件事做得七七八八之后,高层和我都感觉,是时候退出到某个具体业务单元了。 科创人:是您被动提出要退出搜寻业务团队的吗? 林松:应该说是机会符合,腾讯晚期的搜寻业务始终是OEM谷歌,2009年腾讯自研的搜索引擎上线,搜寻业务进入了独立发展期,公司决定加大对搜寻业务的投入,因而调动了大量高级人才汇聚于搜寻业务单元。 相比于研发事业部期间是在某一个专精畛域内晋升拓展能力,在搜寻业务部我轮岗了很多岗位,开辟了本人横向的能力边界,比方市场、PR、品牌宣传,这些彻底解脱了研发属性的工作极大晋升了事业、拓展了思维边界、补全了各个领域的常识信息,形成了我起初决定退出到一个守业团队的底气。 纷享销客 是事业,也是人生 2009年,林松退出搜搜,同年搜搜自研引擎上线 2013年9月,腾讯将搜搜并入搜狗 2015年,林松陪伴搜搜团队实现了与搜狗的交融后到职 2020年8月,搜狗收到了腾讯的非约束性收买要约 分久必合,合久必分。 科创人:技术人成长过程中,35~40岁的抉择是要害一跃,简直决定了本人将来的人生走势。当您决定退出纷享销客的时候,是否思考过本人接下来的成长指标? 林松:(思忖片刻)仿佛没有,但认真想想,守业其实就是将一个事业当作本人人生的一部分,成就它的同时也是自我成长、自我实现的过程。 守业跟打工是两种齐全不同的体验,开车的敌人都晓得,车可能拓展人的空间感和速度感,守业也是相似的感觉,在一直推动、欠缺一个创业项目的过程中,个体的认知、思维、格局,都被事业放大了,对人生的认识会有翻天覆地的变动。 回忆起甲骨文和腾讯的那些经验,总能想起来很多本人的事件,然而纷享销客这些年下来,能回想起来的都是公司的重大事件和重要节点。 比方纷享销客最后对标的Yammer这种企业级协同工具,但钉钉和企业微信的横空出世颠覆了这一畛域的免费模式,我仍记得本人听到钉钉和企业微信进入这一畛域时的情绪,好在纷享销客早早布局CRM业务场景,能力及时调整策略方向。 反而我本人在什么时候做了哪些具体的工作,记忆有些含糊了。 科创人:以您的资格,可抉择的守业团队想必不少,抉择纷享销客是出于怎么的考量? 林松:有比拟事实的起因,纷享销客过后正处于疾速发展期,在资本市场失去了很高的认可度;更要看前景,我认为中国的生产互联网曾经倒退到了寰球顶尖的程度,两相比拟,企业级互联网该当在将来5到10年有很大的倒退——当然5年过来了,这个畛域仍然有很大的后劲。 第三,也是最重要的,是罗旭(纷享销客创始人兼CEO)的诚意。咱们意识很早,但当初我并不知道本人是他潜在的考查对象(笑),最后只是以敌人的身份给他提提意见、互通有无。起初他跟我说,他看好一个人才就得像谈恋爱一样,非要追到身边才行。 科创人:作为中国To B服务畛域成长速度最快、也是竞争最强烈的CRM赛道领跑者之一,这些年遭逢到的最大挑战是什么? 林松:高度个性化造成的千企千面,这是CRM创业者在技术层面面临的最大挑战。企业服务的其余畛域,比方招聘有最佳实际规范模板,绩效是固定周期、固定节奏,但销售齐全不一样,千企千面是CRM服务的外围诉求。因而咱们在后退过程中做出了“必须做PaaS”的决策,如果每一个共性需要都要用代码级开发实现的话,产品将十分难以保护,并且短少灵活性。 第二个挑战是挪动化,CRM服务必须要在挪动端建设竞争劣势,在挪动端这一侧又要面临ios、安卓的原生化开发,以及种种机型适配性的问题。 科创人:在您看来,CRM赛道将来面临的技术挑战有哪些? 林松:首先是行业化,不仅是产品的积攒,更是对客户业务和行业解决方案的洞察和积攒,这是将来倒退的外围重点。 第二是智能化,CRM在将来5~10年中,会逐步降级为帮忙企业进行战略决策的智能平台,它能提供智能化的业务评估,判断客户的价值和成交概率,预测产品销量……智能化与CRM业务联合是技术发力的重点。 第三是连贯化,CRM不再只是企业销售人员应用的工具,它会倒退为企业全员、企业合作伙伴独特应用的工具。 ...

August 17, 2020 · 1 min · jiezi

关于crm:SAP-CRM产品主数据页面的缩略图显示设计原理

In CRM Product UI, A thumbnail could be displayed in Product header and Thumbnail assignment block. The Thumbnail assignment block is not available in SAP predefined UI configuration. Customer needs to manually make it visible via UI configuration change: The thumbnail view implementation itself is very simple, just use the lib thtmlb image tag. The thumbnail view implementation itself is very simple, just use the lib thtmlb image tag. ...

August 6, 2020 · 1 min · jiezi

关于crm:使用代码修改SAP-CRM附件的属性

In our CRM social integration project we extract the picture of one tweet from twitter website and store them in CRM system as attachment. We are creating attachment in CRM via the approach described in this blog. However, we found the Create by property for an attachment is always hard coded with sy-uname, even we explicitly specify the created_by property when callingcl_crm_documents=>create_with_table. However our requirement is it should be filled by the screen name in twitter website who posts the tweet. ...

August 6, 2020 · 2 min · jiezi

关于crm:SAP-CRM-IDOC的详尽调试步骤

(1) Trigger the IDOC sending using tcode R3AS Choose the receiver destination site from f4 help: Click f8 to execute the sending. (2) Launch tcode SMQ2 to check inbound QRFC queue, you should find one entry for our R3AS run in step1. Double click on it: Then double click it again, choose the entry for FM BAPI_CRM_SAVE and click debug icon: ...

August 6, 2020 · 2 min · jiezi

关于crm:如何启用SAP-CRM附件UI上的advanced按钮

As the steps are a little bit tricky, I use the working UI component SMCOV and SMCCMBO to illustrate. After Advanced button is clicked: Step1: The navigation link of SMCCMBO is triggered, navigation link 2ADDDOC: So define the similar navigation link with EXACTLY the NAME 2ADDDOC in your own wrapper component like SMCCMBO: Since the navigation target is SMCCMBO/MainWindow, its inbound plug 2ADDDOC will be called: ...

August 6, 2020 · 1 min · jiezi

关于crm:SAP-CRM和Twitter以及facebook的社交媒体集成方案

Our team has already integrated Twitter ( also Facebook ) into interaction center in CRM7.0 EHP3.You can see an example below:Create a tweet in twitter website:Now I can see the tweet created just now in the web site. And I can also see it in CRM IC agent inbox: select the first row and I can directly reply it in CRM by clicking reply button: ...

August 2, 2020 · 2 min · jiezi

关于crm:在SAP-CRM-WebClient-UI里打开ABAP-Webdynpro页面

Hi Friends, in my recent customer project customer complains to me that they can not navigate from the workflow search result to the target UI. The workflow work item is a document generated via SAP document builder. They would like to navigate to the document detail page and then decide whether to approve the document or not. With SAP standard solution so far in CRM7.0 EHP3, this is not possible since this work item does not have any BOR type but instead modeled via ABAP class /IPRO/CL_WFL_DOCUMNT. What’s more, the target document page is built via ABAP webdynpro which has not respective concept like UI object type, Genil component or BOL object name. ...

August 2, 2020 · 2 min · jiezi

关于crm:在SAP-CRM-WebClient-UI里打开ABAP-Webdynpro页面

Hi Friends, in my recent customer project customer complains to me that they can not navigate from the workflow search result to the target UI. The workflow work item is a document generated via SAP document builder. They would like to navigate to the document detail page and then decide whether to approve the document or not. With SAP standard solution so far in CRM7.0 EHP3, this is not possible since this work item does not have any BOR type but instead modeled via ABAP class /IPRO/CL_WFL_DOCUMNT. What’s more, the target document page is built via ABAP webdynpro which has not respective concept like UI object type, Genil component or BOL object name. ...

August 2, 2020 · 2 min · jiezi

科创人独家销售易CTO张忠做产品不是翻译需求用户思维绝非满足一切

文| babayage 编辑 |笑 笑 本次越洋连线之前,《科创人》对John的理解,仅限于一份由世界级企业小名串联成的富丽简历。信息匮乏、筹备有余导致的缓和,却在第一分钟就被John化于有形,他领有一种由有趣、谦虚、健谈、酷爱分享形成的亲和力。 John其人 · 毕业于中国科学技术大学,业余并非计算机而是工程。短跑专长,5000米、10000米在大学时常年放弃在前5名。 · · 酷爱短跑与性情无关:急躁,不急于求成,违心付出更多辛苦、更多工夫深耕于某一畛域。 · · 加州大学伯克利分校IEOR(工业工程与运筹学)硕士学位——IEOR因其十分不错的待业抉择与就业率火爆至今。 · · 毕业后,先后任职于华为硅谷分部、SAP、AT&T Bell实验室、美国国家宇航局(NASA)工作。 · · 应聘AT&T Bell实验室同时,当年仅20人规模的eBay发来Offer,CTO亲自邀约,John非常打动并礼貌拒绝:“过后想的是Bell Lab多牛呀……要是选了eBay,兴许我当初能做更多的事(笑)。” · · 退出SAP的三个理由:与本人的业余符合度更高;钦佩德国人谨严、业余的做事态度;太太在SAP(请列位看官自行判断权重)。 · · 退出SAP培训时,讲师说:CRM对于技术创新有很高要求,技术改革频次与颠覆水平显著超过ERP,对技术人而言是一条乐趣与挑战兼具的赛道,“20多年体验下来,的确如此”。 · · 在SAP从事CRM相干工作长达18年,参加并领导了SAP三代CRM产品的研发,曾任SAP Cloud for Customer部门研发副总裁,负责SAP云解决方案的技术体系,波及ByD、Cloud for Customer和Travel等产品从零到市场竞争力的全面构建,以及在挪动、剖析和商务智能、云计算等多方面的利用开发,领导在美国、德国和印度的全球化研发团队。 · · 领有近20项专利,在国内期刊上发表多篇技术论文。 · · 来到SAP加盟销售易的起因:“陆奇窘境”,华人技术高管在国内大型企业中的倒退下限;看好中国To B产业,认为中国注定将诞生世界级的To B企业;销售易基于腾讯生态之上的微小设想空间以及技术挑战。 · · 在SAP任职期间,John的下属、也是他的好友对他说过这样一句话:“技术人须要深刻理解三件事:你的产品,你的雇员,你的客户。能吃透一点就足够杰出,三方面都有很高造诣的技术人更是百里挑一。” · · 这句话成为了John鞭策自我成长的座右铭,《科创人》邀请John将这三点别离做了简略分享。 · 产品思维:深刻理解transformation 科创人:销售易已间断多年入选 Gartner SFA 寰球魔力象限,2019 年,销售易还入选 Gartner 寰球 aPaaS 举荐供应商名单,是否分享一下您对于产品的底层理念? John:技术人犯的谬误其实我都犯过,写出过“日抛型”的产品,在写完的那一刻就要被扔掉,还有闭门造车等等。在一次又一次的教训中,我感悟到的是:优良的产品可能帮忙客户实现信息化、数字化转型——transformation,不是translation,不能简略地将需要翻译为技术产品。 以CRM为例,如果产品只是对客户需要的直白翻译,那要如何去撑持5000个客户的个性化需要和变动?前几天和一个世界100 强客户聊天的时候,对方说:当初业务变动太快了,业务变、人变、组织也在变。如果产品和服务跟不上变动,两天就会被淘汰。只满足现有业务就OK的年代一去不返,易于定制、具备高延展性才是重点。 ...

July 13, 2020 · 1 min · jiezi

利用ABAP-740的新关键字REDUCE完成一个实际工作任务

ABAP 740从2013年发布至今已经过去很长的时间了,下面这张图来自SAP社区博客: ABAP News for Release 7.40 – What is ABAP 7.40? 图中的ABAP 8.0, 即现在的SAP Cloud for Customer和Business By Design后台使用的ABAP版本NGAP - Next Generation ABAP Platform,里面存在不少只在8.0版本可用的关键字和语言特性。 因为C4C和BYD的ABAP后台,客户和partners们是无法访问的,所以咱们回到ABAP 740这个版本。从该版本开始,ABAP支持了很多新的关键字和语法特性,“看起来有点不像传统的ABAP编程语言了”。 本文咱们就来看一个具体的例子:ABAP 740里的一个新关键字REDUCE. 这个关键字的作用和在大规模数据集并行计算领域里广泛使用的"Map-Reduce"编程模型中的Reduce操作类似,可以按照字面意思理解为“归约”。 下图是Map Reduce框架的工作步骤,统计一个海量输入数据集(比如大于1TB)中的单词出现次数。作为ABAP开发人员,我们没必要了解Map Reduce框架的每个执行步骤,只需紧盯框架的输入,以及执行结果就行了。 回到Jerry接受的实际工作任务。德国同事让Jerry在某个CRM测试系统上做个统计,列出在数据库表CRM_JSTO里,OBTYP(Object Type)和STSMA(Status Schema)这两列拥有相同值的内表行的个数。大家可以把"OBTYP和STSMA两列具有相同值的内表行"类比成上图中重复出现的单词。 下图是CRM_JSTO的部分行: 下图是Jerry完成的任务: 测试系统上内表一共有55多万行,其中有90279行,只维护了OBTYP为TGP,而没有维护STSMA. 排名第二的是COH和CRMLEAD的组合,出现了78722次。 稍稍做过一些ABAP开发的朋友们,一定会立即写出下面的代码: 利用SELECT COUNT直接在数据库层完成统计工作。这也是SAP推荐的做法,所谓Code pusudown准则,即能放到HANA数据库层面进行的操作,就尽量放进去,以充分利用HANA强大的计算能力。在数据库能够完成计算逻辑的前提下,尽量避免把计算逻辑放到Netweaver ABAP应用层去做。 不过,我们也需要注意到这种方式的局限性。Jerry之前曾经引用过SAP CTO的名言: There is no future with ABAP aloneThere is no future in SAP without ABAP ...

November 4, 2019 · 1 min · jiezi

如何在Hybris-commerce里创建一个media对象

进入backoffice的Media中心,首先新建一个文件夹,用于存放即将创建的media对象:取名为jerryimage: 然后创建一个新的media对象,取名jerryproductimage:上传图片: 选择这个media对象存放的文件夹: 从staged catalog同步到online catalog: 同步成功:要获取更多Jerry的原创文章,请关注公众号"汪子熙":

November 4, 2019 · 1 min · jiezi

云端的ABAP-Restful服务开发

愉快的暑假结束了,今天是小朋友新学期开学后的第一个周日,不知道各位家长是否和小朋友们一起,已经适应了新学期的生活了么?Jerry从少的可怜的属于自己的周末时光挤了一小部分时间出来,写了这篇文章。 Jerry之前的一篇文章 从ABAP Netweaver的SICF到SAP Kyma的Lambda Function,我曾经提到过,如果想将ABAP Netweaver里的资源以Restful API的方式暴露出来,SICF这个事务码绝对是一大利器。 我们只需要在SICF里合适的路径下创建节点,为该节点创建一个ABAP类,就可以专注于实现接口定义的方法IF_HTTP_EXTENSION~HANDLE_REQUEST, 在里面编写应用逻辑了。应用开发人员无需关注和操心这些ABAP类什么时候被实例化和调用,可以把这个HANDLE_REQUEST方法看作是一个回调函数,当请求到来时,由Netweaver的ICF框架(Internet Communication Framework)负责把请求路由到对应的ICF节点并创建ABAP类,调用HANDLE_REQUEST方法。每个SICF节点会根据其路径被分配一个url, 如果是Corporate网络里,用浏览器或者编程语言直接访问该url,就能消费SICF暴露的资源了。如果想让这个位于Corporate网络内的url被Internet网络访问,就得借助SAP Cloud Connector: 具体步骤在我之前的文章使用Java+SAP云平台+SAP Cloud Connector调用ABAP On-Premise系统里的函数 里介绍过。 对于ABAP开发人员来说,一个好消息是,SAP Cloud Platform如今也支持ABAP运行环境了。现在我们通过在SAP云平台 ABAP运行环境里完成类似之前在On-Premises ABAP系统的SICF事务码里的开发任务,来感受ABAP到了云端之后,给ABAP开发者带来的巨大便利。 按照Jerry之前的文章在SAP云平台ABAP编程环境上编写第一段ABAP程序 里介绍的步骤,通过ABAP Development Tools连接SAP云平台 ABAP运行环境的一个实例,完成登录后,后续的操作步骤,同使用ABAP Development Tools连接一个On-Premises ABAP系统,几乎没有差别。 下图是在云上的ABAP环境里,允许我们创建的ABAP对象列表,既有ABAP开发人员感到亲切的ABAP字段对象,ABAP开发包,ABAP消息类等等,也有上了云端之后的新面孔,比如Cloud Communication Management和Cloud IAM等。为了完成在On-Premises的SICF事务码里的开发工作,现在我们要在云上的ABAP环境里创建一个新的HTTP Service: 新建一个名为ZHELLOWORLD的service,创建完毕之后界面如下: ABAP老司机们看到这界面,立即知道下一步怎么做了吧。点击Handler class,就可以进入ABAP类的编辑界面,实现这个HTTP服务的业务逻辑。而通过url字段里维护的值,我们可以在PC或移动设备里,浏览器或代码里访问这个服务。该服务实现类和On-Premises的区别,不过是接口名称从IF_HTTP_EXTENSION换成了IF_HTTP_SERVICE_EXTENSION. 当然,前者因为是直接在云端编写的ABAP代码,所以还要遵循Jerry之前的文章 在SAP云平台ABAP编程环境上编写第一段ABAP程序 里提到的那些限制。 上述的ABAP代码只是简单地返回给消费者一个Hello World的文本信息,保存激活之后,把url贴到浏览器里,就能看到期望的Hello World: 我们从url里,容易得出这样的结论,SAP Cloud Platform ABAP运行环境里支持创建的HTTP服务,其实现原理,其实就是在Netweaver服务器的SICF路径/sap/bc/http/sap/下面增加一个新的节点罢了,只是这个操作,在云端不再需要由ABAP开发人员手动完成,云端的ABAP环境,会自动创建这一底层设施。希望传统ABAP开发人员,能从这个最简单的Hello World级别的例子,体会到云端ABAP开发的便利之处。感谢阅读。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

October 14, 2019 · 1 min · jiezi

在SAP云平台ABAP编程环境上编写第一段ABAP程序

距2017年秋季的SAP TechEd大会上一位大佬Björn Goerke,SAP’s Chief Technology Officer宣布了SAP Cloud Platform即将支持ABAP至今,已经过去了两年的时间。 目前国内的技术媒体平台上,已经有了部分概要性介绍SAP Cloud Platform ABAP编程环境的中文文章,但涉及到具体操作细节的文章比较少。 Jerry最近会做一系列关于如何在SAP Cloud Platform上的ABAP编程环境上做开发的分享。 其实对于一个已经能够熟练使用ABAP Development Tools连接On-Premises ABAP Netweaver服务器做开发的传统开发人员而言,迁移到从On-Premises迁移到SAP云平台上的难度不大,只是需要注意一些开发理念上的转变,这个转变我们在后续具体做开发时会提到。 这种相对平缓的迁移和学习曲线,对于SAP全球庞大生态圈的企业和开发人员来说,无疑是一个好消息——这意味着SAP正在进行中的向云端数字化转型的旅程里,这些企业和个人也能够加入其中,并且他们以前在On-Premises时代积累的宝贵的技术和业务领域知识,能够继续在云时代发光发热。 我曾经在网络上了解到,很多自学SAP ABAP的朋友们,面临的第一道关卡就是在自己本地搭一台Netweaver服务器出来。作为一个写了12年代码的老开发人员,Jerry也搭过各种本地开发环境,深知这里面的水有多深。我以前的老板,也给我们分享过他当年来SAP成都研究院面试的时候,自己本地也搭过Netweaver,并且短短几天啃完几百页的Netweaver英文文档的经历。 相信每一位在本地搭建Netweaver的ABAP学习者,当成功看到Hello World输出的那一刻,成就感一定爆棚。 然而,当Jerry第一次在SAP Cloud Platform的ABAP编程环境上看到Hello World时,却没有多少成就感,因为直接按照ABAP Development Tool里的项目创建向导一步步操作就可以了,过程比较简单易懂——这也体现了云时代到来后,对传统应用开发人员工作方式的影响:无需费神去关心底层硬件或者操作系统等资源,可以把精力集中于应用程序逻辑的编写上。换言之,SAP负责管理和维护底层HANA数据库和中层的ABAP runtime,用户只需管理顶层的ABAP应用代码。 使用ABAP Development Tools的项目创建向导:New->ABAP Cloud Project: Service Instance Connection,选择SAP Cloud Platform CloudFoundry environment: 选择Region,输入用户名密码,前提是你得在这个region下有一个global Account。 下图是我在SAP Cloud Platform的CloudFoundry环境里的Global Account: 这个Global Account所属的space下面我创建了一个ABAP系统实例,ID为ME1: 这个ABAP运行实例具有16GB运行内存,64GB的HANA内存。 再回到ABAP Development Tools, 在项目创建向导里使用Cockpit里维护的上述属性: 点Next,在ABAP Development Tools里会看到一个嵌入的登录窗口。因为Jerry使用的是SAP社区Mentor的账号,所以登录窗口显示的标题是:Welcome to Mentors! ...

July 4, 2019 · 1 min · jiezi

一个SAP开发人员的养蚕流水帐

Jerry打算以此文来给汪子熙全家进行了一个多月的养蚕经历画上一个圆满的句号。 南方长大的80后,对蚕应该不会太陌生。大家还记得你们小时候学过的课文《蚕姑娘》么?课文开头是这样的: 春天天气暖洋洋,蚕卵里钻出蚕姑娘。 又黑又小的蚕姑娘,吃了几天桑叶,就睡在蚕床上,不吃也不动,脱下黑衣裳。醒了,醒了,变成黄姑娘。 又黄又瘦的蚕姑娘,吃了几天桑叶,又睡在蚕床上,不吃也不动,脱下黄衣裳。醒了,醒了变成白姑娘。 又白又嫩的蚕姑娘,吃了几天桑叶,又睡在蚕床上,脱下旧衣裳,换上新衣裳。醒了,醒了,从此一天一天发胖。。。 Jerry小时候当然也学过这篇课文,也按照语文老师的吩咐,在家里养了十几只桑蚕,并且观察它们每天的生长情况。准确的说,我小时只负责观察,一切其他的后勤工作都由我父母完成。由于年龄太小,当时所有的细节我都淡忘了,只依稀记得每只蚕最后都在纸盒里结出了洁白的茧。 时光荏苒,现在Jerry成为了父亲,开始协助汪子熙完成他的语文老师布置的养蚕观察作业。 感谢现在科技水平的飞速发展,我手上30倍的放大镜和三星手机1600万像素的摄像头,让我能够比小时候更清晰地观察蚕们的一举一动。 知乎上有一些很有意思的问题,概括起来大致为:为什么很多人喜欢蚕,但是讨厌,甚至害怕毛毛虫? 我养了一个多月的蚕,我想对于这个问题我有一定的发言权。以下是Jerry对这个问题的看法。下文所说的蚕,如无特殊说明,都指大家为了完成学校作业所养的桑蚕里的大白蚕。 1. 作为一个长期以农业占主导地位的国家,蚕因为能出产具有极高经济价值的蚕丝,从而在我国悠久的农业历史中始终享有很高的地位。早在商周时期,古人们就已经开始在室内养蚕,这个传统延续了几千年一直到现在。 秦汉以后,咱们的养蚕技术通过举世闻名的丝绸之路传入到中亚、南亚及西亚地区,进而传播到欧洲。简单的说,因为蚕对人类有用,所以人类喜爱它们。再加上文人墨客从人类的视角出发,在观察了蚕吃桑叶吐丝的行为之后,发出了"春蚕到死丝方尽,留赠他人御风寒"这种极富褒义色彩的感叹,这使得蚕又经常和另一个具有崇高意义的名词——教师关联起来。在我们从小就接受这些对于蚕正面评价的教育下,我们很难对蚕讨厌得起来。 2. 从外观上看,虽然都是软体动物,蚕和毛毛虫的颜值可谓一个在天上,一个在地上。蚕的全身洁白,白色在我国一直是纯洁的象征,而毛毛虫的颜色往往都很非主流;蚕的全身很光滑,不像毛毛虫那样浑身长满了让人害怕的绒毛。 蚕的性情非常温顺,不会对人造成任何伤害,所以Jerry经常把它们放在自己手上让它们爬来爬去,近距离观察。有的毛毛虫,身上的绒毛蜇到人的皮肤后,会让人很不适,因此大家都不喜欢。 3. 养蚕的环境散发出来的气味很香,至少Jerry闻到的味道是如此。那些动辄饲养上万只蚕的场所发出的气味不在本文讨论之内。蚕吃的桑叶本身带着植物特有的芳香,Jerry也曾经把鼻子凑在自己手上爬来爬去的蚕附近使劲闻,也没有闻到任何味道。而一般的毛毛虫,看着就够恶心了,我实在没有勇气去闻闻它们是什么味道。 4. 蚕很萌。蚕吃得白白胖胖圆圆滚滚在桑叶上蠕动着身子一节节地爬来爬去的样子很萌。如果养了一大群蚕,那么你一定能观察到这种情况:有时在忙忙碌碌啃桑叶的蚕们中间,间杂着几只高昂着头“思考蚕生”的另类: 比如下图正中这只。 关于蚕为什么会昂着头一动不动,网上公认的说法是它们这是在休息,在睡觉。每当这时,我都会忍不住,用手指头轻轻去摸摸它们。有的时候它们被我揩油之后,没有任何反应;有的时候像是受惊了一样,昂起的上半身猛地一缩,很好笑。 5. 蚕的一身都是宝。除了蚕丝能用来做丝绸,蚕丝被,蚕沙(蚕的粪便)能入药,做枕头,蚕蛹能食用之外,很多心灵手巧的小朋友们还用蚕茧做成了各种各样的小工艺品: 透过这些纯天然纯绿色的小手工,我们能看到孩子们如水晶般纯洁的心灵。 前面说到我那30倍放大镜和1600万摄像头的三星手机(这配置在2019年来看应该很渣吧), 是时候让它们出来发挥作用了。 下面是一张蚕宝宝的靓照,最左边棕色的椭圆形部分就是蚕的头部,剩下的都是它的躯干,在靠近头部的胸部部分有三对足,其后每一节身躯的底部都有一对足,总共7对14只足;大家如果仔细看这张照片,会发现蚕的足上其实长了绒毛,而且足的底部还有洗盘,能使自己牢牢吸附在桑叶上,这样能保证蚕即使在桑叶背面爬动时,也不会因为重力原因落到地上。 在躯干的最末一节还有一根小小的向上凸起的尖刺,这是蚕的尾角,我们可以用来辨别蚕的雌雄:雌蚕尾角往前翘且有黑点;雄蚕尾角往上翘而无黑点。这根看似不起眼的尾角对蚕来说是非常重要的器官:其生理作用主要是平衡蚕体内的水压,使蚕前后水压保持相同。蚕的体壁内,肠部,气管和神经等组织都浸泡在血液之中,从蚕的照片我们一眼就能看出蚕的体型是前部稍大尾部稍小,因此需要借助尾角,确保蚕尾部承受液体的压力和胸部的一致。  蚕躯干的每一节都还有一个非常醒目的黑点,这是所有昆虫都具有的呼吸器官——气门,只是蚕的比较明显容易被观察罢了。当蚕周围的气温发生变化时,蚕会借助开关气门的方法来调节体温,让身体的体温适应周围的温度。 那么蚕的眼睛和嘴呢? 先来张头部的正面特写。这小脑袋是不是很萌? 我们很容易根据人类的五官,去揣度蚕的眼睛所在的部位,即头部正中那两个小黑点,事实并不是这样。下面这张图才是蚕的眼在头部的正确部位。是的,我们说眼而不是眼睛,因为蚕作为昆虫,眼部构造和人的眼睛相差太多太多。蚕不像苍蝇,蜻蜓那些昆虫一样具有复眼,蚕的眼是单眼,包含一些感光细胞,能够感觉到光线的强弱,但并没有视觉作用。实际上蚕是靠嗅觉和触觉来判断前方的物体和前进方向,而非视觉。 蚕的嘴也非常有意思。 准确地讲,蚕是用“咀嚼式口器”来进食桑叶的。咀嚼式口器是昆虫具备的另一个非常典型的器官,用来取食固体食物,和人的嘴巴一样有上唇、下唇、上颚(牙齿)和舌,但同时它还有下唇须、下颚和下颚须。蚕的口器上颚前端有锋利的齿,叫做切区,用来切断桑叶纤维。当然,这个锋利是从蚕的角度出发针对桑叶而言的,对人的手指皮肤没有一丁点的破坏力。蚕进食桑叶时,口器会上下蠕动,在桑叶上留下一道道半圆形的缺口。 大家请看下面这段Jerry拍摄的蚕们狼吞虎咽进食桑叶的视频,注意观察文中提到的半圆形缺口: https://v.qq.com/x/page/n08915ahnh1.html 蚕的一生会经历下图四个阶段,在我们小学语文课文《蚕姑娘》里已经阐述清楚了。 蚕蛾产下的卵: 这些卵逐渐变成褐色后,就意味着新的蚕即将来到这个世上了。刚刚破卵而出的蚕个头非常小,遍体黑色,因为很像小蚂蚁,我们称之为“蚁蚕”。 蚁蚕不停得啃桑叶,逐渐长成了大家印象中的蚕的白白胖胖的样子。 蚕一生中总共会蜕4次皮,和其他很多昆虫一样,蚕在生长发育过程中其表皮不能随着身体长大而长大,因此当蚕的身体长大受到限制时,蚕就要蜕皮。Jerry也不知道导演雷德利·斯科特(Ridley Scott)的《异形》系列里的异形蜕皮生长的设定,是否受到了蚕蜕皮的启发。 看一段Jerry拍摄的蚕蜕皮的视频(这种视频很不容易拍到): https://v.qq.com/x/page/t0891... 这是Jerry收集的蚕蜕下的皮,也是一种中药。 ...

July 4, 2019 · 1 min · jiezi

2019年6月SAP发布的未来ABAP平台的发展方向

未来ABAP平台将始终是这些产品的技术平台: S/4HANA On-Premises和Cloud将基于一个统一的ABAP codeline: SAP云平台上的ABAP编程环境: 什么是SAP Cloud Platform上的ABAP编程环境?该编程环境使用基于云优化之后的ABAP编程语言,是传统ABAP编程语言的一个子集,有部分关键字和ABAP语言特性因为不适合云的使用场合,故在SAP Cloud Platform的ABAP环境上无法使用。 在SAP Cloud Platform的ABAP编程环境里推荐使用ABAP Restful编程模型,能方便地扩展云和On-Premises系统上的SAP解决方案。 使用基于Eclipse的ABAP Development Tool这个开发IDE,同时能充分利用SAP云平台上提供的各种服务。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

July 3, 2019 · 1 min · jiezi

CRM和C4C里的组织架构-Organizational-Structure

CRM(WebClient UI) CRM(SAP GUI,事务码PPOMA_CRM) C4C以列表方式显示: 以图形方式显示: UI模型:/SAP_BYD_APPLICATION_UI/mom/org/COD_OrgUnit_OWL.OWL.uicomponent 明细页面:/SAP_BYD_APPLICATION_UI/mom/org/COD_OrgUnit_TI BO name: OrganisationalUnit通过递归执行association ChildOrganisationalUnit就可以得到unit hierarchy: 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

July 2, 2019 · 1 min · jiezi

一步步用ABAP-Development-Tools连接SAP云平台上的ABAP编程环境

使用ABAP Development Tools的项目创建向导: New->ABAP Cloud Project: Service Instance Connection,选择SAP Cloud Platform CloudFoundry environment: 选择Region,输入用户名密码,前提是你得在这个region下有一个global Account。 下图是我在欧洲法兰克福(Frankfurt)这个Region的Global Account: 这个Global Account所属的space下面我创建了一个ABAP系统实例,ID为ME1: 这个ABAP运行实例具有16GB运行内存,64GB的HANA内存。 再回到ABAP Development Tools, 在项目创建向导里使用Cockpit里维护的上述属性: 点Next,在ABAP Development Tools里会看到一个嵌入的登录窗口: 点Finish: Finish点了之后,在ABAP Development Tools左侧的项目列表里就能看见创建好的ABAP Cloud项目了,接下来在这个项目里编写ABAP代码进行开发的方式,和我们用ADT连接On-Premises系统基本一致。大家可以看到下图创建好的高亮的ABAP Cloud项目(系统ID为ME1), 和其他On-Premises上的ABAP项目外观上没有区别。 这两种ABAP项目的差异在于,ABAP Cloud项目里能够使用的ABAP语言特性,只是传统ABAP语言的一个子集,比如传统ABAP语言里和Dynpro相关的关键字,即只能工作在SAPGUI中的那些关键字,因为在Cloud环境下不再适用了,所以在ABAP Development Tools的ABAP Cloud项目里禁止使用。 至于上图ABAP Cloud项目里的Released Objects如何使用,等Jerry有时间再继续写。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

June 28, 2019 · 1 min · jiezi

Marketing-Cloud里取得系统contact数目的API

Marketing Cloud里的Contact标准tile(下图红色tile)上是没有当前系统contact数字显示的,请对比profile tile(下图黑色tile)。 客户有需求希望在Launchpad Contact tile上也显示这个数字,因此我新建了一个tile。 需要给这个tile配置一个OData API url: /sap/opu/odata/sap/CUAN_CONTACT_SRV/InteractionContacts/$count?$filter=YY1_FACEID_MPS%20ne%20%27%27postman里测试确保工作: 最终效果: 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

June 1, 2019 · 1 min · jiezi

ABAP很厉害是怎么一种体验?

知乎上偶然看到这个问题,觉得很有意思,我也来回答一发。我本科和研究生学的是计算机专业,做项目用C/C++,研究生三年项目的代码量大概在三到四万行左右。2007年大学毕业加入SAP成都研究院一直工作到现在,工作中用的最熟练的编程语言是ABAP,Java和JavaScript。当然做SAP Cloud application Studio这个工具开发时,也用过一段时间的C#。做一个SAP内部的大数据项目也用过一阵子Scala,Python和Go语言在做Hyperledge Fabric on SAP Cloud Platform时也学了一些皮毛。我没有把自己定位成“ABAP开发人员”或是“Java开发人员”,而是“SAP应用开发人员”。也就是说组织给我分配一个开发任务,我自己就得去琢磨,选择合适的编程语言来完成。ABAP,Java和JavaScript这三门我工作中用的最多的编程语言,在我眼中没有优劣之分,就是不同的编程工具,有各自的适用场合,如此而已。我曾经写过一篇文章:Jerry的ABAP, Java和JavaScript乱炖百度即可找到,里面包含了我对这三门语言一些特性的横向比较。文章链接:https://www.cnblogs.com/sap-j…回到ABAP语言本身,我认识SAP总部Walldorf很多资深的ABAP应用开发人员,当然也包括ABAP编程语言本身的开发人员,即用C语言开发ABAP虚拟机和运行时的那些同事,称呼他们为计算机科学家更合适。我想任何资深的ABAP应用开发人员,在他们面前也没有资格说自己“ABAP如何如何厉害”,因为这些计算机科学家们才是ABAP世界的创世主和维护者。C和ABAP的关系,可以参考我这篇文章:聊聊C语言和ABAP文章链接:https://www.jianshu.com/p/a99…至于一些网络上老生常谈的问题,诸如:做ABAP开发有前/钱途吗?为什么ABAP开发的收入比Java开发高/低?我已经在一些文章里表明了我的个人意见:上图文章的链接:https://blogs.sap.com/2017/01…中文版:ABAP开发人员未来应该学些什么文章链接:https://www.jianshu.com/p/b74…我写过的其他一些关于ABAP的文章:Jerry 2017年的五一小长假:8种经典排序算法的ABAP实现:https://www.jianshu.com/p/ceb…Jerry的ABAP原创技术文章合集:https://www.jianshu.com/p/020…300行ABAP代码实现一个最简单的区块链原型:https://www.jianshu.com/p/844…ABAP vs Java, 蛙泳 vs 自由泳:https://www.jianshu.com/p/4a0…动手使用ABAP Channel开发一些小工具,提升日常工作效率:https://www.jianshu.com/p/1cb…我用ABAP做过的那些无聊的事情:https://www.jianshu.com/p/688…使用Visual Studio Code编写和激活ABAP代码 (上):https://www.jianshu.com/p/0db…你的ABAP程序给佛祖开过光么?来试试Jerry这个小技巧:https://www.jianshu.com/p/97c…关注Jerry的公众号“汪子熙”,轻松获得所有SAP文章:要获取更多Jerry的原创文章,请关注公众号"汪子熙":

April 13, 2019 · 1 min · jiezi

我做SAP CRM One Order redesign的一些心得体会

框架开发和应用程序的开发完全不一样。举个具体的最近折腾我的例子: 创建新的service order,维护header的shipping data,此时order和shipping data的mode 都是creation,然后创建line item,添加product,header的shipping data带到line item,然后在line shipping data做修改,item的mode变成了change,此时不存盘,直接删除该item,然后马上另外创建一个item,继续编辑,此时第二个item的mode是creation,前一个item的change mode变为deletion,然后再删除第二次加的line item,不存盘,再创建第三个project,维护一些数据,存盘。此时我代码里的buffer处理会出问题,存到DB确实有一条item数据,但是已经corrupt掉了。 由于我buffer 处理logic有bug, 我花了很大功夫最后发现是第二次被删除的那条数据的内容被错误存到了DB里: 我甚至花了大量的时间来找重现这个错误的办法,因为最初我是偶然的机会发现这个错误,但是没留意我的操作,最后才找到能稳定复现问题的步骤,赶紧记录下来: 这个buffer处理的bug直接导致了今天三个新bug: 这就是框架开发的难度。如果是做应用,可以和PO商量,哪个客户吃饱了做这种操作?不支持。但是这些操作从Oneorder框架的角度来看,无非就是create, update和delete三个local buffer的处理罢了,没有任何理由不支持这种sequence的操作。反过来说,当developer经过一段时间努力之后能够自如地应对这些挑战,从这些bug中抽丝剥茧定位问题,给出correction,他的开发能力一定能得到很大提升。Developer对于自己编程能力的提升是没有止境的,我来之前本早已对自己的编程能力非常自信,但是经过这21天的开发,我还是造了一共40个bug出来。但我最终都fix了他们,每解决一个bug就像以前Wuji老师用游戏打比方一样,获得一定经验值。bug越难经验值越高。我做这个POC确实是全神贯注拿出全部精力去做,就这样都还生产了这么多bug,确实很烧脑。我每踩一个坑,都会用Jerry : timestamp这种格式写下注释. 如果用Jerry做关键字搜索,能发现34处坑:每一处坑趟过之后都增加了我对one order的理解,我把这些bug当作我的一笔财富。比如看这个"this code is ugly"的注释,点进去看: 确实很ugly,这恰恰就是fix注1里提到那个buffer更新bug的correction的一部分,加了注释估计没接触过one order的人也看不懂。我们拿成都现在已经完成一部分的product harmonization为例来看:7531行代码。而这个POC,做到今天是第21天,代码量已经超过product harmonization一半了。请看其中我highlight的这个class,是我的搭档IMS写的,他从2010年开始做One order。这个class 到现在写了921行,就为了实现一个功能:把partner的数据从新表里读出来,放到对应的buffer里去。为什么有921行?因为buffer的插入很有讲究。我每天吃饭,骑车的时候都在想这些buffer的东西。这个redesign的关键用三个词来概括的话,就是buffer, buffer, buffer.2017-05-15 9:45PMModel redesign targetOne order model redesign主要发生在下图我画的黑色方框内的模块, 下列是需要完全重新开发, 而非harmonization的内容新的数据库表。每个object type一张表,比如BUS2000116是Service process,有且仅有一张header 表,BUS2000131是sales item,有且仅有一张item表围绕这些数据库表的CRUD API.简单的说,就是这两件事。当然和One order 框架的复杂程度相关。Scope其中有9个component是硬骨头,当前POC已经done了两个,我用黄色标记。现有的POC,整体框架已经搭起来了,one order在新的model下已能正常工作,productive实现除了上述提到的7个硬骨头之外,不存在做不出来的东西和Feature. 当然,根据大家这么多年的开发经验,POC不可能100%暴露productive开发的所有问题。概括起来说,就是我们不需要从头空想一套东西来实现,一切以现有的POC为基础,这也是Carsten现在对这个POC非常重视的原因,每个方法,每行代码,在他力所能及可以抽出时间review的时候,他都不放过。开发这个事情并不是说工作认真负责就能deliver高质量的代码。打个不恰当的例子,我和Oliver工作都很认真,但我们还是生产了38个bug.和Carsten一起工作一个月,我对他工作风格的体会:一方面,他review你东西的时候非常仔细,非常注重细节,包括我之前举的例子,比如某方法是在LOOP里call还是外面call好,method的参数设置等等。另一方面,对于什么才是正确的design,他往往只给出大方向,overall的思路,但不会具体到可以直接拿来实现那么细的粒度,比如他不会告诉你为了实现他的思路,需要几个class,每个class几个方法,每个方法参数如何定义。他这种工作方式make sense,因为Chief Architect不需要把事情拆分这么细。这样就造成我最近按照我自己的理解去实现他那些思路,所以经常返工,refact. 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

March 10, 2019 · 1 min · jiezi

你的ABAP程序给佛祖开过光么?来试试Jerry这个小技巧

最近Jerry在忙一个项目,技术栈换成了nodejs平台,语言换成了JavaScript,因为赶项目进度,一直没时间更新公众号。感谢大家的支持,关注人数还是慢慢地增长到了3000。今天我们来聊聊一个比较轻松的话题。当今这个数字化时代,大家的生活都离不开互联网。互联网公司为了确保服务器不会因为软硬件问题宕机而影响自己的业务,纷纷使出浑身解数,包括设计更健壮的架构,实现高质量的代码,提供硬件条件更好的机房等。当然也有一些脑洞大开的公司,另辟蹊径,采取让佛祖对服务器进行开光的方式,来实现"服务器永不宕机"的美好愿望。下面是Jerry从一则搜狐新闻上看到的一些有趣的图片,转贴于此,新闻原文网址:http://www.sohu.com/a/1166219…有请高僧给服务器贴上灵符:看着这个符咒,Jerry想起了自己曾经通关过无数遍的仙剑奇侠传98柔情版里各种各样的灵符。高僧正在认真地进行开光仪式:这些难道是IT管理员,或者SAP称呼的Basis们,虔诚地跪在服务器前向佛祖祈祷“永不宕机”吗?除了“永不宕机”外,“永无bug”也是程序员们另一个美好的愿望。于是乎,有些程序员希望通过在代码头部加上这种注释,来获得一些心理上的慰藉。而对于SAP ABAP程序员,一看到bug这个词,最容易联想到什么?不知道大家心中的答案是什么,Jerry的答案是:ST22。ABAP程序在执行时,如果遇到了没有捕捉的异常,程序会终止,同时ABAP运行时会产生一个类似Windows系统蓝屏的core dump:这种dump可以在事务码ST22里查看。一般来说,一个有经验的ABAP程序员,通过分析ST22里提供的程序崩溃时的上下文信息,系统变量的内容,调用栈等等,不难修复这种bug。下图是ST22里dump的一个例子,值得一提的是大家可能会忽略的BASIS Developer View, 里面包含了引起运行时错误的ABAP语句对应的C语言实现的具体文件位置,比如下图的//bas/753_STACK/src/krn/abap/runt/abassert.c。大家还记得我写过的聊聊C语言和ABAP 这篇文章么?这里我偷个懒,把那篇文章里介绍C语言和ABAP语言关系的文字引用过来:为什么这篇文章要把C语言和ABAP放在一起讲,而不是别的语言比如Java和ABAP呢?因为ABAP语言底层是基于C/C++实现的,包括其关键字(比如最简单的关键字WRITE的C++实现有2千多行)和虚拟机(ABAP Runtime)。SAP内部的一群计算机科学家们发明了ABAP这门伟大的语言,由它实现的各种SAP应用帮助了全球超过180个国家和地区的客户们更好地运行其业务。通过Google我们能搜索到一些关于这些SAP计算机科学家们的介绍,比如这个链接:http://sapexperts.wispubs.com…SAP内部的Netweaver开发服务器上是能够浏览这些C语言代码的。Jerry 2017年在德国工作时,业余时间比较多,相关的C代码也阅读了不少,比如ABAP里最简单的WRITE关键字,其C语言实现有2000多行。可惜因为这些C语言实现对客户和partner不可见,因此无法在这里给大家分享它们的逻辑。再回到ST22。相信每一位ABAP程序员运行代码看到ST22的dump后,心里都会很沮丧。这个时候,如果有佛祖能够给引起bug的代码开开光,那将是一件很鼓舞人心的事情。相信无论使用何种编程语言的程序员,看到下图红色高亮的这两行字,都会精神为之一振:佛祖保佑,永无bug这段代码佛祖已经做过开光处理,绝无可能再产生bug如何实现ST22里这个显示效果?其实ST22和Windows系统蓝屏显示逻辑一样,都是一段静态模板文本加上运行时异常的实际动态内容合并而成。模板文字存储在ABAP Netweaver服务器的数据库表里。我们只需要在ST22的框架代码把模板文本从数据库表读出之后,将佛祖开光的文本动态添加到模板文本的头部,就大功告成了。实现步骤非常简单,在ST22标准程序SAPMS380的subroutine read_snapt内创建一个隐式增强。从read_snapt的代码能看出ST22的模板文本是存储在数据库表SNAPT里的。把佛祖开光的文本注入到read_snapt输出的头部:这段隐式增强的代码我放在了我的Github上:https://github.com/i042416/Kn…最终效果就是每次出现了运行时程序执行错误后,程序员到ST22里查看dump时,总能看到“佛祖保佑,永无BUG”几个字。这个例子其实也再次体现了Jerry之前提到的,作为ABAP开发环境和运行环境和二而一的Netweaver,给开发者提供了强大的可扩展性。最后也是最重要的1. 本文提供的步骤涉及到了对ABAP框架代码的隐式增强,请谨慎使用。禁止在测试服务器和生产服务器使用! 否则由此造成的一切负面后果,Jerry本人及SAP概不负责。2. 如果真的想确保自己交付的代码“永无BUG”,程序员还是得老老实实练好自己的内功,而不要把自己的命运交给佛祖。毕竟国内这么多程序员,这么多行代码,要是每一位程序员每一行代码都要由佛祖开光,佛祖得多累鸭,佛祖忙不过来鸭!更多阅读动手使用ABAP Channel开发一些小工具,提升日常工作效率聊聊C语言和ABAPABAP vs Java, 蛙泳 vs 自由泳300行ABAP代码实现一个最简单的区块链原型Jerry的ABAP原创技术文章合集ABAP开发人员未来应该学些什么Jerry的ABAP, Java和JavaScript乱炖我用ABAP做过的那些无聊的事情不喜欢SAP GUI?那试试用Eclipse进行ABAP开发吧那些年我用过的SAP IDE使用Visual Studio Code编写和激活ABAP代码

March 10, 2019 · 1 min · jiezi

Fiori Fundamentals和SAP UI5 Web Components

这周有位同事邀请我给团队讲一讲SAP技术的演进历史,所以我准备了下面几个主题来介绍。其中SAP的技术回顾和演进,我的思路就是从前后台两方面分别介绍。我画了一张非常简单的图:去年5月我写过一篇文章:SAP UI和Salesforce UI开发漫谈,简要回顾了SAPUI技术的发展,从最古老的SAP GUI绘制界面,到Webdynpro / WebUI再到现在广泛使用的Fiori UX。当时这篇文章介绍到Fiori(UI5)就嘎然而止了,如今大半年过去了,我们继续聊聊Fiori的发展动向。根据Jerry从SAP社区上已经发布的信息来看,Fiori的两个发展方向,我个人概括为:1. 兼容并蓄,即通过Fiori Fundamentals,让使用非UI5开发框架的前端开发人员,用其喜爱的技术,也能开发出符合Fiori UX的应用。2. 轻装上阵,即通过SAP UI5 Web Components,既能继续提供像之前UI5控件库那些开箱即用的众多UI控件,又避免了前端应用对UI5框架的依赖。我们来分别了解一下这两个新概念。Fiori Fundamentals看看SAP官网上的权威定义:https://experience.sap.com/ne…Jerry在上图把最关键的信息都用红色高亮出来了。重点:1. Fiori Fundamentals在前端应用里扮演着一个轻量级展现层的角色,可配合Angular, React和Vue等前端框架一起使用。2. Fiori Fundamentals不是一项新的UI技术,更不会取代UI5,而是一个CSS和HTML标签的集合,使得开发人员能使用其偏爱的UI框架去开发具有Fiori UX风格的应用。同样,Jerry去年年底写的另一篇文章 SAP Fiori + Vue = ?,介绍的其实就是Fiori Fundamentals针对于Vue的实现。刚刚提到的重点2,Fiori Fundamentals是一系列CSS和HTML标签页的集合,那么我们到Jerry的这篇文章里介绍的例子去找找。这是例子里引用的CSS:这是SAP Fiori Fundamentals帮助文档里提到的绘制表格的标签:在我的Vue应用里如何消费这些标签:至于为这个标签绘制而成的表格添加事件处理机制,其方法和纯粹的Vue应用完全一致,因此一个传统的Vue开发人员,借助Fiori Fundamentals的帮助,几乎不需要任何额外的学习就能够进行SAP Fiori应用的前台界面开发。SAP UI5 Web ComponentsSAP德国的UI5开发人员Peter Muessig最近在SAP社区上发表了一篇博客:UI5 Web Components - the Beta is there,大家可以通过本文末尾的"阅读原文"来阅读他的原文。如Peter文章题目所说,SAP最近发布了UI5 Web Components的Beta版本,并邀请广大SAP生态圈的开发人员试用并提出意见。Peter的文章不长,但是为了方便不喜欢读英文的朋友们也能快速了解这个UI5 Web Components是个什么东东,Jerry还是把里面一些要点用我自己的语言表述出来。下面的部分并非Peter文章内容的简单翻译,而是Jerry阅读了之后,基于自己的理解再加上自己的扩充。大家如果对我文章的内容有质疑,欢迎留言讨论。SAP UI5 Web Components,是SAP将之前SAP UI5控件库里的控件,按照Web Components标准规范重新实现后的产物。相信了解SAP UI5的朋友们,看了我上面这句描述,脑子里会冒出这些问题:1. 什么是Web Components标准?2. SAP为什么要做这个重新实现的事情?3. 重新实现后的产物到底是个什么东东?关于第一个问题,直接访问Web Components的官网即可找到答案。程序猿们都懂的,org结尾的网站最喜欢定义各种几百页甚至上千页的技术规范,Web Components也不例外:https://www.webcomponents.org…前端组件化一直是前端生态圈很火热的讨论话题之一,像前端三驾马车Angular,React和Vue都有自己的组件化实现,而webcomponents.org上定义的规范,其实就是给出了一个标准,只有满足这个标准里的实现,才能算是一个通用的组件化实现,才能被所有现代浏览器支持。这个规范的内容也托管在github上的:https://github.com/w3c/webcom…里面包含四大标准Shadow DOM,Custom Elements,HTML Templates和CSS changes,SAP UI5 Web Components的实现当然也满足这些标准。第二个问题,SAP开发UI5 Web Components的动机。Jerry个人的看法:给客户和Partners提供一种更灵活的使用UI5控件的方式,避免对UI5框架的依赖。举个例子,如果我们想使用UI5控件库里提供的button控件,就算只在XML视图里写简单的一行定义,最后运行时的UI5框架也会执行许多很复杂的逻辑,Jerry在四年前写的UI5框架自学教程里曾详细描述过:https://blogs.sap.com/2015/10…而借助SAP UI5 Web Components,开发人员根本不需要导入UI5框架,就能直接使用UI5里的控件。按照Peter文章的描述,SAP UI5 Web Components能用于任何前端框架中,即下图中高亮的最后一句话。此时自然需要回答第三个问题了。SAP UI5 Web Components到底是个什么东东?上图传达的重点:1. SAP UI5 Web Components并不是基于UI5框架的。换句话说,和UI5框架没有任何依赖关系,可以独立使用。2. SAP UI5 Web Components并不是SAP UI5框架的接替者,而应看作后者的一种补充。3. 将UI5控件库提供的控件在HTML层级暴露给消费者,而非传统方式下的API层面暴露方式。如此一来,UI5 Web Components可以不依赖于UI5框架,能直接用于其他的前端框架。看个具体的例子:在浏览器里打开下面的HTML页面,会看到一个UI5按钮。点击后弹出这个按钮实例的innerHTML属性的值。这是一个最简单的SAP UI5 Web Components的Hello World例子。例子里我们使用了SAP UI5 Web Components自定义的标签<ui5-button>。对于前端应用开发人员来说,这个自定义的标签和W3C里的button标签没有任何不同,至少从消费方式上来说完全一致。关于UI5 Web Components里诸如<ui5-button>这类自定义标签的详细说明,可以查看SAP帮助文档:https://sap.github.io/ui5-web…运行时,和在UI5框架里使用控件一样,仍然有一个专门的ButtonRenderer负责生成按钮原生的HTML代码:从运行时生成的HTML源代码我们不难发现,UI5 Web Components自定义的HTML标签只是起着占位符(place holder)的作用,真正承载运行时用户可以与之交互的实际按钮,还是通过上图ButtonRenderer生成的HTML原生button标签。需要强调的是,通过上述ButtonRenderer生成的运行时按钮实例,仍然满足使用UI5框架的传统方式绘制的控件一样的特性,比如传统方式下SAP保证的所有产品标准,像Accessibility,Internationalization这些,在SAP UI5 Web Components里仍然继续支持,无需应用开发人员额外的编程实现。本地用npm install @ui5/webcomponents命令安装UI5 Web Components之后,就可以找出里面最简单的组件实现,Button.js, 来学习SAP是如何基于Web Components标准,采用ES6支持的mobule和class等特性实现一个自定义标签的。将来Jerry或许可以邀请SAP成都研究院的一些专职做前端开发的同事来分享这里面的技术细节。最后,SAP UI5 Web Components的使用场景是什么?以上是照搬Peter的文字。适用场景有二:1. 在没有使用前端框架开发而成的简单静态页面里,如果想添加一些能够提供用户交互的控件,可以考虑SAP UI5 Web Components。2. 在已有的基于其他前端开发框架的Web应用里,如果需要一些能与用户交互的控件而又不想重复造轮子,那么可以到SAP UI5 Web Component官网上去找找。另一方面,SAP UI5框架仍然是SAP推荐的开发具有企业级复杂度和响应式前端应用的方案。最后,有朋友可能会有疑问,Jerry前一篇文章 SAP Fiori + Vue = ?里介绍的fundamental-vue,里面不是也存在SAP自定义的用于Vue应用的HTML标签吗?https://github.com/SAP/fundam…那么fundamental-vue到底算Fiori Fundamentals还是Web Component?一张图来回答:关于这两个概念大家如果有疑问,请直接留言给我,或者点击“阅读原文”,跳转到SAP社区上给Peter留言,感谢阅读。相关阅读SAP UI5和微信小程序对比之我见当我用UI5诊断工具时我用些什么在Kubernetes上运行SAP UI5应用(上)在Kubernetes上运行SAP UI5应用(下)SAP Fiori + Vue = ?SAP Fiori应用的三种部署方式Jerry的Fiori原创文章合集SAP成都C4C小李探花:浅谈Fiori Design GuidelinesJerry和您聊聊Chrome开发者工具Jerry的UI5框架代码自学教程Jerry的碎碎念:SAPUI5, Angular, React和VueSAP Cloud for Customer 使用SAP UI5的独特之处要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

February 24, 2019 · 1 min · jiezi

SAP 前端技术的演化史简介

Jerry之前曾经写过一篇微信公众号文章,题目叫<<SAP UI和Salesforce UI开发漫谈>>关注我的公号“汪子熙”后,在历史菜单“前端开发相关”里即可找到这篇文章:该文章简单回顾了SAP UI技术的发展历史,然后提了下Salesforce的Apex和Lighting Component等技术和框架。目录SAP UISAP GUI + DynproWeb DynproBSP/CRM WebClient UISAP UI5/FioriUI5 in SAP Cloud for CustomerHybris Enterprise Commerce PlatformSalesforce UIApexLightning ExperienceAura FrameworkLightning Component FrameworkVisualforce我也画了张简单的图:R1和针对于大型机的R2对我们来说实在太古老了,对我们来说,只能通过SAPGUI里的复古主题,即Classical Theme来体验一下这些老古董的外观风采。到了1992年出现了类似JSP技术的BSP(business server page),能够借助在服务器端执行的ABAP语言实现动态网页效果。在运行时,每个BSP页面会自动生成一个临时的ABAP类,执行这些BSP页面上嵌入的ABAP代码,执行的结果再渲染成原生的HTML代码。值得一提的是,BSP技术兼容普通的HTML/JavaScript应用,换句话说,几乎所有能运行在除Netweaver以为的web服务器上的基于HTML/JavaScript的web应用,也能以BSP为载体,运行在Netweaver上。因此,即使是如今SAP的旗舰级产品S/4HANA里的很多Fiori UI应用,也是以BSP应用为载体存储在Netweaver上的。比如S/4HANA物料主数据管理的Fiori应用,其名称在Chrome开发者工具里能看到:这个BSP应用在Netweaver上能找到:诞生于1992年的BSP技术到了今天还在服役,这本身就是一个奇迹了。当然它本身由于历史原因也有一些局限:开发效率不够高,没有类似后来UI5里控件库的概念,导致开发人员需要重复造很多轮子。SAP后来自己也发布了一些BSP Extension,类似JSP里的tag,以此来弥补开发效率的缺陷。另外BSP的开发工具在SAPGUI里只有事务码SE80,这个工具在做HTML和JavaScript开发时显得不够友好。因此后期SAP Fiori开发也采取了在本地现代IDE比如Eclipse里做开发,完毕后再上传到Netweaver自动生成BSP的方式。没有MVC的概念,在大型企业级应用开发中显得力不从心。正是由于暴露了这两个缺陷,促成了WebUI和Webdynpro的问世。对这两种前端技术的详细介绍,请参考Jerry之前提到的微信文章:SAP UI和Salesforce UI开发漫谈,这里不再重复,只是聊聊一些该文章中没有提过的内容。ABAP Webdynpro的亮点就是能够以所见即所得的方式进行UI界面开发,缺点是不再支持类似BSP那样兼容传统的HTML/JavaScript,因此无法实现某些对界面复杂度和交互性要求较高的需求。而WebUI在继承了BSP所有优点的同时,在BSP基础上提供了对MVC的封装,使得开发效率大大提高,同时开发出来的Web应用结构清晰,不再会出现一个视图页面几千行代码的情况。下图是一个典型的WebUI模型,MVC三层在workbench里有清晰的界定。WebUI和ABAP Webdynpro至今仍广泛应用于SAP产品中。在S/4HANA的CRM模块里,WebUI继续扮演着非常重要的角色,详情请阅读我下面这篇文章:Hello World, S/4HANA for Customer Management 1.0而Webdynpro,是SAP SRM UI开发的主流技术。搜索公网上所有使用了SAP BSP技术的网站:https://www.google.com/search…:/sap/bc/bsp/&gws_rd=ssl使用了Webdynpro的:随着时间的推移,用户对移动设备上访问网页的体验要求越来越高,因此有了SAP从业者现在很熟悉的前端技术:SAP UI5。关于UI5最新的技术发展方向,请关注我的公众号“汪子熙”,阅读我写的这篇文章:Fiori Fundamentals和SAP UI5 Web Components要获取更多Jerry的原创文章,请关注公众号"汪子熙":

February 24, 2019 · 1 min · jiezi

用ABAP代码读取S/4HANA生产订单工序明细

在S/4HANA事务码CO03显示的Production Order里,我希望用ABAP代码显示出该订单的operation(工序)ID,描述和状态Status,如下图所示:很简单的几行ABAP代码:DATA: lt_operation TYPE TABLE OF afvgd.CALL FUNCTION ‘PM_ORDER_DATA_READ’ EXPORTING order_number = ‘000001000381’ TABLES iafvgd = lt_operation EXCEPTIONS order_not_found = 1.IF sy-subrc <> 0. WRITE:/ ’not exist’. RETURN.ENDIF.需要读取的数据都在这里:要获取更多Jerry的原创文章,请关注公众号"汪子熙":

February 24, 2019 · 1 min · jiezi

使用Visual Studio Code编写和激活ABAP代码 (上)

猪年春节后的第一篇,Jerry祝各位猪年大吉!2019年的六分之一马上就快过完了,不知道大家在新的一年是否给自己定了新的小目标呢?这里Jerry先预祝大家到2019年年底的时候,在年初制定的小目标都能实现。2018年4月之前,Jerry一半时间为SAP S4CRM团队工作,剩下的一半时间为SAP C4C团队工作,所以那段时间大家能发现,Jerry公众号的文章主要是围绕着这两个SAP产品来写的。4月之后,Jerry换组,到了新的部门,工作内容也发生了变化,不再专注于某个特定的SAP产品,而是项目需要我熟悉什么产品,我就得熟悉什么产品,所以之后我的公众号文章,主题也逐渐多种多样起来。言归正传,Jerry之前的文章 那些年我用过的SAP IDE 曾经介绍过除了SAPGUI之外的其他ABAP开发工具和ABAP代码浏览工具。得益于Netweaver职责清晰的三层架构,提供了ABAP开发环境和运行环境的应用服务器层(下图中间的Application server layer)作为ABAP应用的核心, 其上可以灵活适配不同的展现层(Presentation layer), 比如WebIDE, Eclipse,和今天要介绍的Visual Studio Code。上图中应用服务器层的底层是数据库服务器层,Netweaver也支持多种主流数据库提供商的服务。例如下图是Jerry使用的一个Netweaver系统,支持包括SAP HANA在内的十种数据库管理系统(DBMS)。我们简单回顾下之前Jerry介绍过的不同的ABAP开发工具。首先是ABAP Development Tool(简称ADT), 对ABAP程序提供增删查改和激活操作的函数,通过位于路径sap/bc/下面的SICF服务节点adt暴露给外部消费者。ABAP Development Tool的Java端实现就是Eclipse的一个扩展,使用JCO(Java Connector)连接ABAP后台的adt服务,实现对ABAP程序的操作。关于ABAP Development Tool的细节,Jerry以前已经做过详细介绍,这里不再赘述,可以参考我这些文章:不喜欢SAP GUI?那试试用Eclipse进行ABAP开发吧Jerry在SAP Community上写给老外看的文章:https://blogs.sap.com/2014/08…而在浏览器里编写ABAP,即通常意义上的ABAP WebIDE,实现方式有两种。一种是通过传统的ITS(Internet Trasaction Server),通过这种方式在浏览器里显示的ABAP代码缺乏语法高亮:Jerry写过的相关博客:Open your SAP GUI transaction in Fiori launchpadhttps://blogs.sap.com/2016/12…How is old SAP GUI transaction embedded into Fiori launchpadhttps://blogs.sap.com/2016/12…另一种技术就是S/4HANA某些应用,比如Custom Logic采用的,支持语法高亮。当然这个语法高亮的支持不是天上掉下来的,详细实现参考我的博客:How ABAP syntax highlight is implemented in WebIDE launched via browserhttps://blogs.sap.com/2018/03…再回到今天聊的Visual Studio Code。SAP成都研究院很多前端开发的同事都向我推荐过这个IDE。Jerry试用过之后,印象最深的就是它那超快的启动速度,一流的扩展性和繁荣的生态圈。其扩展应用的丰富程度不亚于Sublime Text和Eclipse这些老牌开发工具。和SAP自研的ABAP Development Tool思路一样,本文介绍的Visual Studio Code扩展应用,ABAP Remote File System,也是通过另一种编程语言TypeScript去远程消费ABAP后台程序的增删查改服务。该扩展应用的作者叫Marcello,一位居住在伦敦的程序猿(Jerry想起了西甲皇家马德里足球队昔日的队宠)。这个Visual Studio Code的扩展是开源的,github仓库地址:https://github.com/marcellour…安装和配置的步骤在仓库的readme里有详细说明,最简单的方式就是在Visual Studio Code里直接用abap作为关键字搜索Market place,然后点Install安装。这个扩展的配置文件settings.json的内容可以参考下图:配置完成后,在Visual Studio Code的命令栏里能看到连接ABAP系统的指令和settings.json里配置的两条记录,任选一个后登入系统,显示该系统下的ABAP程序资源。操作它们的方式和基于Eclipse的ABAP Development Tool大同小异。当然也有一些Visual Studio Code提供的特色功能,比如下图这种类Google的即时搜索。这个扩展本身是不提供ABAP代码语法高亮的,需要安装另一个来自Lars Hvam贡献的语法高亮扩展。安装完毕后,ABAP的语法高亮也能顺利在Visual Studio Code里工作了。下面这张动图来自Marcello,演示了通过Visual Studio Code的这个扩展实现ABAP代码的基本编辑。作者在他的readme也明确注明,这个扩展还处于Beta测试阶段,使用者需自己承担风险。在Jerry看来,Visual Studio Code的这个扩展,如果用来做ABAP开发的话,功能还相对局限,但是如果对SAPGUI或者ABAP Development Tool产生了审美疲劳,想换一种工具来阅读ABAP源代码,那么它和下图的Sublime Text一样,都是不错的选择。将来如果Jerry有空,会在这篇文章的下半部分简单介绍下这个扩展的TypeScript实现细节。另外,今年Jerry也会争取能分享一些SAP云平台上ABAP编程环境的相关内容,敬请期待。感谢阅读。更多阅读动手使用ABAP Channel开发一些小工具,提升日常工作效率聊聊C语言和ABAPABAP vs Java, 蛙泳 vs 自由泳300行ABAP代码实现一个最简单的区块链原型Jerry的ABAP原创技术文章合集ABAP开发人员未来应该学些什么Jerry的ABAP, Java和JavaScript乱炖我用ABAP做过的那些无聊的事情不喜欢SAP GUI?那试试用Eclipse进行ABAP开发吧那些年我用过的SAP IDE要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

February 24, 2019 · 1 min · jiezi

Salesforce的多态存储和SAP C4C的元数据存储仓库

SalesforceForce.com integrates and optimizes several different data persistence technologies to deliver transparent polyglot persistence for all your applications and devices. With Force.com, you don’t have to deal with the complexity of trying to integrate, manage, test, and support several systems, and you only have to code to a single API, no matter which type of persistence is optimal for a given situation. The following figure is an overview of a sampling of Force.com’s persistence technology.Salesforce存在一个Polyglot Persistence多态存储的概念。应用程序可以通过Polyglot persistence暴露出的统一接口去访问平台上的数据,而无需关心这些数据背后具体的存储技术到底是Transaction Engine, 还是由常驻内存提供,亦或是由支持全文本查找的搜索引擎提供。SAP C4C(Cloud for Customer)作为SAP提供的一款SaaS CRM解决方案,C4C也存在类似Salesforce Polyglot Persistence的设计,我们称之为元数据仓库存储。我们在cloud application studio的package下面能看到许许多多的开发对象:可以想象,这二三十种开发对象后台的存储逻辑和技术都各不相同。每次用户登录Cloud application studio,打开自己工作的package后,都会从后台将自己创建的类型各异的开发对象取出然后显示在studio里。为了给Cloud application studio工具端和其他消费者(比如C4C前端UI)提供一个统一高效的API去C4C后台读取这些模型的数据,C4C设计了一个元数据存储仓库,该仓库提供了一个优化过后的API,相当于设计模式里的Facade(外观模式/门面模式)。该API会根据具体被访问的对象,将请求转发到该对象对应的存储服务提供者(Access service provider)上去。对于API的消费者来说,这些对象具体的存储技术是完全透明的,不需要知道。要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

February 15, 2019 · 1 min · jiezi

Salesforce和SAP Netweaver里数据库表的元数据设计

从Salesforce官网可以了解到Salesforce的force.com平台里数据库表的设计:https://developer.salesforce….Every logical database object that Force.com exposes is internally managed using metadata. Objects, (tables in traditional relational database parlance), fields, stored procedures, and database triggers are all abstract constructs that exist merely as metadata in Force.com’s Universal Data Dictionary (UDD). 每个force.com暴露出来的逻辑数据库对象在内部都被metadata元数据管理。数据库表,表的字段,存储过程和数据库触发器,在force.com里只不过都是抽象的实体,以元数据的方式存在于force.com的UDD数据字段中。而SAP Netweaver也有类似salesforce force.com的UDD概念,在Netweaver ABAP里成为ABAP Data Dictionary - DDIC,事务码SE11打开。SAP的数据库表有design time和runtime运行时的概念。也支持在ABAP程序运行时动态生成新的数据库表,以及运行时根据数据库表对应的实例,反方向得到其design time信息的方法,类似其他编程语言比如Java中的反射,不过在ABAP里我们不习惯这样叫,而是称之为ABAP Run Time Type Identification, 简称RTTI。以上图显示的数据库表TADIR为例,其字段的元数据都存储在另一张表DD03L里。通过查询条件TABNAME = TADIR, 即可从数据库表DD03L里找到TADIR所有字段的元数据,包括字段名,字段的ABAP data element名称,内部数据类型和字段长度等等。当然大多数时候我们如果需要获取这些元数据,不需要通过查表的方式,ABAP DDIC给我们提供了丰富的API,这些函数的命名有规律:DD*GET:而一张表的运行时信息,通过菜单Utilities->Runtime Object->Display查看:不过这些信息一般来说和ABAP应用开发人员关系不大,所以很少留意。要获取更多Jerry的原创文章,请关注公众号"汪子熙":

February 14, 2019 · 1 min · jiezi

Salesforce平台支持多租户Multi tenant的核心设计思路

Multitenancy is the fundamental technology that clouds use to share IT resources cost-efficiently and securely.多租户支持是所有云服务提供商都需要着力实现的一种技术,用于云基础设施上在成本可控和保证安全性的前提下进行IT资源分享。多租户支持面临的四大挑战:how to keep tenant-specific data secure in a shared database so that one tenant can’t see another tenant’s data?如何保证共享数据库内不同租户间的数据隔离,通俗的说,一个租户不应该看到其他租户的数据。当一个租户对其拥有的schema对象或者应用编程接口进行调整时,不应影响到其他租户的功能和整个系统的可用性。How can one tenant customize various schema objects and an application’s user interface in real time without affecting the functionality or availability of the system for all other tenants?How can the system’s code base be patched or upgraded without breaking tenant-specific schemas?系统基层实现发生变动,比如代码版本升级,或者新的补丁进来时,不应该破坏每个租户私有的对象。And how will the system’s response time scale as tens of thousands of tenants use the service?随着系统租户数量的增加,整个系统的响应时间不应该急剧下降。Force.com’s core technology uses a runtime engine that materializes all application data from metadata—data about the data itself. In Force.com’s well-defined metadata-driven architecture, there is a clear separation of the compiled runtime database engine (kernel), tenant data, and the metadata that describes each application. These distinct boundaries make it possible to independently update the system kernel and tenant-specific applications and schemas, with virtually no risk of one affecting the others.Salesforce应对这些挑战的设计是,采取了一种运行时引擎的思路,所有的应用数据都通过元数据生成,即所谓元数据驱动的架构(metadata driven architecture)。这样一来,模型的元数据作为输入,交给运行时引擎加工,生成运行时使用的模型和数据,三者各司其职,有严格的区分,实现了一种高度动态的内核。注:本文的英文文字和图片来自Salesforce官网:https://developer.salesforce….中文文字为本文作者原创内容。要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

February 14, 2019 · 1 min · jiezi

SAP ABAP里数据库表的Storage Parameters从哪里来的

如何查看ABAP数据库表的storage parameter?事务码SE11,utilities->Database Object->Database Utility:点这个Storage Parameters:上面SAPGUI里显示的数据实际来自HANA数据库里的System view:TABLES, 使用如下的SQL语句就能查询到COMM_PORODUCT的storage parameters(存储参数了):SELECT *FROM “SYS”.“TABLES"WHERE SCHEMA_NAME = ‘SAPAG3’ AND TABLE_NAME = ‘COMM_PRODUCT’要获取更多Jerry的原创文章,请关注公众号"汪子熙”:

February 14, 2019 · 1 min · jiezi

Salesforce和SAP HANA的元数据访问加速

Salesforce在Jerry的其他文章曾经提到,Salesforce里运行时对象均是通过静态存储的元数据,经过Runtime engine加工而成的。Because metadata is a key ingredient of Force.com applications, the system’s runtime engine must optimize access to metadata; otherwise, frequent metadata access would prevent the service from scaling. 既然元数据在salesforce平台中扮演了如此重要的角色,那么运行时引擎对元数据的高效访问就成为一个重中之重的话题,如果达不到这个目标,频繁的元数据低效访问将无法保证平台上提供服务的高扩展性 high scalability。With this potential bottleneck in mind, Force.com uses massive and sophisticated metadata caches to maintain the most recently used metadata in memory, avoid performance-sapping disk I/O and code recompilations, and improve application response times.Salesforce平台设计了很多复杂的元数据缓存机制,确保最近访问过的元数据驻留在内存里,避免了磁盘IO的开销和代码的重编译,从而确保整个应用的响应时间不会影响元数据访问受到影响。SAPABAP Netweaver也有类似的设计,把很多需要高效访问的数据特别是应用程序的元数据存储到应用服务器的shared memory共享内存里。使用事务码SHMM查看shared memory内容:SAP HANA里还能通过系统视图system view M_METADATA_CACHE_STATISTICS来对元数据的缓存访问进行分析:要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

February 14, 2019 · 1 min · jiezi

S/4HANA服务订单Service Order的批量创建

我工作中接到一个任务,需要在性能测试系统里创建一亿条服务订单service order来做性能测试。这么大规模的数据量,当然只能用代码来创建了。本文提到的所有ABAP代码,我均已上传到我的Github上了:https://github.com/i042416/KnowlegeRepository/tree/master/ABAP/S4This document provides guide about how to generate a large volume of service order ( confirmation ) and service request test data in S4CRM performance test system for performance measurement purpose.The data is generated based on a series of ABAP reports. ZCRMS4_CREATE_MATERIAL_OPTPattern for material number: prefix for generated material ID. Take above screenshot for example, once executed, you will get a series of materials with the following material ID:Pattern for short text: for example if you specify “Android phone S”, you will get the following description pattern:ZCRMS4_HOME_CREATE_BPSZCRMS4_HOME_CREATE_ORDER_LOOPThis report is used to create a large number of Service Orders.Order description: define the description pattern of created service orders.For example, the input parameter in the above screenshot will lead to the created orders with the following description patterns:Max number of created items: if you specify an integer N, a random number among 1 ~ N of line items will be created for each Service order.Max item quantity value: if you specify an integer N, the line item quantity value will be assigned with a random integer among 1 ~ N.Material Number Range:Let’s say you have first created 10000 materials with ID prefix as “ANDROID”, which means now in table MARA you already have 10000 records with ID starting from ANDROID00000000001 and ending with ANDROID00000010000.Now in this report, you specify Material Number Range as ANDROID00000000001 and ANDROID00000010000, so that when this report create a new line item, it will randomly pick up a material among this material repository and assigned to created line item.Sold-to party range: behaves the same as Material Number Range. You have to first create a series of business partners and write down their ID prefix, for example you create 100 BP with prefix BCP. Then maintain Sold-to party range as BCP0000000001 to BCP0000000100. This report will randomly pick one among the 100 BP and assigned it as the Sold to party in Service Order’s header level.ZCRMS4_HOME_CREATE_SR_LOOPUsed for Service Request mass data generation. The input parameter behaves the same as ZCRMS4_HOME_CREATE_ORDER_LOOP.During the period that those reports are running, you can use report ZTABLESIZE to check the number of created records currently. This report will list table name, table record number and table storage size accordingly.You are supposed to run these reports via background job to avoid TIME OUT issue.Please do not occupy ALL Background work processors so that the normal system operation like TR import are not hindered.要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

February 14, 2019 · 2 min · jiezi

S/4HANA生产订单的标准状态和透明工厂原型状态的映射

事务码CO03查看生产订单的状态:从下面的界面能看出S/4HANA里生产订单在任意时刻可能存在多个状态:生产订单的ID和状态ID的关系是1:N,维护在数据库表VSAUFK里:如何把上述SAP系统标准状态映射到透明工厂原型的5个状态去呢?目前的映射实现采取的是“关键状态法”:只要生产订单的状态里包含I0048 - distributed to MES, 就认为该订单处于组装状态只要生产订单的状态里包含I0012 - distributed to MES, 就认为该订单处于已交货状态如果C4C创建的销售订单还未同步到S/4HANA,或者虽然同步到S/4HANA,但是S/4HANA的生产订单尚未创建完成,即下图右边灰色区域的时间窗口所示,此时如果查询生产订单状态,API会返回状态排队中.也就是说,app里尚存在两个状态,“加工”和“检测”,在S/4HANA生产订单里找不到对应可映射的标准状态。要获取更多Jerry的原创文章,请关注公众号"汪子熙":

February 14, 2019 · 1 min · jiezi

SAPGUI系统登录页面配置的SAProuter有什么用

大家在安装完SAPGUI后,准备添加系统列表进行登录时,注意过这个SAProuter字段么?从SAP的帮助文档上可以找到SAProuter的定义:https://help.sap.com/saphelp_…SAProuter is an SAP program that acts as an intermediate station (proxy) in a network connection between SAP systems, or between SAP systems and external networks. SAProuter controls the access to your network, and, as such, is a useful enhancement to an existing firewall system (port filter).Figuratively, the firewall forms an impenetrable “wall”around your network. However, since particular types of connections need to penetrate this wall, a “gate”has to be made in the firewall. SAProuter assumes control of this gate.In short, SAProuter provides you with the means of controlling access to your SAP system.SAProuter是一个SAP发布的应用,在SAP系统与系统之间,SAP系统与外部网络之间扮演着代理的角色。SAProuter能实现对SAP系统的访问控制,是企业防火墙的有效补充。如下图所示,部署于企业局域网的客户端SAPGUI进行系统登录,登录请求通过局域网内的SAP router转发到Internet网络上的另一台SAP Router,再转发给部署于企业内网的ERP服务器。上述描述的场景里,形象的说好比在ERP服务器所在的企业内网和SAPGUI的客户端所在的内网打了两个洞,在洞里部署两台SAP router确保只有受限的网络请求能够进出这两个被防火墙保护的安全网络。这种“打洞”的思路在SAP另一款解决方案:SAP cloud connector里有类似的用法:详情参考我的文章:使用Java+SAP云平台+SAP Cloud Connector调用ABAP On-Premise系统里的函数:https://www.jianshu.com/p/3f2…我们可以把用SAPGUI登录系统的快捷方式保存到本地,下次双击即可直接用SAPGUI登入系统:用记事本打开,发现这些.sap文件的内容如下:我们主要观看红色高亮部分。H表示主机名,S表示服务Service。要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

February 14, 2019 · 1 min · jiezi

为什么S/4HANA的生产订单创建后会自动release

在S/4HANA系统里我们观察到通过函数CO_61_ORDER_EDIT创建的生产订单会自动释放Release:通过第86行的IF语句的条件检测不难找到原因。变量PROFILE_TMP的类型为TCO43:这个scheduling profile的配置在路径Production->Shop Floor Control->Master Data->Define Production Scheduling Profile里:如下图所示:Automatic Actions标签页里的On Creation->Release勾选中,意思就是Production Order创建后自动释放。要获取更多Jerry的原创文章,请关注公众号"汪子熙":

February 14, 2019 · 1 min · jiezi

为什么S/4HANA的销售订单创建会触发生产订单的创建

调用S/4HANA销售订单创建函数SD_SALES_DOCU_MAINTAIN创建一个销售订单时,会触发生产订单的创建。销售订单的每个行项目对应一个独立的生产订单,SD_SALES_DOCU_MAINTAIN相当于CRM里的CRM_ORDER_MAINTAIN,在LOOP里处理每一个行项目:观察这个函数内部的调用栈,发现一个subroutine EIGENFERTIGUNG_BEARBEITEN.:EIGENFERTIGUNG的意思是Own production:BEARBEITEN的意思是TO EDIT:在这个增强里,硬编码了通过Production order maintain的函数CO_61_ORDER_EDIT去创建production order的逻辑:要获取更多Jerry的原创文章,请关注公众号"汪子熙":

February 14, 2019 · 1 min · jiezi

如何给SAP C4C的产品主数据division配置出新的下拉选项

如图:C4C产品主数据division字段默认的下拉菜单选项:切换成调试模式,找到UI这个字段绑定的模型字段名称:/Root/MaterialDivision:再找到这个UI模型字段绑定到的core BO字段:Material.Common.MaterialDivisionCode: 进入Business Configuration的Activity List,找到Division的配置:在这里添加一行新纪录:03-沈阳自动所产品线要获取更多Jerry的原创文章,请关注公众号"汪子熙":

February 14, 2019 · 1 min · jiezi

什么是SAP GUI的client

我们用SAPGUI登录某个系统时,除了用户名和密码外,还要指定一个必填字段client:这个client是什么东东?看文档:SAP Client is the highest hierarchical organizational unit within an SAP system that contains master records and tables. The transactions processed at SAP client level is valid and applicable for all company code data and enterprise structures.Client is a three digits numerical key and from a business point of view, client represents as a corporate group. User is required to enter client key while logging on to the SAP system.SAP client是SAP系统里包含了主数据和业务数据的层级结构最高的组织单元标识符,业务上来说代表一个企业,技术类型是一个三位的正整数。Important Client CharacteristicsEvery SAP user’s access and authorizations must assigned to the SAP client on which client users are working.It is used to differentiate between development, quality and product system within the same or different serverThe data entered at client level is valid for all organizational units.Each client can have one or more company codes, plants and locations but there will be not have connection between clients.事务码SCC4查看Netweaver系统上所有已创建的client列表:要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

February 14, 2019 · 1 min · jiezi

S/4HANA生产订单增强WORKORDER_UPDATE方法BEFORE_UPDATE参数分析

题目这个增强的输入参数很恐怖,长长的一串: CALL BADI l_badi->BEFORE_UPDATE EXPORTING IT_PIINSTRUCTIONVALUE = IT_PIINSTRUCTIONVALUE IT_PIINSTRUCTION = IT_PIINSTRUCTION IT_PMPARTNER_OLD = IT_PMPARTNER_OLD IT_PMPARTNER = IT_PMPARTNER IT_PRT_ALLOCATION_OLD = IT_PRT_ALLOCATION_OLD IT_PRT_ALLOCATION = IT_PRT_ALLOCATION IT_DOCLINK_OLD = IT_DOCLINK_OLD IT_DOCLINK = IT_DOCLINK IT_OPR_RELATIONS_OLD = IT_OPR_RELATIONS_OLD IT_OPR_RELATIONS = IT_OPR_RELATIONS IT_STATUS_OLD = IT_STATUS_OLD IT_STATUS = IT_STATUS IT_PLANNED_ORDER = IT_PLANNED_ORDER IT_MILESTONE_OLD = IT_MILESTONE_OLD IT_MILESTONE = IT_MILESTONE IT_PSTEXT_OLD = IT_PSTEXT_OLD IT_PSTEXT = IT_PSTEXT IT_RELATIONSHIP_OLD = IT_RELATIONSHIP_OLD IT_RELATIONSHIP = IT_RELATIONSHIP IT_COMPONENT_OLD = IT_COMPONENT_OLD IT_COMPONENT = IT_COMPONENT IT_OPERATION_OLD_AFVU = IT_OPERATION_OLD_AFVU IT_OPERATION_OLD_AFVV = IT_OPERATION_OLD_AFVV IT_OPERATION_OLD_AFVC = IT_OPERATION_OLD_AFVC IT_OPERATION = IT_OPERATION IT_SEQUENCE_OLD = IT_SEQUENCE_OLD IT_SEQUENCE = IT_SEQUENCE IT_ITEM_OLD = IT_ITEM_OLD IT_ITEM = IT_ITEM IT_HEADER_OLD = IT_HEADER_OLD IT_HEADER = IT_HEADER.好在绝大部分内表都是空的。我们就一起来看看非空列表里包含的数据。IT_STATUS状态迁移。STAT是SAP系统状态ID,其描述信息在表TJ02T里能查到。比如I0001状态的四位标识符是CRTD,意思是已创建-CreatedINACT栏为X的状态代表该Production Order当前已经从该状态跳转到了其他状态。上图的意思是该Production Order已经从状态I0001已创建,进入了状态I0002- Released已释放。IT_COMPONENT要理解Production Order component这个概念,我们先看一个已经创建好的生产订单。下图component的意思是为了生产REDUCER_A这个成品,我们需要生产它的组件0010 COVER1, 0020 AXIS和0030 BASE。那么REDUCER_A和其三个组件运行时的信息,就维护在内表IT_COMPONENT里。IT_OPERATION同理,一个生产订单可以包含若干生产工序,比如下图的Manual processing, Maching,Assembly和Testing,对应的系统状态都是REL - Released。这些工序信息维护在内表IT_OPERATION里IT_SEQUENCE该生产订单的前置文档信息,即我们说的文档流 - document flowIT_ITEM待生产的成品明细,比如物料主数据ID,待生产数量,单位等。IT_HEADER很好理解,生产订单抬头信息:要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

February 14, 2019 · 1 min · jiezi

SAP R/3系统的R和3分别代表什么含义,负载均衡的实现原理

1972年,SAP诞生,推出了RF系统(实时财务会计系统), 后来命名为R1。R指Real time。3既指第三代系统,又代表3层架构。三层架构分别为下图的Presentation server Layer,Application server layer和Database server layer。值得一提的是,时光之轮已经驶入了2019年的猪年,presentation server层除了上图传统的SAPGUI外,也支持其他的技术:ABAP In EclipseABAP in WebIDEABAP in Visual Studio Code在我 微信公众号“汪子熙”里曾经发表过一篇公众号文章:那些年我用过的SAP IDE里面介绍过上述提到的不同的presentation layer(展现层)的实现技术。下图是在Eclipse里进行ABAP开发:在浏览器里进行ABAP开发:在微软的Visual Studio Code里开发:再看中间的应用服务器层:这里能看出应用服务器层是支持负载均衡的,SAPGUI的使用者会指定消息服务器Message Server的地址,用户通过SAPGUI登录时,消息服务器会将用户请求分配到负载最小的应用服务器实例上。下图含义为在任意一个SAP系统的服务器实例里,使用事务码SM51都可以查看该系统所有的应用服务器实例。而数据库服务器的实例,从菜单System-Status里可以得到。SAP Netweaver 应用服务器可以连接多个数据库,每个数据库可以来自不同的数据库提供商。使用事务码DBCO在Netweaver应用服务器上维护指向数据库服务器的连接明细:从DBMS这个字段能得到所有NetWeaver支持的数据库服务器,比如MaxDB,Infomix,微软的SQL Server,Oracle DB等。要获取更多Jerry的原创文章,请关注公众号"汪子熙":

February 14, 2019 · 1 min · jiezi

SAP S/4HANA生产订单创建时使用的工厂数据是从什么地方带出来的

大家如果使用我github上的这段代码创建S/4HANA的生产订单时,一定会发现,我在代码里并没有硬编码来指定生产订单的ID,然而运行时会发现我在系统里配置的这个2800被自动使用了,这是怎么做到的呢?https://github.com/i042416/Kn…通过阅读SAP S/4HANA有关生产订单的标准代码发现,生产订单使用的plant工厂数据来自表VBAP的字段WERKS。FV45EFMA_VBAP正是销售订单的行项目表。问题就转化为这个2800和销售订单行项目的关系。这个2800来自结构体KUWEV的字段DWERK Delivering Plant:Ship-to Party’s View of the Customer Master RecordFV45PF0K_KOMKG_KOMPG_FUELLEN,第45行。第32行重要的函数 RV_CUSTOMER_MATERIAL_READDA_KUNNR:这个字段存放的是我代码里硬编码的这个客户ID:VBAK-VKORG:VBAK-VKORGVTWEG: distribution channelSPART: division然后通过函数LOCATION_ISS_PLANT_DETERMINE决定出plant:从这里能看出这个plant来自客户主数据的ship to 视图:kuwev KUWEV-DWERKkuwev的值从哪里来?从KNVV的字段VWERK里来:knvv是客户主数据的Sales data存储表:如何查看S/4HANA里的客户主数据的Sales相关数据?事务码BP:根据客户ID搜索之后,在明细页面里将Display in BP role的下拉菜单宣称FLCU01 Customer:点这个Sales and distribution按钮:2800就维护在这里的:要获取更多Jerry的原创文章,请关注公众号"汪子熙":

February 3, 2019 · 1 min · jiezi

一些通过SAP ABAP代码审查得出的ABAP编程最佳实践

这两个IF ELSE分支里检测的条件其实逻辑上来说都是同一类,应该合并到一个IF分支里进行检查:It is an expensive operation to open a file in application server with 50MB file size.Current logic is:1. Open the file in application server2. Read the file content line by line3. If the file is regarding IPG or MIDH or TPG, handle with each line separatelyThe correct logic should be:1. Check the file path whether it is IPG or MIDH or TPG related. If not, quit the report.2. Handle with each line directly without evaluate file path in the BIG loop.The validation logic for input records should be improvedLoop at all service BOM, check whether the ID in current loop does exist in validation table lt_valid_prod or lt_valid_sp. If so, delete them via DELETE TABLE XXX FROM <current line>.Improvement: use DELETE XXX WHERE product_id NOT IN <range table>. It is more efficient when lt_srv_bom_file has a huge number of records. See comparison below ( unit: second )这是一个性能问题。使用ABAP原生支持的NOT IN关键字可以获得更好的性能。性能评测如下:Avoid using SELECT to access table with a large number of entriesIn product / IObject area, the best practice is to use OPEN CURSOR / FETCH NEXT CURSOR to access big DB table.如果需要用ABAP OPEN SQL读取一张包含海量记录的数据库表,那么推荐使用OPEN CURSOR进行分块读取。Although this solution will spend almost the same time to fetch the data from DB, it has far less memory consumption compared with using SELECT to fetch ALL data from DB at one time.The original dump due to out of memory issue could be eliminated by replace SELECT with OPEN CURSOR statement.这种方式和直接用SELECT相比,能显著减少内存消耗量。使用并发编程提高应用程序场景通过下面这段代码模拟一个费时的ABAP程序:定义一个ABAP函数:这个函数里执行一大堆计算,然后把传入的product ID写到一张自定义表ZJERRY1里。调用这个函数的代码:注意第二种方案使用STARTING NEW TASK达到的并发执行效果:通过比较,第二种解决方案的效率是第一种的四倍。1. The more CPU & DB time spent in ZINSERT, the better performance will be gained by usingparallel processing (Asynchronous RFC call).2. The more number of ZINSERT call, the better performance will be gained by using parallelprocessing.要获取更多Jerry的原创文章,请关注公众号"汪子熙":

February 3, 2019 · 2 min · jiezi

SAP HANA Delivery Unit概念简述

介绍在SAP HANA应用开发领域里,我们通常用package来存储modeler views和XS工程等模型。这些包应该被部署到最终的生产服务器上。Delivery Unit是SAP HANA原生开发对象的部署方式,可以被看成一系列包的集合,用于Transportation management的统一管理。SAP HANA提供了一个统一的管理平台,称为HANA Application Lifecycle Management来管理Delivery Unit. 只有具有权限“sap.hana.xs.lm.roles: :Administrator”的用户才能操作Delivery Unit。 下面介绍操作Delivery Unit的两种方式。SAP HANA Studio选择右键菜单里的Transport Management:直接使用具有下列命名规范的url:http://&lt;host_address>:80<instance_number>/sap/hana/xs/lm/index.html我们能用HANA Application Lifecycle Management做哪些事情?导入/导出/创建Delivery unit,搜索包。 第一次使用HANA Application Lifecycle Management时,我们必须提供一个Vendor ID。Delivery Unit的创建页面:在SAP HANA SP07里, HANA安装完毕后,系统会自动创建一些delivery unit,位于PRODUCTS->Delivery Units下面. 我们可以在里面增加,删除或者更改Delivery Unit。Delivery Unit本身的创建操作是很简单的:将包分配给这个Delivery Unit:Delivery Unit和里面包含的包可以通过下面的菜单导出成.tgz文件:导入Delivery Unit时,其包含的包会在HANA实例上创建:SAP HANA Studio提供了DU的管理控制台,切换到modeler视图,选择Setup下面的Delivery Unit进入控制台:创建DU,给其分配包:导入/导出DU:要获取更多Jerry的原创文章,请关注公众号"汪子熙":

February 3, 2019 · 1 min · jiezi

SAP S/4HANA生产订单的BAdI增强点之Initialize方法

在S/4HANA里创建生产订单时,有一个增强点WORKORDER_UPDATE:这个CAUFVDB里存放的是生产订单抬头级别的数据:我们来观察下运行时这个结构里存放的数据。请大家用我github上这个简单的报表创建一个生产订单:https://github.com/i042416/KnowlegeRepository/blob/master/ABAP/SmallApp/209_create_S4_SalesOrder.abap断点触发后,结构体CAUFVDB里的字段,我们一个一个分析:AUFNR: 这个字段代表生产订单的ID,因此此时还没有保存,所以是临时ID。WERKS 工厂ID plant ID,2800。DISPO MRP controller for the order:001PVERW: 1在表T411里发现1代表Production:PLNBEZ:待生产的物料主数据IDPLNAW: Application of the task listP的含义,在表TCA09里找到代表Routings for productionPLNTY:Task list type: N在表TCA01里代表routingPLNNR:Key for Task List Group50000023PLNAL: Group counterPDATV: valid from dateAUFLD: Date of BOM Explosion/Routing TransferAUFPL: Routing number of operations in the orderRSNUM: Number of reservation/dependent requirementsGAMNG: Total Order Quantity 要生产的产品个数GMEIN: 生产的产品的单位TERKZ: 2 - scheduling type2在表T482里的类型是backwards schedulingAUART: 生产订单类型 PP04AUTYP:生产订单category:10 PP Production OrderBUKRS: company codeKAPPL:application code KA条件技术表里KA代表OrdersKALSM:PP-PC1 costing sheetZAEHL和MZAEHL都是内部计数器KLVARP:Costing Variant for Planned CostsKLVARI:Costing Variant For Actual CostsSFCPF:Production Scheduling Profile 这个SIA是我自己配的。AVOUEB:布尔值,Indicator: Display operation overviewFLG_TERM: 布尔值,Indicator: Scheduling must take data changes into accountTYPKZ: 1 Category of object causing the load (order category)代表Work orders (detailed scheduling / routing…)AUKBED:Indicator: Calculate capacity requirements 布尔值要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

February 3, 2019 · 1 min · jiezi

SAP S/4HANA销售订单创建时,会自动触发生产订单的创建

这个自动触发的过程是怎么实现的?使用下面的代码创建一个销售订单:DATA: ls_header TYPE bapisdhd1, ls_headerx TYPE bapisdhd1x, lt_bapiret2 LIKE bapiret2 OCCURS 0 WITH HEADER LINE, po_order_number TYPE bapivbeln-vbeln, lt_partners TYPE TABLE OF bapiparnr, lt_order_items_in TYPE TABLE OF bapisditm, lt_order_item_x TYPE TABLE OF bapisditmx, ls_order_item_x LIKE LINE OF lt_order_item_x, ls_order_items_in LIKE LINE OF lt_order_items_in, lt_schdlin TYPE TABLE OF bapischdl, ls_schdlin LIKE LINE OF lt_schdlin, lt_schdlinx TYPE TABLE OF bapischdlx, ls_schdlinx LIKE LINE OF lt_schdlinx, ls_partners LIKE LINE OF lt_partners, lt_order_text TYPE TABLE OF bapisdtext, ls_order_text TYPE bapisdtext.ls_header-serv_date = ‘20200101’.ls_header-doc_type = ‘TA’.ls_header-purch_no_c = ‘a’.ls_headerx-purch_no_c = ‘X’.*ls_header-sales_org = ‘0001’.*ls_header-distr_chan = ‘01’.ls_header-division = ‘01’.ls_header-comp_cde_b = ‘0001’.ls_headerx-comp_cde_b = ‘X’.ls_headerx-doc_type = ‘X’.ls_headerx-updateflag = ‘I’.ls_partners-partn_role = ‘WE’. “ship to partyls_partners-partn_numb = ‘0000000001’.APPEND ls_partners TO lt_partners.ls_partners-partn_role = ‘AG’. " sold to partyls_partners-partn_numb = ‘0000000001’.APPEND ls_partners TO lt_partners.ls_order_items_in-item_categ = ‘TAN’.ls_order_items_in-material = ‘REDUCER_A’.ls_order_items_in-target_qty = 999.ls_order_items_in-itm_number = 10.ls_order_item_x-item_categ = ‘X’.ls_order_item_x-material = ‘X’.ls_order_item_x-target_qty = ‘X’.ls_order_item_x-itm_number = ‘X’.ls_order_item_x-updateflag = ‘I’.APPEND ls_order_item_x TO lt_order_item_x.APPEND ls_order_items_in TO lt_order_items_in.ls_schdlin-itm_number = 10.ls_schdlin-req_qty = 3.ls_schdlinx-itm_number = ‘X’.ls_schdlinx-itm_number = ‘X’.ls_schdlinx-updateflag = ‘X’.APPEND ls_schdlin TO lt_schdlin.APPEND ls_schdlinx TO lt_schdlinx.“ls_order_text-doc_number = SALESDOCUMENT.ls_order_text-itm_number = ‘000010’.ls_order_text-text_id = ‘0006’.“ls_order_text-langu = ‘E’.ls_order_text-langu_iso = ‘ZH’.ls_order_text-format_col = ‘’.ls_order_text-text_line = ‘Test 2 DSFSDFDSFDS’.ls_order_text-function = ‘006’.APPEND ls_order_text TO lt_order_text.CALL FUNCTION ‘SD_SALESDOCUMENT_CREATE’ EXPORTING sales_header_in = ls_header sales_header_inx = ls_headerx int_number_assignment = ‘X’ IMPORTING salesdocument_ex = po_order_number TABLES return = lt_bapiret2 sales_items_in = lt_order_items_in sales_items_inx = lt_order_item_x sales_schedules_in = lt_schdlin sales_schedules_inx = lt_schdlinx sales_partners = lt_partners sales_text = lt_order_text.LOOP AT lt_bapiret2 ASSIGNING FIELD-SYMBOL(<return>) WHERE type = ‘E’. WRITE:/ ‘Error:’, <return>-message COLOR COL_NEGATIVE. RETURN.ENDLOOP.IF po_order_number IS INITIAL. WRITE:/ ‘PO number initial’. RETURN.ENDIF.CLEAR: lt_bapiret2.CALL FUNCTION ‘BAPI_TRANSACTION_COMMIT’ EXPORTING wait = ‘X’ IMPORTING return = lt_bapiret2.LOOP AT lt_bapiret2 ASSIGNING <return>. WRITE:/ ‘Message:’, <return>-message COLOR COL_POSITIVE.ENDLOOP.用事务码SAT分析,发现总共创建消耗的时间为3.98秒,其中1.84秒花费在EIGENFERTIGUNG_BEARBEITEN这个subroutine上。用一下Google Translate:发现EIGENFERTIGUNG的含义就和生产有关:own productionBEARBEITEN的意思是TO eidt:看这个函数CO_61_ORDER_EDIT:这个函数的描述信息指向了它是用来做生产用的:这个函数所在的包也透露了它的作用,是负责生产相关实现的:观察一下传入这个函数的各参数值:要获取更多Jerry的原创文章,请关注公众号"汪子熙”: ...

February 3, 2019 · 2 min · jiezi

如何在SAP C4C里使用ABSL消费第三方Restful API

首先我们得有一个可以正常工作的Restful API:然后在Cloud for Customer的Cloud Application Studio里创建Restful API的模型,把第一步可以正常工作的Restful API url填进模型里去:然后在ABSL里使用如下代码进行消费:import ABSL;if( this.OutboundDeliveryID.IsInitial() == false){ raise already_delivered.Create(“E”); return;}var HttpMethod = “GET”;var HttpResource = “”; // not requiredvar ContentType = “”; // not requiredvar Body = “”; // not requiredvar HeaderParameter : collectionof NameAndValue; // not requiredvar URLParameter : collectionof NameAndValue;var URLParameterEntry : NameAndValue;URLParameterEntry.Name = “SoID”;URLParameterEntry.Value = this.ID.content;URLParameter.Add(URLParameterEntry);var response = WebServiceUtilities.ExecuteRESTService(“JerryExternalService”, “JerryExternal”, HttpMethod, HttpResource,URLParameter, HeaderParameter,ContentType, Body);this.OutboundDeliveryID = response.Content;raise delivery_message.Create(“S”, this.OutboundDeliveryID);要获取更多Jerry的原创文章,请关注公众号"汪子熙":

February 3, 2019 · 1 min · jiezi

SAP UI5和微信小程序对比之我见

今天继续由SAP成都研究院著名的菜园子小哥Wang Cong,给大家分享他作为一个SAP前端人员是如何看待SAP UI5和微信小程序的异同点的。关于Wang Cong种菜的手艺,大家请移步到他以前的文章 SAP成都研究院非典型程序猿,菜园子小哥:当我用UI5诊断工具时我用些什么 去观摩,这里不再赘述。下面是他的正文。*近几年微信小程序发展之势如火如荼,越来越多的用户放弃原生App,转而投入小程序的怀抱,大有"一个微信行天下"的趋势。面对如此巨大的流量机遇,百度、阿里等公司也纷纷在自家的核心产品中推出小程序功能,欲与腾讯的微信在这场入口大战中一较高下。至少在今天看来,微信小程序的生态圈依然是其中最为繁荣的。同为"前端框架",SAP UI5与微信小程序有着诸多异同点。这里我们摘取其中本人觉得比较有特点的方面进行对比,看看二者相似的表象下隐含着哪些设计理念上的区别。本文仅代表作者个人作为一个前端开发人员的个人观点。UI5是SAP开发的一套开源的前端框架,而微信小程序则是局限在微信内部,表现形式类似于普通App。虽然两者的核心(或者说大部分功能)都是与用户进行交互,但从架构的角度看,存在很多本质上的不同,我们可以从接口的角度窥见一二。入口UI5不依托任何平台,通过UI5实现的页面可以从多种入口进行访问,基本上只要支持浏览器功能的平台,都可以访问UI5页面。而微信则是微信小程序的唯一入口。后端UI5是一个纯粹的前端框架,对于后端没有做任何的限制,同时也没有任何的支持。微信小程序不但允许你自由地选择后端,而且提供了一些基础的后端支持,在很多情况下开发者甚至无需搭建自己的服务器,就能满足需求。这些支持有:(1) 数据库:微信小程序提供远端的类似MongoDB的JSON数据库支持,用户不需要购买数据库,也不需要任何复杂的前期配置,就能在小程序中直接对JSON数据库进行增删查改等操作。(2) 存储:类似于上面提到的JSON数据库,用户可以在微信小程序中直接利用免费且免配置的远端存储空间来存储文件。(3) 云函数:除了数据库和存储之外,微信小程序还提供了后端逻辑的支持。云函数可以理解成一个功能有限的后端服务器,也可以理解成一个运行在云端的JavaScript方法。优点是方便,一键部署而且免费。缺点是功能有限,无法实现复杂的后端功能。以上功能全部免费免配置,如果发现免费的配额不够,可以申请提升配额或考虑自己搭建服务器。访问限制作为开放的框架,UI5对于外部访问没有做任何限制。而微信小程序则有着严格的审核机制,首先要访问的链接必须是https的安全链接,其次地址必须提交给微信进行审核,审核过后还需维护在小程序后台的访问列表当中。如果上述步骤没有做好,就连腾讯自己的官网都无法访问。其实这样做的原因也很容易理解:用户通过微信小程序访问的所有链接,最初的入口都是微信本身,这也是微信为了自身生态安全而做的必要控制。但这项限制在本文发稿时为止还不是特别完善。因为云函数尚未对访问做限制,开发者可以使用云函数作为路由,访问未经审核的链接。从上面和下面两张图中我们可以看出UI5应用和微信小程序在接口方面的区别,其中虚线框内分别为UI5和微信小程序框架内所提供的功能范围。技术细节一个熟悉SAP UI5的前端开发人员,上手微信小程序应该没有什么难度。两者同为前端框架在设计上自然有很多相似的地方。例如:(1) 在微信小程序中的app.js极其类似于UI5中的component.js,都代表整个应用的一个全局实例。某些作用范围为全局的方法或数据都可以存于其中。(2) 两者在数据绑定方面,都支持灵活的表达式绑定,将更多的本应出现在controller层的逻辑向前推放到view层当中,简化逻辑层。(3) 两者都支持列表渲染,例如UI5中的ListBase中的items属性,而微信小程序中则是通过wx:for属性实现同样的功能。(4) 两者都支持自定义控件/模板,UI5有component和custom control,微信小程序有component和template。但两者也有很多技术上的区别,例如:(1) 前文提到的列表渲染,UI5仅支持对列表类控件的子控件进行列表渲染。而微信小程序则显得更加灵活一些,任何一个控件都可以通过wx:for属性进行重复渲染。例如上面例子中被重复渲染的就是image元素。(2) 除了列表渲染,微信小程序更支持wx:if的条件渲染。即if条件检测的结果为true时渲染,为false时则忽略。UI5中实现类似功能则更多是通过控制visible属性来进行。(3) Routing的实现。两者都是使用栈的方式记录跳转的历史,但是与UI5的"宽容"不同,微信小程序最多仅支持5层跳转。如用户需要继续向下访问,则必须通过其他workaround实现,例如通过redirectTo将栈顶的旧页面弹出栈,换成新页面。(4) 数据绑定方面。UI5的数据绑定功能极其强大,支持各种类型的数据模型的排序和筛选,并且提供双向绑定和单向绑定多种绑定方式。另外数据在view层和controller层的反馈也更加积极。关于SAP UI5和Angular数据绑定的比较,可以参考Jerry这篇文章:https://blogs.sap.com/2016/06…关于SAP UI5和Vue数据双向绑定的实现区别,可以参考Jerry这篇文章:https://blogs.sap.com/2017/06…相对而言微信小程序的数据绑定功能要稍弱一些。首先不提供排序和筛选功能。另外反馈也不够积极:view层改动数据模型需要借助触发事件来调用controller层中的方法进行手动赋值;controller层在更改模型时也必须通过setData方法,才能让改动在view层中生效。(5) 微信小程序的底层是"巨人"微信, 因此可以借助微信方便地调用很多硬件以及软件API,例如:NFC,WIFI,蓝牙,微信运动,生物认证,二维码,登陆以及支付功能等。(6) 纵观两者的控件库,我们可以发现UI5可谓大而全,就连一个表格都要提供responsive table,grid table,smart table等, 目的就是为了支持尺寸各异的不同设备以及各种业务场景。而微信小程序则极其专注在移动端的常用控件,轻量,简易且统一。理念综合以上的比较,我们可以大致发现UI5和微信小程序自面世起便肩负着不同的使命。UI5是SAP为其自研的企业管理软件前端页面所设计的前端框架,以此来实现SAP推荐的Fiori风格的前端应用。它的出现体现了SAP对于确保未来产品拥有统一风格,友好界面和良好用户体验的决心。而微信小程序虽然小,却足以彰显微信扩张的雄心:通过丰富的前后端支持以及简易的上手体验,实现生态圈的急速扩充。而入口和外部访问的限制则是快速扩张的同时,仍然恪守的那份理智。轻量,小巧,快速,简易,移动,一站式。微信想要对你说的是,你的生活,被我承包了。关于SAP UI5和微信小程序,SAP成都研究院的开发人员们做过很多研究,如果您想进行更多阅读,可以参考下面的链接:(1) 我的同事,SAP成都研究院大卫哥Wu David的文章:SAP C4C中国本地化之微信小程序集成(2) 以前Jerry写的SAP UI5框架代码自学教程(3) Jerry在SAP社区上发表过的59篇SAP UI5相关的文章合集(4) Jerry和您聊聊Chrome开发者工具:关于Chrome开发者工具一些搞笑的故事(5) Jerry通过自己调试的方式解决过的UI5的问题合集:https://blogs.sap.com/2016/04…(6) Jerry日常工作中使用Chrome开发者工具积累的一些技巧:https://blogs.sap.com/2016/03…(7) Jerry的碎碎念:SAPUI5, Angular, React和Vue(8) Yang Joey的文章:SAP Cloud for Customer 使用SAP UI5的独特之处(9) 我自己的文章:当我用UI5诊断工具时我用些什么(10) Jerry的文章:在Kubernetes上运行SAP UI5应用(11) Jerry的文章:SAP Fiori + Vue = ?要获取更多Jerry的原创文章,请关注公众号"汪子熙":

February 3, 2019 · 1 min · jiezi

SAP技术专家的ABAP调试器培训材料

首先弄清楚ABAP Classic调试器和新调试器的区别:Classic debugger:(1) Static breakpointa. BREAK-POINT : non-user specific b. BREAK user name user specific(2) Dynamic breakpointNew debugger:(1)Static breakpoint(2)Dynamic breakpointa. session breakpointb. external breakpointSession 断点和External断点的区别(1) Session BP is only visible in all external sessions belonging to the same user session, while External BP is visible across all user sessions. Therefore, only External BP is valid for BSP / Webdynpro debugging.(2) When a user logs off, Session BP will be deleted while external BP persists.By setting this flag, if external session A is running, and in external session B ( A and B belongs to the same user session ) you set a session breakpoint in the program source code, the BP will be triggered immediately .ABAP独占断点(Exclusive Breakpoint)和非独占断点的区别下图是非独占断点:下图是独占断点:Exclusive mode means the application to be analyzed exclusively occupies a work process of the application server during debugging. If all exclusive debug work processes are occupied, the Debugger is switched to non-exclusive mode. (rdisp/wpdbug_max_no )Limitation for non-exclusive mode:Due to technical limitations in ABAP debugger implementation, there are following limitations when debugger is run under non-exclusive mode:(1) No possible to debug statement between SELECT and ENDSELECT. In this case, program terminates with this error:(2) No possible for conversion / field exit.(3) No possible for debugging in production system, program terminates with exception DEBUGGING_NOT_POSSIBLE.ABAP调试器里的一些指标该如何阅读?考虑下面这段最简单的ABAP代码:调试器里查看A1这个类型为内表的变量:这里的[2×1(8)]是什么意思?2: table row number1: table column number8: byte length of table rowThe time for which the new Debugger is active is determined by the profile parameter rdisp/max_debug_lazy_time – which is set to 600 seconds in the standard version. After this time space has elapsed, the Debugger process is exited automatically and control is passed back to the application.一些小技巧:how to debug background RFC?解决方案:使用事务码sbgrfcmon小技巧2:如何调试update task小技巧3:如何使用ABAP观察点 Watch point练习:我们进入事务码SE09时,会观察到User字段会自动被填充成当前登录用户。如何通过观察点快速找到是哪一行代码赋的值?When we use SE09, how can we find the logic of the User? When and where is this field filled? What does content come from?Debugging step by step will be very time-consuming.小技巧4:使用ABAP检查组 Check group小技巧5:事务码SRDEBUG小技巧6:调试脚本要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

January 31, 2019 · 2 min · jiezi

SAP CRM One Order跟踪和日志工具CRMD_TRACE_SET

事务码CRMD_TRACE_SET激活跟踪模式: 在跟踪模式下运行One Order场景。运行完毕后,使用事务码CRMD_TRACE_EVAL:双击参数,就能看到参数明细:点Callstack也能看到调用栈明细:这个工具的实现原理是怎样的?ABAP include CRM_TRACE_PART_ONE做了下面的事情:检查One Order的trace模式是否打开了,如果打开,负责收集调用的时间戳,执行工作进程ID,调用栈上下文:另一个ABAP include CRM_TRACE_PART_TWO负责把调用信息写入INDX表。 在这些ABAP include上使用where used list,可以搞清楚哪些API可以支持跟踪模式。除了用上述事务码打开调试模式以外,也可以设置user parameter “CRM_DEBUG_CODE”来达到同样目的。这个参数的检测包含在include CRM_TRACE_PART_TWO里.ABAP包CRM_TOOLS里还有其他有用的工具:要获取更多Jerry的原创文章,请关注公众号"汪子熙":

January 31, 2019 · 1 min · jiezi

SAP CRM系统订单模型的设计与实现

SAP成都研究院的一个部门领导让我给他的团队做一个SAP CRM One Order框架的培训,这是我准备的培训内容。在Jerry之前的文章 基于SAP Kyma的订单编排增强介绍,我表达了自己对SAP应用的理解:模型以及基于模型的增删改查。只是同我们大学专业课学习时完成的家庭作业相比,SAP模型的复杂程度增加了好几个数量级。和传统的增删改查相比,以订单编排领域为例,SAP订单模型的"增",还需要考虑实际业务流程中各种类型的前置和后序订单,即SAP使用的术语 文档流(Document Flow)。而"改", 除了订单自身状态的迁移外,还包括订单模型提供的各种可执行逻辑。这些逻辑既包括订单模型本身字段的更改,也可以包括订单与第三方系统的交互。在很多上下文里,我们称这些逻辑为Action。如下图右下角所示:既然订单模型复杂度如此之高,那么引入一种精良的能支持企业级订单编排应用的高质量建模方式,就显得至关重要。随便看些例子,SAP CRM总共支持多少种标准的订单类型?下图中BUS2000开头的就是不同的订单类型,我没有具体数过,但是几十种总是有的。而SAP Cloud for Customer,虽然位于CRM命名空间下面的Business Object的数量比SAP CRM要少一些,但是基本的用于实现销售自动化流程的订单模型仍然一应俱全。我们先来看SAP CRM的订单模型。有没有可能用一套模型来描述SAP CRM支持的几十种订单类型呢?有,那就是SAP CRM One Order模型,其自描述的名称就体现了该模型的特色。Jerry曾经试图搞清楚"One Order"这个称呼,是来自SAP官方,还是仅仅被SAP开发人员内部使用。用搜索引擎根据关键字One Order搜索,得到的结果几乎全是Jerry写的博客,囧。不过进系统根据ONE ORDER为关键字还是能搜索出大把的代码。我的文章 Jerry的WebClient UI 42篇原创文章合集里有这张架构图:其中One Order框架从架构上讲,位于上图红色区域内,包括数据库表,ABAP结构体以及操作它们的API代码。SAP One Order框架有多成功?搜索引擎输入关键字"SAP CRM ONE ORDER", 第一条搜索结果即Jerry写的一篇博客。其中第一段话就给大家做了详细的阐述:尽管它如此成功,但当Jerry刚刚接触One Order的时候,吃惊地发现,竟然没有一个比较直观的图形化界面,能够显示出这个模型的全貌。不过瑕不掩瑜,对于一个诞生于20年前的框架来说,我们不应该用20年后的标准来苛求它。我们想象一下,不同类型的订单,有什么共同点?无非每种订单都有抬头结构,行项目。有的结构,从业务上说可以同时出现在订单的抬头和行项目,比如参与订单的业务伙伴明细(Involved parties), 组织架构(Organization Unit)等等。有的字段只有行项目才能出现,比如卖出的产品信息(Product, Scheduled Line)。SAP One Order建模的原理,类似我们小时候玩的积木。组成One Order模型最小粒度的单元,就是一个个扮演积木作用的结构体,在事务码CRMC_OBJECTS里查看。下图是这些结构体的列表,如果SAP标准的结构体不能满足需要,客户仍然可以自行创建新的结构体。然后我们用搭积木的方式,将业务上具有关联关系的若干结构体组合起来,共同分配给某个订单类型,比如描述服务流程的订单类型BUS2000116,就由下列这些结构体组成:有了模型之后,剩下的就是实现基于这些模型的增删改查操作,即ABAP编程。One Order API的代码实现原理,实际上就是设计模式里的模板(Template)模式和观察-发布者模式的结合体。我们学习模板模式的时候,有一个经典的例子,上帝通过模板模式主宰芸芸众生的生老病死。我们每个人被父母实例化出来之后,只能被动地实现上帝在模板里定义好的四个方法:生,老,病,死,而不能够更改这个模板本身,比如调换这四个方法的顺序。即使是乔布斯,也没有办法给自己添加一个"永生"的方法。听起来很残酷,但这是事实。那么,One Order框架里,作为One Order应用的上帝,定义了哪些模板方法?事务码CRMV_EVENT,指定BUS2000116, 执行:得到下图列表。红色的第一列,就是前文提到的组成One Order模型的积木。蓝色的第二列,是这些积木对发生在自己身上的感兴趣的事件列表。从图中可以看到这些事件名称都是自描述的,比如AFTER_CREATE, BEFORE_CHANGE, BEFORE_DELETE等等。第三列黑色的ABAP函数,就是这些事件的监听函数。这些监听函数的后缀EC代表Event Callback。借助上述框架,One Order应用的开发人员的开发工作就变得无比轻松:1. 通过搭积木的方式,定义出自己应用需要的One Order模型2. 实现模型里需要关注的事件对应的监听函数。至于这些监听函数什么时候被调用到?应用开发人员完全不用操心。由此我们能发现,One Order框架的实现,把编程复杂度从应用开发人员身上转移到了框架实现身上。One Order框架内部的实现比较复杂,一篇文章的篇幅无法讲述清楚。况且通常情况下,One Order框架的使用者只需要了解CRM_ORDER_READ, CRM_ORDER_MAINTAIN等API的用法即可。如果想了解更多细节,可以参考我的SAP社区博客:1. Buffer logic in One Order header extension Readhttps://blogs.sap.com/2017/03…2. Logic of FILL_OW function module in One Orderhttps://blogs.sap.com/2017/03…3. Logic of CHANGE_OW function module in One Orderhttps://blogs.sap.com/2017/03…4. Logic of CREATE_OW function module in One Orderhttps://blogs.sap.com/2017/03…5. Logic of SAVE_EC function module in One Orderhttps://blogs.sap.com/2017/03…6. CHANGED_AT, HEAD_CHANGED_AT and CRM_CHANGED_AT in order header tablehttps://blogs.sap.com/2017/04…One Order的API之一,为消费者提供修改操作的CRM_ORDER_MAINTAIN, 所有SAP标准支持的结构体都作为输入参数之一出现在参数列表里:这种设计方法虽然让参数列表显得有点冗长,但是从另一方面看,也起到了自描述的效果, 确保API的使用者即使不阅读文档,仅凭浏览这些参数本身,就能大概了解该API到底支持One Order哪些数据的修改。这也符合那份著名的来自Google的API设计最佳实践文档里提到的,好的API应该满足的条件之一:易学易用,自描述,不易造成误解。在我的另一篇文章 Hello World, S/4HANA for Customer Management 1.0 我曾经提到,SAP CRM的部分功能迁移到SAP S/4HANA后,部分实现做了一些改造,其中就包括One Order的改造。Jerry是负责One Order改造设计的三位人员之一,详细的改造原理和实现我已经分享到SAP社区了,这里只简述一些核心概念。https://blogs.sap.com/2018/03…https://blogs.sap.com/2018/03…为什么要改造?因为SAP CRM搬到了S/4HANA上,而S/4HANA的一个强大之处,在我同事Zhang Sean的文章 S/4HANA业务角色概览之订单到收款篇 里也提到了,那就是S/4HANA在SAP历史上第一次实现了OLTP和OLAP的完美结合,即一套系统的唯一数据源,可以同时满足Transaction事务型应用和Analytics分析报表型应用的需要。而SAP CRM One Order没有改造之前的模型是无法和S/4HANA的上述特性匹配的。改造之前,每个组成One Order模型最小粒度的结构体,都有自己独立的一张专属数据库表,命名规范一般是CRMD_加上结构体名。这套底层存储模型如果原封不动地搬到S/4HANA里,在运行报表统计等应用时会出现性能问题——为了取出报表结果,后台需要在很多个结构体的存储表中做各种数据库表的内外连接操作。当参与连接操作的数据库表尺寸增长到一定数量级后,整个应用的性能表现不佳。Jerry也参与了性能评测,最后我们决定对One Order的底层数据模型做改造。因为留给我们从调研到改造的原型开发,再到正式开发一共只有八个月的时间,因此我们选择了一种代价最小,对One Order框架改动最小的方式。首先我们抛弃了之前每个结构体拥有一张专属数据库表的做法,在S/4HANA里,每种订单类型只拥有两张表,一张存储抬头级别的数据,另一张存放行项目数据。之前散落在不同结构体表中的字段,如今统一维护在这两张表里。由于所有的字段都平铺在这两张表里,我们内部形象地称其为平坦表(Flattened Table)。存储模型大大简化之后,我们基于这两张表再创建CDS view,让上层的报表应用消费。这样改造后简化的模型,能满足S/4HANA中OLAP应用的需求。针对S/4HANA OLTP应用的改造,用一句话概括,就是我们采用设计模式里的适配器模式(Adapter), 在API与简化后的数据库表之间引入一个微型的中间件,扮演Adapter的角色。当消费者通过One Order API进行读操作时,中间件负责把存储在简化后的数据表中的数据进行还原,再填充到One Order API上层的缓存中。对后者来说,它对底层存储模型发生的变化毫不知情,因为Adapter封装了底层数据读取的逻辑并做了格式转换,所以One Order API上层不需要做任何改动,也完全能够像在SAP CRM里一样正常运行。而当消费者调用One Order API进行写操作时,在存储于各个结构体对应的缓存中的数据持久化到数据库之前,同样是Adapter负责把这些分散在不同缓存结构中的数据做一个合并,合并后的结构体再写入平坦表。讲完了CRM One Order订单模型的设计,我们再来简单看看SAP Cloud for Customer的订单模型设计。虽然SAP Cloud for Customer的后台对客户和Partners不可见,但我们仍然可以从合法渠道获得一些其订单模型的设计信息。https://archive.sap.com/discu…从SAP社区上这位SAP员工的回复,我们得知ESF2和BOPF有很多相似之处,设计理念类似,但ESF2主要用于部署在云端的产品,比如SAP Cloud for Customer上Business Object的开发,而后者主要服务于On Premises解决方案比如S/4HANA。因为Jerry不能够把C4C后台ESF2的界面给大家看,所以我选择了展示S/4HANA的Business Object开发框架BOPF,因为前面说了,二者很多方面都非常相似。同之前介绍的SAP CRM One Order框架一样,通过BOPF实现的订单模型,同样由若干个结构体通过搭积木的方式组成,这些结构体如上图红色高亮区域所示,每个结构体也有自己的专属存储数据库表。而SAP CRM One Order里每个结构体的事件监听函数,采取的是ABAP传统的面向过程的函数实现,而BOPF则采取了实现指定接口的ABAP类,二者原理相同,只是实现细节有差异。SAP C4C的订单模型,虽然和SAP CRM传统的One Order模型一样,每个结构体拥有一张专属的数据库表,但是在运行报表程序时并不会出现性能问题,这是怎么做到的?答案是采用了TREX,一个专为只读报表应用优化过的存储仓库。换句话说,SAP C4C的事务处理和报表处理使用的是两套不同的存储系统,这一点和S/4HANA不同。SAP Cloud for Customer的订单模型,在Cloud Application Studio里对客户和Partners是可见的,大家感兴趣的可以自行去查看。希望这篇文章能让大家对SAP CRM两款产品中的订单模型设计有最基础的认识,感谢阅读。相关阅读SAP的这三款CRM解决方案,您能区分清楚么SAP S4CRM vs C4C, 诸葛亮和周瑜?基于SAP Kyma的订单编排增强介绍要获取更多Jerry的原创文章,请关注公众号"汪子熙":SAP CRM系统订单模型的设计与实现 ...

January 22, 2019 · 1 min · jiezi

SAP Customer Data Cloud(Gigya)的用户搜索实现

我在Gigya前台根据email搜索,输入一个邮箱地址,回车,在Chrome开发者工具里观察到到后台的网络请求:这是一个post请求:__RequestVerificationToken请求体:{“query”:“SELECT * FROM accounts WHERE (profile.email = ‘abc@sap.com’) OR (profile.email CONTAINS ‘abc@sap.com’) OR (loginIDs.emails = ‘abc@sap.com’) OR (loginIDs.emails CONTAINS ‘abc@sap.com’) ORDER BY lastUpdatedTimestamp desc LIMIT 20 START 0”,“format”:“json”,“apiKey”:“3__ZoBjMduuUpCQF86dWF0B-yjUlPDudlQ7FtPlrmxUnKFN”}这次搜索结果的响应:要获取更多Jerry的原创文章,请关注公众号"汪子熙":

January 22, 2019 · 1 min · jiezi

SAP S/4HANA里如何创建Customer主数据以及执行后续处理

来自Jerry的同事Zhang Sean.1, Launch tcode: BP and select the Organization2, Maintain the information for Customer role3, Maintain information for name and search4, Maintain the Address5, Maintain the information for Sales and Distribution6, then maintain which Sales Area this customer is assigned to, you could also maintain the information for other Sales Area by the button “Switch Area”. Then after that you shall maintain the information for Order, Shipping, Billing.7, last but the most important, remember to save the BP, then you will get the Customer for the SD business.8, Then you could start business transaction in the defined Sales Area. e.g. create Sales Quotation by Tcode: VA219, The created Customer is entered for the Sold-To Party, and Ship-To Party. And one existing Material is used(Later we will have one exercise to show how to create new Material.)But this time, we see one issue.Pricing error: Mandatory condition TTX1 is missing10, we go to the Item conditions, and click the Analysis to analyze the pricing conditions.11, we got a pricing list, and try to find the TTX1 entry. And the 020 entry is mentioned that Condition Record is missing, we go deeper by clicking the 020 entry under TTX1.12, It seems that there is no condition record maintained for this export taxes.13, Let’s go to the pricing master to maintain export taxes for condition type TTX1.14, enter the information there and save the entry.15, go back to the Quotation Creation Page, where we have the conditions, and click the “Update” to update the conditions automatically. And select the Carry out new pricing. Then the Entry for TTX1 will be proposed in the condition list.16, let’s try again with the Pricing Analysis, you will see the check is also successful.17, let’s go back to the Quotation Header and Save, then there will be one Popup to mention that the document is incomplete. And go to edit and maintain the information accordingly.18, and go back to Quotation Header, it’s mentioned document is complete. So Save it and you did it!19, with that, you managed to create Quotation, and then you could continue the business to create Sales Order, Delivery, Transfer Order, and Billing, Accounting, and Payment.20, Create Sales Order by reference to Quotation: 20004141 (Tcode: VA01)21, Create Delivery by reference to Sales Order: 24615 (Tcode: VL01N)Picking the quantity and Save.22, Post Goods issue for the Delivery (Tcode: VL02N)23, create Billing by reference delivery(Tcode: VF01)24, but in the billing document, it’s mentioned “The journal entry has not yet been created.”. Open the billing document you created with Tcode VF02.And menu: Billing Document, use the option “Release to Accounting"And it’s mentioned “Customer 1000260 is not defined in company code 1010"25, try to define the customer in company code 1010.Open the customer(1000260) in BP, and create new BP role Customer(Fin. Accounting)26, Then go back to the VF02, and use the option “Release to Accounting”, this time, the release will be successful. The accounting documents are generated. You could check this with the document flow.27, in the document flow, but the last account document is still not cleared, where payment is needed from customer, but before that, you need to know how much the customer will pay.You could open the billing document by VF03, and goto28, then you got to know 1498 is the amount. Go to the accounting receivable.(Tcode: F-28)29, Open the Document flow, then all the accounting documents are clear!, Well done, you made it.要获取更多Jerry的原创文章,请关注公众号"汪子熙”: ...

January 22, 2019 · 3 min · jiezi

自开发Web应用和SAP Customer Data Cloud Identity服务的集成

今天的文章继续由SAP成都研究院的云时代女王,Aviva给大家分享关于SAP Customer Data Cloud的一些使用经验。Aviva之前的文章可以在本文末尾处获得。下面是她的正文。*大家好,我是Aviva。本人在SAP不负责Gigya的开发工作,只是出于个人兴趣,在业余时间阅读了SAP官网上Gigya的帮助文档后,就Gigya提供的网站登录接入功能做了一些非常简单的Hello World级别的例子,在此分享给大家。2017年SAP收购了以色列创业公司Gigya, 现在Gigya又被称作SAP Customer Data Cloud,是SAP C/4HANA的五朵云之一。所以下文在不同的上下文出现的SAP Customer Data Cloud和Gigya,大家可以认为这两组词表达的是同一个意思。文章分为两部分,第一部分,简单介绍SAP Customer Data Cloud的业务,第二部分用一个demo介绍如何在自己的网站中使用SAP Customer Data Cloud中的某些服务。Customer Data Cloud从功能上分为三大模块:SAP Customer IdentitySAP Customer ConsentSAP Customer Profile我们首先来简单了解一下这三大功能模块。SAP Customer Identity提供跨渠道和跨设备的用户身份识别,在Web,移动设备和物联网设备上提供统一的注册,身份验证,登录等用户体验。除此之外,SAP Customer Identity还提供单点登录,无密码的身份验证,能够安全地识别来自任何接入端的在线访问者。通过抓取客户授权的身份数据,SAP Customer Identity可以推动个性化、即时营销、销售和服务,同时尊重消费者隐私并满足数据保护法规。Gigya 在安全上做了很多工作,确保用户数据不被窃取和攻击。SAP Customer Consent提供了开箱即用的工作流程,帮助企业明确提出各项服务条款,隐私政策,营销沟通,以及其他需要用户授权的同意请求等等。每次企业更新服务条款和隐私政策,SAP Customer Consent会自动触发新的用户同意请求,并记录每次用户的同意选项和授权的时间。企业管理员可以访问用户整个使用周期内每一次授权的历史记录,从而有效地解决政府对隐私的监管和审计。在企业的数字生态系统中,通过将用户的配置文件与企业的应用程序和服务同步,在每个渠道上强制执行用户的隐私许可,满足关键数据隐私要求。SAP Customer Consent提供了跨平台和跨设备的用户隐私设置服务中心,使用户在整个使用产品的生命周期内,都能透明地管理自己的偏好设置,控制企业对自己的隐私数据的访问规则,从而帮助企业和客户建立透明可信任的关系。SAP Customer Profile通过抓取用户授权后的第一手数据,SAP Customer Profile为用户建立丰富的用户档案,让企业的每个应用程序和服务都可以无缝的使用它们。企业各种应用和服务的用户资料通过统一的平台对管理员开放,同时也能为营销人员提供各种用户数据的分析报告,以及为客户细分和个性化的营销方案提供数据支撑。下面通过一个简单的demo,向大家介绍如何将SAP Customer Identity集成到我们自己的Web应用中。我开发了一个基于nodejs的Web应用。后台使用nodejs + express框架,前端使用SAP UI5。登陆SAP Customer Data Cloud的RAAS(Registration-as-a-Service)平台。首先在RAAS平台上创建site和应用。本地开发和测试使用的Site Domain可以填成localhost:创建一个新的Application:创建了Site 和Application之后,Site会自动生成对应的API Key:Application会产生User Key和Secret。其次,在Web应用的index.html中引入Gigya Web SDK:<script src=“https://cdns.gigya.com/js/gigya.js?apikey=YOUR-API-KEY-HERE"></script>然后使用SAP UI5开发Web应用的登录页面 login.view.xml和控制器login.controller.js。Gigya 提供了一个默认的用户登录注册页面,只需两行代码就可以在我们的Web应用里使用。这种便捷的使用方式体现了RAAS的含义。在xml视图中嵌入一个div标签:在控制器实现的初始化函数中加入:gigya.accounts.showScreenSet({ screenSet: ‘Default-RegistrationLogin’, containerID: me.byId(‘LoginGigya’).sId });Gigya的登录和注册服务就加入我们自己的Web应用中去了。除了使用默认的登录屏幕设置之外,我们当然可以直接在Gigya平台上定制登录页面和注册流程。Gigya提供了UI Builder,在UI Builder里可以使用默认的控件,通过拖拽就可以生成不同的登录页面(类似SAP Cloud for Customer UI Designer),也可以直接修改html和css,修改登录和注册流程等等。Gigya定义了许多不同类型的事件,这些事件由用户交互来触发,例如用户登录,按钮点击等。应用程序可以注册监听感兴趣的事件,并在收到这些事件时执行代码。下面是简单的监听用户登录和注销事件的代码:var me = this;gigya.accounts.addEventHandlers({ onLogin: me.login, onLogout: me.onLogout, context: me });登录后,在控制台简单地打印一些字符串。login: function (response) { console.log(“LOGIN!!!!!!!!!!!!!!!!!”); console.log(response);**},关于Gigya支持的所有事件和事件相关参数,可以参考用户手册:https://developers.gigya.com/…在Web应用后台,我们还可以使用Rest API的方式访问Gigya的相关服务。举个例子,在后台获取用户的Account信息,调用Rest API 需要用到Site 的API Key 和Application的User Key和Secret。以上只是基于Gigya提供的服务进行的一些最简单的练习。关于Gigya更多的功能介绍,请移步官网上去查看,有很详细的介绍:https://developers.gigya.com/ 感谢阅读。Aviva另外两篇文章:Hyperledger Fabric on SAP Cloud PlatformSAP C/4HANA与人工智能和增强现实(AR)技术结合的又一个创新案例要获取更多Jerry的原创文章,请关注公众号"汪子熙”: ...

January 22, 2019 · 1 min · jiezi

SAP S/4HANA extensibility扩展原理介绍

SAP产品总的extensibility扩展原理介绍:看Jerry这篇文章。SAP Cloud for Customer Extensibility的设计与实现我的同事Boris写的。而本文是S/4HANA extensibility扩展性专题:Enhancement ConceptSCFD_REGISTRY - Extensibility RegistryBusiness ContextExtensible CDS ViewExtension field is available, extend view generate, on registered CDS view.Extensible OData ModelUse report CFD_CREATE_FLX_CLASS to generate classes …MPC_FLX and …DPC_FLXData Transfer and Business Scenario要获取更多Jerry的原创文章,请关注公众号"汪子熙":

January 22, 2019 · 1 min · jiezi

SAP Cloud for Customer Account和individual customer的区别

在SAP Cloud for Customer的Customers工作中心里,有三个视图:Accounts,Contacts和Individual Customers。这三种主数据的区别是什么?我们可以从它们后台的BO模型开始分析。Account视图的UI模型:/BYD_COD/SalesOnDemand/Account/UI/COD_Account_TI.TI.uicomponent后台BO为Customers:再看Contact视图:Contact:后台BO:BusinessPartner再看Individual Customer:6$/BYD_COD/ServiceOnDemand/PrivateAccount/COD_SEOD_IND_ACCOUNT_TI.TI.uicomponent模型依然是Customers。那么Account和Individual Customer都用了Customers作为BO,有什么区别?答案是,Account数据,后台的BO数据CategoryCode为2:而individual Customer的CategoryCode为1:要获取更多Jerry的原创文章,请关注公众号"汪子熙":

January 15, 2019 · 1 min · jiezi

ABAP文档生成工具

本文介绍的工具原理和JavaDoc类似,位于software component BBPCRM1. 在ABAP类里新建一个名为CLASS_DOCU的私有方法。然后把所有的注释写在这个方法源代码的前面。2. 在每个方法前面,采用和JavaDoc语法一样的方式对ABAP方法书写注释,比如@param修饰输入参数,@return修饰返回参数等。3. 所有方法的文档书写完毕之后,使用事务码CLASS_DOCUGEN生成文档。4. 接下来在事务码SE24,SE80里就可以在class builder里查看这些生成的文档了。要获取更多Jerry的原创文章,请关注公众号"汪子熙":

January 15, 2019 · 1 min · jiezi

S/4HANA业务角色概览之订单到收款篇

大家好我叫Sean Zhang,中文名张正永。目前在S/4HANA产品研发部门任职产品经理,而这一阶段要从2017年算起,而在那之前接触更多还是技术类的,比如做过iOS、HANA、ABAP、UI5等等开发。然后在团队中负责设计和架构之余,也尝试做过一些SAP内部培训课程的讲师,比如在HANA、Fiori、Architecture Modeling等方面。我所在的团队,S/4HANA Sales(SD)成都团队,主要负责S/4HANA里销售模块相关的标准应用研发,或者笼统的理解为SD(Sales and Distribution 销售与分销)模块相关的,所以后续我就用SD简称。如果要追溯的话,我们团队应该是从2012年开始参与SD的产品开发,然后在2014年加入S/4HANA的研发。从最开始主要耕耘在底层的数据模型,到现在我们参与或主导了SD的分析、定价、合同、开票等等领域,当然SD产品的研发部门除了在成都还在欧美多地有研发团队。S/4HANA SD成都团队不仅在多个SD的核心领域有贡献,同时在一些重要前沿也属于先行者,比如在探索机器学习方面,团队最近尝试的一嵌入式机器学习应用也有幸被授予SAP中国研究院的2018年度的最佳产品之一。如果大家对于机器学习如何在S/4HANA中落地感兴趣,下次我的团队成员也可以跟大家一起分享和讨论。今天跟大家分享在订单到收款(Order-to-Cash,有时也简写为O2C)流程中的业务角色,通过熟悉这些主要业务角色,不仅能了解O2C的业务和解决方案,也能了解业务角色在整个S/4HANA里的运转模式继而推而广之。如果大家有关于S/4HANA产品的问题,特别是SD模块的,可以留言讨论。背景过去的企业业务系统,由于技术限制,需要在多方做出不同程度的平衡,比如数据处理的深度,广度,响应的高速性,实时性和简单性等等。当需要专注在数据的广度和深度分析时,会更像是一个OLAP(在线分析处理)系统,而需要实时快捷处理事务操作时更偏向于OLTP(在线事务处理)系统。在S/4HANA里,第一次实现了OLTP和OLAP的完美结合,大部分的业务可以在一套系统的一个数据源上完成。以往一个用户需要在多套系统间来回切换,然后再汇总数据,特别是在月末或季度末,通过漫长等待才能得到最终数据报表的岁月已经成为历史。在S/4HANA里,对于业务人员,一切变得简单和实时,这体现了2014年时SAP提出的一种系统设计思想设想——至简(Simplicity)。事务和分析操作融为一体,这也是为什么在S/4HANA里,我们不仅有事务处理,还有嵌入式分析(Embedded Analytics)。至简不仅仅意味着系统架构的简化,同时也包括业务流程的简化。在过去,每个业务人员需要面对繁杂的基于功能的应用界面,如下左图示例:而在S/4HANA里,所有的应用和解决方案都是基于角色提供(Role Based),换言之,每个业务人员只需要关注跟自己相关的信息,而这主要是通过IAM来实现。IAM的全称叫身份和访问管理(Identity and Access Management),负责确保业务用户访问应用的安全性。业务用户通过业务角色获得 Fiori 应用的访问权限。业务角色可包含一个或多个业务目录,从而包含多个应用。更多细节可以参考最新的SAP帮助文档。为了帮助企业更便捷的使用这一套基于角色的方案,S/4HANA在不同的模块为不同的经典业务角色预定义了各种角色模板,比如在财务领域有应付账款会计、应收账款经理、总账会计等;在销售领域有内部销售代表、销售经理等等。企业的关键用户基于角色模板创建角色,并根据实际业务进行调整,最后赋予每个具体的用户。SAP发布的标准业务角色模板有40个以上,而对于不同行业和国家提供超过200个模板,具体信息可以参照IAM的应用“业务角色模板”。业务角色是为业务服务的,不同的业务需要有不同的应用,继而其需要的业务角色模板也会不同。每个企业的业务在专属领域里会直接或间接的需要有不同的业务流程,比如:从商机到收款(Lead to Cash)从寻源到付款(Source to Pay)从差旅到报销(Travel to Reimburse)从市场到商机(Market to Lead)从设计到运营(Design to Operate)据不完全统计,大部分企业里有超过十个端对端的业务流程。而今天我们的讨论源于从商机到收款这个流程,其通过C/4HANA和S/4HANA的结合可以完整落地。在S/4HANA 销售模块(Sales-SD)中主要是解决该流程中的订单到收款(Order to Cash)这一部分。当然直接面向客户(C-Customer)的商机到订单(Lead to Order)主要是在C/4HANA中完成。接下来我们就一起详细探讨一下从订单到收款流程。从订单到收款在从订单到收款的整个过程中,按照维基百科的解释主要有九大流程:https://zh.wikipedia.org/wiki…S/4HANA,作为企业的数字核心(Digital Core),从订单的录入和履行到开票和付款都能完整体现在系统层面。其中一些典型的流程可以用下图表示:为了保驾护航这些流程,S/4HANA的销售领域已经提供的标准角色模板有:(1) 定价专家(SAP_BR_PRICING_SPECIALIST)(2) 内部销售代表 (SAP_BR_INTERNAL_SALES_REP)(3) 退货与退款职员(SAP_BR_RETURNS_REFUND_CLERK)(4) 开票员工(SAP_BR_BILLING_CLERK)(5) 销售经理 (SAP_BR_SALES_MANAGER)(6) 销售流程经理 (SAP_BR_SALES_PROCESS_MANAGER)当然为了完整实现订单到收款,还会有其他角色,比如装运专家(SAP_BR_SHIPPING_SPECIALIST)和应收账款会计(SAP_BR_AR_ACCOUNTANT)等等,如果大家有兴趣今后我们可以单独分享。接下来我们对订单到收款流程中这几个角色逐一介绍,希望借此能帮助大家理解各种业务角色在标准的企业管理中的常见任务与活动。因为我所在的团队正好负责其中销售经理和销售流程经理相关的应用研发,如果有任何问题也欢迎讨论。1. 定价专家此角色主要负责管理销售中的定价,使价格保持为最新状态并使其及时可用。定价专家定义销售中的定价条件记录。基于这些数据和配置专家进行的定价配置,系统计算销售凭证和开票凭证中的价格和成本。其中包括维护特定赠品的特定条件记录(排除奖励数量或包含奖励数量)。在订单到收款的流程中,定价专家会在业务开始之前就会加入,属于偏主数据管理的范畴。因为大多数的事务操作都离不开价格的设置。当然在实际业务中,由于销售策略和市场的变化,定价也会有调整。此角色能开展以下任务:创建、更改、显示和删除用于价格、折扣和附加费的条件记录执行价格、折扣和附加费的批量变更创建、更改、显示赠品的条件记录2. 内部销售代表此角色主要负责管理各种销售凭证和主数据记录。截图中展示的是销售订单相关的应用,其实从下面长长的单子就能发现在内部销售代表这个角色里有非常多的应用,不管是对各种不同的销售凭证的管理,还是对销售相关的主数据维护,甚至监控凭证履行等等。一方面说明内部销售代表在企业的日常运营的重要性,另一方面从标准产品的角度提供了灵活性,每个企业可以基于标准的角色,根据不同类别的细分用户类去建立特定的业务角色,通过增加或删除一些业务目录从而达到对具体销售人员的权限管理。在订单到收款的流程中,内部销售代表会负责大部分报价和订单管理的活动,从订单的录入到订单的履行,同时跟其他业务角色也有合作,比如装运专家,仓库人员。此角色能开展以下任务:创建、更改和显示销售凭证,如以下项:销售询价、销售报价、销售合同、销售订单或借项和贷项凭证请求管理不同销售凭证清单,例如,重复或不完整的销售凭证跨整个从订单到收款场景流程组件跟踪销售订单状态查看关于客户的信息显示主数据记录、如物料或业务伙伴创建销售主数据记录,例如,客户物料在我的销售概览应用中显示有关各种销售活动的信息在销售订单履行流程中监控、解决和协调重要的未处理问题配置并管理产品分配作为检查销售和库存运输订单中物料可用性的方法监控特定时间期间内产品分配对象、分配期间、特征值组合和订单项目的产品分配情况附上一些相关的应用截图。3. 退货与退款职员此角色主要负责客户退货管理以及触发退款。在订单到收款的流程中,如果涉及到客户因为商品质量等原因需要退货,就需要由企业的退货职员管理。此角色能开展以下任务:从开票凭证或销售订单中创建客户退货编辑客户退货确定客户退货退款查看客户退货详细信息处理无费用销售订单4. 开票员工此角色主要负责监控和管理所有开票流程。开票管理是在订单到收款流程中,从销售领域到财务领域的重要环节。开票员工需要基于前导凭证去管理这个环节,甚至负责管理销售佣金等事宜。此角色能开展以下任务:基于先前凭证(例如,交货、开票凭证请求和借贷凭证请求)创建、管理、更改和输出开票凭证(例如,发票、贷项凭证和借项凭证)并将其过账到财务会计基于先前凭证创建、管理、更改和输出临时开票凭证创建、管理、更改和输出由开票凭证组成的发票清单创建和管理可从内部和外部源中持久保存可开票数据的开票凭证请求以条件合同的形式管理返利协议和销售佣金生成和管理条件合同的结算凭证以结算返利协议并在客户财务会计中创建付款创建部分、增量和最终结算以及增量应计结算5. 销售经理此角色主要负责监控和优化销售流程和销售计划,并分析销售特定的关建性能指标 (KPI),例如,销售量和利润率。前序的四个角色可以把主要的事务流程完成,但是对于一个企业的管理而言,分析和监控业务的运营状况至关重要。所以销售经理的活动会从订到到付款的整个过程贯穿始终。此角色能开展以下任务:监控和优化销售流程和销售计划分析销售特定的 KPI,例如,报价转换率、销售合同转换率、新接销售订单、延期交货订单、交货绩效、销售量、利润率和贷项凭证获取与您最相关的销售特定 KPI 的图形概览,例如,收到的销售订单、客户退货、不完整的销售凭证、延期交货订单、利润率、已冻结和逾期销售订单通过实时计划和分析预测销售并设置目标关于销售计划的解决方案,可以参照我的这篇博客:S/4HANA之管理销售计划入门https://blogs.sap.com/2018/03…为了帮助销售经理更智能化的监控和优化销售流程,在S/4HANA里,我们提供了嵌入式预测分析解决方案。https://blogs.sap.com/2018/06…附上一些相关的应用截图。6. 销售流程经理此角色主要负责从订单到收款流程,需要了解企业中的所有销售订单流程的绩效和一致性。流程经理借助S/4HANA的流程业绩监控解决方案开展活动,监控流程中某些步骤的持续时间,以及执行流程期间触发的重要事件出现次数的关键指标。通过这些关键指标的帮助,流程经理可以轻松确定销售流程的运行状态是否良好,并能够快速找出有待改善的区域。此角色可开展以下活动:跟踪交货冻结或开票冻结检测对销售订单的关键字段进行的更改监控提前期(例如从订单到交货或从发货到开票的提前期)关于订单到收款流程绩效监控,后续我单独再分享。如果想提前了解也可以参考这篇SAP社区的博客:Order-to-Cash Performance Monitoring in S/4HANAhttps://blogs.sap.com/2015/09…总结通过对S/4HANA的销售模块中主要业务角色的介绍,大家应该对从订单到收款流程中的角色活动有一个基本的了解,同时对于如何在S/4HANA里去实现OLAP和OLTP的结合有一个直观的感觉。更多详尽的内容请参照SAP官方帮助文档,如果有任何问题,欢迎讨论,谢谢大家。要获取更多Jerry的原创文章,请关注公众号"汪子熙":

January 15, 2019 · 1 min · jiezi

SAP C/4HANA Sales Cloud使用OData服务和第三方系统集成的一个具体例子

出于工作需要,Jerry写了这篇文章,给某些Partner做参考。以前Jerry曾经介绍过SAP C/4HANA的五朵云到底包含哪些具体产品,其实在SAP官网上有更权威的中文解释:https://www.sap.com/china/pro…其中明确提到销售云包含SAP Cloud for Customer(C4C),SAP Revenue Cloud和Callidus Cloud。有Partner询问有没有更详细的步骤介绍,关于如何在第三方系统里调用SAP C4C暴露出的Restful API进行集成。本文就给出一个具体的例子,将SAP C4C销售订单的创建功能通过自定义的OData服务暴露出来,然后Partner可以根据项目需要选择合适的编程语言(本文选择JavaScript)来消费。Jerry以前发布过一个视频,演示了如何在SAP C4C里手动创建一个销售订单,步骤可以说简单易懂。https://v.qq.com/x/page/d0809…现在我们通过OData的方式将销售订单的创建功能暴露出来,就能在第三方系统或者应用里完成C4C的订单创建。大家如果对SAP OData还不太了解,可以先读一读我这篇文章开头的部分:SAP OData编程指南下面是详细步骤。登录C4C系统,访问工作中心Administrator,工作中心视图OData Service Explorer,这里可以在SAP发布的标准OData服务和客户自定义的OData服务之间切换。因为客户自定义OData服务能够允许客户自行决定从哪一个Business Object的哪一些节点,选择哪一些字段来生成OData模型,通过这种灵活的方式可以避免Business Object上客户业务场景里不需要的字段出现在OData模型中。点击New按钮新建一个OData服务:给Work Center View字段指定一个用来做权限控制的视图,只有分配了这个视图的用户才有权限访问这个OData服务。点击Select Business Object从弹出对话框中选择基于哪一个Business Object创建OData模型。下图就是一个已经创建好并处于Active状态的OData服务。左边显示的是CustomerQuote这个BO的Root节点的所有字段,每个字段都有一个可以勾选或取消的Select属性,勾选则该BO字段会出现在右侧的OData模型里。除了Root节点之外,BO的其他子节点上的字段当然也是可以出现在OData模型里的,比如我上图右边OData模型的子节点CustomerQuoteItem, CustomerQuoteParty和CustomerQuoteText等,就是分别从左边BO的同名节点选中后自动带到右边的OData模型中去的。理论上,完成基于BO模型进行OData模型的创建并激活后,这个OData服务就可以使用了,这体现了SAP C4C OData服务自定义框架的强大之处。然而我也收到了一些朋友从后台给我提的一些问题,罗列如下。问题1: 仍然以本文销售订单创建这一场景为例,假设我希望我创建的OData服务能够允许消费者调用时指定External Reference的值,但是我找遍整个BO列表,也没发现销售订单的BO上有叫这个名称的字段啊?Jerry答:External Reference是UI文本,不是BO字段的技术名称。给C4C系统在浏览器里的url添加参数debugMode=true, 然后刷新页面,按住Ctrl键再单击External Reference字段,就能看到这个UI字段绑定到UI模型上哪一个字段了。在这个UI模型字段上再点击Show Model,就能看到这个UI模型字段绑定到的BO字段名称为BuyerID。所以我们在OData开发工具里,只需把BO字段BuyerID选中,移动到右边的OData模型里即可。问题2:我想让我的OData服务支持行项目数据的创建,比如指定产品ID,描述和购买数量等等。我怎么知道哪些BO节点上的字段需要添加到OData模型中去?Jerry答:现在我们换一种方法,打开Cloud Application Studio的UI Designer,定位到销售订单创建页面的UI模型COD_SALESORDER_QC, 找到Product ID字段,在它的Properties面板里即可看到这个Product ID字段绑定的BO字段的名称和完整路径:Root-.ItemProposal-~ProductUUID-~content因此我们需要将BO对应路径下面的ProductUUID字段添加到OData模型中去。这里能观察到ProductID的Create和Update是没有勾选上的,而ProductUUID则支持Create和Update,这个行为和C4C销售订单行项目创建的标准实现有关——消费者需要提供待创建行项目包含的产品UUID,然后C4C会根据UUID到系统中查询出对应的产品,显示其ID到UI上。如果消费者在调用OData服务时,没有指定ProductUUID,则行项目创建逻辑不会执行。OData模型创建好之后,在用编程语言消费之前,我们可以先用工具Postman(或者C4C自带的测试工具)进行测试。因为SAP C4C后台对Cross-site request forgery(跨站请求伪造)这种攻击采取的防御实现和SAP CRM,SAP S/4HANA一样,采取的是CSRF token验证机制,因此我们在调用OData服务进行销售订单创建时,需要将一个合法的CSRF token一并传递给C4C系统。如何得到一个合法的CSRF token呢?在Postman里构造一个HTTP GET请求,头部字段名为x-csrf-token, 值为fetch:发送这个HTTP GET请求,服务器端会生成一个CSRF token,通过HTTP响应结构头部字段x-csrf-token返回给消费者:sNwnYC9cV4xeGSYZmJ8Dtw==下面我们再在Postman里新建一个HTTP Post请求,将之前通过HTTP GET拿到的CSRF token,以HTTP Post请求头部字段的方式发送给C4C系统。关键在于HTTP Post请求的请求体。下图高亮部分是我在HTTP Post请求里指定的创建销售订单的输入数据:在Postman里发送这个Post请求,几秒钟后得到C4C的响应,订单创建成功,ID为9000000451:为了方便大家对比,下面是我用Postman消费我创建的OData服务生成的销售订单在系统里的显示。字段1~6对应的Postman输入字段可以在前文找到。蓝色区域高亮显示的字段,我在Postman里构造的输入里并没有维护,而是通过SAP C4C系统的各种determination配置,自动决定出来的。最典型的有SAP老司机们天天打交道的Partner determination,Organization determination,Pricing determination等。Postman里测试通过后,就可以写代码消费了。如果想直接复制粘贴我下面列出的代码,可以从我的github上获得:https://github.com/i042416/Kn…注意本代码只用于演示目的,缺少健壮的出错处理,不能直接用于生产环境中。下面的代码使用nodejs提供的request模块向C4C请求CSRF token。注意第3行的url和第11行的Authorization头部的值,我都是用的虚假值,请大家替换成自己实际使用的C4C url和认证信息。Token拿到之后,将其放入第41行构造的HTTP Post请求的头部结构中,作为字段x-csrf-token的值。第47行发送该POST请求,C4C响应的数据存放于JavaScript变量data中。最后我通过简单的console.log打印出创建成功的销售订单ID:在命令行里用node执行这个js文件,会打印出从C4C获取到的CSRF token,以及成功创建的订单ID。我们再回顾一下用SAP C/4HANA Sales Cloud中的C4C OData同外部系统做集成的三个主要步骤:1. 在C4C的OData模型编辑页面里,根据业务需要,从对应的BO节点里选择合适的字段,添加到OData模型中。2. 用Postman或者C4C自带的OData测试工具对OData模型进行测试,确保其正常工作。3. 根据项目需要选择合适的编程语言消费OData服务。如果对于SAP C4C OData有更多的问题需要讨论,欢迎留言。感谢阅读。Jerry关于OData的更多文章1. SAP OData编程指南2. OData服务同步模式和异步模式的讨论https://blogs.sap.com/2015/06…3. OData服务的性能分析https://blogs.sap.com/2015/07…https://blogs.sap.com/2016/01...4. 基于SAP CDS view生成OData服务https://blogs.sap.com/2016/03…5. OData的offline支持5.1 https://blogs.sap.com/2016/08…5.2 https://blogs.sap.com/2016/08…5.3 https://blogs.sap.com/2016/08…6. 使用ABAP消费SAP C4C标准OData服务https://blogs.sap.com/2017/08…7. SAP CRM,C4C和S/4HANA里OData服务实现的横向比较https://blogs.sap.com/2017/08…8. 使用Java和jMeter对需要支持CSRF验证的OData服务进行高并发性能测试https://blogs.sap.com/2017/08…9. 使用C4C OData + ABSL消费自定义BO的逻辑https://blogs.sap.com/2017/12…要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

January 15, 2019 · 1 min · jiezi

浅谈SAP Cloud for Sales 自动化

在Jerry还在本科进行计算机理论知识学习时,我曾经把软件开发里的质量工程师(Quality Engineer)理解成是每天只是简单地做着运行开发人员编写好的软件,如果发现问题,通知开发人员去修改这种机械的体力活。后来进入SAP后,观察团队里的质量工程师每天做的事情,才知道我当初简直是很傻很天真。我的两位同事,姚瑶和郑晓霞,之前已经就她们在SAP质量工程师这个岗位上工作的一些体会做了分享:SAP成都研究院姚瑶:软件质量保证工作的变迁SAP成都研究院郑晓霞:Shift Left Testing和软件质量保证的一些思考今天,由Jerry的另一位同事,Tang Minna继续给大家带来SAP标准产品质量控制方面的分享。*大家好, 我是唐敏(Minna Tang),目前是SAP成都研究院C4S(Cloud for Service)团队的质量工程师。除了本职工作以外,我喜欢烹饪苏菜——少了川菜的热烈与厚重,却多了一份自然与纯真;喜欢在图书馆里拜读名人传记——看尽红尘故事之后,静静地感受时光的流逝;闲暇时也喜欢尤克里里——跟随跳动的音符,感受人生的起起落落。今天我想基于目前C4S产品的现状和自身的技术背景,简单聊聊自动化这个动人心魄、让人又爱又恨的话题。相信任何一个软件开发团队的每位成员,听到“自动化”一词,都会抱有热烈的期待。对于老板来说,这个词意味着成本的下降及更高的ROI(Return On Investment,投资回报率);从开发工程师的角度,自动化有助于更早地检测到代码变更对原有功能的影响;测试工程师当然是全力支持自动化的,因为省心和省力;产品经理自然也不会拒绝自动化,因为它能够带来更高效的交付和更快速的迭代。然而,我们身边也不乏自动化实施失败的团队。2013年在我前一家工作的公司里,我曾参与某核心系统项目的开发工作,这个业务系统从需求到完整上线共耗时一年半,核心功能的开发更是耗时大半年之久。面对如此庞大的业务测试成本和强需求,PMO(Project Manage Office)在项目开发之初就启动了自动化测试需求,然而在业务功能不稳定,产品需求、开发与测试基本属于赶工状态的情况下,与人工回归相比,自动化所带来的收益基本微乎其微。所以选择适当的自动化时机和策略,是自动化成功与否的重要因素之一。众所周知,SAP众多产品都在使用自研的ABAP进行开发。当我加入SAP后,我了解到这些运行在ABAP Netweaver之上的产品,均有完备的自动化测试。对于ABAP后台功能代码,主要是开发人员为核心功能编写完备的,覆盖率高的单元测试,然后用事务码SUT调度成后台作业定期执行,如果自动化测试执行时发现故障,会自动发邮件通知相关人员。前台UI代码,无论是原生的Fiori应用还是CRM Web Client UI这种加了一层皮肤的类Fiori应用,都能通过Selenium来进行UI的自动化测试。当然,SAP成都研究院也在进行众多基于微服务架构的云产品开发,主要使用Java编程,那么自动化测试的实现也更加容易,Spring系列框架里有大量成熟和流行的自动化测试套件可供使用。从迭代发布的角度讲,C4S产品的发布周期为一个季度一次,每个季度中有三个周期:前两个周期主要完成新功能开发,第三个周期需要团队成员既完成新功能测试,也需要回归系统原有功能。与此同时,每个季度中还有5次补丁的发布,每一次都需要完成原有业务的回归测试。夹在产品新特性测试和回归测试之间的,是一望无际的工作量和对高效率、高质量测试的需求。我为所在团队负责的功能制定的自动化的策略是: 接口 + UI自动化覆盖。也许您会问,作为一个请求的最前端,既然UI的测试都能覆盖了,那自动化测试为什么还需要接口的覆盖?工作量是否存在重复?从功能的角度来讲,确实有些重复。但从收益的角度来讲,对接口的自动化测试进行投入,收益远超成本。1. 对于任意一个系统,接口的稳定性在整个系统中的重要地位不言而喻。相对于后置的E2E(端到端)测试,接口测试能够从基础层减小变更对整个应用及下游业务调用方的影响范围。2. 同时,接口的测试也能为UI自动化实施提供基础数据。UI自动化为了完成某个场景的测试,通常会有很多前置业务数据的依赖。这些UI自动化需要的测试数据如何生成?有同事建议可以提前手工造数据。如果自动化测试的数据都要依靠手工来维护,在我看来,这个自动化不要也罢。通常,在接口测试完成之后会将已测试通过的接口封装成工具类,供后续UI自动化的工程化调用,这样既减少了UI自动化的数据依赖,对接口测试通过率也提出了更高的要求。所以一般的接口工程必须100%通过,才能完成触发后续UI自动化的作用去执行功能测试。3. 为性能测试准备打下坚实的基础。通常准备性能测试之前,接口测试的响应时间会成为反馈接口性能的重要依据。我们在制定接口性能的SLA(Service-Level Agreement)时,其基本数据来源就是接口测试。而很多互联网公司,相对于端到端的响应时间,他们更注重接口的响应时间,因为接口更底层。尤其针对多层接口依赖的系统,每年 618,双11之前的线上大促压测,接口全链路测试必定是重中之重。我在C4S推荐使用的接口测试框架为Spring + Maven + Testng,语言为Java, 被测对象为C4S oData服务提供的HTTP API。其中Spring框架主要负责通过注解方式完成对象注入,Maven负责工程结构和Jar包管理,Testng负责具体的测试工作。对于不熟悉Java的朋友来说,借助现有工具诸如Postman也能很好地胜任这项工作。1. 工程结构及说明接口主体工程以Maven规范工程为模板,所有的代码和相关资源文件均放置在src/test目录下。工程模块主要分为4部分:测试代码、枚举对象、工具类及相关资源文件。测试代码:这是测试代码的主要存放目录。 通常根据业务的不同,我们将每一个接口的测试案例按照业务测试和参数测试分别编写。所谓业务测试,是指测试案例中涉及业务规则的部分。比如,某接口中存在一个channel(渠道)字段。业务规则定义:当channel为all时,创建全渠道使用的数据;当channel为特定值时,创建的数据只能适用于特定的场景。则业务测试的案例有2个:o Channel = allo Channel = 特定数据参数测试:主要测试接口参数字段是否为必填项。比如,某接口中存在一个channel为必填字段且必须为指定枚举类型字符串,当传入接口为null或blank或非枚举值时,框架返回HTTP 400参数错误,同时提示错误信息。此时参数测试案例有3个:o Channel = nullo Channel = “”(blank)o Channel = “XXXX”(XXXX为非枚举值)枚举对象:此部分是将业务中经常用到的固定参数使用枚举的方式列出,方便整个工程使用。见下图中httpEnum文件夹中的类。工具类:包括基本工具类和业务工具类部分。业务工具类是将特定接口进行封装,方便下游接口调用使用。资源文件:包括Spring相关配置,properties文件以及参数测试中的数据来源文件等。2. 案例编写此处以实现oData的SocialMediaActivity 接口的自动化测试为例来进行说明。我们借用颜值大师——李晓刚老师画的图来大致了解SociaMediaActivity在C4S微信集成架构中的作用:由上图所知,C4S通过暴露SocialMediaActivity接口来方便Agent调用。在C4S和Social Media集成的相关场景中,用户可以通过关注微信公众号来绑定一个特定的BusinessPartner(以下简称BP), 从而达到通过用户在系统中自定义的微信Channel来直接与C4C服务模块中的工作人员直接交互的目的。而Activity是针对指定的BP所进行的活动,例如创建ticket,点赞,回复等。故而完整的业务流程如下:获取系统token获取已关联的BP信息创建ticket信息评论/点赞/回复操作 数据清理BeforeClass: 执行获取token的准备工作。BeforeMethod: 创建/获取已关联的BP信息。Test: 特定业务的测试案例。本处对Activity的层级和操作内容进行检查,因此有2个测试方法。AfterMethod:清理已创建的Activity。此处需要重点说明是,为避免后台错误数据对应用正常使用的影响,每一次执行都需要对增量数据进行清除处理,保持环境干净整洁。AfterClass: 清理创建的BP信息。3. CI(Continuous Integration, 持续集成)基于Maven工程的集成,本例中使用Jenkins进行示例,与此同时项目工程中需要使用surefire-plugin(一个用来执行测试用例的Maven插件)来配置相关的测试案例范围。在pom.xml中配置testng.xml文件:testng.xml文件内容示例:使用Maven的好处再次体现,只需要简单配置即可使用:在Jenkins中加入testng report plugin展示,然后build即可。虽然我更擅长使用基于Java的Selenium这个UI自动化框架,也明白接口测试完成之后,对UI自动化的巨大帮助,但由于C4S在印度和美国团队内都使用现有的成型产品SAHI,所以这里我只介绍SAHI在C4S的应用。SAHI是Tyto Software旗下的一个基于业务的Web应用自动化测试工具, 通过注入 JavaScript来访问 Web 页面中的元素。相对于Selenium等自动化测试工具,SAHI在动态 ID元素查找和隐式页面等待处理等方面具有一定的优势。感兴趣的同事可前往官网进行尝试。1. 工程结构及说明此处以Social 案例为例:DD_CSV: 案例运行的的数据来源Function_Library: 该目录中存放已封装的基本共用函数,如登录、登出、工作中心访问、表格访问等。更加细致的封装则是将页面元素抽象到Library中的IDS下,便于统一管理, 如下图:SCRIPTS:特定的UI测试案例。SUITE:测试案例运行的范围。2. 案例编写此处以RUI项目中SingleTab功能为例进行说明。MultiTab和SingleTab功能是指在C4S产品中,当用户在全屏模式下打开某一个或多个工作视图时,系统会将多个工作视图以Tab的形式显示在工作区中;但是当用户修改浏览器大小到一定尺寸后,工作区中将只显示活动的那个Tab。 MultiTab显示时,有活动与非活动Tab之分,同时要适配多个Tab的鼠标操作切换和通过功能菜单的切换。如下图所示:SingleTab显示:只显示当前活动的Tab,在显示数据和形式上与MultiTab有差别,同时也要适配通过功能菜单的Tab切换。与此同时,该特性需要测试系统在不同的主题、字体大小下此特性也能正常工作。因此测试案例的流程如下(可参考代码注释部分): (1) 重置相关特性:浏览器大小,主题,字体大小,视图类型,页面默认过滤器(2) 访问特定的工作视图并显示特定数据,验证全屏模式下活动状态的/非活动状态的MultiTab的显示和Tab上数据的正确性(3) 缩小浏览器大小:验证Tab上数据正确性修改系统主题,验证SingleTab的显示修改字体大小,验证SingleTab显示3. CI集成基于Jenkins的强大的插件功能,C4S通过将Jenkins与GTP(内部缺陷管理平台)的集成完成CI调度和运行。UI自动化的CI集成,使得C4S产品的回归测试的效率大大提升。以今年8月份发布的版本为例,手工回归的测试案例目前已接近7000个。如前文所述,诸多的测试案例在每个迭代中持续的回归测试,则是一项耗时又耗力的工程。而且这仅仅只针对回归测试所执行的案例。从手工回归测试案例的数量不难看出,快速反馈系统功能状态机制在持续交付链中的重要性。而在对接口进行全覆盖测试之后,对UI自动化覆盖回归测试主流程的需求也愈加强烈。在C4S,我们借助Jenkins 并行测试完成UI自动化,并使用邮件通知测试结果。在节省人工回归成本的同时,使得产品管理团队能够在短时间内快速、全面了解系统功能的运行情况,并给与团队成员质量的信心。与此同时,在出现模块功能失效甚至是系统宕机时,这种快速反馈链的建立为开发人员尽早尽快修复问题争取了时间,减少了后续修复的时间成本。就目前的测试覆盖需求而言,由内到外的接口覆盖及端到端的UI覆盖,在满足底层稳定可靠的同时,也保证前端功能的可用性。对于SAP质量工程师而言,工作内容远非测试工作这一项内容,从团队成员质量意识的提升到单元测试覆盖及检查;从测试工作到团队质量反馈,都是SAP质量工程师在每日工作中需要去花心思琢磨的。而从团队利益着手,考虑每一项质量活动的价值和意义,对质量工程师来说是一项全局观的考验,也是一场质量与效率的平衡。以上就是我今天关于C4S自动化的分享,如有疑问或进一步探讨,欢迎联系我们,感谢阅读。相关阅读SAP成都研究院姚瑶:软件质量保证工作的变迁SAP成都研究院郑晓霞:Shift Left Testing和软件质量保证的一些思考要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

January 15, 2019 · 1 min · jiezi

SAP S/4HANA使用ABAP获得生产订单的状态

在S/4HANA里,我们如何根据一个销售订单的行项目,查看对应的生产订单状态?双击行项目:点击Schedule line:这里就能看到生产订单的ID和状态了。其中订单的状态存储在表vsaufk里,注意订单和状态可以是1对多的关系。状态的ID和描述信息存储在表tj02t里,所以有了下面的代码:METHOD get_prod_order_status.DATA: lt_status TYPE TABLE OF j_status,lt_text TYPE TABLE OF tj02t,lv_id LIKE iv_prod_order_id,ls_result LIKE LINE OF rt_status_in_s4_format.lv_id = iv_prod_order_id.CALL FUNCTION ‘CONVERSION_EXIT_ALPHA_INPUT’EXPORTINGinput = lv_idIMPORTINGoutput = lv_id.SELECT stat INTO TABLE lt_status FROM vsaufk WHERE inact = space ANDaufnr = lv_id.CHECK sy-subrc = 0.SELECT * INTO TABLE lt_text FROM tj02t FOR ALL ENTRIES IN lt_statusWHERE istat = lt_status-table_line AND spras = ‘EN’.LOOP AT lt_text ASSIGNING FIELD-SYMBOL(<text>).CLEAR: ls_result.ls_result-status_id = <text>-istat.ls_result-status_code = <text>-txt04.ls_result-status_text = <text>-txt30.APPEND ls_result TO rt_status_in_s4_format.ENDLOOP.ENDMETHOD.测试一下,成功拿到所有状态,和事务码CO03里看到的一样。要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

January 15, 2019 · 1 min · jiezi

SAP Cloud for Customer销售订单External Note的建模细节

SAP Cloud for Customer的销售订单创建页面里,我们可以给一个订单维护External Note,当这个订单同步到S/4HANA生成对应的生产订单后,这个note可以作为备注提示生产工人。它的建模逻辑是:首先进入调试模式,查看到这个字段绑定到UI模型的TextCollection/CustomerInformation上然后进入Cloud Application Studio,找到UI模型这个字段,查看发现它又绑定到了BO的TextByTextTypeCodeAndLanguageCode.这里不难猜测出,SAP C4C BO上支持多种类型的note,通过typecode区分。那么我怎么知道External Note对应的typecode的值呢?这个好办,在系统里维护一条带有External note数据的销售订单,比如这条:然后通过OData读取这条销售订单,OData url如下:https://jerry.sap/c4c/odata/c…‘00163E7209B31EE98297C038F2A3FDDC’)/CustomerQuoteText响应里包含的字段TypeCode的值10024就是External Note的type code。要获取更多Jerry的原创文章,请关注公众号"汪子熙":

January 15, 2019 · 1 min · jiezi

SAP成都研究院2018年总共87篇技术文章合集

2018年很快就要结束了。Jerry在2017年年底准备开始写这个公众号时,给自己定的目标是:2018年至少保证每周发布一篇高质量的文章。如今2018年就快过去了,高质量与否需要大家来反馈,至少从量上看,已经达到我订的目标了。当然这87篇技术文章,有31篇文章是Jerry的成都研究院同事贡献的,在这里对这些同事表示感谢。按照名字的字母顺序,依次感谢:Chen VickyDeng SunHe AndrewLi BenLiao JanetMa HongboPeng SunShinePing JingJingSong HaoTang MinnaWang CongWen AvivaWu DavidXia JasonXu BorisXu HaythamYang JoeyYao YoyoZhang HarryZhang JonathanZhang SeanZheng KateZhou Shuai下面是文章列表。文章后面如果未跟作者名字,则默认作者是Jerry本人。这个视频是我的同事,Zhou Shuai用他的无人机完成的SAP成都研究院大楼的航拍,欢迎广大SAP同仁来访问参观。1. Jerry的CDS view自学系列 2. Jerry的通过CDS view + Smart Template 开发Fiori应用的blog合集3. Jerry的ABAP, Java和JavaScript乱炖4. C4C和微信集成系列教程5. Jerry的2017, 编程与游泳6. Jerry的UI5框架代码自学教程 1/1/20187. Jerry的碎碎念:SAPUI5, Angular, React和Vue 1/2/20188. ABAP开发人员未来应该学些什么 1/3/20189. Jerry 2017年的五一小长假:8种经典排序算法的ABAP实现 1/5/201810. SAP的这三款CRM解决方案,您能区分清楚么 1/6/201811. SAP Fiori应用的三种部署方式 1/8/201812. 关于S/4HANA里Sales Office 和Sales Organization那些事儿 1/10/2018 Zhang Sean13. SAP成都研究院35岁以上的开发人员都去哪儿了? 1/13/201814. Jerry的WebClient UI 42篇原创文章合集 1/14/201815. Jerry的CRM Middleware(中间件)文章合集 1/16/201816. 从产品展示页面谈谈Hybris的特有概念和设计结构 1/17/2018 Zhang Jonathan17. 阿里云上到底能运行SAP哪些产品? 1/19/201818. Jerry的ABAP原创技术文章合集 1/21/201819. Jerry的Fiori原创文章合集 1/26/201820. OAuth 2.0协议在SAP产品中的应用 2/3/201821. 从产品展示页面谈谈Hybris系列之二: DTO, Converter和Populator 2/10/2018 Zhang Jonathan22. Hello World, S/4HANA for Customer Management 1.0 2/28/201823. 从程序猿到SAP产品经理,我是如何转型的?(上篇)3/11/2018 Xia Jason24. 从程序猿到SAP产品经理,我是如何转型的?(下篇)3/18/2018 Xia Jason25. 那些年我用过的SAP IDE 3/24/201826. SAP S4CRM vs C4C, 诸葛亮和周瑜? 3/30/201827. SAP成都C4C小李探花:浅谈Fiori Design Guidelines 4/8/2018 Zhou Shuai28. Jerry和您聊聊Chrome开发者工具 4/15/201829. SAP成都研究院李三郎:SCP Application Router简介 4/22/2018 Li Ben30. Jerry眼中的SAP客户数据模型 4/28/201831. 300行ABAP代码实现一个最简单的区块链原型 5/3/201832. SAP UI和Salesforce UI开发漫谈 5/8/201833. 汶川大地震中的SAP成都研究院 5/12/201834. SAP成都研究院的体育故事 5/13/2018 Deng Sun35. 使用Java程序消费SAP Leonardo的机器学习API 5/14/201836. 使用Java+SAP云平台+SAP Cloud Connector调用ABAP On-Premise系统里的函数 5/16/201837. 使用JDBC操作SAP云平台上的HANA数据库 5/18/201838. 用JavaScript访问SAP云平台上的服务遇到跨域问题该怎么办 5/23/201839. 金庸和古龙,Netweaver和微服务,以及SAP Hybris Revenue Cloud 5/25/2018 Chen Vicky40. SAP成都研究院马洪波:提升学习力,增强竞争力,收获一生乐趣 5/27/2018 Ma, Hongbo41. SAP Cloud for Customer 使用SAP UI5的独特之处 5/30/2018 Yang Joey42. 一个SAP顾问在美国的这些年 6/2/2018 Song Hao43. SAP成都研究院菜园子小哥王聪:当我用UI5诊断工具时我用些什么 6/4/2018 Wang Cong44. 写在Github被微软收购之际 - Github的那些另类用法 6/5/201845. 在SAP云平台的CloudFoundry环境下消费ABAP On-Premise OData服务 6/7/201846. 企业数字化转型与SAP云平台 6/10/201847. SAP UI 搜索分页技术 6/16/2018 Wang Cong48. SAP OData编程指南 6/18/201849. SAP数据中心概述 6/23/201850. SAP成都研究院飞机哥:程序猿和飞机的不解之缘 6/24/2018 Zhang Harry51. SAP成都研究院DevOps那些事 6/30/2018 Ping, Jingjing52. ABAP vs Java, 蛙泳 vs 自由泳 7/3/201853. SAP产品的Field Extensibility 7/14/201854. SAP Cloud for Customer Extensibility的设计与实现 7/21/2018 Xu Boris55. 从产品展示页面谈谈Hybris系列之三:Hybris Service层介绍 7/28/2018 Zhang Jonathan56. SAP成都研究院姚瑶:软件质量保证工作的变迁 8/3/2018 Yao Yoyo57. SAP移动应用解决方案之一:HTML5应用 + Cordova = 平台相关的混合应用 8/8/2018 Yang Joey58. 使用Recast.AI创建具有人工智能的聊天机器人 8/9/201859. SAP成都研究院安德鲁:自己动手开发一个Chrome Extension 8/18/2018 He Andrew60. 在SAP UI中使用纯JavaScript显示产品主数据的3D模型视图 8/21/201861. 一个SAP开发人员的双截棍之路 8/22/201862. 机器学习在SAP Cloud for Customer中的应用 8/26/201863. 你的项目刚刚启动?是时候考虑Globalization了!9/1/2018 Wang Cong64. 聊聊C语言和ABAP 9/7/201865. SAP成都研究院郑晓霞:Shift Left Testing和软件质量保证的一些思考 9/13/2018 Zheng Kate66. Hyperledger Fabric on SAP Cloud Platform 9/16/2018 Wen Aviva67. SAP云平台,区块链,超级账本和智能合约 9/18/201868. 动手使用ABAP Channel开发一些小工具,提升日常工作效率 9/22/201869. 打通C/4HANA和S/4HANA的一个原型开发:智能服务创新案例 9/26/201870. 我用ABAP做过的那些无聊的事情 9/29/201871. 不喜欢SAP GUI?那试试用Eclipse进行ABAP开发吧 10/8/201872. SAP成都研究院数字创新空间沟通S/4HANA和C/4HANA的智能服务演示视频和Coresystems分享预告 10/13/201873. SAP成都研究院许聚龙:Hello, Coresystems!10/17/2018 Xu Hathyam74. SAP成都研究院Sunshine: 我的C4C实习感受和保研之路 10/25/2018 Peng, Sunshine75. Jerry的知识星球:SAP中国神秘奶牛关卡 10/29/201876. 金庸的武侠世界和SAP的江湖 11/1/201877. 加入Jerry的知识星球,共同讨论SAP技术 11/3/201878. SAP成都研究院大卫哥:SAP C4C中国本地化之微信小程序集成 11/7/2018 Wu David79. SAP成都研究院飞机哥: SAP C4C中国本地化之微信聊天机器人的集成 11/12/2018 Zhang Harry80. 站在巨人肩膀上的牛顿:Kubernetes和SAP Kyma 11/18/201881. SAP S4CRM 1811 服务订单API介绍 11/24/2018 Song Hao82. 在Kubernetes上运行SAP UI5应用(上)12/2/201883. 在Kubernetes上运行SAP UI5应用(下) 12/4/201884. 一些SAP Partners能够通过二次开发实现打通C/4HANA和S/4HANA的方法介绍 12/7/201885. SAP成都研究院廖婧:SAP C4C社交媒体集成概述 12/8/2018 Liao Janet86. SAP Fiori + Vue = ?12/18/201887. 浅谈SAP C4S自动化 12/25/2018 Tang Minna要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

January 15, 2019 · 2 min · jiezi

SAP Cloud for Customer里Sales Order和Sales Quote的建模方式

SAP Cloud for Customer的Sales工作中心里有Sales Quote和Sales Order两个视图,一个用于销售报价单,另一个用于销售订单。流程上是先有报价单 ,报价单是一份OFFER,并不具备法律效力,只有在生成销售订单后,即买卖双方都对报价单上的内容进行一些协商后,达成一致生成的最终订单,才具有法律效力。现在我需要搞清楚Sales Order这个视图的UI是基于哪个Business object创建的。SAP C4C的UI都是基于MVC pattern设计的,首先在Chrome开发者工具里找到UI的模型名称:/BYD_COD/SalesOnDemand/SalesOrder/UI/COD_SALESORDER_TI.TI.uicomponent到cloud Application Studio的UI Designer里打开这个UI 模型,在Data model区域找到Business object的名称为CustomerQuote,这就有点怪了,我起初以为是Sales Order。后来在CustomerQuote这个BO上发现一个字段叫做TypeCode,才知道Sales Order和Sales Quote这两个业务模型底层的技术模型都是共享CustomerQuote这个BO,可以通过TypeCode来区分。typecode为30,代表这是个Sales Quote:typecode为2059代表是一个Sales Order:要获取更多Jerry的原创文章,请关注公众号"汪子熙":

January 13, 2019 · 1 min · jiezi

SAP Cloud for Customer Sales Order Requested Date的业务含义和实现

我们在创建Sales order销售订单时,需要指定一个RequestedDate:这个字段绑定到了BO字段:CustomerQuote.RequestedFulfillmentPeriod.TimePointPeriod.StartTimePoint.DateTime这是一个0-1的BO内部的association:为什么Requested Date总是比创建日期晚两天呢?是在这里配置的:2 Days意思就是比创建日期晚2天抬头的Requested Date的值会通过C4C BO后台的determination复制给行项目Schedline line的同名字段。要获取更多Jerry的原创文章,请关注公众号"汪子熙":

December 21, 2018 · 1 min · jiezi

SAP CRM settype的创建,背后发生了什么

来自我的同事Sara。当我们在CRM系统里创建一个settype之后,其实系统后台悄悄的帮我们创建了很多ABAP对象,比如对应的database tables, other ABAP Dictionary objects, function groups, function modules, and screens等等。Create set types:DB check:自动创建了一个和settype ID同名的数据库表问题:How this DB generate?How to check what function groups, function modules, and screens are created? Especially which screens?When we assign the attributes to the set type, I guess it will insert lines into the table.Jerry的解答:当你创建一个新的settype时,product框架会自动生成针对该settype的structure和存储Table, 以及对应的用于CRUD的function module。但是了解框架本身如何实现我前面说的这些事情,对我们接下来做的co deployment没有直接帮助。你的这个问题可以转换成:假设我只知道product的description字段是通过某个settype实现的,我想不问别人,自己弄清楚该settype的名字和访问该settype的CRUD的function module名字,该如何做?I got one information from my colleague, the Product Description function is implemented by the SAP standard set type. Then I want to make clear:(1) Which standard set type implement Product Description and it’s DB table?(2) Which function module (API) implement the CRUD of Product Description?写在前面:本文提及的方法只限一种思路,不排除个别Assignment Block 不适用的情景,请大家广开思路,积极探索更多的方法来研究,希望能总结出更多的具体API,简化每一个功能的实现。Product ID: SZIPC (in QHD)After this self study, I can get a general knowledge of how the product fields implemented in the SAP System.Then I will start this self study step-by-step by question driven.(1) Which standard set type implement Product Description?Try Google it first. Wow, got some information. set type name COMM_PR_SHTEXT.(2) Is it right? How can I display set type?One way, Google.Second way, I would like to use SE93 to find transaction code by transaction description, got it!TCODE: COMM_SETTYPEThere is some issue, you can not display set type by TCODE: COMM_SETTYPE directly, you can only use COMM_ATTRSET input the set type COMM_PR_SHTEXT first the sue TCODE: COMM_SETTYPE to dispaly.(3) Then how can I find the DB for this set type and the CRUD function model?There is 2 ways.The first way, is to use TCODE: ST05 trace.I update the description from Material_Sara to Material_SaraZhang. I search with key words ‘Material_SaraZhang’, then I find the DB–COMM_PORTEXT.The second way, I would like to use TCODE: SE93 find the package of TCODE COMM_SETTYPE.–Assume,I do not know, Most of the Set Type name = DB Table name.There must be a table include all the Set Type name and DB Table names, how can I find it?This is an important thinking point, for every TCODE in SAP, it’s a collection of multiple functions /tables/views. Which should be packaged in a package.In the package, there is multiple DB, from the DB description, you can know COMC_SETTYPE is the admin table which include all information we want.–Admin table and header table always as the start and base point of DB relationship.Filter by the set type name COMM_PR_SHTEXT, we found the set type DB COMM_PRSHTEXT and related function module.(4) How the function module work when I read the product description?TCODE: SE37 find COM_COMM_PR_SHTEXT_READ_WITH_P and set breakpoint.search Product ID: SZIPCin WebClient UI.Follow the call stack, find the key API for read product set types.(5) How the function module work when I Update the product description?Function Module: COM_COMM_PR_SHTEXT_MAINTAIN_UPFollow the call stack, find the key API for update product set types.(6) I will try to simplify this function module, pick this function into a report for confirming how does this CALL FUNCTION ‘CRM_PRODUCT_UI_GETDETAIL’ work?This is the key function for processing product set types.We’d better to understand it’s indeed input valueOne, is product guid in a structure.Two, is the set type name.It means that, any set type can read by this function.要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

December 21, 2018 · 3 min · jiezi

Vtiger CRM 几处SQL注入漏洞分析,测试工程师可借鉴

本文由云+社区发表0x00 前言干白盒审计有小半年了,大部分是业务上的代码,逻辑的复杂度和功能模块结构都比较简单,干久了收获也就一般,有机会接触一个成熟的产品(vtiger CRM)进行白盒审计,从审计的技术难度上来说,都比公司内的那些业务复杂得多,而真正要提高自己技术水平,更应该看的也是这些代码。vtiger CRM是一个客户关系管理系统。0x01 分析整体结构https://www.vtiger.com/open-source-crm/download-open-source/代码下载下来,本地搭建。使用phpstorm进行审计。主目录下的vtigerversion.php可以查看当前版本。整体代码目录 其中主要得功能实现就在modules目录当中,也是我们重点审计的地方。libraries目录是使用到的第三方的一些东西,includes目录是路由加载,封装系统函数的地方。整个系统代码量确实很多,真要审计完估计没有十天半个月是不行的,看了一个礼拜,只发现几个问题。0x02 modules/Calender/actions/feed.php SQL注入分析一个成熟的产品,审计的难点就在于各种类,对象的封装和继承,A调用B,B调用C,C调用D……Vtiger_BasicAjax_Action 这个对象,是modules下vtiger目录里的,而vtiger这个也是核心的module.回到feed.php,直接定位有漏洞的代码,103行后。我图中标的,也正是注入点的位置。$fieldName参数由逗号分割成数组,如果分成后的数组值为2则进入逻辑,然后参数进入SQL语句形成注入。虽然整个系统采用了PDO的查询方式,但是如果有SQL语句存在直接拼接的话,还是有注入的风险。这里payload不能使用逗号,可以采用 (select user())a join的方法绕过。往下走的话,SQL注入漏洞更是多不胜数。也没有再看的必要了。0x03 /modules/Documents/models/ListView.php SQL注入直接看漏洞代码可以看到sortorder参数又是直接拼接。此处是order by后的注入,只能用基于时间的盲注。直接上SQLmap吧,但是sqlmap的payload会使用>,尖括号因为xss防御,已经被过滤所以需要使用绕过脚本。 –tamper greatest 绕过。poc:index.php?module=Documents&parent=&page=1&view=List&viewname=22&orderby=filename&sortorder=and/**/sleep(5)&app=MARKETING&search_params=[]&tag_params=[]&nolistcache=0&list_headers=[%22notes_title%22,%22filename%22,%22modifiedtime%22,%22assigned_user_id%22,%22filelocationtype%22,%22filestatus%22]&tag=0x04 写在最后由于时间原因,只看了前几个模块,还有好多地方没有看。漏洞都很简单,真正花费时间的是走通逻辑,验证漏洞,不停地跳转查看函数调用,和各种类对象的继承。这也是白盒审计的头疼之处,要忍着性子看开发跳来跳去,没准哪个地方就跳错了。有点难受,还没找到getshell的地方。此文已由作者授权腾讯云+社区发布

December 21, 2018 · 1 min · jiezi