@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.
- package/README.md +384 -0
- package/dist/adt-client.js +364 -0
- package/dist/cli/activate.js +113 -0
- package/dist/cli/init.js +333 -0
- package/dist/cli/remove.js +80 -0
- package/dist/cli/status.js +229 -0
- package/dist/cli/systems.js +68 -0
- package/dist/cli.js +81 -0
- package/dist/index.js +1318 -0
- package/dist/knowledge/abap/abap-dictionary.md +199 -0
- package/dist/knowledge/abap/abap-sql.md +296 -0
- package/dist/knowledge/abap/amdp.md +273 -0
- package/dist/knowledge/abap/clean-code.md +293 -0
- package/dist/knowledge/abap/cloud-background-processing.md +250 -0
- package/dist/knowledge/abap/cloud-communication.md +265 -0
- package/dist/knowledge/abap/cloud-development.md +176 -0
- package/dist/knowledge/abap/cloud-extensibility.md +252 -0
- package/dist/knowledge/abap/cloud-released-apis.md +261 -0
- package/dist/knowledge/abap/constructor-expressions.md +289 -0
- package/dist/knowledge/abap/enhancements.md +232 -0
- package/dist/knowledge/abap/exceptions.md +271 -0
- package/dist/knowledge/abap/internal-tables.md +205 -0
- package/dist/knowledge/abap/object-orientation.md +298 -0
- package/dist/knowledge/abap/performance.md +216 -0
- package/dist/knowledge/abap/rap-abstract-entities.md +206 -0
- package/dist/knowledge/abap/rap-business-events.md +216 -0
- package/dist/knowledge/abap/rap-draft.md +191 -0
- package/dist/knowledge/abap/rap-eml.md +453 -0
- package/dist/knowledge/abap/rap-end-to-end.md +486 -0
- package/dist/knowledge/abap/rap-feature-control.md +185 -0
- package/dist/knowledge/abap/rap-numbering.md +280 -0
- package/dist/knowledge/abap/rap-service-exposure.md +163 -0
- package/dist/knowledge/abap/rap-unmanaged.md +468 -0
- package/dist/knowledge/abap/string-processing.md +180 -0
- package/dist/knowledge/abap/unit-testing.md +303 -0
- package/dist/knowledge/abap-cds/access-control.md +241 -0
- package/dist/knowledge/abap-cds/annotations.md +331 -0
- package/dist/knowledge/abap-cds/associations.md +254 -0
- package/dist/knowledge/abap-cds/expressions.md +230 -0
- package/dist/knowledge/abap-cds/functions.md +245 -0
- package/dist/knowledge/abap-cds/metadata-extensions.md +294 -0
- package/dist/knowledge/cap/authentication.md +278 -0
- package/dist/knowledge/cap/cdl-syntax.md +247 -0
- package/dist/knowledge/cap/cql-queries.md +266 -0
- package/dist/knowledge/cap/deployment.md +343 -0
- package/dist/knowledge/cap/event-handlers.md +287 -0
- package/dist/knowledge/cap/fiori-integration.md +303 -0
- package/dist/knowledge/cap/service-definitions.md +287 -0
- package/dist/knowledge/fiori/annotations.md +347 -0
- package/dist/knowledge/fiori/deployment.md +340 -0
- package/dist/knowledge/fiori/fiori-elements.md +332 -0
- package/dist/knowledge/fiori/fiori-side-effects.md +107 -0
- package/dist/knowledge/fiori/fiori-valuelist.md +144 -0
- package/dist/knowledge/fiori/ui5-controllers.md +358 -0
- package/dist/knowledge/fiori/ui5-data-binding.md +311 -0
- package/dist/knowledge/fiori/ui5-fragments-dialogs.md +330 -0
- package/dist/knowledge/fiori/ui5-manifest.md +411 -0
- package/dist/knowledge/fiori/ui5-routing.md +303 -0
- package/dist/knowledge/fiori/ui5-xml-views.md +294 -0
- package/dist/logger.js +114 -0
- package/dist/system-profile.js +207 -0
- package/dist/tools/abap-doc.js +72 -0
- package/dist/tools/abapgit.js +161 -0
- package/dist/tools/activate.js +68 -0
- package/dist/tools/atc-check.js +117 -0
- package/dist/tools/auth-object.js +56 -0
- package/dist/tools/breakpoints.js +76 -0
- package/dist/tools/call-hierarchy.js +84 -0
- package/dist/tools/cds-annotations.js +98 -0
- package/dist/tools/cds-dependencies.js +65 -0
- package/dist/tools/check.js +47 -0
- package/dist/tools/code-completion.js +70 -0
- package/dist/tools/code-coverage.js +111 -0
- package/dist/tools/create-amdp.js +111 -0
- package/dist/tools/create-dcl.js +81 -0
- package/dist/tools/create-transport.js +38 -0
- package/dist/tools/create.js +285 -0
- package/dist/tools/data-preview.js +37 -0
- package/dist/tools/delete.js +45 -0
- package/dist/tools/deploy-bsp.js +298 -0
- package/dist/tools/discovery.js +59 -0
- package/dist/tools/element-info.js +93 -0
- package/dist/tools/enhancements.js +186 -0
- package/dist/tools/extract-method.js +44 -0
- package/dist/tools/function-group.js +59 -0
- package/dist/tools/knowledge.js +275 -0
- package/dist/tools/lock-object.js +75 -0
- package/dist/tools/message-class.js +67 -0
- package/dist/tools/navigate.js +80 -0
- package/dist/tools/number-range.js +57 -0
- package/dist/tools/object-documentation.js +43 -0
- package/dist/tools/object-structure.js +78 -0
- package/dist/tools/object-versions.js +57 -0
- package/dist/tools/package-contents.js +60 -0
- package/dist/tools/pretty-printer.js +35 -0
- package/dist/tools/publish-binding.js +49 -0
- package/dist/tools/quick-fix.js +69 -0
- package/dist/tools/read.js +167 -0
- package/dist/tools/refactor-rename.js +60 -0
- package/dist/tools/release-transport.js +24 -0
- package/dist/tools/released-apis.js +51 -0
- package/dist/tools/repository-tree.js +90 -0
- package/dist/tools/scaffold-rap.js +642 -0
- package/dist/tools/search.js +73 -0
- package/dist/tools/shared/data-format.js +101 -0
- package/dist/tools/sql-console.js +17 -0
- package/dist/tools/system-info.js +270 -0
- package/dist/tools/traces.js +66 -0
- package/dist/tools/transport-contents.js +83 -0
- package/dist/tools/transports.js +67 -0
- package/dist/tools/unit-test.js +135 -0
- package/dist/tools/where-used.js +59 -0
- package/dist/tools/write.js +101 -0
- 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 |
|