/* @(#) $Id: //bas/710_REL/src/ca/cad/cadrftst.c#1 $ SAP */
/*--------------------------------------------------------------------*/
/*                                                                    */
/*  SAP AG Walldorf                                                   */
/*  SAP  Systeme, Anwendungen und Produkte in der Datenverarbeitung   */
/*                                                                    */
/*  (C) Copyright SAP AG 1995                                         */
/*                                                                   */
/*--------------------------------------------------------------------*/
/*  File: cadrftst.c                                                  */
/*--------------------------------------------------------------------*/
/*  program for testing the dialog rfc                                */
/*                                                                    */
/*  functions:                                                        */
/*  ---------                                                         */
/*                                                                    */
/*  change_bom_master_via_api  change BOM (Dialog RFC)                */
/*  change_bom_with_sub_items  change BOM w. sub items (no SAP dialog)*/
/*  change_document_via_api    change document          (RFC-API)     */
/*  connect_to_sap()           connet to SAP from the externl appl.   */
/*  create_bom_master_via_api  create BOM (Dialog RFC)                */
/*  create_bom_with_sub_items  create BOM w. sub items (no SAP dialog)*/
/*  create_document_via_api    create document          (RFC-API)     */
/*  display_bom_master_via_api display BOM (Dialog RFC)               */
/*  display_bom_with_sub_items display BOM w.sub items (no SAP dialog)*/
/*  DisplayMessage()           Display message                        */
/*  DisplayReturnMessage()     Display message returned by RFC call   */
/*  display_mat_master()       Display Mat.Master via dialog rfc      */
/*  display_mat_master_via_api Display Mat.Master via dia.rfc (API)   */
/*  read_document_via_api      read document data       (RFC-API)     */
/*  read_mat_master_via_api    Read Material Master data via RFC-API  */
/*  request_mat_master()       Request Mat.Master data via SAP CAD    */
/*  search_mat_via_class()     Search material via class ode          */
/*  search_mat_via_mcd()       Search material via matchcode          */
/*  RfcError()                 writes error messages into dev_rfc file*/
/*--------------------------------------------------------------------*/
/*  4.6C                                                              */
/*  P.  172131 091199 get rid of compiler errors sun                  */
/*  4.6A                                                              */
/*  Perf.66105 170599 new function create_material                    */
/*  4.5B                                                              */
/*  CORK011097 270199 new function create_document_via_api            */
/*                    new function change_document_via_api            */
/*                    new function read_document_via_api              */
/*  4.0A                                                              */
/*  BINK128033 101197 new function search_mat_via_class               */
/*                    new function search_mat_via_mcd                 */
/*  BINK123657 080997 delete define _OSF_SOURCE because of alpha osf  */
/*                    waring                                          */
/*  BINK123425 050997 new example read_mat_master_via_api             */
/*  BINK121255 110897 UNIX and Windows work in the same way (no motif */
/*                    dialogs any more)                               */
/*                    new funct. create,change,display BOM (SAP-GUI)  */
/*                    create,change,display BOM with sub items        */
/*                    (in blackground without SAP-GUI)                */
/*  BINK114073 060697 get rid of compiler warnings                    */
/*  BINK110955 150597 get rid of compiler warnings                    */
/*  3.0F                                                              */
/*  BINK097985 231096 get rid of compiler warnings                    */
/*  3.0E                                                              */
/*  BINK090600 120796 connect to SAP with function CadRfcOpen         */
/*  3.0A                                                              */
/*  BINK052794 020595 new                                             */
/*--------------------------------------------------------------------*/
/*                 !!!! Read this first !!!!                          */
/*                                                                    */
/*   call the test program CADRFTST with one of following usages:     */
/*                                                                    */
/*   usage 1: Display material master    (direct RFC call)            */
/*         2: Display material master    (CAD-RFC  call)              */
/*         3: Display material master    (CAD dialog call)            */
/*         4: Create Bill of Material    (CAD-RFC call)               */
/*         5: Change Bill of Material    (CAD-RFC call)               */
/*         6: Display Bill of Material   (CAD-RFC call)               */
/*         7: Create BOM with sub items  (CAD-RFC call, no SAP dialog)*/
/*         8: Change BOM with sub items  (CAD-RFC call, no SAP dialog)*/
/*         9: Display BOM with sub items (CAD-RFC call, no SAP dialog)*/
/*        10: Read material master data  (CAD-RFC call, no SAP dialog)*/
/*        11: Search Material via Mcode  (CAD-RFC call)               */
/*        12: Search Material via Class  (CAD-RFC call)               */
/*        13: Create Document            (CAD-RFC call)               */
/*        14: Change Document            (CAD-RFC call)               */
/*        15: Read Document Data         (CAD-RFC call)               */
/*        16: Create Material            (CAD-RFC call)               */
/*                                                                    */
/*   Parameters that are necessary to establish the connection with   */
/*   the SAP system must be maintained in file CADRFC.INI.            */
/*                                                                    */
/*   To run the functions successfully you should create material     */
/*   master records with following material numbers in the SAP system.*/
/*   Please maintain only the view 'Basic Data' for these materials   */
/*   1) AH01                                                          */
/*   2) AH02                                                          */
/*   3) AH03                                                          */
/*   4) AH04                                                          */
/*                                                                    */
/*   You should also create following document info record:           */
/*   document number:  AH01                                           */
/*   document type:    DRW                                            */
/*   document part:    000                                            */
/*   document version: 00                                             */
/*--------------------------------------------------------------------*/

#define _XOPEN_SOURCE_EXTENDED 1             /* 060697 */
#define _HPUX_SOURCE           1             /* 060697 */
#define _ALL_SOURCE            1             /* 060697 */
#define __EXTENSIONS__         1             /* 060697 */

#include "saptype.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>

/* RFC libraries */
#include "saprfc.h"
#include "sapitab.h"

/* Header file needed for call in display_mat_master_via_api() */
#include "cadrfc.h"

/* Header file needed for call in request_mat_master() */
#include "caddialg.h"

#if defined(SAPonWINDOWS) || defined(SAPonNT)
#include <windows.h>
int PASCAL WinMain (HANDLE, HANDLE, LPSTR, int);
#endif

/* function  prototypes */
int reconnect_to_sap(int, char **);           /* 150597 */
int connect_to_sap(void);                     /* 150597 */
int display_mat_master(void);                 /* 150597 */
int display_mat_master_via_api(void);         /* 150597 */
int request_mat_master(char **);              /* 150597 */
int create_bom_master_via_api(void);          /* 050897 */
int change_bom_master_via_api(void);          /* 050897 */
int display_bom_master_via_api(void);         /* 050897 */
int create_bom_with_sub_items(void);          /* 110897 */
int change_bom_with_sub_items(void);          /* 110897 */
int display_bom_with_sub_items(void);         /* 110897 */
int read_mat_master_via_api(void);            /* 050997 */
int search_mat_via_mcd(void);                 /* 101197 */
int search_mat_via_class(void);               /* 101197 */
int create_document_via_api(void);            /* 271199 */
int change_document_via_api(void);            /* 271199 */
int read_document_via_api(void);              /* 271199 */
int create_material(void);                    /* 170599 */

void RfcError(char *);                        /* 150597 */
void DisplayMessage(int);                     /* 150597 */
void DisplayReturnMessage(CadRfcImportField*, int);

/* external used function from cadrfcxx.dll */
int  GetFileEntry (char *, char *, char *, char *);

/* global variables needed in SAP CAD function library APIs */
SAPHD          hd;
char           *sapmes;
char           *rcvstr;

/* global variables needed in RFC calls */
RFC_RC              CadRfcRc;
RFC_HANDLE          handle;

CadRfcExportField   *pExportData;
CadRfcImportField   *pImportData;
DRAW_RFC            *pDocumentData;
BICSK               *MaterialHeaderData;
/* the values below were initialised to ITAB_NULL, but that results
   an implicit conversion: void* to void**: this could hardly be intended! */ 
ITAB_H              *SapFieldData = NULL; /* ITAB_NULL; */
ITAB_H              *DmsCharac    = NULL; /* ITAB_NULL; */
ITAB_H              *ObjCharac    = NULL; /* ITAB_NULL; */

char messagex[400];
char ux_mess[4000];
int  rc=0;
char *argv_glob[2];

/*--------------------------------------------------------------------*/
/* int WinMain for MS-Windows and MS-WindowsNT                        */
/* int main    for UNIX                                               */
/*--------------------------------------------------------------------*/
/* main starting routine of cadrftst                                  */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   hInstance        WinMain                               */
/*             hPrevInstance       "                                  */
/*             lpszCmdLine         "                                  */
/*             nCmdShow            "                                  */
/*             __argc           main and WinMain                      */
/*             __argv                 "                               */
/*   OUTPUT:   ----             -----                                 */
/*--------------------------------------------------------------------*/
/*   Return:   rc               exit code                             */
/*--------------------------------------------------------------------*/
/*   110897    changed to start with parameter 1 - 9                  */
/*             Unix and Windows work in the same way !                */
/*--------------------------------------------------------------------*/
#if defined(SAPonWINDOWS) || defined(SAPonNT)
int PASCAL WinMain (HANDLE  hInstance,
                    HANDLE  hPrevInstance,
                    LPSTR   lpszCmdLine,
                    int nCmdShow)
#else
int main( int __argc, char ** __argv )
#endif

{
#if defined(SAPonWINDOWS) || defined(SAPonNT)
  extern char ** __argv;
  extern int  __argc;
#endif

  int  rc = 0, order = 1;

  printf("\n\n***************************************************************\n");
  printf("*                    CAD-RFC Test Program 4.6A                *\n");
  printf("***************************************************************\n\n");

  /* Print possible parameters if no parameter is specified */
  if (__argc < 2 || strncmp(__argv[1],"/r3connect",10) == 0) {

    DisplayMessage(2);
    exit(1);
  }

  /* one parameter is specified */
  if (__argc == 2) 
  {
    order = atoi(__argv[1]);
    if ( order < 1 || order > 16)
    {
       DisplayMessage(2);
       exit(1);
    }
  }

  /* connect from the external application to SAP */
  rc = connect_to_sap();
  if (rc != 0) return(rc);

  /* Displaying mat.master via dialog RFC (direct RFC call) */
  if (order == 1)
  {
    DisplayMessage(1);
    rc = display_mat_master();
  }

  /* Displaying mat.master via dialog RFC (with API)   */
  else if (order == 2)
  {
    DisplayMessage(3);
    rc = display_mat_master_via_api();
  }

  /* Retrieving mat.master infos with SAP CAD function library call  */
  else if (order == 3)
  {
    DisplayMessage(4);
    rc = request_mat_master(__argv);
  }

  /* create bill of material via dialog RFC (with API) */
  else if (order == 4)
  {
    DisplayMessage(18);
    rc = create_bom_master_via_api();
  }

  /* Change bill of material via dialog RFC (with API) */
  else if (order == 5)
  {
    DisplayMessage(19);
    rc = change_bom_master_via_api();
  }

  /* Display bill of material via dialog RFC (with API) */
  else if (order == 6)
  {
    DisplayMessage(20);
    rc = display_bom_master_via_api();
  }

  /* create BOM with sub items (with API) */
  else if (order == 7)
  {
    DisplayMessage(26);
    rc = create_bom_with_sub_items();
  }

  /* change BOM with sub items (with API) */
  else if (order == 8)
  {
    DisplayMessage(27);
    rc = change_bom_with_sub_items();
  }

  /* display BOM with sub items (with API) */
  else if (order == 9)
  {
    DisplayMessage(28);
    rc = display_bom_with_sub_items();
  }

  /* read material master data (with API) */
  else if (order == 10)
  {
    DisplayMessage(34);
    rc = read_mat_master_via_api();
  }

  /* search material via matchcode (CAD-RFC call) */
  else if (order == 11)
  {
    DisplayMessage(35);
    rc = search_mat_via_mcd();
  }

  /* search material via class (CAD-RFC call) */
  else if (order == 12)
  {
    DisplayMessage(36);
    rc = search_mat_via_class();
  }
   
  /* create document (CAD-RFC call) */
  else if (order == 13)                                /* 270199 */
  {                                                    /* 270199 */
    DisplayMessage(39);                                /* 270199 */
    rc = create_document_via_api();                    /* 270199 */
  }                                                    /* 270199 */

  /* change document (CAD-RFC call) */
  else if (order == 14)                                /* 270199 */
  {                                                    /* 270199 */
    DisplayMessage(40);                                /* 270199 */
    rc = change_document_via_api();                    /* 270199 */
  }                                                    /* 270199 */

  /* read document data (CAD-RFC call) */
  else if (order == 15)                                /* 270199 */
  {                                                    /* 270199 */
    DisplayMessage(41);                                /* 270199 */
    rc = read_document_via_api();                      /* 270199 */
  }                                                    /* 270199 */

  /* create material master (CAD-RFC call) */
  else if (order == 16)                                /* 170599 */
  {                                                    /* 170599 */
    DisplayMessage(45);                                /* 170599 */
    rc = create_material();                            /* 170599 */
  }                                                    /* 170599 */

  else
  {
    DisplayMessage(25);
  }

  /* Terminating RFC connection */

  printf("\nTerminate connection\n");
  RfcClose(handle);
  return(rc);
}

/*--------------------------------------------------------------------*/
/* void  RfcError                                                    */
/*--------------------------------------------------------------------*/
/* RFC error handling. Write message in dev_rfc file                  */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   operation        RFC operation code                    */
/*   OUTPUT:   ----             -----                                 */
/*--------------------------------------------------------------------*/
/*   Return:   ----             -----                                 */
/*--------------------------------------------------------------------*/
void RfcError( char * operation )
{
  FILE *fp;

#if defined (SAPonWINDOWS)
  RFC_ERROR_INFO    error_info;                             /* 110897 */
#else
  RFC_ERROR_INFO_EX error_info;                             /* 110897 */
#endif

  char *envp;
  char finame[133];
  char dirsign;

  memset(finame, 0, sizeof(finame));

  /* get CADRFC environment variable for logfile                        */

  envp=getenv("CADRFC");
  if (envp == NULL) {
    fp = fopen("./dev_rfc","a");

    /* When impossible to access file in working dir -> use home dir      */

    if (fp == 0) {
      envp=getenv("HOME");
      if (envp == NULL) return;

      strcpy(finame,envp);
      dirsign = finame[strlen(finame)-1];
      if (dirsign != '/' && dirsign != '\\') strcat(finame,"/");

      strcat(finame,"dev_rfc");
      fp = fopen(finame , "a");
      if (fp  == NULL) return;
    }
  }
  else {

    /* try environment variable                                          */

    strcpy(finame, envp);
    dirsign = finame[strlen(finame)-1];
    if (dirsign != '/' && dirsign != '\\') strcat(finame,"/");

    strcat(finame,"dev_rfc");
    fp = fopen(finame , "a");
    if (fp == NULL) return;
  }

  fprintf( fp, "\n%s in CADRFTST\n", operation );
  memset( &error_info, 0, sizeof( error_info ) );
#if defined (SAPonWINDOWS)
  RfcLastError( &error_info );                            /* 110897 */
#else
  RfcLastErrorEx( &error_info );                          /* 110897 */
#endif
  fprintf( fp, "Error info :\n" );
  fprintf( fp, "key        : %s\n", error_info.key );
  fprintf( fp, "message    : %s\n", error_info.message );
  fclose(fp);
  return;
}


/*--------------------------------------------------------------------*/
/* int connect_to_sap                                                 */
/*--------------------------------------------------------------------*/
/* Routine for connecting to SAP (possible from 3.0C)                 */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ----             -----                                 */
/*   OUTPUT:   ----             -----                                 */
/*--------------------------------------------------------------------*/
/*   Return:   rc               return code                           */
/*--------------------------------------------------------------------*/
int connect_to_sap() {

  int retcod;
  char message[256];

  /* connect to the SAP-System                   */
  /* get connect parameter from CADRFC.INI file */

  printf("Establish the connection ...\n");

  retcod = CadRfcOpen ( "", "", "", "", "", "", "", &handle);

  /* error establishing the connection */
  if( retcod != 0 ) 
  {
     /* get last error message */
     CadRfcGetLastError(message);

     if (strlen(message) > 0)
       printf("%s\n", message);
     else
       DisplayMessage(17);

     return(17);
  }

  printf("<- OK\n");

  /* Intialize API Interface (must be done one time before the first api call) */

  retcod = CadRfcAllocMemory(&pExportData, &pImportData,
                             &MaterialHeaderData, &pDocumentData);

  if (retcod != (int) RFC_OK) 
  {
    DisplayMessage(12);
    return(12);
  }

  /* Give RFC handle to API lib  */

  retcod = CadRfcSetHandle(&handle);

  if (retcod != (int) RFC_OK)
  {
    DisplayMessage(32);
    return(32);
  }

  return(0);
}



/*--------------------------------------------------------------------*/
/* int display_mat_master                                             */
/*--------------------------------------------------------------------*/
/* Routine calls a dialog RFC for displaying a mat. master            */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ----             ----                                  */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   rc               return code                           */
/*--------------------------------------------------------------------*/
int display_mat_master() {
  RFC_PARAMETER exporting[8];
  RFC_TABLE     tables[8];
  char *        exception_ptr;
  RFC_PARAMETER importing[8];
  char          Material[18];
  char          FunctionCode[14];

/* the next two definitions are necassary to define the two table    */
/* structures which are used in the Mat.Master Display RFC           */
#ifndef SAP_ST_SAP_FIELD_DATA
#define SAP_ST_SAP_FIELD_DATA
  typedef struct
    {
    RFC_CHAR Fieldmulti[40];
    RFC_CHAR Fieldname[35];
    RFC_CHAR Fieldvalue[255];
    } SAP_FIELD_DATA;
#endif

#ifndef SAP_ST_CLASS_CHARACTERISTICS
#define SAP_ST_CLASS_CHARACTERISTICS
  typedef struct
    {
    RFC_CHAR Atnam[30];
    RFC_CHAR Atbez[30];
    RFC_CHAR Atwrt[30];
    RFC_CHAR Dinkb[3];
    RFC_CHAR Unit[6];
    } CLASS_CHARACTERISTICS;
#endif

  ITAB_H SapFieldData = ITAB_NULL;
  ITAB_H DmsCharac    = ITAB_NULL;

  /* initialize table for SAP_FIELD_DATA                              */

  SapFieldData = ItCreate ("SAP_FIELD_DATA", sizeof (SAP_FIELD_DATA), 0, 0);
  if (SapFieldData == ITAB_NULL) {
    DisplayMessage(9);
    return(9);
  }

  /* initialize table for Class-Characteristics                       */

  DmsCharac = ItCreate ("CLASS_CHARACTERISTICS", sizeof (CLASS_CHARACTERISTICS), 0, 0);
  if (DmsCharac == ITAB_NULL) {
    DisplayMessage(10);
    return(10);
  }

  /* Fill in material master number which should be displayed         */

  memset(Material,' ', sizeof(Material));
  memcpy(Material,"AH01",4);

  memset(FunctionCode,' ', sizeof(FunctionCode));

  exporting[0].name = "MATERIAL";
  exporting[0].nlen = 8;
  exporting[0].addr = Material;
  exporting[0].leng = sizeof(Material);
  exporting[0].type = TYPC;
  exporting[1].name = NULL;
  importing[0].name = "FUNCTION_CODE";
  importing[0].nlen = 13;
  importing[0].addr = FunctionCode;
  importing[0].leng = sizeof(FunctionCode);
  importing[0].type = TYPC;
  importing[1].name = NULL;
  tables[0].name     = "SAP_FIELD_DATA";
  tables[0].nlen     = 14;
  tables[0].type     = TYPC;
  tables[0].ithandle = SapFieldData;
  tables[0].leng     = sizeof(SAP_FIELD_DATA);
  tables[0].itmode   = RFC_ITMODE_BYREFERENCE;
  tables[1].name     = "DMS_CLASS_DATA";
  tables[1].nlen     = 14;
  tables[1].type     = TYPC;
  tables[1].ithandle = DmsCharac;
  tables[1].leng     = sizeof(CLASS_CHARACTERISTICS);
  tables[1].itmode   = RFC_ITMODE_BYREFERENCE;
  tables[2].name     = NULL;

  CadRfcRc = RfcCallReceive( handle, "RFC_DISPLAY_MATERIAL_MASTER",
                             exporting, importing, tables,
                             &exception_ptr );
  if (CadRfcRc != RFC_OK) {
    DisplayMessage(11);
    return(11);
  }

  printf("<- OK\n");

  return(0);
}



/*--------------------------------------------------------------------*/
/* int display_mat_master_via_api                                     */
/*--------------------------------------------------------------------*/
/* Routine calls a dialog RFC for displaying a mat. master            */
/* Routine uses a call out of the CAD dialog rfc library              */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ----             ----                                  */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   rc               return code                           */
/*--------------------------------------------------------------------*/
int display_mat_master_via_api() {
  
  int                   rc;

  /* Fill in material master number which should be displayed         */
  /* Call mat.master display API                                      */

  memcpy(pExportData->Material,"AH01",4);

  rc = CadRfcMatDisplay(pExportData, pImportData, &SapFieldData, &DmsCharac);

  (void) DisplayReturnMessage(pImportData,13);
  if (rc != (int) RFC_OK) {
    return(13);
  }

  printf("<- OK\n");

  return(0);
}


/*--------------------------------------------------------------------*/
/* int create_bom_master_via_api                                      */
/*--------------------------------------------------------------------*/
/* Routine calls a dialog RFC for creating a BOM                      */
/* Routine uses a call out of the CAD dialog rfc library              */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ----             ----                                  */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   rc               return code                           */
/*--------------------------------------------------------------------*/
int create_bom_master_via_api() {

  int                   rc;

  /* fill BOM header */

  memcpy(MaterialHeaderData->Matnr, "AH01", 4);             /* material number */
  memcpy(MaterialHeaderData->Stlan, "1", 1);                /* BOM usage       */
  memcpy(MaterialHeaderData->Stktx, "BOM short text", 14);  /* BOM text        */
    
  /* fill BOM items */
  
  CadRfcWriteBomTabEntry("IDNRK", "AH02",1);                /* material number */
  CadRfcWriteBomTabEntry("POSNR", "10",1);                  /* item number     */
  CadRfcWriteBomTabEntry("POSTP", "L",1);                   /* item type       */
  CadRfcWriteBomTabEntry("MENGE", "1",1);                   /* quantity        */

  CadRfcWriteBomTabEntry("IDNRK", "AH03",2);
  CadRfcWriteBomTabEntry("POSNR", "20",2);
  CadRfcWriteBomTabEntry("POSTP", "L",2);
  CadRfcWriteBomTabEntry("MENGE", "1",2);

  CadRfcWriteBomTabEntry("", "",0);

  /* Call BOM create API */
  
  rc = CadRfcBomCreate(MaterialHeaderData, pImportData, &SapFieldData, &DmsCharac);

  (void) DisplayReturnMessage(pImportData,29);

  if (rc != (int) RFC_OK) {
    return(29);
  }

  printf("<- OK\n");

  return(0);
}

/*--------------------------------------------------------------------*/
/* int change_bom_master_via_api                                      */
/*--------------------------------------------------------------------*/
/* Routine calls a dialog RFC for changing a BOM                      */
/* Routine uses a call out of the CAD dialog rfc library              */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ----             ----                                  */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   rc               return code                           */
/*--------------------------------------------------------------------*/
int change_bom_master_via_api() {

  int                   rc;

  /* fill BOM header */

  memcpy(MaterialHeaderData->Matnr, "AH01", 4);
  memcpy(MaterialHeaderData->Stlan, "1", 1);
  memcpy(MaterialHeaderData->Stlal, "1", 1);
  memcpy(MaterialHeaderData->Stktx, "BOM short text new", 18);
    
  /* fill BOM items */
  
  CadRfcWriteBomTabEntry("IDNRK", "AH02",1);
  CadRfcWriteBomTabEntry("POSNR", "10",1);
  CadRfcWriteBomTabEntry("POSTP", "L",1);
  CadRfcWriteBomTabEntry("MENGE", "1",1);

  CadRfcWriteBomTabEntry("IDNRK", "AH03",2);
  CadRfcWriteBomTabEntry("POSNR", "20",2);
  CadRfcWriteBomTabEntry("POSTP", "L",2);
  CadRfcWriteBomTabEntry("MENGE", "1",2);

  CadRfcWriteBomTabEntry("IDNRK", "AH04",3);
  CadRfcWriteBomTabEntry("POSNR", "30",3);
  CadRfcWriteBomTabEntry("POSTP", "L",3);
  CadRfcWriteBomTabEntry("MENGE", "1",3);

  CadRfcWriteBomTabEntry("", "",0);

  /* Call BOM change API */
  
  rc = CadRfcBomChange(MaterialHeaderData, pImportData, &SapFieldData, &DmsCharac);

  (void) DisplayReturnMessage(pImportData,30);

  if (rc != (int) RFC_OK) {
    return(30);
  }

  printf("<- OK\n");

  return(0);
}

/*--------------------------------------------------------------------*/
/* int display_bom_master_via_api                                     */
/*--------------------------------------------------------------------*/
/* Routine calls a dialog RFC for displaying a BOM                    */
/* Routine uses a call out of the CAD dialog rfc library              */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ----             ----                                  */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   rc               return code                           */
/*--------------------------------------------------------------------*/
int display_bom_master_via_api() {

  int                   rc;

  /* fill BOM header */

  memcpy(pExportData->Material, "AH01", 4);
  memcpy(pExportData->BomAction, "5", 1);
  memcpy(pExportData->BomAlternative, "1", 1);
  memcpy(pExportData->BomType, "1", 1);
    
  /* Call BOM create API */
  
  rc = CadRfcBomDisplay(pExportData, pImportData, &SapFieldData, &DmsCharac);

  (void) DisplayReturnMessage(pImportData,31);

  if (rc != (int) RFC_OK) {
    return(31);
  }

  printf("<- OK\n");

  return(0);
}

/*--------------------------------------------------------------------*/
/* int create_bom_with_sub_items                                      */
/*--------------------------------------------------------------------*/
/* This function creates a BOM with sub items in background           */
/* No SAP dialog appears                                              */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ----             ----                                  */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   rc               return code                           */
/*--------------------------------------------------------------------*/
int create_bom_with_sub_items() {

  int                   rc;
  
  /* fill bom header */
  
  memcpy(MaterialHeaderData->Matnr, "AH01", 4);              /* material number */
  memcpy(MaterialHeaderData->Stlan, "1", 1);                 /* BOM usage       */
  memcpy(MaterialHeaderData->Stktx, "BOM short text", 14);   /* short text      */
    
  /* fill BOM items */
  
  CadRfcWriteBomTabEntry("UPSKZ", "X",1);                    /* flag, sub items */
  CadRfcWriteBomTabEntry("IDNRK", "AH02",1);                 /* material number */
  CadRfcWriteBomTabEntry("POSNR", "10",1);                   /* item number     */
  CadRfcWriteBomTabEntry("POSTP", "L",1);                    /* item type       */
  CadRfcWriteBomTabEntry("MENGE", "1",1);                    /* quantity        */

  CadRfcWriteBomTabEntry("UPSKZ", "X",2);   
  CadRfcWriteBomTabEntry("IDNRK", "AH03",2);
  CadRfcWriteBomTabEntry("POSNR", "20",2);
  CadRfcWriteBomTabEntry("POSTP", "L",2);
  CadRfcWriteBomTabEntry("MENGE", "1",2);

  CadRfcWriteBomTabEntry("IDNRK", "AH04",3);
  CadRfcWriteBomTabEntry("POSNR", "30",3);
  CadRfcWriteBomTabEntry("POSTP", "L",3);
  CadRfcWriteBomTabEntry("MENGE", "1",3);

  CadRfcWriteBomTabEntry("", "",0);

  /* fill BOM sub items */

  /* sub item number 1 for item tab entry number 1 */
  CadRfcWriteBomSubItemEntry("POSID", "1",1);               /* number of item       */
  CadRfcWriteBomSubItemEntry("EBORT", "Left",1);            /* location             */
  CadRfcWriteBomSubItemEntry("UPMNG", "1",1);               /* quantity of sub item */
  CadRfcWriteBomSubItemEntry("UPOSZ", "1",1);               /* sub item number      */
  CadRfcWriteBomSubItemEntry("UPTXT", "Position: Left",1);  /* sub item text        */

  /* sub item number 2 for item tab entry number 1 */
  CadRfcWriteBomSubItemEntry("POSID", "1",2);
  CadRfcWriteBomSubItemEntry("EBORT", "Right",2);
  CadRfcWriteBomSubItemEntry("UPMNG", "1",2);
  CadRfcWriteBomSubItemEntry("UPOSZ", "2",2);
  CadRfcWriteBomSubItemEntry("UPTXT", "Position: Right",2);

  /* sub item number 1 for item tab entry number 2 */
  CadRfcWriteBomSubItemEntry("POSID", "2",3);
  CadRfcWriteBomSubItemEntry("EBORT", "Bottom",3);
  CadRfcWriteBomSubItemEntry("UPMNG", "1",3);
  CadRfcWriteBomSubItemEntry("UPOSZ", "1",3);
  CadRfcWriteBomSubItemEntry("UPTXT", "Position: Bottom",3);

  /* sub item number 2 for item tab entry number 2 */
  CadRfcWriteBomSubItemEntry("POSID", "2",4);
  CadRfcWriteBomSubItemEntry("EBORT", "Top",4);
  CadRfcWriteBomSubItemEntry("UPMNG", "1",4);
  CadRfcWriteBomSubItemEntry("UPOSZ", "2",4);
  CadRfcWriteBomSubItemEntry("UPTXT", "Position: Top",4);

  CadRfcWriteBomSubItemEntry("", "",0);

  /* Call BOM create (API) */
  
  rc = CadBomCreateSubItem(MaterialHeaderData, pImportData, &SapFieldData, &DmsCharac);

  (void) DisplayReturnMessage(pImportData,24);

  /* error occured */
  if (rc != (int) RFC_OK )
  {
     /* application error */
     if ( rc == 99 ) return(99);
     else            return(24);
  }

  printf("<- OK\n");

  return(0);
}

/*--------------------------------------------------------------------*/
/* int change_bom_with_sub_items                                      */
/*--------------------------------------------------------------------*/
/* This function changes a BOM with sub items in background           */
/* No SAP dialog appears                                              */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ----             ----                                  */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   rc               return code                           */
/*--------------------------------------------------------------------*/
int change_bom_with_sub_items() {

  CSRFCITEM             ItemData;
  CSSUBITEM             SubItemData;
  int                   rc, index_item, index_sub_item, iPosid;
  char                  sPosnr[5], sIdnrk[19], sPostp[2],
                        sPosid[5], sEbort[21], sUposz[5], sUptxt[41];

  /* fill bom header */

  memcpy(MaterialHeaderData->Matnr, "AH01", 4);      /* material number */
  memcpy(MaterialHeaderData->Stlan, "1", 1);         /* BOM usage       */
  memcpy(MaterialHeaderData->Stlal, "1", 1);         /* BOM alternative */
    
  /* Display BOM data for change */
  
  rc = CadBomChangeSubItemRead(MaterialHeaderData, pImportData, &SapFieldData, &DmsCharac);

  (void) DisplayReturnMessage(pImportData,23);

  /* error occured */
  if (rc != (int) RFC_OK )
  {
    /* application error */
    if ( rc == 99 ) return(99);
    else            return(23);
  }

  printf("<- OK\n");
  
  index_item = 1;

  /* print existing BOM data */
  while ( CadRfcGetBomItemEntry(index_item, &ItemData) == 0)
  {
    memcpy(sPosnr,ItemData.Posnr,sizeof(ItemData.Posnr) );
    sPosnr[sizeof(ItemData.Posnr)] = '\0';

    memcpy(sIdnrk,ItemData.Idnrk,sizeof(ItemData.Idnrk));
    sIdnrk[sizeof(ItemData.Idnrk)] = '\0';

    memcpy(sPostp,ItemData.Postp,sizeof(ItemData.Postp));
    sPostp[sizeof(ItemData.Postp)] = '\0';

    printf("Item:     %s %s %s\n",sPosnr, sIdnrk, sPostp);
    if (ItemData.Upskz[0] == 'X')
    {
      index_sub_item = 1;

      /* get all sub items for an item */
      while ( CadRfcGetBomSubItemEntry(index_sub_item, &SubItemData) == 0)
      {
         iPosid = atoi( (char*)SubItemData.Posid );
         if ( iPosid == index_item )
         {
           memcpy(sUposz,SubItemData.Uposz,sizeof(SubItemData.Uposz) );
           sUposz[sizeof(SubItemData.Uposz)] = '\0';

           memcpy(sEbort,SubItemData.Ebort,sizeof(SubItemData.Ebort) );
           sEbort[sizeof(SubItemData.Ebort)] = '\0';

           memcpy(sUptxt,SubItemData.Uptxt,sizeof(SubItemData.Uptxt) );
           sUptxt[sizeof(SubItemData.Uptxt)] = '\0';

           memcpy(sPosid,SubItemData.Posid,sizeof(SubItemData.Posid) );
           sPosid[sizeof(SubItemData.Posid)] = '\0';

           printf("Sub Item: %s %s %20s %s\n",sUposz,sEbort,sUptxt,sPosid);
         }
         index_sub_item++;
      }
    }
    index_item++;
  }

  /* fill BOM header data */

  memset(MaterialHeaderData->Matnr, ' ', sizeof(MaterialHeaderData->Matnr));
  memcpy(MaterialHeaderData->Matnr, "AH01", 4);

  memset(MaterialHeaderData->Stlan, ' ', sizeof(MaterialHeaderData->Stlan));
  memcpy(MaterialHeaderData->Stlan, "1", 1);

  memset(MaterialHeaderData->Stlal, ' ', sizeof(MaterialHeaderData->Stlal));
  memcpy(MaterialHeaderData->Stlal, "1", 1);

  memset(MaterialHeaderData->Stktx, ' ', sizeof(MaterialHeaderData->Stktx));
  memcpy(MaterialHeaderData->Stktx, "new BOM text", 12);

  /* fill new BOM items */
  /* All items and sub items must be written to the item tables with the    */
  /* changed item data again.                                               */
  /* If entry number = 1 the old table is deleted and a new one is created. */

  /* item 1 with sub items */
  CadRfcWriteBomTabEntry("UPSKZ", "X",1);                /* flag: sub items */
  CadRfcWriteBomTabEntry("IDNRK", "AH02",1);             /* material number */
  CadRfcWriteBomTabEntry("POSNR", "10",1);               /* item number     */
  CadRfcWriteBomTabEntry("POSTP", "L",1);                /* item type       */
  CadRfcWriteBomTabEntry("MENGE", "1",1);                /* quantity        */

  /* item 2 with sub items */
  CadRfcWriteBomTabEntry("IDNRK", "AH03",2);
  CadRfcWriteBomTabEntry("POSNR", "20",2);
  CadRfcWriteBomTabEntry("POSTP", "L",2);
  CadRfcWriteBomTabEntry("MENGE", "1",2);

  /* item 3 no sub items */
  CadRfcWriteBomTabEntry("UPSKZ", "X",3); 
  CadRfcWriteBomTabEntry("IDNRK", "AH04",3);
  CadRfcWriteBomTabEntry("POSNR", "30",3);
  CadRfcWriteBomTabEntry("POSTP", "L",3);
  CadRfcWriteBomTabEntry("MENGE", "1",3);

  CadRfcWriteBomTabEntry("", "",0);

  /* fill new BOM sub items */

  /* sub item number 1 for item tab entry number 1 */
  CadRfcWriteBomSubItemEntry("POSID", "1",1);                 /* number of item    */
  CadRfcWriteBomSubItemEntry("EBORT", "Left 2",1);            /* location          */
  CadRfcWriteBomSubItemEntry("UPMNG", "1",1);                 /* sub item quantity */
  CadRfcWriteBomSubItemEntry("UPOSZ", "1",1);                 /* sub item number   */
  CadRfcWriteBomSubItemEntry("UPTXT", "Position: Left 2",1);  /* sub item text     */

  /* sub item number 2 for item tab entry number 1 */
  CadRfcWriteBomSubItemEntry("POSID", "1",2);
  CadRfcWriteBomSubItemEntry("EBORT", "Right 2",2);
  CadRfcWriteBomSubItemEntry("UPMNG", "1",2);
  CadRfcWriteBomSubItemEntry("UPOSZ", "2",2);
  CadRfcWriteBomSubItemEntry("UPTXT", "Position: Right 2",2);

  /* sub item number 1 for item tab entry number 3 */
  CadRfcWriteBomSubItemEntry("POSID", "3",3);
  CadRfcWriteBomSubItemEntry("EBORT", "Bottom 2",3);
  CadRfcWriteBomSubItemEntry("UPMNG", "1",3);
  CadRfcWriteBomSubItemEntry("UPOSZ", "1",3);
  CadRfcWriteBomSubItemEntry("UPTXT", "Position: Bottom 2",3);

  /* sub item number 2 for item tab entry number 3 */
  CadRfcWriteBomSubItemEntry("POSID", "3",4);
  CadRfcWriteBomSubItemEntry("EBORT", "Top 2",4);
  CadRfcWriteBomSubItemEntry("UPMNG", "1",4);
  CadRfcWriteBomSubItemEntry("UPOSZ", "2",4);
  CadRfcWriteBomSubItemEntry("UPTXT", "Position: Top 2",4);

  CadRfcWriteBomSubItemEntry("", "",0);

  printf("Send changed BOM items ...\n");

  /* Call BOM change (API) */
  
  rc = CadBomChangeSubItem(MaterialHeaderData, pImportData, &SapFieldData, &DmsCharac);

  (void) DisplayReturnMessage(pImportData,22);

  /* error occured */
  if (rc != (int) RFC_OK )
  {
    /* application error */
    if ( rc == 99 ) return(99);
    else            return(22);
  }

  printf("<- OK\n");

  return(0);
}

/*--------------------------------------------------------------------*/
/* int display_bom_with_sub_items                                     */
/*--------------------------------------------------------------------*/
/* This function displays a BOM with or without sub items             */
/* No SAP dialog appears                                              */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ----             ----                                  */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   rc               return code                           */
/*--------------------------------------------------------------------*/
int display_bom_with_sub_items() 
{
  CSRFCITEM             ItemData;
  CSSUBITEM             SubItemData;
  int                   rc, index_item, index_sub_item, iPosid;
  char                  sPosnr[5], sIdnrk[19], sPostp[2],
                        sPosid[5], sEbort[21], sUposz[5], sUptxt[41];
  
  /* fill bom header */

  memcpy(MaterialHeaderData->Matnr, "AH01", 4);           /* material number */
  memcpy(MaterialHeaderData->Stlan, "1", 1);              /* BOM usage       */
  memcpy(MaterialHeaderData->Stlal, "1", 1);              /* BOM alternative */
    
  /* Display BOM data for change */
  
  rc = CadBomDisplaySubItem(MaterialHeaderData, pImportData, &SapFieldData, &DmsCharac);

  (void) DisplayReturnMessage(pImportData,21);

  /* error occured */
  if (rc != (int) RFC_OK )
  {
    /* application error */
    if ( rc == 99 ) return(99);
    else            return(21);
  }

  printf("<- OK\n");

  index_item = 1;

  /* print existing BOM data */

  while ( CadRfcGetBomItemEntry(index_item, &ItemData) == 0)
  {

    memcpy(sPosnr,ItemData.Posnr,sizeof(ItemData.Posnr) );
    sPosnr[sizeof(ItemData.Posnr)] = '\0';

    memcpy(sIdnrk,ItemData.Idnrk,sizeof(ItemData.Idnrk));
    sIdnrk[sizeof(ItemData.Idnrk)] = '\0';

    memcpy(sPostp,ItemData.Postp,sizeof(ItemData.Postp));
    sPostp[sizeof(ItemData.Postp)] = '\0';

    printf("Item:     %s %s %s\n",sPosnr, sIdnrk, sPostp);

    if (ItemData.Upskz[0] == 'X')
    {

      index_sub_item = 1;

      /* get all sub items for an item */

      while ( CadRfcGetBomSubItemEntry(index_sub_item, &SubItemData) == 0)
      {
         iPosid = atoi( (char*)SubItemData.Posid );
         if ( iPosid == index_item )
         {
           memcpy(sUposz,SubItemData.Uposz,sizeof(SubItemData.Uposz) );
           sUposz[sizeof(SubItemData.Uposz)] = '\0';

           memcpy(sEbort,SubItemData.Ebort,sizeof(SubItemData.Ebort) );
           sEbort[sizeof(SubItemData.Ebort)] = '\0';

           memcpy(sUptxt,SubItemData.Uptxt,sizeof(SubItemData.Uptxt) );
           sUptxt[sizeof(SubItemData.Uptxt)] = '\0';

           memcpy(sPosid,SubItemData.Posid,sizeof(SubItemData.Posid) );
           sPosid[sizeof(SubItemData.Posid)] = '\0';

           printf("Sub Item: %s %s %20s %s\n",sUposz,sEbort,sUptxt,sPosid);
         }
         index_sub_item++;
      }
    }
    index_item++;
  }

  return (0);
}

/*--------------------------------------------------------------------*/
/* int read_mat_master_via_api                                        */
/*--------------------------------------------------------------------*/
/* Read material master data via dialog RFC API                       */
/* Fields of structure MARA are returned                              */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ----             ----                                  */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   rc               return code                           */
/*--------------------------------------------------------------------*/
int read_mat_master_via_api() 
{

  SAP_FIELD_DATA        FieldData;
  char                  lFieldName[36];
  char                  lFieldValue[256];
  char                  lFieldMulti[41];
  int                   rc, index;

  lFieldName[0] = '\0';
  lFieldValue[0] = '\0';
  lFieldMulti[0] = '\0';

  /* Specify material master number which should be read */

  memcpy(pExportData->Material,"AH01",4);

  rc = CadRfcGetMaterialData(pExportData, pImportData, &SapFieldData, &DmsCharac);

  (void) DisplayReturnMessage(pImportData,33);
  if (rc != (int) RFC_OK) {
    return(33);
  }

  printf("<- OK\n");

  /* print returned values */

  printf("Fieldname            FieldValue           Description          \n");
  printf("---------------------------------------------------------------\n");

  index = 1; 

  while ( CadRfcGetFieldTabEntry(index, SapFieldData, &FieldData) == 0 ) 
  {
    memcpy(lFieldName,FieldData.Fieldname,35);      
    lFieldName[35] = '\0';
    memcpy(lFieldValue,FieldData.Fieldvalue,255);   
    lFieldValue[255] = '\0';
    memcpy(lFieldMulti,FieldData.Fieldmulti,40);    
    lFieldMulti[40] = '\0';

    printf("%.20s %.20s %.20s\n",lFieldName, lFieldValue, lFieldMulti);
                            
    index++;
  }

  return(0);
}

/*--------------------------------------------------------------------*/
/* int search_mat_via_mcd                                             */
/*--------------------------------------------------------------------*/
/* Search material master via matchcode                               */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ----             ----                                  */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   rc               return code                           */
/*--------------------------------------------------------------------*/
/* 101197 */
int search_mat_via_mcd() 
{

  SAP_FIELD_DATA        FieldData;
  char                  lFieldName[36];
  char                  lFieldValue[256];
  char                  lFieldMulti[41];
  int                   rc, index;

  /* Search material via matchcode and return the selected value */
  /* The selected material number is also returned if the        */
  /* parameter ReturnMcdValues is not set. In this case the      */
  /* material master record is also displayed (transaction MM01) */
  
  memcpy(pExportData->ObjectId,"M",1);
  memcpy(pExportData->ReturnMcdValues,"X",1);

  rc = CadRfcMatchcode(pExportData, pImportData, &SapFieldData, &DmsCharac);

  (void) DisplayReturnMessage(pImportData,37);
  if (rc != (int) RFC_OK) {
    return(37);
  }

  printf("<- OK\n");

  /* print returned values */

  printf("Fieldname            FieldValue           Description          \n");
  printf("---------------------------------------------------------------\n");

  index = 1; 

  while ( CadRfcGetFieldTabEntry(index, SapFieldData, &FieldData) == 0 ) 
  {
    memcpy(lFieldName,FieldData.Fieldname,35);      
    lFieldName[35] = '\0';
    memcpy(lFieldValue,FieldData.Fieldvalue,255);   
    lFieldValue[255] = '\0';
    memcpy(lFieldMulti,FieldData.Fieldmulti,40);    
    lFieldMulti[40] = '\0';

    printf("%.20s %.20s %.20s\n",lFieldName, lFieldValue, lFieldMulti);
                            
    index++;
  }

  return(0);
}

/*--------------------------------------------------------------------*/
/* int search_mat_via_class                                           */
/*--------------------------------------------------------------------*/
/* Search material master via class                                   */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ----             ----                                  */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   rc               return code                           */
/*--------------------------------------------------------------------*/
/* 101197 */
int search_mat_via_class() 
{

  SAP_FIELD_DATA        FieldData;
  CLASS_CHARACTERISTICS ClassData;
  char                  lFieldName[36];
  char                  lFieldValue[256];
  char                  lFieldMulti[41];
  char                  lAtnam[31];
  char                  lAtbez[31];
  char                  lAtwrt[31];
  char                  lstr[256];
  int                   rc, index;

  /* Specify class type */                                     

  memcpy(pExportData->ClassType,"001",3);

  /* call Dialog-RFC function */

  rc = CadRfcClassSelection(pExportData, pImportData, &SapFieldData, &DmsCharac, &ObjCharac);

  (void) DisplayReturnMessage(pImportData,38);
  if (rc != (int) RFC_OK) {
    return(38);
  }

  printf("<- OK\n");

  /* print import parameters */

  printf("\nImport parameters\n");
  printf("---------------------------------------------------\n");

  memcpy(lstr,pImportData->FunctionCode,14);
  lstr[14] = '\0';
  printf("Function Code: %s",lstr);

  memcpy(lstr,pImportData->ClassNo,18);
  lstr[18] = '\0';
  printf("\nClass Number:  %s",lstr);

  memcpy(lstr,pImportData->ClassType,3);
  lstr[3] = '\0';
  printf("\nClass Type:    %s\n",lstr);

  /* print selected objects */

  printf("\nObject type          FieldName                     \n");
  printf("---------------------------------------------------\n");

  index = 1; 

  while ( CadRfcGetFieldTabEntry(index, SapFieldData, &FieldData) == 0 ) 
  {
    memcpy(lFieldName,FieldData.Fieldname,35);      
    lFieldName[35] = '\0';
    memcpy(lFieldValue,FieldData.Fieldvalue,255);   
    lFieldValue[255] = '\0';

    printf("%.20s %.20s \n",lFieldName, lFieldValue);
                            
    index++;
  }

  /* print classification data */

  printf("\nCharac.Name          Description          Value               \n");
  printf("---------------------------------------------------------------\n");

  index = 1; 

  while ( CadRfcGetCharTabEntry(index, DmsCharac, &ClassData) == 0 ) 
  {
    memcpy(lAtnam,ClassData.Atnam,30);      
    lAtnam[30] = '\0';
    memcpy(lAtbez,ClassData.Atbez,30);   
    lAtbez[30] = '\0';
    memcpy(lAtwrt,ClassData.Atwrt,30);    
    lAtwrt[30] = '\0';

    printf("%.20s %.20s %.20s\n",lAtnam, lAtbez, lAtwrt);
                            
    index++;
  }

  return(0);
}


/*--------------------------------------------------------------------*/
/* int request_mat_master                                             */
/*--------------------------------------------------------------------*/
/* Routine retrieves data from a mat. master record from SAP          */
/* This routine uses APIs out of the SAP CAD function library         */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ----             ----                                  */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   rc               return code                           */
/*--------------------------------------------------------------------*/
int request_mat_master(char** argv) {
  char        sendstr[100];
  int         rc;

  /* Give RFC handle to API lib                                      */

  rc = CadRfcSetHandle(&handle);

  /* Intialize SAP CAD function library                              */
  /* (must be done one time before the first api call)               */

  hd = SapConncRfc(*argv,"DEMO",&rcvstr,&sapmes);
  if (hd.cpicrc != RFC_OK) {
    if (strlen(sapmes) > 0 ) 
      printf("%s\n",sapmes);
    else 
      DisplayMessage(14);
    return(14);
  }

  /* Mat.master request call                                         */

  strcpy(sendstr,"AH01                      X     ");

  hd = SapMatrq("MR",sendstr,&rcvstr,&sapmes);

  if (hd.cpicrc != RFC_OK) {
    if (strlen(sapmes) > 0)
      printf("%s\n",sapmes);
    else 
      DisplayMessage(15);
    return(15);
  }
  else {
    DisplayMessage(16);
    return(0);
  }
}

/*--------------------------------------------------------------------*/
/* int create_document_via_api                                        */
/*--------------------------------------------------------------------*/
/* Routine calls a dialog RFC function for creating a document info   */
/* record uses a call out of the CAD dialog rfc library               */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ----             ----                                  */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   rc               return code                           */
/*--------------------------------------------------------------------*/
int create_document_via_api() {                             /* 270199 */

  int   rc;
  char  doknr[26];               
  char  dokar[4];
  char  doktl[4];
  char  dokvr[3];
  char  dokst[3];
  char  doktxt[41];
  char  functioncode[15];

  /* delete items in internal table which could be filled with  */
  /* previous function calls                                    */
  ItFree(SapFieldData);
  ItFree(DmsCharac);

  memcpy(pDocumentData->Dokar,"DRW",3);

  rc = CadRfcDocCreate(pDocumentData, pImportData, &SapFieldData, &DmsCharac);

  (void) DisplayReturnMessage(pImportData,42);
  if (rc != (int) RFC_OK) {
    return(13);
  }

  memcpy(doknr,  pDocumentData->Doknr, sizeof(pDocumentData->Doknr));
  doknr[25] = '\0';
  memcpy(dokar,  pDocumentData->Dokar, sizeof(pDocumentData->Dokar));
  dokar[3] = '\0';
  memcpy(doktl,  pDocumentData->Doktl, sizeof(pDocumentData->Doktl));
  doktl[3] = '\0';
  memcpy(dokvr,  pDocumentData->Dokvr, sizeof(pDocumentData->Dokvr));
  dokvr[2] = '\0';
  memcpy(dokst, pDocumentData->Dokst, sizeof(pDocumentData->Dokst));
  dokst[2] = '\0';
  memcpy(doktxt, pDocumentData->Doktxt, sizeof(pDocumentData->Doktxt));
  doktxt[40] = '\0';
  memcpy(functioncode, pImportData->FunctionCode, sizeof(pImportData->FunctionCode));
  functioncode[14] = '\0';

  printf("\nDocument number : %s\n",doknr);
  printf("Document type   : %s\n",dokar);
  printf("Document part   : %s\n",doktl);
  printf("Document version: %s\n",dokvr);
  printf("Document status : %s\n",dokst);
  printf("Description     : %s\n",doktxt);
  printf("Function code   : %s\n",functioncode);

  printf("<- OK\n");

  return(0);
}

/*--------------------------------------------------------------------*/
/* int change_document_via_api                                        */
/*--------------------------------------------------------------------*/
/* Routine calls a dialog RFC function for changing a document info   */
/* record uses a call out of the CAD dialog rfc library               */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ----             ----                                  */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   rc               return code                           */
/*--------------------------------------------------------------------*/
int change_document_via_api() {                             /* 270199 */

  int   rc;
  char  doknr[26];               
  char  dokar[4];
  char  doktl[4];
  char  dokvr[3];
  char  dokst[3];
  char  doktxt[41];
  char  functioncode[15];

  /* delete items in internal table which could be filled with  */
  /* previous function calls                                    */
  ItFree(SapFieldData);
  ItFree(DmsCharac);

  memcpy(pDocumentData->Doknr,"AH01",4);
  memcpy(pDocumentData->Dokar,"DRW",3);
  memcpy(pDocumentData->Doktl,"000",3);
  memcpy(pDocumentData->Dokvr,"00",2);

  rc = CadRfcDocChange(pDocumentData, pImportData, &SapFieldData, &DmsCharac);

  (void) DisplayReturnMessage(pImportData,43);
  if (rc != (int) RFC_OK) {
    return(13);
  }

  memcpy(doknr,  pDocumentData->Doknr, sizeof(pDocumentData->Doknr));
  doknr[25] = '\0';
  memcpy(dokar,  pDocumentData->Dokar, sizeof(pDocumentData->Dokar));
  dokar[3] = '\0';
  memcpy(doktl,  pDocumentData->Doktl, sizeof(pDocumentData->Doktl));
  doktl[3] = '\0';
  memcpy(dokvr,  pDocumentData->Dokvr, sizeof(pDocumentData->Dokvr));
  dokvr[2] = '\0';
  memcpy(dokst, pDocumentData->Dokst, sizeof(pDocumentData->Dokst));
  dokst[2] = '\0';
  memcpy(doktxt, pDocumentData->Doktxt, sizeof(pDocumentData->Doktxt));
  doktxt[40] = '\0';
  memcpy(functioncode, pImportData->FunctionCode, sizeof(pImportData->FunctionCode));
  functioncode[14] = '\0';

  printf("\nDocument number : %s\n",doknr);
  printf("Document type   : %s\n",dokar);
  printf("Document part   : %s\n",doktl);
  printf("Document version: %s\n",dokvr);
  printf("Document status : %s\n",dokst);
  printf("Description     : %s\n",doktxt);
  printf("Function code   : %s\n",functioncode);

  printf("<- OK\n");

  return(0);
}

/*--------------------------------------------------------------------*/
/* int read_document_via_api                                          */
/*--------------------------------------------------------------------*/
/* Routine calls a dialog RFC function for reading document info      */
/* record data uses a call out of the CAD dialog rfc library          */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ----             ----                                  */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   rc               return code                           */
/*--------------------------------------------------------------------*/
int read_document_via_api() {                             /* 270199 */

  CLASS_CHARACTERISTICS ClassData;
  int                   rc, index;
  char                  doknr[26];               
  char                  dokar[4];
  char                  doktl[4];
  char                  dokvr[3];
  char                  dokst[3];
  char                  doktxt[41];
  char                  lAtnam[31];
  char                  lAtbez[31];
  char                  lAtwrt[31];
  		
  memcpy(pExportData->DocNumber,"AH01",4);
  memcpy(pExportData->Dokar,"DRW",3);
  memcpy(pExportData->Doktl,"000",3);
  memcpy(pExportData->Dokvr,"00",2);

  rc = CadRfcGetDmsData(pExportData, pDocumentData, pImportData, &SapFieldData, &DmsCharac);

  (void) DisplayReturnMessage(pImportData,44);
  if (rc != (int) RFC_OK) {
    return(13);
  }

  memcpy(doknr,  pDocumentData->Doknr, sizeof(pDocumentData->Doknr));
  doknr[25] = '\0';
  memcpy(dokar,  pDocumentData->Dokar, sizeof(pDocumentData->Dokar));
  dokar[3] = '\0';
  memcpy(doktl,  pDocumentData->Doktl, sizeof(pDocumentData->Doktl));
  doktl[3] = '\0';
  memcpy(dokvr,  pDocumentData->Dokvr, sizeof(pDocumentData->Dokvr));
  dokvr[2] = '\0';
  memcpy(dokst, pDocumentData->Dokst, sizeof(pDocumentData->Dokst));
  dokst[2] = '\0';
  memcpy(doktxt, pDocumentData->Doktxt, sizeof(pDocumentData->Doktxt));
  doktxt[40] = '\0';

  printf("\nDocument number      : %s\n",doknr);
  printf("Document type        : %s\n",dokar);
  printf("Document part        : %s\n",doktl);
  printf("Document version     : %s\n",dokvr);
  printf("Document status      : %s\n",dokst);
  printf("Description          : %s\n",doktxt);
  
  /* print classification data */

  printf("\nCharac.Name          Description          Value               \n");
  printf("---------------------------------------------------------------\n");

  index = 1; 

  while ( CadRfcGetCharTabEntry(index, DmsCharac, &ClassData) == 0 ) 
  {
    memcpy(lAtnam,ClassData.Atnam,30);      
    lAtnam[30] = '\0';
    memcpy(lAtbez,ClassData.Atbez,30);   
    lAtbez[30] = '\0';
    memcpy(lAtwrt,ClassData.Atwrt,30);    
    lAtwrt[30] = '\0';

    printf("%.20s %.20s %.20s\n",lAtnam, lAtbez, lAtwrt);
                            
    index++;
  }

  printf("<- OK\n");

  return(0);
}
/*--------------------------------------------------------------------*/
/* int create_material                                                */
/*--------------------------------------------------------------------*/
/* Routine calls a dialog RFC function for creating a material master */
/* record data uses a call out of the CAD dialog rfc library          */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ----             ----                                  */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   rc               return code                           */
/*--------------------------------------------------------------------*/
int create_material() {                                     /* 170599 */

  char l_material[19];

  /* specify material number */

  /* memcpy(pExportData->Material,"AHTEST01",8);  */

  /* specify industry */

  memcpy(pExportData->MatApplication,"M",1);  

  /* specify material type */

  memcpy(pExportData->MatType,"HALB",4);     

  /* specify material description text */

  CadRfcWriteFieldTabEntry("FIELDNAME",  "MAKT-MKTXT", 1);
  CadRfcWriteFieldTabEntry("FIELDVALUE", "short text", 1);

  /* specify basic material (basic constituent of a material)*/

  CadRfcWriteFieldTabEntry("FIELDNAME",  "MARA-WRKST", 2);
  CadRfcWriteFieldTabEntry("FIELDVALUE", "metal", 2);

  CadRfcWriteFieldTabEntry("", "", 0);

  /* call material create function */

  rc = CadRfcMatCreate(pExportData, pImportData, &SapFieldData, &DmsCharac);

  (void) DisplayReturnMessage(pImportData,46);
  if (rc != (int) RFC_OK) {
    return(13);
  }

  /* print material number */

  memcpy(l_material,  pImportData->Material, sizeof(pImportData->Material));
  l_material[18] = '\0';

  printf("\nMaterial number : %s\n",l_material);

  return (0);
}

/*--------------------------------------------------------------------*/
/* void DisplayMessage                                                */
/*--------------------------------------------------------------------*/
/* Display window with message                                        */
/*                                                                    */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   code             Message-Code                          */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   ----             ----                                  */
/*--------------------------------------------------------------------*/
void DisplayMessage(int code) {
  char messagex[800];
  char header[40];

#if defined(SAPonWINDOWS) || defined(SAPonNT)
  HWND dummy_hwnd = 0;
#endif

  strcpy(header, "CAD dialog RFC");

  switch(code) {
    case 1:
      strcpy(messagex, "Reconnect to SAP o.k.\n");
      strcat(messagex, "Next step: Display material master using RFC call");
	  break;
    case 2:
      strcpy(messagex, "Usage: cadrftst <parameter> \n\n");
      strcat(messagex, "possible values for <parameter>: \n\n");
      strcat(messagex, " 1: Display material master    (direct RFC call)\n");
      strcat(messagex, " 2: Display material master    (CAD-RFC call)\n");
      strcat(messagex, " 3: Display material master    (CAD dialog call)\n");
      strcat(messagex, " 4: Create Bill of Material       (CAD-RFC call)\n");
      strcat(messagex, " 5: Change Bill of Material       (CAD-RFC call)\n");
      strcat(messagex, " 6: Display Bill of Material      (CAD-RFC call)\n");
      strcat(messagex, " 7: Create BOM with sub items     (no SAP dialog)\n");
      strcat(messagex, " 8: Change BOM with sub items     (no SAP dialog)\n");
      strcat(messagex, " 9: Display BOM with sub items    (no SAP dialog)\n");
      strcat(messagex, "10: Read material master data     (no SAP dialog)\n");
      strcat(messagex, "11: Search material via Matchcode (CAD-RFC call)\n");
      strcat(messagex, "12: Search material via Class     (CAD-RFC call)\n");
      strcat(messagex, "13: Create Document               (CAD-RFC call)\n");
      strcat(messagex, "14: Change Document               (CAD-RFC call)\n");
      strcat(messagex, "15: Read Document data            (CAD-RFC call)\n");
      strcat(messagex, "16: Create Material               (CAD-RFC call)\n");
      break;
    case 3:
      strcpy(messagex, "Display material master using Dialog RFC API ...");
	  break;
    case 4:
      strcpy(messagex, "Retrieving mat. master record using\n");
      strcat(messagex, "API call out of the  SAP CAD function library...");
	  break;
    case 5:
      strcpy(messagex, "Now terminating program...");
	  break;
    case 6:
      strcpy(messagex, "Rfc error by RfcAccept");
      RfcError(messagex);
	  break;
    case 7:
      strcpy(messagex, "Rfc error by RfcGetName");
      RfcError(messagex);
	  break;
    case 8:
      strcpy(messagex, "Rfc error by RfcGetData");
      RfcError(messagex);
	  break;
    case 9:
      strcpy(messagex, "Error by creating SAP_FIELD_DATA");
      RfcError(messagex);
	  break;
    case 10:
      strcpy(messagex, "Error by creating DmsCharac");
	  break;
    case 11:
      strcpy(messagex, "RFC error by RFC_DISPLAY_MATERIAL_MASTER");
      RfcError(messagex);
	  break;
    case 12:
      strcpy(messagex, "RFC error by CadRfcAllocMemory");
	  break;
    case 13:
      strcpy(messagex, "RFC error by CadRfcMatDisplay");
      RfcError(messagex);
	  break;
    case 14:
      strcpy(messagex, "RFC error by SapConncRfc");
      RfcError(messagex);
	  break;
    case 15:
      strcpy(messagex, "RFC error by SapMatrq");
      RfcError(messagex);
	  break;
    case 16:
      strcpy(messagex,"Received data: ");
      strncat(messagex, rcvstr,(int) hd.datalen);
      strcat(messagex, "\nReceived message: ");
      strncat(messagex, sapmes,hd.meslen);
      strcpy(header, "CAD dialog RFC - SapMatrq");
      break;
    case 17:
      strcpy(messagex, "Rfc error by CadRfcOpen");
      RfcError(messagex);
	  break;
    case 18:
      strcpy(messagex, "Create Bill of Material using Dialog RFC API ...");
	  break;
    case 19:
      strcpy(messagex, "Change Bill of Material using Dialog RFC API ...");
	  break;
    case 20:
      strcpy(messagex, "Display Bill of Material using Dialog RFC API ...");
	  break;
    case 21:
      strcpy(messagex, "RFC error by CadBomDisplaySubItem");
      RfcError(messagex);
	  break;
    case 22:
      strcpy(messagex, "RFC error by CadBomChangeSubItem");
      RfcError(messagex);
	  break;
    case 23:
      strcpy(messagex, "RFC error by CadBomChangeSubItemRead");
      RfcError(messagex);
	  break;
    case 24:
      strcpy(messagex, "RFC error by CadBomCreateSubItem");
      RfcError(messagex);
	  break;
    case 25:
      strcpy(messagex, "Please call CADRFTST with a value between 1 - 10");
	  break;
    case 26:
      strcpy(messagex, "Create Bill of Material with sub items ...");
	  break;
    case 27:
      strcpy(messagex, "Change Bill of Material with sub items ...");
	  break;
    case 28:
      strcpy(messagex, "Display Bill of Material with sub items ...");
	  break;
    case 29:
      strcpy(messagex, "RFC error by CadRfcBomCreate");
      RfcError(messagex);
	  break;
    case 30:
      strcpy(messagex, "RFC error by CadRfcBomChange");
      RfcError(messagex);
	  break;
    case 31:
      strcpy(messagex, "RFC error by CadRfcBomDisplay");
      RfcError(messagex);
	  break;
    case 32:
      strcpy(messagex, "RFC error by CadRfcSetHandle");
	  break;
    case 33:
      strcpy(messagex, "RFC error by CadRfcGetMaterialData");
      RfcError(messagex);
	  break;
    case 34:
      strcpy(messagex, "Read material master data using Dialog RFC API ...");
	  break;
    case 35:
      strcpy(messagex, "Search material master via matchcode using Dialog RFC API ...");
	  break;
    case 36:
      strcpy(messagex, "Search material master via class using Dialog RFC API ...");
	  break;
    case 37:
      strcpy(messagex, "RFC error by CadRfcMatchcode");
      RfcError(messagex);
	  break;
    case 38:
      strcpy(messagex, "RFC error by CadRfcClassSelection");
      RfcError(messagex);
	  break;
    case 39:                                                                        /* 270199 */
      strcpy(messagex, "Create document info record using Dialog RFC API ...");
	  break;
    case 40:                                                                        /* 270199 */
      strcpy(messagex, "Change document info record using Dialog RFC API ...");
	  break;
    case 41:                                                                        /* 270199 */
      strcpy(messagex, "Read document info record data using Dialog RFC API ...");
        break;
    case 42:                                                                        /* 270199 */
      strcpy(messagex, "RFC error by CadRfcDocCreate");
      RfcError(messagex);
	  break;
    case 43:                                                                        /* 270199 */
      strcpy(messagex, "RFC error by CadRfcDocChange");
      RfcError(messagex);
	  break;
    case 44:                                                                        /* 270199 */
      strcpy(messagex, "RFC error by CadRfcGetDmsData");
      RfcError(messagex);
	  break;
    case 45:                                                                        /* 170599 */
      strcpy(messagex, "Create material master record usind Dialog RFC API ...");
        break;
    case 46:                                                                        /* 170599 */
      strcpy(messagex, "RFC error by CadRfcMatCreate");
      RfcError(messagex);
	  break;


    default:
      strcpy(messagex, "Unknown message");
	  break;
  }
  printf("%s\n",messagex);
}

/*--------------------------------------------------------------------*/
/* void DisplayReturnMessage                                          */
/*--------------------------------------------------------------------*/
/* Display returned message of last RFC call                          */
/*--------------------------------------------------------------------*/
/*             NAME             DESCRIPTION                           */
/*             ---------------- ------------------------------------  */
/*   INPUT :   ImportData       Returned Structure of RFC function    */
/*             MessageNumber    Message number                        */
/*   OUTPUT:   ----             ----                                  */
/*--------------------------------------------------------------------*/
/*   Return:   ----             ----                                  */
/*--------------------------------------------------------------------*/
void DisplayReturnMessage(CadRfcImportField *ImportData, int MessageNumber)
{
  char   slen[5];
  int    len;

  memcpy(slen, ImportData->MessageLength, 4);
  slen[4] = '\0';

  len = atoi(slen);
  if (len > 0)
  {
    ImportData->Message[len] = '\0';
    printf("%s\n",ImportData->Message);
  }
  else
    if ( rc != (int) RFC_OK) DisplayMessage(MessageNumber);

  return;
}
