Thanks for any help
Bundled products
#281
Posted 28 March 2007 - 08:31 PM
Thanks for any help
#282
Posted 02 May 2007 - 03:51 PM
I have this contribution working fine for 2 yrs.
Lately i am getting this error:
1062 - Duplicate entry '32767-32767' for key 1
INSERT INTO products_bundles (bundle_id, subproduct_id, subproduct_qty) VALUES ('46698', '49029', '1')
Can some one please help
Kunal
#283
Posted 30 May 2007 - 11:00 AM
kunal247, on May 2 2007, 04:51 PM, said:
I have this contribution working fine for 2 yrs.
Lately i am getting this error:
1062 - Duplicate entry '32767-32767' for key 1
INSERT INTO products_bundles (bundle_id, subproduct_id, subproduct_qty) VALUES ('46698', '49029', '1')
Can some one please help
Kunal
#284
Posted 09 June 2007 - 12:39 AM
kunal247, on May 2 2007, 10:51 AM, said:
I have this contribution working fine for 2 yrs.
Lately i am getting this error:
1062 - Duplicate entry '32767-32767' for key 1
INSERT INTO products_bundles (bundle_id, subproduct_id, subproduct_qty) VALUES ('46698', '49029', '1')
Can some one please help
Kunal
Kunal,
The modification had a slight oversight, which I caught when I was looking into it. When you follow instruction to create the products_bundles table, it uses a data type of SMALLINT for the bundle_id and subproduct_id fields. SMALLINT only allows a maximum value of 32767. So each time you try to bundle a product with a master or sub product_id greater than 32767, it defaults to 32767.
To fix this, run this SQL to ALTER the table structure as follows...
ALTER TABLE `products_bundles` CHANGE `bundle_id` `bundle_id` INT( 9 ) NOT NULL DEFAULT '0', CHANGE `subproduct_qty` `subproduct_qty` INT( 9 ) NOT NULL DEFAULT '0';
This should allow for a maxium product id of 999,999,999.
-=Kaleb
#285
Posted 12 June 2007 - 08:12 PM
#286
Posted 22 June 2007 - 11:54 PM
#287
Posted 24 June 2007 - 11:46 AM
Just two points for general discussion:
1.
The latest contribution pack has no instructions. If you are installing this mod to a totally virgin install of osC then it's a simple job of copying the new files over - but how many of us are working with unmodified setups?
If someone with experience could add an instruction file to the mod pack it would help the inexperienced.
2.
We need to find a way of sorting the product list that appears in the bundle setup in the admin section. If you only have 10 products then I guess it's not too difficult to find the single items you want to add to your bundle, but we have around 500 products. Trying to find a single items from the seemingly random list can be a major pain.
If anyone has ideas on how to improve the sorting of the list I would be very happy to hear it.
Again, congrats on such a fantastic mod, keep up the good work.
#288
Posted 26 June 2007 - 02:32 PM
peasplease, on Jun 24 2007, 06:46 AM, said:
The latest contribution pack has no instructions. If you are installing this mod to a totally virgin install of osC then it's a simple job of copying the new files over - but how many of us are working with unmodified setups?
If someone with experience could add an instruction file to the mod pack it would help the inexperienced.
Anyway, my main purpose was to correct some mistakes in the previous rollup. Let me see if I can find the time to restore the older instructions to the readme.txt, and add the newer/missing ones.
#290
Posted 29 July 2007 - 04:17 AM
viper2626, on Mar 28 2007, 03:31 PM, said:
Thanks for any help
$product_query = tep_db_query("select pd.products_name, pd.products_description, pd.products_url, p.products_id, p.products_quantity, p.products_model, p.products_image, p.products_price, p.products_weight, p.products_date_added, p.products_last_modified, date_format(p.products_date_available, '%Y-%m-%d') as products_date_available, p.products_status, p.products_tax_class_id, p.manufacturers_id, p.products_bundlefrom " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd where p.products_id = '" . (int)$HTTP_GET_VARS['pID'] . "' and p.products_id = pd.products_id and pd.language_id = '" . (int)$languages_id . "'");
#291
Posted 16 August 2007 - 11:16 AM
I've installed the module and it seems to be working great with no problems so far.
The only issue I have with it, relates with the product images...It would be great if the images of the products that make the bundle, could appear automatically instead of uploading a new image. The buy two module seems to be working like that, and produces to small images that appear next to each other. I tried using the code there, but it was beyond my skills.
Has anyone tried or is willing to try it?
This must be one of the most useful contributions so far for os commerce!!
#292
Posted 21 October 2007 - 05:20 AM
Any help would be great?
Edited by runo1377, 21 October 2007 - 05:21 AM.
#293
Posted 06 November 2007 - 04:34 PM
I have installed the bundled products and it works fine but there is a little problem....
I have a product that cust 996.71 € and a bundled it one that cust 26.56 €.
The price of the bundle is 999 €
Cost of separate parts: € 26.56
And in the end, he say :
You save € -972.44
The total You save is € -24.27
who can i fix this ?
Best regards
Ema Ferreira
#294
Posted 26 November 2007 - 05:43 PM
I am planning on using the Bundles contrib (store still being set up with huge database) for the KITS I designed and assemble from the stock I also sell. The Bundles contrib will stop people from overloading me with orders I can't fill, such as schools wanting 100's of kits from my little mom & pop org. I'd be glad to fill them, but only if I have the stock to do so, and Bundles solves that for me.
However, I do keep 6 or so kits in stock ready to sell so I can fill orders efficiently, but the Bundles contrib doesn't let me do that. Since Bundles only subtracts the stock when the kit is sold, my actual stock levels would be inaccurate when I pre-assemble kits. People could end up buying stock I have already put into a kit.
There are 2 possible solutions I can see, one super easy, the other a little more involved:
1. Just change it so that the Bundles contrib will take the quantity sold from the Qty of kits on hand (from the master product) if that is greater than 0, or build the kit from scratch if there are not enough kits on hand. Then I could create a pretend order when I assemble kits to move the inventory out of the components, and then manually change the QOH of the kits. This is a very non-glamorous way of doing things, but it would work.
2. Make a "workorder" module that would do that manual part for me from the admin side. In other words, I wouldn't have to pretend to be a customer placing an order for kits I assembled, and then go delete the order without updating stock and manually change the kit stock level. It could all be done in the workorder system on the admin side. The change to first take stock from the existing kits in option 1 would still also have to be changed.
Even though I have been a programmer for 20+ years, I don't know PHP or SQL, or I would do at least option 1 myself. But perhaps someone could just lead me to the right area of code and I could figure out this option myself (hopefully). It just needs to consider the quantity of the master product as valid and use that first, while still showing the customer the components when they place the order (a feature I love about Bundles, but I blocked what they would pay if they bought it separately).
Any feedback would be greatly appreciated.
Thanks
#295
Posted 06 December 2007 - 12:22 AM
Well, it doesnt take into account the weight of all the products bundled together e.g. If admin has bundled product A with Product B and C; then the shipping chareges will only be calculated based on Product A's weight and not on A, B & Cs weight.
Other issue is that if the customer has added the bundled items in the cart and he click on the product listed in the "Shopping Cart Box", which appears on the top left side of shop; the system throws a SQL error like:
1064 - You have an error in your SQL syntax near '{4}1{3}5 and language_id = '1'' at line 7
SELECT pd.products_name, pb.*, p.products_bundle, p.products_id, p.products_price, p.products_image FROM products p INNER JOIN products_description pd ON p.products_id=pd.products_id INNER JOIN products_bundles pb ON pb.subproduct_id=pd.products_id WHERE pb.bundle_id = 1{4}1{3}5 and language_id = '1'
[TEP STOP]
Please let me know if any one can help me with the issue. Thanks.
#296
Posted 10 July 2008 - 10:37 PM
First, sorry for my english
I really need yout help to do my code working.
I have a php file which is executed each day to request payment (7 days after order), for people who chooses bank transfer and have not paid. It cancels it and restock after 14 days if payment have not been received.
It also cancels paypal pending payment after 1 day.
Here is the code :
<?php
/*
Contribution based on:
osCommerce, Open Source E-Commerce Solutions
http://www.oscommerce.com
*******************************************************************************
* Relance et annulation automatique de commandes clients v1.4 *
*******************************************************************************
* Ce script est à lancer tous les jours, manuellement ou à l'aide d'une tache *
* cron (bien plus pratique) *
* L'exécution de ce script permet de : *
* - Relancer les clients n'ayant pas encore payés leur commande après x jours *
* par rapport à la date de leur achat en leur envoyant un rappel par email *
* dont le contenu est personnalisable *
* - Annuler les commandes non réglées de plus de x jours par rapport à la *
* date d'achat *
* - Gérer 2 statuts de commande différents : "en attente virement" et "en *
* attente chèque" *
* - Remettre en stock les produits des commandes annulées *
*******************************************************************************
* v1.0 : par MarcelPiano le 27 janvier 2008 *
* Relance automatique tous les x jours des clients ayant une commande en *
* attente de paiement *
*******************************************************************************
* v1.1 : par Regne le 11 février 2008 *
* Modif pour correction du lien commande dans le mail de relance *
*******************************************************************************
* v1.2 : par Zardhoz le 14 février 2008 *
* Modif du code pour : *
* - Gérer 2 statuts de commande différents : "en attente virement" et "en *
* attente chèque" *
* - Annuler automatiquement les commandes passé x jours sans règlement à *
* partir de la date de commande. *
*******************************************************************************
* v1.3 par Ptitvasy le 22 février 2008 *
* Modif du code pour : *
* - Remettre en stock les produits des commandes annulées *
*******************************************************************************
* v1.4 par Zardhoz le 26 février 2008 *
* Modif du code pour : *
* - Ajout de commentaires *
* - Regroupement des paramètres modifiables pour une utilisation plus aisée *
*******************************************************************************
*/
include('includes/application_top.php');
//---------------------------------------------------------------------------------
// DEFINITION DU CONTENU DU MAIL DE RELANCE :
// A MODIFIER EN FONCTION DE VOS BESOINS
//---------------------------------------------------------------------------------
define('EMAIL_TEXT_SEPARATEUR', '------------------------------------------------------');
define('EMAIL_TEXT_SUBJECT', 'Votre commande est en attente');
define('EMAIL_TEXT_SUBJECT_P', 'Votre commande a été annulée');
define('EMAIL_TEXT_ORDER_NUMBER', 'Commande numéro :');
define('EMAIL_TEXT_INVOICE_URL', 'Facture détaillée :');
define('EMAIL_TEXT_DATE_ORDERED', 'Date de la commande :');
define('EMAIL_TEXT_COMMENTS_INTRO', 'Bonjour et merci d\'avoir choisi Bluecars.');
define('EMAIL_TEXT_COMMENTS_LIGNE1', 'Vous avez passé une commande il y a quelques jours et, sauf erreur de notre part, nous n\'avons toujours pas reçu votre réglement.');
define('EMAIL_TEXT_COMMENTS_LIGNE1P', 'Vous avez passé une commande il y a quelques jours et, sauf erreur de notre part, il semble que votre paiement par carte bleue n\'ait pas fonctionné.');
define('EMAIL_TEXT_COMMENTS_LIGNE2', 'Si vous venez d\'envoyer celui-ci, ou l\'avez envoyé depuis moins de 2 jours, ignorez ce mail.');
define('EMAIL_TEXT_COMMENTS_LIGNE2P', 'Votre commande a été automatiquement annulée, et nous vous invitons donc à réaliser une nouvelle commande.');
define('EMAIL_TEXT_COMMENTS_LIGNE3', 'Si vous souhaitez annuler votre commande, merci de nous en faire part en répondant à ce mail.');
define('EMAIL_TEXT_COMMENTS_LIGNE3P', 'Si vous avez deja effectué une nouvelle commande, ignorez ce mail.');
define('EMAIL_TEXT_COMMENTS_LIGNE4', 'Votre commande ne pourra être expédiée qu\'à réception de votre paiement, et à défaut de ce dernier, sera automatiquement annulée passé un délais de 14 jours à compter la date de commande.');
define('EMAIL_TEXT_COMMENTS_LIGNE5', 'Bluecars vous remercie de votre compréhension et de votre confiance.');
define('EMAIL_TEXT_END', 'A bientôt sur www.bluecars.net');
//---------------------------------------------------------------------------------
// PARAMETRES COMMUNS :
// A MODIFIER EN FONCTION DE VOS BESOINS ET DES PARAMETRES DE VOTRE BOUTIQUE
//---------------------------------------------------------------------------------
// Numéro du statut de commande annulée
$annulation_statut = '7';
// Notification client par mail lors de la relance : 0=non / 1=oui
$customer_notified_relance = '1';
// Notification client par mail lors de l'annulation de la commande : 0=non / 1=oui
$customer_notified_annulation = '0';
//---------------------------------------------------------------------------------
// PAYEMENT PAR CHEQUE et VIREMENT :
// A MODIFIER EN FONCTION DE VOS BESOINS ET DES PARAMETRES DE VOTRE BOUTIQUE
//---------------------------------------------------------------------------------
// Numéro du statut de commande en attente chèque et virement
$relance_statut_cheque = '1';
// Nombre de jours depuis commande avant relance automatique du client
$relance_nombre_cheque = '7';
// Nombre de jours depuis commande avant annulation de commande
$annulation_nombre_cheque = '14';
// Commentaire relance par mail
$comments_relance_cheque = 'Relance par mail ce jour';
// Commentaire annulation commande
$comments_annulation_cheque = 'Commande annulée';
//---------------------------------------------------------------------------------
// PAYEMENT PAR PAYPAL :
// A MODIFIER EN FONCTION DE VOS BESOINS ET DES PARAMETRES DE VOTRE BOUTIQUE
//---------------------------------------------------------------------------------
// Numéro du statut de commande verification paypal
$relance_statut_virement = '4';
// Nombre de jours depuis commande avant relance automatique du client
$relance_nombre_virement = '1';
// Nombre de jours depuis commande avant annulation de commande
$annulation_nombre_virement = '1';
// Commentaire relance par mail
$comments_relance_virement = 'Mail envoyé ce jour';
// Commentaire annulation commande
$comments_annulation_virement = 'Commande annulée';
//---------------------------------------------------------------------------------
// RELANCE AUTOMATIQUE PAYEMENT PAR CHEQUE ET VIREMENT
//---------------------------------------------------------------------------------
echo "Démarrage des relances de commandes en attente chèque et virement<br>";
// Test du champ orders.last_modified. Si le champs est vide, rempli avec la date de la commande
$req_last = "select orders_id, last_modified, date_purchased FROM orders WHERE orders_status = $relance_statut_cheque and last_modified is NULL";
$resultat_last = mysql_query($req_last);
while($l_last = mysql_fetch_array($resultat_last)){
tep_db_query("update orders set last_modified = date_purchased where orders_id = '" . $l_last['orders_id'] . "'");
}
// Sélection des commandes en attente paiement par rapport a la date date de commande
$req_relance = "select c.customers_id, c.customers_firstname, c.customers_lastname, c.customers_email_address, o.orders_id, o.customers_id, o.last_modified, o.date_purchased, o.orders_status from " . TABLE_CUSTOMERS . " c, " . TABLE_ORDERS . " o where o.orders_status = $relance_statut_cheque and c.customers_id = o.customers_id and TO_DAYS(NOW()) - TO_DAYS(o.date_purchased) = $relance_nombre_cheque";
$resultat = mysql_query($req_relance);
while($l = mysql_fetch_array($resultat)){
// Préparation et envoi du mail
$check_status_query = tep_db_query("select customers_name, customers_id, customers_email_address, orders_status, date_purchased from orders where orders_id = '" . $l['orders_id'] . "'");
$check_status = tep_db_fetch_array($check_status_query);
$num_com = $l['orders_id'];
$email = STORE_NAME . "\n" . EMAIL_TEXT_SEPARATEUR . "\n" . EMAIL_TEXT_ORDER_NUMBER . ' ' . $l['orders_id'] . "\n" . EMAIL_TEXT_INVOICE_URL . ' ' . tep_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $num_com, 'SSL', false) . "\n" . EMAIL_TEXT_DATE_ORDERED . ' ' . tep_date_short($l['date_purchased']) . "\n\n" . EMAIL_TEXT_COMMENTS_INTRO . "\n\n" . EMAIL_TEXT_COMMENTS_LIGNE1 . "\n\n" . EMAIL_TEXT_COMMENTS_LIGNE2 ."\n\n" . EMAIL_TEXT_COMMENTS_LIGNE3 . "\n\n" . EMAIL_TEXT_COMMENTS_LIGNE4 . "\n\n" . EMAIL_TEXT_COMMENTS_LIGNE5 . "\n\n" . EMAIL_TEXT_END;
tep_mail($check_status['customers_name'], $check_status['customers_email_address'], EMAIL_TEXT_SUBJECT, $email, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);
// Mise à jour de la table orders pour ajout dans l'historique de la commande
$customer_notified = $customer_notified_relance;
$status = $relance_statut_cheque;
$comments = $comments_relance_cheque;
tep_db_query("update orders set last_modified = now() where orders_id = '" . $l['orders_id'] . "'");
tep_db_query("insert into orders_status_history (orders_id, orders_status_id, date_added, customer_notified, comments) values ('" . $l['orders_id'] . "', '" . tep_db_input($status) . "', now(), '" . tep_db_input($customer_notified) . "', '" . tep_db_input($comments) . "')");
echo "x";
}
echo "<br>Traitement terminé des relances de commandes en attente chèque et virement<br><br><br>";
// Stoppe pour 2 secondes
sleep(2);
//---------------------------------------------------------------------------------
// ANNULATION AUTOMATIQUE PAYEMENT PAR CHEQUE ET VIREMENT
//---------------------------------------------------------------------------------
echo "Démarrage des annulations de commandes en attente chèque et virement<br>";
// Test du champ orders.last_modified. Si le champs est vide, rempli avec la date de la commande
$req_last = "select orders_id, last_modified, date_purchased FROM orders WHERE orders_status = $relance_statut_cheque and last_modified is NULL";
$resultat_last = mysql_query($req_last);
while($l_last = mysql_fetch_array($resultat_last)){
tep_db_query("update orders set last_modified = date_purchased where orders_id = '" . $l_last['orders_id'] . "'");
}
// Sélection des commandes en attente paiement par rapport a la date date de commande
$req_relance = "select c.customers_id, c.customers_firstname, c.customers_lastname, c.customers_email_address, o.orders_id, o.customers_id, o.last_modified, o.date_purchased, o.orders_status from " . TABLE_CUSTOMERS . " c, " . TABLE_ORDERS . " o where o.orders_status = $relance_statut_cheque and c.customers_id = o.customers_id and TO_DAYS(NOW()) - TO_DAYS(o.date_purchased) = $annulation_nombre_cheque";
$resultat = mysql_query($req_relance);
while($l = mysql_fetch_array($resultat)){
// Mise à jour de la table orders pour ajout dans l'historique de la commande et remise en stock des produits
$customer_notified = $customer_notified_annulation;
$status = $annulation_statut;
$comments = $comments_annulation_cheque;
tep_db_query("update orders set last_modified = now() where orders_id = '" . $l['orders_id'] . "'");
tep_db_query("update orders set orders_status = '" . tep_db_input($status) . "' where orders_id = '" . $l['orders_id'] . "'");
tep_db_query("insert into orders_status_history (orders_id, orders_status_id, date_added, customer_notified, comments) values ('" . $l['orders_id'] . "', '" . tep_db_input($status) . "', now(), '" . tep_db_input($customer_notified) . "', '" . tep_db_input($comments) . "')");
$proannule_query = tep_db_query("select products_id, products_quantity from " . TABLE_ORDERS_PRODUCTS . " where orders_id = '" . $l['orders_id'] . "'");
while ($proannule = tep_db_fetch_array($proannule_query)) {
tep_db_query("update " . TABLE_PRODUCTS . " set products_quantity = products_quantity + " . $proannule['products_quantity'] . ", products_ordered = products_ordered - " . $proannule['products_quantity'] . " where products_id = '" . (int)$proannule['products_id'] . "'"); }
echo "x";
}
echo "<br>Traitement terminé des annulations de commandes en attente chèque et virement<br><br><br>";
//---------------------------------------------------------------------------------
// RELANCE AUTOMATIQUE PAYEMENT PAR PAYPAL
//---------------------------------------------------------------------------------
echo "Démarrage des relances de commandes en attente de paiement paypal<br>";
// Test du champ orders.last_modified. Si le champs est vide, rempli avec la date de la commande
$req_last = "select orders_id, last_modified, date_purchased FROM orders WHERE orders_status = $relance_statut_virement and last_modified is NULL";
$resultat_last = mysql_query($req_last);
while($l_last = mysql_fetch_array($resultat_last)){
tep_db_query("update orders set last_modified = date_purchased where orders_id = '" . $l_last['orders_id'] . "'");
}
// Sélection des commandes en attente paiement par rapport a la date date de commande
$req_relance = "select c.customers_id, c.customers_firstname, c.customers_lastname, c.customers_email_address, o.orders_id, o.customers_id, o.last_modified, o.date_purchased, o.orders_status from " . TABLE_CUSTOMERS . " c, " . TABLE_ORDERS . " o where o.orders_status = $relance_statut_virement and c.customers_id = o.customers_id and TO_DAYS(NOW()) - TO_DAYS(o.date_purchased) = $relance_nombre_virement";
$resultat = mysql_query($req_relance);
while($l = mysql_fetch_array($resultat)){
// Préparation et envoi du mail
$check_status_query = tep_db_query("select customers_name, customers_id, customers_email_address, orders_status, date_purchased from orders where orders_id = '" . $l['orders_id'] . "'");
$check_status = tep_db_fetch_array($check_status_query);
$num_com = $l['orders_id'];
$email = STORE_NAME . "\n" . EMAIL_TEXT_SEPARATEUR . "\n" . EMAIL_TEXT_ORDER_NUMBER . ' ' . $l['orders_id'] . "\n" . EMAIL_TEXT_INVOICE_URL . ' ' . tep_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $num_com, 'SSL', false) . "\n" . EMAIL_TEXT_DATE_ORDERED . ' ' . tep_date_short($l['date_purchased']) . "\n\n" . EMAIL_TEXT_COMMENTS_INTRO . "\n\n" . EMAIL_TEXT_COMMENTS_LIGNE1P . "\n\n" . EMAIL_TEXT_COMMENTS_LIGNE2P . "\n\n" . EMAIL_TEXT_COMMENTS_LIGNE3P ."\n\n" . EMAIL_TEXT_COMMENTS_LIGNE5 . "\n\n" . EMAIL_TEXT_END;
tep_mail($check_status['customers_name'], $check_status['customers_email_address'], EMAIL_TEXT_SUBJECT_P, $email, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);
// Mise à jour de la table orders pour ajout dans l'historique de la commande
$customer_notified = $customer_notified_relance;
$status = $relance_statut_virement;
$comments = $comments_relance_virement;
tep_db_query("update orders set last_modified = now() where orders_id = '" . $l['orders_id'] . "'");
tep_db_query("insert into orders_status_history (orders_id, orders_status_id, date_added, customer_notified, comments) values ('" . $l['orders_id'] . "', '" . tep_db_input($status) . "', now(), '" . tep_db_input($customer_notified) . "', '" . tep_db_input($comments) . "')");
echo "x";
}
echo "<br>Traitement terminé des relances de commandes en attente de paiement paypal<br><br><br>";
// Stoppe pour 2 secondes
sleep(2);
//---------------------------------------------------------------------------------
// ANNULATION AUTOMATIQUE PAYEMENT PAR PAYPAL
//---------------------------------------------------------------------------------
echo "Démarrage des annulations de commandes en attente de paiement paypal<br>";
// Test du champ orders.last_modified. Si le champs est vide, rempli avec la date de la commande
$req_last = "select orders_id, last_modified, date_purchased FROM orders WHERE orders_status = $relance_statut_virement and last_modified is NULL";
$resultat_last = mysql_query($req_last);
while($l_last = mysql_fetch_array($resultat_last)){
tep_db_query("update orders set last_modified = date_purchased where orders_id = '" . $l_last['orders_id'] . "'");
}
// Sélection des commandes en attente paiement par rapport a la date date de commande
$req_relance = "select c.customers_id, c.customers_firstname, c.customers_lastname, c.customers_email_address, o.orders_id, o.customers_id, o.last_modified, o.date_purchased, o.orders_status from " . TABLE_CUSTOMERS . " c, " . TABLE_ORDERS . " o where o.orders_status = $relance_statut_virement and c.customers_id = o.customers_id and TO_DAYS(NOW()) - TO_DAYS(o.date_purchased) = $annulation_nombre_virement";
$resultat = mysql_query($req_relance);
while($l = mysql_fetch_array($resultat)){
// Mise à jour de la table orders pour ajout dans l'historique de la commande et remise en stock des produits
$customer_notified = $customer_notified_annulation;
$status = $annulation_statut;
$comments = $comments_annulation_virement;
tep_db_query("update orders set last_modified = now() where orders_id = '" . $l['orders_id'] . "'");
tep_db_query("update orders set orders_status = '" . tep_db_input($status) . "' where orders_id = '" . $l['orders_id'] . "'");
tep_db_query("insert into orders_status_history (orders_id, orders_status_id, date_added, customer_notified, comments) values ('" . $l['orders_id'] . "', '" . tep_db_input($status) . "', now(), '" . tep_db_input($customer_notified) . "', '" . tep_db_input($comments) . "')");
$proannule_query = tep_db_query("select products_id, products_quantity from " . TABLE_ORDERS_PRODUCTS . " where orders_id = '" . $l['orders_id'] . "'");
while ($proannule = tep_db_fetch_array($proannule_query)) {
tep_db_query("update " . TABLE_PRODUCTS . " set products_quantity = products_quantity + " . $proannule['products_quantity'] . ", products_ordered = products_ordered - " . $proannule['products_quantity'] . " where products_id = '" . (int)$proannule['products_id'] . "'"); }
echo "x";
}
echo "<br>Traitement terminé des annulations de commandes en attente de paiement paypal<br><br><br>";
?>
This file is great but I also install the contrib Bundle 1.5.1 because I have some product which contain other product.
But now I have a problem with the automatic file which cancel and restock orders which have not been paid.
Here is a function in Bundle 1.5.1 (admin/functions/general.php) which restock bundle products when an order is deleted. I'm sure it can be adapted in the automatic file. Here is the function :
function tep_remove_order($order_id, $restock = false) {
if ($restock == 'on') {
$order_query = tep_db_query("select products_id, products_quantity from " . TABLE_ORDERS_PRODUCTS . " where orders_id = '" . (int)$order_id . "'");
while ($order = tep_db_fetch_array($order_query)) {
$is_bundle = 'no';
$product_bundle_query = tep_db_query("select subproduct_id, subproduct_qty from " . TABLE_PRODUCTS_BUNDLES . ", " . TABLE_PRODUCTS . " where bundle_id = '" . (int)$order['products_id'] . "' and products_id = '" . (int)$order['products_id'] . "' and products_bundle = 'yes'");
while ($product_bundle_data = tep_db_fetch_array($product_bundle_query)) {
$is_bundle = 'yes';
tep_db_query("update " . TABLE_PRODUCTS . " set products_quantity = products_quantity + " . $product_bundle_data['subproduct_qty']*$order['products_quantity'] . ", products_ordered = products_ordered - " . $product_bundle_data['subproduct_qty']*$order['products_quantity'] . " where products_id = '" . (int)$product_bundle_data['subproduct_id'] . "'");
}
if ($is_bundle == 'no') {
tep_db_query("update " . TABLE_PRODUCTS . " set products_quantity = products_quantity + " . $order['products_quantity'] . ", products_ordered = products_ordered - " . $order['products_quantity'] . " where products_id = '" . (int)$order['products_id'] . "'");
}
}
}
tep_db_query("delete from " . TABLE_ORDERS . " where orders_id = '" . (int)$order_id . "'");
tep_db_query("delete from " . TABLE_ORDERS_PRODUCTS . " where orders_id = '" . (int)$order_id . "'");
tep_db_query("delete from " . TABLE_ORDERS_PRODUCTS_ATTRIBUTES . " where orders_id = '" . (int)$order_id . "'");
tep_db_query("delete from " . TABLE_ORDERS_STATUS_HISTORY . " where orders_id = '" . (int)$order_id . "'");
tep_db_query("delete from " . TABLE_ORDERS_TOTAL . " where orders_id = '" . (int)$order_id . "'");
}
So I try to do this in my automatic file
<?php
/*
Contribution based on:
osCommerce, Open Source E-Commerce Solutions
http://www.oscommerce.com
*******************************************************************************
* Relance et annulation automatique de commandes clients v1.4 *
*******************************************************************************
* Ce script est à lancer tous les jours, manuellement ou à l'aide d'une tache *
* cron (bien plus pratique) *
* L'exécution de ce script permet de : *
* - Relancer les clients n'ayant pas encore payés leur commande après x jours *
* par rapport à la date de leur achat en leur envoyant un rappel par email *
* dont le contenu est personnalisable *
* - Annuler les commandes non réglées de plus de x jours par rapport à la *
* date d'achat *
* - Gérer 2 statuts de commande différents : "en attente virement" et "en *
* attente chèque" *
* - Remettre en stock les produits des commandes annulées *
*******************************************************************************
* v1.0 : par MarcelPiano le 27 janvier 2008 *
* Relance automatique tous les x jours des clients ayant une commande en *
* attente de paiement *
*******************************************************************************
* v1.1 : par Regne le 11 février 2008 *
* Modif pour correction du lien commande dans le mail de relance *
*******************************************************************************
* v1.2 : par Zardhoz le 14 février 2008 *
* Modif du code pour : *
* - Gérer 2 statuts de commande différents : "en attente virement" et "en *
* attente chèque" *
* - Annuler automatiquement les commandes passé x jours sans règlement à *
* partir de la date de commande. *
*******************************************************************************
* v1.3 par Ptitvasy le 22 février 2008 *
* Modif du code pour : *
* - Remettre en stock les produits des commandes annulées *
*******************************************************************************
* v1.4 par Zardhoz le 26 février 2008 *
* Modif du code pour : *
* - Ajout de commentaires *
* - Regroupement des paramètres modifiables pour une utilisation plus aisée *
*******************************************************************************
*/
include('includes/application_top.php');
//---------------------------------------------------------------------------------
// DEFINITION DU CONTENU DU MAIL DE RELANCE :
// A MODIFIER EN FONCTION DE VOS BESOINS
//---------------------------------------------------------------------------------
define('EMAIL_TEXT_SEPARATEUR', '------------------------------------------------------');
define('EMAIL_TEXT_SUBJECT', 'Votre commande est en attente');
define('EMAIL_TEXT_SUBJECT_P', 'Votre commande a été annulée');
define('EMAIL_TEXT_ORDER_NUMBER', 'Commande numéro :');
define('EMAIL_TEXT_INVOICE_URL', 'Facture détaillée :');
define('EMAIL_TEXT_DATE_ORDERED', 'Date de la commande :');
define('EMAIL_TEXT_COMMENTS_INTRO', 'Bonjour et merci d\'avoir choisi Bluecars.');
define('EMAIL_TEXT_COMMENTS_LIGNE1', 'Vous avez passé une commande il y a quelques jours et, sauf erreur de notre part, nous n\'avons toujours pas reçu votre réglement.');
define('EMAIL_TEXT_COMMENTS_LIGNE1P', 'Vous avez passé une commande il y a quelques jours et, sauf erreur de notre part, il semble que votre paiement par carte bleue n\'ait pas fonctionné.');
define('EMAIL_TEXT_COMMENTS_LIGNE2', 'Si vous venez d\'envoyer celui-ci, ou l\'avez envoyé depuis moins de 2 jours, ignorez ce mail.');
define('EMAIL_TEXT_COMMENTS_LIGNE2P', 'Votre commande a été automatiquement annulée, et nous vous invitons donc à réaliser une nouvelle commande.');
define('EMAIL_TEXT_COMMENTS_LIGNE3', 'Si vous souhaitez annuler votre commande, merci de nous en faire part en répondant à ce mail.');
define('EMAIL_TEXT_COMMENTS_LIGNE3P', 'Si vous avez deja effectué une nouvelle commande, ignorez ce mail.');
define('EMAIL_TEXT_COMMENTS_LIGNE4', 'Votre commande ne pourra être expédiée qu\'à réception de votre paiement, et à défaut de ce dernier, sera automatiquement annulée passé un délais de 14 jours à compter la date de commande.');
define('EMAIL_TEXT_COMMENTS_LIGNE5', 'Bluecars vous remercie de votre compréhension et de votre confiance.');
define('EMAIL_TEXT_END', 'A bientôt sur www.bluecars.net');
//---------------------------------------------------------------------------------
// PARAMETRES COMMUNS :
// A MODIFIER EN FONCTION DE VOS BESOINS ET DES PARAMETRES DE VOTRE BOUTIQUE
//---------------------------------------------------------------------------------
// Numéro du statut de commande annulée
$annulation_statut = '7';
// Notification client par mail lors de la relance : 0=non / 1=oui
$customer_notified_relance = '1';
// Notification client par mail lors de l'annulation de la commande : 0=non / 1=oui
$customer_notified_annulation = '0';
//---------------------------------------------------------------------------------
// PAYEMENT PAR CHEQUE et VIREMENT :
// A MODIFIER EN FONCTION DE VOS BESOINS ET DES PARAMETRES DE VOTRE BOUTIQUE
//---------------------------------------------------------------------------------
// Numéro du statut de commande en attente chèque et virement
$relance_statut_cheque = '1';
// Nombre de jours depuis commande avant relance automatique du client
$relance_nombre_cheque = '7';
// Nombre de jours depuis commande avant annulation de commande
$annulation_nombre_cheque = '14';
// Commentaire relance par mail
$comments_relance_cheque = 'Relance par mail ce jour';
// Commentaire annulation commande
$comments_annulation_cheque = 'Commande annulée';
//---------------------------------------------------------------------------------
// PAYEMENT PAR PAYPAL :
// A MODIFIER EN FONCTION DE VOS BESOINS ET DES PARAMETRES DE VOTRE BOUTIQUE
//---------------------------------------------------------------------------------
// Numéro du statut de commande verification paypal
$relance_statut_virement = '4';
// Nombre de jours depuis commande avant relance automatique du client
$relance_nombre_virement = '1';
// Nombre de jours depuis commande avant annulation de commande
$annulation_nombre_virement = '1';
// Commentaire relance par mail
$comments_relance_virement = 'Mail envoyé ce jour';
// Commentaire annulation commande
$comments_annulation_virement = 'Commande annulée';
//---------------------------------------------------------------------------------
// RELANCE AUTOMATIQUE PAYEMENT PAR CHEQUE ET VIREMENT
//---------------------------------------------------------------------------------
echo "Démarrage des relances de commandes en attente chèque et virement<br>";
// Test du champ orders.last_modified. Si le champs est vide, rempli avec la date de la commande
$req_last = "select orders_id, last_modified, date_purchased FROM orders WHERE orders_status = $relance_statut_cheque and last_modified is NULL";
$resultat_last = mysql_query($req_last);
while($l_last = mysql_fetch_array($resultat_last)){
tep_db_query("update orders set last_modified = date_purchased where orders_id = '" . $l_last['orders_id'] . "'");
}
// Sélection des commandes en attente paiement par rapport a la date date de commande
$req_relance = "select c.customers_id, c.customers_firstname, c.customers_lastname, c.customers_email_address, o.orders_id, o.customers_id, o.last_modified, o.date_purchased, o.orders_status from " . TABLE_CUSTOMERS . " c, " . TABLE_ORDERS . " o where o.orders_status = $relance_statut_cheque and c.customers_id = o.customers_id and TO_DAYS(NOW()) - TO_DAYS(o.date_purchased) = $relance_nombre_cheque";
$resultat = mysql_query($req_relance);
while($l = mysql_fetch_array($resultat)){
// Préparation et envoi du mail
$check_status_query = tep_db_query("select customers_name, customers_id, customers_email_address, orders_status, date_purchased from orders where orders_id = '" . $l['orders_id'] . "'");
$check_status = tep_db_fetch_array($check_status_query);
$num_com = $l['orders_id'];
$email = STORE_NAME . "\n" . EMAIL_TEXT_SEPARATEUR . "\n" . EMAIL_TEXT_ORDER_NUMBER . ' ' . $l['orders_id'] . "\n" . EMAIL_TEXT_INVOICE_URL . ' ' . tep_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $num_com, 'SSL', false) . "\n" . EMAIL_TEXT_DATE_ORDERED . ' ' . tep_date_short($l['date_purchased']) . "\n\n" . EMAIL_TEXT_COMMENTS_INTRO . "\n\n" . EMAIL_TEXT_COMMENTS_LIGNE1 . "\n\n" . EMAIL_TEXT_COMMENTS_LIGNE2 ."\n\n" . EMAIL_TEXT_COMMENTS_LIGNE3 . "\n\n" . EMAIL_TEXT_COMMENTS_LIGNE4 . "\n\n" . EMAIL_TEXT_COMMENTS_LIGNE5 . "\n\n" . EMAIL_TEXT_END;
tep_mail($check_status['customers_name'], $check_status['customers_email_address'], EMAIL_TEXT_SUBJECT, $email, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);
// Mise à jour de la table orders pour ajout dans l'historique de la commande
$customer_notified = $customer_notified_relance;
$status = $relance_statut_cheque;
$comments = $comments_relance_cheque;
tep_db_query("update orders set last_modified = now() where orders_id = '" . $l['orders_id'] . "'");
tep_db_query("insert into orders_status_history (orders_id, orders_status_id, date_added, customer_notified, comments) values ('" . $l['orders_id'] . "', '" . tep_db_input($status) . "', now(), '" . tep_db_input($customer_notified) . "', '" . tep_db_input($comments) . "')");
echo "x";
}
echo "<br>Traitement terminé des relances de commandes en attente chèque et virement<br><br><br>";
// Stoppe pour 2 secondes
sleep(2);
//---------------------------------------------------------------------------------
// ANNULATION AUTOMATIQUE PAYEMENT PAR CHEQUE ET VIREMENT
//---------------------------------------------------------------------------------
echo "Démarrage des annulations de commandes en attente chèque et virement<br>";
// Test du champ orders.last_modified. Si le champs est vide, rempli avec la date de la commande
$req_last = "select orders_id, last_modified, date_purchased FROM orders WHERE orders_status = $relance_statut_cheque and last_modified is NULL";
$resultat_last = mysql_query($req_last);
while($l_last = mysql_fetch_array($resultat_last)){
tep_db_query("update orders set last_modified = date_purchased where orders_id = '" . $l_last['orders_id'] . "'");
}
// Sélection des commandes en attente paiement par rapport a la date date de commande
$req_relance = "select c.customers_id, c.customers_firstname, c.customers_lastname, c.customers_email_address, o.orders_id, o.customers_id, o.last_modified, o.date_purchased, o.orders_status from " . TABLE_CUSTOMERS . " c, " . TABLE_ORDERS . " o where o.orders_status = $relance_statut_cheque and c.customers_id = o.customers_id and TO_DAYS(NOW()) - TO_DAYS(o.date_purchased) = $annulation_nombre_cheque";
$resultat = mysql_query($req_relance);
while($l = mysql_fetch_array($resultat)){
// Mise à jour de la table orders pour ajout dans l'historique de la commande et remise en stock des produits
$customer_notified = $customer_notified_annulation;
$status = $annulation_statut;
$comments = $comments_annulation_cheque;
tep_db_query("update orders set last_modified = now() where orders_id = '" . $l['orders_id'] . "'");
tep_db_query("update orders set orders_status = '" . tep_db_input($status) . "' where orders_id = '" . $l['orders_id'] . "'");
tep_db_query("insert into orders_status_history (orders_id, orders_status_id, date_added, customer_notified, comments) values ('" . $l['orders_id'] . "', '" . tep_db_input($status) . "', now(), '" . tep_db_input($customer_notified) . "', '" . tep_db_input($comments) . "')");
//Code que j'ai rajouté
$order_query = tep_db_query("select products_id, products_quantity from " . TABLE_ORDERS_PRODUCTS . " where orders_id = '" . (int)$order_id . "'");
while ($order = tep_db_fetch_array($order_query)) {
$is_bundle = 'no';
$product_bundle_query = tep_db_query("select subproduct_id, subproduct_qty from " . TABLE_PRODUCTS_BUNDLES . ", " . TABLE_PRODUCTS . " where bundle_id = '" . (int)$order['products_id'] . "' and products_id = '" . (int)$order['products_id'] . "' and products_bundle = 'yes'");
while ($product_bundle_data = tep_db_fetch_array($product_bundle_query)) {
$is_bundle = 'yes';
tep_db_query("update " . TABLE_PRODUCTS . " set products_quantity = products_quantity + " . $product_bundle_data['subproduct_qty']*$order['products_quantity'] . ", products_ordered = products_ordered - " . $product_bundle_data['subproduct_qty']*$order['products_quantity'] . " where products_id = '" . (int)$product_bundle_data['subproduct_id'] . "'");
}
if ($is_bundle == 'no') {
tep_db_query("update " . TABLE_PRODUCTS . " set products_quantity = products_quantity + " . $order['products_quantity'] . ", products_ordered = products_ordered - " . $order['products_quantity'] . " where products_id = '" . (int)$order['products_id'] . "'");
}
}
echo "x";
}
echo "<br>Traitement terminé des annulations de commandes en attente chèque et virement<br><br><br>";
//---------------------------------------------------------------------------------
// RELANCE AUTOMATIQUE PAYEMENT PAR PAYPAL
//---------------------------------------------------------------------------------
echo "Démarrage des relances de commandes en attente de paiement paypal<br>";
// Test du champ orders.last_modified. Si le champs est vide, rempli avec la date de la commande
$req_last = "select orders_id, last_modified, date_purchased FROM orders WHERE orders_status = $relance_statut_virement and last_modified is NULL";
$resultat_last = mysql_query($req_last);
while($l_last = mysql_fetch_array($resultat_last)){
tep_db_query("update orders set last_modified = date_purchased where orders_id = '" . $l_last['orders_id'] . "'");
}
// Sélection des commandes en attente paiement par rapport a la date date de commande
$req_relance = "select c.customers_id, c.customers_firstname, c.customers_lastname, c.customers_email_address, o.orders_id, o.customers_id, o.last_modified, o.date_purchased, o.orders_status from " . TABLE_CUSTOMERS . " c, " . TABLE_ORDERS . " o where o.orders_status = $relance_statut_virement and c.customers_id = o.customers_id and TO_DAYS(NOW()) - TO_DAYS(o.date_purchased) = $relance_nombre_virement";
$resultat = mysql_query($req_relance);
while($l = mysql_fetch_array($resultat)){
// Préparation et envoi du mail
$check_status_query = tep_db_query("select customers_name, customers_id, customers_email_address, orders_status, date_purchased from orders where orders_id = '" . $l['orders_id'] . "'");
$check_status = tep_db_fetch_array($check_status_query);
$num_com = $l['orders_id'];
$email = STORE_NAME . "\n" . EMAIL_TEXT_SEPARATEUR . "\n" . EMAIL_TEXT_ORDER_NUMBER . ' ' . $l['orders_id'] . "\n" . EMAIL_TEXT_INVOICE_URL . ' ' . tep_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $num_com, 'SSL', false) . "\n" . EMAIL_TEXT_DATE_ORDERED . ' ' . tep_date_short($l['date_purchased']) . "\n\n" . EMAIL_TEXT_COMMENTS_INTRO . "\n\n" . EMAIL_TEXT_COMMENTS_LIGNE1P . "\n\n" . EMAIL_TEXT_COMMENTS_LIGNE2P . "\n\n" . EMAIL_TEXT_COMMENTS_LIGNE3P ."\n\n" . EMAIL_TEXT_COMMENTS_LIGNE5 . "\n\n" . EMAIL_TEXT_END;
tep_mail($check_status['customers_name'], $check_status['customers_email_address'], EMAIL_TEXT_SUBJECT_P, $email, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);
// Mise à jour de la table orders pour ajout dans l'historique de la commande
$customer_notified = $customer_notified_relance;
$status = $relance_statut_virement;
$comments = $comments_relance_virement;
tep_db_query("update orders set last_modified = now() where orders_id = '" . $l['orders_id'] . "'");
tep_db_query("insert into orders_status_history (orders_id, orders_status_id, date_added, customer_notified, comments) values ('" . $l['orders_id'] . "', '" . tep_db_input($status) . "', now(), '" . tep_db_input($customer_notified) . "', '" . tep_db_input($comments) . "')");
echo "x";
}
echo "<br>Traitement terminé des relances de commandes en attente de paiement paypal<br><br><br>";
// Stoppe pour 2 secondes
sleep(2);
//---------------------------------------------------------------------------------
// ANNULATION AUTOMATIQUE PAYEMENT PAR PAYPAL
//---------------------------------------------------------------------------------
echo "Démarrage des annulations de commandes en attente de paiement paypal<br>";
// Test du champ orders.last_modified. Si le champs est vide, rempli avec la date de la commande
$req_last = "select orders_id, last_modified, date_purchased FROM orders WHERE orders_status = $relance_statut_virement and last_modified is NULL";
$resultat_last = mysql_query($req_last);
while($l_last = mysql_fetch_array($resultat_last)){
tep_db_query("update orders set last_modified = date_purchased where orders_id = '" . $l_last['orders_id'] . "'");
}
// Sélection des commandes en attente paiement par rapport a la date date de commande
$req_relance = "select c.customers_id, c.customers_firstname, c.customers_lastname, c.customers_email_address, o.orders_id, o.customers_id, o.last_modified, o.date_purchased, o.orders_status from " . TABLE_CUSTOMERS . " c, " . TABLE_ORDERS . " o where o.orders_status = $relance_statut_virement and c.customers_id = o.customers_id and TO_DAYS(NOW()) - TO_DAYS(o.date_purchased) = $annulation_nombre_virement";
$resultat = mysql_query($req_relance);
while($l = mysql_fetch_array($resultat)){
// Mise à jour de la table orders pour ajout dans l'historique de la commande et remise en stock des produits
$customer_notified = $customer_notified_annulation;
$status = $annulation_statut;
$comments = $comments_annulation_virement;
tep_db_query("update orders set last_modified = now() where orders_id = '" . $l['orders_id'] . "'");
tep_db_query("update orders set orders_status = '" . tep_db_input($status) . "' where orders_id = '" . $l['orders_id'] . "'");
tep_db_query("insert into orders_status_history (orders_id, orders_status_id, date_added, customer_notified, comments) values ('" . $l['orders_id'] . "', '" . tep_db_input($status) . "', now(), '" . tep_db_input($customer_notified) . "', '" . tep_db_input($comments) . "')");
//Code que j'ai rajouté
$order_query = tep_db_query("select products_id, products_quantity from " . TABLE_ORDERS_PRODUCTS . " where orders_id = '" . (int)$order_id . "'");
while ($order = tep_db_fetch_array($order_query)) {
$is_bundle = 'no';
$product_bundle_query = tep_db_query("select subproduct_id, subproduct_qty from " . TABLE_PRODUCTS_BUNDLES . ", " . TABLE_PRODUCTS . " where bundle_id = '" . (int)$order['products_id'] . "' and products_id = '" . (int)$order['products_id'] . "' and products_bundle = 'yes'");
while ($product_bundle_data = tep_db_fetch_array($product_bundle_query)) {
$is_bundle = 'yes';
tep_db_query("update " . TABLE_PRODUCTS . " set products_quantity = products_quantity + " . $product_bundle_data['subproduct_qty']*$order['products_quantity'] . ", products_ordered = products_ordered - " . $product_bundle_data['subproduct_qty']*$order['products_quantity'] . " where products_id = '" . (int)$product_bundle_data['subproduct_id'] . "'");
}
if ($is_bundle == 'no') {
tep_db_query("update " . TABLE_PRODUCTS . " set products_quantity = products_quantity + " . $order['products_quantity'] . ", products_ordered = products_ordered - " . $order['products_quantity'] . " where products_id = '" . (int)$order['products_id'] . "'");
}
}
echo "x";
}
echo "<br>Traitement terminé des annulations de commandes en attente de paiement paypal<br><br><br>";
?>
But it doesn't work. I have no error but bundle product are not restocked.
Can someone help me to do this code working fine?
Thanks a lot
Edited by royal38, 10 July 2008 - 10:38 PM.
#297
Posted 13 July 2008 - 11:38 PM
I've a problem with paypal ipn. I try to include this code in my paypal_ipn.php but I can't find this code which must be replaced! :
for ($i=0, $n=sizeof($order->products); $i<$n; $i++) {
// Stock Update - Joao Correia
if (STOCK_LIMITED == 'true') {
if (DOWNLOAD_ENABLED == 'true') {
$stock_query_raw = "SELECT products_quantity, pad.products_attributes_filename
FROM " . TABLE_PRODUCTS . " p
LEFT JOIN " . TABLE_PRODUCTS_ATTRIBUTES . " pa
ON p.products_id=pa.products_id
LEFT JOIN " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad
ON pa.products_attributes_id=pad.products_attributes_id
WHERE p.products_id = '" . tep_get_prid($order->products[$i]['id']) . "'";
// Will work with only one option for downloadable products
// otherwise, we have to build the query dynamically with a loop
$products_attributes = $order->products[$i]['attributes'];
if (is_array($products_attributes)) {
$stock_query_raw .= " AND pa.options_id = '" . $products_attributes[0]['option_id'] . "' AND pa.options_values_id = '" . $products_attributes[0]['value_id'] . "'";
}
$stock_query = tep_db_query($stock_query_raw);
} else {
$stock_query = tep_db_query("select products_quantity from " . TABLE_PRODUCTS . " where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
}
if (tep_db_num_rows($stock_query) > 0) {
$stock_values = tep_db_fetch_array($stock_query);
// do not decrement quantities if products_attributes_filename exists
if ((DOWNLOAD_ENABLED != 'true') || (!$stock_values['products_attributes_filename'])) {
$stock_left = $stock_values['products_quantity'] - $order->products[$i]['qty'];
} else {
$stock_left = $stock_values['products_quantity'];
}
tep_db_query("update " . TABLE_PRODUCTS . " set products_quantity = '" . $stock_left . "' where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
if ( ($stock_left < 1) && (STOCK_ALLOW_CHECKOUT == 'false') ) {
tep_db_query("update " . TABLE_PRODUCTS . " set products_status = '0' where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
}
}
}
Does someone have the same problem.
Thanks a lot
#298
Posted 14 August 2008 - 11:47 AM
I've just installed the contribution and i have variouse prblems:
first when editting a product and wanting to add bundled products:
1. the fields dont have headings hence im unsure what the numbers next to the name mean?
2. when clicking to preview before updating i dont see any of the bundled products. it does however seem to save the info when i click to update.
second when logging in on the clients side and adding the bundle product to the cart:
1. when viewing Cart Content i get the following SQL error: 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '{6}14 and language_id = '1'' at line 7
SELECT pd.products_name, pb.*, p.products_bundle, p.products_id, p.products_price, p.products_image FROM products p INNER JOIN products_description pd ON p.products_id=pd.products_id INNER JOIN products_bundles pb ON pb.subproduct_id=pd.products_id WHERE pb.bundle_id = 34{6}14 and language_id = '1'
for some reason the products_id comes trough as 34{6}14 and that causes the error. but i have no idea why it is like that.
2. nowhere can i see any sort've breakdown of the bundle?
Please help,
Tal.
Edited by talo, 14 August 2008 - 11:48 AM.
#299
Posted 12 September 2008 - 09:13 PM
the only problem is that the bundled product is being updated rather then the subproducts.
It dose however restock correctly (restocking the items and not the bundle) if I delete the order (when using the restock items option)
I am using a paypal mod but it seems to be different from the "paypal IPN" so I haven't changed it here is what my paypal mod looks like :
<?php
/*
$Id: paypal.php,v 1.39 2003/01/29 19:57:15 hpdl Exp $
osCommerce, Open Source E-Commerce Solutions
[url="http://www.oscommerce.com"]http://www.oscommerce.com[/url]
Copyright © 2003 osCommerce
Released under the GNU General Public License
*/
class paypal {
var $code, $title, $description, $enabled;
// class constructor
function paypal() {
global $order;
$this->code = 'paypal';
$this->title = MODULE_PAYMENT_PAYPAL_TEXT_TITLE;
$this->description = MODULE_PAYMENT_PAYPAL_TEXT_DESCRIPTION;
$this->sort_order = MODULE_PAYMENT_PAYPAL_SORT_ORDER;
$this->enabled = ((MODULE_PAYMENT_PAYPAL_STATUS == 'True') ? true : false);
if ((int)MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID > 0) {
$this->order_status = MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID;
}
if (is_object($order)) $this->update_status();
$this->form_action_url = 'https://secure.paypal.com/cgi-bin/webscr';
}
// class methods
function update_status() {
global $order;
if ( ($this->enabled == true) && ((int)MODULE_PAYMENT_PAYPAL_ZONE > 0) ) {
$check_flag = false;
$check_query = tep_db_query("select zone_id from " . TABLE_ZONES_TO_GEO_ZONES . " where geo_zone_id = '" . MODULE_PAYMENT_PAYPAL_ZONE . "' and zone_country_id = '" . $order->billing['country']['id'] . "' order by zone_id");
while ($check = tep_db_fetch_array($check_query)) {
if ($check['zone_id'] < 1) {
$check_flag = true;
break;
} elseif ($check['zone_id'] == $order->billing['zone_id']) {
$check_flag = true;
break;
}
}
if ($check_flag == false) {
$this->enabled = false;
}
}
}
function javascript_validation() {
return false;
}
function selection() {
return array('id' => $this->code,
'module' => $this->title);
}
function pre_confirmation_check() {
return false;
}
function confirmation() {
return false;
}
function process_button() {
global $order, $currencies, $currency;
if (MODULE_PAYMENT_PAYPAL_CURRENCY == 'Selected Currency') {
$my_currency = $currency;
} else {
$my_currency = substr(MODULE_PAYMENT_PAYPAL_CURRENCY, 5);
}
if (!in_array($my_currency, array('CAD', 'EUR', 'GBP', 'JPY', 'USD'))) {
$my_currency = 'SEK';
}
$process_button_string = tep_draw_hidden_field('cmd', '_xclick') .
tep_draw_hidden_field('business', MODULE_PAYMENT_PAYPAL_ID) .
tep_draw_hidden_field('item_name', STORE_NAME) .
tep_draw_hidden_field('amount', number_format(($order->info['total'] - $order->info['shipping_cost']) * $currencies->get_value($my_currency), $currencies->get_decimal_places($my_currency))) .
tep_draw_hidden_field('shipping', number_format($order->info['shipping_cost'] * $currencies->get_value($my_currency), $currencies->get_decimal_places($my_currency))) .
tep_draw_hidden_field('currency_code', $my_currency) .
tep_draw_hidden_field('return', tep_href_link(FILENAME_CHECKOUT_PROCESS, '', 'SSL')) .
tep_draw_hidden_field('cancel_return', tep_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL'));
return $process_button_string;
}
function before_process() {
return false;
}
function after_process() {
return false;
}
function output_error() {
return false;
}
function check() {
if (!isset($this->_check)) {
$check_query = tep_db_query("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'MODULE_PAYMENT_PAYPAL_STATUS'");
$this->_check = tep_db_num_rows($check_query);
}
return $this->_check;
}
function install() {
tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable PayPal Module', 'MODULE_PAYMENT_PAYPAL_STATUS', 'True', 'Do you want to accept PayPal payments?', '6', '3', 'tep_cfg_select_option(array(\'True\', \'False\'), ', now())");
tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('E-Mail Address', 'MODULE_PAYMENT_PAYPAL_ID', 'you@yourbusiness.com', 'The e-mail address to use for the PayPal service', '6', '4', now())");
tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Transaction Currency', 'MODULE_PAYMENT_PAYPAL_CURRENCY', 'Selected Currency', 'The currency to use for credit card transactions', '6', '6', 'tep_cfg_select_option(array(\'Selected Currency\',\'Only USD\',\'Only CAD\',\'Only EUR\',\'Only GBP\',\'Only JPY\',\'Only SEK\'), ', now())");
tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Sort order of display.', 'MODULE_PAYMENT_PAYPAL_SORT_ORDER', '0', 'Sort order of display. Lowest is displayed first.', '6', '0', now())");
tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, use_function, set_function, date_added) values ('Payment Zone', 'MODULE_PAYMENT_PAYPAL_ZONE', '0', 'If a zone is selected, only enable this payment method for that zone.', '6', '2', 'tep_get_zone_class_title', 'tep_cfg_pull_down_zone_classes(', now())");
tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('Set Order Status', 'MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID', '0', 'Set the status of orders made with this payment module to this value', '6', '0', 'tep_cfg_pull_down_order_statuses(', 'tep_get_order_status_name', now())");
}
function remove() {
tep_db_query("delete from " . TABLE_CONFIGURATION . " where configuration_key in ('" . implode("', '", $this->keys()) . "')");
}
function keys() {
return array('MODULE_PAYMENT_PAYPAL_STATUS', 'MODULE_PAYMENT_PAYPAL_ID', 'MODULE_PAYMENT_PAYPAL_CURRENCY', 'MODULE_PAYMENT_PAYPAL_ZONE', 'MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID', 'MODULE_PAYMENT_PAYPAL_SORT_ORDER');
}
}
?>
If somebody could look this over and let me know if it needs to be changed that would be great!
the reason I have this paypal solution is because it works together with a paypal fee added for the customer in the order total.
thanks
#300
Posted 28 September 2008 - 11:10 PM
Please look at www.serendipityme.co.uk this is my test site.
The test item in teh candles section has the bundles added, all works fine, but as you can see, the prices and quantities are not functioning correctly..
Any Ideas?
Thanks
KF









