Sales Order Output

Print Program for sales order output

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:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
413:
414:
415:
416:
417:
418:
419:
420:
421:
422:
423:
424:
425:
426:
427:
428:
429:
430:
431:
432:
433:
434:
435:
436:
437:
438:
439:
440:
441:
442:
443:
444:
445:
446:
447:
448:
449:
450:
451:
452:
453:
454:
455:
456:
457:
458:
459:
460:
461:
462:
463:
464:
465:
466:
467:
468:
469:
470:
471:
472:
473:
474:
475:
476:
477:
478:
479:
480:
481:
482:
483:
484:
485:
486:
487:
488:
489:
490:
491:
492:
493:
494:
495:
496:
497:
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508:
509:
510:
511:
512:
513:
514:
515:
516:
517:
518:
519:
520:
521:
522:
523:
524:
525:
526:
527:
528:
529:
530:
531:
532:
533:
534:
535:
536:
537:
538:
539:
540:
541:
542:
543:
544:
545:
546:
547:
548:
549:
550:
551:
552:
553:
554:
555:
556:
557:
558:
559:
560:
561:
562:
563:
564:
565:
566:
567:
568:
569:
570:
571:
572:
573:
574:
575:
576:
577:
578:
579:
580:
581:
582:
583:
584:
585:
586:
587:
588:
589:
590:
591:
592:
593:
594:
595:
596:
597:
598:
599:
600:
601:
602:
603:
604:
605:
606:
607:
608:
609:
610:
611:
612:
613:
614:
615:
616:
617:
618:
619:
620:
621:
622:
623:
624:
625:
626:
627:
628:
629:
630:
631:
632:
633:
634:
635:
636:
637:
638:
639:
640:
641:
642:
643:
644:
645:
646:
647:
648:
649:
650:
651:
652:
653:
654:
655:
656:
657:
658:
659:
660:
661:
662:
663:
664:
665:
666:
667:
668:
669:
670:
671:
672:
673:
674:
675:
676:
677:
678:
679:
680:
681:
682:
683:
684:
685:
686:
687:
688:
689:
690:
691:
692:
693:
694:
695:
696:
697:
698:
699:
700:
701:
702:
703:
704:
705:
706:
707:
708:
709:
710:
711:
712:
713:
714:
715:
716:
717:
718:
719:
720:
721:
722:
723:
724:
725:
726:
727:
728:
729:
730:
731:
732:
733:
734:
735:
736:
737:
738:
739:
740:
741:
742:
743:
744:
745:
746:
747:
748:
749:
750:
751:
752:
753:
754:
755:
756:
757:
758:
759:
760:
761:
762:
763:
764:
765:
766:
767:
768:
769:
770:
771:
772:
773:
774:
775:
776:
777:
778:
779:
780:
781:
782:
783:
784:
785:
786:
787:
788:
789:
790:
791:
792:
793:
794:
795:
796:
797:
798:
799:
800:
801:
802:
803:
804:
805:
806:
807:
808:
809:
810:
811:
812:
813:
814:
815:
816:
817:
818:
819:
820:
821:
822:
823:
824:
825:
826:
827:
828:
829:
830:
831:
832:
833:
834:
835:
836:
837:
838:
839:
840:
841:
842:
843:
844:
845:
846:
847:
848:
849:
850:
851:
852:
853:
854:
855:
856:
857:
858:
859:
860:
861:
862:
863:
864:
865:
866:
867:
868:
869:
870:
871:
872:
873:
874:
875:
876:
877:
878:
879:
880:
881:
882:
883:
884:
885:
886:
887:
888:
889:
890:
891:
892:
893:
894:
895:
896:
897:
898:
899:
900:
901:
902:
903:
904:
905:
906:
907:
908:
909:
910:
911:
912:
913:
914:
915:
916:
917:
918:
919:
920:
921:
922:
923:
924:
925:
926:
927:
928:
929:
930:
931:
932:
933:
934:
935:
936:
937:
938:
939:
940:
941:
942:
943:
944:
945:
946:
947:
948:
949:
950:
951:
952:
953:
954:
955:
956:
957:
958:
959:
960:
961:
962:
963:
964:
965:
966:
967:
968:
969:
970:
971:
972:
973:
974:
975:
976:
977:
978:
979:
980:
981:
982:
983:
984:
985:
986:
987:
988:
989:
990:
991:
992:
993:
994:
995:
996:
997:
998:
999:
1000:
1001:
1002:
1003:
1004:
1005:
1006:
1007:
1008:
1009:
1010:
1011:
1012:
1013:
1014:
1015:
1016:
1017:
1018:
1019:
1020:
1021:
1022:
1023:
1024:
1025:
1026:
1027:
1028:
1029:
1030:
1031:
1032:
1033:
1034:
1035:
1036:
1037:
1038:
1039:
1040:
1041:
1042:
1043:
1044:
1045:
1046:
1047:
1048:
1049:
1050:
1051:
1052:
1053:
1054:
1055:
1056:
1057:
1058:
1059:
1060:
1061:
1062:
1063:
1064:
1065:
1066:
1067:
1068:
1069:
1070:
1071:
1072:
1073:
1074:
1075:
1076:
1077:
1078:
1079:
1080:
1081:
1082:
1083:
1084:
1085:
1086:
1087:
1088:
1089:
1090:
1091:
1092:
1093:
1094:
1095:
1096:
1097:
1098:
1099:
1100:
1101:
1102:
1103:
1104:
1105:
1106:
1107:
1108:
1109:
1110:
1111:
1112:
1113:
1114:
1115:
1116:
1117:
1118:
1119:
1120:
1121:
1122:
1123:
1124:
1125:
1126:
1127:
1128:
1129:
1130:
1131:
1132:
1133:
1134:
1135:
1136:
1137:
1138:
1139:
1140:
1141:
1142:
1143:
1144:
1145:
1146:
1147:
1148:
1149:
1150:
1151:
1152:
1153:
1154:
1155:
1156:
1157:
1158:
1159:
1160:
1161:
1162:
1163:
1164:
1165:
1166:
1167:
1168:
1169:
1170:
1171:
1172:
1173:
1174:
1175:
1176:
1177:
1178:
1179:
1180:
1181:
1182:
1183:
1184:
1185:
1186:
1187:
1188:
1189:
1190:
1191:
1192:
1193:
1194:
1195:
1196:
1197:
1198:
1199:
1200:
1201:
1202:
1203:
1204:
1205:
1206:
1207:
1208:
1209:
1210:
1211:
1212:
1213:
1214:
1215:
1216:
1217:
1218:
1219:
1220:
1221:
1222:
1223:
1224:
1225:
1226:
1227:
1228:
1229:
1230:
1231:
1232:
1233:
1234:
1235:
1236:
1237:
1238:
1239:
1240:
1241:
1242:
1243:
1244:
1245:
1246:
1247:
1248:
1249:
1250:
1251:
1252:
1253:
1254:
1255:
1256:
1257:
1258:
1259:
1260:
1261:
1262:
1263:
1264:
1265:
1266:
1267:
1268:
1269:
1270:
1271:
1272:
1273:
1274:
1275:
1276:
1277:
1278:
1279:
1280:
1281:
1282:
1283:
1284:
1285:
1286:
1287:
1288:
1289:
1290:
1291:
1292:
1293:
1294:
1295:
1296:
1297:
1298:
1299:
1300:
1301:
1302:
1303:
1304:
1305:
1306:
1307:
1308:
1309:
1310:
1311:
1312:
1313:
1314:
1315:
1316:
1317:
1318:
1319:
1320:
1321:
1322:
1323:
1324:
1325:
1326:
1327:
1328:
1329:
1330:
1331:
1332:
1333:
1334:
1335:
1336:
1337:
1338:
1339:
1340:
1341:
1342:
1343:
1344:
1345:
1346:
1347:
1348:
1349:
1350:
1351:
1352:
1353:
1354:
1355:
1356:
1357:
1358:
1359:
1360:
1361:
1362:
1363:
1364:
1365:
1366:
1367:
1368:
1369:
1370:
1371:
1372:
1373:
1374:
1375:
1376:
1377:
1378:
1379:
1380:
1381:
1382:
1383:
1384:
1385:
1386:
1387:
1388:
1389:
1390:
1391:
1392:
1393:
1394:
1395:
1396:
1397:
1398:
1399:
1400:
1401:
1402:
1403:
1404:
1405:
1406:
1407:
1408:
1409:
1410:
1411:
1412:
1413:
1414:
1415:
1416:
1417:
1418:
1419:
1420:
1421:
1422:
1423:
1424:
1425:
1426:
1427:
1428:
1429:
1430:
1431:
1432:
1433:
1434:
1435:
1436:
1437:
1438:
1439:
1440:
1441:
1442:
1443:
1444:
1445:
1446:
1447:
1448:
1449:
1450:
1451:
1452:
1453:
1454:
1455:
1456:
1457:
1458:
1459:
1460:
1461:
1462:
1463:
1464:
1465:
1466:
1467:
1468:
1469:
1470:
1471:
1472:
1473:
1474:
1475:
1476:
1477:
1478:
1479:
1480:
1481:
1482:
1483:
1484:
1485:
1486:
1487:
1488:
1489:
1490:
1491:
1492:
1493:
1494:
1495:
1496:
1497:
1498:
1499:
1500:
1501:
1502:
1503:
1504:
1505:
1506:
1507:
1508:
1509:
1510:
1511:
1512:
1513:
1514:
1515:
1516:
1517:
1518:
1519:
1520:
1521:
1522:
1523:
1524:
1525:
1526:
1527:
1528:
1529:
1530:
1531:
1532:
1533:
1534:
1535:
1536:
1537:
1538:
1539:
1540:
1541:
1542:
1543:
1544:
1545:
1546:
1547:
1548:
1549:
1550:
1551:
1552:
1553:
1554:
1555:
1556:
1557:
1558:
1559:
1560:
1561:
1562:
1563:
1564:
1565:
1566:
1567:
1568:
1569:
1570:
1571:
1572:
1573:
1574:
1575:
1576:
1577:
1578:
1579:
1580:
1581:
1582:
1583:
1584:
1585:
1586:
1587:
1588:
1589:
1590:
1591:
1592:
1593:
1594:
1595:
1596:
1597:
1598:
1599:
1600:
1601:
1602:
1603:
1604:
1605:
1606:
1607:
1608:
1609:
1610:
1611:
1612:
1613:
1614:
1615:
1616:
1617:
1618:
1619:
1620:
1621:
1622:
1623:
1624:
1625:
1626:
1627:
1628:
1629:
1630:
1631:
1632:
1633:
1634:
1635:
1636:
1637:
1638:
1639:
1640:
1641:
1642:
1643:
1644:
1645:
1646:
1647:
1648:
1649:
1650:
1651:
1652:
1653:
1654:
1655:
1656:
1657:
1658:
1659:
1660:
1661:
1662:
1663:
1664:
1665:
1666:
1667:
1668:
1669:
1670:
1671:
1672:
1673:
1674:
1675:
1676:
1677:
1678:
1679:
1680:
1681:
1682:
1683:
1684:
1685:
1686:
1687:
1688:
1689:
1690:
1691:
1692:
1693:
1694:
1695:
1696:
1697:
1698:
1699:
1700:
1701:
1702:
1703:
1704:
1705:
1706:
1707:
1708:
1709:
1710:
1711:
1712:
1713:
1714:
1715:
1716:
1717:
1718:
1719:
1720:
1721:
1722:
1723:
1724:
1725:
1726:
1727:
1728:
1729:
1730:
1731:
1732:
1733:
1734:
1735:
1736:
1737:
1738:
1739:
1740:
1741:
1742:
1743:
1744:
1745:
1746:
1747:
1748:
1749:
1750:
1751:
1752:
1753:
1754:
1755:
1756:
1757:
1758:
1759:
1760:
1761:
1762:
1763:
1764:
1765:
1766:
1767:
1768:
1769:
1770:
1771:
1772:
1773:
1774:
1775:
1776:
1777:
1778:
1779:
1780:
1781:
1782:
1783:
1784:
1785:
1786:
1787:
1788:
1789:
1790:
1791:
1792:
1793:
1794:
1795:
1796:
1797:
1798:
1799:
1800:
1801:
1802:
1803:
1804:
1805:
1806:
1807:
1808:
1809:
1810:
1811:
1812:
1813:
1814:
1815:
1816:
1817:
1818:
1819:
1820:
1821:
1822:
1823:
1824:
1825:
1826:
1827:
1828:
1829:
1830:
1831:
1832:
1833:
1834:
1835:
1836:
1837:
1838:
1839:
1840:
1841:
1842:
1843:
1844:
1845:
1846:
1847:
1848:
1849:
1850:
1851:
1852:
1853:
1854:
1855:
1856:
1857:
1858:
1859:
1860:
1861:
1862:
1863:
1864:
1865:
1866:
1867:
1868:
1869:
1870:
1871:
1872:
1873:
1874:
1875:
1876:
1877:
1878:
1879:
1880:
1881:
1882:
1883:
1884:
1885:
1886:
1887:
1888:
1889:
1890:
1891:
1892:
1893:
1894:
1895:
1896:
1897:
1898:
1899:
1900:
1901:
1902:
1903:
1904:
1905:
1906:
1907:
1908:
1909:
1910:
1911:
1912:
1913:
1914:
1915:
1916:
1917:
1918:
1919:
1920:
1921:
1922:
1923:
1924:
1925:
1926:
1927:
1928:
1929:
1930:
1931:
1932:
1933:
1934:
1935:
1936:
1937:
1938:
1939:
1940:
1941:
1942:
1943:
1944:
1945:
1946:
1947:
1948:
1949:
1950:
1951:
1952:
1953:
1954:
1955:
1956:
1957:
1958:
1959:
1960:
1961:
1962:
1963:
1964:
1965:
1966:
1967:
1968:
1969:
1970:
1971:
1972:
1973:
1974:
1975:
1976:
1977:
1978:
1979:
1980:
1981:
1982:
1983:
1984:
1985:
1986:
1987:
1988:
1989:
1990:
1991:
1992:
1993:
1994:
1995:
1996:
1997:
1998:
1999:
2000:
2001:
2002:
2003:
2004:
2005:
2006:
2007:
2008:
2009:
2010:
2011:
2012:
2013:
2014:
2015:
2016:
2017:
2018:
2019:
2020:
2021:
2022:
2023:
2024:
2025:
2026:
2027:
2028:
2029:
2030:
2031:
2032:
2033:
2034:
2035:
2036:
2037:
2038:
2039:
2040:
2041:
2042:
2043:
2044:
2045:
2046:
2047:
2048:
2049:
2050:
2051:
2052:
2053:
2054:
2055:
2056:
2057:
2058:
2059:
2060:
2061:
2062:
2063:
2064:
2065:
2066:
2067:
2068:
2069:
2070:
2071:
2072:
2073:
2074:
2075:
2076:
2077:
2078:
2079:
2080:
2081:
2082:
2083:
2084:
2085:
2086:
2087:
2088:
2089:
2090:
2091:
2092:
2093:
2094:
2095:
2096:
2097:
2098:
2099:
2100:
2101:
2102:
2103:
2104:
2105:
2106:
2107:
2108:
*&---------------------------------------------------------------------*
*& Report  ZSD_SALESDOC_FLOE - Copy of SD_SDOC_PRINT01
*&---------------------------------------------------------------------*
*& Print Program for Sales Documents
*&---------------------------------------------------------------------*

REPORT ZSD_SALESDOC_FLOE2 MESSAGE-ID vd_pdf.

TABLES:
  nast,
  tnapr,
  toa_dara,
  vbdka,                                          "#EC NEEDED sapscript
  komk,                                           "#EC NEEDED sapscript
  tvko.                                           "#EC NEEDED sapscript

TYPE-POOLS:
  szadr.

DATA:
  BEGIN OF gs_nast.
    INCLUDE STRUCTURE nast.
DATA:
  email_addr TYPE ad_smtpadr,
  END OF gs_nast.

DATA:
  gr_badi_print              TYPE REF TO badi_sd_sls_print01,

  gt_komv                    TYPE TABLE OF komv,
  gt_vedpa                   TYPE TABLE OF vedpa,
  gt_item_cancellation_dates TYPE vedpn_t,
  gt_vbtyp_fix_values        TYPE TABLE OF dd07v,
  gt_add_msg                 TYPE balmi_t,

  gs_interface               TYPE sdoc_s_prt_interface,
  gs_komk                    TYPE komk,

  gv_screen_display          TYPE char1,
  gv_price_print_mode        TYPE char1,
  gv_language                TYPE sylangu,
  gv_scenario                TYPE c,
  gv_dummy                   TYPE char1,                    "#EC NEEDED

  gv_output_comm_fax_ext     TYPE c.

FIELD-SYMBOLS:
  <gs_vbdka>      TYPE vbdka,
  <gv_returncode> TYPE sysubrc.

CONSTANTS:
  gc_pr_kappl  TYPE char1 VALUE 'V',
  gc_true      TYPE char1 VALUE 'X',
  gc_false     TYPE char1 VALUE space,
  gc_english   TYPE char1 VALUE 'E',
  gc_pdf       TYPE char1 VALUE '2',
  gc_equal     TYPE char2 VALUE 'EQ',
  gc_include   TYPE char1 VALUE 'I',
  gc_cash_sale TYPE char1 VALUE 'C',
  gc_max_brtwr TYPE brtwr VALUE '999999999.99',
  BEGIN OF gc_nacha,
    printer       TYPE na_nacha VALUE 1,
    fax           TYPE na_nacha VALUE 2,
    external_send TYPE na_nacha VALUE 5,
  END OF gc_nacha,
  BEGIN OF gc_device,
    printer    TYPE output_device VALUE 'P',
    fax        TYPE output_device VALUE 'F',
    email      TYPE output_device VALUE 'E',
    web_dynpro TYPE output_device VALUE 'W',
  END OF gc_device.

*----------------------------------------------------------------------*
* Floe declarations: START
*----------------------------------------------------------------------*
TYPES: BEGIN OF ty_floe_rec_email_s,
         email TYPE ad_smtpadr,
         type  TYPE char1,
       END OF ty_floe_rec_email_s.

TYPES: ty_floe_rec_email_t TYPE TABLE OF ty_floe_rec_email_s.

TYPES: BEGIN OF ty_floe_var_code_s,
         var_code       TYPE char30,
         value          TYPE string,
         row_num        TYPE numc3,
         parent_row_num TYPE numc3,
       END OF ty_floe_var_code_s.

TYPES: ty_floe_var_code_t TYPE TABLE OF ty_floe_var_code_s.

DATA: gt_rec_emails TYPE ty_floe_rec_email_t,
      gs_rec_email  TYPE ty_floe_rec_email_s,
      gt_vars       TYPE ty_floe_var_code_t,
      gs_vars       TYPE ty_floe_var_code_s,
      gv_subrc      TYPE sysubrc.

DATA: ls_attach TYPE /floe/att_s,
      lt_attach TYPE /floe/att_t,
      l_im_doc  TYPE /floe/doc_ref,
      gv_etype  TYPE /floe/etype_code,
      l_order   TYPE string.

DATA: lt_lines TYPE TABLE OF tline,
      ls_lines TYPE tline,
      l_text   TYPE string,
      l_tdname TYPE tdobname.
*----------------------------------------------------------------------*
* Floe declarations: END
*----------------------------------------------------------------------*
INCLUDE:
  rvdirekt.

* >>>>> BUNDLING <<<<< *************************************************
INCLUDE check_bundling_print.
* >>>>> BUNDLING <<<<< *************************************************

*---------------------------------------------------------------------*
*       FORM ENTRY                                                    *
*---------------------------------------------------------------------*
FORM entry                                                  "#EC CALLED
     USING cv_returncode  TYPE sysubrc
           uv_screen      TYPE char1.

  TRY.
*     Get BAdI handle
      GET BADI gr_badi_print
        FILTERS
          filter_order = tnapr-sform.
    CATCH cx_badi_not_implemented.
*     This should not occur due to fallback class but to be save...
      CLEAR gr_badi_print.
    CATCH cx_badi_multiply_implemented.
*     Several implementations exist for the filter 'form name'.
*     This appears to be very unlikely but to be save...
      CLEAR gr_badi_print.
  ENDTRY.

* Assign RC
  ASSIGN cv_returncode TO <gv_returncode>.

* Refresh global data
  PERFORM initialize_data.

* Set data and start processing
  gv_screen_display = uv_screen.
  gs_nast           = nast.
  PERFORM processing.

ENDFORM.                    "entry

*---------------------------------------------------------------------*
*       FORM ENTRY FLOE                                                   *
*---------------------------------------------------------------------*
FORM entry_floe                                             "#EC CALLED
     USING cv_returncode  TYPE sysubrc
           uv_screen      TYPE char1.

  TRY.
*     Get BAdI handle
      GET BADI gr_badi_print
        FILTERS
          filter_order = tnapr-sform.
    CATCH cx_badi_not_implemented.
*     This should not occur due to fallback class but to be save...
      CLEAR gr_badi_print.
    CATCH cx_badi_multiply_implemented.
*     Several implementations exist for the filter 'form name'.
*     This appears to be very unlikely but to be save...
      CLEAR gr_badi_print.
  ENDTRY.

* Assign RC
  ASSIGN cv_returncode TO <gv_returncode>.

* Refresh global data
  PERFORM initialize_data.

* Set data and start processing
  gv_screen_display = uv_screen.
  gs_nast           = nast.
  PERFORM processing_floe.

ENDFORM.                    "entry_floe

*---------------------------------------------------------------------*
*       FORM ENTRY_CASH_SALE                                          *
*---------------------------------------------------------------------*
FORM entry_cash_sale                                        "#EC CALLED
     USING cv_returncode TYPE sysubrc
           uv_screen     TYPE char1.

  TRY.
*     Get BAdI handle
      GET BADI gr_badi_print
        FILTERS
          filter_order = tnapr-sform.
    CATCH cx_badi_not_implemented.
*     This should not occur due to fallback class but to be save...
      CLEAR gr_badi_print.
    CATCH cx_badi_multiply_implemented.
*     Several implementations exist for the filter 'form name'.
*     This appears to be very unlikely but to be save...
      CLEAR gr_badi_print.
  ENDTRY.

* Assign RC
  ASSIGN cv_returncode TO <gv_returncode>.

* Refresh global data
  PERFORM initialize_data.

* Set data and start processing
  gv_screen_display = uv_screen.
  gs_nast           = nast.
  gv_scenario       = gc_cash_sale.
  PERFORM processing.

ENDFORM.                    "entry_cash_sale

*&---------------------------------------------------------------------*
*&      Form  processing
*&---------------------------------------------------------------------*
FORM processing.

* Retrieve the data
  PERFORM get_data.
  CHECK <gv_returncode> IS INITIAL.

* Print, fax, send data
  PERFORM print_data.
  CHECK <gv_returncode> IS INITIAL.

  IF cl_ops_switch_check=>sd_sfws_sc4( ) EQ abap_true.
*   Export additional messages into ABAP memory (even if empty)
    SORT gt_add_msg
         BY msgty msgid msgno msgv1 msgv2 msgv3 msgv4.
    DELETE ADJACENT DUPLICATES
           FROM gt_add_msg COMPARING
           msgty msgid msgno msgv1 msgv2 msgv3 msgv4.
    EXPORT lt_add_msg = gt_add_msg TO MEMORY ID 'PDF_ADD_MSG'.
    CLEAR gt_add_msg.
  ENDIF.

ENDFORM.                    " processing

*&---------------------------------------------------------------------*
*&      Form  processing_floe
*&---------------------------------------------------------------------*
FORM processing_floe.

* Check email type
  gv_etype  = tnapr-fonam.
  CHECK gv_etype IS NOT INITIAL.

* Retrieve the data
  PERFORM get_data.
  CHECK <gv_returncode> IS INITIAL.

* Generate email
  PERFORM send_data_floe.
  CHECK <gv_returncode> IS INITIAL.

  IF cl_ops_switch_check=>sd_sfws_sc4( ) EQ abap_true.
*   Export additional messages into ABAP memory (even if empty)
    SORT gt_add_msg
         BY msgty msgid msgno msgv1 msgv2 msgv3 msgv4.
    DELETE ADJACENT DUPLICATES
           FROM gt_add_msg COMPARING
           msgty msgid msgno msgv1 msgv2 msgv3 msgv4.
    EXPORT lt_add_msg = gt_add_msg TO MEMORY ID 'PDF_ADD_MSG'.
    CLEAR gt_add_msg.
  ENDIF.

ENDFORM.                    " processing_floe

*&---------------------------------------------------------------------*
*&      Form  get_data
*&---------------------------------------------------------------------*
FORM get_data.

  DATA:
    lt_vbdpa TYPE vbdpa_t,
    lt_vedka TYPE TABLE OF vedka,
    lt_mess  TYPE TABLE OF vbfs,

    ls_comwa TYPE vbco3,

    ls_mess  TYPE vbfs.

  FIELD-SYMBOLS:
    <ls_item_detail> TYPE sdoc_s_prt_item_detail.

* Init pricing on demand
  CALL FUNCTION 'RV_PRICE_PRINT_GET_MODE'
    IMPORTING
      e_print_mode = gv_price_print_mode.
  IF gv_price_print_mode EQ chara.
    CALL FUNCTION 'RV_PRICE_PRINT_REFRESH'
      TABLES
        tkomv = gt_komv.
  ENDIF.

* Set data and call print view
  ls_comwa-mandt = sy-mandt.
  ls_comwa-spras = gs_nast-spras.
  ls_comwa-vbeln = gs_nast-objky.
  ls_comwa-kunde = gs_nast-parnr.
  ls_comwa-parvw = gs_nast-parvw.
  CALL FUNCTION 'RV_DOCUMENT_PRINT_VIEW'
    EXPORTING
      comwa                       = ls_comwa
    IMPORTING
      kopf                        = gs_interface-head_detail-vbdka
    TABLES
      pos                         = lt_vbdpa
      mess                        = lt_mess
    EXCEPTIONS
      fehler_bei_datenbeschaffung = 1.
  IF sy-subrc NE 0.
*   Error whilst data retrieval
    <gv_returncode> = sy-subrc.
    PERFORM protocol_update.
  ENDIF.
* In create mode if the sales document has no external number and it
* does not contain any item, yet, the above module undesired returns
* an item w/ initial POSNR and we have to get rid of it...
  DELETE lt_vbdpa WHERE posnr EQ posnr_low.
* Adopt messages into log
  LOOP AT lt_mess INTO ls_mess.
    MESSAGE ID ls_mess-msgid TYPE ls_mess-msgty NUMBER ls_mess-msgno
         WITH ls_mess-msgv1 ls_mess-msgv2 ls_mess-msgv3 ls_mess-msgv4
         INTO gv_dummy.
    PERFORM protocol_update.
  ENDLOOP.
  CHECK <gv_returncode> IS INITIAL.

* Assign a global pointer to the VBDKA
  ASSIGN gs_interface-head_detail-vbdka TO <gs_vbdka>.

* Set default language
  gv_language = gs_nast-spras.

* Set Country for display conversions e.g. WRITE TO
  SET COUNTRY <gs_vbdka>-land1.

* Fetch servicecontract-data and notice-data for head and position.
  CALL FUNCTION 'SD_VEDA_GET_PRINT_DATA'
    EXPORTING
      i_document_number = <gs_vbdka>-vbeln
      i_language        = gv_language
      i_posnr_low       = posnr_low
    TABLES
      print_data_pos    = gt_vedpa
      print_data_head   = lt_vedka
      print_notice_pos  = gt_item_cancellation_dates
      print_notice_head = gs_interface-head_detail-cancellation_dates.

* Validity dates of service contracts
  READ TABLE lt_vedka INTO gs_interface-head_detail-vedka INDEX 1.

* Cancellation dates of service contracts
  IF NOT gs_interface-head_detail-cancellation_dates IS INITIAL.
*   Set up control
    gs_interface-head_detail-ex_cancellation_dates = gc_true.
  ENDIF.

* Get the item details
  PERFORM get_item_details   USING lt_vbdpa.
  CHECK <gv_returncode> IS INITIAL.

* Get the header details
  PERFORM get_head_details.
  CHECK <gv_returncode> IS INITIAL.

*ENHANCEMENT-POINT EHP603_SD_SDOC_PRINT01_01 SPOTS ES_SD_SDOC_PRINT01.


*---------------------------------------------------------------------*
* fill_floe_variables
*---------------------------------------------------------------------*

  DATA: lt_comp        TYPE abap_compdescr_tab,
        ls_comp_a      LIKE LINE OF lt_comp,
        ld_type        TYPE abap_typekind,
        ls_item_detail TYPE vbdpa,
        l_row_num      TYPE numc3,
        l_parent_num   TYPE numc3,
        l_item_num     TYPE numc3,
        l_schl_num     TYPE numc3,
        l_old_posnr    TYPE posnr.

  DATA:
    lo_struct TYPE REF TO cl_abap_structdescr,
    lo_table  TYPE REF TO cl_abap_tabledescr,
    ldo_data  TYPE REF TO data.

  FIELD-SYMBOLS:
    <lt_itab>  TYPE table,
    <lo_field>.
*---------------------------------------------------------------------*
* Convert data into floe variables: START
*---------------------------------------------------------------------*
*
* Only for Floe
  CHECK gv_etype IS NOT INITIAL.
* Take header data from structure <gs_vbdka>.
  GET REFERENCE OF <gs_vbdka> INTO ldo_data .
  lo_struct ?=  cl_abap_structdescr=>describe_by_data_ref( ldo_data ).
  lt_comp = lo_struct->components.
*
  LOOP AT lt_comp INTO ls_comp_a.
    ASSIGN COMPONENT ls_comp_a-name OF STRUCTURE <gs_vbdka> TO <lo_field>.
    gs_vars-var_code = ls_comp_a-name.
    gs_vars-value = <lo_field>.
    APPEND gs_vars TO gt_vars.
  ENDLOOP.
*
* Take item data and schedule line data from table vbdpa.
  GET REFERENCE OF lt_vbdpa INTO ldo_data .
  ASSIGN ldo_data->* TO <lt_itab>.
  lo_table  ?= cl_abap_structdescr=>describe_by_data_ref( ldo_data ).
  lo_struct ?= lo_table->get_table_line_type( ).
  lt_comp = lo_struct->components.
*
*
  l_item_num = 0.

  LOOP AT lt_vbdpa INTO ls_item_detail.
*
    IF sy-tabix EQ 1 OR l_old_posnr NE ls_item_detail-posnr.
      l_schl_num = 0.
      l_parent_num = 0.
      l_item_num = l_item_num + 1.
      l_row_num = l_item_num.
      l_old_posnr = ls_item_detail-posnr..
    ELSE.
* New schedule line
      l_schl_num = l_schl_num + 1.
      l_parent_num = l_item_num.
      l_row_num = l_schl_num.
    ENDIF.
*
    LOOP AT lt_comp INTO ls_comp_a.
      ASSIGN COMPONENT ls_comp_a-name OF STRUCTURE ls_item_detail TO <lo_field>.
*
      gs_vars-var_code = ls_comp_a-name.
      gs_vars-value = <lo_field>.
      gs_vars-row_num = l_row_num.
      gs_vars-parent_row_num = l_parent_num.
      APPEND gs_vars TO gt_vars.
    ENDLOOP.
*
  ENDLOOP.
*---------------------------------------------------------------------*
* Convert data into floe variables: END
*---------------------------------------------------------------------*

ENDFORM.                    " get_data

*&---------------------------------------------------------------------*
*&      Form  protocol_update
*&---------------------------------------------------------------------*
FORM protocol_update.

  CHECK gv_screen_display = gc_false.
  CALL FUNCTION 'NAST_PROTOCOL_UPDATE'
    EXPORTING
      msg_arbgb = sy-msgid
      msg_nr    = sy-msgno
      msg_ty    = sy-msgty
      msg_v1    = sy-msgv1
      msg_v2    = sy-msgv2
      msg_v3    = sy-msgv3
      msg_v4    = sy-msgv4
    EXCEPTIONS
      OTHERS    = 0.

ENDFORM.                    " protocol_update

*&---------------------------------------------------------------------*
*&      Form  print_data
*&---------------------------------------------------------------------*
FORM print_data.

  DATA:
    ls_outputparams TYPE sfpoutputparams,
    ls_docparams    TYPE sfpdocparams,
    ls_pdf_file     TYPE fpformoutput,

    lv_fm_name      TYPE rs38l_fnam,
    lv_device       TYPE output_device,
    lv_failed       TYPE boole_d.

* The form must be of type PDF
  IF tnapr-formtype NE gc_pdf.
    <gv_returncode>  = 1.
    MESSAGE e005 WITH <gs_vbdka>-vbeln
                      tnapr-sform
                 INTO gv_dummy.
    PERFORM protocol_update.
    RETURN.
  ENDIF.

* Get output parameters
  PERFORM get_output_params CHANGING ls_outputparams
                                     ls_docparams
                                     lv_device.
  CHECK <gv_returncode> IS INITIAL.

  IF cl_ops_switch_check=>sd_sfws_sc1( ) IS NOT INITIAL.
* >>>>> BUNDLING <<<<< *************************************************
* Check for bundling
* Import parameter from memory
    DATA:  bundling TYPE char1.
    CLEAR: bundling.
    IMPORT bundling FROM MEMORY ID 'BUNDLING'.
    IF sy-subrc NE 0 OR bundling NE 'X' OR
       nast-nacha NE '1'.
      CLEAR: bundling.
*   Open the spool job
      CALL FUNCTION 'FP_JOB_OPEN'
        CHANGING
          ie_outputparams = ls_outputparams
        EXCEPTIONS
          cancel          = 1
          usage_error     = 2
          system_error    = 3
          internal_error  = 4
          OTHERS          = 5.
      IF sy-subrc <> 0.
        <gv_returncode> = sy-subrc.
        PERFORM protocol_update.
        RETURN.
      ENDIF.
    ENDIF.
* >>>>> BUNDLING <<<<< *************************************************
  ELSE.
* Open the spool job
    CALL FUNCTION 'FP_JOB_OPEN'
      CHANGING
        ie_outputparams = ls_outputparams
      EXCEPTIONS
        cancel          = 1
        usage_error     = 2
        system_error    = 3
        internal_error  = 4
        OTHERS          = 5.
    IF sy-subrc <> 0.
*   Error with spool job
      <gv_returncode> = sy-subrc.
      PERFORM protocol_update.
      RETURN.
    ENDIF.
  ENDIF.



* Get the name of the generated function module
  TRY.
      CALL FUNCTION 'FP_FUNCTION_MODULE_NAME'
        EXPORTING
          i_name     = tnapr-sform
        IMPORTING
          e_funcname = lv_fm_name.
    CATCH cx_fp_api_repository
          cx_fp_api_usage
          cx_fp_api_internal.
*     Function generation did fail
      <gv_returncode> = 99.
      MESSAGE e000 WITH <gs_vbdka>-vbeln
                   INTO gv_dummy.
      PERFORM protocol_update.
      RETURN.
  ENDTRY.

  IF gr_badi_print IS BOUND.
*   Call BAdI for printing
    CALL BADI gr_badi_print->print_data
      EXPORTING
        iv_fm_name    = lv_fm_name
        is_interface  = gs_interface
        is_docparams  = ls_docparams
        is_nast       = nast
      IMPORTING
        es_formoutput = ls_pdf_file
      EXCEPTIONS
        error         = 1.
  ELSE.
*   No BAdI handle: Directly call the function module generated
*   from according PDF form
    CALL FUNCTION lv_fm_name
      EXPORTING
        /1bcdwb/docparams  = ls_docparams
        sls_prt_com        = gs_interface
      IMPORTING
        /1bcdwb/formoutput = ls_pdf_file
      EXCEPTIONS
        usage_error        = 1
        system_error       = 2
        internal_error     = 3
        OTHERS             = 4.
  ENDIF.
  IF NOT sy-subrc IS INITIAL.
*   Printing failed
    <gv_returncode> = sy-subrc.
    PERFORM protocol_update.
    MESSAGE e000 WITH <gs_vbdka>-vbeln
                 INTO gv_dummy.
    PERFORM protocol_update.
*   Do not directly return but only after closing the spool job
    lv_failed = abap_true.
  ENDIF.

  IF cl_ops_switch_check=>sd_sfws_sc1( ) IS NOT INITIAL.
* >>>>> BUNDLING <<<<< *************************************************
    IF bundling NE 'X'.
*   Close the spool job
      CALL FUNCTION 'FP_JOB_CLOSE'
        EXCEPTIONS
          usage_error    = 1
          system_error   = 2
          internal_error = 3
          OTHERS         = 4.
      IF sy-subrc <> 0.
        <gv_returncode> = sy-subrc.
        MESSAGE e000 WITH <gs_vbdka>-vbeln
                     INTO gv_dummy.
        PERFORM protocol_update.
        RETURN.
      ENDIF.
    ENDIF.
* >>>>> BUNDLING <<<<< *************************************************
  ELSE.
* Close the spool job
    CALL FUNCTION 'FP_JOB_CLOSE'
      EXCEPTIONS
        usage_error    = 1
        system_error   = 2
        internal_error = 3
        OTHERS         = 4.
    IF sy-subrc <> 0.
*   Error with spool job
      <gv_returncode> = sy-subrc.
      MESSAGE e000 WITH <gs_vbdka>-vbeln
                   INTO gv_dummy.
      PERFORM protocol_update.
      RETURN.
    ENDIF.
  ENDIF.

  IF NOT lv_failed IS INITIAL.
*   Now, leave processing if printing did fail
    RETURN.
  ENDIF.

* Post processing
  CASE lv_device.
    WHEN gc_device-fax
      OR gc_device-email.
      PERFORM send_data USING lv_device
                              ls_pdf_file.
      IF ls_outputparams-arcmode <> '1'.
        CALL FUNCTION 'ARCHIV_CREATE_OUTGOINGDOC_MULT'
          EXPORTING
            documentclass            = 'PDF'
            document                 = ls_pdf_file-pdf
          TABLES
            arc_i_tab                = ls_docparams-daratab
          EXCEPTIONS
            error_archiv             = 1
            error_communicationtable = 2
            error_connectiontable    = 3
            error_kernel             = 4
            error_parameter          = 5
            error_format             = 6
            OTHERS                   = 7.
        IF sy-subrc <> 0.
          MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
                  WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
                  RAISING system_error.
        ENDIF.
      ENDIF.
    WHEN gc_device-web_dynpro.
      EXPORT lv_pdf_file = ls_pdf_file-pdf TO MEMORY ID 'PDF_FILE'.
  ENDCASE.
  CHECK <gv_returncode> IS INITIAL.

ENDFORM.                    " print_data

*&---------------------------------------------------------------------*
*&      Form  send_data_floe
*&---------------------------------------------------------------------*
FORM send_data_floe.

  DATA:
    ls_outputparams TYPE sfpoutputparams,
    ls_docparams    TYPE sfpdocparams,
    lv_device       TYPE output_device,
    lv_order        TYPE char12,
    lv_reprint TYPE flag.

  DATA:
    lt_mess TYPE bapiret2_t,
    ls_mess TYPE bapiret2.

  DATA:
    ev_ebody         TYPE  string,
    et_rec_emails    TYPE  /floe/rec_email_t,
    et_attachments   TYPE  /floe/att_t,
    ev_esubject_long TYPE  /floe/esubject_long,
    lv_inupd         TYPE i,
    lv_no_commit     TYPE flag.

* Get output parameters
  PERFORM get_output_params CHANGING ls_outputparams
                                     ls_docparams
                                     lv_device.
  CHECK <gv_returncode> IS INITIAL.
*---------------------------------------------------------------------*
* Fill recipient
* Add additional recipients in recipient user-exit
*---------------------------------------------------------------------*
  gs_rec_email-email = gs_nast-email_addr.
  gs_rec_email-type = '1'.
  APPEND gs_rec_email TO gt_rec_emails.
*----------------------------------------------------------------------*
* Add variables
* Add additional variables in email data user-exit
*----------------------------------------------------------------------*
  CLEAR gs_vars .
  gs_vars-var_code = 'REPRINT'.
  gs_vars-value = lv_reprint.
  APPEND gs_vars  TO gt_vars.       "Floe
*
  CLEAR gs_vars .
  gs_vars-var_code = 'KSCHL'.
  gs_vars-value = gs_nast-kschl.
  APPEND gs_vars  TO gt_vars.       "Floe
*
  CLEAR gs_vars .
  gs_vars-var_code = 'SPRAS'.
  gs_vars-value = gs_nast-spras.
  APPEND gs_vars  TO gt_vars.       "Floe
*
  IF gv_screen_display IS INITIAL.
    CLEAR gs_vars .
    gs_vars-var_code = 'FLOE_SEND'.
    gs_vars-value = 'X'.
    APPEND gs_vars  TO gt_vars.       "Floe
  ENDIF.
*
*-------------------------------------------------------------------
* Determine whether this is run as update task
*
  CLEAR: lv_inupd, lv_no_commit.
  CALL METHOD cl_system_transaction_state=>get_in_update_task
    RECEIVING
      in_update_task = lv_inupd.
*
  IF lv_inupd = 1.
    lv_no_commit = 'X'.
  ENDIF.
*
*----------------------------------------------------------------------*
* Call Floe API
*----------------------------------------------------------------------*
  CLEAR ev_ebody.
*
  l_im_doc = lv_order.
*
  CALL FUNCTION '/FLOE/EMAIL_OUT'
    EXPORTING
      im_etype            = gv_etype
      im_elang            = gv_language
      im_document         = l_im_doc
      im_rec_emails       = gt_rec_emails
      im_variables        = gt_vars
      im_send_immediately = 'X'
      im_attachments      = lt_attach
      im_preview          = gv_screen_display
      im_no_commit        = lv_no_commit
    IMPORTING
      ex_subrc            = <gv_returncode>
      ex_ebody            = ev_ebody
      ex_mess             = lt_mess
      ex_rec_emails       = et_rec_emails
      ex_attachments      = et_attachments
      ex_esubject_long    = ev_esubject_long.

  LOOP AT lt_mess INTO ls_mess.
    CALL FUNCTION 'NAST_PROTOCOL_UPDATE'
      EXPORTING
        msg_arbgb = ls_mess-id
        msg_nr    = ls_mess-number
        msg_ty    = ls_mess-type
        msg_v1    = ls_mess-message_v1
        msg_v2    = ls_mess-message_v2
        msg_v3    = ls_mess-message_v3
        msg_v4    = ls_mess-message_v4
      EXCEPTIONS
        OTHERS    = 0.
  ENDLOOP.
*
* Drop out if API has thrown an error
  IF <gv_returncode> NE 0.
    RETURN.
  ENDIF.
*
*----------------------------------------------------------------------*
* Preview Email if required.
*----------------------------------------------------------------------*
  IF NOT gv_screen_display IS INITIAL.

    CALL FUNCTION '/FLOE/EMAIL_VIEWER'
      EXPORTING
        im_preview     = 'X'
*       IM_ETYPE       =
*       IM_EID         =
        im_esubject    = 'FLOE Preview'
        im_ebody       = ev_ebody
        im_rec_emails  = et_rec_emails
        im_attachments = et_attachments
      IMPORTING
        ex_subrc       = <gv_returncode>.
  ENDIF.
*
ENDFORM.                    " send_data_floe

*&---------------------------------------------------------------------*
*&      Form  get_item_details
*&---------------------------------------------------------------------*
FORM get_item_details
     USING ut_vbdpa       TYPE vbdpa_t.

  DATA:
    lt_sub_items   TYPE vbdpau_t,

    ls_dd07v       TYPE dd07v,
    ls_text        TYPE tline,
    ls_item_detail TYPE sdoc_s_prt_item_detail.

  FIELD-SYMBOLS:
    <ls_vbdpa>            TYPE vbdpa,
    <ls_last_item_detail> TYPE sdoc_s_prt_item_detail,
    <ls_item_detail>      TYPE sdoc_s_prt_item_detail.

* Get domain fix values of VBTYP
  CALL FUNCTION 'DD_DOMVALUES_GET'
    EXPORTING
      domname        = 'VBTYPL'
      text           = gc_true
      langu          = gv_language
    TABLES
      dd07v_tab      = gt_vbtyp_fix_values
    EXCEPTIONS
      wrong_textflag = 1
      OTHERS         = 2.
  IF sy-subrc <> 0.
*   Domain fixed values not existing in target language...!?
    <gv_returncode> = sy-subrc.
    MESSAGE e000 WITH <gs_vbdka>-vbeln
                 INTO gv_dummy.
    PERFORM protocol_update.
    RETURN.
  ENDIF.

* Get Sub items
  PERFORM get_sub_items USING    ut_vbdpa
                        CHANGING lt_sub_items.
  CHECK <gv_returncode> IS INITIAL.

  LOOP AT ut_vbdpa ASSIGNING <ls_vbdpa>
                   WHERE dragr EQ space. "Not print rejected item
*   Init item
    CLEAR ls_item_detail.
*   Assign schedule lines to the main item
    IF <ls_vbdpa>-posnr_neu EQ space.
      IF NOT <ls_last_item_detail> IS ASSIGNED
        OR <ls_last_item_detail>-vbdpa-posnr NE <ls_vbdpa>-posnr.
        READ TABLE gs_interface-item_detail
             ASSIGNING <ls_last_item_detail>
             WITH KEY vbdpa-posnr = <ls_vbdpa>-posnr
             BINARY SEARCH.
        IF sy-subrc <> 0.
*         Item does not exist
          <gv_returncode> = sy-subrc.
          MESSAGE e000 WITH <gs_vbdka>-vbeln
                       INTO gv_dummy.
          PERFORM protocol_update.
          RETURN.
        ENDIF.
      ENDIF.
      APPEND <ls_vbdpa> TO <ls_last_item_detail>-schedule_lines.
*     Set up control
      <ls_last_item_detail>-ex_schedule_lines = gc_true.
      CONTINUE.
    ENDIF.
*   Fill the VBDPA structure
    ls_item_detail-vbdpa = <ls_vbdpa>.
*   Clear Predecessor document if equal to header predecessor
    IF ls_item_detail-vbdpa-vbtyp_vang EQ <gs_vbdka>-vbtyp_vang AND
       ls_item_detail-vbdpa-vbeln_vang EQ <gs_vbdka>-vbeln_vang.
      CLEAR: ls_item_detail-vbdpa-vbeln_vang,
             ls_item_detail-vbdpa-vbtyp_vang.
    ENDIF.
*   Clear LFDAT
    IF ls_item_detail-vbdpa-etenr_da EQ gc_true
      OR <gs_vbdka>-lfdat EQ
         ls_item_detail-vbdpa-lfdat.
      CLEAR ls_item_detail-vbdpa-lfdat.
    ENDIF.
*   Get the type text of the predecessor document
    IF NOT ls_item_detail-vbdpa-vbtyp_vang IS INITIAL.
      READ TABLE gt_vbtyp_fix_values  INTO ls_dd07v
                WITH KEY domvalue_l = ls_item_detail-vbdpa-vbtyp_vang.

      IF sy-subrc IS INITIAL.
        ls_item_detail-vbtyp_vang_text = ls_dd07v-ddtext.
      ENDIF.
    ENDIF.
*   Validity dates of service contracts
    READ TABLE gt_vedpa INTO ls_item_detail-vedpa INDEX 1.
*   Get the item prices
    PERFORM get_item_prices CHANGING ls_item_detail.
    IF <gv_returncode> <> 0.
      RETURN.
    ENDIF.
*   Get the item billing schedules
    PERFORM get_item_billing_schedules CHANGING ls_item_detail.
    IF <gv_returncode> <> 0.
      RETURN.
    ENDIF.
*   Get configurations
    PERFORM get_item_characteristics CHANGING ls_item_detail.
    IF <gv_returncode> <> 0.
      RETURN.
    ENDIF.
*   Get serials
    PERFORM get_item_serials CHANGING ls_item_detail.
    IF <gv_returncode> <> 0.
      RETURN.
    ENDIF.
*   Get correction text
    PERFORM get_item_correction_text CHANGING ls_item_detail.
    IF <gv_returncode> <> 0.
      RETURN.
    ENDIF.
    IF gr_badi_print IS BOUND.
*     Call BAdI concerning item details
      CALL BADI gr_badi_print->get_item_details
        EXPORTING
          is_vbdka       = <gs_vbdka>
          is_nast        = nast
          iv_language    = gv_language
        CHANGING
          cs_item_detail = ls_item_detail.
    ENDIF.
    APPEND ls_item_detail TO gs_interface-item_detail
                          ASSIGNING <ls_last_item_detail>.
  ENDLOOP.

* Assign the sub items to their master items
  SORT lt_sub_items BY posnr.
  PERFORM assign_sub_items USING lt_sub_items
                           CHANGING gs_interface-item_detail.
  CHECK <gv_returncode> IS INITIAL.

* Assign the cancellation dates to the items
  PERFORM assign_cancel_dates CHANGING gs_interface-item_detail.
  CHECK <gv_returncode> IS INITIAL.

ENDFORM.                    " get_item_details

*&---------------------------------------------------------------------*
*&      Form  get_item_prices
*&---------------------------------------------------------------------*
FORM get_item_prices
     CHANGING cs_item_detail TYPE sdoc_s_prt_item_detail.

  DATA:
    ls_komp  TYPE komp,
    ls_komvd TYPE komvd,

    lv_lines TYPE i.

* Fill the communication structure
  IF gs_komk-knumv NE <gs_vbdka>-knumv OR
     gs_komk-knumv IS INITIAL.
    CLEAR gs_komk.
    gs_komk-mandt     = sy-mandt.
    gs_komk-kalsm     = <gs_vbdka>-kalsm.
    gs_komk-kappl     = gc_pr_kappl.
    gs_komk-waerk     = <gs_vbdka>-waerk.
    gs_komk-knumv     = <gs_vbdka>-knumv.
    gs_komk-knuma     = <gs_vbdka>-knuma.
    gs_komk-vbtyp     = <gs_vbdka>-vbtyp.
    gs_komk-land1     = <gs_vbdka>-land1.
    gs_komk-vkorg     = <gs_vbdka>-vkorg.
    gs_komk-vtweg     = <gs_vbdka>-vtweg.
    gs_komk-spart     = <gs_vbdka>-spart.
    gs_komk-bukrs     = <gs_vbdka>-bukrs_vf.
    gs_komk-hwaer     = <gs_vbdka>-waers.
    gs_komk-prsdt     = <gs_vbdka>-erdat.
    gs_komk-kurst     = <gs_vbdka>-kurst.
    gs_komk-kurrf     = <gs_vbdka>-kurrf.
    gs_komk-kurrf_dat = <gs_vbdka>-kurrf_dat.
  ENDIF.
  ls_komp-kposn     = cs_item_detail-vbdpa-posnr.
  ls_komp-kursk     = cs_item_detail-vbdpa-kursk.
  ls_komp-kursk_dat = cs_item_detail-vbdpa-kursk_dat.
  IF <gs_vbdka>-vbtyp CA 'HKNOT6'.
    IF cs_item_detail-vbdpa-shkzg CA ' A'.
      ls_komp-shkzg = gc_true.
    ENDIF.
  ELSE.
    IF cs_item_detail-vbdpa-shkzg CA 'BX'.
      ls_komp-shkzg = gc_true.
    ENDIF.
  ENDIF.

  IF gr_badi_print IS BOUND.
*   Call BAdI for preparation of item pricing
    CALL BADI gr_badi_print->prepare_item_prices
      EXPORTING
        is_vbdka       = <gs_vbdka>
        iv_language    = gv_language
        is_item_detail = cs_item_detail
        is_nast        = nast
      CHANGING
        cs_komp        = ls_komp
        cs_komk        = gs_komk.
  ENDIF.

* Get the item prices
  IF gv_price_print_mode EQ chara.
    CALL FUNCTION 'RV_PRICE_PRINT_ITEM'
      EXPORTING
        comm_head_i = gs_komk
        comm_item_i = ls_komp
        language    = gv_language
      IMPORTING
        comm_head_e = gs_komk
        comm_item_e = ls_komp
      TABLES
        tkomv       = gt_komv
        tkomvd      = cs_item_detail-conditions.
  ELSE.
    CALL FUNCTION 'RV_PRICE_PRINT_ITEM_BUFFER'
      EXPORTING
        comm_head_i = gs_komk
        comm_item_i = ls_komp
        language    = gv_language
      IMPORTING
        comm_head_e = gs_komk
        comm_item_e = ls_komp
      TABLES
        tkomv       = gt_komv
        tkomvd      = cs_item_detail-conditions.
  ENDIF.

  IF NOT cs_item_detail-conditions IS INITIAL.
*   The conditions have always one initial line
    DESCRIBE TABLE cs_item_detail-conditions LINES lv_lines.
    IF lv_lines EQ 1.
      READ TABLE cs_item_detail-conditions INTO ls_komvd
                                           INDEX 1.
      IF NOT ls_komvd IS INITIAL.
*       Set up control
        cs_item_detail-ex_conditions = gc_true.
      ENDIF.
    ELSE.
*     Set up control
      cs_item_detail-ex_conditions = gc_true.
    ENDIF.
  ENDIF.

* Fill the tax code
  CALL FUNCTION 'SD_TAX_CODE_MAINTAIN'
    EXPORTING
      key_knumv           = gs_komk-knumv
      key_kposn           = ls_komp-kposn
      i_application       = ' '
      i_pricing_procedure = gs_komk-kalsm
    TABLES
      xkomv               = gt_komv.

ENDFORM.                    " get_item_prices

*&---------------------------------------------------------------------*
*&      Form  get_head_details
*&---------------------------------------------------------------------*
FORM get_head_details.

* Get Sales Org detail
  PERFORM get_head_tvko.
  CHECK <gv_returncode> IS INITIAL.

* Get header prices
  PERFORM get_head_prices.
  CHECK <gv_returncode> IS INITIAL.

* Get dynamic texts
  PERFORM get_head_text.
  CHECK <gv_returncode> IS INITIAL.

* Get sending country
  PERFORM get_head_sending_country.
  CHECK <gv_returncode> IS INITIAL.

* Check repeat printout
  PERFORM get_head_repeat_flag.
  CHECK <gv_returncode> IS INITIAL.

  IF gr_badi_print IS BOUND.
*   Call BAdI concerning head details
    CALL BADI gr_badi_print->get_head_details
      EXPORTING
        iv_language  = gv_language
        is_nast      = nast
      CHANGING
        cs_interface = gs_interface.
  ENDIF.

ENDFORM.                    " get_head_details

*&---------------------------------------------------------------------*
*&      Form  get_head_repeat_flag
*&---------------------------------------------------------------------*
FORM get_head_repeat_flag.

  DATA:
    lv_nast TYPE nast.

* Get message
  SELECT SINGLE * INTO lv_nast FROM nast
                                WHERE kappl = gs_nast-kappl "#EC *
                                AND   objky = gs_nast-objky
                                AND   kschl = gs_nast-kschl
                                AND   spras = gv_language
                                AND   parnr = gs_nast-parnr
                                AND   parvw = gs_nast-parvw
                                AND   nacha BETWEEN '1' AND '5'
                                AND   vstat = '1'.
  IF sy-subrc IS INITIAL.
    gs_interface-head_detail-repeat = gc_true.
  ENDIF.

ENDFORM.                    " get_head_repeat_flag

*&---------------------------------------------------------------------*
*&      Form  get_head_sending_country
*&---------------------------------------------------------------------*
FORM get_head_sending_country.

  DATA:
    ls_address TYPE sdpartner_address.

* Check country is still outstanding
  CHECK <gs_vbdka>-sland IS INITIAL.
* Retrieve from address
  CALL FUNCTION 'SD_ADDRESS_GET'
    EXPORTING
      fif_address_number      = gs_interface-head_detail-tvko-adrnr
      fif_address_type        = char1
    IMPORTING
      fes_sdpartner_address   = ls_address
    EXCEPTIONS
      address_not_found       = 1
      address_type_not_exists = 2
      no_person_number        = 3
      OTHERS                  = 4.
  IF sy-subrc IS INITIAL.
*   Use country detected
    <gs_vbdka>-sland = ls_address-country.
  ELSE.
*   No country detected
    <gv_returncode> = sy-subrc.
    MESSAGE e004 WITH <gs_vbdka>-vbeln
                      gs_interface-head_detail-tvko-vkorg
                 INTO gv_dummy.
    PERFORM protocol_update.
    RETURN.
  ENDIF.

ENDFORM.                    " get_head_sending_country

*&---------------------------------------------------------------------*
*&      Form  get_item_billing_schedules
*&---------------------------------------------------------------------*
FORM get_item_billing_schedules
     CHANGING cs_item_detail TYPE sdoc_s_prt_item_detail.

  DATA:
    ls_bill_plan             TYPE fpltdr.

* Check we deal with a billing plan at all
  CHECK NOT cs_item_detail-vbdpa-fplnr IS INITIAL.
* Get billing plan data
  CALL FUNCTION 'BILLING_SCHED_PRINTVIEW_READ'
    EXPORTING
      i_fplnr    = cs_item_detail-vbdpa-fplnr
      i_language = gv_language
      i_vbeln    = <gs_vbdka>-vbeln
    TABLES
      zfpltdr    = cs_item_detail-bill_plan.
  IF NOT cs_item_detail-bill_plan IS INITIAL.
*   Transfer billing plan data
    READ TABLE cs_item_detail-bill_plan INTO ls_bill_plan
                                        INDEX 1.
    IF NOT ls_bill_plan-perio IS INITIAL.
      cs_item_detail-bill_plan_periodic = ls_bill_plan.
      CLEAR cs_item_detail-bill_plan.
    ELSE.
      SORT cs_item_detail-bill_plan BY fkdat.
*     Set up control
      cs_item_detail-ex_bill_plan = gc_true.
    ENDIF.
  ENDIF.

ENDFORM.                    " get_item_billing_schedules

*&---------------------------------------------------------------------*
*&      Form  get_sub_items
*&---------------------------------------------------------------------*
FORM get_sub_items
  USING    ut_vbdpa     TYPE vbdpa_t
  CHANGING ct_sub_items TYPE vbdpau_t.

  DATA:
    ls_sub_item         TYPE vbdpau.

  FIELD-SYMBOLS:
    <ls_vbdpa>          TYPE vbdpa.

  LOOP AT ut_vbdpa ASSIGNING <ls_vbdpa>.
    IF <ls_vbdpa>-uepos IS INITIAL           OR
       <ls_vbdpa>-uepos NE ls_sub_item-posnr.
*     Append work area to table ct_sub_items
      IF ls_sub_item-uposv > 0.
        APPEND ls_sub_item TO ct_sub_items.
        CLEAR ls_sub_item.
      ENDIF.
*     Start filling new work area
      ls_sub_item-posnr = <ls_vbdpa>-posnr.
      IF NOT <ls_vbdpa>-uepos IS INITIAL           AND
             <ls_vbdpa>-uepos NE ls_sub_item-posnr.
        ls_sub_item-posnr = <ls_vbdpa>-uepos.
        ls_sub_item-uepvw = <ls_vbdpa>-uepvw.
        ls_sub_item-uposv = <ls_vbdpa>-posnr.
      ENDIF.
    ELSE.
      IF ls_sub_item-uposv IS INITIAL          OR
         ls_sub_item-uposv GT <ls_vbdpa>-posnr.
        ls_sub_item-uposv = <ls_vbdpa>-posnr.
      ENDIF.
      IF ls_sub_item-uposb LT <ls_vbdpa>-posnr AND
         ls_sub_item-uposv LT <ls_vbdpa>-posnr.
        ls_sub_item-uposb = <ls_vbdpa>-posnr.
      ENDIF.
      ls_sub_item-uepvw = <ls_vbdpa>-uepvw.    "UPOS usage
    ENDIF.
  ENDLOOP.
  IF ls_sub_item-uposv > 0.
    APPEND ls_sub_item TO ct_sub_items.
  ENDIF.
  SORT ct_sub_items.

  LOOP AT ct_sub_items INTO ls_sub_item.
    LOOP AT ut_vbdpa ASSIGNING <ls_vbdpa> WHERE posnr EQ ls_sub_item-uposv AND
                                                dragr EQ 'X'.
      DELETE TABLE ct_sub_items FROM ls_sub_item.
    ENDLOOP.
  ENDLOOP.


ENDFORM.                    " get_sub_items

*&---------------------------------------------------------------------*
*&      Form  assign_sub_items
*&---------------------------------------------------------------------*
FORM assign_sub_items
     USING    ut_sub_items   TYPE vbdpau_t
     CHANGING ct_item_detail TYPE sdoc_t_prt_item_detail.

  DATA:
    ls_sub_item              TYPE vbdpau.

  FIELD-SYMBOLS:
    <ls_item_detail>         TYPE sdoc_s_prt_item_detail.

* Treat subordinated items
  LOOP AT ut_sub_items INTO ls_sub_item.
    IF NOT <ls_item_detail>             IS ASSIGNED          OR
           <ls_item_detail>-vbdpa-posnr NE ls_sub_item-posnr.
      READ TABLE ct_item_detail ASSIGNING <ls_item_detail>
                                WITH KEY vbdpa-posnr = ls_sub_item-posnr
                                BINARY SEARCH.
      IF sy-subrc <> 0.
*        <gv_returncode> = sy-subrc.
*        message e000 with <gs_vbdka>-vbeln
*                     into gv_dummy.
*        perform protocol_update.
*        return.
        CONTINUE.
      ENDIF.
    ENDIF.
    APPEND ls_sub_item TO <ls_item_detail>-sub_items.
*   Set up control
    <ls_item_detail>-ex_sub_items = gc_true.
  ENDLOOP.

ENDFORM.                    " assign_sub_items

*&---------------------------------------------------------------------*
*&      Form  get_head_text
*&---------------------------------------------------------------------*
FORM get_head_text.

  DATA:
    ls_dd07v         TYPE dd07v.

  CONSTANTS:
    lc_vbtyp_invoice TYPE vbtyp VALUE 'M'.

* VBDKA-VBTYP
  IF gv_scenario EQ gc_cash_sale.
    READ TABLE gt_vbtyp_fix_values
         INTO ls_dd07v
         WITH KEY domvalue_l = lc_vbtyp_invoice.
  ELSE.
    READ TABLE gt_vbtyp_fix_values
         INTO ls_dd07v
         WITH KEY domvalue_l = <gs_vbdka>-vbtyp.
  ENDIF.

  IF sy-subrc IS INITIAL.
    gs_interface-head_detail-vbtyp_text = ls_dd07v-ddtext.
  ENDIF.

* VBDKA-VBTYP_VANG
  IF NOT <gs_vbdka>-vbeln_vang IS INITIAL.
    READ TABLE gt_vbtyp_fix_values
         INTO ls_dd07v
         WITH KEY domvalue_l = <gs_vbdka>-vbtyp_vang.
    IF sy-subrc IS INITIAL.
      gs_interface-head_detail-vbtyp_vang_text = ls_dd07v-ddtext.
    ENDIF.
  ENDIF.

ENDFORM.                    " get_head_text

*&---------------------------------------------------------------------*
*&      Form  get_item_characteristics
*&---------------------------------------------------------------------*
FORM get_item_characteristics
     CHANGING cs_item_detail TYPE sdoc_s_prt_item_detail.

  DATA:
    lt_conf TYPE TABLE OF conf_out,
    lt_cabn TYPE TABLE OF cabn,

    ls_conf TYPE conf_out,
    ls_cabn TYPE cabn.

  RANGES:
    lr_cabn FOR ls_cabn-atinn.

* Check appropriate config exists
  CHECK NOT cs_item_detail-vbdpa-cuobj IS INITIAL AND
            cs_item_detail-vbdpa-attyp NE var_typ.
* Get config data
  CALL FUNCTION 'VC_I_GET_CONFIGURATION'
    EXPORTING
      instance      = cs_item_detail-vbdpa-cuobj
      language      = gv_language
      print_sales   = gc_true
    TABLES
      configuration = lt_conf
    EXCEPTIONS
      OTHERS        = 4.
  IF sy-subrc <> 0.
*   Error whilst config data retrieval
    <gv_returncode> = sy-subrc.
    MESSAGE e001 WITH <gs_vbdka>-vbeln
                 INTO gv_dummy.
    PERFORM protocol_update.
    RETURN.
  ENDIF.
  IF NOT lt_conf IS INITIAL.
*   Transfer config data
    LOOP AT lt_conf INTO ls_conf.
      lr_cabn-option = gc_equal.
      lr_cabn-sign   = gc_include.
      lr_cabn-low    = ls_conf-atinn.
      COLLECT lr_cabn.
    ENDLOOP.
*   Get config characteristics
    CALL FUNCTION 'CLSE_SELECT_CABN'
      TABLES
        in_cabn        = lr_cabn
        t_cabn         = lt_cabn
      EXCEPTIONS
        no_entry_found = 1
        OTHERS         = 2.
    IF sy-subrc <> 0.
*     Error whilst config characteristic retrieval
      <gv_returncode> = sy-subrc.
      MESSAGE e001 WITH <gs_vbdka>-vbeln
                   INTO gv_dummy.
      PERFORM protocol_update.
      RETURN.
    ENDIF.
*   Transfer config characteristics
    SORT lt_cabn BY atinn.
    LOOP AT lt_conf INTO ls_conf.
      READ TABLE lt_cabn
           INTO ls_cabn
           WITH KEY atinn = ls_conf-atinn
           BINARY SEARCH.
      IF sy-subrc        NE 0             OR
         ( ls_cabn-attab EQ 'SDCOM' AND
           ls_cabn-atfel EQ 'VKOND'     ) OR
         ls_cabn-attab   EQ 'VCSD_UPDATE'.
        DELETE lt_conf.
      ENDIF.
    ENDLOOP.
    cs_item_detail-configuration = lt_conf.
    IF NOT cs_item_detail-configuration IS INITIAL.
*     Set up control
      cs_item_detail-ex_configuration = gc_true.
    ENDIF.
  ENDIF.

ENDFORM.                    " get_item_characteristics

*&---------------------------------------------------------------------*
*&      Form  GET_head_PRICES
*&---------------------------------------------------------------------*
FORM get_head_prices.

  DATA:
    ls_balmi TYPE balmi.

  IF gr_badi_print IS BOUND.
*   Call BAdI for preparation of head pricing
    CALL BADI gr_badi_print->prepare_head_prices
      EXPORTING
        is_interface = gs_interface
        iv_language  = gv_language
        is_nast      = nast
      CHANGING
        cs_komk      = gs_komk.
  ENDIF.

* Get the head prices
  IF gv_price_print_mode EQ chara.
    CALL FUNCTION 'RV_PRICE_PRINT_HEAD'
      EXPORTING
        comm_head_i = gs_komk
        language    = gv_language
      IMPORTING
        comm_head_e = gs_komk
      TABLES
        tkomv       = gt_komv
        tkomvd      = gs_interface-head_detail-conditions.
  ELSE.
    CALL FUNCTION 'RV_PRICE_PRINT_HEAD_BUFFER'
      EXPORTING
        comm_head_i = gs_komk
        language    = gv_language
      IMPORTING
        comm_head_e = gs_komk
      TABLES
        tkomv       = gt_komv
        tkomvd      = gs_interface-head_detail-conditions.
  ENDIF.

* Fill gross value
  gs_interface-head_detail-doc_currency = gs_komk-waerk.
  IF gs_komk-fkwrt GT gc_max_brtwr.
    gs_interface-head_detail-gross_value = gc_max_brtwr.
    IF cl_ops_switch_check=>sd_sfws_sc4( ) EQ abap_true.
*     Expose additional message
      MESSAGE i013(vd_pdf)
              WITH gc_max_brtwr gs_komk-fkwrt
              INTO gv_dummy.
      MOVE-CORRESPONDING sy TO ls_balmi.
      INSERT ls_balmi INTO TABLE gt_add_msg.
    ENDIF.

  ELSE.
    gs_interface-head_detail-gross_value = gs_komk-fkwrt.
  ENDIF.

  " capture value of supos in PDF document interface
*  gs_interface-head_detail-vbdka-supos = gs_komk-supos.

ENDFORM.                    " GET_head_PRICES

*&---------------------------------------------------------------------*
*&      Form  assign_cancel_dates
*&---------------------------------------------------------------------*
FORM assign_cancel_dates
     CHANGING ct_item_detail TYPE sdoc_t_prt_item_detail.

  DATA:
    ls_item_cancel_dates     TYPE vedpn.

  FIELD-SYMBOLS:
    <ls_item_detail>         TYPE sdoc_s_prt_item_detail.

* Treat cancellatrion of dates
  SORT gt_item_cancellation_dates BY vposn.
  LOOP AT gt_item_cancellation_dates INTO ls_item_cancel_dates.

    IF NOT <ls_item_detail>            IS ASSIGNED                   OR   <ls_item_detail>-vbdpa-posnr NE ls_item_cancel_dates-vposn.
      READ TABLE ct_item_detail
           ASSIGNING <ls_item_detail>
           WITH KEY vbdpa-posnr = ls_item_cancel_dates-vposn
           BINARY SEARCH.
      IF sy-subrc = 0.
        APPEND ls_item_cancel_dates TO <ls_item_detail>-cancellation_dates.
*         Set up control
        <ls_item_detail>-ex_cancellation_dates = gc_true.
      ENDIF.
    ENDIF.

  ENDLOOP.

ENDFORM.                    " assign_cancel_dates

*&---------------------------------------------------------------------*
*&      Form  get_item_serials
*&---------------------------------------------------------------------*
FORM get_item_serials
     CHANGING cs_item_detail TYPE sdoc_s_prt_item_detail.

  DATA:
    lt_sernos   TYPE TABLE OF rserob,
    lt_serials  TYPE TABLE OF riserls,

    ls_key_data TYPE rserob,
    ls_sernos   TYPE rserob,
    ls_serials  TYPE riserls.

* Set key data
  ls_key_data-taser   = 'SER02'.
  ls_key_data-sdaufnr = <gs_vbdka>-vbeln.
  ls_key_data-posnr   = cs_item_detail-vbdpa-posnr.
  IF     ls_key_data-sdaufnr IS INITIAL AND
     NOT ls_key_data-posnr   IS INITIAL.
*   Whilst creation the doc number might be initial: Use temp placeholder
    ls_key_data-sdaufnr = char$.
  ENDIF.

* Read the serialnumbers of the position.
  CALL FUNCTION 'GET_SERNOS_OF_DOCUMENT'
    EXPORTING
      key_data            = ls_key_data
    TABLES
      sernos              = lt_sernos
    EXCEPTIONS
      key_parameter_error = 1
      no_supported_access = 2
      no_data_found       = 3
      OTHERS              = 4.
  IF sy-subrc NE 0 AND
     sy-subrc NE 3.
*   Error occurred
*    <gv_returncode> = sy-subrc.
*    MESSAGE e002 WITH <gs_vbdka>-vbeln
*                 INTO gv_dummy.
    PERFORM protocol_update.
*    RETURN.
  ENDIF.
* Check any data has been retrieved
  CHECK sy-subrc EQ 0.
* Transfer serialnumbers
  LOOP AT lt_sernos INTO ls_sernos.
    ls_serials-vbeln = ls_sernos-sdaufnr.
    ls_serials-posnr = ls_sernos-posnr.
    ls_serials-sernr = ls_sernos-sernr.
    APPEND ls_serials TO lt_serials.
  ENDLOOP.
* Process the stringtable for Printing.
  CALL FUNCTION 'PROCESS_SERIALS_FOR_PRINT'
    EXPORTING
      i_boundary_left             = '(_'
      i_boundary_right            = '_)'
      i_sep_char_strings          = ',_'
      i_sep_char_interval         = '_-_'
      i_use_interval              = 'X'
      i_boundary_method           = 'C'
      i_line_length               = 70
      i_no_zero                   = 'X'
      i_alphabet                  = sy-abcde
      i_digits                    = '0123456789'
      i_special_chars             = '-'
      i_with_second_digit         = ' '
    TABLES
      serials                     = lt_serials
      serials_print               = cs_item_detail-serials
    EXCEPTIONS
      boundary_missing            = 01
      interval_separation_missing = 02
      length_to_small             = 03
      internal_error              = 04
      wrong_method                = 05
      wrong_serial                = 06
      two_equal_serials           = 07
      serial_with_wrong_char      = 08
      serial_separation_missing   = 09.
  IF sy-subrc NE 0.
    <gv_returncode> = sy-subrc.
    MESSAGE e002 WITH <gs_vbdka>-vbeln
                 INTO gv_dummy.
    PERFORM protocol_update.
    RETURN.
  ENDIF.

  IF NOT cs_item_detail-serials IS INITIAL.
*   Set up control
    cs_item_detail-ex_serials = gc_true.
  ENDIF.

ENDFORM.                    " get_item_serials

*&---------------------------------------------------------------------*
*&      Form  get_head_tvko
*&---------------------------------------------------------------------*
FORM get_head_tvko.

* Get TVKO
  CALL FUNCTION 'TVKO_SINGLE_READ'
    EXPORTING
      vkorg     = <gs_vbdka>-vkorg
    IMPORTING
      wtvko     = gs_interface-head_detail-tvko
    EXCEPTIONS
      not_found = 1
      OTHERS    = 2.
  IF sy-subrc <> 0.
    <gv_returncode> = sy-subrc.
    MESSAGE e003 WITH <gs_vbdka>-vbeln
                      <gs_vbdka>-vkorg
                 INTO gv_dummy.
    PERFORM protocol_update.
    RETURN.
  ENDIF.

ENDFORM.                    " get_head_tvko

*&---------------------------------------------------------------------*
*&      Form  get_item_correction_text
*&---------------------------------------------------------------------*
FORM get_item_correction_text
     CHANGING cs_item_detail TYPE sdoc_s_prt_item_detail.

  DATA:
    ls_vbtyp_desc LIKE LINE OF gt_vbtyp_fix_values,
    ls_tline      TYPE tline.

* Check correction text is necessary
  CHECK <gs_vbdka>-vbklt EQ vbklt_rech_korr.

  IF <gs_vbdka>-vbtyp = vbtyp_ganf.
*   Credit memo
    IF cs_item_detail-vbdpa-shkzg = gc_true.
*     Credit memo request
      READ TABLE gt_vbtyp_fix_values
           INTO ls_vbtyp_desc
           WITH KEY domvalue_l = vbtyp_ganf.
      cs_item_detail-correction_text = ls_vbtyp_desc-ddtext.
    ELSE.
*     Debit memo request
      READ TABLE gt_vbtyp_fix_values
           INTO ls_vbtyp_desc
           WITH KEY domvalue_l = vbtyp_lanf.
      cs_item_detail-correction_text = ls_vbtyp_desc-ddtext.
    ENDIF.
  ELSEIF <gs_vbdka>-vbtyp = vbtyp_lanf..
*   Debit memo
    IF cs_item_detail-vbdpa-shkzg = gc_false.
*     Debit memo request
      READ TABLE gt_vbtyp_fix_values
           INTO ls_vbtyp_desc
           WITH KEY domvalue_l = vbtyp_lanf.
      cs_item_detail-correction_text = ls_vbtyp_desc-ddtext.
    ELSE.
*     Credit memo request
      READ TABLE gt_vbtyp_fix_values
           INTO ls_vbtyp_desc
           WITH KEY domvalue_l = vbtyp_ganf.
      cs_item_detail-correction_text = ls_vbtyp_desc-ddtext.
    ENDIF.
  ENDIF.

ENDFORM.                    " get_item_correction_text

*&---------------------------------------------------------------------*
*&      Form  send_data
*&---------------------------------------------------------------------*
FORM send_data
     USING uv_device   TYPE output_device
           us_pdf_file TYPE fpformoutput.

  DATA:
    lt_mail_text       TYPE bcsy_text,
    lt_adsmtp          TYPE TABLE OF adsmtp,
    lt_adfax           TYPE TABLE OF adfax,

    ls_adsmtp          TYPE adsmtp,
    ls_adfax           TYPE adfax,
    ls_address         TYPE sdprt_addr_s,

    lv_date(14)        TYPE c,
    lv_mail_subject    TYPE so_obj_des,
    lv_send_to_all     TYPE os_boolean,
    lv_vbeln           TYPE vbeln.

  CHECK gv_screen_display NE gc_true.

* Construct the subject text
  if nast-TDCOVTITLE is initial.
    write <gs_vbdka>-audat to lv_date.
  WRITE <gs_vbdka>-vbeln TO lv_vbeln NO-ZERO.
  CONCATENATE gs_interface-head_detail-vbtyp_text
              lv_vbeln
              lv_date
         INTO lv_mail_subject
         SEPARATED BY space.
  else.
    lv_mail_subject = nast-TDCOVTITLE.
  endif.
  CASE uv_device.
    WHEN gc_device-email.
*     Get the e-mail-text
      PERFORM get_mail_body CHANGING lt_mail_text.
      CHECK <gv_returncode> IS INITIAL.
*     Get the e-mail address of the recipient
      ls_address-recip_email_addr = gs_nast-email_addr.
*     Get the e-mail address of the sender from sales org. or
*     user's e-mail as fallback
      CALL FUNCTION 'ADDR_COMM_GET'
        EXPORTING
          address_number    = gs_interface-head_detail-tvko-adrnr
          language          = gv_language
          table_type        = 'ADSMTP'
        TABLES
          comm_table        = lt_adsmtp
        EXCEPTIONS
          parameter_error   = 1
          address_not_exist = 2
          internal_error    = 3
          OTHERS            = 4.
      IF sy-subrc <> 0.
        <gv_returncode> = sy-subrc.
        PERFORM protocol_update.
        RETURN.
      ENDIF.
*     Transfer e-mail address
      READ TABLE lt_adsmtp INTO ls_adsmtp
           WITH KEY flgdefault = gc_true.
      IF sy-subrc IS INITIAL.
        ls_address-sender_email_addr = ls_adsmtp-smtp_addr.
      ENDIF.

    WHEN gc_device-fax.
*     Get the e-mail address of the recipient
      ls_address-recip_fax_country = gs_nast-tland.
      ls_address-recip_fax_number  = gs_nast-telfx(30).
*     Get the fax address of the sender from sales org. or
*     user's e-mail as fallback
      CALL FUNCTION 'ADDR_COMM_GET'
        EXPORTING
          address_number    = gs_interface-head_detail-tvko-adrnr
          language          = gv_language
          table_type        = 'ADFAX'
        TABLES
          comm_table        = lt_adfax
        EXCEPTIONS
          parameter_error   = 1
          address_not_exist = 2
          internal_error    = 3
          OTHERS            = 4.
      IF sy-subrc <> 0.
        <gv_returncode> = sy-subrc.
        PERFORM protocol_update.
        RETURN.
      ENDIF.
*     Transfer e-mail address
      READ TABLE lt_adfax INTO ls_adfax
           WITH KEY flgdefault = gc_true.

      IF sy-subrc IS INITIAL.
        ls_address-sender_fax_country = ls_adfax-country.
        ls_address-sender_fax_number  = ls_adfax-fax_number.
      ENDIF.
  ENDCASE.

* Send PDF data
  CALL FUNCTION 'SD_PDF_SEND_DATA'
    EXPORTING
      iv_device        = uv_device
      iv_email_subject = lv_mail_subject
      it_email_text    = lt_mail_text
      is_main_data     = us_pdf_file
      iv_language      = gv_language
      is_address       = ls_address
    IMPORTING
      ev_send_to_all   = lv_send_to_all
    EXCEPTIONS
      exc_document     = 1
      exc_send_request = 2
      exc_address      = 3
      OTHERS           = 4.
  IF sy-subrc <> 0.
*   Sending did fail
    MESSAGE e000 WITH <gs_vbdka>-vbeln
                 INTO gv_dummy.
    PERFORM protocol_update.
    <gv_returncode> = 99.
    RETURN.
  ENDIF.
  IF lv_send_to_all = gc_true.
*   Write success message into log
    MESSAGE i022(so)
            INTO gv_dummy.
    PERFORM protocol_update.
  ELSE.
*   Write fail message into log
    MESSAGE i023(so)
            WITH <gs_vbdka>-vbeln
            INTO gv_dummy.
    PERFORM protocol_update.
  ENDIF.

ENDFORM.                    " send_data

*&---------------------------------------------------------------------*
*&      Form  get_mail_body
*&---------------------------------------------------------------------*
FORM get_mail_body
     CHANGING ct_mail_text TYPE bcsy_text.

  DATA:
    lt_lines   TYPE TABLE OF tline,
    lt_otfdata TYPE TABLE OF itcoo,

    ls_options TYPE itcpo.

* Checkl a form does exist at all
  CHECK NOT tnapr-fonam IS INITIAL.
* Set data
  ls_options-tdgetotf = gc_true.
  ls_options-tddest   = gs_nast-ldest.
  ls_options-tdprogram = tnapr-pgnam.
  vbdka               = <gs_vbdka>.
  komk                = gs_komk.
  tvko                = gs_interface-head_detail-tvko.
* Open form
  CALL FUNCTION 'OPEN_FORM'
    EXPORTING
      dialog                      = ' '
      form                        = tnapr-fonam
      language                    = gv_language
      options                     = ls_options
    EXCEPTIONS
      canceled                    = 1
      device                      = 2
      form                        = 3
      options                     = 4
      unclosed                    = 5
      mail_options                = 6
      archive_error               = 7
      invalid_fax_number          = 8
      more_params_needed_in_batch = 9
      spool_error                 = 10
      codepage                    = 11
      OTHERS                      = 12.
  IF sy-subrc <> 0.
    <gv_returncode> = sy-subrc.
    PERFORM protocol_update.
    RETURN.
  ENDIF.
* Write form
  CALL FUNCTION 'WRITE_FORM'
    EXPORTING
      element                  = 'MAIL_BODY'
    EXCEPTIONS
      element                  = 1
      function                 = 2
      type                     = 3
      unopened                 = 4
      unstarted                = 5
      window                   = 6
      bad_pageformat_for_print = 7
      spool_error              = 8
      codepage                 = 9
      OTHERS                   = 10.
  IF sy-subrc <> 0.
    <gv_returncode> = sy-subrc.
    PERFORM protocol_update.
    RETURN.
  ENDIF.
* Close form
  CALL FUNCTION 'CLOSE_FORM'
    TABLES
      otfdata                  = lt_otfdata
    EXCEPTIONS
      unopened                 = 1
      bad_pageformat_for_print = 2
      send_error               = 3
      spool_error              = 4
      codepage                 = 5
      OTHERS                   = 6.
  IF sy-subrc <> 0.
    <gv_returncode> = sy-subrc.
    PERFORM protocol_update.
    RETURN.
  ENDIF.
* Convert form data
  CALL FUNCTION 'CONVERT_OTF'
    TABLES
      otf                   = lt_otfdata
      lines                 = lt_lines
    EXCEPTIONS
      err_max_linewidth     = 1
      err_format            = 2
      err_conv_not_possible = 3
      err_bad_otf           = 4
      OTHERS                = 5.
  IF sy-subrc <> 0.
    <gv_returncode> = sy-subrc.
    PERFORM protocol_update.
    RETURN.
  ENDIF.
  CALL FUNCTION 'CONVERT_ITF_TO_STREAM_TEXT'
    EXPORTING
      language    = gv_language
    TABLES
      itf_text    = lt_lines
      text_stream = ct_mail_text.

ENDFORM.                    " get_mail_body

*&---------------------------------------------------------------------*
*&      Form  get_output_params
*&---------------------------------------------------------------------*
FORM get_output_params
     CHANGING cs_outputparams  TYPE sfpoutputparams
              cs_docparams     TYPE sfpdocparams
              cv_device        TYPE output_device.

  DATA:
    ls_comm_values       TYPE szadr_comm_values,
    lv_comm_type         TYPE ad_comm,
    lv_otf_memory_switch TYPE c.


  CASE gs_nast-nacha.
    WHEN gc_nacha-external_send.
*     Send
      IF NOT gs_nast-tcode IS INITIAL.
        CALL FUNCTION 'ADDR_GET_NEXT_COMM_TYPE'
          EXPORTING
            strategy           = gs_nast-tcode
            address_type       = <gs_vbdka>-address_type
            address_number     = <gs_vbdka>-adrnr
            person_number      = <gs_vbdka>-adrnp
          IMPORTING
            comm_type          = lv_comm_type
            comm_values        = ls_comm_values
          EXCEPTIONS
            address_not_exist  = 1
            person_not_exist   = 2
            no_comm_type_found = 3
            internal_error     = 4
            parameter_error    = 5
            OTHERS             = 6.
        IF sy-subrc <> 0.
          <gv_returncode> = sy-subrc.
          PERFORM protocol_update.
          RETURN.
        ENDIF.
*       Proccess communication type
        CASE lv_comm_type.
          WHEN 'INT'.  "e-mail
            cs_outputparams-getpdf = gc_true.
            cv_device              = gc_device-email.
            gs_nast-email_addr     = ls_comm_values-adsmtp-smtp_addr.
          WHEN 'FAX'.
            cs_outputparams-getpdf = gc_true.
            cv_device              = gc_device-fax.
            gs_nast-telfx          = ls_comm_values-adfax-fax_number.

            " is user parameter that combines fax number and fax extension in output control defined?
            IF ( gv_output_comm_fax_ext = 'X' ).
              " has a fax extension been defined?  If so append it to the fax number...
              IF ( strlen( ls_comm_values-adfax-fax_extens ) > 0 ).
                " combine fax number and fax extension into fax number field..
                CONCATENATE gs_nast-telfx ls_comm_values-adfax-fax_extens INTO gs_nast-telfx.
              ENDIF.
            ENDIF.

            gs_nast-tland          = ls_comm_values-adfax-country.
          WHEN 'LET'.   "Printer
            cv_device              = gc_device-printer.
        ENDCASE.
      ELSE.
        cv_device                  = gc_device-printer.
      ENDIF.
    WHEN gc_nacha-printer.
*     Print
      cv_device                    = gc_device-printer.
    WHEN gc_nacha-fax.
*     Fax
      cs_outputparams-getpdf       = gc_true.
      cv_device                    = gc_device-fax.
  ENDCASE.

* The original document should be printed only once
  IF NOT gv_screen_display               IS INITIAL  AND
         gs_interface-head_detail-repeat EQ gc_false.
    cs_outputparams-noprint   = gc_true.
    cs_outputparams-nopributt = gc_true.
    cs_outputparams-noarchive = gc_true.
  ENDIF.
* Set up screen display
  IF gv_screen_display     = 'X'.
    cs_outputparams-preview = gc_true.
    cs_outputparams-getpdf  = gc_false.
  ELSEIF gv_screen_display = 'W'. "Web dynpro
    cs_outputparams-getpdf  = gc_true.
    cv_device               = gc_device-web_dynpro.
  ENDIF.
* Set basic data
  cs_outputparams-nodialog  = gc_true.
  cs_outputparams-dest      = gs_nast-ldest.
  cs_outputparams-copies    = gs_nast-anzal.
  cs_outputparams-dataset   = gs_nast-dsnam.
  cs_outputparams-suffix1   = gs_nast-dsuf1.
  cs_outputparams-suffix2   = gs_nast-dsuf2.
  cs_outputparams-cover     = gs_nast-tdocover.
  cs_outputparams-covtitle  = gs_nast-tdcovtitle.
  cs_outputparams-authority = gs_nast-tdautority.
  cs_outputparams-receiver  = gs_nast-tdreceiver.
  cs_outputparams-division  = gs_nast-tddivision.
  cs_outputparams-arcmode   = gs_nast-tdarmod.
  cs_outputparams-reqimm    = gs_nast-dimme.
  cs_outputparams-reqdel    = gs_nast-delet.
  cs_outputparams-senddate  = gs_nast-vsdat.
  cs_outputparams-sendtime  = gs_nast-vsura.

* Print Preview for CRM Web UI, printing button always active
  IF cl_ops_switch_check=>sd_sfws_sc3( ) EQ abap_true.
    CALL FUNCTION 'GET_OTF_MEMORY_SWITCH'
      IMPORTING
        ev_otf_memory_switch = lv_otf_memory_switch.
    IF lv_otf_memory_switch EQ abap_true.
      cs_outputparams-noprint   = gc_false.
    ENDIF.
  ENDIF.

* Set language and default language
  cs_docparams-langu     = gv_language.
  cs_docparams-replangu1 = <gs_vbdka>-spras_vko.
  cs_docparams-replangu2 = gc_english.
  cs_docparams-country   = <gs_vbdka>-land1.

* Archiving
  APPEND toa_dara TO cs_docparams-daratab.

ENDFORM.                    " get_output_params

*&---------------------------------------------------------------------*
*&      Form  initialize_data
*&---------------------------------------------------------------------*
FORM initialize_data.

  CLEAR:
    gt_vedpa,
    gt_vbtyp_fix_values,
    gt_item_cancellation_dates,
    gt_komv,

    gs_interface,
    gs_komk,
    gs_nast,

    gv_screen_display,
    gv_price_print_mode,
    gv_language,
    gv_scenario,
    gv_dummy,

    <gv_returncode>.

  IF gr_badi_print IS BOUND.
*   Call BAdI concerning initialization
    CALL BADI gr_badi_print->initialize_data.
  ENDIF.

  " is user parameter that combines fax number and fax extension in output control defined?
  GET PARAMETER ID 'OUTPUT_COMM_FAX_EXT' FIELD gv_output_comm_fax_ext.

ENDFORM.                    " initialize_data