1
votes

Ideally we would like to prevent any items on an order from being shipped if they do not have an invoice created.

At the moment Magento (1.7.0.2) allows the creation of a shipment even if there has been no invoices created for the order. I realise this is by design for site owners who wish to ship first and invoice afterwards but our workflow requires payment first on creation of the invoice before allowing a shipment.

Could anyone please offer any suggestions code wise on what to change? I think the correct file would be /app/code/local/Mage/Sales/Model/Order/Shipment.php and the code we require to change would be below but im not sure how to check each item for an invoice individually.

Edit - Would the following code work well?

protected function _beforeSave()
{
    if ((!$this->getId() || null !== $this->_items) && !count($this->getAllItems())) {
        Mage::throwException(
            Mage::helper('sales')->__('Cannot create an empty shipment.')
        );
    }

    $order = $this->getOrder();
    if ($order->canInvoice()) {
        Mage::throwException(
            Mage::helper('sales')->__('Cannot ship items without an Invoice.')
        );
    }
1

1 Answers

0
votes

You can get some hints about the code to use by looking at this piece of code from: \app\code\core\Mage\Sales\Model\Order.php in the public function canInvoice():

public function canInvoice()
{
    if ($this->canUnhold() || $this->isPaymentReview()) {
        return false;
    }
    $state = $this->getState();
    if ($this->isCanceled() || $state === self::STATE_COMPLETE || $state === self::STATE_CLOSED) {
        return false;
    }

    if ($this->getActionFlag(self::ACTION_FLAG_INVOICE) === false) {
        return false;
    }

    foreach ($this->getAllItems() as $item) {
        if ($item->getQtyToInvoice()>0 && !$item->getLockedDoInvoice()) {
            return true;
        }
    }
    return false;
}