Aresh Posted December 20, 2021 Share Posted December 20, 2021 (edited) 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. ps_order_cart_rules ps_orders: ps_order_invoice: BO>Catalog>Coupons: 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 December 20, 2021 by Aresh (see edit history) Link to comment Share on other sites More sharing options...
Aresh Posted December 23, 2021 Author Share Posted December 23, 2021 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now