Acumatica:如何在ruby中创建新客户?

时间:2015-01-12 20:00:57

标签: ruby xml api soap acumatica

我需要在ruby中使用SOAP API创建Customer(我们希望从Ruby on Rails项目中使用Acumatica api)。

目前我使用Savon gem的代码如下:

client = Savon.client(wsdl: 'wsdl.wsdl') # sample wsdl path

response = client.call :login, message: { name: '', password: '' }
auth_cookies = response.http.cookies


class ServiceRequest

  def to_s
    builder = Builder::XmlMarkup.new
    builder.instruct!(:xml, encoding: 'UTF-8')

    # ... problem is here, I don't know how XML request should look like

    builder
  end

end

p client.call :submit, message: ServiceRequest.new, cookies: auth_cookies

问题在于,我不知道XML请求应该是什么样子。

C#请求看起来像这样(只是来自文档的一部分样本):

PO302000result = context.PO302000Submit(
      new Command[]
      { new Value { Value = "PORE000079", LinkedCommand =
                                       PO302000.DocumentSummary.ReceiptNbr},
        new Value { Value = "OK", LinkedCommand =
               PO302000.AddPurchaseOrderLine.ServiceCommands.DialogAnswer,
               PO302000.Actions.AddPOOrderLine, new Key { Value = "='PORG000084'", FieldName = Commit = true },
   PO302000.AddPurchaseOrderLine.OrderNbr.FieldName, ObjectName =
              PO302000.AddPurchaseOrderLine.OrderNbr.ObjectName },
       new Key { Value = "='CPU00004'", FieldName =
              PO302000.AddPurchaseOrderLine.InventoryID.FieldName, ObjectName =
              PO302000.AddPurchaseOrderLine.InventoryID.ObjectName },
      new Value{ Value = "True", LinkedCommand =
          PO302000.AddPurchaseOrderLine.Selected, Commit = true },
                                PO302000.Actions.AddPOOrderLine2
       new Key{ Value = "='CPU00004'", FieldName =
     PO302000.DocumentDetails_.InventoryID.FieldName, ObjectName =
                 PO302000.DocumentDetails_.InventoryID.ObjectName},
     new Value{ Value = "1.00", LinkedCommand =
            PO302000.DocumentDetails_.ReceiptQty, Commit = true},
    // the next part of code is needed if you use Serial items
    PO302000.BinLotSerialNumbers.ServiceCommands.NewRow,
   new Value { Value = "R01", LinkedCommand =
                         PO302000.BinLotSerialNumbers.Location },
   PO302000.Actions.Save
  } );

但我不知道这段代码产生的XML类型。看起来我们的Commands数组包含Values,然后是action name。但是这种代码呈现的XML是什么?也许一些C#或Java人员可以复制由这种代码呈现的xml请求样本?

非常感谢你。

4 个答案:

答案 0 :(得分:1)

基本上手动生成XML SOAP包是个坏主意,你应该有一些包装器,这需要简化你的代码。

答案 1 :(得分:0)

无论如何,下面的C#代码+ XML SOAP请求

            Content[] result = context.Submit(
            new Command[] 
                {                                                    
                    new Value { Value = "PORE000079", LinkedCommand = PO302000.DocumentSummary.ReceiptNbr}
                    ,new Value { Value = "OK", LinkedCommand = PO302000.AddPurchaseOrderLine.ServiceCommands.DialogAnswer, Commit = true }
                    ,PO302000.Actions.AddPOOrderLine                                                
                    ,new Key { Value = "='PORG000077'", FieldName = PO302000.AddPurchaseOrderLine.OrderNbr.FieldName, ObjectName = PO302000.AddPurchaseOrderLine.OrderNbr.ObjectName }
                    ,new Key { Value = "='CPU00004'", FieldName = PO302000.AddPurchaseOrderLine.InventoryID.FieldName, ObjectName = PO302000.AddPurchaseOrderLine.InventoryID.ObjectName }
                    ,new Value{ Value = "True", LinkedCommand = PO302000.AddPurchaseOrderLine.Selected, Commit = true }
                    ,PO302000.Actions.AddPOOrderLine2                        
                    ,new Key{ Value = "='CPU00004'", FieldName = PO302000.DocumentDetails.InventoryID.FieldName, ObjectName = PO302000.DocumentDetails.InventoryID.ObjectName}
                    ,new Value{ Value = "1.00", LinkedCommand = PO302000.DocumentDetails.ReceiptQty, Commit = true}         

                    // the next part of code is needed if you use Serial items                            
                    ,PO302000.BinLotSerialNumbers.ServiceCommands.NewRow
                    ,new Value { Value = "R01", LinkedCommand = PO302000.BinLotSerialNumbers.Location }
                    ,new Value { Value = "1.00", LinkedCommand = PO302000.BinLotSerialNumbers.Quantity, Commit = true }
                    ,new Value { Value = "25.00", LinkedCommand = PO302000.DocumentDetails.UnitCost, Commit = true }
                    ,new Key { Value = "='CPU00004'", FieldName = PO302000.DocumentDetails.InventoryID.FieldName, ObjectName = PO302000.DocumentDetails.InventoryID.ObjectName }
                    ,new Value { Value = "0.00", LinkedCommand = PO302000.DocumentDetails.ReceiptQty, Commit = true }

                    ,PO302000.Actions.Save
                }
        );








<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><Submit xmlns="http://www.acumatica.com/typed/"><commands><Command xsi:type="Value"><Value>PORE000079</Value><LinkedCommand xsi:type="Field"><FieldName>ReceiptNbr</FieldName><ObjectName>Document</ObjectName><Value>ReceiptNbr</Value><Commit>true</Commit><LinkedCommand xsi:type="Action"><FieldName>cancel</FieldName><ObjectName>Document</ObjectName><LinkedCommand xsi:type="Key"><FieldName>ReceiptNbr</FieldName><ObjectName>Document</ObjectName><Value>=[Document.ReceiptNbr]</Value><LinkedCommand xsi:type="Key"><FieldName>ReceiptType</FieldName><ObjectName>Document</ObjectName><Value>=[Document.ReceiptType]</Value></LinkedCommand></LinkedCommand></LinkedCommand></LinkedCommand></Command><Command xsi:type="Value"><Value>OK</Value><Commit>true</Commit><LinkedCommand xsi:type="Answer"><ObjectName>poLinesSelection</ObjectName><Value>='Yes'</Value></LinkedCommand></Command><Command xsi:type="Action"><FieldName>AddPOOrderLine</FieldName><ObjectName>Document</ObjectName><Commit>true</Commit></Command><Command xsi:type="Key"><FieldName>OrderNbr</FieldName><ObjectName>poLinesSelection</ObjectName><Value>='PORG000077'</Value></Command><Command xsi:type="Key"><FieldName>InventoryID</FieldName><ObjectName>poLinesSelection</ObjectName><Value>='CPU00004'</Value></Command><Command xsi:type="Value"><Value>True</Value><Commit>true</Commit><LinkedCommand xsi:type="Field"><FieldName>Selected</FieldName><ObjectName>poLinesSelection</ObjectName><Value>Selected</Value><Commit>true</Commit></LinkedCommand></Command><Command xsi:type="Action"><FieldName>AddPOOrderLine2</FieldName><ObjectName>Document</ObjectName><Commit>true</Commit></Command><Command xsi:type="Key"><FieldName>InventoryID</FieldName><ObjectName>transactions</ObjectName><Value>='CPU00004'</Value></Command><Command xsi:type="Value"><Value>1.00</Value><Commit>true</Commit><LinkedCommand xsi:type="Field"><FieldName>ReceiptQty</FieldName><ObjectName>transactions</ObjectName><Value>ReceiptQty</Value><Commit>true</Commit></LinkedCommand></Command><Command xsi:type="NewRow"><ObjectName>splits</ObjectName></Command><Command xsi:type="Value"><Value>R01</Value><LinkedCommand xsi:type="Field"><FieldName>LocationID</FieldName><ObjectName>splits</ObjectName><Value>Location</Value></LinkedCommand></Command><Command xsi:type="Value"><Value>1.00</Value><Commit>true</Commit><LinkedCommand xsi:type="Field"><FieldName>Qty</FieldName><ObjectName>splits</ObjectName><Value>Quantity</Value></LinkedCommand></Command><Command xsi:type="Value"><Value>25.00</Value><Commit>true</Commit><LinkedCommand xsi:type="Field"><FieldName>CuryUnitCost</FieldName><ObjectName>transactions</ObjectName><Value>UnitCost</Value></LinkedCommand></Command><Command xsi:type="Key"><FieldName>InventoryID</FieldName><ObjectName>transactions</ObjectName><Value>='CPU00004'</Value></Command><Command xsi:type="Value"><Value>0.00</Value><Commit>true</Commit><LinkedCommand xsi:type="Field"><FieldName>ReceiptQty</FieldName><ObjectName>transactions</ObjectName><Value>ReceiptQty</Value><Commit>true</Commit></LinkedCommand></Command><Command xsi:type="Action"><FieldName>Save</FieldName><ObjectName>Document</ObjectName></Command></commands></Submit></soap:Body></soap:Envelope>

答案 2 :(得分:0)

所以最后我做了什么:

gem install 'mumboe-soap4r'  # not soap4r, 
                             # because soap4r is old and bugged with newer rubies

然后我跑了

wsdl2ruby.rb --wsdl customer.wsdl --type client

wsdl2ruby.rb与mumboe-soap4r gem一起安装。将customer.wsdl替换为wsdl的路径,可以是URL或文件系统路径。

运行此命令后,下一个文件被创建:

default.rb
defaultMappingRegistry.rb
defaultDriver.rb
ScreenClient.rb

使用这些文件,您可以编写类似于C#代码或php代码的代码,以便与acumatica API进行交互:

require_relative  'defaultDriver'
require           'soap/wsdlDriver'

# this is my helper method to make life easier
def prepare_value(value, command, need_commit = false, ignore = false)
  value_command                   = Value.new
  value_command.value             = value
  value_command.linkedCommand     = command
  value_command.ignoreError       = ignore        unless ignore.nil?
  value_command.commit            = need_commit   unless need_commit.nil?
  value_command
end

soap_client = SOAP::WSDLDriverFactory.new('customer.wsdl').create_rpc_driver
soap_client.login(name: '', password: '').loginResult

screen = soap_client.getSchema(nil)
soap_client.clear(nil)
content = screen.getSchemaResult
# p schema

p customer      = content.customerSummary.customerID
p customer_name = content.customerSummary.customerName
country         = content.generalInfoMainAddress.country
customer_class  = content.generalInfoFinancialSettings.customerClass


commands = ArrayOfCommand.new
commands << prepare_value('ABBA',     customer_name)
commands << prepare_value('US',       country)
commands << prepare_value('MERCHANT', customer_class)
commands << content.actions.insert
commands << customer.clone                # to return

p commands

p soap_client.submit(commands)

希望它会对某人有所帮助。

答案 3 :(得分:0)

实际上'mumboe-soap4r'或'soap2r'或'soap4r'不适用于Acumatica soap API。他们太老了,车子太大了。

最后我使用的是Savon gem(版本2)。我正在使用XmlMarkup类创建消息。但我怎么知道我应该创建什么XML?为了知道这一点,我在.net中创建了soap请求,然后我看到了正确的XML请求,然后我才使用Savon gem创建soap请求。太多的工作,但我现在还不知道更好的方法。有用。

为了使Savon能够使用Acumatica API,我设置了下一个选项:

client = Savon.client do

  wsdl                    'http://path/Soap/AR303000.asmx?wsdl'
  log                     true
  namespaces              'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/'
  env_namespace           'soap'

  namespace_identifier    nil
  element_form_default    ''

end

不要忘记通过身份验证cookie

response = client.call(:login, message: { name: '', password: '' })
auth_cookies = response.http.cookies

建立客户创建xml,然后提交

m = build_create_submit(customer_name)

response = client.call(:submit, message: m, cookies: auth_cookies)

# get customer id of newly created customer
customer_id = response.try(:hash).try(:[], :envelope).
                       try(:[], :body).
                       try(:[], :submit_response).
                       try(:[], :submit_result).
                       try(:[], :content).
                       try(:[], :customer_summary).
                       try(:[], :customer_id).
                       try(:[], :value)