Nowy odświeżony szablon michelson.pl

Napisany przez admin, dodany w Niedziele 21 września 2014r. w kategorii Nasze realizacje Tagi: , , ,  •  Brak komentarzy

Kilka dni temu zakończyliśmy prace nad migracją sklepu naszego klienta do wersji Magento 1.9.0.1, stara wersja sklepu pracowała pod kontrolą Magento w wersji 1.6.1.0.
Prócz aktualizacji samego silnika modyfikacji doczekała się i szata graficzna. Wygląd strony przeszedł gruntowną metamorfozę. Aktualna wersja jest dużo lżejsza a jej celem było lepsze wyeksponowanie produktów. Aby uzyskać taki efekt zaimplementowane zostały algorytmy image sharpening-u pomagające wyostrzyć każde zdjęcie niezależnie od jego wielkości. Teraz każdy pierścionek wygląda wyjątkowo ślicznie ;)

michelson_v2

Dzięki tym zabiegom użytkownik może skupić się bardziej na aspekcie wizualnym strony oraz zamieszczonych na niej produktach. Strona przygotowana została w oparciu o responsive web design dzięki czemu sklep prezentuje się bardzo ładnie na urządzeniach mobilnych. Liczba kolumn dynamicznie jest dostosowywana do wielkości ekranu a menu przy małych rozdzielczościach jest zwijane nie zajmując zbędnego miejsca. Wersje responsywne również kładą nacisk na wyeksponowanie produktu i funkcjonalności. A prezentują się tak :

michelson_v3

Również od strony serwerowej, pojawiło się sporo zmian, cała platforma została przeniesiona na nową maszynę z wydajnym procesorem i dużą ilością pamięci ram. Środowisko zostało przygotowane z założeniem wpięcia go w klaster w niedalekiej przyszłości. Za serwowanie witryny odpowiada teraz najnowsza wersja wydajnego serwera nginx a php działa w oparciu o bezpieczną i wydajną technologię php-fpm. Zrezygnowaliśmy z APC na rzecz OPcache który podczas wywołania skryptu sprawdza czy kod pośredni dla wywołanej wersji skryptu jest dostępny – jeśli tak to wywołuje istniejącą już kod pośredni. Natomiast Couchbase przechowuje cache Magento i Sesje co pozwoliło mocno ulżyć IO Dysku. Baza danych została zmigrowana do Percony zapewniając dużą stabilność.

Na samym froncie stoi Varnich odpowiedzialny głównie za chacowanie treści statycznych, co dodatkowo odciąża serwer www i znacząco przyspiesza ładowanie się strony.

Dzięki naszemu doświadczeniu cały proces przełączania sklepu i migracji trwał mniej niż 20 minut, a godziny jego przeprowadzenia zostały wybrane na czas najmniejszego obciążenia sklepu.

Szybki import stanów magazynowych w Magento

Napisany przez admin, dodany w Niedziele 21 września 2014r. w kategorii Nasze rozwiązania, Praktyczne porady Tagi: , ,  •  Komentowanie nie jest możliwe

Często zachodzi potrzeba zaimportowania stanów magazynowych z innego systemu. Najczęściej w tym celu wykorzystywane jest API, jednak ma ono jedną podstawową wadę, jest bardzo powolne. Kiedy potrzebujemy w krótkim czasie dokonać zmiany kilku tysięcy produktów, to wykorzystanie API może być nie najlepszym rozwiązaniem z powodu jego bardzo dużej pracochłonności i narzutu na zasoby.

Innym popularnym rozwiązaniem jest napisanie własnego skryptu mającego realizować to zadanie w oparciu o modele Magento.
Poniżej prezentujemy przykładowy skrypt importujący stany magazynowe na podstawie pliku CSV, oczywiście jako źródło wejściowe posłużyć inna baza danych lub API programu magazynowego.

ini_set("display_errors", 1);
ini_set("memory_limit","1024M");
 
require_once 'app/Mage.php';
umask(0);
 
$currentStore = Mage::app()->getStore()->getId();
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
 
$path = getcwd().'/WebStockInput.csv';
$readfile = file ($path);
for ($i=1; $i < count($readfile); $i++ ) {
    $fields = split("\t",$readfile[$i]);
     
    $product = Mage::getModel('catalog/product');
    $product->load($product->getIdBySku($fields[0]));
    // get product's stock data such quantity, in_stock etc
    $stockData = $product->getStockData();
 
    // update stock data using new data
    $stockData['qty'] = $fields[2];
    $stockData['is_in_stock'] = 1;
 
    // then set product's stock data to update
    $product->setStockData($stockData);
    try {
        $product->save();
    }
    catch (Exception $ex) {
        echo $ex->getMessage();
    }
 
}
 
Mage::app()->setCurrentStore($currentStore);
?>

Niestety i to rozwiązanie nie należy do zbyt szybkich. Dlatego poniżej prezentujemy jak my to robimy. Nasz skrypt pozwala na zmianę stanów kilku tysięcy produktów w mniej niż 120 sekund. Został przetestowany w wielu rozwiązaniach i jak na razie sprawdza się bardzo dobrze. Jeżeli zajdzie potrzeba dostosowania go do współpracy z innymi programami magazynowymi lub źródłami danych zachęcamy do kontaktu z nami.

Konfiguracja
Aby skrypt działał poprawnie należy ustawić zmienną $workdir na folder z plikiem wejściowym o nazwie magento2.csv.
W tym też folderze skrypt zapisze raport z wynikiem swojej pracy.

//Centerkom.pl - najlepsze rozwiązania Magento

$workdir - "/var/www/import/"

function getmicrotime(){list($usec, $sec) = explode(" ",microtime());return ((float)$usec + (float)$sec);}
$time_start = getmicrotime();


$mageFilename = "../app/Mage.php";
require_once $mageFilename;
Mage::setIsDeveloperMode(true);
ini_set("display_errors", 1);
umask(0);
Mage::app("admin");
Mage::register("isSecureArea", 1);
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
 
set_time_limit(0);
ini_set("memory_limit","1024M");
 
/***************** UTILITY FUNCTIONS ********************/
function _getConnection($type = "core_read"){
    return Mage::getSingleton("core/resource")->getConnection($type);
}
 
function _getTableName($tableName){
    return Mage::getSingleton("core/resource")->getTableName($tableName);
}
 
function _getAttributeId($attribute_code = "price"){
    $connection = _getConnection("core_read");
    $sql = "SELECT attribute_id
                FROM " . _getTableName("eav_attribute") . "
            WHERE
                entity_type_id = ?
                AND attribute_code = ?";
    $entity_type_id = _getEntityTypeId();
    return $connection->fetchOne($sql, array($entity_type_id, $attribute_code));
}
 
function _getEntityTypeId($entity_type_code = "catalog_product"){
    $connection = _getConnection("core_read");
    $sql        = "SELECT entity_type_id FROM " . _getTableName("eav_entity_type") . " WHERE entity_type_code = ?";
    return $connection->fetchOne($sql, array($entity_type_code));
}
 
function _checkIfSkuExists($sku){
    $connection = _getConnection("core_read");
    $sql        = "SELECT COUNT(*) AS count_no FROM " . _getTableName("catalog_product_entity") . " WHERE sku = ?";
    $count      = $connection->fetchOne($sql, array($sku));
    if($count > 0){
        return true;
    }else{
        return false;
    }
}
 
function _getIdFromSku($sku){
    $connection = _getConnection("core_read");
    $sql        = "SELECT entity_id FROM " . _getTableName("catalog_product_entity") . " WHERE sku = ?";
    return $connection->fetchOne($sql, array($sku));
}
 
function _updateStocks($data){
    $connection     = _getConnection("core_write");
    $sku            = $data[0];
    $newQty         = $data[1];
    $productId      = _getIdFromSku($sku);
    $attributeId    = _getAttributeId();
 
    $sql            = "UPDATE " . _getTableName("cataloginventory_stock_item") . " csi,
                       " . _getTableName("cataloginventory_stock_status") . " css
                       SET
                       csi.qty = ?,
                       csi.is_in_stock = ?,
                       css.qty = ?,
                       css.stock_status = ?
                       WHERE
                       csi.product_id = ?
                       AND csi.product_id = css.product_id";
    $isInStock      = $newQty > 0 ? 1 : 0;
    $stockStatus    = $newQty > 0 ? 1 : 0;
    $connection->query($sql, array($newQty, $isInStock, $newQty, $stockStatus, $productId));
}
/***************** UTILITY FUNCTIONS ********************/
 
$csv                = new Varien_File_Csv();
$data               = $csv->getData($workdir/"magento2.csv"); //path to csv
array_shift($data);
 
$message = "";

$count   = 1;
$count_success = 0;
foreach($data as $_data){
    if(_checkIfSkuExists($_data[0])){
        try{
            _updateStocks($_data);
            $message .= $count . "> Success:: Qty (" . $_data[1] . ") of Sku (" . $_data[0] . ") has been updated. \n";
            //echo $count . "> Success:: Qty (" . $_data[1] . ") of Sku (" . $_data[0] . ") has been updated. \n";
            $count_success++;
 
        }catch(Exception $e){
            $message .=  $count ."> Error:: while Upating  Qty (" . $_data[1] . ") of Sku (" . $_data[0] . ") => ".$e->getMessage()."\n";
            echo $count ."> Error:: while Upating  Qty (" . $_data[1] . ") of Sku (" . $_data[0] . ") => ".$e->getMessage()."\n";
        }
    }else{
        $message .=  $count ."> Error:: Product with Sku (" . $_data[0] . ") does't exist.\n";
        //echo  $count ."> Error:: Product with Sku (" . $_data[0] . ") does't exist.\n";
    }
    $count++;
}


$fp = fopen($workdir.date("Ymd"), 'w');
$time_end = getmicrotime();
$time = $time_end - $time_start;

fwrite($fp, $message);
fwrite($fp, "\nZmieniono :".$count_success);
fwrite($fp, "\nCzas wygenerowania strony $time s"); 
fwrite($fp, "\nmemory_get_usage ".((memory_get_usage()/1024)/1024));
fwrite($fp, "\nreal_memory_get_usage ".((memory_get_usage(true)/1024)/1024));

Współpraca przy newcraft.eu

Napisany przez admin, dodany w Niedziele 21 września 2014r. w kategorii Nasze realizacje Tagi:  •  Komentowanie nie jest możliwe

Wdrożenie przy którym mieliśmy okazję współuczestniczyć, nasza rola ograniczyła się do konfiguracji i instalacji Magento na serwerze klienta.
Ponadto specjalnie na potrzeby systemy newcraft.ey wykonania kilka modułów umożliwiających osiągnięcie zamierzonego przez klienta efektu.

Wiosna pod znakiem nowego layoutu strony Michelson.pl

Napisany przez admin, dodany w Niedziele 21 września 2014r. w kategorii Nasze realizacje Tagi: ,  •  Komentowanie nie jest możliwe

A jak wyglądają te zmiany, zobaczcie sami :

Amor zapanował w wiosennej odsłonie Michelsona i pokazał, jak bardzo ceni Zakochanych! W powietrzu unosi się miłość i świeży powiew wyjątkowych okazji. Strona teraz wygląda jeszcze ładniej niż poprzednio, a ciekawa kolorystyka współgra z ofertą sklepu.

Klasyczne i awangardowe pierścionki zaręczynowe tylko czekają na romantyczny moment oświadczyn. Piękny złoty pierścionek z brylantem już niedługo zabłyszczy na dłoni Ukochanej, kiedy wzruszona i zachwycona powie „Tak!”. Eleganckie złote obrączki ślubne są gotowe dla tych, którzy już podjęli tę radosną decyzję, by być razem na zawsze. A oryginalna biżuteria aż płonie, by stać się wyjątkową ozdobą i wzbogacić wykwintną kreację. Wszystko to z materiałów najlepszego gatunku i w wyjątkowych cenach, które zaskakują swoją dostępnością.

Jesteśmy przekonani, że nowa odświeżona szata graficzna michelson.pl pomoże naszemu partnerowi zdobyć wielu nowych klientów i pomnożyć swoje zyski.

Świąteczna odsłona michelson.pl

Napisany przez admin, dodany w Niedziele 21 września 2014r. w kategorii Nasze realizacje Tagi:  •  Komentowanie nie jest możliwe

W okresie świątecznym, dzięki funkcjonalności magento sklepy naszych klientów przybierają nową formę. Poprzez zastosowanie unikalnej i kojarzącej się z świątecznymi zakupami naszemu klientowi udało się pobić kolejne rekordy sprzedaży.