Minimum purchase in the checkout page by address ( City for example ) - prestashop

Hello to all the community,
Thank you in advance to whoever will take the time to answer me 😆!
In fact, I want to find a solution to make the minimum purchase on the checkout page ( not on the cart page ) and it depends on the address city.
I already did it in Prestashop 1.6 but now I use Prestashop 1.7.7.1 I am obliged to override the cart Presenter but I didn't rich a convenient solution.
Even I purchased a module of minimum purchase by country and modified it to be by the city but the module itself is not stable and it didn't work properly and the support of the module cannot find a solution because it requires an override of the core of Prestashop in the Symfony code and it will affect all the order tunnel which is typically impossible.
This topic will be a real challenge for developers that they don't know the impossible 😆!
Thanks in advance.

Assuming you are creating a module, in CartPresenter class you have hook overrideMinimalPurchasePrice. You can hook your module to this hook and modify the $minimalPurchase value in your module according to your logic.
You said that price depends on the address's city. Well, in your hook you can get the address, because in Prestashop front-office you always have access to cart and cart might have delivery address id:
public function hookOverrideMinimalPurchasePrice($params)
{
$cart = $this->context->cart;
$id_address = $cart->id_address_delivery;
// If customer did not enter the address yet, the address id is 0.
if($id_address != 0)
{
$address = new Address($id_address);
$city = $address->city;
if($city == 'New York')
$params['minimalPurchase'] = 100;
}
}
}
You do not have to return anything in the hook, because in CartPresenter.php the hook is called with parameter being passed by reference:
Hook::exec('overrideMinimalPurchasePrice', [
'minimalPurchase' => &$minimalPurchase,
]);

Related

Prestashop actionUpdateQuantity loop

I'm developing a simple module that hooks to actionUpdateQuantity hook. So, every time the stock of a product is updated I must update the stock of other products.
But, to update the stock I call stockAvailable object, which trigger the actionUpdateQuantity hook. So, I have a endless loop.
Then I tried to manually update the stock directly on the database using SQL, but this have the problem that other modules don't "see" the stock updates. So, modules like MailAlert, ebay or Amazon don't update stock correctly.
I'm a bit stuck here.
How can I update the stock without enter a loop ?
Thanks!
I had similar issue before and think this is not best way but worked for me. Idea is to add class variable in your module:
protected $isSaved = false;
then in hookActionProductUpdate function first check that variable and later after you done saving data change its value
public function hookActionProductUpdate($params)
{
if ($this->isSaved)
return null;
...
$this->isSaved = true;
}
Another way to do this is, in your module when you submit new quantity make sure you also submit product id and attribute id. Then in your hook you can do a check.
public function hookActionUpdateQuantity($params)
{
if ((int)Tools::getValue('id_product') != $params['id_product']
|| (int)Tools::getValue('id_attribute') != $params['id_product_attribute']) {
return false;
}
// do your stuff
}
Everytime the hook actionUpdateQuantity triggers you have a $params array of product whose quantity is being updated.
$params['id_product'] // id of a product being updated
$params['id_product_attribute'] // id of product combination being updated
$params['quantity'] // quantity being set to product
This way your hook will run only once when you are updating quantity of a product from your module (form?). As you update other products quantity they will also trigger this hook but since the data in $params array is different than your POST'ed data, the hook method will return false.

Module delivery/shipping prestashop

I created a custom module delivery/carrier, but I need to pass the weight of products, the ZIP Code of delivery and the order value for the webservice. I am not succeeding in taking this information into my module.
The following piece of code I'm using, actually, I'm following this example.
http://doc.prestashop.com/display/PS16/Creating+a+carrier+module
public function getOrderShippingCost($params, $shipping_cost)
{ // here I call my webservice }
I believe that this information is within $params, but do not know how to handle them or what they are.
It was pretty simple to fix, just use the following command.
$address = new Address ($params->id_address_delivery);
$zip = $address->postcode;
I can pick up any object parameter $address above.

How to create a new product from a custom form and then add it to the cart?

I am trying to develop a custom page on PS 1.6 where a customer could create a new product from a form and then add it to the cart.
Let's say for example, i am selling woodcrafts and i want my customers to fill a form where they need to specify the type of wood, dimensions, ...
Depending on these criterias, the price would be modified and it will create a "final" product that will be added to the customer's cart.
I know how i will develop the form and i believe i can add the product to the cart with updateQty() from Cart.php but how do i instanciate my product from the data i get from the form? I am trying to search through all files but i can't seem to find where new products are instanciated from.
Thanks in advance for the help
I'm answering my question since i managed to do it. Here's my solution :
public static function créerProduct($name, $ean13, $category, $price, $description, $reference){
$product = new Product();
$languages=Language::getLanguages();
foreach($languages as $lang){
$product->name[$lang['id_lang']]=$name;
$product->link_rewrite[$lang['id_lang']]=$name;
$product->description[$lang['id_lang']]=$description;
}
$product->reference=$reference;
$product->quantity=0;
$product->id_category_default=$category;
$product->id_category[]=$product->id_category_default;
$product->price=$price;
$product->id_tax_rules_group=1;
$product->indexed=0;
try{
$product->save();
} catch (PrestaShopException $e){
echo $e->displayMessage();
}
$product->updateCategories(array_map('intval', $product->id_category));
StockAvailable::setQuantity($product->id,'',1);
return $product->id;
}
public static function addProduitauPanier($id_product){
$context=Context::getContext();
$result=$context->cart->updateQty(1,$id_product);
}
Can you not use attributes to develop the product? The reason being is that you are going to have in effect customers adding information to your database and then you are going to have to sanitize it and validate it. I would use Prestashop's built in attributes for doing something like this.

How to show product quantity in the cart on custom page

I'm using Prestashop 1.5 and created page with list of grouped products. I want to show quantity of each product in the cart. At shopping cart page exist $product.cart_quantity property, but on my page it doesn't. Please, explain me, how to show product quantity in the cart on my page.
Easyest way I can think of is to access the data via cookies since cart data is stored in them.
You can get cookies data like this:
$context = Context::getContext();
echo '<pre>',print_r($context->cookie, true).'</pre>';
Prestashop Context is a registry for PHP variables that were previously accessed as globals. It aims to standardize the way these variables are accessed, and to make the code more robust by getting rid of global vars.
And our echo is just for example to show what info you can get from cookies.
When costumer adds something to the shopping-cart it automatically gives it a cart id (id_cart) and from there it's fairly easy to access to access that value to get all the info.
To get a cart id ( assuming you already got context ) use this
$Cart = $context->cart;
This returns you a ID of a current cart.
Now you want to return the current products in the cart ( with all the information it includes ). For that you have to use the public function located in prestashop_main_folder/classes/cart.php
So to return all the current products just use the following line
$Cart->getProducts($refresh = false, $id_product = false, $id_country = null)
And then it returns you a array with all the variables what you can easily then access.
BR's
You can do the following:
$context=Context::getContext();
$id_cart=$context->cookie->id_cart;
if($id_cart=='') $id_cart=Tools::getValue('id_cart');
$theCart = new Cart($id_cart);
$products = $theCart->getProducts(true);
$nbTotalProducts = 0;
foreach ($products as $product)
{
$nbTotalProducts += (int)$product['cart_quantity'];
}

Prestashop Module: hooks and orders

I am having multiple questions about this topic
As the title states, I am in need to find the correct hook to bind when an order has been placed and the payment was accepted.
1.) Which hook should I bind in my module when an order has been placed (and payed)?
2.) I am under the impression that there is no generalized hook for this, since some payment methods set the order status to 'payed' automatically (like a successful PayPal transaction) while other methodes require the shopowner to manually set the status to 'payed'. Are there any more than just those two that must be called to cover most cases?
3.) Eventhough I am still hoping that there is a generalized hook, if there's none, how would I approach this issue? Bind "actionPaymentConfirmation" aswell as "displayPaymentReturn" to cover both cases?
4.) Why is the hook "actionPaymentConfirmation" never called when I set the order status to "payed" in the backoffice. My code looks like this
public function install() {
if (!parent::install() || !$this->registerHook("actionPaymentConfirmation")) {
return false;
}
return true;
}
public function actionPaymentConfirmation($params) {
print_r($params); // stepping through with XDebug but the function is never being invoked
}
5.) Does anyone know a free module doing something simmilar I can dig into to get a better idea?
6.) Or might it be easier to override Prestashops core classes to tackle my problems? To break it down, I want to execute stuff after an order has been placed and the status is set to payment was accepted or remotely accepted.
Well, I hope I am not asking to much stuff at the same time, but as you can see, I am interested in mastering these things but have some troubles along the way. Have now been trying and especially search for answers for days now without any luck.
Regards!
I assume that you're with PrestaShop 1.5
1 actionValidateOrder (for new order) & actionOrderStatusPostUpdate (here you can check about the "paid" status)
2 Like 1.
3 Like 1.
4 The hook is actionOrderStatusPostUpdate
5
public function install()
{
return (parent::install()
AND $this->registerHook('newOrder')
AND $this->registerHook('actionOrderStatusPostUpdate'));
}
public function hookNewOrder($params)
{
return $this->hookActionOrderStatusPostUpdate($params);
}
public function hookActionOrderStatusPostUpdate($params)
{
//$params['newOrderStatus'] // after status changed
//$params['orderStatus'] // after order is placed
}
6 Look at 5.
Note: actionValidateOrder the new name (alias) of newOrder