-
Acesta nu este un tutorial despre cum se seteaza o regula de tip Shopping Cart Price Rule in Magento, dar despre cum se implementeaza una noua.
Un tip nou de regula in Magento presupune doua lucuri:
– modificarea admin-ului pt a adauga noua regula folosind un observer pentru adminhtml_block_salesrule_actions_prepareform,
– un mod de aplicare pentru noua regula folosind un observer pentru salesrule_validator_process.Sa luam un exemplu. Sa zicem ca exista o regula de tip Shopping Cart Price Rule care ofera discount diferit in functie de numarul de produse din cos. Se va calcula o valoare de incrementare pentru fiecare pas ($step). Primul produs nu va primi nici un discount, al doilea produs va primi un discount de $step, al doilea produs un discount de 2*$step, pana se ajunge la valoarea maxima de discount. Urmatoarele produse vor avea discount maxim. Ex:
Discount Amount = 50
Discount Qty = 5
Step = Discount Amount / Discount Qty = 10Discountul rezultat:
– 0% prod 1
– 10% prod 2
…
– 50% prod 6
– 50% prod 7Primul pas este activarea modulului cu fisierul: app/etc/modules/CP_ProductNrDiscount.xml
1<?xml version="1.0" encoding="UTF-8"?> 2<config> 3 <modules> 4 <CP_ProductNrDiscount> 5 <active>true</active> 6 <codePool>local</codePool> 7 </CP_ProductNrDiscount> 8 </modules> 9</config>
Primul observer, adminhtml_block_salesrule_actions_prepareform, trebuie sa fie in config in zona “adminhtml”, pentru ca se va aplica admin-ul. Acest observer are acces la formularul din admin, permitand modificarea acestuia.
Al doilea observer, salesrule_validator_process, poate sa fie in zona de “frontend” sau “global” din config. Daca este in “frontend” se va aplica doar in partea de frontend, daca este in global acesta se va aplica si in backend daca este nevoie. In general global este necesar atunci cand se fac operatiuni pe cart din backend.
1<?xml version="1.0" encoding="UTF-8"?> 2<config> 3 <modules> 4 <CP_ProductNrDiscount> 5 <version>0.0.1</version> 6 </CP_ProductNrDiscount> 7 </modules> 8 <global> 9 <models> 10 <productnrdiscount> 11 <class>CP_ProductNrDiscount_Model</class> 12 </productnrdiscount> 13 </models> 14 <events> 15 <salesrule_validator_process> 16 <observers> 17 <productnrdiscount> 18 <type>model</type> 19 <class>productnrdiscount/observer</class> 20 <method>salesruleValidatorProcess</method> 21 </productnrdiscount> 22 </observers> 23 </salesrule_validator_process> 24 </events> 25 </global> 26 <adminhtml> 27 <events> 28 <adminhtml_block_salesrule_actions_prepareform> 29 <observers> 30 <productnrdiscount> 31 <type>model</type> 32 <class>productnrdiscount/observer</class> 33 <method>adminhtmlBlockSalesruleActionsPrepareform</method> 34 </productnrdiscount> 35 </observers> 36 </adminhtml_block_salesrule_actions_prepareform> 37 </events> 38 </adminhtml> 39</config>
Al doilea observer trebuie sa fie atasat la “frontend” sau “global”, daca trebuie sa ruleze doar in frontend sau si in backend.
Asa cum se poate vedea mai sus, trebuie facut un model Observer care sa aiba cele doua metode care modifica admin-ul si aplica discountul.
1<?php 2/** 3 * Number of product discount module 4 * 5 * @author Claudiu Persoiu https://blog.claudiupersoiu.ro 6 */ 7class CP_ProductNrDiscount_Model_Observer { 8 9 // Noul tip de regula 10 const PRODUCT_NR_DISCOUNT = 'product_nr_discount'; 11 12 /** 13 * Adaugare nou tip de regula in meniul de administrare 14 * 15 * @param Varien_Event_Observer $observer 16 */ 17 public function adminhtmlBlockSalesruleActionsPrepareform 18 (Varien_Event_Observer $observer) { 19 // Extragem campul din formular 20 $field = $observer->getForm()->getElement('simple_action'); 21 // Extragem valorile campului 22 $options = $field->getValues(); 23 // Adaugam noua valoare 24 $options[] = array( 25 'value' => self::PRODUCT_NR_DISCOUNT, 26 'label' => 'Product Number Discount' 27 ); 28 // Setare camp 29 $field->setValues($options); 30 } 31 32 /** 33 * Aplicare discount 34 * Discountul se va aplica la minim 2 produse progresiv cate un "step" pentru 35 * fiecare produs, unde un "step" este discountul maxim / numarul de produse 36 * pe care se aplica. 37 * 38 * @param Varien_Event_Observer $observer 39 */ 40 public function salesruleValidatorProcess(Varien_Event_Observer $observer) { 41 42 // $item typeof Mage_Sales_Model_Quote_Item 43 $item = $observer->getEvent()->getItem(); 44 // $rule typeof Mage_SalesRule_Model_Rule 45 $rule = $observer->getEvent()->getRule(); 46 47 // Numarul de produse de acest fel 48 $qty = $item->getQty(); 49 50 // Trebuie verificat ce tip de regula este, pentru a izola tipul 51 // nostu de regula 52 if($rule->getSimpleAction() == self::PRODUCT_NR_DISCOUNT && $qty > 1) { 53 54 // Detalii regula 55 $discountAmount = $rule->getDiscountAmount(); 56 $discountQty = $rule->getDiscountQty(); 57 58 // Step de discount 59 $step = $discountAmount/$discountQty; 60 61 // Calcul discount 62 $discount = 0; 63 for($i = 1; $i < $qty; $i++) { 64 $itemDiscount = $i * $step; 65 // Daca discountul este mai mare decat discountul maxim 66 // atunci se foloseste discount maxim 67 if($itemDiscount > $discountAmount) { 68 $itemDiscount = $discountAmount; 69 } 70 71 $discount += $itemDiscount; 72 } 73 74 // Discountul propriuzis 75 $totalDiscountAmount = ($item->getPrice() * $discount)/100; 76 77 // Discount in procente pentru fiecare quote item 78 $item->setDiscountPercent($discount / $qty); 79 80 // Setare discount efectiv, practic aceasta este valoarea de discount 81 $result = $observer->getResult(); 82 $result->setDiscountAmount($totalDiscountAmount); 83 $result->setBaseDiscountAmount($totalDiscountAmount); 84 85 } 86 } 87 88}
Acest observer se va aplica la fiecare request cand exista module in cart pentru care se aplica regula. Daca discountul trebuie sa se aplice doar pentru anumite produse acestea se pot filtra folosind sesiunea de “Conditions” a regulii definite, asa cum este normal.