I am working on partials payments by creating order programmatically.
I am stuck with the issue when I am doing partials payments of a product in order. I created the order total successfully but woo commerce add remaining amount as a coupons, whereas I did not any coupons.
Here is my Function:
public function createNewOrder($order_array){
$address = array(
'first_name' => $order_array['first_name'],
'last_name' => $order_array['last_name'],
'company' => $order_array['company'],
'email' => $order_array['email'],
'phone' => $order_array['phone'],
'address_1' => $order_array['address_1'],
'address_2' => $order_array['address_2'],
'city' => $order_array['city'],
'state' => $order_array['state'],
'postcode' => $order_array['postcode'],
'country' => $order_array['country']
);
$args = array(
'customer_id' => $order_array['customer_id'],
'status' => $order_array['order_status'],
);
$order = wc_create_order($args);
$productArray = json_decode(stripslashes($order_array["productArray"]), true);
// This is an existing SIMPLE product
foreach ($productArray as $key => $value) {
$itemData=$value['id'];
$wc_deposit_enabled = get_post_meta( $itemData, '_wc_deposit_enabled', true );
$wc_deposit_amount = get_post_meta( $itemData, '_wc_deposit_amount', true );
$wc_amount = get_post_meta( $itemData,'_price',true );
if ($wc_deposit_enabled!="") {
$order->add_product( get_product($itemData), $value['quantity'], array(
'totals' => array(
'subtotal' => $wc_amount,
'total' => $wc_deposit_amount,
'subtotal_tax' => 0,
'tax' => 0,
)));
[enter image description here][1]
}else{
$order->add_product( get_product($itemData), $value['quantity']);
}
}
if(!empty($order_array['order_status']))
{
$order->update_status($order_array['order_status']);
}
$order->set_address( $address, 'billing' );
$order->calculate_totals();
$order->save();
}
Related
I'm using a Laravel 8 with darryldecode/laravelshoppingcart Cart Package. I'm struggling a bit with updating product quantity if it exists in users cart.
For example: If cart is empty, while adding a product and then clicking mutliple times on "Add To Cart" it adds only one product and then updates quantity to its maximum. But when I'm adding a second product, and then adding again product 1 it adds another product to the cart. It definitely should not add another product but it has to be restricted to maximum quantity of first product.
My cart store method:
public function store(CartStoreRequest $request) {
$validated = $request->validated();
$product = Product::findOrFail($validated['product_id']);
$rowId = uniqid();
$userID = $validated['user_id'];
// get current user cart
$currentCart = \Cart::session($userID);
if(!empty($currentCart->getContent()->toArray())) {
foreach($currentCart->getContent() as $item) {
$productID = $item->associatedModel->id;
if($productID === $product->id) {
$currentCart->update($item->id, [
'quantity' => [
'relative' => false,
'value' => $product->minStock($item->quantity + $validated['quantity']),
]
]);
} else {
$currentCart->add(array(
'id' => $rowId,
'name' => $product->name,
'price' => $product->price->amount(),
'quantity' => $validated['quantity'],
'associatedModel' => $product,
'attributes' => array(
'first_image' => $product->firstImage,
'formatted_price' => $product->formattedPrice,
'product_stock' => $product->stockCount()
)
));
}
}
} else {
$currentCart->add(array(
'id' => $rowId,
'name' => $product->name,
'price' => $product->price->amount(),
'quantity' => $validated['quantity'],
'associatedModel' => $product,
'attributes' => array(
'first_image' => $product->firstImage,
'formatted_price' => $product->formattedPrice,
'product_stock' => $product->stockCount()
)
));
}
return redirect()->back();
}
I hope that's someone had similar problem and knows how to solve this.
Okay, so the solution is to use product ID as $rowId,
$validated = $request->validated();
$product = Product::findOrFail($validated['product_id']);
$rowId = $product->id;
$userID = $validated['user_id'];
$currentCart = \Cart::session($userID);
$currentCart->add(array(
'id' => $rowId,
'name' => $product->name,
'price' => $product->price->amount(),
'quantity' => $product->minStock($validated['quantity']),
'associatedModel' => $product,
'attributes' => array(
'first_image' => $product->firstImage,
'formatted_price' => $product->formattedPrice,
'product_stock' => $product->stockCount()
)
));
$currentCartContents = $currentCart->get($rowId);
$quantity = $product->minStock($currentCartContents->quantity);
if($currentCartContents->quantity !== $quantity) {
$currentCart->update($rowId, [
'quantity' => [
'relative' => false,
'value' => $quantity,
]
]);
}
return redirect()->back();
I want set an alternative address if the cart has a product type that is equal on a specific type.
<?php
add_filter( 'woocommerce_checkout_create_order', 'mbm_alter_shipping', 10, 1 );
function mbm_alter_shipping ($order) {
global $woocommerce;
$items = $woocommerce->cart->get_cart();
foreach($items as $product => $values) {
$product->get_product();
if ($product->is_type('octopus')) {
$address = array(
'company' => 'Test',
'email' => 'test#test.com',
'phone' => '777-777-777-777',
'city' => 'London',
'state' => '',
'postcode' => '12345',
'country' => 'UK'
);
}
$order->set_address( $address, 'shipping' );
}
return $order;
}
?>
But when trying to place an order, I get an Internal Server Error and the order is not placed.
What I am doing wrong? Any help is appreciated.
The woocommerce_checkout_create_order is an action hook, your code is outdated and full of mistakes… Try to use the following instead:
add_action( 'woocommerce_checkout_create_order', 'alter_order_shipping_address', 10, 2 );
function alter_order_shipping_address( $order, $data ) {
// Loop through cart items
foreach( WC()->cart->get_cart() as $cart_item ) {
// Targetting a custom product type
if ( $cart_item['data']->is_type('octopus') ) {
// Changing shipping address
$order->set_address( array(
'company' => 'Test',
'email' => 'test#test.com',
'phone' => '777-777-777-777',
'city' => 'London',
'state' => '',
'postcode' => '12345',
'country' => 'UK'
), 'shipping' );
break; // stop the loop
}
}
}
Code goes in functions.php file of the active child theme (or active theme). It should works.
I am trying to add manual orders to woocommerce. Webshop is where I have stock values. I have store also. When customer buy in store, I have to add an order. When I want to add it via Orders->Add order it do not work properly, as I need to add tax value manual (Automattic, why?).
I'd like to have hidden page, to add orders.
I've seen Programmatically creating new order in Woocommerce
Here is what I tried:
I got order.php file in main folder:
<?php
/*
* Create order dynamically
*/
require(dirname(__FILE__) . '/wp-load.php');
echo 'ok?';
function create_vip_order() {
global $woocommerce;
$address = array(
'first_name' => 'John',
'last_name' => 'Doe',
'email' => 'test#gmail.com',
'phone' => '123456789',
'address_1' => '123 Main st.',
'city' => 'San Diego',
'state' => 'Ca',
'postcode' => '92121',
);
// Now we create the order
$order = wc_create_order();
// The add_product() function below is located in /plugins/woocommerce/includes/abstracts/abstract_wc_order.php
$order->add_product( get_product( '376' ), 1 ); // This is an existing SIMPLE product
$order->set_address( $address, 'billing' );
//
$order->calculate_totals();
$order->update_status("Completed", 'Imported order', TRUE);
}
add_action( 'init', 'create_vip_order' );
Finally code that I need is:
<?php
/*
* Create order manual
*/
require(dirname(__FILE__) . '/wp-load.php');
function create_new_order() {
global $woocommerce;
$address = array(
'first_name' => 'Zakup',
'last_name' => 'Sklepowy',
'email' => 'test#test.pl',
'phone' => '123',
'address_1' => 'ul. Przykladowa 1',
'address_2' => 'm. 2',
'city' => 'Wroclaw',
'postcode' => '50-123',
);
$order = wc_create_order();
$product = new WC_Product(wc_get_product_id_by_sku('*sku_here*'));
$order->add_product( $product, 1 );
$order->set_address( $address, 'billing' );
// Set payment gateway
$payment_gateways = WC()->payment_gateways->payment_gateways();
$order->set_payment_method( $payment_gateways['cod'] );
// Calculate totals
$order->calculate_totals();
$order->update_status('completed', 'In Store ', TRUE);
}
create_new_order();
?>
o/
Working on a minor project, and I'm creating a WC order from the admin area (programmatically), and i want to add a line item(Non product/fee to the order after it been created, but how exactly do i do that?
I create a order by doing:
$address = array(
'first_name' => $sBillingFirstName,
'last_name' => $sBillingLastName,
'company' => $sBillingCompanyName,
'email' => $sBillingEmail,
'phone' => $sBillingPhone,
'address_1' => $sBillingAddress1,
'address_2' => $sBillingAddress2,
'city' => $sBillingCity,
'state' => '',
'postcode' => $sBillingZipcode,
'country' => $sBillingCountry,
);
$oOrder = wc_create_order();
$oOrder->set_address( $address, 'billing' );
$oOrder->set_address( $address, 'shipping' );
and normally i would just do add_fee, as seen below to add a "non product" lineitem/fee, but since i dont have a cart object - what am i supposed to do?
wc->cart->add_fee("deposit", 200);
but i don't have a cart object, so how do i go about creating a the deposit in my new order?
Hi I have a cart in Codeigniter that works well. I tried to look for a discount/coupon handling but can't.
This is my cart code:
public function addToCart($id){
$this->load->model('products_model');
$products = $this->products_model->getItemDetail($id);
foreach ($products as $product) {
$insert = array(
'id' => $product->id,
'name' => $product->name,
'qty' => '1',
'price' => $product->item_eur,
'image' => $product->image,
'options' => array(
'info' => $product->cart_description,
'qty_description' => $product->qty_description
)
);
$this->cart->insert($insert);
}
$last = end($this->cart->contents());
echo $last['rowid'];
}
I thought of making a Coupon Code read from the DB and insert a discount as an item in the cart:
public function addCoupon(){
$this->load->model('products_model');
$res = $this->products_model->getCoupon($_POST['value']);
if($res){
foreach($res as $result){
$coupon = array(
'id' => $result->id,
'name' => $result->name,
'qty' => '1',
'price' => $result->discount,
'options' => array(
'info' => 'coupon',
'qty_description' => ''
)
);
$this->cart->insert($coupon);
}
echo '1';
}else{
$this->lang->load('products');
echo $this->lang->line('cart_notok');
}
}
Where the DB is
[name:type] (example)
id:int (1)
name: varchar ('Discount of 20€')
code: varchar ('AFD1234')
discount: decimal (-20)
[Edit]
And the model:
public function getCoupon($code){
$results = $this->db->get_where('coupons', array('code' => $code));
return $results->result();
}
The item gets added to the cart but if the 'price' => $result->discount is set to -20 or a percentage it gets set as +20€ and not -20€.
Any way to do this?