我需要使用 SOAP api 更新 magento 表中的组价
我试过这样做:
require_once 'app/Mage.php';
$proxy = new SoapClient('http://example.com/api/soap/?wsdl');
$sessionId = $proxy->login('abhi', '123456');
$productId = 1;
$price = 200;
$tierPrices = array(
array('customer_group_id' => '2', 'website' => '0', 'qty' => '1', 'price' => $price)
);
$result = $proxy->call(
$sessionId,
'product_attribute_group_price.update',
array(
$productId,
$tierPrices
)
);
if($result)
echo "Price has been update successfully";
它给出了错误:
Uncaught SoapFault exception: [3] Invalid api path. in /opt/lampp/htdocs/elligatorssilverjewelry/import.php:243 Stack trace: #0 /opt/lampp/htdocs/elligatorssilverjewelry/import.php(243): SoapClient->__call('call', Array) #1 /opt/lampp/htdocs/elligatorssilverjewelry/import.php(243): SoapClient->call('045aea7add6d7b7...', 'product_attribu...', Array) #2 {main} thrown in /opt/lampp/htdocs/elligatorssilverjewelry/import.php on line 243
但如果我使用 'product_attribute_tier_price.update' 代替 'product_attribute_group_price.update',它会更新等级价格,但我想更新团体价格。
最佳答案
我遇到了同样的问题,所以我为 soap 创建了一个自定义模块 API:
文件:
app/local/TreDing/Tapy/. (我的公司/模块)
.etc/api.xml
.etc/config.xml
.etc/wsdl.xml
.Model/New/Api.php
.Model/New/Api/V2.php
应用程序/etc/modules/TreDing_Tapy.xml
所以:
TreDing_Tapy.xml
<?xml version="1.0"?>
<config>
<modules>
<TreDing_Tapy>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Api />
</depends>
</TreDing_Tapy>
</modules>
</config>
API.xml
<?xml version="1.0"?>
<config>
<api>
<resources>
<tapy_new translate="title" module="tapy">
<model>tapy/new_api</model>
<acl>tapy/new</acl>
<title>Test Api</title>
<methods>
<info translate="title" module="tapy">
<title>func Test</title>
<method>info</method>
<acl>tapy/new/info</acl>
</info>
<update translate="title" module="tapy">
<title>func Test</title>
<method>update</method>
<acl>tapy/new/update</acl>
</update>
</methods>
</tapy_new>
</resources>
<acl>
<resources>
<all>
</all>
</resources>
</acl>
<v2>
<resources_function_prefix>
<new>new</new>
</resources_function_prefix>
</v2>
<resources_alias>
<new>tapy_new</new>
</resources_alias>
</api>
</config>
配置文件
<?xml version="1.0"?>
<config>
<modules>
<TreDing_Tapy>
<active>true</active>
<version>1.0</version>
</TreDing_Tapy>
</modules>
<global>
<models>
<tapy>
<class>TreDing_Tapy_Model</class>
</tapy>
</models>
</global>
wsdl.xml
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
<types>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
<!--<complexType name="catalogProductGroupPriceEntityArray">
<complexContent>
<restriction base="soapenc:Array">
<attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductGroupPriceEntity[]"/>
</restriction>
</complexContent>
</complexType>-->
<complexType name="catalogProductGroupPriceEntity">
<all>
<element name="customer_group_id" type="xsd:string" minOccurs="0"/>
<element name="website" type="xsd:string" minOccurs="0"/>
<element name="price" type="xsd:double" minOccurs="0"/>
</all>
</complexType>
<complexType name="catalogProductGroupPriceEntityArray">
<complexContent>
<restriction base="soapenc:Array">
<attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductGroupPriceEntity[]"/>
</restriction>
</complexContent>
</complexType>
</schema>
</types>
<message name="newInfoRequest">
<part name="sessionId" type="xsd:string"/>
<part name="product" type="xsd:string"/>
<part name="identifierGroup" type="xsd:string"/>
</message>
<message name="newInfoResponse">
<!--<part name="result" type="xsd:string" />-->
<part name="result" type="typens:catalogProductGroupPriceEntityArray"/>
</message>
<message name="newUpdateRequest">
<part name="sessionId" type="xsd:string"/>
<part name="product" type="xsd:string"/>
<part name="group_price" type="typens:catalogProductGroupPriceEntityArray"/>
<part name="identifierType" type="xsd:string"/>
</message>
<message name="newUpdateResponse">
<part name="result" type="xsd:int"/>
</message>
<portType name="{{var wsdl.handler}}PortType">
<operation name="newInfo">
<documentation>api test</documentation>
<input message="typens:newInfoRequest" />
<output message="typens:newInfoResponse" />
</operation>
<operation name="newUpdate">
<documentation>Update product group prices</documentation>
<input message="typens:newUpdateRequest"/>
<output message="typens:newUpdateResponse"/>
</operation>
</portType>
<binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="newInfo">
<soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
<input>
<soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</input>
<output>
<soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</output>
</operation>
<operation name="newUpdate">
<soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
<input>
<soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</input>
<output>
<soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</output>
</operation>
</binding>
<service name="{{var wsdl.name}}Service">
<port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
<soap:address location="{{var wsdl.url}}" />
</port>
</service>
API.php
<?php
class TreDing_Tapy_Model_New_Api extends Mage_Api_Model_Resource_Abstract
{
const ATTRIBUTE_CODE = 'group_price';
public function __construct()
{
$this->_storeIdSessionField = 'product_store_id';
}
public function info($productId, $identifierType = null)
{
$product = $this->_initProduct($productId, $identifierType);
$groupPrices = $product->getData(self::ATTRIBUTE_CODE);
if (!is_array($groupPrices)) {
return array();
}
$result = array();
foreach ($groupPrices as $groupPrice) {
$row = array();
$row['customer_group_id'] = $groupPrice['cust_group'];
$row['website'] = ($groupPrice['website_id'] ?
Mage::app()->getWebsite($groupPrice['website_id'])->getCode() :
'all'
);
$row['price'] = $groupPrice['price'];
$result[] = $row;
}
return $result;
}
public function update($productId, $groupPrices, $identifierType = null)
{
$product = $this->_initProduct($productId, $identifierType);
$updatedGroupPrices = $this->prepareGroupPrices($product, $groupPrices);
if (is_null($updatedGroupPrices)) {
$this->_fault('data_invalid', Mage::helper('catalog')->__('Invalid Group Prices'));
}
$product->setData(self::ATTRIBUTE_CODE, $updatedGroupPrices);
try {
/**
* @todo implement full validation process with errors returning which are ignoring now
* @todo see Mage_Catalog_Model_Product::validate()
*/
if (is_array($errors = $product->validate())) {
$strErrors = array();
foreach($errors as $code=>$error) {
$strErrors[] = ($error === true)? Mage::helper('catalog')->__('Value for "%s" is invalid.', $code) : Mage::helper('catalog')->__('Value for "%s" is invalid: %s', $code, $error);
}
$this->_fault('data_invalid', implode("\n", $strErrors));
}
$product->save();
} catch (Mage_Core_Exception $e) {
$this->_fault('not_updated', $e->getMessage());
}
return true;
}
public function prepareGroupPrices($product, $groupPrices = null)
{
if (!is_array($groupPrices)) {
return null;
}
if (!is_array($groupPrices)) {
$this->_fault('data_invalid', Mage::helper('catalog')->__('Invalid Group Prices'));
}
$updateValue = array();
foreach ($groupPrices as $groupPrice) {
if (!is_array($groupPrice)
|| !isset($groupPrice['price'])) {
$this->_fault('data_invalid', Mage::helper('catalog')->__('Invalid Group Prices'));
}
if (!isset($groupPrice['website']) || $groupPrice['website'] == 'all') {
$groupPrice['website'] = 0;
} else {
try {
$groupPrice['website'] = Mage::app()->getWebsite($groupPrice['website'])->getId();
} catch (Mage_Core_Exception $e) {
$groupPrice['website'] = 0;
}
}
if (intval($groupPrice['website']) > 0 && !in_array($groupPrice['website'], $product->getWebsiteIds())) {
$this->_fault('data_invalid', Mage::helper('catalog')->__('Invalid group prices. The product is not associated to the requested website.'));
}
$updateValue[] = array(
'website_id' => $groupPrice['website'],
'cust_group' => $groupPrice['customer_group_id'],
'price' => $groupPrice['price']
);
}
return $updateValue;
}
protected function _initProduct($productId, $identifierType = null)
{
$product = Mage::helper('catalog/product')->getProduct($productId, 0, $identifierType);
if (!$product->getId()) {
$this->_fault('product_not_exists');
}
return $product;
}
}
V2.php
<?php
class TreDing_Tapy_Model_New_Api_V2 extends TreDing_Tapy_Model_New_Api
{
public function Foo()
{
$a = 1;
return "test".$a;
}
public function prepareGroupPrices($product, $groupPrices = null)
{
if (!is_array($groupPrices)) {
return null;
}
$updateValue = array();
foreach ($groupPrices as $groupPrice) {
if (!is_object($groupPrice)
|| !isset($groupPrice->price)) {
$this->_fault('data_invalid', Mage::helper('catalog')->__('Invalid Group Prices'));
}
if (!isset($groupPrice->website) || $groupPrice->website == 'all') {
$groupPrice->website = 0;
} else {
try {
$groupPrice->website = Mage::app()->getWebsite($groupPrice->website)->getId();
} catch (Mage_Core_Exception $e) {
$groupPrice->website = 0;
}
}
if (intval($groupPrice->website) > 0 && !in_array($groupPrice->website, $product->getWebsiteIds())) {
$this->_fault('data_invalid', Mage::helper('catalog')->__('Invalid group prices. The product is not associated to the requested website.'));
}
/*if (!isset($groupPrice->customer_group_id)) {
$tierPrice->customer_group_id = 'all';
}
if ($tierPrice->customer_group_id == 'all') {
$tierPrice->customer_group_id = Mage_Customer_Model_Group::CUST_GROUP_ALL;
}*/
$updateValue[] = array(
'website_id' => $groupPrice->website,
'cust_group' => $groupPrice->customer_group_id,
'price' => $groupPrice->price
);
}
return $updateValue;
}
}
方法是 $soap->newInfo(); $soap->newUpdate();
这就像层组 api。 我用这个模块,一切正常。
问候
关于php - 如何通过 SOAP api 更新团体价格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17060295/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为