woocommerce product price change based on formula - php

Here's the formula:
(raw material cost) + (fee_1 for processing) + (fee_2 for other processes) = final price.
+What I need is:
Set the (raw material cost) to a number globally, change it accordingly, basically weekly;
(fee_1) is set in the product admin page as an attribute;
same with (fee_2).
+My problem is:
dont have a clue about how to set a global material cost to the database with a admin frontend page.
the (fee_1) and (fee_2) seem like easier, I've read some pages, just need to test it.
Any one can provide me with some links or guides about how to get that?
High appriciated!
Michael

You can use this code to functions.php to add raw material cost to the whole cart and you can update it every week.
function woo_add_cart_fee() {
global $woocommerce;
$woocommerce->cart->add_fee( __('Custom', 'woocommerce'), 5 );
}
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );
But this won't be for every product and will be added to the whole cart no matter how many products there are.
To add raw material cost to each product based on the quantity, a much better way would be to use this plugin "Woocommerce product fee"

Related

Filter "woocommerce_cart_contents_weight" not applied for shipping weight

I'm trying to take account of the package weight in the total weight of the cart so I can bill the right shipping cost.
I tried adding a filter on 'woocommerce_cart_contents_weight' like explained there
So I added the following code snippet
function add_package_weight_to_cart_contents_weight( $weight ) {
$weight = $weight * 1.3; // add 30%
return $weight;
}
add_filter('woocommerce_cart_contents_weight', 'add_package_weight_to_cart_contents_weight');
I've also added a snippet to print cart weight on cart page, and I can see that the weight filter isn't applied : The total weight of the cart doesn't change wether the snippet is active or not.
I also tried putting exactly 900g articles in the cart so that, with the box weight, it goes over 1kg and change price, but the shipping price is still the one for under 1kg.
Any idea on why it isn't applied and how I could fix it ?
Your code works and only affects WC_Cart method get_cart_contents_weight() usage.
Now for shipping methods, as cart items can be divided into packages, the weight is calculated for each shipping package and doesn't use WC_Cart method get_cart_contents_weight(). Instead it will make a calculation on the cart items for each package.
A possible way should be to use the filter hook woocommerce_package_rates to alter cost based on the package weight calculation. But this is going to be much more complicated as it seems that you are using 3rd party plugins.

Woocommerce- Different prices for same product in cart

I am creating an eCommerce store for a relative's business. He has products that the user must personalize on the website. I am coding a separate page that will allow the user to do this, that will link back to the store and add the item to the cart when they are done.
I found a solution to add each product to the cart separately, instead of adding to the quantity (since each product added has been personalized), and a solution to change the price of items in the cart.
WooCommerce: Add product to cart with price override?
https://businessbloomer.com/woocommerce-display-separate-cart-items-product-quantity-1/
The problem is that all the items are changed, not just the last one added.
For example: User designs a ballpoint pen with her name on it. The price is $4. The user then designs a gel pen with her name. The cart will show two separate pens with an increased calculated price, but the price will increase for all pens, not just the last one added. I need to find a way to set the price for the last item added, based on the price sent from the product building page. So far, nothing I've tried has worked.
Variable products won't work for this site.
//To display a product separately every time it is added
function bbloomer_split_product_individual_cart_items( $cart_item_data, $product_id ){
$unique_cart_item_key = uniqid();
$cart_item_data['unique_key'] = $unique_cart_item_key;
return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data','bbloomer_split_product_individual_cart_items', 10, 2 );
add_filter( 'woocommerce_is_sold_individually', '__return_true' );
//To change the item price programmatically. Changes all items with the same ID
//I need it to change only the last one added.
//Set to retrieve new price from the customizing page
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price', 10, 1);
/**
* #param $cart_obj
*/
function add_custom_price($cart_obj ) {
ob_start();
include 'createbb.php';
global $custom_price;
$target_product_id = 17;
// This is necessary for WC 3.0+
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
foreach ( $cart_obj->get_cart() as $key => $value ) {
if ($value['product_id'] == $target_product_id) {
$value['data']->set_price($custom_price);
}
}
ob_end_clean();
}
The type of functionality you are looking for is actually so common that it has a name "Product Options" (this is different to variations). This feature allows you to add configurable add-on's to the price of a product through a design on the edit product page. In a lot of eCommerce platforms like OpenCart you have this sort of functionality built in for free, however Automattic opted to keep it as a separate bolt on which they charge for:
https://woocommerce.com/products/product-add-ons/
Before you say it yes it is annoying that they charge for it, really this is such a common thing for people to request you can tell that it was a calculated decision to monetise it. And yes it is still very possible to program everything bespoke, but you are inevitably re-inventing the wheel for no reason other than to avoid paying for the feature (there are free versions of the plugin above that others have made, google is your friend).
Consider something, what if Automattic change their hooks in the future? you'll have to modify your code, assuming you find out before it borks the site. What if you wish to change options, or you need someone else to change them and you are not around?
If you weigh things up, you'll find the best option in the end is either to grab the official plug-in, or use one of the free alternatives. Trust me I am doing you a favour.
Koda

Grey out Woocommerce product variation based on conditions?

I've got a customized WooCommerce shop where I want to be able to grey out certain product variations based on conditions, but I'm not sure where in the code to do it.
I have two prices for each item, one is a member price and one is a retail price.
I want everyone to see each variation but not be able to select the one that isn't available to them, so that non-members can see the retail price but can't select it, and vice versa.
The other customization I want is the following: I want to be able to only allow members to buy 5 products at member price per month, and then it will switch them over to retail price, so I need to be able to grey out the member price for members based on certain conditions as well.
Can anyone point me to the files/hooks/actions where I can inject some custom code into the variation output so I can make this happen?
Thanks.
For your two questions you can use in a different way woocommerce_add_to_cart_validation filter hook. With some conditions based on your users roles and on existing function arguments, customer will be able to select a variation of your product, but will not be able to added it to cart, if he is not allowed. You can even display a notice when customer try to add something when is not allowed…
add_filter( 'woocommerce_add_to_cart_validation', 'custom_add_to_cart_validation', 10, 5 );
function custom_add_to_cart_validation( $passed, $product_id, $quantity, $variation_id, $variations ) {
// Your code goes here
// If $passed is set to "false", the product is not added
// $passed = false;
return $passed;
}
For your last question, you will need to set/update some custom user meta data regarding the 5 products by month for the members, each time they place an order. You can use for this the woocommerce_thankyou or woocommerce_order_status_completed action hooks to set that custom data in the user meta data. Then you will be able to check this data enabling or disabling the right product variation in the woocommerce_add_to_cart_validation filter hook.
To finish, if you really want to grey out some variations, you will have to use Javascript/jQuery, but is going to be quite difficult as there is already a lot of javascript/Ajax WooCommerce events on product variations, that will conflict yours. But in WooCommerce everything is possible depending on time and skills…

magento customize quote collectTotals to show the updated totals

hey i'm implementing a custom discount system since magento discount system does not feet my requirements so i'm trying to apply a discount on an Mage_Sales_Model_Quote_Item I've read some and I've found the following function setOriginalCustomPrice the thing is that it applies on the item, and if the user changes the quantity he will get the discount on the item with the new quantity, so i'm trying to use a different method addOption on the item and only on the cart page show the calculations based on the quantity in the option value
$item->addOption(array('code'=>'promo','value' => serialize(['amount'=>10,'qty'=>1])));
and in the cart page
$promo = $item->getOptionByCode('promo');
echo '<div class="orig-price">'.$item->getOriginalPrice().'</div>';
echo '<div class="new-price">'.$item->getOriginalPrice() - ($promo['amount'] * $promo['qty']).'</div>';
the problem is that it does'nt actually apply the new price on the product,
so i want to customize Mage_Sales_Model_Quote->collectTotals() to show my discounts
and send it to the admin back-end when order is completed
how can i achieve that?
thanks in advance
I think there is a fundamental flaw in your approach. I'm not sure what you don't like in standard discounts, and what you can't achieve with catalog or shopping cart rules, but what you're trying to do definitely breaks these features (along with my heart).
However, if you're sure about what you're trying to do, then don't customize Mage_Sales_Model_Quote->collectTotals().
This function just... well, it collects all totals: subtotal, shipping, discount, etc. And it looks like you're changing only price output, but Magento itself doesn't know anything about it.
So if you want to let Magento know that you're changing the item price, you have to either add your own total, or change one of the existing totals. After that Magento will do everything else. Since after your changes Magento outputs already calculated price instead of original one, it may be strange for customer to see the original price in the cart and the additional discount total. So it looks like you will have to change subtotal total.
To do that you have to rewrite Mage_Sales_Model_Quote_Address_Total_Subtotal class in your extension and insert your calculation in _initItem() method. Around line 111 in the original file you will see the code:
$item->setPrice($finalPrice)
->setBaseOriginalPrice($finalPrice);
And this is where Magento sets price for the item, so you can insert your calculations and change $finalPrice before that. If you have virtual products, you will have to change collect() method too.

Magento - Dynamic Products / Dynamic Pricing / Creating Products on the fly

I have used magento many times, but this is the ultimate challenge. Im working on a magento store which has over 400,000 products - each with its own variation / product options. Hundreds of products are added and removed daily on our master store (which is based on a custom shopping cart system and runs on MSSQL).
I have configured magento to grab all the categories, products, text, descriptio, prices, variations etc and create the product pages dynamically on the fly e.g http://www.offices-furniture.co.uk/pp?prod=mercury-reception-unit.html
The problem is I now need to be able to add these products to the shopping cart without them physically existing in the back end. I have added one product to the back end and plan to use this as a GENERAL template type product, so its always this product (variations of it) that get added to the cart e.g
http://www.offices-furniture.co.uk/frodo.php but I cannot for the life of me get the price to change.... grrrr..
If anyone could point me in the right direction on how to change the price via HTML or PHP on the front end and post it to the shopping cart without changing the price on the back end
Thanks in advance all…
Here is the code i’ve tried using to change the price;
<?php
require_once ("app/Mage.php");
umask(0);
Mage::app("default");
Mage::getSingleton("core/session", array("name" => "frontend"));
// get the current Magento cart
$cart = Mage::getSingleton('checkout/cart');
$product = Mage::getModel('catalog/product');
$product->setCustomPrice(99);
$product->setOriginalCustomPrice(99);
$product->getProduct()->setIsSuperMode(true);
$product->setTypeId('configurable');
$product->setTaxClassId(1); //none
$product->setSku(ereg_replace("\n","","videoTest2.2"));
$product->setName(ereg_replace("\n","","videoTest2.2"));
$product->setDescription("videoTest2.2");
$product->setPrice("129.95");
$product->setShortDescription(ereg_replace("\n","","videoTest2.2"));
$cart->save();
if(isset($_POST['submit'])){
// call the Magento catalog/product model
$product = Mage::getModel('catalog/product')
// set the current store ID
->setStoreId(Mage::app()->getStore()->getId())
// load the product object
->load($_POST['product']);
*/
////////////////////////////
// get the current Magento cart
$cart = Mage::getSingleton('checkout/cart');
$product = Mage::getModel('catalog/product')
// set the current store ID
->setStoreId(Mage::app()->getStore()->getId())
// load the product object
->load($_POST['product']);
$product->setCustomPrice(99);
$product->setOriginalCustomPrice(99);
$product->getProduct()->setIsSuperMode(true);
$product->setTypeId('configurable');
$product->setTaxClassId(1); //none
$product->setSku(ereg_replace("\n","","videoTest2.2"));
$product->setName(ereg_replace("\n","","videoTest2.2"));
$product->setDescription("videoTest2.2");
$product->setPrice("129.95");
$product->setShortDescription(ereg_replace("\n","","videoTest2.2"));
$cart->save();
/////////////////////////////////////
// start adding the product
// format: addProduct(<product id>, array(
// 'qty' => <quantity>,
// 'super_attribute' => array(<attribute id> => <option id>)
// )
// )
$cart->addProduct($product, array(
'qty' => $_POST['qty'],
'price' => 50,
'super_attribute' => array( key($_POST['super_attribute']) => $_POST['super_attribute'][525] )
)
);
// save the cart
$cart->save();
// very straightforward, set the cart as updated
Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
// redirect to index.php
header("Location: frodo.php");
}else{
?>
Here is a snippet which might help you out... you can definitely change the price on the fly when a product is added to the cart. I'm using this on the checkout_cart_save_before event observer, and in this example it triggers when the weight of an item is over 10 lbs.
/**
* Set the price if the weight is over 10 lbs
*
* #param Varien_Event_Observer $observer
*/
public function setPriceOnCartSaveBefore(Varien_Event_Observer $observer)
{
$cart = $observer->getCart();
$items = $cart->getItems();
foreach($items as $item) {
if ($item->getWeight() > 10) {
$item->setCustomPrice(69.99);
$item->setOriginalCustomPrice(69.99);
}
}
}
Your question is not completely clear. There are two possible ways of interpreting this (of which I'm guessing you mean the second, because the first problem has a relatively easy solution):
1) You only need the custom price in the shopping cart, but it doesn't need to last through checkout
2) You do actually need to be able to sell the product for the custom price using the Magento checkout.
Ad 1: Only change price in shopping cart
This is relatively easy. I would use JavaScript and a custom PHP script that is accessible through AJAX and can calculate the price that should be displayed. This can then be done through DOM manipulation. CSS can help you hide the price until the AJAX calculation is finished.
Another way of doing it would be to edit the price template file. Because Magento phtml files get called within the View class of the object that is currently rendering (e.g. cart or quote), you will be able to get the ProductID. You can then check if the Product that is being added is your magic custom template product and change the price accordingly.
In the base/default template you would get the item ID as such in base/default/template/checkout/cart/item/default.phtml
$product_id = $_item->getProduct()->getId();
When you figure out what combination of Weee, InclTax etc. you have used for your website (so you know where in default.pthml your price actually gets displayed), you can get an if statement in there and display the custom price somehow.
Ad 2: Keep price changed through checkout
I don't think it's possible to do this. Especially with Magento obsessing about order integrity (being that products and their info will always be available through that order, even if you delete them from the catalog).
The closest thing you'll get to this (at least as far as I can imagine) is to have the template product you set up include a custom drop-down option that enables using a variable price.
You could try to set the price of the only value for that custom drop-down option dynamically, but I doubt even that would work. The last thing you could try then is to add a value (with your custom price) to the custom option for that product every time an order is placed. That way, you keep Magento overhead to a minimum, but still satisfy Magento bureaucracy by providing Magento a way to keep a history of the physical product you have sold.
Another suggestion
There is also the possibility of using products with custom options the way they were meant to be used. If you create a basic template product with enough custom options (e.g. shirt size, color, print, fabric) and add new custom option values on the fly. This way you could also check if an option already exists and each option can have its own added price value.
Last suggestion
If you really want to go all-out, you could try writing a custom module for Magento that in turn:
Creates a product when it gets added to the basket.
Removes that product again when the order is finished or when a customer removes it from the basket.
Prunes the custom products periodically (e.g. through Mage/cron) provided they are not still in a stored basked for any of your customers.
This would create temporary products instead of no products at all.
I hope I have shared some thoughts that can help you move along!

Categories