프로그래밍 방식으로 발송물 작성


32

프로그래밍 방식으로 발송물을 작성하는 다른 방법을 발견했습니다. 그들은

     //Type 1
     $converter=Mage::getModel('sales/convert_order');
     $shipment=$converter->toShipment($order);
     // snip

     //Type 2
     $shipment = Mage::getModel('sales/service_order', $order)
                                ->prepareShipment($this->_getItemQtys($order));
     // snip

     //Type 3
     $shipment = Mage::getModel('sales/service_order', $order)->prepareShipment($itemQty);
     $shipment = new Mage_Sales_Model_Order_Shipment_Api();
     $shipmentId = $shipment->create($orderId);
     // snip

이 방법의 차이점은 다음과 같습니다. 세 가지 방법 중 배송을 생성하고 추적 번호를 추가하는 적절한 방법입니다.


수락 및 현상금 상을 보증하기 위해 내 답변에 더 자세한 정보가 필요합니까? 당신이 원한다면 나는 비판이나 설명에 열려 있습니다.
philwinkle

답변:


47

나는 그것을 줄 것이다. 한 번에 하나씩 가져 갑시다.

방법 1

$converter=Mage::getModel('sales/convert_order');
$shipment=$converter->toShipment($order);

$converter위의 클래스는 클래스 세부 사항 에서로드되며,이 클래스 Mage_Sales_Model_Convert_OrdercopyFieldset주문 세부 사항을 운송 오브젝트로 복사하기 위해 호출되는 핵심 헬퍼를 사용 합니다. $ order는 array 또는 형식이어야 Varien_Object합니다.

이 메소드는 Mage::getModel('sales/convert_order')생성자 호출에서 사용 되는 메소드 3의 핵심입니다 .

이 방법의 주요 차별화 요소-배열 또는 객체를 가져 와서 $order기본 $shipment객체를 생성 할 수 있습니다 . 방법 2, 방법 3에 제시된 방법에 의해 독점적으로 사용되는 하위 수준 방법입니다.

방법 2

 $shipment = Mage::getModel('sales/service_order', $order)
                            ->prepareShipment($this->_getItemQtys($order));

이는 배송 및 송장 컨트롤러 모두에서 사용되는 배송을 생성하는 마 젠토 코어에서 가장 보편적 인 방법 인 것 같습니다. $order의 인스턴스화에 대한 생성자 인수로 사용되어 Mage_Sales_Model_Service_Order객체의 보호 속성으로 설정됩니다.

그런 다음 전화를 걸어 prepareShipment수량을 전달합니다. 이 메소드는 메소드 1의 변환기 클래스를 사용하므로 여기에서로 호출 되는 인수 에서 주문 항목 전달 항목 운송 수량 세부 사항과 같은 세부 사항을 지정할 필요가 없습니다 . 이를 자신의 상황에서 사용하려면 다음 형식으로 배열의 항목 수량을 전달하면됩니다.prepareShipment$this->_getItemQtys

array(
  'order_item_id'=>$qty,
  'order_item_id'=>$qty,
  'order_item_id'=>$qty
)

이 방법의 주요 차별화 요소-$ shipment 객체를 반환하지만 모든 항목이 변환됩니다. 플러그 앤 플레이입니다.

방법 3

Core에서이 방법을 사용했다는 증거를 찾을 수 없었습니다. 정직하게 말하면 해킹처럼 보입니다. 방법은 다음과 같습니다.

$itemQty =  $order->getItemsCollection()->count();
$shipment = Mage::getModel('sales/service_order', $order)->prepareShipment($itemQty);
$shipment = new Mage_Sales_Model_Order_Shipment_Api();
$shipmentId = $shipment->create($orderId);

1 단계는 위의 방법 2와 정확히 동일합니다. 차이 없음. 그러나 $shipment개체를 다시 가져 오면이 개체는을 (를) 직접 insantiation으로 대체합니다 Mage_Sales_Model_Order_Shipment_Api. 이것은 비표준입니다. 배송 Api 객체를 얻는 가장 좋은 방법은을 호출하는 것 Mage::getModel('sales/order_shipment_api')입니다.

그런 다음 덮어 쓴 새로운 Shipment API 객체를 사용 $orderId하여 코드에 정의되지 않은 변수 에서 발송물을 만듭니다 . 다시 말하지만 이것은 해결 방법처럼 보입니다.

보면 Mage_Sales_Model_Order_Shipment_Api::create()선적을 만드는 데 필요한 가장 기본적인 세부 사항은 순서대로, 그것은 선적을 생성하기위한 원 스톱 상점처럼 보인다 increment_id.

이것은 모듈이나 확장 프로그램에서 사용해서는 안되는 해킹입니다. 이 API는 XML RPC / SOAP API 요청을 통해 노출되는 기능에 사용되며 의도적으로 기본적으로 여러 단계 API 요청을 제거하는 데 사용됩니다.

결국 방법 3은 가장 중요하지만 Mage_Sales_Model_Order에 대한 호출을 통해 prepareShipment위의 익숙한 방법 2에 대한 상위 추상화 인을 호출합니다 .

public function prepareShipment($qtys = array())
{
    $shipment = Mage::getModel('sales/service_order', $this)->prepareShipment($qtys);
    return $shipment;
}

주요 차별화 요소 -발송물이 필요한 경우 핵을 신경 쓰지 않고 increment_id 만있는 경우이 방법을 사용하십시오. SOAP API를 통해이를 처리하려는 경우에도 유용한 정보입니다.

도움이 되길 바랍니다.


1
Magestore 재고 관리를 사용하는 모든 사람을 위해 노력합니다. 방법 3은 후크를 트리거하지 않으므로 Magento 핵심 배송과 창고 배송간에 배송 불일치가 발생합니다. 또한 좋은 답변 OP :)
Ricky Odin Matthews

7

여기서 중요한 것은 방법 1과 2가 작동하지 않는다는 것입니다.

나는 @philwinkle에 동의하지만 방법 3은 해키입니다. API 함수는 비 API 컨텍스트에서 실제로 호출해서는 안됩니다. 향후 릴리스에서 어떤 종류의 코드를 손상시킬 수 있는지 알 수 없습니다.

그래서 그게 뭐야? 글쎄, 방법 1과 2는 정확히 깨지지 않았습니다. 단지 그들이 일의 일부만을 수행한다는 것입니다. 다음과 같은 모습입니다.

참고 : 간결하게하기 위해 다음 코드 스 니펫은 적격 한 모든 항목을 배송에 추가합니다. 주문의 일부만 배송하고 싶다면 코드의 특정 부분을 수정해야합니다.

방법 1

당신의 코드를 보면 app/code/core/Mage/Sales/Model/Order/Shipment/Api.php(방법 3에서 사용되는) 당신이 외에도 것을 볼 수 있습니다 $convertor->toShipment($order)그것은 또한 호출 $item = $convertor->itemToShipmentItem($orderItem), $item->setQty($qty)그리고 $shipment->addItem($item)모든 자격이 주문 항목. 그렇습니다. 마 젠토는 정말 게으 르기 때문에 모든 것을 통해 동원해야합니다. 단일. 단계. 그런 다음 데이터베이스에 발송물을 실제로 저장하려면 몇 가지 후프를 뛰어 넘어야합니다.

따라서 방법 1은 다음과 같아야합니다.

$convertor = Mage::getModel('sales/convert_order');
$shipment = $convertor->toShipment($order);
foreach ($order->getAllItems() as $orderItem) {
    if ($orderItem->getQtyToShip() && !$orderItem->getIsVirtual()) {
        $item = $convertor->itemToShipmentItem($orderItem);
        $item->setQty($orderItem->getQtyToShip());
        $shipment->addItem($item);
    }
}
$shipment->register();
$order->setIsInProcess(true);
Mage::getModel('core/resource_transaction')
         ->addObject($shipment)
         ->addObject($order))
         ->save();

방법 2

우선, $this->_getItemQtys()특정 클래스 (_getItemQtys 함수를 가지고 있거나 상속 한 클래스)에서만 작동 하는 호출 이 있습니다. 따라서 변경해야하며 방법 1과 마찬가지로 프로세스를 육체 화해야합니다.

에서 찾고 app/code/core/Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php그것을하는 것은이 방법 약간 더 나은 상황 -이 항목이 출하 자체와 함께 변환됩니다 보인다. 그러나 여전히 임시 객체를 다시 가져 와서 데이터베이스에 직접 저장해야합니다.

$itemQtys = array();
foreach ($order->getAllItems() as $orderItem) {
    if ($orderItem->getQtyToShip() && !$orderItem->getIsVirtual()) {
        $itemQtys[$orderItem->getId()] = $orderItem->getQtyToShip();
    }
}
$shipment = Mage::getModel('sales/service_order', $order)->prepareShipment($itemQtys);
$shipment->register();
$order->setIsInProcess(true);
Mage::getModel('core/resource_transaction')
         ->addObject($shipment)
         ->addObject($order)
         ->save();

또한 배송에 실제로 어떤 품목이 들어 있는지 확인하기 위해 약간의 오류 검사를 추가하는 것이 좋습니다 register().

어느 것이 가장 좋은가요?

나는 그것이 의견의 문제라고 말하고 싶습니다. 벤치 마크 테스트를 수행하지는 않았지만 두 방법 간의 속도 차이가 무시할 만하다고 확신합니다. 코드 크기 및 가독성에 대해서는 그 사이에별로 있지 않습니다.

순서대로 모든 항목을 명시 적으로 변환하지 않아도되는 방법 2를 좋아하지만 여전히 수량을 추출하기 위해 항목을 통과해야합니다. 좋은 작은 코드 풋 프린트를 위해, 방법 3이 가장 좋아할 것입니다! 그러나 소프트웨어 엔지니어로서 나는 그것을 추천 할 수 없습니다. 그래서 나는 방법 2에 대해 통통하게 될 것입니다.


1

여러분 위의 어느 것도 내 문제에 효과가 없었습니다. 다음은 나를 위해 일했습니다. 그것이 당신을 도울 수 있도록 여기에 내려 놓으십시오.

public function _createShipment($orderIncrementId = '100310634'){
    // Load Product ..
    $order = Mage::getModel('sales/order')->loadByIncrementId($orderIncrementId);

    // Create Qty array
    $shipmentItems = array();
    foreach ($order->getAllItems() as $item) {
        $shipmentItems [$item->getId()] = $item->getQtyToShip();
    }

    // Prepear shipment and save ....
    if ($order->getId() && !empty($shipmentItems) && $order->canShip()) {
        $shipment = Mage::getModel('sales/service_order', $order)->prepareShipment($shipmentItems);
        $shipment->save();
    }
}

qty_shipped가 sales_flat_order_item 테이블에서이 메소드로 채워지지 않은 이유는 무엇입니까?
Creative Apps
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.