@EndUserText.label: '航班管理 - 根实体' @AccessControl.authorizationCheck: #CHECK define root view entity ZR_Flight as select from sflight
association [0..1] to ZI_Carrier as _Carrier on $projection.Carrid = _Carrier.Carrid
{ key carrid as Carrid, key connid as Connid, key fldate as Fldate, @Semantics.amount.currencyCode: 'Currency' price as Price, @Semantics.currencyCode: true currency as Currency, seatsmax as Seatsmax, seatsocc as Seatsocc, " 关联 _Carrier }
9.3 Composition(组合关系)
" 根实体:采购订单抬头 define root view entity ZR_PurchaseOrder composition [0..*] of ZR_PurchaseOrderItem as _Items { key po_number as PoNumber, vendor as Vendor, total_amount as TotalAmount, status as Status, _Items " 行项目(一对多组合) }
" 子实体:采购订单行项目 define view entity ZR_PurchaseOrderItem as select from zpo_item_table association to parent ZR_PurchaseOrder as _Header on $projection.PoNumber = _Header.PoNumber { key po_number as PoNumber, key item_number as ItemNumber, material as Material, quantity as Quantity, _Header " 指向父实体 }
{ " CRUD操作 create; " 允许创建 update; " 允许更新 delete; " 允许删除 " 自定义操作 action Approve result [1] $self; " 审批操作 " 自动计算(创建时自动触发) determination setDefaultValues on modify { create; } " 校验(保存前自动触发) validation checkPrice on save { field Price; } " 字段级控制 field (readonly) Carrid, Connid; " 主键只读 field (mandatory) Price; " 价格必填 }
10.2 Determination(自动计算)
" 在Behavior Definition中声明 determination calculateTotal on modify { create, update; field Quantity, UnitPrice; } determination setCreatedAt on modify { create; }
" 在Behavior Implementation中实现 METHOD calculateTotal. " 读取当前实体数据 READ ENTITIES OF zr_purchaseorder IN LOCAL MODE ENTITY PurchaseOrder FIELDS ( Quantity UnitPrice TotalAmount ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_orders).
LOOP AT lt_orders INTO DATA(ls_order). " 计算总金额 DATA(lv_total) = ls_order-Quantity * ls_order-UnitPrice. " 回写 MODIFY ENTITIES OF zr_purchaseorder IN LOCAL MODE ENTITY PurchaseOrder UPDATE FIELDS ( TotalAmount ) WITH VALUE #( FOR order IN lt_orders ( %tky = order-%tky TotalAmount = lv_total ) ) REPORTED DATA(lt_reported). ENDLOOP. ENDMETHOD.
10.3 Validation(校验)
" Behavior Definition中声明 validation checkPrice on save { field Price; }
" Behavior Implementation中实现 METHOD checkPrice. READ ENTITIES OF zr_flight IN LOCAL MODE ENTITY Flight FIELDS ( Price Currency ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_flights).
LOOP AT lt_flights INTO DATA(ls_flight). IF ls_flight-Price < 0. " 报错 APPEND VALUE #( %tky = ls_flight-%tky ) TO failed-flight. APPEND VALUE #( %tky = ls_flight-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = '价格不能为负数' ) %element-Price = if_abap_behv=>mk-on ) TO reported-flight. ENDIF. ENDLOOP. ENDMETHOD.
10.4 Action(自定义操作)
" 声明 action Approve result [1] $self;
" 实现 METHOD Approve. READ ENTITIES OF zr_flight IN LOCAL MODE ENTITY Flight ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(lt_flights).
LOOP AT lt_flights INTO DATA(ls_flight). " 更新状态 MODIFY ENTITIES OF zr_flight IN LOCAL MODE ENTITY Flight UPDATE FIELDS ( Status ) WITH VALUE #( ( %tky = ls_flight-%tky Status = 'APPROVED' ) ) MAPPED DATA(lt_mapped). ENDLOOP.
" 返回结果 result = VALUE #( FOR flight IN lt_flights ( %tky = flight-%tky %param = flight ) ). ENDMETHOD.
@EndUserText.label: '员工管理 - 根实体' @AccessControl.authorizationCheck: #CHECK define root view entity ZR_Employee composition [0..*] of ZR_EmployeeSkill as _Skills association [0..1] to ZI_Department as _Dept on $projection.Department = _Dept.DeptId
{ key emp_id as EmpId, emp_name as EmpName, department as Department, position as Position, @Semantics.amount.currencyCode: 'Currency' salary as Salary, @Semantics.currencyCode: true currency as Currency, hire_date as HireDate, status as Status, created_at as CreatedAt, last_changed_at as LastChangedAt, _Skills, _Dept }
@EndUserText.label: '员工技能 - 子实体' define view entity ZR_EmployeeSkill as select from zemp_skill association to parent ZR_Employee as _Employee on $projection.EmpId = _Employee.EmpId
{ key emp_id as EmpId, key skill_id as SkillId, skill_name as SkillName, skill_level as SkillLevel, " 1-5 certified as Certified, _Employee }
步骤3:创建行为定义
managed implementation in class ZBP_R_Employee unique;
define behavior for ZR_Employee alias Employee persistent table zemployee draft table zemployee_dra etag master last_changed_at { create; update; delete; action Promote result [1] $self; action Terminate result [1] $self; determination setDefaults on modify { create; } determination updateStatus on modify { field Status; } validation checkSalary on save { field Salary; } validation checkHireDate on save { field HireDate; } field (readonly) EmpId, CreatedAt, LastChangedAt; field (mandatory) EmpName, Department, HireDate; " 行项目 association _Skills { create; } }
define behavior for ZR_EmployeeSkill alias Skill persistent table zemp_skill draft table zemp_skill_dra { update; delete; field (readonly) EmpId, SkillId; field (mandatory) SkillName; validation checkLevel on save { field SkillLevel; } association _Employee; }
步骤4:创建行为实现类
CLASS zbp_r_employee DEFINITION PUBLIC ABSTRACT FINAL FOR BEHAVIOR OF zr_employee. ENDCLASS.
CLASS zbp_r_employee IMPLEMENTATION. METHOD setDefaults. " 新建员工默认状态为试用期 MODIFY ENTITIES OF zr_employee IN LOCAL MODE ENTITY Employee UPDATE FIELDS ( Status CreatedAt ) WITH VALUE #( FOR key IN keys ( %tky = key-%tky Status = 'P' CreatedAt = utclong_current( ) ) ). ENDMETHOD.
METHOD checkSalary. READ ENTITIES OF zr_employee IN LOCAL MODE ENTITY Employee FIELDS ( Salary ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_employees).
LOOP AT lt_employees INTO DATA(ls_emp). IF ls_emp-Salary < 0. APPEND VALUE #( %tky = ls_emp-%tky ) TO failed-employee. APPEND VALUE #( %tky = ls_emp-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = '薪资不能为负数' ) %element-Salary = if_abap_behv=>mk-on ) TO reported-employee. ENDIF. ENDLOOP. ENDMETHOD.
METHOD checkHireDate. READ ENTITIES OF zr_employee IN LOCAL MODE ENTITY Employee FIELDS ( HireDate ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_employees).
LOOP AT lt_employees INTO DATA(ls_emp). IF ls_emp-HireDate > cl_abap_context_info=>get_system_date( ). APPEND VALUE #( %tky = ls_emp-%tky ) TO failed-employee. APPEND VALUE #( %tky = ls_emp-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = '入职日期不能晚于今天' ) %element-HireDate = if_abap_behv=>mk-on ) TO reported-employee. ENDIF. ENDLOOP. ENDMETHOD.
METHOD Promote. " 提升: 试用期→在职 READ ENTITIES OF zr_employee IN LOCAL MODE ENTITY Employee ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(lt_employees).
MODIFY ENTITIES OF zr_employee IN LOCAL MODE ENTITY Employee UPDATE FIELDS ( Status ) WITH VALUE #( FOR emp IN lt_employees WHERE ( Status = 'P' ) ( %tky = emp-%tky Status = 'A' ) ).
result = VALUE #( FOR emp IN lt_employees ( %tky = emp-%tky %param = CORRESPONDING #( emp ) ) ). ENDMETHOD.
METHOD Terminate. " 离职 READ ENTITIES OF zr_employee IN LOCAL MODE ENTITY Employee ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(lt_employees).
MODIFY ENTITIES OF zr_employee IN LOCAL MODE ENTITY Employee UPDATE FIELDS ( Status ) WITH VALUE #( FOR emp IN lt_employees ( %tky = emp-%tky Status = 'I' ) ).
result = VALUE #( FOR emp IN lt_employees ( %tky = emp-%tky %param = CORRESPONDING #( emp ) ) ). ENDMETHOD.
" 1. 数据模型 define root view entity ZR_PurchaseRequest composition [0..*] of ZR_PRItem as _Items { key pr_number as PrNumber, description as Description, requester as Requester, request_date as RequestDate, total_amount as TotalAmount, currency as Currency, status as Status, " NEW/APPROVED/REJECTED approved_by as ApprovedBy, approved_at as ApprovedAt, _Items }
" 2. 行为定义 define behavior for ZR_PurchaseRequest alias PR { create; update; delete; action Approve result [1] $self; action Reject result [1] $self; determination setStatus on modify { create; } validation checkAmount on save { field TotalAmount; } field (readonly) PrNumber, Status, ApprovedBy, ApprovedAt; field (readonly) TotalAmount; " 自动计算 }