PROGETTO ORDINI FORNITORI Magento attualmente è uno dei più popolari e innovativi CMS dedicati al mondo del commercio elettronico. Nato nel 2007 ad opera della società americana Varien Inc. questo software ha subito uno sviluppo e una diffusione quasi istantanea, grazie anche allo stile innovativo che lo contraddistingue. Pur essendo la piattaforma così grande e complessa In realtà Magento manca di alcune caratteristiche che è possibile integrare, partendo dalla sua strutturazione complessa, ma con una logica molto semplice e chiara. Come detto Magento non prevede la gestione degli ordini a Fornitore quando il livello di riordino dei materiali in magazzino viene raggiunto. Con questa modifica si vuole aggiungere questa ‘feature’ al cms. Nella foto sotto l’ambiente operativo di cui ha bisogno ogni feature di Magento. In Magento è possibile aggiungere nuovi attributi al product model ed editare i relativi valori nella Product page. Nel nostro caso si vuole aggiungere una estensione, più che un attributo: in particolare una custom extension che aggiungerà una nuova tab al product edit page, la tab dei ‘Fornitori’ Creare una “Magento Extension” Il primo passo è creare il file di setup della extension, l’estensione in Magento. che caricherà app/etc/modules/Fornitori_Customtabs.xml 1 2 <br /> version="1.0"?><br /> 3 <?xml <config><br /> 4 <modules><br /> 5 <Fornitori_Customtabs><br /> <active>true</active><br /> 6 <codePool>local</codePool><br /> 7 </Fornitori_Customtabs><br /> 8 </modules><br /> 9 </config><br /> 10 Questo file registrerà la extension app/code/local/Fornitori/Customtabs/ eseguire. in Magento, indicando la directory come riferimento per il codice da app/code/local/ Fornitori /Customtabs/etc/config.xml Il file successive è quello di configurazione della extension (config file). Questo file contiene le informazioni necessarie sulle extension's classes, layout files e tutto il necessario al funzionamento. 1 <br /> version="1.0"?><br /> 2 <?xml <config><br /> 3 <modules><br /> 4 <Fornitori_Customtabs><br /> <version>0.1.0</version><br /> 5 </Fornitori_Customtabs><br /> 6 </modules><br /> 7 <global><br /> 8 <blocks><br /> <customtabs><br /> 9 <class>Fornitori_Customtabs_Block</class><br /> 10 </customtabs><br /> 11 </blocks><br /> 12 <models><br /> 13 <customtabs><br /> <class>Fornitori_Customtabs_Model</class><br /> 14 </customtabs><br /> 15 </models><br /> 16 </global><br /> 17 <adminhtml><br /> 18 <layout><br /> <updates><br /> 19 <customtabs><br /> 20 <file>customtabs.xml</file><br /> 21 </customtabs><br /> 22 </updates><br /> </layout><br /> 23 </adminhtml><br /> 24 </config><br /> 25 28 29 app/design/adminhtml/default/default/layout/customtabs.xml Questo è il layout file per la ‘Adminhtml section’ della extension, necessario ad includere la tab nella product edit page di Magento. 1 2 <br /> 3 <?xml version="1.0"?><br /> /> 4 <layout><br <adminhtml_catalog_product_edit><br /> 5 <reference name="product_tabs"><br /> 6 <action method="addTab"><br /> <name>my_custom_tab</name><br /> 7 <block>customtabs/adminhtml_catalog_product_tab</block><br /> 8 </action><br /> 9 </reference><br /> 10 </adminhtml_catalog_product_edit><br /> 11</layout><br /> 12 Un file molto semplice, ma senza il quale non viene mostrato niente nella product edit page. L’ultima cosa da fare per far comparire la tab è creare un nuovo template file. app/design/adminhtml/default/default/template/customtabs/catalog /product/tab.phtml 1 2 <br /> /> 3 <?php<br /**<br /> 4 * Custom tab template<br /> 5 */<br /> 6 ?></p> 7 <div class="input-field"> <label for="custom_field">Custom Field</label><br /> 8 <input type="text" class="input-text" name="custom_field" id="custom_field" /> 9 </div> 10 A questo punto la estensione è configurata per eseguire il codice del block adminhtml_catalog_product_tab, quindi qui piazzeremo le routines che operareranno la gestione dei Fornitori, a seguire il file index.php nella directory DelivOrders\Block. Questo file proietta la situazione degli ordini ai fornitori in corso, con il loro stato di avanzamento (compilati, spediti, in attesa). Vengono poi estratte le righe d’ordine e visualizzati i materiali ordinati divisi per fornitore. A questo punto c’è la possibilità di aggiornare la situazione del codice articolo (materiale ordine consegnato, annulla materiale ordine consegnato). <?php class Fornitori_DelivOrders_Block_Index extends Mage_Core_Block_Template { protected function _toHtml() { $start=microtime(); $time_start = $this->microtime_float(); echo "<br><b>SITUAZIONE ORDINI FORNITORI 'in DELIVERING' (ORDINAMENTO PER FORNITORE)</b>"; echo "<br></b>"; echo "<br>ORDINI COMPILATI E SPEDITI</b>"; echo "<br></b>"; include ("connectMag.php"); //SQL $sql_man = "SELECT * FROM manufacturer"; //prendi tutti i produttori $result = mysql_query($sql_man); if (!$result) { echo "Could not successfully run query ($sql_man) from DB: " . mysql_error(); exit; } ?> <form action = "../../delorders/admin" method = "post"> <?php //********** //prendi nomi fornitori $k=0; while($tutti_manufact = mysql_fetch_array($result)){ $k++; $man = $tutti_manufact['name_id']; echo "<br></br>"; // //ciclo ricerca ordini per fornitore corrente = $man $sql_cod_ord = "SELECT * FROM ord_forn WHERE ord_forn.product_forn = '$man' AND is_compiled = 1 AND is_sent = 1"; ORDER BY ord_forn.cod_ord" ; $result1 = mysql_query($sql_cod_ord); if (!$result1) { echo "impossibile eseguire la query ($sql_cod_ord) from DB: " . mysql_error(); exit; } $i=0; while($tutti_gli_ord = mysql_fetch_array($result1)){ if ($i==0){ $ord = $tutti_gli_ord['cod_ord']; //salvo la coordinata ordine fornitore prod ?> <INPUT type="checkbox" name="checkbox[]" value=<?php echo $ord?> > <?php echo "<b>ord: '$ord' a fornit '$man'</b>"; echo "stato dell'ordine"; //aggiungi stato dell'ordine $delivered = $tutti_gli_ord['is_deliv']; if($delivered==1){$delivered="checked";}else{$delivered="";} ?> <INPUT type="checkbox" disabled name="delivered" value="bho" <?php echo $delivered ?>>Materiale consegnato <input type="text" name="manufact[]" value = "<?php echo $man ?>" size="1" style = "visibility:hidden"> <?php }//fine if $i=0 //prendi tutti i prod di questo ordine $prod_name = $tutti_gli_ord['product_name']; $prod_id = $tutti_gli_ord['product_id']; $product_qty = $tutti_gli_ord['product_qty']; echo "<br><b>riga ".$i.": ".$prod_id." ".$prod_name." qty: ".$product_qty."</b>"; //<input type="text" name="product_id[]" value = " <?php echo $prod_id ;" size="20" style = "visibility:hidden"> //<input type="text" name="parallel_id[]" value = " <?php echo $ord ;" size="20" style = "visibility:hidden"> $i++; } } ?> <table border="0"><tr><td> <select name="ddlist2" size="1"> <option>seleziona azione</option> <option>materiale ordine consegnato</option> <option>annulla materiale ordine consegnato</option> </select></td> <td><hr width="20" align="tr" noshade></td> <td> <input type = "submit" value = "esegui azione" > </td></tr></table> </form > <?php //***********+ echo "<br><b></b>"; $time_end = $this->microtime_float(); $time = $time_end - $time_start; echo "tempo di corsa = ".$time." secondi\n"; } function microtime_float() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); } } ?> La seguente routine invece aggiorna il magazzino in base alle scelte eseguite sugli ordini fornitori in corso, in particolare in funzione della gestione dei materiali: per fare questo si crea una cartella ‘DelOrders’ nella cartella principale ‘app/code/community/Fornitori’. Al termine dell’esecuzione viene riproiettata la situazione Ordini Fornitori aggiornata. Nella cartella Block inseriamo il seguente index.php <?php class Fornitori_DelOrders_Block_Index extends Mage_Core_Block_Template { protected function _toHtml() { $start=microtime(); $time_start = $this->microtime_float(); echo "<br><b>NUOVA SITUAZIONE ORDINI FORNITORI</b>"; echo "<br></b>"; include ("connectMag.php"); //controlla lo stato delle DropDownList1 if(isset($_POST['ddlist1'])){ $action = $_POST['ddlist1']; } //controlla lo stato delle DropDownList2 if(isset($_POST['ddlist2'])){ $action = $_POST['ddlist2']; } //controlla che siano stati passati ordini da cancellare if(!isset($_POST['checkbox'])&& ($action!="cancella tutti gli ordini")){ //$all_ord= $_POST['parallel_id']; //if(count($all_ord)==0){ echo "hai passato 0 ordini"; exit; } //1: nessuna azione selezionata if($action == "seleziona azione") {echo "<br>nessuna azione selezionata</br>";} //2: flagga ordine spedito if($action == "ordine spedito al fornitore"){ //analizza lo stato delle checkbox degli ordini if(isset($_POST['checkbox'])){ $checked = $_POST['checkbox']; } //fai sql_update in JOIN per rilasciare materiali e poterli rimettere in ordine for ($i = 0; $i < count($checked); $i++) { $sql_up = "UPDATE ord_forn SET is_sent = 1 WHERE ord_forn.cod_ord = '$checked[$i]' AND is_compiled = 1 "; $result = mysql_query($sql_up); if (!$result) { echo "Could not successfully run query ($sql_up) from DB: " . mysql_error(); exit; } else{ echo "<BR>Ordine '$checked[$i]' spedito</BR>"; } } } //3: annulla flagga ordine spedito if($action == "annulla ordine spedito al fornitore"){ //analizza lo stato delle checkbox degli ordini if(isset($_POST['checkbox'])){ $checked = $_POST['checkbox']; } //fai sql_update in JOIN per rilasciare materiali e poterli rimettere in ordine for ($i = 0; $i < count($checked); $i++) { $sql_up = "UPDATE ord_forn SET is_sent = 0 WHERE ord_forn.cod_ord = '$checked[$i]' AND is_compiled = 1 AND is_sent = 1 "; $result = mysql_query($sql_up); if (!$result) { echo "Could not successfully run query ($sql_up) from DB: " . mysql_error(); exit; } else{ echo "<BR>Ordine".$checked[$i]." marcato non spedito</BR>"; } } } //: cancella ordini if($action == "cancella tutti gli ordini"){ //sql in ord_forn $sql_del = "DELETE FROM ord_forn;"; $result = mysql_query($sql_del); if (!$result) { echo "Could not successfully run query ($sql_del) from DB: " . mysql_error(); exit; } //rilascia materiali per poterli rimettere in ordine $sql_release = "UPDATE cataloginventory_stock_item SET is_in_order = 0 WHERE is_in_stock = 0 AND is_in_order = 1 "; $result = mysql_query($sql_release); if (!$result) { echo "Impossibile eseguire la query ($sql_release) from DB: " . mysql_error(); exit; } else { echo "tutti gli ordini ai fornitori sono stati cancellati"; } } //: cancella ordini selezionati if($action == "cancella ordini selezionati"){ //analizza lo stato delle checkbox degli ordini if(isset($_POST['checkbox'])){ $checked = $_POST['checkbox']; //fai sql_update in JOIN per rilasciare materiali e poterli rimettere in ordine for ($i = 0; $i < count($checked); $i++) { $sql_up = "UPDATE cataloginventory_stock_item,ord_forn SET cataloginventory_stock_item.is_in_order = 0 WHERE ord_forn.cod_ord = '$checked[$i]' AND cataloginventory_stock_item.product_id = ord_forn.product_id AND cataloginventory_stock_item.is_in_stock = 0 AND cataloginventory_stock_item.is_in_order = 1 "; //echo $sql_up; //echo "<br>".$sql."</br>"; $result = mysql_query($sql_up); if (!$result) { echo "Could not successfully run query ($sql_up) from DB: " . mysql_error(); exit; } //fai sql_del in ord_forn per cancellare ordini $sql_del = "DELETE FROM ord_forn WHERE cod_ord = '$checked[$i]'"; //echo $sql_del; $result = mysql_query($sql_del); if (!$result) { echo "Could not successfully run query ($sql_del) from DB: " . mysql_error(); exit; } } echo "materiale disimpegnato";} }//if($action == "cancella ordini selezionati") //:materiale ordine consegnato if($action == "materiale ordine consegnato"){ // echo "mat cons?"; //analizza lo stato delle checkbox degli ordini if(isset($_POST['checkbox'])){ $checked = $_POST['checkbox']; } //sql sulle qty del prod in magazzino e sui flag di stato //metti materiali nello stato is_in_order=0 (non sono più in ordine perchè consegnati) //e ord_forn.is_deliv = 1 cataloginventory_stock_item.low_stock_date = ' formato data deve ess 2009-09-07 08:16:49 // // for ($i = 0; $i < count($checked); $i++) { $sql_update_qty = "UPDATE ord_forn,cataloginventory_stock_item SET cataloginventory_stock_item.qty = cataloginventory_stock_item.qty + ord_forn.product_qty, cataloginventory_stock_item.is_in_stock = 1, cataloginventory_stock_item.is_in_order = 0, ord_forn.is_deliv = 1 WHERE ord_forn.cod_ord = '$checked[$i]' AND cataloginventory_stock_item.product_id = ord_forn.product_id AND cataloginventory_stock_item.is_in_stock = 0 AND ord_forn.product_qty + cataloginventory_stock_item.qty > cataloginventory_stock_item.min_qty AND cataloginventory_stock_item.is_in_order = 1 AND ord_forn.is_deliv = 0 "; //echo $sql_update_qty; //i record che erano in stock non li aggiorno da qui $result = mysql_query($sql_update_qty); if (!$result) { echo "Could not successfully run query ($sql_update_qty) from DB: " . mysql_error(); exit; } else { echo "<BR>materiale dell'ordine '$checked[$i]' reintegrato</BR>"; } }//: cancella ordini selezionati }// //:annulla materiale ordine consegnato if($action == "annulla materiale ordine consegnato"){ if(isset($_POST['checkbox'])){ $checked = $_POST['checkbox']; } //riporta indietro ord_forn: reset qty, for ($i = 0; $i < count($checked); $i++) { $sql_up = "UPDATE ord_forn,cataloginventory_stock_item SET ord_forn.is_deliv = 0, cataloginventory_stock_item.qty = cataloginventory_stock_item.qty ord_forn.product_qty, cataloginventory_stock_item.is_in_stock = 0, cataloginventory_stock_item.is_in_order = 1 WHERE ord_forn.cod_ord = '$checked[$i]' AND cataloginventory_stock_item.product_id = ord_forn.product_id AND cataloginventory_stock_item.qty - ord_forn.product_qty < cataloginventory_stock_item.min_qty AND cataloginventory_stock_item.is_in_stock = 1 AND cataloginventory_stock_item.is_in_order = 0 AND ord_forn.is_compiled = 1 AND ord_forn.is_sent = 1 AND ord_forn.is_deliv = 1 "; //echo $sql_up; //AND cataloginventory_stock_item.qty - ord_forn.product_qty < cataloginventory_stock_item.min_qty $result = mysql_query($sql_up); if (!$result) { echo "Could not successfully run query ($sql_up) from DB: " . mysql_error(); exit; } else{ echo "<BR>Ordine '$checked[$i]' marcato non consegnato</BR>"; } } // //riporta indietro cataloginventory_stock_item } echo "<br>"; ?> <input type="button" value="Torna a ordini 'PENDING'"> <?php echo "<br>"; $time_end = $this->microtime_float(); $time = $time_end - $time_start; echo "<br>tempo di corsa = ".$time." secondi\n"; } function microtime_float() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); } } ?> In entrambi i precedenti files viene utilizzato un file di connessione al database ‘connectMag.php’, qui di seguito riportato. ?php $databasehost = "localhost"; $databasename = "magento1"; $databasetable = "ord_forn"; $databaseusername ="root"; $databasepassword = ""; //connessione DB $con = mysql_connect($databasehost, $databaseusername, $databasepassword); if (!$con){die('<span style="color:#FF0000"><strong>MSCon sbagliata: </strong></span>' . mysql_error());} mysql_select_db($databaseusername,$con); if (!mysql_select_db($databasename)) { echo "Impossibile selezionare db: " . mysql_error(); exit; } ?> Come si vede dal file precendente, è stata creata ad hoc una tabella parallela nel database di Magento per la gestione degli ordini fornitori (ord_forn): questo ha permesso di guadagnare notevolmente in velocità e di bypassare la intricata e un po’ carente gestione dei dati di Magento . Con questi passaggi Magento è adesso dotato di gestione degli ordini ai fornitori.