Ticket : https://projets.decitre-corporate.com/issues/55569
Problème : Lorsqu'un ebook n'est pas commandable, il peut quand même être ajouté au panier et la commande peut être validée. Elle est annulée après validation complète, sans que le client ne soit prévenu.
Solution : Rester au plus proche de l'existant, faire un appel à une (nouvelle ?) API de vérification du panier quand le client clique sur "Commander vos articles" dans le panier.
-
Côté FC :
- L'appel actuel au webservice MyVivlio (WMV) se fait au traitement de la commande
-
Côté Magento :
- La vérification est trigger automatiquement dans un observer (
beforeOnePageControllerIndex) lié à l'accès à la page de Checkout
/** * Listen to 'controller_action_predispatch_checkout_onepage_index' event * Method used to check availability of ebooks if some are present in the cart * @param Varien_Event_Observer $observer */ public function beforeOnePageControllerIndex($observer) { /** @var Decitre_Checkout_OnepageController $onepageController */ $onepageController = $observer->getControllerAction(); /** @var Mage_Sales_Model_Quote $quote */ $quote = $onepageController->getOnepage()->getQuote(); // Loops through the quote to retrieve ebook products $ebookItems = array(); foreach ($quote->getItemsCollection() as $item) { if ($item->getProductType() == self::EBOOK_ITEM_TYPE) { $ebookItems[$item->getSku()] = $item; } } if (count($ebookItems) == 0) { return; } // Calls the web service to check ebooks availability $customer = Mage::getSingleton('customer/session')->getCustomer(); $countryCode = Mage::helper('decitreebook')->getCustomerCountryCode($customer); $soapClient = Mage::getModel('decitreebook_ws/checkBookAvailability'); $soapClient->generateRequest($countryCode, $ebookItems); $cmsContent = ''; try { $unavailableEbooks = $soapClient->getUnavailableEbookSkus(array_keys($ebookItems)); } catch (\Exception $e) { $unavailableEbooks = array_keys($ebookItems); $cmsContent = Mage::helper('decitrecms')->getCmsBlockByCode('suppression_ebook_panier'); $context = array('ebooks-ids' => $unavailableEbooks, 'customer-id' => $customer->getId(), 'message' => $e->getMessage()); Mage::log(sprintf('Ebook webservice unavailable : %s', json_encode($context)), Zend_Log::ERR, 'indisponibilite-ws-tea.log', true); } if ($unavailableEbooks === false || count($unavailableEbooks) == 0) { return; } // Some ebooks are unavailable, redirects to cart index and add warnings $unavailableEbookIds = array(); $unavailableEbookTitles = array(); foreach ($unavailableEbooks as $sku) { $unavailableEbookIds[] = $ebookItems[$sku]->getId(); $unavailableEbookTitles[] = $ebookItems[$sku]->getProduct()->getName(); $quote->removeItem($ebookItems[$sku]->getId()); } $quote->setTriggerRecollect(1) ->setTotalsCollectedFlag(true) ->save(); $checkoutSession = Mage::getSingleton('checkout/session'); if (count($unavailableEbooks) > 1) { $warningMessage = 'The following eBooks are no longer available and have been removed from your cart: %s'; } else { $warningMessage = 'The following eBook is no longer available and has been removed from your cart: %s'; } if (0 !== strlen(trim($cmsContent))) { $cmsContent .= '<br />'; } $checkoutSession->addWarning( $cmsContent . Mage::helper('decitreebook')->__($warningMessage, '<br />- '.implode('<br />- ', $unavailableEbookTitles)) ); if ($quote->getItemsCount()==0){ $redirectionUrl = Mage::getUrl('*/cart/index'); $onepageController->getResponse()->setRedirect($redirectionUrl); $onepageController->setFlag('', Mage_Core_Controller_Varien_Action::FLAG_NO_DISPATCH, true); } }
- Appel SOAP ? On passe une liste de SKUs au WMV qui répond en renvoyant une liste si dispo, sinon indispo.
- Différence SOAP/API.
- La vérification est trigger automatiquement dans un observer (
- Identifier le bouton Commander vos articles :
theme/modules/Checkout/CheckoutSideRecap/CheckoutSideRecapCheckoutButton.jsx- Remplacer la redirection par un
onClickavec la vérification. - Le front envoie la liste des SKUs présents dans le panier au WMV pour vérifier la dispo.
- Traiter la réponse du WMV.
- Remplacer la redirection par un
- Créer un nouveau point d'API côté API Platform qui reçoit les SKUs et transmets la demande à Magento.
- Un contrôleur
- Une route
- Dans un service, Magento réutilise
CheckBookAvailabilityet renvoie la liste des ebooks dispos.
- FC
- Route Api :
app/routes/api.cart.ebooks-availability.ts- Création d'une requête graphql
- Gestion de cette requête dans l'extension checkout
- Elle envoie une liste de SKUs et récupère les indispos.
Flux données : UI (client React) → POST SKUs ebooks → Api Platform → réponse (SKUs indisponibles) → mise à jour panier UI
- Api Platform
-
Controller :
src/Controller/Availability/CheckAvailability.php- Reçoit la requête POST avec la liste de SKUs envoyée par FC
- Valide et extrait les SKUs
- Appelle le service métier Symfony qui fait la liaison avec Magento
- Retourne au front la liste JSON des SKUs indispos
-
Service de liaison avec Magento :
src/Service/Mage/EbookAvailabilityChecker.php- Sert d’interface entre Api Platform et Magento.
- Prépare et transmet la requête au client Magento (wrapper).
- Traite la réponse Magento et retourne uniquement les informations utiles (ex : quels SKUs sont indisponibles).
-
Client Magento (wrapper) :
src/Magento/CheckAvailabilityClient.php- Contient la logique technique d’appel vers Magento.
- Utilise un client SOAP (par exemple) pour appeler la méthode Magento
Decitre_Ebook_Model_Ws_Service_CheckAvailability. - Traduit la réponse Magento en format compréhensible par Symfony.
-
Route exposée.
Flux données : Api Platform → EbookAvailabilityChecker → CheckAvailabilityClient → Magento SOAP → réponse → Symfony → front
- Magento
-
Client SOAP (existant) :
magento/www/app/code/local/Decitre/Ebook/Model/Ws/Client/CheckBookAvailability.php- Génère la requête SOAP (XML) avec les SKUs.
- Envoie la requête au serveur SOAP Magento (ou tiers).
- Récupère la réponse XML SOAP, la parse, et prépare les données brutes.
-
Service métier Magento :
magento/www/app/code/local/Decitre/Ebook/Model/Ws/Service/CheckAvailability.php- Interface métier Magento pour vérifier la disponibilité des ebooks.
- Utilise le client SOAP pour récupérer les infos.
- Prépare les objets Magento (quote, produits, stock) selon la disponibilité.
- Retourne les résultats à l’appelant Symfony (via SOAP).
Flux données : SOAP request → Magento SOAP server → parse → business logic → response SOAP
- Autres Configuration Symfony (services.yaml) Injection de dépendances pour que EbookAvailabilityChecker reçoive le client Magento correctement configuré.
Proxy HTTP (optionnel) Si direct Symfony→Magento est complexe, on peut intercaler un proxy HTTP pour relayer et simplifier les échanges. (??)
- Vérification des impacts (double clics, gérer le loading, erreurs)
- Cas d'usage à tester avec une BDD plus complète :
- Panier avec uniquement des ebooks dispos
- Panier avec uniquement des ebooks indispos
- Panier avec ebooks dispos et ebooks indispos
- Le panier est vide après suppréssion