/
zrefactor_v3.prog.abap
332 lines (250 loc) · 8.53 KB
/
zrefactor_v3.prog.abap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
*&---------------------------------------------------------------------*
*& Report zrefactor_v3
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zrefactor_v3 LINE-SIZE 90.
TYPES: BEGIN OF lty_product,
id TYPE c LENGTH 5,
description TYPE c LENGTH 30,
quantity TYPE n LENGTH 3,
unit_price TYPE p LENGTH 5 DECIMALS 2,
END OF lty_product.
INTERFACE output_generator DEFERRED.
CLASS product DEFINITION DEFERRED.
TYPES items_table TYPE TABLE OF REF TO product.
CLASS product DEFINITION.
PUBLIC SECTION.
METHODS constructor IMPORTING imc_product TYPE lty_product.
METHODS set IMPORTING im_product TYPE lty_product.
METHODS get RETURNING VALUE(re_product) TYPE lty_product.
METHODS get_value RETURNING VALUE(re_value) TYPE zcalc_result.
PRIVATE SECTION.
DATA: product TYPE lty_product.
ENDCLASS.
CLASS product IMPLEMENTATION.
METHOD constructor.
me->set( imc_product ).
ENDMETHOD.
METHOD set.
me->product = im_product.
ENDMETHOD.
METHOD get.
re_product = me->product.
ENDMETHOD.
METHOD get_value.
re_value = me->product-unit_price * me->product-quantity.
ENDMETHOD.
ENDCLASS.
CLASS test_product DEFINITION FOR TESTING RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA test_product TYPE REF TO product.
METHODS product_total FOR TESTING.
ENDCLASS.
CLASS test_product IMPLEMENTATION.
METHOD product_total.
DATA product_data TYPE lty_product.
product_data-id = '025'.
product_data-description = 'Cellphone 3000'.
product_data-quantity = 3.
product_data-unit_price = 1400.
CREATE OBJECT me->test_product EXPORTING imc_product = product_data.
DATA(product_value) = me->test_product->get_value( ).
cl_abap_unit_assert=>assert_equals( act = product_value exp = 4200 ).
ENDMETHOD.
ENDCLASS.
CLASS purchase_order DEFINITION.
PUBLIC SECTION.
METHODS constructor IMPORTING ponum TYPE zpoheader-ponum.
METHODS get_po_number RETURNING VALUE(po_number) TYPE zpoheader-ponum.
METHODS add_item IMPORTING im_item TYPE REF TO product
RAISING zcx_price_zeroless.
METHODS get_po_total RETURNING VALUE(re_total) TYPE lty_product-unit_price.
METHODS get_items EXPORTING items_list TYPE items_table.
PRIVATE SECTION.
DATA po_number TYPE zpoheader-ponum.
DATA items_list TYPE items_table.
DATA display_generator TYPE REF TO output_generator.
ENDCLASS.
CLASS purchase_order IMPLEMENTATION.
METHOD constructor.
po_number = ponum.
ENDMETHOD.
METHOD get_po_number.
po_number = me->po_number.
ENDMETHOD.
METHOD add_item.
DATA(product_data) = im_item->get( ).
IF product_data-unit_price GT 0.
APPEND im_item TO items_list.
ELSE.
RAISE EXCEPTION TYPE zcx_price_zeroless.
ENDIF.
ENDMETHOD.
METHOD get_po_total.
DATA: r_product TYPE REF TO product,
wa_product TYPE lty_product,
vg_total TYPE lty_product-unit_price.
LOOP AT items_list INTO r_product.
wa_product = r_product->get( ).
vg_total = wa_product-unit_price * wa_product-quantity.
ADD vg_total TO re_total.
ENDLOOP.
ENDMETHOD.
METHOD get_items.
items_list = me->items_list.
ENDMETHOD.
ENDCLASS.
CLASS test_purchase_order DEFINITION FOR TESTING RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA test_purchase_order TYPE REF TO purchase_order.
METHODS setup.
METHODS return_total_po FOR TESTING.
METHODS should_not_have_price_zeroless FOR TESTING.
ENDCLASS.
CLASS test_purchase_order IMPLEMENTATION.
METHOD setup.
CREATE OBJECT me->test_purchase_order EXPORTING ponum = '00000'.
ENDMETHOD.
METHOD return_total_po.
DATA product_data TYPE lty_product.
DATA test_product TYPE REF TO product.
product_data-id = '025'.
product_data-description = 'Cellphone 3000'.
product_data-quantity = 3.
product_data-unit_price = 1400.
CREATE OBJECT test_product
EXPORTING
imc_product = product_data.
me->test_purchase_order->add_item( test_product ).
product_data-id = '984'.
product_data-description = 'TV 40pol'.
product_data-quantity = 6.
product_data-unit_price = 3400.
CREATE OBJECT test_product
EXPORTING
imc_product = product_data.
me->test_purchase_order->add_item( test_product ).
product_data-id = '758'.
product_data-description = 'Audio System 439'.
product_data-quantity = 2.
product_data-unit_price = 7800.
CREATE OBJECT test_product
EXPORTING
imc_product = product_data.
me->test_purchase_order->add_item( test_product ).
DATA(po_total) = me->test_purchase_order->get_po_total( ).
cl_abap_unit_assert=>assert_equals( act = po_total exp = 40200 ).
ENDMETHOD.
METHOD should_not_have_price_zeroless.
DATA product_data TYPE lty_product.
DATA test_product TYPE REF TO product.
DATA test_exception TYPE REF TO cx_static_check.
product_data-id = '025'.
product_data-description = 'Cellphone 3000'.
product_data-quantity = 3.
product_data-unit_price = 0.
CREATE OBJECT test_product
EXPORTING
imc_product = product_data.
TRY.
me->test_purchase_order->add_item( test_product ).
CATCH zcx_price_zeroless INTO test_exception.
ENDTRY.
cl_abap_unit_assert=>assert_bound( act = test_exception ).
ENDMETHOD.
ENDCLASS.
INTERFACE data_loader.
METHODS load_data IMPORTING load_po TYPE REF TO purchase_order
RAISING zcx_po_not_exists.
ENDINTERFACE.
CLASS products_loader_db DEFINITION.
PUBLIC SECTION.
INTERFACES data_loader.
ENDCLASS.
CLASS products_loader_db IMPLEMENTATION.
METHOD data_loader~load_data.
DATA poheader TYPE zpoheader.
DATA poitems TYPE TABLE OF zpoitems.
FIELD-SYMBOLS <poitem> TYPE zpoitems.
DATA(po_number) = load_po->get_po_number( ).
SELECT SINGLE * FROM zpoheader INTO poheader WHERE ponum = po_number.
IF sy-subrc NE 0.
RAISE EXCEPTION TYPE zcx_po_not_exists.
ENDIF.
SELECT * FROM zpoitems INTO TABLE poitems WHERE ponum = po_number.
IF sy-subrc NE 0.
RAISE EXCEPTION TYPE zcx_po_not_exists.
ENDIF.
LOOP AT poitems ASSIGNING <poitem>.
DATA product_data TYPE lty_product.
DATA add_product TYPE REF TO product.
product_data-id = <poitem>-product_id.
SELECT SINGLE description FROM zproducts
INTO product_data-description
WHERE id = <poitem>-product_id.
product_data-quantity = <poitem>-quantity.
product_data-unit_price = <poitem>-unit_price.
CREATE OBJECT add_product
EXPORTING
imc_product = product_data.
load_po->add_item( add_product ).
clear product_data.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
INTERFACE output_generator.
METHODS generate IMPORTING po_object TYPE REF TO purchase_order.
ENDINTERFACE.
CLASS report_list DEFINITION.
PUBLIC SECTION.
INTERFACES output_generator.
ENDCLASS.
CLASS report_list IMPLEMENTATION.
METHOD output_generator~generate.
DATA: r_product TYPE REF TO product,
wa_product TYPE lty_product,
vg_total TYPE lty_product-unit_price,
vg_total_p TYPE lty_product-unit_price.
DATA items_list TYPE items_table.
po_object->get_items( IMPORTING items_list = items_list ).
LOOP AT items_list INTO r_product.
AT FIRST.
FORMAT COLOR COL_HEADING.
WRITE: /1 'ID',
5 'Description',
30 'Quant.',
60 'Unit Price',
80 'Total'.
FORMAT COLOR OFF.
ULINE.
ENDAT.
wa_product = r_product->get( ).
WRITE: /1 wa_product-id,
5 wa_product-description,
30 wa_product-quantity,
60 wa_product-unit_price,
80 r_product->get_value( ).
AT LAST.
ULINE.
FORMAT COLOR 7.
WRITE: / 'Total of Purchase Order --> ', po_object->get_po_total( ).
ENDAT.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
DATA: r_product TYPE REF TO product,
r_pur_ord TYPE REF TO purchase_order,
wa_product TYPE lty_product.
START-OF-SELECTION.
CREATE OBJECT r_pur_ord EXPORTING ponum = '00001'.
DATA db_po_loader TYPE REF TO data_loader.
db_po_loader = NEW products_loader_db( ).
TRY.
db_po_loader->load_data( r_pur_ord ).
CATCH zcx_po_not_exists.
MESSAGE 'PO does not exist.' TYPE 'E'.
ENDTRY.
DATA out_display TYPE REF TO output_generator.
out_display = NEW report_list( ) .
out_display->generate( r_pur_ord ).