Get a calculated price of Product Variation - drupal

I created a promotion with offer type - Fixed amount off each matching product and applies to - Specific product. In my custom block I get the product entity, but don't see any promotions there. How can I get it?
UPD: Tried to solve this problem with via commerce_order.price_calculator service.
commercePriceCalc = \Drupal::service('commerce_order.price_calculator');
$context = new Context(\Drupal::entityTypeManager()->getStorage('user')->load(1),
\Drupal::entityTypeManager()->getStorage('commerce_store')->load(1));
$prices = $commercePriceCalc->calculate($slide->field_product->entity, 1, $context);
So, calculate method returns me a PriceCalculatorResult object with 2 properties, calculatedPrice and basePrice but they are identical, as if the discount didn't apply, but I see it applied in a cart.

Solved this problem, by passing the 4th argument $adjustment_types to the $commercePriceCalc->calculate method.
$adjustment_types = array("promotion" => "promotion");
So, the final version of the code
$commercePriceCalc = \Drupal::service('commerce_order.price_calculator');
$context = new Context(\Drupal::currentUser(),
\Drupal::entityTypeManager()->getStorage('commerce_store')->load($store_id));
$prices = $commercePriceCalc->calculate($slide->field_product->entity, 1, $context, $adjustment_types);

Related

woocommerce recalculate price programmatically

11/5/21 Update
It's really tricky that find out the wc_order couldn't access the calculate_totals and calculate_taxes.I find out the solution is put $order = wc_get_order( $order->get_id() ); before calulation. The 2 $order type is different , one is (object)WC_Order and another one is (Object)Automattic\WooCommerce\Admin\Overrides\Order. The method of second object works.
I wanna make the AJAX function to place an order programmatically. The product price is base on metadata so I have to calculate every line item. It doesn't with any issue from the client side that sends the post the request to place. The problem point, even I set the price to the line item, and use calculate_totals for the WC_Order but the price didn't correct. The only correction is the cost and subtotal. Though I hit the recalculate button the price would be right.
code
function place_an_order($data){
$screen_prodcut = new WC_Product_Simple(6310);
$userid = get_current_user_id();
$order = wc_create_order(array('customer_id'=>$userid));
$screen_quantity = 2;
$item_id = $order->add_product($screen_prodcut,$screen_quantity);
wc_add_order_item_meta($item_id,'width','1201');
wc_add_order_item_meta($item_id,'height','1201');
wc_add_order_item_meta($item_id,'note','** this is testing**');
$screen_price = 50;
$new_line_screen_price = $screen_price * $screen_quantity;
$item = $order->get_item($item_id);
$item->set_subtotal( $new_line_screen_price / 11 * 10 );
$item->set_total( $new_line_screen_price / 11 * 10 );
$item->save();
// ###section 1###
$order->calculate_taxes();
$order->calculate_totals();
// ###section 2###
}
When run in section 1, the $item subtotal and total are correct. But run in section 2 there is the failure out when printing $order and retrieve the total is wrong. In the dashboard, the price would be shown wrong but the total and subtotal are correct.
After clicking the recalculate, the order total is corrected.
I have no idea why calculate_totals and calculate_taxes don't work. woocommerce_calc_line_taxes is the AJAX action via hit the recalculate button. Usage is calculate_totals and taxes as well. Alternatively, I have to use the set_total instead of calculate_totals?

Trying to get shipping fields with a new custome field created

I am trying to get the array for all the shipping forms with a new custom element that I already added. This code is not working:
$newObj = new WC_Checkout();
$shipping_fields = $newObj->get_checkout_fields($fieldset = 'shipping');
Woocommerce WC_Checkout methods:
Visit https://docs.woocommerce.com/wc-apidocs/source-class-WC_Checkout.html#197-281 for more info!
https://superuser.com?
I get NULL so the object is not existing
In detail:
I'm developing a website, where the total price is calculated according to a delivery area in some city. I decided to create a custom field within the shipping-form:
// Adding districts for the city of Lima on shipping form
add_filter('woocommerce_checkout_fields', 'custom_district_checkout_field');
function custom_district_checkout_field($fields) {
//the list for this example was shortened
$option_cities = array(
'' =>__('Select your district'),
'chorrillos' =>'Chorrillos',
'miraflores' =>'Miraflores'
};
$fields['shipping']['shipping_district']['type'] = 'select';
$fields['shipping']['shipping_district']['options'] = $option_cities;
$fields['shipping']['shipping_district']['class'] = array('update_totals_on_change');
$fields['shipping']['shipping_district']['input_class'] = array('wc-enhanced-select');
$fields['billing']['billing_district']['type'] = 'select';
$fields['billing']['billing_district']['options'] = $option_cities;
$fields['billing']['billing_district']['input_class'] = array('wc-enhanced-select');
wc_enqueue_js("jQuery( ':input.wc-enhanced-select' ).filter( ':not(.enhanced)' ).each( function() {var select2_args = { minimumResultsForSearch:5};jQuery( this ).select2( select2_args ).addClass( 'enhanced' );})");
return $fields;
I can confirm that the custome field is working. For other hand I'm trying to change the way the WooCommerce Advance Shipping plugin works as Jeroen Sormani (who is the developer) explain in his blogs:
How the plugin works!
and WAS Shipping fields conditions
The idea is to add to the condition list the shipping fields, the plugin shows by default this fields: WC Advanced Shipping Fields by Default
The goal is to been able to select the newly created field in the conditions (for example: "districts") so the price would appear in the cart when the user select the correct option, the plugin already has a list of the different districts with their respective prices. However, there is an error in the plugin because this line is not working (check the Github for the WAS Shipping fields conditions inside the first function:
$shipping_fields = WC()->checkout()->checkout_fields['shipping'];
I have been trying to solve this for weeks, hence the original ask in this post.
/**
* WAS all checkout fields
*/
add_filter('was_conditions', 'was_conditions_add_shipping_fields', 10, 1);
function was_conditions_add_shipping_fields($conditions) {
$newObj = new WC_Checkout();
$shipping_fields = $newObj->get_checkout_fields($fieldset = 'shipping');
debugToConsole($shipping_fields);
foreach ($shipping_fields as $key => $values) :
if (isset($values['label'])) :
$conditions['Shipping Fields'][$key] = $values['label'];
endif;
endforeach;
return $conditions;
}
The above results in a NULL with the debugToConsole function.

Akeneo: Create a new variant group with attributes

I want to create a new variant group in Akeneo with some fixed attributes to "simulate" the behaviour of a product family. Unfortunately I don't know how to get a ProductTemplate with some attributes with empty values.
When I tried my code below, I get an error after opening the created variant group in the Akeneo GUI:
Error: Option "attributes" must only contains instances of "Pim\Bundle\CatalogBundle\Entity\Attribute", got "Pim\Bundle\EnrichBundle\Form\Type\AvailableAttributesType"
My code looks like this:
$groupType = $this->groupManager
->getGroupTypeRepository()
->findOneBy(['code' => 'VARIANT']);
$group = $this->groupFactory->createGroup($groupType);
$group->setCode('MY_VARIANT_GROUP');
$attributes = array($this->attributeRepository->findOneByIdentifier('AXIS_ATTRIBUTE'));
$group->setAxisAttributes($attributes);
// ??? How can I create a new product value?
$productValue1 = new ProductValue();
$productValue1->setId('PREDEFINED_ATTRIBUTE1');
$productValue1->setAttribute($this->attributeRepository->findOneByIdentifier('PREDEFINED_ATTRIBUTE1'));
$productTemplate = new ProductTemplate();
$productTemplate->setValuesData(array($productValue1));
$group->setProductTemplate($productTemplate);
$this->groupSaver->save($group);
I advise you to use the Pim\Bundle\CatalogBundle\Builder\ProductTemplateBuilder to create and add attributes to your product template.
This will ensure that the product template will be properly created with empty product values.

How to set parameters in nested query in DQL

Hi,
I'd like to get number of created articles by a user, the query used to work until I added some parameters filtering the query by "fromDate" and "toDate" dates, here's my query :
// query String
$dql = 'SELECT u.idUser,
u.lastName,
u.email,
u.mobile,
(SELECT AVG(n.note)
FROM MyBundle:Note n
WHERE n.noteFor = u.idUser) AS note,
(SELECT COUNT(a)
FROM MyBundle:Article a
WHERE (a.createdBy = u.idUser) AND (a.createdAt BETWEEN :fromDate AND :toDate)) AS articles
FROM MyBundle:User u';
// create the actual query
$users= $em->createQuery($dql);
// set filter date parameter
$users->setParameter('fromDate', $fromDate.'00:00:00');
$users->setParameter('toDate', $toDate.'23:59:59');
I keep getting this error : Invalid parameter number: number of bound variables does not match number of tokens.
I tried searching in the doctrine documentation for how to set parameters in nested queries without finding anything. first I need to know if it's possible to do that then find where the error come from, Please Help !
Use setParameters() instead of setParameter()
$users->setParameters(array('fromDate'=> $fromDate.'00:00:00','toDate'=> $toDate.'23:59:59'))
So after performing some tests, I found out that the query worked well the way it was and the problem wasn't there.
I'm using KnpPaginatorBundle to paginate my queries, it seems that the problem was that it couldn't paginate complex queries like passing multiple parameters in the nested query. so I found a solution. So this is the old code :
// Pagination
$paginator = $this->get('knp_paginator');
$users = $paginator->paginate($users, 1, 10);
And this is the new code :
// Pagination
$paginator = $this->get('knp_paginator');
$users = $paginator->paginate($users, 1, 10, array('wrap-queries' => true) );
Thanks to Nisam and Matteo for their time, hope this helps someone

Accessing WordPress query var from a function hooked to woocommerce_add_to_cart_validation

I need to perform a check before adding a product to a WooCommerce cart. The check is based on a value stored in a WordPress query var. The problem is I can not access the $WP_Query from a function fired on the *woocommerce_add_to_cart_validation* hook.
The basic idea I'm trying to use for that is expressed in the following code:
add_action('woocommerce_add_to_cart_validation', 'the_function_to_go_with', 1, 5);
function the_function_to_go_with($passed, $product_id, $quantity) {
global $WP_Query;
$product_city = get_query_var('product_city');
$product_cat = get_query_var('product_cat');
*// a set of if clauses for the actual check*
}
If printed out to a file, the $WP_Query returns NULL. So, neither the query vars are returned.
An advice of what I am missing here would be much appreciated.

Resources