{"id":15148522,"url":"https://github.com/mindsquare-custom-solutions/rap_samples","last_synced_at":"2025-10-24T03:32:00.283Z","repository":{"id":154485765,"uuid":"631485454","full_name":"mindsquare-Custom-Solutions/RAP_Samples","owner":"mindsquare-Custom-Solutions","description":"Codebeispiele für die mindsquare Restful Application Programming Model Schulung","archived":false,"fork":false,"pushed_at":"2024-08-13T08:22:53.000Z","size":154,"stargazers_count":2,"open_issues_count":3,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-10T02:23:42.160Z","etag":null,"topics":["abap","rap","restful-application-programming-model","sap"],"latest_commit_sha":null,"homepage":"https://mindsquare.de/schulungen/","language":"ABAP CDS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mindsquare-Custom-Solutions.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-23T06:57:02.000Z","updated_at":"2024-08-13T08:22:57.000Z","dependencies_parsed_at":"2023-11-12T12:33:30.241Z","dependency_job_id":"87e2f4c1-2952-4985-84b2-8d4a95bfd095","html_url":"https://github.com/mindsquare-Custom-Solutions/RAP_Samples","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mindsquare-Custom-Solutions%2FRAP_Samples","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mindsquare-Custom-Solutions%2FRAP_Samples/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mindsquare-Custom-Solutions%2FRAP_Samples/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mindsquare-Custom-Solutions%2FRAP_Samples/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mindsquare-Custom-Solutions","download_url":"https://codeload.github.com/mindsquare-Custom-Solutions/RAP_Samples/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219866820,"owners_count":16555824,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["abap","rap","restful-application-programming-model","sap"],"created_at":"2024-09-26T13:20:17.900Z","updated_at":"2025-10-24T03:31:59.927Z","avatar_url":"https://github.com/mindsquare-Custom-Solutions.png","language":"ABAP CDS","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://mindsquare.de/files/logo-mindsquare-176x781.png\" alt=\"mindsquare Logo\" title=\"mindsquare AG\" align=\"right\"\u003e\n\n# Begleitmaterialien zur RAP Schulung\n\nCodebeispiele für die [mindsquare Restful Application Programming Model Schulung](https://mindsquare.de/schulungen/)\n\n\n## Datenmodell\nTODO\n\n## Core Data Services im RAP\n\n### Root View Entities\n\n```cds\n@AccessControl.authorizationCheck: #NOT_REQUIRED\n@EndUserText.label: 'RAP Example: Root View'\ndefine root view entity ZREX_I_Carrier\n  as select from ZMIND2E_I_Carrier\n  composition [0..*] of ZREX_I_Connection as _Connection\n{\n  key AirlineId as CarrierId,\n      Name,\n      CurrencyCode,\n      \n      CreatedBy,\n      CreatedAt,\n      LastChangedBy,\n      LastChangedAt,\n      LocalLastChangedAt,\n\n      /* Associations */\n      _Connection\n}\n```\n\n### Kompositionen\n\n```cds\n@AccessControl.authorizationCheck: #NOT_REQUIRED\n@EndUserText.label: 'RAP Example: Child View'\ndefine view entity ZREX_I_Connection\n  as select from ZMIND2E_I_Connection\n  association to parent ZREX_I_Carrier as _Carrier on $projection.CarrierId = _Carrier.CarrierId\n  composition [0..*] of ZREX_I_Flight  as _Flight\n{\n  key AirlineId as CarrierId,\n  key ConnectionId,\n      DepartureAirport,\n      DestinationAirport,\n      DepartureTime,\n      ArrivalTime,\n      Distance,\n      DistanceUnit,\n      LocalLastChangedAt,\n\n      /* Associations */\n      _Carrier,\n      _Flight\n}\n```\n\n```cds\n@AccessControl.authorizationCheck: #NOT_REQUIRED\n@EndUserText.label: 'RAP Example: Grant Child View'\ndefine view entity ZREX_I_Flight\n  as select from ZMIND2E_I_Flight\n  association     to parent ZREX_I_Connection as _Connection on  $projection.CarrierId    = _Connection.CarrierId\n                                                             and $projection.ConnectionID = _Connection.ConnectionId\n  association [1] to ZREX_I_Carrier           as _Carrier    on  $projection.CarrierId = _Carrier.CarrierId\n{\n  key AirlineID as CarrierId,\n  key ConnectionID,\n  key FlightDate,\n      Price,\n      CurrencyCode,\n      PlaneType,\n      MaximumSeats,\n      OccupiedSeats,\n\n      LocalLastChangedAt,\n\n      /* Associations */\n      _Carrier,\n      _Connection\n}\n```\n\n### Annotationen\n\n```cds\ndefine view entity ZMIND2E_I_Flight\n  as select from zmind2_flight\n  association [0..1] to I_Currency as _Currency on $projection.CurrencyCode = _Currency.Currency\n{\n  key carrier_id            as AirlineID,\n  key connection_id         as ConnectionID,\n  key flight_date           as FlightDate,\n\n      @Semantics.amount.currencyCode: 'CurrencyCode'\n      price                 as Price,\n\n      @ObjectModel.foreignKey.association: '_Currency'\n      currency_code         as CurrencyCode,\n\n      // Weitere Felder\n\n      // Assoziation für Fremdschlüsselbeziehung\n      _Currency\n}\n```\n\n```cds\n@ObjectModel.representativeKey: 'Currency'\ndefine view I_Currency \n  as select from tcurc\n{\n    key waers as Currency\n}\n```\n\n#### Annotationen für administrative Felder\n\n```cds\ndefine view entity ZMIND2E_I_Carrier\n  as select from zmind2_carrier\n{\n  key carrier_id            as AirlineId,\n\n      @Semantics.user.createdBy: true\n      local_created_by      as CreatedBy,\n\n      @Semantics.systemDateTime.createdAt: true\n      local_created_at      as CreatedAt,\n\n      @Semantics.systemDateTime.lastChangedAt: true\n      last_changed_at       as LastChangedAt,\n\n      @Semantics.user.lastChangedBy: true\n      local_last_changed_by as LastChangedBy,\n\n      @Semantics.systemDateTime.localInstanceLastChangedAt: true\n      local_last_changed_at as LocalLastChangedAt\n}\n```\n\n### Abstract CDS Entity\n\n```cds\n@EndUserText.label: 'Parameter for Action Book Travel'\ndefine abstract entity ZMIND2RAP_A_BookTravel\n{\n    @EndUserText.label: 'book flights, too?'\n    @EndUserText.quickInfo: 'Should all flights of the selected travels be booked as well?'\n    @Consumption.defaultValue: 'X'\n    bookFlights : abap_boolean;   \n}\n```\n\n### Custom CDS Entity\n\n```cds\n@EndUserText.label: 'Custom entity for unmanaged travel query'\n@ObjectModel.query.implementedBy:'ABAP:/dmo/cl_travel_uq' \n\ndefine custom entity /DMO/I_TRAVEL_UQ \n{\n  key Travel_ID     : abap.numc( 8 );\n      Agency_ID     : abap.numc( 6 );\n      Customer_ID   : abap.numc( 6 );\n      Begin_Date    : abap.dats;\n      End_Date      : abap.dats;\n      Booking_Fee   : abap.dec( 17, 3 );\n      Total_Price   : abap.dec( 17, 3 );\n      Currency_Code : abap.cuky;\n      Status        : abap.char( 1 );\n      LastChangedAt : timestampl;\n}\n```\n\nImplementierung der Datensaelektion\n\n```abap\nCLASS /dmo/cl_travel_uq DEFINITION\n  PUBLIC\n  FINAL\n  CREATE PUBLIC .\n\n  PUBLIC SECTION.\n    INTERFACES if_rap_query_provider.\n  PROTECTED SECTION.\n  PRIVATE SECTION.\nENDCLASS.\n\n\nCLASS /dmo/cl_travel_uq IMPLEMENTATION.\n\n  METHOD if_rap_query_provider~select.\n    TRY.\n        CASE io_request-\u003eget_entity_id( ).\n\n          WHEN '/DMO/I_TRAVEL_UQ' .\n**query implementation for travel entity\n\n**filter\n            DATA(lv_sql_filter) = io_request-\u003eget_filter( )-\u003eget_as_sql_string( ).\n            TRY.\n                DATA(lt_filter) = io_request-\u003eget_filter( )-\u003eget_as_ranges( ).\n              CATCH cx_rap_query_filter_no_range.\n                \"handle exception\n            ENDTRY.\n**parameters\n            DATA(lt_parameters) = io_request-\u003eget_parameters( ).\n            DATA(lv_next_year) =  CONV /dmo/end_date( cl_abap_context_info=\u003eget_system_date( ) + 365 )  .\n            DATA(lv_par_filter) = | BEGIN_DATE \u003e= '{ cl_abap_dyn_prg=\u003eescape_quotes( VALUE #( lt_parameters[ parameter_name = 'P_START_DATE' ]-value\n                                                                                              DEFAULT cl_abap_context_info=\u003eget_system_date( ) ) ) }'| \u0026\u0026\n                                  | AND | \u0026\u0026\n                                  | END_DATE \u003c= '{ cl_abap_dyn_prg=\u003eescape_quotes( VALUE #( lt_parameters[ parameter_name = 'P_END_DATE' ]-value\n                                                                                            DEFAULT lv_next_year ) ) }'| .\n            IF lv_sql_filter IS INITIAL.\n              lv_sql_filter = lv_par_filter.\n            ELSE.\n              lv_sql_filter = |( { lv_sql_filter } AND { lv_par_filter } )| .\n            ENDIF.\n**search\n            DATA(lv_search_string) = io_request-\u003eget_search_expression( ).\n            DATA(lv_search_sql) = |DESCRIPTION LIKE '%{ cl_abap_dyn_prg=\u003eescape_quotes( lv_search_string ) }%'|.\n\n            IF lv_sql_filter IS INITIAL.\n              lv_sql_filter = lv_search_sql.\n            ELSE.\n              lv_sql_filter = |( { lv_sql_filter } AND { lv_search_sql } )|.\n            ENDIF.\n**request data\n            IF io_request-\u003eis_data_requested( ).\n**paging\n              DATA(lv_offset) = io_request-\u003eget_paging( )-\u003eget_offset( ).\n              DATA(lv_page_size) = io_request-\u003eget_paging( )-\u003eget_page_size( ).\n              DATA(lv_max_rows) = COND #( WHEN lv_page_size = if_rap_query_paging=\u003epage_size_unlimited\n                                          THEN 0 ELSE lv_page_size ).\n**sorting\n              DATA(sort_elements) = io_request-\u003eget_sort_elements( ).\n              DATA(lt_sort_criteria) = VALUE string_table( FOR sort_element IN sort_elements\n                                                         ( sort_element-element_name \u0026\u0026 COND #( WHEN sort_element-descending = abap_true THEN ` descending`\n                                                                                                                                         ELSE ` ascending` ) ) ).\n              DATA(lv_sort_string)  = COND #( WHEN lt_sort_criteria IS INITIAL THEN `primary key`\n                                                                               ELSE concat_lines_of( table = lt_sort_criteria sep = `, ` ) ).\n**requested elements\n              DATA(lt_req_elements) = io_request-\u003eget_requested_elements( ).\n**aggregate\n              DATA(lt_aggr_element) = io_request-\u003eget_aggregation( )-\u003eget_aggregated_elements( ).\n\n              IF lt_aggr_element IS NOT INITIAL.\n                LOOP AT lt_aggr_element ASSIGNING FIELD-SYMBOL(\u003cfs_aggr_element\u003e).\n                  DELETE lt_req_elements WHERE table_line = \u003cfs_aggr_element\u003e-result_element.\n                  DATA(lv_aggregation) = |{ \u003cfs_aggr_element\u003e-aggregation_method }( { \u003cfs_aggr_element\u003e-input_element } ) as { \u003cfs_aggr_element\u003e-result_element }|.\n                  APPEND lv_aggregation TO lt_req_elements.\n                ENDLOOP.\n              ENDIF.\n              DATA(lv_req_elements)  = concat_lines_of( table = lt_req_elements sep = `, ` ).\n****grouping\n              DATA(lt_grouped_element) = io_request-\u003eget_aggregation( )-\u003eget_grouped_elements( ).\n              DATA(lv_grouping) = concat_lines_of(  table = lt_grouped_element sep = `, ` ).\n\n**select data\n              DATA lt_travel_response TYPE STANDARD TABLE OF /dmo/i_travel_uq.\n              SELECT (lv_req_elements) FROM /dmo/travel\n                                       WHERE (lv_sql_filter)\n                                       GROUP BY (lv_grouping)\n                                       ORDER BY (lv_sort_string)\n                                       INTO CORRESPONDING FIELDS OF TABLE @lt_travel_response\n                                       OFFSET @lv_offset UP TO @lv_max_rows ROWS.\n**fill response\n              io_response-\u003eset_data( lt_travel_response ).\n            ENDIF.\n**request count\n            IF io_request-\u003eis_total_numb_of_rec_requested( ).\n**select count\n              SELECT COUNT( * ) FROM /dmo/travel\n                                WHERE (lv_sql_filter)\n                                INTO @DATA(lv_travel_count).\n**fill response\n              io_response-\u003eset_total_number_of_records( lv_travel_count ).\n            ENDIF.\n\n          WHEN `/DMO/I_BOOKING_UQ`.\n**query implementation for booking entity\n        ENDCASE.\n      CATCH cx_rap_query_provider.\n\n    ENDTRY.\n\n  ENDMETHOD.\nENDCLASS.\n```\n\n## Implementierungsarten\n\n### Managed Scenario\n\n```cds\nmanaged;\n\ndefine behavior for ZREX_I_Carrier alias Carrier\npersistent table zmind2_carrier\n...\n```\n\n#### Managed Sencario with additional save\n\nZusätzliche Speichersequenz für alle CDS Entitäten:\n```cds\nmanaged with additional save;\n\ndefine behavior for ZREX_I_Carrier alias Carrier\npersistent table zmind2_carrier\n...\n```\n\nZusätzliche Speichersequenz für eine CDS Entität:\n```cds\nmanaged;\n\ndefine behavior for ZREX_I_Carrier alias Carrier\npersistent table zmind2_carrier\nwith additional save\n...\n```\n\n#### Managed Scenario with unmanaged save\n\nUnmanaged Speichersequenz für alle CDS Entitäten:\n```cds\nmanaged with unmanaged save;\n\ndefine behavior for ZREX_I_Carrier alias Carrier\n...\n```\n\nUnmanmaged Speichersequenz für eine CDS Entität:\n```cds\nmanaged;\n\ndefine behavior for ZREX_I_Carrier alias Carrier\nwith unmanged save\n...\n```\n\n### Unmanaged Scenario\n\n```cds\nunmanaged;\n\ndefine behavior for ZREX_I_Carrier alias Carrier\n...\n```\n\n## Einführung RAP\n\n### Behavior Definition\n\n```cds\nmanaged implementation in class zbp_rex_i_carrier unique;\nstrict ( 2 );\nextensible;\n\ndefine behavior for ZREX_I_Carrier alias Carrier\npersistent table zmind2_carrier\nauthorization master ( instance )\netag master LocalLastChangedAt\nextensible\n{\n  create;\n  update;\n  delete;\n\n  association _Connection { create; }\n}\n```\n\n### Standardaktionen\n\n#### Create, Update \u0026 Delete\n\n```cds\ndefine behavior for ZREX_I_Carrier alias Carrier\n...\n{\n  create;\n  update;\n  delete;\n}\n```\n\n#### Read per Assoziation\n\n```cds\ndefine behavior for ZREX_I_Carrier alias Carrier\n...\n{\n  ...\n  // Lesen per Assoziation\n  association _Connection { }\n}\n\ndefine behavior for ZREX_I_Connection alias Connection\n...\n{\n  ...\n  // Lesen per Assoziation\n  association _Carrier { }\n}\n```\n\n#### Create per Assoziation\n\n```cds\ndefine behavior for ZREX_I_Carrier alias Carrier\n...\n{\n  ...\n  // Lesen und Anlegen per Assoziation\n  association _Connection { create; }\n}\n\ndefine behavior for ZREX_I_Connection alias Connection\n...\n{\n  ...\n  // Lesen per Assoziation\n  association _Carrier { }\n}\n```\n\n### Feldmapping\n\n```cds\ndefine behavior for ZREX_I_Carrier alias Carrier\n...\n{\n  ...\n   mapping for zmind2_carrier corresponding extensible\n  {\n    CarrierId = carrier_id;\n    Name = name;\n    CurrencyCode = currency_code;\n    CreatedBy = local_created_by;\n    CreatedAt = local_created_at;\n    LastChangedBy = local_last_changed_by;\n    LastChangedAt = last_changed_at;\n    LocalLastChangedAt = local_last_changed_at;\n  }\n  ...\n}\n```\n\n#### Nutzung in ABAP\n\nZuweisung CDS Entität als Quelle:\n```abap\ndata ls_po type bapimepoheader.\nls_po = corresponding #( po_entity mapping from entity ).\n```\n\nZuweisung CDS Entität als Ziel:\n```abap\ndata ls_po type bapimepoheader.\ndata ls_po_entity type zi_rap_purchaseorder_m.\nls_po_entity = corresponding #( ls_po mapping to entity ).\n```\n\n### Feature Control\n\n#### Felder: Statische Feature Control\n\n```cds\ndefine behavior for ZI_SalesOrder alias SalesOrder\n...\n{\n    field ( numbering : managed ) SalesOrderUuid;\n    // Schlüssel auf nur lesend setzen\n    field ( readonly ) SalesOrderUuid;\n    field ( mandatory : create ) SalesOrderType;\n\n    field( mandatory : create, readonly : update ) PersonId;\n    ...\n```\n\n#### Operationen: Statische Feature Control\n\n```cds\ndefine behavior for ZI_SalesOrder alias SalesOrder\n...\n{\n    internal create;\n    ...\n}\n```\n\n#### Dynamische Feature Control\n\nGlobal:\n```cds\ndefine behavior for ZI_SalesOrder alias SalesOrder\n...\n{\n    ...\n    create ( features : global );\n}\n```\n\n```abap\nCLASS lhc_handler DEFINITION INHERITING FROM cl_abap_behavior_handler.\n    PRIVATE SECTION.\n    METHODS get_global_features FOR GLOBAL FEATURES\n        IMPORTING REQUEST requested_features\n        FOR entity RESULT result.\nENDCLASS.\n\nCLASS lhc_handler IMPLEMENTATION.\n    METHOD get_global_features.\n        result = VALUE #(\n            \" Feature Control für Aktion\n            %features-%action-action_name = COND #( WHEN condition\n                                                        THEN if_abap_behv=\u003efc-o-disabled\n                                                    ELSE if_abap_behv=\u003efc-o-enabled )\n            %features-%update = COND #( WHEN condition\n                                            THEN if_abap_behv=\u003efc-o-disabled\n                                        ELSE if_abap_behv=\u003efc-o-enabled )\n\n            \" Feature Control für eine create-Operation per Assoziation\n            %assoc-_Assoc = COND #( WHEN condition\n                                        THEN if_abap_behv=\u003efc-o-disabled\n                                    ELSE if_abap_behv=\u003efc-o-enabled )\n        ).\n    ENDMETHOD.\nENDCLASS.\n```\n\nInstanzbasiert:\n```cds\ndefine behavior for ZI_SalesOrder alias SalesOrder\n...\n{\n    ...\n    create ( features : instance );\n}\n```\n\n```abap\nCLASS lhc_handler DEFINITION INHERITING FROM cl_abap_behavior_handler.\n    PRIVATE SECTION.\n    METHODS get_features FOR INSTANCE FEATURES\n        IMPORTING keys\n        FOR entity RESULT result.\nENDCLASS.\n\nCLASS lhc_handler IMPLEMENTATION.\n    METHOD get_features.\n        READ ENTITIES OF /dmo/i_travel_m IN LOCAL MODE\n            ENTITY travel\n                FIELDS ( travel_id overall_status )\n                WITH CORRESPONDING #( keys )\n            RESULT DATA(lt_travel_result).\n\n        result = VALUE #( FOR ls_travel IN lt_travel_result\n                          ( %key = ls_travel-%key\n                            \n                            %field-travel_id = if_abap_behv=\u003efc-f-read_only\n                            \n                            %features-%action-rejectTravel = COND #( WHEN ls_travel-overall_status = 'X'\n                                                                        THEN if_abap_behv=\u003efc-o-disabled\n                                                                     ELSE if_abap_behv=\u003efc-o-enabled )\n                            %features-%action-acceptTravel = COND #( WHEN ls_travel-overall_status = 'A'\n                                                                        THEN if_abap_behv=\u003efc-o-disabled\n                                                                     ELSE if_abap_behv=\u003efc-o-enabled )\n                            \n                            %assoc-_Booking = COND #( WHEN ls_travel-overall_status = 'X'\n                                                        THEN if_abap_behv=\u003efc-o-disabled\n                                                      ELSE if_abap_behv=\u003efc-o-enabled )\n        ) ).\n    ENDMETHOD.\nENDCLASS.\n```\n\n### Projection View Entity\n\n```cds\n@EndUserText.label: 'RAP Example: Projection Root View'\n@AccessControl.authorizationCheck: #NOT_REQUIRED\n@Metadata.allowExtensions: true\n\ndefine root view entity ZREX_C_Carrier\n  provider contract transactional_query\n  as projection on ZREX_I_Carrier\n{\n  key CarrierId,\n      Name,\n      \n      @ObjectModel.text.element: ['CurrencyName']\n      CurrencyCode,\n      @Semantics.text: true\n      _Currency._Text.CurrencyName : localized,\n      \n      CreatedBy,\n      CreatedAt,\n      LastChangedBy,\n      LastChangedAt,\n      LocalLastChangedAt,\n\n      /* Associations */\n      _Connection : redirected to composition child ZREX_C_Connection,\n      _Currency\n}\n```\n\n```cds\n@EndUserText.label: 'RAP Example: Projection Child View'\n@AccessControl.authorizationCheck: #NOT_REQUIRED\n@Metadata.allowExtensions: true\ndefine view entity ZREX_C_Connection\n  as projection on ZREX_I_Connection\n{\n  key CarrierId,\n  key ConnectionId,\n      DepartureAirport,\n      DestinationAirport,\n      DepartureTime,\n      ArrivalTime,\n      Distance,\n      DistanceUnit,\n      LocalLastChangedAt,\n\n      /* Associations */\n      _Carrier : redirected to parent ZREX_C_Carrier,\n      _Flight  : redirected to composition child ZREX_C_Flight,\n      _DepartureAirport,\n      _DestinationAirport\n}\n```\n\n```cds\n@EndUserText.label: 'RAP Example: Projection Grant Child View'\n@AccessControl.authorizationCheck: #NOT_REQUIRED\n@Metadata.allowExtensions: true\ndefine view entity ZREX_C_Flight\n  as projection on ZREX_I_Flight\n{\n  key CarrierId,\n  key ConnectionID,\n  key FlightDate,\n      Price,\n      CurrencyCode,\n      PlaneType,\n      MaximumSeats,\n      OccupiedSeats,\n      LocalLastChangedAt,\n\n      /* Associations */\n      _Carrier    : redirected to ZREX_C_Carrier,\n      _Connection : redirected to parent ZREX_C_Connection,\n      _Currency\n}\n```\n\n### Behavior Definition Projektion\n\n```cds\nprojection;\nstrict ( 2 );\n\ndefine behavior for ZREX_C_Carrier alias Carrier\n{\n  use create;\n  use update;\n  use delete;\n\n  use association _Connection { create; }\n}\n```\n\n### Service Definition\n\n\u003eLeading Entity Annotation ab S/4HANA Platform 2023/ BTP abap Environment 2308\n\n```cds\n@EndUserText.label: 'Released Objects: CDS'\n@ObjectModel.leadingEntity.name: 'ZC_RO_CDSViewTP'\ndefine service ZUI_RO_CDSVIEW {\n  expose ZC_RO_CDSViewTP                as CDSViewTP;\n  expose ZC_RO_CDSViewBusinessContextTP as BusinessContextTP;\n  expose ZC_RO_CDSViewCapabilityTP      as CDSViewCapabilityTP;\n  expose ZC_RO_CDSViewFieldTP           as FieldTP;\n  expose ZC_RO_CDSViewSuccessorTP       as SuccessorTP;\n  expose ZI_RO_ReleaseState             as ReleaseState;\n  expose ZI_RO_SupportedCapability      as Capability;\n  expose ZI_RO_SupportedCapabilityText  as CapabilityText;\n}\n```\n\n### Metadatenerweiterung\n\nZu erweiternde CDS View Entity:\n```cds\n@Metadata.allowExtensions: true\n\ndefine view entity ZREX_C_Carrier\n  as select from ZREX_I_Carrier\n{\n  key CarrierId\n  ...\n}\n```\n\nCDS View Entity Metadatenerweiterung\n```cds\n@Metadata.layer: #PARTNER\n\n@Search.searchable: true\n\nannotate entity ZREX_C_Carrier with\n{\n  \n  @UI.lineItem: [{ position: 10 }]\n  CarrierId;\n\n  ...\n}\n```\n\n## EML\n\n### Interner Zugriff\n\n```abap\nREAD ENTITIES OF /dmo/i_travel_m IN LOCAL MODE\n    ENTITY travel\n        FIELDS ( travel_id\n                 agency_id\n                 customer_id\n                 booking_fee\n                 total_price\n                 currency_code )\n        WITH CORRESPONDING #( keys )\n    RESULT DATA(lt_read_result)\n    FAILED failed\n    REPORTED reported.\n```\n\n### EML Read\n\n```abap\nREAD ENTITIES OF /dmo/i_travel_m IN LOCAL MODE\n    ENTITY travel\n        FIELDS ( travel_id\n                 agency_id\n                 customer_id\n                 booking_fee\n                 total_price\n                 currency_code )\n        WITH CORRESPONDING #( keys )\n    RESULT DATA(lt_read_result)\n    FAILED failed\n    REPORTED reported.\n```\n\n### EML Read per Assoziation\n\n```abap\nREAD ENTITIES OF /DMO/I_Travel_D IN LOCAL MODE\n    ENTITY Travel BY \\_Booking\n        FIELDS ( FlightPrice CurrencyCode )\n        WITH VALUE #( ( %tky = \u003cfs_travel\u003e-%tky ) )\n    RESULT DATA(lt_booking).\n```\n\n### EML Create\n\n```abap\nMODIFY ENTITIES OF /dmo/i_travel_m IN LOCAL MODE\n    ENTITY travel\n        CREATE FIELDS ( travel_id\n                        agency_id\n                        customer_id\n                        begin_date\n                        end_date\n                        booking_fee\n                        total_price\n                        currency_code\n                        description\n                        overall_status )\n        WITH lt_create\n    MAPPED mapped\n    FAILED failed\n    REPORTED reported.\n```\n\n### EML Deep Create\n\n```abap\nMODIFY ENTITIES OF /DMO/I_Travel_D\n    ENTITY Travel\n        CREATE \n            FIELDS ( CustomerID \n                        AgencyID \n                        BeginDate \n                        EndDate \n                        Description ) \n            WITH create \" Variable vom TYPE TABLE FOR CREATE /DMO/I_TRAVEL_D\n        CREATE BY \\_Booking\n            FIELDS ( CustomerID \n                     AirlineID \n                     ConnectionID\n                     FlightDate ) \n            WITH VALUE #( (\n                %cid_ref = 'create_travel'\n                %target = VALUE #( \n                (\n                    %cid = 'create_booking_1'\n                    CustomerID = '1'\n                    AirlineID = flight-AirlineID\n                    ConnectionID = flight-ConnectionID\n                    FlightDate = flight-FlightDate )\n                ( \n                    %cid = 'create_booking_2'\n                    CustomerID = '1'\n                    AirlineID = flight-AirlineID\n                    ConnectionID = flight-ConnectionID\n                    FlightDate = flight-FlightDate) ) ) )\n    MAPPED DATA(mapped)\n    REPORTED DATA(reported)\n    FAILED DATA(failed).\n```\n\n### EML Update\n\n```abap\nMODIFY ENTITIES OF /DMO/I_Travel_D IN LOCAL MODE\n    ENTITY Travel\n        UPDATE \n            FIELDS ( OverallStatus )\n            WITH VALUE #( FOR key IN keys (\n                          %tky = key-%tky\n                          OverallStatus = travel_status-accepted ) )\n    REPORTED DATA(reported)\n    FAILED DATA(failed).\n```\n\n### EML Delete\n\n```abap\nMODIFY ENTITIES OF /DMO/I_Travel_D IN LOCAL MODE\n    ENTITY Travel\n        DELETE FROM VALUE #( ( TravelUUID = lv_travel_id ) )\n    REPORTED DATA(reported)\n    FAILED DATA(failed).\n```\n\n### EML Aktionen ausführen\n\n```abap\nDATA travel_action TYPE TABLE FOR ACTION IMPORT ZMIND2RAP_I_Travel~bookTravel.\n    travel_action = VALUE #( ( %is_draft = if_abap_behv=\u003emk-off\n                               TravelId  = '00000009'\n                               %param    = VALUE #( bookFlights = abap_true ) ) ).\n\n    MODIFY ENTITIES OF ZMIND2RAP_I_Travel\n           ENTITY Travel\n               EXECUTE bookTravel\n               FROM CORRESPONDING #( travel_action )\n           RESULT DATA(action_result)\n           FAILED DATA(action_failed)\n           REPORTED DATA(action_reported).\n```\n\n### EML Verschiedene Operationen in einer Modifiy Anweisung\n\n### EML Commit \u0026 Rollback\n\n```abap\nCOMMIT ENTITIES.\n\nROLLBACK ENTITIES.\n```\n\n## Behavior Pool\n\n### BP für Verhaltensdefinition\n\n```cds\nmanaged implementation in class zbp_rex_i_carrier unique;\nstrict ( 2 );\n\ndefine behavior for ZREX_I_Carrier alias Carrier\n...\n```\n\n### BP für CDS Entität\n\n```cds\nmanaged;\nstrict ( 2 );\n\ndefine behavior for ZREX_I_Carrier alias Carrier\nimplementation in class zbp_rex_i_carrier unique\n...\n\ndefine behavior for ZREX_I_Connection alias Connection\nimplementation in class zbp_rex_i_connection unique\n...\n```\n\n### BP für Implementierungsgruppen\n\nTODO\n\n### Phasen des Programmflusses\n\n#### Methodendefinition\n\n```abap\nCLASS lhc_travel DEFINITION INHERITING FROM cl_abap_behavior_handler.\n    PRIVATE SECTION.\n        TYPES:\n            tt_travel_update TYPE TABLE\n                FOR UPDATE /dmo/i_travel_u.\n        \n        METHODS:\n            create_travel FOR MODIFY\n                IMPORTING it_travel_create FOR CREATE travel,\n            update_travel FOR MODIFY\n                IMPORTING it_travel_update FOR UPDATE travel,\n            delete_travel FOR MODIFY\n                IMPORTING it_travel_delete FOR DELETE travel,\n            read_travel FOR READ\n                IMPORTING it_travel FOR READ travel\n                RESULT et_travel,\n            create_booking_ba FOR MODIFY\n                IMPORTING it_booking_create_ba\n                FOR CREATE travel\\_booking,\n            read_booking_ba FOR READ\n                IMPORTING it_travel FOR READ travel\\_Booking\n                FULL iv_full_requested\n                RESULT et_booking\n                LINK et_link_table,\n            lock FOR LOCK\n                IMPORTING it_travel_lock FOR LOCK travel,\n            set_travel_status FOR MODIFY\n                IMPORTING it_travel_set_status_booked\n                FOR ACTION travel~set_status_booked\n                RESULT et_travel_set_status_booked,\n            get_features FOR FEATURES\n                IMPORTING keys REQUEST requested_features\n                FOR travel\n                RESULT result.\nENDCLASS.\n```\n\n### Messages\n\n```abap\nAPPEND VALUE #( %tky = \u003ccarrier\u003e-%tky\n                %msg = new_message(\n                    id = 'ZMC_REX_CARRIER'\n                    number = '001'\n                    severity = if_abap_behv_message=\u003eseverity-error )\n                    %element-CarrierId = if_abap_behv=\u003emk-on \n                ) TO reported-carrier.\n```\n\n## Nummernvergabe\n\n### Frühe, interne Nummernvergabe\n\n```cds\ndefine behavior for ZI_SalesOrder alias SalesOrder\nearly numbering\n...\n{\n    ...\n```\n\n```cds\ndefine behavior for ZI_SalesOrder alias SalesOrder\n...\n{\n    field ( numbering : managed ) SalesOrderUuid;\n    ...\n}\n```\n\n#### Nummernvergabe mit Nummernkreis\n\n```abap\nCLASS lhc_travel DEFINITION INHERITING FROM cl_abap_behavior_handler\n\n  PRIVATE SECTION.\n    METHODS earlynumbering_create FOR NUMBERING\n      IMPORTING entities FOR CREATE travel.\n\nENDCLASS.\n\nCLASS lhc_travel IMPLEMENTATION.\n\n  METHOD earlynumbering_create.\n\n    DATA:\n      entity        TYPE STRUCTURE FOR CREATE /DMO/I_Travel_M,\n      travel_id_max TYPE /dmo/travel_id.\n\n    \" Ensure Travel ID is not set yet (idempotent)- must be checked when BO is draft-enabled\n    LOOP AT entities INTO entity WHERE travel_id IS NOT INITIAL.\n      APPEND CORRESPONDING #( entity ) TO mapped-travel.\n    ENDLOOP.\n\n    DATA(entities_wo_travelid) = entities.\n    DELETE entities_wo_travelid WHERE travel_id IS NOT INITIAL.\n\n    \" Get Numbers\n    TRY.\n        cl_numberrange_runtime=\u003enumber_get(\n          EXPORTING\n            nr_range_nr       = '01'\n            object            = '/DMO/TRV_M'\n            quantity          = CONV #( lines( entities_wo_travelid ) )\n          IMPORTING\n            number            = DATA(number_range_key)\n            returncode        = DATA(number_range_return_code)\n            returned_quantity = DATA(number_range_returned_quantity)\n        ).\n      CATCH cx_number_ranges INTO DATA(lx_number_ranges).\n        LOOP AT entities_wo_travelid INTO entity.\n          APPEND VALUE #(  %cid = entity-%cid\n                           %key = entity-%key\n                           %msg = lx_number_ranges\n                        ) TO reported-travel.\n          APPEND VALUE #(  %cid = entity-%cid\n                           %key = entity-%key\n                        ) TO failed-travel.\n        ENDLOOP.\n        EXIT.\n    ENDTRY.\n\n    CASE number_range_return_code.\n      WHEN '1'.\n        \" 1 - the returned number is in a critical range (specified under “percentage warning” in the object definition)\n        LOOP AT entities_wo_travelid INTO entity.\n          APPEND VALUE #( %cid = entity-%cid\n                          %key = entity-%key\n                          %msg = NEW /dmo/cm_flight_messages(\n                                      textid = /dmo/cm_flight_messages=\u003enumber_range_depleted\n                                      severity = if_abap_behv_message=\u003eseverity-warning )\n                        ) TO reported-travel.\n        ENDLOOP.\n\n      WHEN '2' OR '3'.\n        \" 2 - the last number of the interval was returned\n        \" 3 - if fewer numbers are available than requested,  the return code is 3\n        LOOP AT entities_wo_travelid INTO entity.\n          APPEND VALUE #( %cid = entity-%cid\n                          %key = entity-%key\n                          %msg = NEW /dmo/cm_flight_messages(\n                                      textid = /dmo/cm_flight_messages=\u003enot_sufficient_numbers\n                                      severity = if_abap_behv_message=\u003eseverity-warning )\n                        ) TO reported-travel.\n          APPEND VALUE #( %cid        = entity-%cid\n                          %key        = entity-%key\n                          %fail-cause = if_abap_behv=\u003ecause-conflict\n                        ) TO failed-travel.\n        ENDLOOP.\n        EXIT.\n    ENDCASE.\n\n    \" At this point ALL entities get a number!\n    ASSERT number_range_returned_quantity = lines( entities_wo_travelid ).\n\n    travel_id_max = number_range_key - number_range_returned_quantity.\n\n    \" Set Travel ID\n    LOOP AT entities_wo_travelid INTO entity.\n      travel_id_max += 1.\n      entity-travel_id = travel_id_max .\n\n      APPEND VALUE #( %cid  = entity-%cid\n                      %key  = entity-%key\n                    ) TO mapped-travel.\n    ENDLOOP.\n\n  ENDMETHOD.\n\nENDCLASS.\n```\n\n#### Nummernvergabe durch Hochzählen\n\n```abap\nCLASS lhc_travel DEFINITION INHERITING FROM cl_abap_behavior_handler\n\n  PRIVATE SECTION.\n    METHODS earlynumbering_cba_booking FOR NUMBERING\n      IMPORTING entities FOR CREATE travel\\_booking.\n\nENDCLASS.\n\nCLASS lhc_travel IMPLEMENTATION.\n\n  METHOD earlynumbering_cba_booking.\n    DATA: max_booking_id TYPE /dmo/booking_id.\n\n    READ ENTITIES OF /DMO/I_Travel_M IN LOCAL MODE\n      ENTITY travel BY \\_booking\n        FROM CORRESPONDING #( entities )\n        LINK DATA(bookings).\n\n    \" Loop over all unique TravelIDs\n    LOOP AT entities ASSIGNING FIELD-SYMBOL(\u003ctravel_group\u003e) GROUP BY \u003ctravel_group\u003e-travel_id.\n\n      \" Get highest booking_id from bookings belonging to travel\n      max_booking_id = REDUCE #( INIT max = CONV /dmo/booking_id( '0' )\n                                 FOR  booking IN bookings USING KEY entity WHERE ( source-travel_id  = \u003ctravel_group\u003e-travel_id )\n                                 NEXT max = COND /dmo/booking_id( WHEN booking-target-booking_id \u003e max\n                                                                    THEN booking-target-booking_id\n                                                                    ELSE max )\n                               ).\n      \" Get highest assigned booking_id from incoming entities\n      max_booking_id = REDUCE #( INIT max = max_booking_id\n                                 FOR  entity IN entities USING KEY entity WHERE ( travel_id  = \u003ctravel_group\u003e-travel_id )\n                                 FOR  target IN entity-%target\n                                 NEXT max = COND /dmo/booking_id( WHEN   target-booking_id \u003e max\n                                                                    THEN target-booking_id\n                                                                    ELSE max )\n                               ).\n\n      \" Loop over all entries in entities with the same TravelID\n      LOOP AT entities ASSIGNING FIELD-SYMBOL(\u003ctravel\u003e) USING KEY entity WHERE travel_id = \u003ctravel_group\u003e-travel_id.\n\n        \" Assign new booking-ids if not already assigned\n        LOOP AT \u003ctravel\u003e-%target ASSIGNING FIELD-SYMBOL(\u003cbooking_wo_numbers\u003e).\n          APPEND CORRESPONDING #( \u003cbooking_wo_numbers\u003e ) TO mapped-booking ASSIGNING FIELD-SYMBOL(\u003cmapped_booking\u003e).\n          IF \u003cbooking_wo_numbers\u003e-booking_id IS INITIAL.\n            max_booking_id += 10 .\n            \u003cmapped_booking\u003e-booking_id = max_booking_id .\n          ENDIF.\n        ENDLOOP.\n\n      ENDLOOP.\n\n    ENDLOOP.\n  ENDMETHOD.\n\nENDCLASS.\n```\n\n### Späte Nummernvergabe\n\n```cds\ndefine behavior for ZI_SalesOrder alias SalesOrder\nlate numbering\n...\n{\n    // Schlüsselfeld auf »nur lesend« setzen\n    field ( readonly ) SalesOrderId;\n    ...\n}\n```\n\n## Ermittlungen\n\n### Ermittlungen definieren\n\n```cds\ndefine behavior for ZI_SalesOrderItem alias Item\n...\n{\n    ...\n    determination calcTotalAmount on modify { delete; field ItemAmount }\n}\n```\n\n### Ermittlungen implementieren\n\n```cds\ndefine behavior for ZMIND2RAP_I_Booking alias Booking\n...\n{\n  ...\n  determination setBookingDate on modify { create; }\n}\n```\n\n```abap\nMETHOD setBookingDate.\n    READ ENTITIES OF ZMIND2RAP_I_Travel IN LOCAL MODE\n        ENTITY Booking\n            FIELDS ( BookingDate )\n            WITH CORRESPONDING #( keys )\n        RESULT DATA(bookings).\n\n    DELETE bookings WHERE BookingDate IS NOT INITIAL.\n    CHECK bookings IS NOT INITIAL.\n\n    MODIFY ENTITIES OF ZMIND2RAP_I_Travel IN LOCAL MODE\n        ENTITY Booking\n            UPDATE FIELDS ( BookingDate )\n            WITH VALUE #( FOR booking IN bookings\n                          ( %tky = booking-%tky\n                            BookingDate = cl_abap_context_info=\u003eget_system_date( ) ) ).\nENDMETHOD.\n```\n\n## Validierung\n\n### Validierungen definieren\n\nOperationen als Auslösebedingung:\n```cds\ndefine behavior for ZI_SalesOrder alias SalesOrder\n...\n{\n    ...\n    validation validateOnChange on save { create; update; }\n}\n```\n\nFelder als Ausläsebedingung:\n```cds\ndefine behavior for ZI_SalesOrderItem alias Item\n...\n{\n    ...\n    validation validateMaterial on save { field MaterialId; }\n}\n```\n\nKombination aus Operation und Feld:\n```cds\ndefine behavior for ZI_SalesOrderItem alias Item\n...\n{\n    ...\n    field ( mandatory ) MaterialId;\n    validation validateMaterial on save { create; field MaterialId; }\n}\n```\n\n### Validierungen implementieren\n\n```abap\nMETHOD validate_agency.\n    \" Read relevant travel instance data\n    READ ENTITIES OF /DMO/I_Travel_M IN LOCAL MODE\n        ENTITY travel\n            FIELDS ( agency_id )\n            WITH CORRESPONDING #(  keys )\n        RESULT DATA(travels).\n\n    DATA agencies TYPE SORTED TABLE OF /dmo/agency WITH UNIQUE KEY agency_id.\n\n    \" Optimization of DB select: extract distinct non-initial agency IDs\n    agencies = CORRESPONDING #(  travels DISCARDING DUPLICATES MAPPING agency_id = agency_id EXCEPT * ).\n    DELETE agencies WHERE agency_id IS INITIAL.\n    IF  agencies IS NOT INITIAL.\n\n      \" check if agency ID exist\n      SELECT FROM /dmo/agency FIELDS agency_id\n        FOR ALL ENTRIES IN @agencies\n        WHERE agency_id = @agencies-agency_id\n        INTO TABLE @DATA(agencies_db).\n    ENDIF.\n\n    \" Raise msg for non existing and initial agency id\n    LOOP AT travels INTO DATA(travel).\n      IF travel-agency_id IS INITIAL\n         OR NOT line_exists( agencies_db[ agency_id = travel-agency_id ] ).\n\n        APPEND VALUE #(  %tky = travel-%tky ) TO failed-travel.\n        APPEND VALUE #(  %tky = travel-%tky\n                         %msg      = NEW /dmo/cm_flight_messages(\n                                          textid    = /dmo/cm_flight_messages=\u003eagency_unkown\n                                          agency_id = travel-agency_id\n                                          severity  = if_abap_behv_message=\u003eseverity-error )\n                         %element-agency_id = if_abap_behv=\u003emk-on\n                      ) TO reported-travel.\n      ENDIF.\n    ENDLOOP.\n\n  ENDMETHOD.\n```\n\n### Vorprüfungen\n\n```cds\ndefine behavior for ZI_SalesOrder alias SalesOrder\n...\n{\n    create ( precheck );\n    ...\n}\n```\n\n```abap\nCLASS lhc_salesorder DEFINITION INHERITING FROM cl_abap_behavior_handler.\n    ...\n    METHODS testCheck for PRECHECK\n        IMPORTING keys FOR ACTION SalesOrder~test.\nENDCLASS.\n\nCLASS lhc_salesorder IMPLEMENTATION.\n    ...\n    METHOD testcheck.\n        READ ENTITIES OF ...\n        IF ...\n        ...\n    ENDMETHOD.\nENDCLASS.\n```\n\n## Aktionen\n\n```cds\ndefine behavior for ZI_SalesOrder alias SalesOrder\n...\n{\n    ...\n    action cancel;\n}\n```\n\n### statische Aktionen\n\n```cds\ndefine behavior for ZI_Address alias Address\n...\n{\n    ...\n    static action markDuplicates;\n}\n```\n\n### Factory Aktionen\n\n```cds\ndefine behavior for ZI_SalesOrder alias SalesOrder\n...\n{\n    ...\n    factory action copy [1];\n}\n```\n\n```cds\ndefine behavior for ZI_SalesOrder alias SalesOrder\n...\n{\n    ...\n    factory action deepCopy parameter zrap_s_so_copy_ops [1];\n}\n```\n\n### Eingabeparameter\n\n```cds\ndefine behavior for ZI_SalesOrder alias SalesOrder\n...\n{\n    ...\n    action cancel parameter ZRAP_A_CancellationOpts;\n}\n```\n\n### Rückgabeparameter\n\n```cds\ndefine behavior for ZI_Address alias Address\n...\n{\n    ...\n    action setAsDefault result [1] $self;\n}\n```\n\n### Aktionen implementieren\n\n```cds\ndefine behavior for ZMIND2RAP_I_Travel alias Travel\n...\n{\n    ...\n    action ( features : instance ) cancelTravel result [1] $self;\n}\n```\n\n```abap\nMETHOD cancelTravel.\n    MODIFY ENTITIES OF ZMIND2RAP_I_Travel IN LOCAL MODE\n           ENTITY Travel\n              UPDATE FIELDS ( Status )\n              WITH VALUE #( FOR key IN keys\n                            ( %tky = key-%tky\n                              status = 'X' ) ).\n\n    READ ENTITIES OF ZMIND2RAP_I_Travel IN LOCAL MODE\n      ENTITY travel\n         ALL FIELDS WITH\n         CORRESPONDING #( keys )\n       RESULT DATA(travels).\n\n    result = VALUE #( FOR travel IN travels\n                      ( %tky = travel-%tky\n                        %param = travel ) ).\nENDMETHOD.\n```\n\n### Aktionen: Dynamische Feature Control\n\n```cds\ndefine behavior for ZMIND2RAP_I_Travel alias Travel\n...\n{\n    ...\n    action ( features : instance ) bookTravel parameter ZMIND2RAP_A_BookTravel result [1] $self;\n    action ( features : instance ) cancelTravel result [1] $self;\n}\n```\n\n```abap\nMETHOD get_features.\n        READ ENTITIES OF ZMIND2RAP_I_Travel IN LOCAL MODE\n            ENTITY travel\n                FIELDS ( travel_id overall_status )\n                WITH CORRESPONDING #( keys )\n            RESULT DATA(lt_travel_result).\n\n        result = VALUE #( FOR ls_travel IN lt_travel_result\n                          ( %tky = ls_travel-%tky\n                            \n                            %field-travel_id = if_abap_behv=\u003efc-f-read_only\n                            \n                            %features-%action-rejectTravel = COND #( WHEN ls_travel-overall_status = 'X'\n                                                                        THEN if_abap_behv=\u003efc-o-disabled\n                                                                     ELSE if_abap_behv=\u003efc-o-enabled )\n                            %features-%action-acceptTravel = COND #( WHEN ls_travel-overall_status = 'A'\n                                                                        THEN if_abap_behv=\u003efc-o-disabled\n                                                                     ELSE if_abap_behv=\u003efc-o-enabled )\n                            \n                            %assoc-_Booking = COND #( WHEN ls_travel-overall_status = 'X'\n                                                        THEN if_abap_behv=\u003efc-o-disabled\n                                                      ELSE if_abap_behv=\u003efc-o-enabled )\n        ) ).\n```\n\n### Aktionen: Fiori Elements\n\n```cds\ndefine root view entity ZMIND2RAP_C_Travel\n  provider contract transactional_query\n  as projection on ZMIND2RAP_I_Travel\n{\n    @UI.lineItem: [\n        { type: #FOR_ACTION, dataAction: 'bookTravel', label: 'Book Travel', position: 10 },\n        { type: #FOR_ACTION, dataAction: 'cancelTravel', label: 'Cancel Travel', position: 20 }\n    ]\n    @UI.identification: [\n        { type: #FOR_ACTION, dataAction: 'bookTravel', label: 'Book Travel', position: 10 },\n        { type: #FOR_ACTION, dataAction: 'cancelTravel', label: 'Cancel Travel', position: 20 }\n    ]\n\n  key TravelId,\n  ...\n```\n\n## Funktionen\n\n```cds\ndefine behavior for DEMO_CDS_FUNCTION_1 alias PurchaseDocument\n{\n  ...\n\n  // instance function\n  function getDetails result [0..*] $self;\n\n  // static function\n  static function calculateTotal result [1] demo_sales_total_price;\n\n  //function with input parameter\n  function calculateDiscount parameter DEMO_CDS_DEDUCT_DISCOUNT\n                             result [1] $self;\n  ...\n}\n```\n\n```abap\nCLASS lhc_PurchaseDocument\nDEFINITION INHERITING FROM cl_abap_behavior_handler.\n  PRIVATE SECTION.\n    METHODS getDetails FOR READ\n      IMPORTING keys FOR FUNCTION PurchaseDocument~getDetails\n        RESULT result.\n    METHODS calculateTotal FOR READ\n      IMPORTING keys FOR FUNCTION PurchaseDocument~calculateTotal\n        RESULT result.\n    METHODS calculateDiscount FOR READ\n      IMPORTING keys FOR FUNCTION PurchaseDocument~calculateDiscount\n        RESULT result.\n    METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION\n      IMPORTING keys REQUEST requested_authorizations FOR PurchaseDocument RESULT result.\nENDCLASS.\n\nCLASS lhc_PurchaseDocument IMPLEMENTATION.\n  METHOD getDetails.\n    DATA(lt_keys) = keys.\n    CHECK lt_keys IS NOT INITIAL.\n\n    READ ENTITIES OF demo_cds_function_1 IN LOCAL MODE\n      ENTITY PurchaseDocument\n        FIELDS ( PurchaseDocument Price Status )\n        WITH CORRESPONDING #( lt_keys )\n      RESULT DATA(lt_item)\n      FAILED DATA(read_failed).\n\n    failed = CORRESPONDING #( DEEP read_failed ).\n\n    LOOP AT lt_item ASSIGNING FIELD-SYMBOL(\u003cfs_item\u003e).\n     APPEND VALUE #( %tky   = \u003cfs_item\u003e-%tky\n                     %param = CORRESPONDING #( \u003cfs_item\u003e ) ) TO result.\n    ENDLOOP.\n  ENDMETHOD.\n\n  METHOD calculateTotal.\n    SELECT *\n    FROM demo_purch_doc\n    WHERE status = 'O'\n    INTO TABLE @DATA(lt_db_new_purch).\n\n    READ ENTITIES OF demo_cds_function_1 IN LOCAL MODE\n      ENTITY PurchaseDocument\n        FIELDS ( Price )\n        WITH CORRESPONDING #( lt_db_new_purch )\n      RESULT DATA(read_result)\n      FAILED failed\n      REPORTED reported.\n\n    DATA lv_sum TYPE demo_cds_function_1-Price.\n    CLEAR lv_sum.\n\n    LOOP AT read_result ASSIGNING FIELD-SYMBOL(\u003cfs_new_purch\u003e).\n      lv_sum += \u003cfs_new_purch\u003e-Price.\n    ENDLOOP.\n\n    result = VALUE #( ( %cid    = keys[ 1 ]-%cid\n                        %param  = lv_sum )  ).\n  ENDMETHOD.\n\n  METHOD calculateDiscount.\n    DATA lt_reduced_purch TYPE TABLE FOR FUNCTION RESULT\n      demo_cds_function_1\\\\PurchaseDocument~calculateDiscount.\n    DATA lt_update_purch TYPE TABLE FOR UPDATE\n      demo_cds_function_1\\\\PurchaseDocument.\n    DATA(lt_keys) = keys.\n\n    LOOP AT lt_keys\n    ASSIGNING FIELD-SYMBOL(\u003cfs_key\u003e)\n    WHERE %param-discount_percent IS INITIAL\n                                  OR %param-discount_percent \u003e 100\n                                  OR %param-discount_percent \u003c= 0.\n\n      APPEND VALUE #( %tky = \u003cfs_key\u003e-%tky ) TO failed-purchasedocument.\n      APPEND VALUE #( %tky = \u003cfs_key\u003e-%tky\n                      %msg = new_message_with_text(\n                      severity = if_abap_behv_message=\u003eseverity-error\n                      text = 'function failed' )\n                      %element-price = if_abap_behv=\u003emk-on )\n                      TO reported-purchasedocument.\n      DELETE lt_keys.\n    ENDLOOP.\n\n    CHECK lt_keys IS NOT INITIAL.\n\n    \"get total price\n    READ ENTITIES OF demo_cds_function_1 IN LOCAL MODE\n      ENTITY PurchaseDocument\n        ALL FIELDS\n        WITH CORRESPONDING #( lt_keys )\n      RESULT DATA(lt_purc)\n      FAILED DATA(read_failed).\n\n    failed = CORRESPONDING #( DEEP read_failed ).\n\n    LOOP AT lt_purc ASSIGNING FIELD-SYMBOL(\u003cfs_purch\u003e).\n      DATA lv_percentage TYPE decfloat16.\n      DATA(lv_discount_percent) = lt_keys[\n      KEY entity  %tky = \u003cfs_purch\u003e-%tky ]-%param-discount_percent.\n      lv_percentage =  lv_discount_percent / 100 .\n      \u003cfs_purch\u003e-Price = \u003cfs_purch\u003e-price * ( 1 - lv_percentage ) .\n\n      APPEND VALUE #( %tky               = \u003cfs_purch\u003e-%tky\n                      %param             = CORRESPONDING #( \u003cfs_purch\u003e ) )\n                      TO lt_reduced_purch.\n    ENDLOOP.\n\n    result = VALUE #( FOR purchase IN lt_reduced_purch\n                          ( %tky   = purchase-%tky\n                            %param = purchase-%param ) ).\n  ENDMETHOD.\n  METHOD get_instance_authorizations.\n  ENDMETHOD.\n\nENDCLASS.\n```\n\n## Berechtigungen\n\n### Lesende Berechtigungen\n\n```cds\n@EndUserText.label: 'Carrier'\n@MappingRole: true\ndefine role ZMIND2E_C_CARRIER {\n    grant select on ZMIND2E_C_CARRIER\n    where (AirlineId) = aspect pfcg_auth(S_CARRID, CARRID, ACTVT = '03' );\n    \n}\n```\n\n### Authorization Master\n\n```cds\ndefine behavior for /DMO/I_Travel_D alias Travel\n...\nauthorization master ( global, instance )\n{\n    create;\n    update;\n    delete;\n    action acceptTravel ...;\n    ...\n}\n```\n\n### Authorization Dependent\n\n```cds\ndefine behavior for /DMO/I_Booking_D alias Booking\n...\nauthorization dependent by _Travel\n{\n    update;\n    delete;\n    association _Travel { }\n}\n```\n\n### Global Authorization\n\n```abap\nCLASS lhc_travel DEFINITION INHERITING FROM cl_abap_behavior_handler.\n\n  PRIVATE SECTION.\n\n...\n    METHODS get_global_authorizations FOR GLOBAL AUTHORIZATION\n      IMPORTING REQUEST requested_authorizations FOR travel RESULT result.\n\nENDCLASS.\n\nCLASS lhc_travel IMPLEMENTATION.\n  METHOD get_global_authorizations.\n    IF requested_authorizations-%create EQ if_abap_behv=\u003emk-on.\n      IF is_create_granted( ) = abap_true.\n        result-%create = if_abap_behv=\u003eauth-allowed.\n      ELSE.\n        result-%create = if_abap_behv=\u003eauth-unauthorized.\n        APPEND VALUE #( %msg    = NEW /DMO/CM_FLIGHT_MESSAGES(\n                                       textid   = /DMO/CM_FLIGHT_MESSAGES=\u003enot_authorized\n                                       severity = if_abap_behv_message=\u003eseverity-error )\n                        %global = if_abap_behv=\u003emk-on \n                      ) TO reported-travel.\n\n      ENDIF.\n    ENDIF.\n\n    \"Edit is treated like update\n    IF requested_authorizations-%update                =  if_abap_behv=\u003emk-on OR\n       requested_authorizations-%action-Edit           =  if_abap_behv=\u003emk-on.\n\n      IF  is_update_granted( ) = abap_true.\n        result-%update                =  if_abap_behv=\u003eauth-allowed.\n        result-%action-Edit           =  if_abap_behv=\u003eauth-allowed.\n\n      ELSE.\n        result-%update                =  if_abap_behv=\u003eauth-unauthorized.\n        result-%action-Edit           =  if_abap_behv=\u003eauth-unauthorized.\n\n        APPEND VALUE #( %msg    = NEW /DMO/CM_FLIGHT_MESSAGES(\n                                       textid   = /DMO/CM_FLIGHT_MESSAGES=\u003enot_authorized\n                                       severity = if_abap_behv_message=\u003eseverity-error )\n                        %global = if_abap_behv=\u003emk-on \n                      ) TO reported-travel.\n\n      ENDIF.\n    ENDIF.\n\n\n    IF requested_authorizations-%delete =  if_abap_behv=\u003emk-on.\n      IF is_delete_granted( ) = abap_true.\n        result-%delete = if_abap_behv=\u003eauth-allowed.\n      ELSE.\n        result-%delete = if_abap_behv=\u003eauth-unauthorized.\n        APPEND VALUE #( %msg    = NEW /DMO/CM_FLIGHT_MESSAGES(\n                                       textid   = /DMO/CM_FLIGHT_MESSAGES=\u003enot_authorized\n                                       severity = if_abap_behv_message=\u003eseverity-error )\n                        %global = if_abap_behv=\u003emk-on \n                       ) TO reported-travel.\n      ENDIF.\n    ENDIF.\n\n  ENDMETHOD.\n\nENDCLASS.\n```\n\n### Instance Authorization\n\n```abap\nCLASS lhc_travel DEFINITION INHERITING FROM cl_abap_behavior_handler.\n\n  PRIVATE SECTION.\n\n...\n    METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION\n      IMPORTING keys REQUEST requested_authorizations FOR travel RESULT result.\n\nENDCLASS.\n\nCLASS lhc_travel IMPLEMENTATION.\n  METHOD get_instance_authorizations.\n\n    DATA: update_requested TYPE abap_bool,\n          delete_requested TYPE abap_bool,\n          update_granted   TYPE abap_bool,\n          delete_granted   TYPE abap_bool.\n\n    READ ENTITIES OF /DMO/R_Travel_D IN LOCAL MODE\n      ENTITY Travel\n        FIELDS ( AgencyID )\n        WITH CORRESPONDING #( keys )\n    RESULT DATA(travels)\n    FAILED failed.\n\n    CHECK travels IS NOT INITIAL.\n\n    \"Select country_code and agency of corresponding persistent travel instance\n    \"authorization  only checked against instance that have active persistence\n    SELECT  FROM /DMO/A_TRAVEL_D AS travel  INNER JOIN /DMO/AGENCY AS agency\n          ON travel~agency_id = agency~agency_id\n          FIELDS travel~travel_uuid , travel~agency_id, agency~country_code\n          FOR ALL ENTRIES IN @travels WHERE travel_uuid EQ @travels-TravelUUID\n          INTO  TABLE @DATA(travel_agency_country).\n\n\n    \"edit is treated like update\n    update_requested = COND #( WHEN requested_authorizations-%update                = if_abap_behv=\u003emk-on OR\n                                    requested_authorizations-%action-Edit           = if_abap_behv=\u003emk-on\n                               THEN abap_true ELSE abap_false ).\n\n    delete_requested = COND #( WHEN requested_authorizations-%delete                = if_abap_behv=\u003emk-on\n                               THEN abap_true ELSE abap_false ).\n\n\n    LOOP AT travels INTO DATA(travel).\n      \"get country_code of agency in corresponding instance on persistent table\n      READ TABLE travel_agency_country WITH KEY travel_uuid = travel-TravelUUID\n        ASSIGNING FIELD-SYMBOL(\u003ctravel_agency_country_code\u003e).\n\n      \"Auth check for active instances that have before image on persistent table\n      IF sy-subrc = 0.\n\n        \"check auth for update\n        IF update_requested = abap_true.\n          update_granted = is_update_granted( \u003ctravel_agency_country_code\u003e-country_code  ).\n          IF update_granted = abap_false.\n            APPEND VALUE #( %tky = travel-%tky\n                            %msg = NEW /DMO/CM_FLIGHT_MESSAGES(\n                                                     textid    = /DMO/CM_FLIGHT_MESSAGES=\u003enot_authorized_for_agencyid\n                                                     agency_id = travel-AgencyID\n                                                     severity  = if_abap_behv_message=\u003eseverity-error )\n                            %element-AgencyID = if_abap_behv=\u003emk-on\n                           ) TO reported-travel.\n          ENDIF.\n        ENDIF.\n\n        \"check auth for delete\n        IF delete_requested = abap_true.\n          delete_granted = is_delete_granted( \u003ctravel_agency_country_code\u003e-country_code ).\n          IF delete_granted = abap_false.\n            APPEND VALUE #( %tky = travel-%tky\n                            %msg = NEW /DMO/CM_FLIGHT_MESSAGES(\n                                     textid   = /DMO/CM_FLIGHT_MESSAGES=\u003enot_authorized_for_agencyid\n                                     agency_id = travel-AgencyID\n                                     severity = if_abap_behv_message=\u003eseverity-error )\n                            %element-AgencyID = if_abap_behv=\u003emk-on\n                           ) TO reported-travel.\n          ENDIF.\n        ENDIF.\n\n        \" operations on draft instances and on active instances that have no persistent before image (eg Update on newly created instance)\n        \" create authorization is checked, for newly created instances\n      ELSE.\n        update_granted = delete_granted = is_create_granted( ).\n        IF update_granted = abap_false.\n          APPEND VALUE #( %tky = travel-%tky\n                          %msg = NEW /DMO/CM_FLIGHT_MESSAGES(\n                                   textid   = /DMO/CM_FLIGHT_MESSAGES=\u003enot_authorized\n                                   severity = if_abap_behv_message=\u003eseverity-error )\n                          %element-AgencyID = if_abap_behv=\u003emk-on\n                        ) TO reported-travel.\n        ENDIF.\n      ENDIF.\n\n      APPEND VALUE #( LET upd_auth = COND #( WHEN update_granted = abap_true THEN if_abap_behv=\u003eauth-allowed\n                                             ELSE if_abap_behv=\u003eauth-unauthorized )\n                          del_auth = COND #( WHEN delete_granted = abap_true THEN if_abap_behv=\u003eauth-allowed\n                                             ELSE if_abap_behv=\u003eauth-unauthorized )\n                      IN\n                       %tky = travel-%tky\n                       %update                = upd_auth\n                       %action-Edit           = upd_auth\n\n                       %delete                = del_auth\n                    ) TO result.\n    ENDLOOP.\n\n\n  ENDMETHOD.\n\nENDCLASS.\n```\n\n#### Instance Authorization Beispiel\n\n```abap\n  METHOD get_instance_authorizations.\n    data: update_requested type abap_bool,\n          delete_requested type abap_bool.\n\n    read entities of ZMIND2RAP_I_Travel in local mode\n        ENTITY Travel\n            Fields ( AgencyId )\n            WITH CORRESPONDING #( keys )\n        RESULT data(travels)\n        failed failed.\n\n    check travels is not INITIAL.\n\n    update_requested = COND #( when requested_authorizations-%update = if_abap_behv=\u003emk-on then abap_true\n*                              Diese Zeile nur wenn Draft Handling aktiviert ist\n                               when requested_authorizations-%action-Edit = if_abap_behv=\u003emk-on then abap_true\n                               else abap_false ).\n    delete_requested = COND #( when requested_authorizations-%delete = if_abap_behv=\u003emk-on then abap_true\n                               else abap_false ).\n\n    LOOP AT travels ASSIGNING FIELD-SYMBOL(\u003cagency\u003e) GROUP BY \u003cagency\u003e-AgencyId.\n        data(update_authorized) = cond #( when update_requested = abap_true\n                                            then zcl_mind2rap_helper=\u003eis_granted( agency = \u003cagency\u003e-AgencyId actvt = '02' )\n                                          else abap_false ).\n\n        data(delete_authorized) = cond #( when delete_requested = abap_true\n                                            then zcl_mind2rap_helper=\u003eis_granted( agency = \u003cagency\u003e-AgencyId actvt = '06' )\n                                          else abap_false ).\n\n        LOOP AT GROUP \u003cagency\u003e ASSIGNING FIELD-SYMBOL(\u003ctravel\u003e).\n            if ( update_requested = abap_true AND update_authorized = abap_false ) OR\n               ( delete_requested = abap_true AND delete_authorized = abap_false ).\n                append value #( %tky = \u003ctravel\u003e-%tky\n                                %msg = new_message(\n                                    id = 'ZCM_MIND2RAP_TRAVEL'\n                                    number = '007'\n                                    severity = if_abap_behv_message=\u003eseverity-error\n                                    v1 = \u003ctravel\u003e-TravelId\n                                ) ) to reported-travel.\n            endif.\n\n            append value #( let update_auth = cond #( when update_authorized = abap_true then if_abap_behv=\u003eauth-allowed\n                                                      else if_abap_behv=\u003eauth-unauthorized )\n                                delete_auth = cond #( when delete_authorized = abap_true then if_abap_behv=\u003eauth-allowed\n                                                      else if_abap_behv=\u003eauth-unauthorized )\n                            in\n                                %tky = \u003ctravel\u003e-%tky\n                                %update = update_auth\n                                %delete = delete_auth\n*                               Diese Aktion nur wenn Draft Handling aktiviert ist\n                                %action-Edit = update_auth ) to result.\n        ENDLOOP.\n    ENDLOOP.\n  ENDMETHOD.\n```\n\n## Sperren\n\n### Pessimistische Sperren\n\n```cds\ndefine behavior for /DMO/I_Travel_D alias Travel\nlock master\n...\n{\n    ...\n}\n\ndefine behavior for /DMO/I_Booking_D alias Booking\nlock dependent by _Travel\n...\n{\n    ...\n    association _Travel { }\n}\n```\n\n### Optimistische Sperren\n\n```cds\ndefine behavior for /DMO/I_Travel_M alias Travel\netag master LocalLastChangedAt\n...\n\ndefine behavior for /DMO/I_Booking_D alias Booking\netag master LocalLastChangedAt\n...\n```\n\n```cds\ndefine behavior for ZI_SalesOrder alias SalesOrder\netag master LastChangedAt\n...\n\ndefine behavior for ZI_SalesOrderItem alias Item\netag dependant by _SalesOrder\n...\n{\n    association _SalesOrder { }\n}\n```\n\n## Draft Handling\n\n```cds\nmanaged;\nstrict;\nwith draft;\ndefine behavior for /DMO/I_Travel_D alias Travel\n```\n\n### Draft Tabellen\n\n```cds\n...\ndefine behavior for /DMO/I_Travel_D alias Travel\n...\npersistent table /dmo/a_travel_d\ndraft table /dmo/d_travel_d\n...\n\ndefine behavior for /DMO/I_Booking_D alias Booking\n...\npersistent table /dmo/a_booking_d\ndraft table /dmo/d_booking_d\n...\n```\n\n### Draft etag Handling\n\n```cds\ndefine behavior for /DMO/I_Travel_D alias Travel\n...\ntotal etag LastChangedAt\n...\n```\n\n### Draft Assoziationen\n\n```cds\ndefine behavior for /DMO/I_Travel_D alias Travel\n...\n{\n    ...\n    association _Booking { create; with draft; }\n}\n...\n```\n\n### Draft Aktionen\n\n```cds\ndefine behavior for /DMO/I_Travel_D alias Travel\n...\n{\n    draft action Resume;\n    draft action Edit;\n    draft action Activate;\n    draft action Discard;\n    \n    draft determine action Prepare\n    {\n        validation validateAgency;\n        validation validateCustomer;\n        ...\n    }\n\n    validation validateCustomer on save { ... }\n    validation validateAgency on save { ... }\n    ...\n}\n```\n\n## Implementierung Speichersequenz\n\n### Managed scenario with unmanaged save\n\n```cds\ndefine behavior for /DMO/I_BookSuppl_M alias booksuppl\nimplementation in class /DMO/BP_BOOKINGSUPPLEMENT_M unique\nwith unmanaged save\n...\n{\n   ... \n}\n```\n\n```abap\nCLASS lcl_save DEFINITION INHERITING FROM cl_abap_behavior_saver.\n\n  PROTECTED SECTION.\n    METHODS save_modified REDEFINITION.\n\nENDCLASS.\n\n\nCLASS lcl_save IMPLEMENTATION.\n\n DATA booksuppls_db TYPE STANDARD TABLE OF /dmo/booksuppl_m.\n\n    \" (1) Get instance data of all instances that have been created\n    IF create-booksuppl IS NOT INITIAL.\n      booksuppls_db = CORRESPONDING #( create-booksuppl ).\n\n      CALL FUNCTION '/DMO/FLIGHT_BOOKSUPPL_C' EXPORTING values = booksuppls_db .\n\n    ENDIF.\n\n    \" (2) Get instance data of all instances that have been updated during the transaction\n    booksuppls_db = CORRESPONDING #( update-booksuppl ).\n    IF booksuppls_db IS NOT INITIAL.\n\n      \" Read all field values from database\n      SELECT * FROM /dmo/booksuppl_m FOR ALL ENTRIES IN @booksuppls_db\n               WHERE booking_supplement_id = @booksuppls_db-booking_supplement_id\n               INTO TABLE @booksuppls_db .\n\n      \" Take over field values that have been changed during the transaction\n      LOOP AT update-booksuppl ASSIGNING FIELD-SYMBOL(\u003cunmanaged_booksuppl\u003e).\n        ASSIGN booksuppls_db[ travel_id  = \u003cunmanaged_booksuppl\u003e-travel_id\n                              booking_id = \u003cunmanaged_booksuppl\u003e-booking_id\n                   booking_supplement_id = \u003cunmanaged_booksuppl\u003e-booking_supplement_id\n                            ] TO FIELD-SYMBOL(\u003cbooksuppl_db\u003e).\n\n        IF \u003cunmanaged_booksuppl\u003e-%control-supplement_id = if_abap_behv=\u003emk-on.\n          \u003cbooksuppl_db\u003e-supplement_id = \u003cunmanaged_booksuppl\u003e-supplement_id.\n        ENDIF.\n\n        IF \u003cunmanaged_booksuppl\u003e-%control-price = if_abap_behv=\u003emk-on.\n          \u003cbooksuppl_db\u003e-price = \u003cunmanaged_booksuppl\u003e-price.\n        ENDIF.\n\n        IF \u003cunmanaged_booksuppl\u003e-%control-currency_code = if_abap_behv=\u003emk-on.\n          \u003cbooksuppl_db\u003e-currency_code = \u003cunmanaged_booksuppl\u003e-currency_code.\n        ENDIF.\n\n      ENDLOOP.\n\n      \" Update the complete instance data\n      CALL FUNCTION '/DMO/FLIGHT_BOOKSUPPL_U' EXPORTING values = booksuppls_db .\n\n    ENDIF.\n\n    \" (3) Get keys of all travel instances that have been deleted during the transaction\n    IF delete-booksuppl IS NOT INITIAL.\n      booksuppls_db = CORRESPONDING #( delete-booksuppl ).\n\n      CALL FUNCTION '/DMO/FLIGHT_BOOKSUPPL_D' EXPORTING values = booksuppls_db .\n\n    ENDIF.\n\n\n  ENDMETHOD.\n\nENDCLASS.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmindsquare-custom-solutions%2Frap_samples","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmindsquare-custom-solutions%2Frap_samples","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmindsquare-custom-solutions%2Frap_samples/lists"}