Jump to content

How to use addCartRule to already existing order?


Recommended Posts

Hello,

I need to add a coupon programmatically to already exsiting order. It works very well with creating new order via new Cart() and same named method addCartRule(). But when I try to add a coupon to an existing order (1) it's being created in all coupons, (2) it's even added to an order, but unfortunately: (3) the discount does not affect the invoice and total amount, (4) it disappears when I update this specific order discounts through BO (f.e. want to add another coupon or delete existing one).

For creating throught new Cart i use following code: 

// Create New Cart
$new_cart = new Cart();
$new_cart->id_lang = (int) $orderData['id_lang'];
$new_cart->id_shop = (int) $orderData['id_shop'];
$new_cart->id_shop_group = (int) $orderData['id_shop_group'];
$new_cart->id_currency = $orderData['id_currency'];
$new_cart->id_customer = $orderData['id_customer'];
$new_cart->id_address_delivery = $orderData['id_address_delivery'];
$new_cart->id_address_invoice = $orderData['id_address_invoice'];
$new_cart->id_carrier = $orderData['id_carrier'];
$new_cart->add();

// Create Cart Rule - discount 100%
$cart_rule = new CartRule();
$cart_rule->id_customer = $new_cart->id_customer;
$cart_rule->name = array(
Configuration::get('PS_LANG_DEFAULT') => $this->l('Discount 100%')
);
$cart_rule->date_from = date('Y-m-d H:i:s', time());
$cart_rule->date_to = date('Y-m-d H:i:s', time() + 24 * 3600);
$cart_rule->code = $this->customGenerateCouponCode();
$cart_rule->quantity = 1;
$cart_rule->quantity_per_user = 1;
$cart_rule->minimum_amount_currency = $new_cart->id_currency;
$cart_rule->reduction_currency = $new_cart->id_currency;
$cart_rule->free_shipping = true;
$cart_rule->reduction_percent = 100;
$cart_rule->active = 1;
$cart_rule->add();

// Add cart rule to cart and in order
$values = array(
'tax_incl' => $cart_rule->getContextualValue(true),
'tax_excl' => $cart_rule->getContextualValue(false)
);

$new_cart->addCartRule($cart_rule->id, $cart_rule->name[Configuration::get('PS_LANG_DEFAULT')], $values);

// Creating order from cart
$payment_module = Module::getInstanceByName('ps_wirepayment');
$resultp = $payment_module->validateOrder(
$new_cart->id,
35,
$new_cart->getOrderTotal(),
$orderData['payment_title'],
$orderData['comment'],
[],
null,
false,
$orderData['secure_key']
);

 

 And it works well. Below there is code to add coupon to existing order, and I have problem with the invoice.

$order = new Order((int) $orderData['id_order']);

$discountAmount = $this->customGetDiscountAmmount($orderData);

// Create Cart Rule
$cart_rule = new CartRule();
$cart_rule->id_customer = $orderData['id_customer'];
$cart_rule->name = array(
Configuration::get('PS_LANG_DEFAULT') => $this->l('Discount amount: ') . $discountAmount['tax_incl']
);
$cart_rule->date_from = date('Y-m-d H:i:s', time());
$cart_rule->date_to = date('Y-m-d H:i:s', time() + 24 * 3600);
$cart_rule->code = $this->customGenerateCouponCode();
$cart_rule->quantity = 1;
$cart_rule->quantity_per_user = 1;
$cart_rule->minimum_amount_currency = $orderData['id_currency'];
$cart_rule->reduction_currency = $orderData['id_currency'];
$cart_rule->free_shipping = false;
$cart_rule->partial_use = 0;
$cart_rule->reduction_amount = (int) $discountAmount['tax_incl']; #discount value
$cart_rule->active = 1;
$cart_rule->add();

// Add cart rule to cart and in order
$values = array(
'tax_incl' => (int) $discountAmount['tax_incl'],
'tax_excl' => (int) $discountAmount['tax_excl']
);

$order->addCartRule($cart_rule->id, $cart_rule->name[Configuration::get('PS_LANG_DEFAULT')], $values, $orderData['invoice_number']);

 

The discount is visible in order details, but doesn't affect the total price. 
image.thumb.png.728e241c46f999f69999c1f4fec7144f.png

 

ps_order_cart_rules
image.thumb.png.eb1aa0bd18968c37d2ebf0248cb0d63f.png

 

ps_orders:
image.thumb.png.346baa029f713ca61ccb411c184c5759.png

 

ps_order_invoice:
image.thumb.png.ea29cbd0a9a975854913d6f5eac9af8a.png

 

BO>Catalog>Coupons:
image.thumb.png.3df49f72e26c4cbb2fd0af3e2846fd20.png

 

Adding new coupon from BO to this order unbinds all coupons added through $order->addCartRule() method to this order. 

How to add coupon properly to existing order and how to make it affect order total amount?

Thanks in advance!

Edited by Aresh (see edit history)
Link to comment
Share on other sites

Found an answer. Below code seems to work properly. Vouchers don't disappear, invoice is updated same as order's totals. Adding manually vouchers doesn't make them disappear. 

Needed changes: we have to (1) link Cart Rule not only to the placed order, but also to cart on which the order was created; (2) we have to manually update invoice totals and discount values; (3) we have to manually update order's totals and discount values. It's necessary, because actually validateOrder() method makes similiar thing, but we cannot call this method on already placed order/cart.

Helped me replacing this:

$order = new Order((int) $orderData['id_order']);

$discountAmount = $this->customGetDiscountAmmount($orderData);

// Create Cart Rule
$cart_rule = new CartRule();
$cart_rule->id_customer = $orderData['id_customer'];
$cart_rule->name = array(
Configuration::get('PS_LANG_DEFAULT') => $this->l('Discount amount: ') . $discountAmount['tax_incl']
);
$cart_rule->date_from = date('Y-m-d H:i:s', time());
$cart_rule->date_to = date('Y-m-d H:i:s', time() + 24 * 3600);
$cart_rule->code = $this->customGenerateCouponCode();
$cart_rule->quantity = 1;
$cart_rule->quantity_per_user = 1;
$cart_rule->minimum_amount_currency = $orderData['id_currency'];
$cart_rule->reduction_currency = $orderData['id_currency'];
$cart_rule->free_shipping = false;
$cart_rule->partial_use = 0;
$cart_rule->reduction_amount = (int) $discountAmount['tax_incl']; #discount value
$cart_rule->active = 1;
$cart_rule->add();

// Add cart rule to cart and in order
$values = array(
'tax_incl' => (int) $discountAmount['tax_incl'],
'tax_excl' => (int) $discountAmount['tax_excl']
);

$order->addCartRule($cart_rule->id, $cart_rule->name[Configuration::get('PS_LANG_DEFAULT')], $values, $orderData['invoice_number']);

 

with this:

$order = new Order((int) $orderData['id_order']);
$old_cart = Cart::getCartByOrderId($order->id);

$discountAmount = $this->customGetDiscountAmmount($orderData);

// Create Cart Rule
$cart_rule = new CartRule();
$cart_rule->id_customer = $orderData['id_customer'];
$cart_rule->name = array(
Configuration::get('PS_LANG_DEFAULT') => $this->l('Discount amount: ') . $discountAmount['tax_incl']
);
$cart_rule->date_from = date('Y-m-d H:i:s', time());
$cart_rule->date_to = date('Y-m-d H:i:s', time() + 24 * 3600);
$cart_rule->code = $this->customGenerateCouponCode();
$cart_rule->quantity = 1;
$cart_rule->quantity_per_user = 1;
$cart_rule->minimum_amount_currency = $orderData['id_currency'];
$cart_rule->reduction_currency = $orderData['id_currency'];
$cart_rule->free_shipping = false;
$cart_rule->partial_use = 0;
$cart_rule->reduction_amount = (int) $discountAmount['tax_incl']; #discount value
$cart_rule->active = 1;
$cart_rule->add();

// Add cart rule to cart and in order
$values = array(
'tax_incl' => (int) $discountAmount['tax_incl'],
'tax_excl' => (int) $discountAmount['tax_excl']
);

$old_cart->addCartRule($cart_rule->id);
$order->addCartRule($cart_rule->id, $cart_rule->name[Configuration::get('PS_LANG_DEFAULT')], $values, $orderData['invoice_number']);

if ($order->hasInvoice()) {
  $order_invoice = new OrderInvoice($orderData['invoice_number']);
  if ($order_invoice->id !== 0) {
    $order_invoice->total_discount_tax_excl += (float) abs($values['tax_excl']);
    $order_invoice->total_paid_tax_excl -= (float) abs($values['tax_excl']);
    $order_invoice->total_discount_tax_incl += (float) abs($values['tax_incl']);
    $order_invoice->total_paid_tax_incl -= (float) abs($values['tax_incl']);
    $order_invoice->update();
  }
}

$order->total_discounts += (float) abs($values['tax_incl']);
$order->total_paid -= (float) abs($values['tax_incl']);
$order->total_discounts_tax_excl += (float) abs($values['tax_excl']);
$order->total_paid_tax_excl -= (float) abs($values['tax_excl']);
$order->total_discounts_tax_incl += (float) abs($values['tax_incl']);
$order->total_paid_tax_incl -= (float) abs($values['tax_incl']);

$order->update();

 

Greetings

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...