I want to disable cod when 100 cod orders is completed in prestashop - prestashop

I want to disable the cod delivery feature in the order page of prestashop 1.6.3 when 100 /50 orders ( this will be a parameter) is completed per day.
How to disable this programmatically by finding out whether 100 cod is been completed .

I will modify the hookPayment() in cashondelivery module to do this :
public function hookPayment($params)
{
if (!$this->active)
return ;
global $smarty;
// Check if cart has product download
if ($this->hasProductDownload($params['cart']))
return false;
//Check whether the cod done exceeds the daily limit if yes dont display the cod option
$cod_limit = Configuration::get('PS_KITS_COD_DAILY_LIMIT');// number of cod
$sql = "select count(*) AS cod_count from ps_orders where module='cashondelivery' and date(date_add) = CURDATE() and ( current_state= 3 or current_state=4)";
if ($row = Db::getInstance()->getRow($sql)){
$cod_count = $row['cod_count'];
}
if ($cod_count >= $cod_limit){
return ;
}
$smarty->assign(array(
'this_path' => $this->_path, //keep for retro compat
'this_path_cod' => $this->_path,
'this_path_ssl' => Tools::getShopDomainSsl(true, true).__PS_BASE_URI__.'modules/'.$this->name.'/'
));
return $this->display(__FILE__, 'payment.tpl');
}

Related

How we display discount percentage badge and sale badge separately on WooCommerce product?

Want to display discount percentage badge on right hand side of product image and sale badge on left hand side of product image in products slider. So, Please Suggest some hooks for this functionality!
Tried to add the following hook but it will replace the existing sale badge with the discount percentage badge on shop page and also this hook is not working for the product slider on homepage.
add_filter('woocommerce_sale_flash', 'add_percentage_to_sale_bubble'); function add_percentage_to_sale_bubble( $html ) { global $product; $percentage = round( ( ( $product->regular_price - $product->sale_price ) / $product->regular_price ) * 100 ); $output =' <span class="onsale">'.$percentage.'%</span>'; return $output; }
you can use the following hook
add_filter( 'woocommerce_get_price_html', 'change_displayed_sale_price_html', 10, 2 );
function change_displayed_sale_price_html( $price, $product ) {
// Only on sale products on frontend and excluding min/max price on variable products
if( $product->is_on_sale() && ! is_admin() && $product->is_type('simple') ){
// Get product prices
$regular_price = (float) $product->get_regular_price(); // Regular price
// Active price (the "Sale price" when on-sale)
$sale_price = (float) $product->get_price();
// "Saving Percentage" calculation and formatting
$precision = 0; // Max number of decimals
$saving_percentage = round( 100 - ( $sale_price / $regular_price * 100 ), $precision ) . '%';
// Append to the formated html price
$price .= sprintf( __('<p class="saved-sale">%s</p>', 'woocommerce' ), $saving_percentage );
}
return $price;
}

How to set a maximum stock level for total WooCommerce variations sold, disregarding individual variation stock levels

I'm wondering if we are able to hook into WooCommerce to set a maximum amount of stock that can be purchased for a variable product. Disregarding the individual variation stock levels once this maximum amount is reached.
For example, I have a variable product selling workshop groups. There are 4 variations, each with a stock level set at 100. This is because no group can have more than 100 people in. However, only 250 tickets are available for sale (not 400 that we might expect because of the 4x100 quantity).
So this works as far as the max 100 places per workshop group. We just need to somehow be able to limit the total stock level of all 4 variations to 250.
I had hoped enabling the parent product "Manage stock" option and setting this to 250 would work. But obviously, variations must override this. If we can hook into that and turn that back on even when variation stock management is in use that might be a nice way of solving this.
Thanks for any help.
I came up with a solution to my problem by doing the following:
Add 2 custom fields to the WooCommerce product page, which will store the max quantity of the total variations we can sell and also the max quantity of an individual variation. The code for this is:
// Modify WooCommerce Product Settings
add_action('woocommerce_product_options_inventory_product_data', 'wc_add_custom_field' );
function wc_add_custom_field() {
$fields = array('Total quantity' => 'total_quantity','Variation quantity' => 'variation_quantity');
$field_description = array('total_quantity' ='description','variation_quantity' ='description');
$field_placeholder = array('total_quantity' =>'e.g. 300','variation_quantity' =>'e.g. 100');
foreach ($fields as $key => $value) {
woocommerce_wp_text_input( array(
'id' => $value,
'label' => $key,
'description' => $field_description[$value],
'desc_tip' => 'true',
'placeholder' => $field_placeholder[$value]
) );
}
}
// Save Fields
add_action( 'save_post_product', 'woo_add_custom_general_fields_save' );
function woo_add_custom_general_fields_save( $post_id ){
update_post_meta( $post_id, 'total_quantity', $_POST['total_quantity'] );
update_post_meta( $post_id, 'variation_quantity', $_POST['variation_quantity'] );
}
Add cart/basket validation rules to stop customers being able to purchase products that exceed the value of the custom "total_quantity" field added above:
add_action( "woocommerce_add_to_cart_validation","sc_woocommerce_add_to_cart_validation", 1, 5 );
function sc_woocommerce_add_to_cart_validation( $passed, $product_id, $quantity, $variation_id, $variations ) {
// Iterate through each variation and get the total stock remaining
$product_variable = new WC_Product_Variable($product_id);
$product_variations = $product_variable->get_available_variations();
settype($variation_stock_availability, "integer");
foreach ($product_variations as $variation) {
$variation_stock_availability = +(int)$variation['max_qty'];
}
$count_variations = count($product_variations);
$total_quantity = get_post_meta( $product_id, 'total_quantity', true );
$variation_quantity = get_post_meta( $product_id, 'variation_quantity', true );
// formula to test if any stock remaining based on sold variations
$formula = $count_variations * $variation_quantity;
$formula1 = (int)$formula + (int)$quantity;
$formula1 = $formula1 - $variation_stock_availability;
// Iterating through each cart item and use the current running quantity in the cart in the forumula
foreach (WC()->cart->get_cart() as $cart_item_key=>$cart_item ){
// count(selected category) quantity
$running_qty += (int) $cart_item['quantity'];
$formula2 = (int)$formula + (int)$running_qty;
$formula2 = $formula2 - $variation_stock_availability;
// More than allowed products in the cart is not allowed
if ($formula2 >= $total_places) {
wc_add_notice( sprintf( __( "Unfortunately there is no availability based on your selection", "donaheys" )), 'error' );
$passed = false;
return $passed;
}
}
// More than allowed products in the cart is not allowed
if ($formula1 >= $total_places) {
// Add the error
wc_add_notice( sprintf( __( "Unfortunately there is no availability based on your selection", "donaheys" )), 'error' );
$passed = false;
return $passed;
} else {
$passed = true;
return $passed;
}
$running_qty = 0;
}
The result of the above code ensures we are can set a maximum amount of stock that can be purchased for a variable product, disregarding the individual variation stock levels once this maximum amount is reached.

How set quantity to out of stock in Prestashop

i'd like that when my product quantity is equal to 1, the product is out of stock ( and not when quantity is equal to 0 ).
Is it possible ?
How ?
In PrestaShop 1.6 (tested and confirmed working in v1.6.0.14) you can accomplish this by the following method, where the website will always show an available stock quantity that is the real quantity minue one. If you have 6 in stock this modification will change your website to report the stock as 5 to your customers, when you have only 1 stock available, customers will see the product with 0 quantity and marked as out of stock.
Copy the file /classes/stock/StockAvailable.php to /override/classes/stock/StockAvailable.php.
Edit the file /override/classes/stock/StockAvailable.php as follows.
At lines 357-380 is the function AvailableStock::getQuantityAvailableByProduct() that will normally read like this (formatting may vary slightly):
public static function getQuantityAvailableByProduct( $id_product,
$id_product_attribute = null, $id_shop = null ) {
if( $id_product_attribute === null ) $id_product_attribute = 0;
$skey = 'StockAvailable::getQuantityAvailableByProduct_' . (int)$id_product . '-' .
(int)$id_product_attribute . '-' . (int)$id_shop;
if( !Cache::isStored( $key )) {
$query = new DbQuery();
$query->select( 'SUM(quantity)' );
$query->from( 'stock_available' );
if( $id_product !== null ) $query->where( 'id_product = ' . (int)$id_product );
$query->where( 'id_product_attribute = ' . (int)$id_product_attribute );
$query = StockAvailable::addSqlShopRestriction( $query, $id_shop );
Cache::store( $key, (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue( $query ));
}
return Cache::retrieve( $key );
}
Replace the last line of the function beginning with the keyword return to the following:
$iStockQty = Cache::retrieve( $key );
if( $iStockQty > 0 ) $iStockQty--;
return $iStockQty;
Delete the file /cache/class_index.php so that Prestashop automatically re-creates this file taking into account the new override file.
I also found the method self::removeProductFromStockAvailable($id_product) in StockAvailable.php to do some similar stuff.

Exclude products out of stock from list of new products - Prestashop

I am using a module that displays new added products in home page. I need to customize the module so that this list doesnt contain products sold. In other words, if a product is out of stock before the number of days it is condidered new is over, then do not show this product in list.
I can do it in view part by using {if $product.quantity < 0}{/if} but my goal is to perform it in controller. Here is my code:
function hookHome($params)
{
global $smarty, $cookie;
$nb = intval(Configuration::get('HOME_NEW_PRODUCTS_NBR'));
$rand = intval(Configuration::get('HOME_NEW_PRODUCTS_RANDOM'));
if ($rand == 1) {
$products = Product::getNewProducts(intval($cookie->id_lang), 0, $nb);
if ( $products )
{
shuffle($products);
array_slice($products, ($nb ? $nb : 10));
}
}
else
{
$products = Product::getNewProducts(intval($cookie->id_lang), NULL - 0, (intval($nb ? $nb : 4)), false, NULL, NULL);
}
$smarty->assign(array(
....
'products' => $products,
....
);
return $this->display(__FILE__, 'homenewproducts.tpl');
}
How can I override the class Product so that the method getNewProducts take into account excluding products out of stock?
Or at least, how can I remove from $products the products with quantity =0 using PHP?
Your help is appreciated.
Well, the solution I am using now is:
In product.php, I changed the sql queries in getNewProducts method inside of NewProductsController so that it takes into account if product is available in stock
I added AND 'quantity'!=0 in line 2062 and $sql->where('p.'quantity' != 0'); in line 2086 . Prestashop 1.6.0.6.
Of course, better override the classe Product.php than modifying it.
I hope it can help.

Can't update product in magento module

have an issue updating magento product from frontend using a module that its function is for customers to create their own products and have the admin approve before enabled(this part is working).
the problem is when a customer tries to updated their admin approved product (as before approval, product states that newly created product is pending, but they can still update the data/attributes created during the product create function, the same attributes that are not updating using the controller)
first of all i have a controller with the action to update the approved/pending customer product
public function editPostAction() {
$id = $this->getRequest()->getParam('productid');
if ( $id !== false ) {
list($data, $errors) = $this->validatePost();
if ( !empty($errors) ) {
foreach ($errors as $message) {
$this->_getSession()->addError($message);
}
$this->_redirect('customer/products/edit/', array(
'id' => $id
));
} else {
$customerId = $this->_getSession()->getCustomer()->getid();
$product = Mage::getResourceModel('customerpartner/customerpartner_product_collection')
->addAttributeToSelect('*')
->addAttributeToFilter('customer_id', $customerId)
->addAttributeToFilter('entity_id', $id)
->load()
->getFirstItem();
$product->setName($this->getRequest()->getParam('name'));
$product->setSku($this->getRequest()->getParam('sku'));
$product->setDescription($this->getRequest()->getParam('description'));
$product->setShortDescription($this->getRequest()->getParam('short_description'));
$product->setPrice($this->getRequest()->getParam('price'));
$product->setWeight($this->getRequest()->getParam('weight'));
$product->setStock($this->getRequest()->getParam('stock'));
$product->save();
if ( isset($_FILES) && count($_FILES) > 0 ) {
foreach($_FILES as $image ) {
if ( $image['tmp_name'] != '' ) {
if ( ( $error = $this->uploadImage($image, $id) ) !== true ) {
$errors[] = $error;
}
}
}
}
if ( empty($errors) ) {
$this->_getSession()->addSuccess($this->__('Your product was successfully updated'));
} else {
$this->_getSession()->addError('Product info was saved but was imposible to save the image');
foreach ($errors as $message) {
$this->_getSession()->addError($message);
}
}
$this->_redirect('customer/products/');
}
}
}
as well as a form that on submit is supposed to update the product attributes and images but the page reloads on submit and shows successful saved message but the attributes are not updated and going back to the edit form (for each product created) for that product the values in the update form have the values of the update we just submitted, bet yet the products attributes are not updated in the catalog either (they remain the same values as entered in the create new process)
don't no if to continue to figure out what is going wrong or just move to either use api or direct sql to get the job done.
see this post Magento 1.7: Non-system product attribute not saving in PHP script the problem maybe different but the solution can be found in that post
updated to a new action to call in .phtml see below as it seems to be updating the product data as needed, still wanting to improve..
called in form using /frontendname/editApprovedPost/
public function editApprovedPostAction() {
$id = $this->getRequest()->getParam('productid');
$idproduct = $this->getRequest()->getParam('product_id');
if ( $id !== false ) {
list($data, $errors) = $this->validatePost();
if ( !empty($errors) ) {
foreach ($errors as $message) {
$this->_getSession()->addError($message);
}
$this->_redirect('customer/products/edit/', array(
'id' => $id
));
} else {
- now added more php code to action (in this order) after the } else {...
require_once 'app/Mage.php';
then add admin store for frontend product updates...
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
then get the customer id...
$customerId = Mage::getSingleton('customer/session')->getCustomerId();
then use the forms product Id to get the Product Id to update...
$product = Mage::getModel('catalog/product')->load("".$idproduct."");
then use setName() to update/save the attribute value grabbed from the forms input value...
$product->setName($this->getRequest()->getParam('name'));//use whatever attributes need (only text and text area tested so far)
then save/update product data with...
$product->save();
then add to run through errors...
if ( empty($errors) ) {
$this->_getSession()->addSuccess($this->__('Your product was successfully updated'));
} else {
$this->_getSession()->addError('Product info was saved but was imposible to save the image');
foreach ($errors as $message) {
$this->_getSession()->addError($message);
}
}
$this->_redirect('customer/products/');
}
}
}
then with a form to submit in frontend with customer logged in and customer group config
custom form only visible to Customer Group 2 (default is Wholesale)
form below....
sorry cant paste form to much work to paste the code here, any way using the
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
which i have read in some posts is that to update product in frontend you need to be "admin", which this seems to do just fine. As Noted before, the script was not updating and it was because it is trying to save to a different models data when the data to be updated was an actual product (that has been approved and created using the different models data) and it was updating using
$product = Mage::getResourceModel('customerpartner/customerpartner_product_collection')
would be good to here anyone else's comments
hope this helps someone because was think time to close this build.