Acumatica API使用多个DocumentDetails行创建SalesOrder

时间:2016-04-22 06:59:05

标签: php erp acumatica

当我在PHP中使用多个DocumentDetails创建SalesOrder时,这是我的代码

$SO301000Submit->commands = array
        (
            $acumatica->prepareValue("SO", $SO301000GetSchema->OrderSummary->OrderType),
            $SO301000GetSchema->Actions->Insert,
            $acumatica->prepareValue("ACTIVESTAF", $SO301000GetSchema->OrderSummary->Customer),

            $SO301000GetSchema->DocumentDetails->ServiceCommands->NewRow,
            $acumatica->prepareValue("HQ", $SO301000GetSchema->DocumentDetails->Branch),
            $acumatica->prepareValue("AALEGO500", $SO301000GetSchema->DocumentDetails->InventoryID),
            $acumatica->prepareValue("WHOLESALE", $SO301000GetSchema->DocumentDetails->Warehouse, true),

            $SO301000GetSchema->DocumentDetails->ServiceCommands->NewRow,
            $acumatica->prepareValue("VA", $SO301000GetSchema->DocumentDetails->Branch),
            $acumatica->prepareValue("AAPOWERAID", $SO301000GetSchema->DocumentDetails->InventoryID),
            $acumatica->prepareValue("RETAIL", $SO301000GetSchema->DocumentDetails->Warehouse, true),


            $SO301000GetSchema->Actions->Save,
            $SO301000GetSchema->OrderSummary->OrderNbr
        );
        $result = $acumatica->client->SO301000Submit($SO301000Submit);

它将返回错误

  

System.Web.Services.Protocols.SoapException:服务器无法处理请求。 ---> System.NullReferenceException:未将对象引用设置为对象的实例。      在PX.Api.SyImportContext.ParseCommand(SyCommand cmd)      在PX.Api.SyExportContext.ParseCommand(SYMappingField字段)      at System.Linq.Enumerable.WhereSelectArrayIterator 2.MoveNext() at System.Collections.Generic.List 1..ctor(IEnumerable 1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable 1 source)      在PX.Api.SyExportContext..ctor(SYMapping mapping,IEnumerable 1 fields, String[] providerFields, Dictionary 2 viewFilters,Boolean breakOnError,Int32 start,Int32 count,Dictionary 2 selectorViews, String rowFilterField) at PX.Api.ScreenUtils.Submit(String screenId, Command[] commands, SchemaMode schemaMode, PXGraph& graph, String& redirectContainerView, String& redirectScreen, Boolean mobile, Dictionary 2 viewFilters)      在PX.Api.Services.ScreenService.Submit(String id,IEnumerable 1 commands, SchemaMode schemaMode, Boolean mobile, PXGraph& forceGraph, String& redirectContainerView, String& redirectScreen, Dictionary 2 viewFilters)      在PX.Api.Services.ScreenService.Submit(String id,IEnumerable`1命令,SchemaMode schemaMode)      在PX.Api.Soap.Screen.ScreenGate.Submit(Command []命令)      ---内部异常堆栈跟踪结束---

但是,如果我使用单个DocumentDetails减少代码,如下所示:

$SO301000Submit->commands = array
        (
            $acumatica->prepareValue("SO", $SO301000GetSchema->OrderSummary->OrderType),
            $SO301000GetSchema->Actions->Insert,
            $acumatica->prepareValue("ACTIVESTAF", $SO301000GetSchema->OrderSummary->Customer),

            $SO301000GetSchema->DocumentDetails->ServiceCommands->NewRow,
            $acumatica->prepareValue("HQ", $SO301000GetSchema->DocumentDetails->Branch),
            $acumatica->prepareValue("AALEGO500", $SO301000GetSchema->DocumentDetails->InventoryID),
            $acumatica->prepareValue("WHOLESALE", $SO301000GetSchema->DocumentDetails->Warehouse, true),

            $SO301000GetSchema->Actions->Save,
            $SO301000GetSchema->OrderSummary->OrderNbr
        );
        $result = $acumatica->client->SO301000Submit($SO301000Submit);

然后,一切正常,创建了SalesOrder。

这是函数prepareValue:

public function prepareValue($value, $command, $needcommit = false, $ignore = false)
{
    $value_command = new ObjectDocument\Value();
    $value_command->Value = $value;
    $value_command->LinkedCommand = $command;
    if($needcommit) $value_command->Commit = true;

    $soapvar = new \SoapVar($value_command, SOAP_ENC_OBJECT, "Value", "http://www.acumatica.com/generic/");
    return $soapvar;
}

我不知道为什么?请帮我解释一下这个案子。

1 个答案:

答案 0 :(得分:1)

正如@Gabriel所提到的,PHP发送的SOAP消息略有不同。 问题是为PHP请求创建的XML引入了XML中的id,然后在找到相同节点的任何地方,它只传递id作为引用。

示例(使用Fiddler捕获SOAP消息下方): -

enter image description here

要解决此问题,请创建具有相同结构的两个不同项目。您可以使用clone

如下所示创建新函数PrepareValueExt并将其用于行。

public function PrepareValueExt($value, $command, $needcommit=false, $ignore=false)
{
    $value_command = new Value();
    $value_command->Value = $value;
    $value_command->LinkedCommand = clone $command;
    //$value_command->IgnoreError = $ignore;
    if($needcommit) $value_command->Commit = true;

    return($value_command);
}

并更改NewRow的代码:

array_push($command, clone $schema->DocumentDetails->ServiceCommands->NewRow);