Search code examples
prestashopprestashop-1.6

Create Order in prestashop programmatically


I am trying to create an order in prestashop programmatically,

Here are the steps I am following:

$billingAddress = $order->getBillingAddress();
        $shippingAddress = $order->getShippingAddress();
        if (empty($billingAddress)) {
            continue;
        }
        $id_customer = $this->createPrestashopCustomer($billingAddress, $order->getEmail());
        $lines = $order->getLines();

        $AddressObject = new AddressCore();
        $AddressObject->id_customer = $id_customer;
        $AddressObject->firstname = $billingAddress->getfirstName();
        $AddressObject->lastname = $billingAddress->getlastName();
        $AddressObject->address1 = " " . $billingAddress->getHouseNr();
        $AddressObject->address1.= " " . $billingAddress->getHouseNrAddition();
        $AddressObject->address1.= " " . $billingAddress->getStreetName();
        $AddressObject->address1.= " " . $billingAddress->getZipCode();
        $AddressObject->address1.= " " . $billingAddress->getCity();
        $AddressObject->city = $billingAddress->getCity();
        $AddressObject->id_customer = $id_customer;
        $AddressObject->id_country = CountryCore::getByIso($billingAddress->getCountryIso());
        $AddressObject->alias = ($billingAddress->getcompanyName() != "") ? "Company" : "Home";
        $AddressObject->add();
        $currency_object = new CurrencyCore();
        $default_currency_object = $currency_object->getDefaultCurrency();
        $id_currency = $default_currency_object->id;
        $id_address = $AddressObject->id;

        $cart = new Cart();
        $cart->id_customer = (int) $id_customer;
        $cart->id_address_delivery = $id_address;
        $cart->id_address_invoice = $id_address;
        $cart->id_lang = 1;
        $cart->id_currency = (int) $id_address;
        $cart->id_carrier = 1;
        $cart->recyclable = 0;
        $cart->gift = 0;
        $cart->add();
        if (!empty($lines)) {
            foreach ($lines as $item) {
                $cart->updateQty(1, 5, 19);
            }
        } 
        $cart->update();
        $order_object = new OrderCore();
        $order_object->id_address_delivery = $id_address;
        $order_object->id_address_invoice = $id_address;
        $order_object->id_cart = $cart->id;

        $order_object->id_currency = $id_currency;
        $order_object->id_customer = $id_customer;
        $CarrierObject = new CarrierCore();
        $CarrierObject->delay[1] = "2-4";
        $CarrierObject->active = 1;
        $CarrierObject->name = "ChannelEngine Order2";
        $CarrierObject->add();
        $id_carrier = $CarrierObject->id;
        $order_object->id_carrier = $id_carrier;
        $order_object->payment = "Channel Engine Order";
        $order_object->module = "1";
        echo $order->getTotalInclVat();
        $order_object->valid = 1;
        $order_object->total_paid_tax_excl = $order->getTotalInclVat();
        $order_object->total_discounts_tax_incl = $order->getTotalInclVat();
        $order_object->total_paid = $order->getTotalInclVat();
        $order_object->total_paid_real = $order->getTotalInclVat();
        $order_object->total_products = $order->getSubTotalInclVat() - $order->getSubTotalVat();
        $order_object->total_products_wt = $order->getSubTotalInclVat();
        $order_object->conversion_rate = 1;
        $order_object->id_shop = 1;
        $order_object->id_lang = 1;
        $order_object->secure_key = md5(uniqid(rand(), true));
        $order_id = $order_object->add();

The Order is getting added to admin But somehow I can not see products in the order, Can anyone check and let me know what I am doing wrong here. Also order total is also 0.


Solution

  • You should also create OrderDetail Objects for each product of this order.

    Have a look at validateOrder() method of PaymentModule Class.

    Here is an extract from this method:

    $order = new Order();
    $order->product_list = $package['product_list'];
    
    if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_delivery') {
        $address = new Address((int)$id_address);
        $this->context->country = new Country((int)$address->id_country, (int)$this->context->cart->id_lang);
        if (!$this->context->country->active) {
            throw new PrestaShopException('The delivery address country is not active.');
        }
    }
    
    $carrier = null;
    if (!$this->context->cart->isVirtualCart() && isset($package['id_carrier'])) {
        $carrier = new Carrier((int)$package['id_carrier'], (int)$this->context->cart->id_lang);
        $order->id_carrier = (int)$carrier->id;
        $id_carrier = (int)$carrier->id;
    } else {
        $order->id_carrier = 0;
        $id_carrier = 0;
    }
    
    $order->id_customer = (int)$this->context->cart->id_customer;
    $order->id_address_invoice = (int)$this->context->cart->id_address_invoice;
    $order->id_address_delivery = (int)$id_address;
    $order->id_currency = $this->context->currency->id;
    $order->id_lang = (int)$this->context->cart->id_lang;
    $order->id_cart = (int)$this->context->cart->id;
    $order->reference = $reference;
    $order->id_shop = (int)$this->context->shop->id;
    $order->id_shop_group = (int)$this->context->shop->id_shop_group;
    
    $order->secure_key = ($secure_key ? pSQL($secure_key) : pSQL($this->context->customer->secure_key));
    $order->payment = $payment_method;
    if (isset($this->name)) {
        $order->module = $this->name;
    }
    $order->recyclable = $this->context->cart->recyclable;
    $order->gift = (int)$this->context->cart->gift;
    $order->gift_message = $this->context->cart->gift_message;
    $order->mobile_theme = $this->context->cart->mobile_theme;
    $order->conversion_rate = $this->context->currency->conversion_rate;
    $amount_paid = !$dont_touch_amount ? Tools::ps_round((float)$amount_paid, 2) : $amount_paid;
    $order->total_paid_real = 0;
    
    $order->total_products = (float)$this->context->cart->getOrderTotal(false, Cart::ONLY_PRODUCTS, $order->product_list, $id_carrier);
    $order->total_products_wt = (float)$this->context->cart->getOrderTotal(true, Cart::ONLY_PRODUCTS, $order->product_list, $id_carrier);
    $order->total_discounts_tax_excl = (float)abs($this->context->cart->getOrderTotal(false, Cart::ONLY_DISCOUNTS, $order->product_list, $id_carrier));
    $order->total_discounts_tax_incl = (float)abs($this->context->cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS, $order->product_list, $id_carrier));
    $order->total_discounts = $order->total_discounts_tax_incl;
    
    $order->total_shipping_tax_excl = (float)$this->context->cart->getPackageShippingCost((int)$id_carrier, false, null, $order->product_list);
    $order->total_shipping_tax_incl = (float)$this->context->cart->getPackageShippingCost((int)$id_carrier, true, null, $order->product_list);
    $order->total_shipping = $order->total_shipping_tax_incl;
    
    if (!is_null($carrier) && Validate::isLoadedObject($carrier)) {
        $order->carrier_tax_rate = $carrier->getTaxesRate(new Address((int)$this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
    }
    
    $order->total_wrapping_tax_excl = (float)abs($this->context->cart->getOrderTotal(false, Cart::ONLY_WRAPPING, $order->product_list, $id_carrier));
    $order->total_wrapping_tax_incl = (float)abs($this->context->cart->getOrderTotal(true, Cart::ONLY_WRAPPING, $order->product_list, $id_carrier));
    $order->total_wrapping = $order->total_wrapping_tax_incl;
    
    $order->total_paid_tax_excl = (float)Tools::ps_round((float)$this->context->cart->getOrderTotal(false, Cart::BOTH, $order->product_list, $id_carrier), _PS_PRICE_COMPUTE_PRECISION_);
    $order->total_paid_tax_incl = (float)Tools::ps_round((float)$this->context->cart->getOrderTotal(true, Cart::BOTH, $order->product_list, $id_carrier), _PS_PRICE_COMPUTE_PRECISION_);
    $order->total_paid = $order->total_paid_tax_incl;
    $order->round_mode = Configuration::get('PS_PRICE_ROUND_MODE');
    $order->round_type = Configuration::get('PS_ROUND_TYPE');
    
    $order->invoice_date = '0000-00-00 00:00:00';
    $order->delivery_date = '0000-00-00 00:00:00';
    
    if (self::DEBUG_MODE) {
        PrestaShopLogger::addLog('PaymentModule::validateOrder - Order is about to be added', 1, null, 'Cart', (int)$id_cart, true);
    }
    
    // Creating order
    $result = $order->add();
    
    if (!$result) {
        PrestaShopLogger::addLog('PaymentModule::validateOrder - Order cannot be created', 3, null, 'Cart', (int)$id_cart, true);
        throw new PrestaShopException('Can\'t save Order');
    }
    
    // Amount paid by customer is not the right one -> Status = payment error
    // We don't use the following condition to avoid the float precision issues : http://www.php.net/manual/en/language.types.float.php
    // if ($order->total_paid != $order->total_paid_real)
    // We use number_format in order to compare two string
    if ($order_status->logable && number_format($cart_total_paid, _PS_PRICE_COMPUTE_PRECISION_) != number_format($amount_paid, _PS_PRICE_COMPUTE_PRECISION_)) {
        $id_order_state = Configuration::get('PS_OS_ERROR');
    }
    
    $order_list[] = $order;
    
    if (self::DEBUG_MODE) {
        PrestaShopLogger::addLog('PaymentModule::validateOrder - OrderDetail is about to be added', 1, null, 'Cart', (int)$id_cart, true);
    }
    
    // Insert new Order detail list using cart for the current order
    $order_detail = new OrderDetail(null, null, $this->context);
    $order_detail->createList($order, $this->context->cart, $id_order_state, $order->product_list, 0, true, $package_list[$id_address][$id_package]['id_warehouse']);
    $order_detail_list[] = $order_detail;
    
    if (self::DEBUG_MODE) {
        PrestaShopLogger::addLog('PaymentModule::validateOrder - OrderCarrier is about to be added', 1, null, 'Cart', (int)$id_cart, true);
    }
    
    // Adding an entry in order_carrier table
    if (!is_null($carrier)) {
        $order_carrier = new OrderCarrier();
        $order_carrier->id_order = (int)$order->id;
        $order_carrier->id_carrier = (int)$id_carrier;
        $order_carrier->weight = (float)$order->getTotalWeight();
        $order_carrier->shipping_cost_tax_excl = (float)$order->total_shipping_tax_excl;
        $order_carrier->shipping_cost_tax_incl = (float)$order->total_shipping_tax_incl;
        $order_carrier->add();
    }