Контролировать количество результатов от вызова Magento API - PullRequest
10 голосов
/ 17 октября 2011

У меня есть программа, которую мы используем для подключения нашего магазина Magento к нашей внутренней системе управления запасами через API.В настоящее время он запрашивает у Magento API все заказы в состоянии «Ожидание», вставляет их в серверную систему и устанавливает для них статус «Обработка в Magento».Из-за ограничений в нашей системе инвентаризации мы можем одновременно вводить только ограниченное количество заказов.Мы контролируем это, выполняя весь процесс через цикл if, как показано ниже (к вашему сведению, код был отредактирован, чтобы показать только ключевые части этой проблемы):

//The maximum number of orders to download
$iMaxCount = 10 ;

try {
  $proxy = new SoapClient($wsdl_url);
} catch (Exception $e) {
  echo 'Caught exception: ',  $e->getMessage(), "\n";
}

$sessionId = $proxy->login($login, $password);

//fetch the pending orders from the site
$field = array(array('status'=>array( 'pending') ));
$arr = $proxy->call($sessionId, 'sales_order.list', $field);
$iCnt = 0;

foreach($arr as $key => $value){
//only down up to the max count
if ($iCnt < $iMaxCount) {

[... Do the updating and insertion part of the program ...]

   $iCnt++;
} //End of looping through orders

Очевидный недостаток в выполнении этогоКстати, мне все еще нужно отозвать все отложенные ордера, хотя я собираюсь работать только с 10 из них.т.е. если у меня есть 200 отложенных ордеров, API возвращает все 200 из них, обрабатывает 10, а затем пропускает остальные.То, что я хочу сделать, это изменить фильтр вызова API, чтобы получать только 10 заказов в момент обработки статуса.Это позволило бы мне удалить издержки цикла if и сделать программу более эффективной, потому что она получает только те данные, которые ей нужны.

Кто-нибудь знает, как применять этот тип фильтра?Все, что я видел, говорит о том, что вы можете сделать это только в том случае, если вы знаете номера заказов и устанавливаете ограничения на основе этого.Спасибо за вашу помощь !!!

Ответы [ 3 ]

18 голосов
/ 17 октября 2011

Все вызовы API, в конце концов, просто исполняют код PHP.Где-то будет один метод PHP, который принимает аргументы, переданные через вызов API, поэтому лучше всего отслеживать, где выполняется этот код PHP.

Шаг 1 - найти конфигурацию вызова API.В современных версиях Magento конфигурации API хранятся в файлах с именем api.xml

$ find app/code/core/Mage/ -name 'api.xml'
app/code/core/Mage/Api/etc/api.xml
app/code/core/Mage/Catalog/etc/api.xml
app/code/core/Mage/CatalogInventory/etc/api.xml
app/code/core/Mage/Checkout/etc/api.xml
app/code/core/Mage/Customer/etc/api.xml
app/code/core/Mage/Directory/etc/api.xml
app/code/core/Mage/GiftMessage/etc/api.xml
app/code/core/Mage/Sales/etc/api.xml

Как только вы найдете все файлы api.xml, найдите их, чтобы определить, какой из них настраивает ваш "API верхнего уровня".namespace "(не знаю, как это на самом деле называют внутренние разработчики)

$ find app/code/core/Mage/ -name 'api.xml' | xargs grep sales_order
app/code/core/Mage/Sales/etc/api.xml:            <sales_order translate="title" module="sales">
app/code/core/Mage/Sales/etc/api.xml:            </sales_order>
app/code/core/Mage/Sales/etc/api.xml:            <sales_order_shipment>
app/code/core/Mage/Sales/etc/api.xml:            </sales_order_shipment>
app/code/core/Mage/Sales/etc/api.xml:            <sales_order_invoice>
app/code/core/Mage/Sales/etc/api.xml:            </sales_order_invoice>
app/code/core/Mage/Sales/etc/api.xml:            <order>sales_order</order>
app/code/core/Mage/Sales/etc/api.xml:            <order_shipment>sales_order_shipment</order_shipment>
app/code/core/Mage/Sales/etc/api.xml:            <order_invoice>sales_order_invoice</order_invoice>

Похоже, app/code/core/Mage/Sales/etc/api.xml - это файл, который мы хотим, так как он имеет тег <sales_order />.Затем откройте файл и посмотрите на узел <sales_order />.

<sales_order translate="title" module="sales">
    <model>sales/order_api</model>
    <title>Order API</title>
    <acl>sales/order</acl>
    <methods>
        <list translate="title" module="sales">
            <title>Retrieve list of orders by filters</title>
            <method>items</method>
            <acl>sales/order/info</acl>
        </list>
        <info translate="title" module="sales">
            <title>Retrieve order information</title>
            <acl>sales/order/info</acl>
        </info>

Первый интересующий нас узел - <model>sales/order_api</model>.Это указывает на объект, который будет создан для обработки любого вызова API в пространстве имен sales_order.

Далее мы будем искать метод list в узле <methods/>.

<list translate="title" module="sales">
    <title>Retrieve list of orders by filters</title>
    <method>items</method>
    <acl>sales/order/info</acl>
</list>

Этот узел сообщает нам, что вызов sales_order.list соответствует методу items.Объединяя это с информацией, найденной выше, мы теперь знаем, что вызов API sales_order.list будет запускать код PHP, эквивалентный следующему

$m = Mage::getModel('sales/order_api');
$results = $m->items($args);

Далее, откройте файл модели и посмотрите на метод items

#File: app/code/core/Mage/Sales/Model/Order/Api.php
public function items($filters = null)
{
    //..a bunch of code to instantiate a collection object..
    if (is_array($filters)) {
        try {
            foreach ($filters as $field => $value) {
                if (isset($this->_attributesMap['order'][$field])) {
                    $field = $this->_attributesMap['order'][$field];
                }

                $collection->addFieldToFilter($field, $value);
            }
        } catch (Mage_Core_Exception $e) {
            $this->_fault('filters_invalid', $e->getMessage());
        }
    }        
}

В конце этого метода вы можете увидеть, что метод будет проходить через каждый аргумент и пытаться использовать его в качестве фильтра для коллекции.Ключом является поле, значением является поиск значения.Если вы осмотрите остальную часть метода, вы увидите, что нет другого способа взаимодействия параметров с коллекцией для добавления какого-либо подкачки или ограничений.

Итак, у вас остается три варианта.Первый - найти набор значений для передачи в

$collection->addFieldToFilter($field, $value);

, которые ограничат вашу коллекцию.Я бы предложил использовать фильтр даты с использованием синтаксиса array('from'=>'10','to'=>'20').

Второй вариант - создать переписать класс для Mage_Sales_Model_Order_Api::items, который выполняет дополнительную фильтрацию.

Ваш третийМожно было бы исследовать создание модуля, который добавляет пользовательский метод API для вызова.

1 голос
/ 05 сентября 2013

Быстрое решение для установки ограничения - найти приложение / код / ​​ядро ​​/ Маг / Продажи / Модель / Заказ / Api.php (и выполнить перезапись класса), а затем:

Измените сигнатуру метода, чтобы она принимала другой параметр $ limit, чтобы сигнатура метода выглядела следующим образом:

public function items($filters = null, $limit = null)

Затем добавьте следующую строку перед "foreach ($ orderCollection как $ order) {":

if( $limit ) $orderCollection->setPageSize( $limit );

Затем просто передайте лимит в качестве дополнительного аргумента вызову API sales_order.list.

Booyah!

0 голосов
/ 17 октября 2011

Вы должны иметь возможность использовать setPage, который устанавливает условие LIMIT запроса, указывая номер страницы (с одним индексом) и количество записей на странице.

$collection->setPage($pageNum, $pageSize);

Чтобы выбрать второй набор из 10 элементов, вы бы использовали следующее:

$collection->setPage(2, 10);

Более подробную информацию по этой теме можно найти здесь: Использование коллекций в Magento

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...