@linkup-ai/abap-ai 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/README.md +384 -0
  2. package/dist/adt-client.js +364 -0
  3. package/dist/cli/activate.js +113 -0
  4. package/dist/cli/init.js +333 -0
  5. package/dist/cli/remove.js +80 -0
  6. package/dist/cli/status.js +229 -0
  7. package/dist/cli/systems.js +68 -0
  8. package/dist/cli.js +81 -0
  9. package/dist/index.js +1318 -0
  10. package/dist/knowledge/abap/abap-dictionary.md +199 -0
  11. package/dist/knowledge/abap/abap-sql.md +296 -0
  12. package/dist/knowledge/abap/amdp.md +273 -0
  13. package/dist/knowledge/abap/clean-code.md +293 -0
  14. package/dist/knowledge/abap/cloud-background-processing.md +250 -0
  15. package/dist/knowledge/abap/cloud-communication.md +265 -0
  16. package/dist/knowledge/abap/cloud-development.md +176 -0
  17. package/dist/knowledge/abap/cloud-extensibility.md +252 -0
  18. package/dist/knowledge/abap/cloud-released-apis.md +261 -0
  19. package/dist/knowledge/abap/constructor-expressions.md +289 -0
  20. package/dist/knowledge/abap/enhancements.md +232 -0
  21. package/dist/knowledge/abap/exceptions.md +271 -0
  22. package/dist/knowledge/abap/internal-tables.md +205 -0
  23. package/dist/knowledge/abap/object-orientation.md +298 -0
  24. package/dist/knowledge/abap/performance.md +216 -0
  25. package/dist/knowledge/abap/rap-abstract-entities.md +206 -0
  26. package/dist/knowledge/abap/rap-business-events.md +216 -0
  27. package/dist/knowledge/abap/rap-draft.md +191 -0
  28. package/dist/knowledge/abap/rap-eml.md +453 -0
  29. package/dist/knowledge/abap/rap-end-to-end.md +486 -0
  30. package/dist/knowledge/abap/rap-feature-control.md +185 -0
  31. package/dist/knowledge/abap/rap-numbering.md +280 -0
  32. package/dist/knowledge/abap/rap-service-exposure.md +163 -0
  33. package/dist/knowledge/abap/rap-unmanaged.md +468 -0
  34. package/dist/knowledge/abap/string-processing.md +180 -0
  35. package/dist/knowledge/abap/unit-testing.md +303 -0
  36. package/dist/knowledge/abap-cds/access-control.md +241 -0
  37. package/dist/knowledge/abap-cds/annotations.md +331 -0
  38. package/dist/knowledge/abap-cds/associations.md +254 -0
  39. package/dist/knowledge/abap-cds/expressions.md +230 -0
  40. package/dist/knowledge/abap-cds/functions.md +245 -0
  41. package/dist/knowledge/abap-cds/metadata-extensions.md +294 -0
  42. package/dist/knowledge/cap/authentication.md +278 -0
  43. package/dist/knowledge/cap/cdl-syntax.md +247 -0
  44. package/dist/knowledge/cap/cql-queries.md +266 -0
  45. package/dist/knowledge/cap/deployment.md +343 -0
  46. package/dist/knowledge/cap/event-handlers.md +287 -0
  47. package/dist/knowledge/cap/fiori-integration.md +303 -0
  48. package/dist/knowledge/cap/service-definitions.md +287 -0
  49. package/dist/knowledge/fiori/annotations.md +347 -0
  50. package/dist/knowledge/fiori/deployment.md +340 -0
  51. package/dist/knowledge/fiori/fiori-elements.md +332 -0
  52. package/dist/knowledge/fiori/fiori-side-effects.md +107 -0
  53. package/dist/knowledge/fiori/fiori-valuelist.md +144 -0
  54. package/dist/knowledge/fiori/ui5-controllers.md +358 -0
  55. package/dist/knowledge/fiori/ui5-data-binding.md +311 -0
  56. package/dist/knowledge/fiori/ui5-fragments-dialogs.md +330 -0
  57. package/dist/knowledge/fiori/ui5-manifest.md +411 -0
  58. package/dist/knowledge/fiori/ui5-routing.md +303 -0
  59. package/dist/knowledge/fiori/ui5-xml-views.md +294 -0
  60. package/dist/logger.js +114 -0
  61. package/dist/system-profile.js +207 -0
  62. package/dist/tools/abap-doc.js +72 -0
  63. package/dist/tools/abapgit.js +161 -0
  64. package/dist/tools/activate.js +68 -0
  65. package/dist/tools/atc-check.js +117 -0
  66. package/dist/tools/auth-object.js +56 -0
  67. package/dist/tools/breakpoints.js +76 -0
  68. package/dist/tools/call-hierarchy.js +84 -0
  69. package/dist/tools/cds-annotations.js +98 -0
  70. package/dist/tools/cds-dependencies.js +65 -0
  71. package/dist/tools/check.js +47 -0
  72. package/dist/tools/code-completion.js +70 -0
  73. package/dist/tools/code-coverage.js +111 -0
  74. package/dist/tools/create-amdp.js +111 -0
  75. package/dist/tools/create-dcl.js +81 -0
  76. package/dist/tools/create-transport.js +38 -0
  77. package/dist/tools/create.js +285 -0
  78. package/dist/tools/data-preview.js +37 -0
  79. package/dist/tools/delete.js +45 -0
  80. package/dist/tools/deploy-bsp.js +298 -0
  81. package/dist/tools/discovery.js +59 -0
  82. package/dist/tools/element-info.js +93 -0
  83. package/dist/tools/enhancements.js +186 -0
  84. package/dist/tools/extract-method.js +44 -0
  85. package/dist/tools/function-group.js +59 -0
  86. package/dist/tools/knowledge.js +275 -0
  87. package/dist/tools/lock-object.js +75 -0
  88. package/dist/tools/message-class.js +67 -0
  89. package/dist/tools/navigate.js +80 -0
  90. package/dist/tools/number-range.js +57 -0
  91. package/dist/tools/object-documentation.js +43 -0
  92. package/dist/tools/object-structure.js +78 -0
  93. package/dist/tools/object-versions.js +57 -0
  94. package/dist/tools/package-contents.js +60 -0
  95. package/dist/tools/pretty-printer.js +35 -0
  96. package/dist/tools/publish-binding.js +49 -0
  97. package/dist/tools/quick-fix.js +69 -0
  98. package/dist/tools/read.js +167 -0
  99. package/dist/tools/refactor-rename.js +60 -0
  100. package/dist/tools/release-transport.js +24 -0
  101. package/dist/tools/released-apis.js +51 -0
  102. package/dist/tools/repository-tree.js +90 -0
  103. package/dist/tools/scaffold-rap.js +642 -0
  104. package/dist/tools/search.js +73 -0
  105. package/dist/tools/shared/data-format.js +101 -0
  106. package/dist/tools/sql-console.js +17 -0
  107. package/dist/tools/system-info.js +270 -0
  108. package/dist/tools/traces.js +66 -0
  109. package/dist/tools/transport-contents.js +83 -0
  110. package/dist/tools/transports.js +67 -0
  111. package/dist/tools/unit-test.js +135 -0
  112. package/dist/tools/where-used.js +59 -0
  113. package/dist/tools/write.js +101 -0
  114. package/package.json +49 -0
@@ -0,0 +1,486 @@
1
+ # RAP End-to-End — managed BO com draft, OData V4, Fiori Elements
2
+
3
+ ## Stack
4
+
5
+ ```
6
+ DB Tables → CDS Interface (root+child) → BDEF managed with draft → Handler Class
7
+ → CDS Projection (root+child) → Projection BDEF (use draft)
8
+ → Service Definition → Service Binding (OData V4 UI)
9
+ → Metadata Extension (UI annotations)
10
+ ```
11
+
12
+ ## 1. Database Tables
13
+
14
+ ```abap
15
+ define table ztravel {
16
+ key client : abap.clnt not null;
17
+ key travel_id : abap.numc(8) not null;
18
+ agency_id : abap.numc(6);
19
+ customer_id : abap.numc(6);
20
+ begin_date : abap.dats;
21
+ end_date : abap.dats;
22
+ @AbapCatalog.currency.currencyCode : 'ztravel.currency_code'
23
+ booking_fee : abap.curr(17,2);
24
+ @AbapCatalog.currency.currencyCode : 'ztravel.currency_code'
25
+ total_price : abap.curr(17,2);
26
+ currency_code : abap.cuky(5);
27
+ description : abap.char(256);
28
+ overall_status : abap.char(1);
29
+ created_by : abp_creation_user;
30
+ created_at : abp_creation_tstmpl;
31
+ last_changed_by : abp_locinst_lastchange_user;
32
+ last_changed_at : abp_locinst_lastchange_tstmpl;
33
+ local_last_changed_at : abp_lastchange_tstmpl;
34
+ }
35
+
36
+ define table zbooking {
37
+ key client : abap.clnt not null;
38
+ key travel_id : abap.numc(8) not null;
39
+ key booking_id : abap.numc(4) not null;
40
+ booking_date : abap.dats;
41
+ carrier_id : abap.char(3);
42
+ connection_id : abap.numc(4);
43
+ flight_date : abap.dats;
44
+ @AbapCatalog.currency.currencyCode : 'zbooking.currency_code'
45
+ flight_price : abap.curr(17,2);
46
+ currency_code : abap.cuky(5);
47
+ booking_status : abap.char(1);
48
+ local_last_changed_at : abp_lastchange_tstmpl;
49
+ }
50
+ ```
51
+
52
+ Draft tables sao geradas automaticamente pelo framework.
53
+
54
+ ## 2. CDS Interface — Root
55
+
56
+ ```abap
57
+ @AccessControl.authorizationCheck: #CHECK
58
+ @Metadata.allowExtensions: true
59
+ define root view entity ZI_Travel
60
+ as select from ztravel
61
+ composition [0..*] of ZI_Booking as _Booking
62
+ association [0..1] to /DMO/I_Agency as _Agency on $projection.AgencyID = _Agency.AgencyID
63
+ association [0..1] to /DMO/I_Customer as _Customer on $projection.CustomerID = _Customer.CustomerID
64
+ association [0..1] to I_Currency as _Currency on $projection.CurrencyCode = _Currency.Currency
65
+ {
66
+ key travel_id as TravelID,
67
+ agency_id as AgencyID,
68
+ customer_id as CustomerID,
69
+ begin_date as BeginDate,
70
+ end_date as EndDate,
71
+ @Semantics.amount.currencyCode: 'CurrencyCode'
72
+ booking_fee as BookingFee,
73
+ @Semantics.amount.currencyCode: 'CurrencyCode'
74
+ total_price as TotalPrice,
75
+ currency_code as CurrencyCode,
76
+ description as Description,
77
+ overall_status as OverallStatus,
78
+ @Semantics.user.createdBy: true
79
+ created_by as CreatedBy,
80
+ @Semantics.systemDateTime.createdAt: true
81
+ created_at as CreatedAt,
82
+ @Semantics.user.localInstanceLastChangedBy: true
83
+ last_changed_by as LastChangedBy,
84
+ @Semantics.systemDateTime.localInstanceLastChangedAt: true
85
+ last_changed_at as LastChangedAt,
86
+ @Semantics.systemDateTime.lastChangedAt: true
87
+ local_last_changed_at as LocalLastChangedAt,
88
+ _Booking,
89
+ _Agency,
90
+ _Customer,
91
+ _Currency
92
+ }
93
+ ```
94
+
95
+ ## 3. CDS Interface — Child
96
+
97
+ ```abap
98
+ @AccessControl.authorizationCheck: #CHECK
99
+ @Metadata.allowExtensions: true
100
+ define view entity ZI_Booking
101
+ as select from zbooking
102
+ association to parent ZI_Travel as _Travel on $projection.TravelID = _Travel.TravelID
103
+ association [0..1] to /DMO/I_Carrier as _Carrier on $projection.CarrierID = _Carrier.AirlineID
104
+ association [0..1] to I_Currency as _Currency on $projection.CurrencyCode = _Currency.Currency
105
+ {
106
+ key travel_id as TravelID,
107
+ key booking_id as BookingID,
108
+ booking_date as BookingDate,
109
+ carrier_id as CarrierID,
110
+ connection_id as ConnectionID,
111
+ flight_date as FlightDate,
112
+ @Semantics.amount.currencyCode: 'CurrencyCode'
113
+ flight_price as FlightPrice,
114
+ currency_code as CurrencyCode,
115
+ booking_status as BookingStatus,
116
+ @Semantics.systemDateTime.lastChangedAt: true
117
+ local_last_changed_at as LocalLastChangedAt,
118
+ _Travel,
119
+ _Carrier,
120
+ _Currency
121
+ }
122
+ ```
123
+
124
+ ## 4. BDEF Interface
125
+
126
+ ```abap
127
+ managed implementation in class ZBP_I_TRAVEL unique;
128
+ strict ( 2 );
129
+ with draft;
130
+
131
+ define behavior for ZI_Travel alias Travel
132
+ persistent table ztravel
133
+ draft table ztravel_d
134
+ etag master LocalLastChangedAt
135
+ lock master total etag LastChangedAt
136
+ authorization master ( global )
137
+ {
138
+ field ( readonly ) TravelID;
139
+ field ( readonly ) CreatedBy, CreatedAt, LastChangedBy, LastChangedAt, LocalLastChangedAt;
140
+ field ( mandatory ) AgencyID, CustomerID;
141
+
142
+ create;
143
+ update;
144
+ delete;
145
+
146
+ draft action Edit;
147
+ draft action Activate optimized;
148
+ draft action Discard;
149
+ draft action Resume;
150
+ draft determine action Prepare { validation validateDates; validation validateCustomer; }
151
+
152
+ validation validateDates on save { create; field BeginDate, EndDate; }
153
+ validation validateCustomer on save { create; field CustomerID; }
154
+ determination setTravelID on modify { create; }
155
+ determination calculateTotalPrice on modify { field BookingFee; }
156
+
157
+ action ( features : instance ) acceptTravel result [1] $self;
158
+ action ( features : instance ) rejectTravel result [1] $self;
159
+
160
+ side effects {
161
+ field BookingFee affects field TotalPrice;
162
+ determine action Prepare executed on field BeginDate, field EndDate, field CustomerID;
163
+ }
164
+
165
+ mapping for ztravel corresponding;
166
+ association _Booking { create; with draft; }
167
+ }
168
+
169
+ define behavior for ZI_Booking alias Booking
170
+ persistent table zbooking
171
+ draft table zbooking_d
172
+ etag master LocalLastChangedAt
173
+ lock dependent by _Travel
174
+ authorization dependent by _Travel
175
+ {
176
+ field ( readonly ) TravelID, BookingID;
177
+ field ( mandatory ) CarrierID, ConnectionID, FlightDate;
178
+
179
+ update;
180
+ delete;
181
+
182
+ determination setBookingID on modify { create; }
183
+
184
+ mapping for zbooking corresponding;
185
+ association _Travel { with draft; }
186
+ }
187
+ ```
188
+
189
+ ## 5. Handler Class
190
+
191
+ ```abap
192
+ CLASS zbp_i_travel DEFINITION PUBLIC ABSTRACT FINAL FOR BEHAVIOR OF ZI_Travel.
193
+ ENDCLASS.
194
+ CLASS zbp_i_travel IMPLEMENTATION.
195
+ ENDCLASS.
196
+ ```
197
+
198
+ ### Local handler (lhc_travel):
199
+
200
+ ```abap
201
+ CLASS lhc_travel DEFINITION INHERITING FROM cl_abap_behavior_handler.
202
+ PRIVATE SECTION.
203
+ METHODS get_global_authorizations FOR GLOBAL AUTHORIZATION
204
+ IMPORTING REQUEST requested_authorizations FOR Travel RESULT result.
205
+ METHODS setTravelID FOR DETERMINE ON MODIFY IMPORTING keys FOR Travel~setTravelID.
206
+ METHODS calculateTotalPrice FOR DETERMINE ON MODIFY IMPORTING keys FOR Travel~calculateTotalPrice.
207
+ METHODS validateDates FOR VALIDATE ON SAVE IMPORTING keys FOR Travel~validateDates.
208
+ METHODS validateCustomer FOR VALIDATE ON SAVE IMPORTING keys FOR Travel~validateCustomer.
209
+ METHODS acceptTravel FOR MODIFY IMPORTING keys FOR ACTION Travel~acceptTravel RESULT result.
210
+ METHODS rejectTravel FOR MODIFY IMPORTING keys FOR ACTION Travel~rejectTravel RESULT result.
211
+ METHODS get_instance_features FOR INSTANCE FEATURES
212
+ IMPORTING keys REQUEST requested_features FOR Travel RESULT result.
213
+ ENDCLASS.
214
+
215
+ CLASS lhc_travel IMPLEMENTATION.
216
+
217
+ METHOD get_global_authorizations.
218
+ result = VALUE #( ( %create = if_abap_behv=>auth-allowed
219
+ %update = if_abap_behv=>auth-allowed
220
+ %delete = if_abap_behv=>auth-allowed ) ).
221
+ ENDMETHOD.
222
+
223
+ METHOD setTravelID.
224
+ READ ENTITIES OF ZI_Travel IN LOCAL MODE
225
+ ENTITY Travel FIELDS ( TravelID ) WITH CORRESPONDING #( keys )
226
+ RESULT DATA(travels).
227
+ SELECT SINGLE FROM ztravel FIELDS MAX( travel_id ) INTO @DATA(max_id).
228
+ MODIFY ENTITIES OF ZI_Travel IN LOCAL MODE
229
+ ENTITY Travel UPDATE FIELDS ( TravelID )
230
+ WITH VALUE #( FOR t IN travels WHERE ( TravelID IS INITIAL )
231
+ ( %tky = t-%tky TravelID = max_id + 1 ) ).
232
+ ENDMETHOD.
233
+
234
+ METHOD calculateTotalPrice.
235
+ READ ENTITIES OF ZI_Travel IN LOCAL MODE
236
+ ENTITY Travel FIELDS ( BookingFee CurrencyCode ) WITH CORRESPONDING #( keys )
237
+ RESULT DATA(travels).
238
+ READ ENTITIES OF ZI_Travel IN LOCAL MODE
239
+ ENTITY Travel BY \_Booking FIELDS ( FlightPrice )
240
+ WITH CORRESPONDING #( keys ) RESULT DATA(bookings).
241
+ LOOP AT travels ASSIGNING FIELD-SYMBOL(<t>).
242
+ DATA(total) = <t>-BookingFee.
243
+ LOOP AT bookings INTO DATA(b) WHERE TravelID = <t>-TravelID.
244
+ total += b-FlightPrice.
245
+ ENDLOOP.
246
+ MODIFY ENTITIES OF ZI_Travel IN LOCAL MODE
247
+ ENTITY Travel UPDATE FIELDS ( TotalPrice )
248
+ WITH VALUE #( ( %tky = <t>-%tky TotalPrice = total ) ).
249
+ ENDLOOP.
250
+ ENDMETHOD.
251
+
252
+ METHOD validateDates.
253
+ READ ENTITIES OF ZI_Travel IN LOCAL MODE
254
+ ENTITY Travel FIELDS ( BeginDate EndDate ) WITH CORRESPONDING #( keys )
255
+ RESULT DATA(travels).
256
+ LOOP AT travels INTO DATA(t).
257
+ APPEND VALUE #( %tky = t-%tky ) TO result.
258
+ IF t-BeginDate IS INITIAL.
259
+ APPEND VALUE #( %tky = t-%tky %state_area = 'VALIDATE_DATES'
260
+ %msg = NEW /dmo/cm_flight_messages( textid = /dmo/cm_flight_messages=>begin_date_required
261
+ severity = if_abap_behv_message=>severity-error )
262
+ %element-BeginDate = if_abap_behv=>mk-on ) TO reported-travel.
263
+ ENDIF.
264
+ IF t-EndDate IS NOT INITIAL AND t-EndDate < t-BeginDate.
265
+ APPEND VALUE #( %tky = t-%tky %state_area = 'VALIDATE_DATES'
266
+ %msg = NEW /dmo/cm_flight_messages( textid = /dmo/cm_flight_messages=>end_date_before_begin
267
+ severity = if_abap_behv_message=>severity-error )
268
+ %element-EndDate = if_abap_behv=>mk-on ) TO reported-travel.
269
+ ENDIF.
270
+ ENDLOOP.
271
+ ENDMETHOD.
272
+
273
+ METHOD validateCustomer.
274
+ READ ENTITIES OF ZI_Travel IN LOCAL MODE
275
+ ENTITY Travel FIELDS ( CustomerID ) WITH CORRESPONDING #( keys )
276
+ RESULT DATA(travels).
277
+ DATA customers TYPE SORTED TABLE OF /dmo/customer WITH UNIQUE KEY customer_id.
278
+ customers = CORRESPONDING #( travels DISCARDING DUPLICATES MAPPING customer_id = CustomerID ).
279
+ SELECT FROM /dmo/customer FIELDS customer_id
280
+ FOR ALL ENTRIES IN @customers WHERE customer_id = @customers-customer_id
281
+ INTO TABLE @DATA(valid).
282
+ LOOP AT travels INTO DATA(t).
283
+ APPEND VALUE #( %tky = t-%tky ) TO result.
284
+ IF t-CustomerID IS NOT INITIAL AND NOT line_exists( valid[ customer_id = t-CustomerID ] ).
285
+ APPEND VALUE #( %tky = t-%tky %state_area = 'VALIDATE_CUSTOMER'
286
+ %msg = NEW /dmo/cm_flight_messages( textid = /dmo/cm_flight_messages=>customer_unknown
287
+ customer_id = t-CustomerID severity = if_abap_behv_message=>severity-error )
288
+ %element-CustomerID = if_abap_behv=>mk-on ) TO reported-travel.
289
+ ENDIF.
290
+ ENDLOOP.
291
+ ENDMETHOD.
292
+
293
+ METHOD acceptTravel.
294
+ MODIFY ENTITIES OF ZI_Travel IN LOCAL MODE
295
+ ENTITY Travel UPDATE FIELDS ( OverallStatus )
296
+ WITH VALUE #( FOR key IN keys ( %tky = key-%tky OverallStatus = 'A' ) )
297
+ FAILED failed REPORTED reported.
298
+ READ ENTITIES OF ZI_Travel IN LOCAL MODE
299
+ ENTITY Travel ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(travels).
300
+ result = VALUE #( FOR t IN travels ( %tky = t-%tky %param = t ) ).
301
+ ENDMETHOD.
302
+
303
+ METHOD rejectTravel.
304
+ MODIFY ENTITIES OF ZI_Travel IN LOCAL MODE
305
+ ENTITY Travel UPDATE FIELDS ( OverallStatus )
306
+ WITH VALUE #( FOR key IN keys ( %tky = key-%tky OverallStatus = 'X' ) )
307
+ FAILED failed REPORTED reported.
308
+ READ ENTITIES OF ZI_Travel IN LOCAL MODE
309
+ ENTITY Travel ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(travels).
310
+ result = VALUE #( FOR t IN travels ( %tky = t-%tky %param = t ) ).
311
+ ENDMETHOD.
312
+
313
+ METHOD get_instance_features.
314
+ READ ENTITIES OF ZI_Travel IN LOCAL MODE
315
+ ENTITY Travel FIELDS ( OverallStatus ) WITH CORRESPONDING #( keys )
316
+ RESULT DATA(travels).
317
+ result = VALUE #( FOR t IN travels
318
+ ( %tky = t-%tky
319
+ %action-acceptTravel = COND #( WHEN t-OverallStatus = 'A'
320
+ THEN if_abap_behv=>fc-o-disabled ELSE if_abap_behv=>fc-o-enabled )
321
+ %action-rejectTravel = COND #( WHEN t-OverallStatus = 'X'
322
+ THEN if_abap_behv=>fc-o-disabled ELSE if_abap_behv=>fc-o-enabled ) ) ).
323
+ ENDMETHOD.
324
+
325
+ ENDCLASS.
326
+ ```
327
+
328
+ ## 6. CDS Projection — Root
329
+
330
+ ```abap
331
+ @AccessControl.authorizationCheck: #CHECK
332
+ @Metadata.allowExtensions: true
333
+ @Search.searchable: true
334
+ define root view entity ZC_Travel
335
+ provider contract transactional_query
336
+ as projection on ZI_Travel
337
+ {
338
+ key TravelID,
339
+ @Search.defaultSearchElement: true
340
+ AgencyID,
341
+ @Search.defaultSearchElement: true
342
+ CustomerID,
343
+ BeginDate,
344
+ EndDate,
345
+ @Semantics.amount.currencyCode: 'CurrencyCode'
346
+ BookingFee,
347
+ @Semantics.amount.currencyCode: 'CurrencyCode'
348
+ TotalPrice,
349
+ CurrencyCode,
350
+ @Search.defaultSearchElement: true
351
+ @Search.fuzzinessThreshold: 0.7
352
+ Description,
353
+ OverallStatus,
354
+ CreatedBy, CreatedAt, LastChangedBy, LastChangedAt, LocalLastChangedAt,
355
+ _Booking : redirected to composition child ZC_Booking,
356
+ _Agency, _Customer, _Currency
357
+ }
358
+ ```
359
+
360
+ ## 7. CDS Projection — Child
361
+
362
+ ```abap
363
+ @AccessControl.authorizationCheck: #CHECK
364
+ @Metadata.allowExtensions: true
365
+ define view entity ZC_Booking
366
+ as projection on ZI_Booking
367
+ {
368
+ key TravelID,
369
+ key BookingID,
370
+ BookingDate, CarrierID, ConnectionID, FlightDate,
371
+ @Semantics.amount.currencyCode: 'CurrencyCode'
372
+ FlightPrice,
373
+ CurrencyCode, BookingStatus, LocalLastChangedAt,
374
+ _Travel : redirected to parent ZC_Travel,
375
+ _Carrier, _Currency
376
+ }
377
+ ```
378
+
379
+ ## 8. Projection BDEF
380
+
381
+ ```abap
382
+ projection;
383
+ strict ( 2 );
384
+ use draft;
385
+
386
+ define behavior for ZC_Travel alias Travel
387
+ use etag
388
+ {
389
+ use create; use update; use delete;
390
+ use action Edit; use action Activate; use action Discard;
391
+ use action Resume; use action Prepare;
392
+ use action acceptTravel; use action rejectTravel;
393
+ use association _Booking { create; with draft; }
394
+ }
395
+
396
+ define behavior for ZC_Booking alias Booking
397
+ use etag
398
+ {
399
+ use update; use delete;
400
+ use association _Travel { with draft; }
401
+ }
402
+ ```
403
+
404
+ ## 9. Service Definition
405
+
406
+ ```abap
407
+ @EndUserText.label: 'Travel Service'
408
+ define service ZUI_TRAVEL {
409
+ expose ZC_Travel as Travel;
410
+ expose ZC_Booking as Booking;
411
+ expose /DMO/I_Agency as Agency;
412
+ expose /DMO/I_Customer as Customer;
413
+ expose /DMO/I_Carrier as Carrier;
414
+ expose I_Currency as Currency;
415
+ }
416
+ ```
417
+
418
+ ## 10. Service Binding
419
+
420
+ Tipo: OData V4 - UI. Service Definition: ZUI_TRAVEL. Publicar apos criar.
421
+
422
+ ## 11. Metadata Extension
423
+
424
+ ```abap
425
+ @Metadata.layer: #CORE
426
+ annotate entity ZC_Travel with
427
+ {
428
+ @UI.facet: [
429
+ { id: 'Travel', type: #IDENTIFICATION_REFERENCE, label: 'Travel', position: 10 },
430
+ { id: 'Booking', type: #LINEITEM_REFERENCE, label: 'Bookings', position: 20, targetElement: '_Booking' }
431
+ ]
432
+
433
+ @UI.hidden: true
434
+ TravelID;
435
+
436
+ @UI: { lineItem: [{ position: 10 }], selectionField: [{ position: 10 }], identification: [{ position: 10 }] }
437
+ AgencyID;
438
+
439
+ @UI: { lineItem: [{ position: 20 }], selectionField: [{ position: 20 }], identification: [{ position: 20 }] }
440
+ CustomerID;
441
+
442
+ @UI: { lineItem: [{ position: 30 }], identification: [{ position: 30 }] }
443
+ BeginDate;
444
+
445
+ @UI: { lineItem: [{ position: 40 }], identification: [{ position: 40 }] }
446
+ EndDate;
447
+
448
+ @UI.identification: [{ position: 50 }]
449
+ BookingFee;
450
+
451
+ @UI: { lineItem: [{ position: 50 }], identification: [{ position: 60 }] }
452
+ TotalPrice;
453
+
454
+ @UI: { lineItem: [{ position: 60 }], selectionField: [{ position: 30 }], identification: [{ position: 70 }] }
455
+ OverallStatus;
456
+
457
+ @UI: { lineItem: [{ position: 70 }], identification: [{ position: 80 }] }
458
+ Description;
459
+ }
460
+ ```
461
+
462
+ ## Ordem de criacao
463
+
464
+ 1. Tables (TABL) → 2. CDS Interface root+child (DDLS) → 3. BDEF Interface (BDEF) → 4. Handler Class (CLAS) → 5. CDS Projection root+child (DDLS) → 6. Projection BDEF (BDEF) → 7. Service Definition (SRVD) → 8. Service Binding (SRVB) → 9. Metadata Extension (DDLX)
465
+
466
+ Ativar em lotes: tabelas → CDS → BDEF → service.
467
+
468
+ ## Regras
469
+ - Root CDS usa `define root view entity` + `composition [0..*] of`
470
+ - Child CDS usa `association to parent`
471
+ - BDEF root: `lock master total etag`, child: `lock dependent by`
472
+ - Projection CDS: `provider contract transactional_query` (so na root)
473
+ - Projection CDS: `redirected to composition child` / `redirected to parent`
474
+ - Service Definition expoe projections (ZC_*), nunca interfaces (ZI_*)
475
+ - Service Definition expoe entidades de value help
476
+ - Todas as 5 draft actions devem ser expostas na projection BDEF
477
+
478
+ ## Anti-patterns
479
+ | Errado | Correto |
480
+ |--------|---------|
481
+ | Expor ZI_* no Service Definition | Expor ZC_* |
482
+ | Esquecer `with draft` na association | `association _Child { create; with draft; }` |
483
+ | UI annotations direto no CDS interface | `@Metadata.allowExtensions` + Metadata Extension separada |
484
+ | `lock master` no child | `lock dependent by _Root` |
485
+ | Esquecer `provider contract transactional_query` | Obrigatorio na root projection para Fiori |
486
+ | Nao expor entidade de value help | `expose /DMO/I_Agency as Agency;` |
@@ -0,0 +1,185 @@
1
+ # RAP Feature Control — dynamic field and action enablement
2
+
3
+ ## BDEF Declaration
4
+
5
+ ```abap
6
+ define behavior for ZI_Order alias Order
7
+ {
8
+ " Instance feature control — per-record dynamic enablement
9
+ action ( features : instance ) acceptOrder result [1] $self;
10
+ action ( features : instance ) rejectOrder result [1] $self;
11
+
12
+ " Field-level feature control
13
+ field ( features : instance ) Status, Description;
14
+
15
+ " Static operation feature control
16
+ create ( features : global );
17
+ update;
18
+ delete;
19
+ }
20
+ ```
21
+
22
+ ## Instance Features — Handler Method
23
+
24
+ ```abap
25
+ CLASS lhc_order DEFINITION INHERITING FROM cl_abap_behavior_handler.
26
+ PRIVATE SECTION.
27
+ METHODS get_instance_features FOR INSTANCE FEATURES
28
+ IMPORTING keys REQUEST requested_features FOR Order RESULT result.
29
+ ENDCLASS.
30
+
31
+ CLASS lhc_order IMPLEMENTATION.
32
+ METHOD get_instance_features.
33
+ READ ENTITIES OF ZI_Order IN LOCAL MODE
34
+ ENTITY Order FIELDS ( Status ) WITH CORRESPONDING #( keys )
35
+ RESULT DATA(orders).
36
+
37
+ result = VALUE #( FOR order IN orders
38
+ ( %tky = order-%tky
39
+
40
+ " Action control
41
+ %action-acceptOrder = COND #(
42
+ WHEN order-Status = 'A' " Already accepted
43
+ THEN if_abap_behv=>fc-o-disabled
44
+ ELSE if_abap_behv=>fc-o-enabled )
45
+
46
+ %action-rejectOrder = COND #(
47
+ WHEN order-Status = 'X' " Already rejected
48
+ THEN if_abap_behv=>fc-o-disabled
49
+ ELSE if_abap_behv=>fc-o-enabled )
50
+
51
+ " Field control
52
+ %field-Status = COND #(
53
+ WHEN order-Status = 'A' OR order-Status = 'X'
54
+ THEN if_abap_behv=>fc-f-read_only
55
+ ELSE if_abap_behv=>fc-f-mandatory )
56
+
57
+ %field-Description = if_abap_behv=>fc-f-unrestricted
58
+
59
+ " Standard operation control
60
+ %update = COND #(
61
+ WHEN order-Status = 'A'
62
+ THEN if_abap_behv=>fc-o-disabled
63
+ ELSE if_abap_behv=>fc-o-enabled )
64
+
65
+ %delete = COND #(
66
+ WHEN order-Status = 'A'
67
+ THEN if_abap_behv=>fc-o-disabled
68
+ ELSE if_abap_behv=>fc-o-enabled )
69
+ ) ).
70
+ ENDMETHOD.
71
+ ENDCLASS.
72
+ ```
73
+
74
+ ## Feature Control Constants
75
+
76
+ ### Operations (actions, create, update, delete)
77
+
78
+ | Constant | Value | Effect |
79
+ |----------|:-----:|--------|
80
+ | `if_abap_behv=>fc-o-enabled` | 01 | Action/operation available |
81
+ | `if_abap_behv=>fc-o-disabled` | 00 | Action/operation greyed out |
82
+
83
+ ### Fields
84
+
85
+ | Constant | Value | Effect |
86
+ |----------|:-----:|--------|
87
+ | `if_abap_behv=>fc-f-unrestricted` | 01 | Editable (default) |
88
+ | `if_abap_behv=>fc-f-read_only` | 02 | Read-only |
89
+ | `if_abap_behv=>fc-f-mandatory` | 03 | Mandatory (required) |
90
+ | `if_abap_behv=>fc-f-unrestricted_or_hidden` | 04 | Hidden or editable |
91
+
92
+ ## Global Features — Static Operation Control
93
+
94
+ ```abap
95
+ " BDEF:
96
+ create ( features : global );
97
+
98
+ " Handler:
99
+ METHODS get_global_features FOR GLOBAL FEATURES
100
+ IMPORTING REQUEST requested_features FOR Order RESULT result.
101
+
102
+ METHOD get_global_features.
103
+ " Example: disable create outside business hours
104
+ DATA(lv_hour) = CONV i( sy-uzeit(2) ).
105
+ result = VALUE #(
106
+ %create = COND #(
107
+ WHEN lv_hour < 8 OR lv_hour > 18
108
+ THEN if_abap_behv=>fc-o-disabled
109
+ ELSE if_abap_behv=>fc-o-enabled ) ).
110
+ ENDMETHOD.
111
+ ```
112
+
113
+ ## Combining with Side Effects
114
+
115
+ ```abap
116
+ " BDEF — refresh feature control when status changes
117
+ side effects {
118
+ field Status affects action acceptOrder, action rejectOrder;
119
+ }
120
+ ```
121
+
122
+ When `Status` changes, Fiori recalculates `get_instance_features` → buttons enable/disable dynamically.
123
+
124
+ ## Complex Example — Multi-field, Multi-action
125
+
126
+ ```abap
127
+ METHOD get_instance_features.
128
+ READ ENTITIES OF ZI_Travel IN LOCAL MODE
129
+ ENTITY Travel FIELDS ( OverallStatus BeginDate )
130
+ WITH CORRESPONDING #( keys )
131
+ RESULT DATA(travels).
132
+
133
+ result = VALUE #( FOR t IN travels
134
+ LET is_accepted = xsdbool( t-OverallStatus = 'A' )
135
+ is_rejected = xsdbool( t-OverallStatus = 'X' )
136
+ is_open = xsdbool( t-OverallStatus = 'O' )
137
+ is_past = xsdbool( t-BeginDate < sy-datum )
138
+ IN
139
+ ( %tky = t-%tky
140
+
141
+ %action-acceptTravel = COND #(
142
+ WHEN is_accepted = abap_true OR is_past = abap_true
143
+ THEN if_abap_behv=>fc-o-disabled ELSE if_abap_behv=>fc-o-enabled )
144
+
145
+ %action-rejectTravel = COND #(
146
+ WHEN is_rejected = abap_true
147
+ THEN if_abap_behv=>fc-o-disabled ELSE if_abap_behv=>fc-o-enabled )
148
+
149
+ %update = COND #(
150
+ WHEN is_accepted = abap_true
151
+ THEN if_abap_behv=>fc-o-disabled ELSE if_abap_behv=>fc-o-enabled )
152
+
153
+ %delete = COND #(
154
+ WHEN is_accepted = abap_true OR is_open = abap_false
155
+ THEN if_abap_behv=>fc-o-disabled ELSE if_abap_behv=>fc-o-enabled )
156
+
157
+ %field-OverallStatus = if_abap_behv=>fc-f-read_only
158
+ %field-BeginDate = COND #(
159
+ WHEN is_accepted = abap_true
160
+ THEN if_abap_behv=>fc-f-read_only ELSE if_abap_behv=>fc-f-mandatory )
161
+ %field-EndDate = COND #(
162
+ WHEN is_accepted = abap_true
163
+ THEN if_abap_behv=>fc-f-read_only ELSE if_abap_behv=>fc-f-unrestricted )
164
+ ) ).
165
+ ENDMETHOD.
166
+ ```
167
+
168
+ ## Rules
169
+ - `( features : instance )` on action/field in BDEF enables instance-level control
170
+ - `( features : global )` on operation enables class-level control (no per-record logic)
171
+ - Handler method name is always `get_instance_features` / `get_global_features`
172
+ - READ ENTITIES with IN LOCAL MODE to avoid authorization loops
173
+ - Use LET in VALUE expressions for cleaner multi-condition logic
174
+ - Combine with `side effects { field X affects action Y }` for dynamic UI refresh
175
+ - `%field-X` only works if field declared with `field ( features : instance )` in BDEF
176
+
177
+ ## Anti-Patterns
178
+ | Anti-Pattern | Correct |
179
+ |---|---|
180
+ | `field ( readonly ) Status` when control should be dynamic | `field ( features : instance ) Status` |
181
+ | Feature control without IN LOCAL MODE | Always use IN LOCAL MODE in handler |
182
+ | Hardcoded `if_abap_behv=>fc-o-disabled` for all records | Check per-record state |
183
+ | Missing side effect for status field | `field Status affects action X` for UI refresh |
184
+ | `get_instance_features` without reading entity data | Always READ ENTITIES first |
185
+ | Complex IF/ELSEIF chains | Use COND with LET for readability |