I am accessing a webservice using SOAP and PHP. I can connect to a number of functions through to webservice API. But one eludes me. I have an example but it is in C#.
I have tried to emulate the example in PHP with no luck.
I have attached the C# code and my attempt in PHP. Also the error message are included.
C# code
public void MakeSale()
{
string yourKey = "your key";
using(DdDSaleService.SaleServiceClient client = new SaleServiceClient())
{
Sale sale = client.StartSale();
//header info
sale.ClientNumber = 996001;
sale.Date = DateTime.Now;
sale.Employee = 1;
sale.NoteID = 123;
sale.Terminal = 1;
sale.Type = SaleType.Sale;
//items in basket.
ItemLine line1 = new ItemLine();
line1.Type = ItemLineType.Sale;
line1.ItemGroup = 1;
line1.Supplier = 1;
line1.Qty = 3; //should -3 if a return of goods.
line1.LineAmount = 600; //The normal amount of the goods.
line1.EDBNumber = 1; //unique key in our system. You have this if you got the articles by our service.
line1.DiscountAmount = -100; //the discount.
//line2 comes here....
//add the lines to the sale
sale.ItemLines = new ItemLine[] { line1 };
//The payment lines
//1 with cash, and one with the change. the sale MUST sum to zero (itemlines + paymentlines)
PaymentLine cash = new PaymentLine();
cash.Type = PaymentLineType.Cash;
cash.Qty = 1;
cash.LineAmount = 600;
PaymentLine change = new PaymentLine();
change.Type = PaymentLineType.Change;
change.Qty = 1;
change.LineAmount = -100;
//add the paymentlines
sale.PaymentLines = new PaymentLine[]{cash,change};
//submit the sale.
Status response = client.SaveSale(sale, yourKey);
Console.WriteLine(string.Format("got response from save sale saved: {0}, message: {1}",response.Saved,response.Message));
Console.ReadLine();
}
}
PHP code
$client = new SoapClient("http://xxx.xxxxx.xxxx/xxxxxxx.svc?wsdl", array("trace" => 1, "connection_timeout" => 500));
// Initialize sale
// $client is a valid SOAP connection
// That has been setup earlier
$Sale = $client->StartSale();
// Output what initalize sale returns
print_r($Sale);
// Format order date/time
$timezone = new DateTimeZone("Europe/Copenhagen");
$date = new DateTime("now", $timezone);
$order_date_time = $date->format("Y-m-d\TH:i:s");
// Set header information
$Sale->StartSaleResult->ClientNumber = 996001;
$Sale->StartSaleResult->Date = $order_date_time;
$Sale->StartSaleResult->Employee = 1;
$Sale->StartSaleResult->NoteID = 123;
$Sale->StartSaleResult->Terminal = 1;
$Sale->StartSaleResult->Type = 'Sale';
// Itemline
$line = new stdClass();
$line->Type = 'Sale';
$line->ItemGroup = 1;
$line->Supplier = 1;
$line->Qty = 3;
$line->LineAmount = 600;
$line->EDBNumber = 1;
$line->DiscountAmount = 1-100;
$Sale->StartSaleResult->ItemLines->ItemLine[] = $line;
// Payment line, cash
$cash = new stdClass();
$cash->Type = 'Cash';
$cash->Qty = 1;
$cash->LineAmount = 600;
$Sale->StartSaleResult->PaymentLines->PaymentLine[] = $cash;
// Payment line, Change
$change = new stdClass();
$change->Type = 'Change';
$change->Qty = 1;
$change->LineAmount = -100;
$Sale->StartSaleResult->PaymentLines->PaymentLine[] = $change;
// Save sale
$response = $client->SaveSale($Sale->StartSaleResult, 'xxxxxxxx');
print_r($response);
Output what webservice returns when connecting
print_r($Sale);
stdClass Object
(
[ClientNumber] => 0
[Date] => 0001-01-01T00:00:00
[Employee] => 0
[ItemLines] => stdClass Object
(
)
[NoteID] => 0
[PaymentLines] => stdClass Object
(
)
[Terminal] => 0
[Type] => Sale
)
Error message
[previous:Exception:private] =>
[faultstring] => End element 'Body' from namespace 'http://schemas.xmlsoap.org/soap/envelope/' expected. Found element 'param1' from namespace ''. Line 2, position 149.
[faultcode] => a:InternalServiceFault
[detail] => stdClass Object
(
[ExceptionDetail] => stdClass Object
(
[HelpLink] =>
[InnerException] =>
[Message] => End element 'Body' from namespace 'http://schemas.xmlsoap.org/soap/envelope/' expected. Found element 'param1' from namespace ''. Line 2, position 149.
[StackTrace] => at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)
at System.Xml.XmlExceptionHelper.ThrowEndElementExpected(XmlDictionaryReader reader, String localName, String ns)
at System.Xml.XmlBaseReader.ReadEndElement()
at System.ServiceModel.Channels.Message.ReadFromBodyContentsToEnd(XmlDictionaryReader reader, EnvelopeVersion envelopeVersion)
at System.ServiceModel.Channels.Message.ReadFromBodyContentsToEnd(XmlDictionaryReader reader)
at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)
at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
[Type] => System.Xml.XmlException
)
)
The formula for converting Fahrenheit to Celsius is C = 5/9(F-32). Fahrenheit and Celsius are the same at -40°. At ordinary temperatures, Fahrenheit is a larger number than Celsius. For example, body temperature is 98.6 °F or 37 °C.
Quick Celsius (°C) / Fahrenheit (°F) Conversion: °C. °F. °C. °F. 0° C = 32° F.
Your arrays don't look right. ItemLines
and PaymentLines
should be arrays instead of an object containing an array.
Even though StartSale
returns them as objects, they should still be an array for the call to SaveSale
. The reason they are returned as objects is a quirk of the PHP SoapClient. What happens is, if there is just one element in the array, the SoapClient gives you an object with its properties set as the single element properties. However if there is more than one element in the array, you get an array of objects instead, and so is one level deeper than the result when there's only a single element. So because they are returned with no elements from StartSale
, they are given as objects instead of an empty array.
...
...
$Sale->StartSaleResult->ItemLines = array($line);
// Payment line, cash
$cash = new stdClass();
$cash->Type = 'Cash';
$cash->Qty = 1;
$cash->LineAmount = 600;
// Payment line, Change
$change = new stdClass();
$change->Type = 'Change';
$change->Qty = 1;
$change->LineAmount = -100;
$Sale->StartSaleResult->PaymentLines = array($cash, $change);
Also depending on what the WSDL looks like, you may need to pass an associative array as the parameters, with keys as sale
and key
(according to the WSDL), instead of passing two separate arguments:
$response = $client->SaveSale(array('sale' => $Sale->StartSaleResult, 'key' => 'xxxxxxxx'));
Change sale
and key
to whatever the WSDL defines them as.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With