SAP and PHP: An easy way for SD sales order entry
function validateSubmit() {
// very basic missing data handling
checkentry=myform.ponumb.value;
if (checkentry==”) {
alert(‘Purchase Order number (PO number) must be specified. Please enter a value.’);
document.myform.ponumb.focus();
event.returnValue=false;
}
checkentry=myform.inumb.value;
if (checkentry==”) {
alert(‘Item number is a mandatory entry. Please try again.’);
document.myform.inumb.focus();
event.returnValue=false;
}
checkentry=myform.matnr.value;
if (checkentry==1) {
alert(‘A Material code must be specified. Please select one.’);
document.myform.matnr.focus();
event.returnValue=false;
}
checkentry=myform.oqty.value;
if (checkentry==”) {
alert(‘Order quantity must be specified. Please try again.’);
document.myform.oqty.focus();
event.returnValue=false;
}
}
// –>
Thinking about a simplified way for creating SAP SD sales orders, possibly using everyday, well-known tools (like a web browser) was the starting point for this trial.
Having available the great SAPRFC extension module for PHP and few BAPIs, it is relatively simple to create something for this need.
The following example has been developed using a Windows XP prof box, with Apache (2.0.50), MySQL (4.0.15), PHP (4.3.8) and, of course, SAPRFC (1.4-5.0.4) installed. SAP is 4.6B.
Looking at the BAPIs repository, BAPI_SALESORDER_CREATEFROMDAT2 seems to be the right choice. There is also to make use of BAPI_TRANSACTION_COMMIT or BAPI_TRANSACTION_ROLLBACK, this latter in case of unsuccesful result.
The idea is to start with a web page containing the basic fields needed for SD sales order booking, with some of them proposed as default.
Here is a sample of it:
MySQL is helping with the default values.
Once the form fields are completed (a very basic check about missing data is available within the code), the script can run, calling the BAPI.
These are the fields that have been considered:
|
field description |
SAP fields |
BAPI import/internal tables |
BAPI fields |
|
Order Type |
AUART |
ORDER_HEADER_IN |
DOC_TYPE |
|
Sales organization |
VKORG |
|
SALES_ORG |
|
Distribution channel |
VTWEG |
|
DISTR_CHANN |
|
Division |
SPART |
|
DIVISION |
|
Sales office |
VKGRP |
|
SALES_GRP |
|
Sales group |
VKBUR |
|
SALES_OFF |
|
Purchase order number |
BSTKD |
|
PURCH_NO_C |
|
|
|
|
|
|
Sales document number |
POSNR |
ORDER_CONDITIONS_IN |
ITM_NUMBER |
|
Condition type |
KSCHL |
|
COND_TYPE |
|
Rate |
KBETR |
|
COND_VALUE |
|
|
|
|
|
|
Sales document number |
POSNR |
ORDER_ITEMS_IN |
ITM_NUMBER |
|
Material number |
MABNR |
|
MATERIAL |
|
Item category |
PSTYV |
|
ITEM_CATEG |
|
|
|
|
|
|
Partner role |
PARVW |
ORDER_PARTNERS |
PARTN_ROLE |
|
Partner number |
KUNNR |
|
PARTN_NUMB |
|
|
|
|
|
|
Sales document number |
POSNR |
ORDER_SCHEDULES_IN |
ITM_NUMBER |
|
Order quantity |
KWMENG |
|
REQ_QTY |
If successfully completed, the script should output a series of messages:
where one can see the sales order number saved. Moving to SAP, transaction VA03 shows the following:
Now, coming to the code, here are the scripts:
Main page
This is the main script code:
include (“config.php”);include (“bapi_salesorder_createfromdat2.php”);// set default valuesif (! isset($_POST[‘doc_type’])) $doc_type = set_default(‘eoe_doc_type’); else $doc_type = $_POST[‘doc_type’];if (! isset($_POST[‘sales_org’])) $sales_org = set_default(‘eoe_sales_org’); else $sales_org = $_POST[‘sales_org’];if (! isset($_POST[‘distr_chann’])) $distr_chann = set_default(‘eoe_distr_chann’); else $distr_chann = $_POST[‘distr_chann’];if (! isset($_POST[‘division’])) $division = set_default(‘eoe_division’); else $division = $_POST[‘division’];if (! isset($_POST[‘sales_off’])) $sales_off = set_default(‘eoe_sales_off’); else $sales_off = $_POST[‘sales_off’];if (! isset($_POST[‘sales_grp’])) $sales_grp = set_default(‘eoe_sales_grp’); else $sales_grp = $_POST[‘sales_grp’];if (! isset($_POST[‘partn_role’])) $partn_role = set_default(‘eoe_partn_role’); else $partn_role = $_POST[‘partn_role’];// table TPART-PARVW lang. DEif (! isset($_POST[‘partn_numb’])) $partn_numb = set_default(‘eoe_partn_numb’); else $partn_numb = $_POST[‘partn_numb’];if (! isset($_POST[‘sunit’])) $sunit = set_default(‘eoe_sunit’); else $sunit = $_POST[‘sunit’];// reading _POST dataif (! isset($_POST[‘ponumb’])) ; else $ponumb = $_POST[‘ponumb’];if (! isset($_POST[‘inumb’])) ; else $inumb = $_POST[‘inumb’];if (! isset($_POST[‘matnr’])) $matnr = 1; else $matnr = $_POST[‘matnr’];$mat_nr = str_pad($matnr, 18, “0”, STR_PAD_LEFT);if (! isset($_POST[‘oqty’])) ; else $oqty = $_POST[‘oqty’];if (! isset($_POST[‘rate’])) $rate = 0.01 ; else $rate = $_POST[‘rate’];?>
<font color=”#3366CC”>SAPRFC:<br>SD – Easy Order Entry</font>
— phpMyAdmin SQL Dump
— version 2.6.0-pl1
—
— Host: localhost
— Generated on: 08 Set, 2006 at 05:55 PM
— MySQL version: 4.0.15
— PHP version: 4.3.8
—
— Database: `sap_eoe`
—
— –
—
— Table structure `eoe_distr_chann`
—
DROP TABLE IF EXISTS eoe_distr_chann;
CREATE TABLE IF NOT EXISTS eoe_distr_chann (
eoe_idx int(2) NOT NULL default ‘0’,
eoe_distr_chann char(2) NOT NULL default ”,
eoe_descr varchar(30) NOT NULL default ”,
eoe_default char(1) default NULL,
PRIMARY KEY (eoe_idx)
) TYPE=MyISAM;
—
— Table data dump `eoe_distr_chann`
—
INSERT INTO eoe_distr_chann VALUES (1, ’01’, ‘Channel 1’, ‘x’);
— –
—
— Table structure `eoe_division`
—
DROP TABLE IF EXISTS eoe_division;
CREATE TABLE IF NOT EXISTS eoe_division (
eoe_idx int(2) NOT NULL default ‘0’,
eoe_division char(2) NOT NULL default ”,
eoe_descr varchar(30) NOT NULL default ”,
eoe_default char(1) default NULL,
PRIMARY KEY (eoe_idx)
) TYPE=MyISAM;
—
— Table data dump `eoe_division`
—
INSERT INTO eoe_division VALUES (1, ’01’, ‘Product Sales’, NULL);
INSERT INTO eoe_division VALUES (2, ’02’, ‘Scrap’, NULL);
INSERT INTO eoe_division VALUES (3, ’03’, ‘Other Sales’, NULL);
INSERT INTO eoe_division VALUES (4, ’04’, ‘Interco Hollows’, ‘x’);
INSERT INTO eoe_division VALUES (5, ’05’, ‘Sales 1’, NULL);
INSERT INTO eoe_division VALUES (6, ’06’, ‘Sales 2’, NULL);
INSERT INTO eoe_division VALUES (7, ’07’, ‘Sales 3’, NULL);
INSERT INTO eoe_division VALUES (8, ’08’, ‘Sales 4’, NULL);
— –
—
— Table structure `eoe_doc_type`
—
DROP TABLE IF EXISTS eoe_doc_type;
CREATE TABLE IF NOT EXISTS eoe_doc_type (
eoe_idx int(2) NOT NULL default ‘0’,
eoe_doc_type varchar(4) NOT NULL default ”,
eoe_descr varchar(30) NOT NULL default ”,
eoe_default char(1) default NULL,
PRIMARY KEY (eoe_idx)
) TYPE=MyISAM;
—
— Table data dump `eoe_doc_type`
—
INSERT INTO eoe_doc_type VALUES (1, ‘ZCTS’, ‘Internal Order’, NULL);
INSERT INTO eoe_doc_type VALUES (2, ‘ZDHO’, ‘Hollow Order’, ‘x’);
INSERT INTO eoe_doc_type VALUES (3, ‘ZDHT’, ‘Hollow Tollwork’, NULL);
INSERT INTO eoe_doc_type VALUES (4, ‘ZDMV’, ‘Customer Order’, NULL);
— –
—
— Table structure `eoe_matnr`
—
DROP TABLE IF EXISTS eoe_matnr;
CREATE TABLE IF NOT EXISTS eoe_matnr (
eoe_idx int(2) NOT NULL default ‘0’,
eoe_matnr varchar(18) NOT NULL default ”,
eoe_descr varchar(30) NOT NULL default ”,
eoe_default char(1) default NULL,
PRIMARY KEY (eoe_idx)
) TYPE=MyISAM;
—
— Table data dump `eoe_matnr`
—
INSERT INTO eoe_matnr VALUES (1, ‘choose …’, ”, NULL);
INSERT INTO eoe_matnr VALUES (2, ‘302252’, ‘Material descript. 01’, NULL);
INSERT INTO eoe_matnr VALUES (3, ‘302253’, ‘Material descript. 02’, NULL);
INSERT INTO eoe_matnr VALUES (4, ‘302254’, ‘Material descript. 03’, NULL);
INSERT INTO eoe_matnr VALUES (5, ‘302255’, ‘Material descript. 04’, NULL);
INSERT INTO eoe_matnr VALUES (6, ‘302256’, ‘Material descript. 05’, NULL);
INSERT INTO eoe_matnr VALUES (7, ‘302257’, ‘Material descript. 06’, NULL);
INSERT INTO eoe_matnr VALUES (8, ‘302258’, ‘Material descript. 07’, NULL);
INSERT INTO eoe_matnr VALUES (9, ‘302259’, ‘Material descript. 08’, NULL);
INSERT INTO eoe_matnr VALUES (10, ‘302260’, ‘Material descript. 09’, NULL);
INSERT INTO eoe_matnr VALUES (11, ‘302261’, ‘Material descript. 10’, NULL);
INSERT INTO eoe_matnr VALUES (12, ‘302262’, ‘Material descript. 11’, NULL);
INSERT INTO eoe_matnr VALUES (13, ‘302270’, ‘Material descript. 12’, NULL);
INSERT INTO eoe_matnr VALUES (14, ‘302271’, ‘Material descript. 13’, NULL);
INSERT INTO eoe_matnr VALUES (15, ‘302280’, ‘Material descript. 14’, NULL);
INSERT INTO eoe_matnr VALUES (16, ‘302290’, ‘Material descript. 15’, NULL);
INSERT INTO eoe_matnr VALUES (17, ‘302300’, ‘Material descript. 16’, NULL);
INSERT INTO eoe_matnr VALUES (18, ‘302301’, ‘Material descript. 17’, NULL);
INSERT INTO eoe_matnr VALUES (19, ‘302310’, ‘Material descript. 18’, NULL);
INSERT INTO eoe_matnr VALUES (20, ‘302320’, ‘Material descript. 19’, NULL);
INSERT INTO eoe_matnr VALUES (21, ‘302321’, ‘Material descript. 20’, NULL);
INSERT INTO eoe_matnr VALUES (22, ‘302322’, ‘Material descript. 21’, NULL);
INSERT INTO eoe_matnr VALUES (23, ‘302323’, ‘Material descript. 22’, NULL);
INSERT INTO eoe_matnr VALUES (24, ‘302324’, ‘Material descript. 23’, NULL);
INSERT INTO eoe_matnr VALUES (25, ‘302325’, ‘Material descript. 24’, NULL);
INSERT INTO eoe_matnr VALUES (26, ‘302326’, ‘Material descript. 25’, NULL);
INSERT INTO eoe_matnr VALUES (27, ‘302327’, ‘Material descript. 26’, NULL);
INSERT INTO eoe_matnr VALUES (28, ‘302328’, ‘Material descript. 27’, NULL);
INSERT INTO eoe_matnr VALUES (29, ‘302329’, ‘Material descript. 28’, NULL);
INSERT INTO eoe_matnr VALUES (30, ‘302330’, ‘Material descript. 29’, NULL);
INSERT INTO eoe_matnr VALUES (31, ‘302331’, ‘Material descript. 30’, NULL);
— –
—
— Table structure `eoe_partn_numb`
—
DROP TABLE IF EXISTS eoe_partn_numb;
CREATE TABLE IF NOT EXISTS eoe_partn_numb (
eoe_idx int(2) NOT NULL default ‘0’,
eoe_partn_numb varchar(5) NOT NULL default ”,
eoe_descr varchar(30) NOT NULL default ”,
eoe_default char(1) default NULL,
PRIMARY KEY (eoe_idx)
) TYPE=MyISAM;
—
— Table data dump `eoe_partn_numb`
—
INSERT INTO eoe_partn_numb VALUES (1, ‘10200’, ‘Customer 1’, NULL);
INSERT INTO eoe_partn_numb VALUES (2, ‘10201’, ‘Customer 2’, NULL);
INSERT INTO eoe_partn_numb VALUES (3, ‘10202’, ‘Customer 3’, NULL);
INSERT INTO eoe_partn_numb VALUES (4, ‘10203’, ‘Customer 4’, NULL);
INSERT INTO eoe_partn_numb VALUES (5, ‘10204’, ‘Customer 5’, NULL);
INSERT INTO eoe_partn_numb VALUES (6, ‘10205’, ‘Customer 6’, NULL);
INSERT INTO eoe_partn_numb VALUES (7, ‘10206’, ‘DMV’, ‘x’);
INSERT INTO eoe_partn_numb VALUES (8, ‘10207’, ‘Customer 7’, NULL);
INSERT INTO eoe_partn_numb VALUES (9, ‘10208’, ‘Customer 8’, NULL);
INSERT INTO eoe_partn_numb VALUES (10, ‘10209’, ‘Customer 9’, NULL);
— –
—
— Table structure `eoe_partn_role`
—
DROP TABLE IF EXISTS eoe_partn_role;
CREATE TABLE IF NOT EXISTS eoe_partn_role (
eoe_idx int(2) NOT NULL default ‘0’,
eoe_partn_role char(2) NOT NULL default ”,
eoe_descr varchar(30) NOT NULL default ”,
eoe_default char(1) default NULL,
PRIMARY KEY (eoe_idx)
) TYPE=MyISAM;
—
— Table data dump `eoe_partn_role`
—
INSERT INTO eoe_partn_role VALUES (1, ‘AG’, ‘Sold-to party’, ‘x’);
INSERT INTO eoe_partn_role VALUES (2, ‘WE’, ‘Ship-to party’, NULL);
— –
—
— Table structure `eoe_sales_grp`
—
DROP TABLE IF EXISTS eoe_sales_grp;
CREATE TABLE IF NOT EXISTS eoe_sales_grp (
eoe_idx int(2) NOT NULL default ‘0’,
eoe_sales_grp char(3) NOT NULL default ”,
eoe_descr varchar(30) NOT NULL default ”,
eoe_default char(1) default NULL,
PRIMARY KEY (eoe_idx)
) TYPE=MyISAM;
—
— Table data dump `eoe_sales_grp`
—
INSERT INTO eoe_sales_grp VALUES (1, ‘AA’, ‘Plant 00’, NULL);
INSERT INTO eoe_sales_grp VALUES (2, ‘BB’, ‘Plant 01’, NULL);
INSERT INTO eoe_sales_grp VALUES (3, ‘CC’, ‘Plant 02’, NULL);
INSERT INTO eoe_sales_grp VALUES (4, ‘HDE’, ‘Plant 03’, ‘x’);
INSERT INTO eoe_sales_grp VALUES (5, ‘DD’, ‘Plant 04’, NULL);
INSERT INTO eoe_sales_grp VALUES (6, ‘TT’, ‘Plant 05’, NULL);
INSERT INTO eoe_sales_grp VALUES (7, ‘ZZZ’, ‘Plant 06’, NULL);
— –
—
— Table structure `eoe_sales_off`
—
DROP TABLE IF EXISTS eoe_sales_off;
CREATE TABLE IF NOT EXISTS eoe_sales_off (
eoe_idx int(2) NOT NULL default ‘0’,
eoe_sales_off char(3) NOT NULL default ”,
eoe_descr varchar(30) NOT NULL default ”,
eoe_default char(1) default NULL,
PRIMARY KEY (eoe_idx)
) TYPE=MyISAM;
—
— Table data dump `eoe_sales_off`
—
INSERT INTO eoe_sales_off VALUES (1, ‘AA’, ‘Plant 00’, NULL);
INSERT INTO eoe_sales_off VALUES (2, ‘BB’, ‘Plant 01’, NULL);
INSERT INTO eoe_sales_off VALUES (3, ‘CC’, ‘Plant 02’, NULL);
INSERT INTO eoe_sales_off VALUES (4, ‘HDE’, ‘Plant 03’, ‘x’);
INSERT INTO eoe_sales_off VALUES (5, ‘DD’, ‘Plant 04’, NULL);
INSERT INTO eoe_sales_off VALUES (6, ‘TT’, ‘Plant 05’, NULL);
INSERT INTO eoe_sales_off VALUES (7, ‘ZZZ’, ‘Plant 06’, NULL);
— –
—
— Table structure `eoe_sales_org`
—
DROP TABLE IF EXISTS eoe_sales_org;
CREATE TABLE IF NOT EXISTS eoe_sales_org (
eoe_idx int(2) NOT NULL default ‘0’,
eoe_sales_org varchar(4) NOT NULL default ”,
eoe_descr varchar(30) NOT NULL default ”,
eoe_default char(1) default NULL,
PRIMARY KEY (eoe_idx)
) TYPE=MyISAM;
—
— Table data dump `eoe_sales_org`
—
INSERT INTO eoe_sales_org VALUES (1, ‘DMVD’, ‘DMV STAINLESS 1’, ‘x’);
INSERT INTO eoe_sales_org VALUES (2, ‘DMVF’, ‘DMV STAINLESS 2’, NULL);
INSERT INTO eoe_sales_org VALUES (3, ‘DMVI’, ‘DMV STAINLESS 3’, NULL);
INSERT INTO eoe_sales_org VALUES (4, ‘DMVS’, ‘DMV STAINLESS 4’, NULL);
INSERT INTO eoe_sales_org VALUES (5, ‘DMVU’, ‘DMV STAINLESS 5’, NULL);
— –
—
— Table structure `eoe_sunit`
—
DROP TABLE IF EXISTS eoe_sunit;
CREATE TABLE IF NOT EXISTS eoe_sunit (
eoe_idx int(2) NOT NULL default ‘0’,
eoe_sunit char(2) NOT NULL default ”,
eoe_descr varchar(30) NOT NULL default ”,
eoe_default char(1) default NULL,
PRIMARY KEY (eoe_idx)
) TYPE=MyISAM;
—
— Table data dump `eoe_sunit`
—
INSERT INTO eoe_sunit VALUES (1, ‘M’, ‘Meter’, NULL);
INSERT INTO eoe_sunit VALUES (2, ‘KG’, ‘Kilo’, ‘x’);
INSERT INTO eoe_sunit VALUES (3, ‘FT’, ‘Foot’, NULL);
INSERT INTO eoe_sunit VALUES (4, ‘PC’, ‘Piece’, NULL);
INSERT INTO eoe_sunit VALUES (5, ‘TO’, ‘Tonne’, NULL);
Limitations and further improvements
As one can easily see, this very basic example creates a single line item in a sales order. However, this can be the starting point for further improvements.
Moreover, the following areas could also be investigated:
• managing material configuration data at item level
• managing sales order changes
These could be the subject for further webblogs.


iam from indonesia, now i want to make program just like the program that you have done.
when i execute your program....the message was
"Please enter sold-to party or ship-to party"
can you help me??
which field that i should use to insert "sold to party" and "ship to party"
Warm Regards,
anggara mahardika
Garuda Indonesia Airline
anggara.mahardika@garuda-indonesia.com
Thank you for your interest.
The message seems be related to a missing partner function, very likely the field KUNNR (customer number). In the example I used a mySQL table to set few default values, and among them the partner function type (AG, sold-to-party). In the form, the user should then specify which customer (in the example, the code 10206).
I do hope this could be of some help. Feel free to contact me in case of other needs.
Kind regards,
Flavio Ciotola
In this example, did you use SAP RFC connector for PHP ? did you have to compile the code using Visual Studio ?
Thank you
Eyal
Usually, and also in this example, I did not use SAP RFC connector for PHP.
It is just a script running in the webserver, thanks to the SAPRFC extension module for PHP (http://saprfc.sourceforge.net/); no need to compile the code then.
Hope this could help.
Flavio