W dzisiejszym artykule opiszę, w jaki sposób uwzględnić rabaty produktów w widoku zamówienia. Poniższa treść przedstawia cały proces dla panelu klienta. Pamiętaj by tę samą zasadę zastosować także dla panelu administratora oraz wysyłki potwierdzenia, aby nie przekazać przypadkiem klientowi niewłaściwego zamówienia.

W pierwszej kolejności będziemy musieli zmodyfikować tabelę w bazie danych, która przechowuje zamówienia. Tabela ta nazywa się #__{vm}_orders, gdzie #__ to przedrostek bazy danych Joomla! a {vm} to przedrostek tabel VirtueMart. U mnie pełna nazwa tabeli, po uwzględnieniu przedrostków, to jos_vm_orders.

Co musimy dodać ? Dwa pola. Pierwsze, przechowujące wartość rabatu w %, drugie zaś całkowitą kwotę zamówienia, po uwzględnieniu rabatu. Poniżej przedstawiam przykładowe zapytania SQL, które zrealizują opisane zadanie:

ALTER TABLE jos_vm_orders ADD COLUMN rabat INT(3) NOT NULL default '0';
ALTER TABLE jos_vm_orders ADD COLUMN rabat_total DECIMAL(10,2) NOT NULL default '0';

Mamy zmodyfikowaną tabelę. Teraz należy uwzględnić nowe pola, podczas zapisu zamówienia. Przejdźmy zatem do pliku, który odpowiada za zapis zamówienia, a mianowicie:

administrator/components/com_virtuemart/classes/ps_checkout.php

Modyfikacje tego pliku będą bardzo podobne do modyfikacji poprzednich plików. Zaczynamy od linijki ok. 924, gdzie znajduje się następujący kod:

/* Set the order number */
$order_number = $this->get_order_number();

$totals = $this->calc_order_totals( $d );
extract( $totals );

Tuż za nim, dodajemy ponownie skrypt regulujący wykorzystanie rabatów:

// * Rabat

$rabat = array('100-200'=>'5','201-400'=>'10','401-10000000000'=>'15');
$do_rabat = 0;
foreach ($rabat as $pr=>$rr){
    $pr = explode("-",$pr);
    // sprawdź czy mieści się w przedziale
    if(($order_total)>=intval($pr[0]) && ($order_total)<=intval($pr[1])){
        // jeśli tak to przypisz rabat
        $do_rabat = intval($rr);
    }
}
// jeśli jest rabat to zmień cenę końcową
if ($do_rabat>0){
    $rabat_order_total = $order_total - ($order_total*($do_rabat/100));
    $rabat_total_display = $GLOBALS['CURRENCY_DISPLAY']->getFullValue($rabat_order_total);
}

// * End Rabat

Wydaje mi się, że powyższego kodu nie trzeba w żaden sposób komentować. Wszystko powinno być jasne po modyfikacjach z poprzedniego artykułu :)

Jesteśmy coraz bliżej zakończenia modyfikacji. Przedostatnim krokiem będzie dodanie otrzymanych zmiennych, przechowujących rabaty, do bazy danych. Wszystkie pola, które są umieszczone w tabeli zamówienia, zostały przypisane do zmiennej $fields. Powinniśmy znaleźć ją kilkanaście linijek poniżej kodu, który dopiero co dodaliśmy. Na samym końcu tablicy, należy dopisać nowe zmienne:

// Collect all fields and values to store them!
$fields = array(
    'user_id' => $auth["user_id"],
    'vendor_id' => $ps_vendor_id,
    'order_number' => $order_number,
    'user_info_id' =>  $d["ship_to_info_id"],
    'ship_method_id' => @urldecode($d["shipping_rate_id"]),
    'order_total' => $order_total,
    'order_subtotal' => $order_subtotal,
    'order_tax' => $order_tax,
    'order_tax_details' => serialize($order_tax_details),
    'order_shipping' => $order_shipping,
    'order_shipping_tax' => $order_shipping_tax,
    'order_discount' => $payment_discount,
    'coupon_discount' => $coupon_discount,
    'coupon_code' => @$_SESSION['coupon_code'],
    'order_currency' => $GLOBALS['product_currency'],
    'order_status' => 'P',
    'cdate' => $timestamp,
    'mdate' => $timestamp,
    'customer_note' => htmlspecialchars(vmRequest::getString('customer_note','', 'POST', 'none' ), ENT_QUOTES )
    'ip_address' => $ip,
    'rabat' => $do_rabat,
    'rabat_total' => $rabat_order_total
);

Teraz przyszedł czas na wykończenie. Mamy już wszystko czego potrzebujemy. Jedyne co zostaje, to pokazać nowe dane w widoku zamówienia. Otwieramy zatem plik, który odpowiada za tą akcję:

components/com_virtuemart/themes/default/templates/pages/account.order_details.php

Pamiętaj, że jeśli korzystasz z innego szablonu niż domyślny, musisz uwzględnić go w ścieżce wspomnianego pliku. Wówczas zamiast default pojawi się nazwa Twojego szablonu.

Powyższy plik listuje całe zamówienie. Należy dodać tutaj praktycznie ten sam kod, który dodaliśmy w przypadku koszyka. Gdzie go dodasz, zależy już od Ciebie. Ja dodałem go tak samo jak w poprzednim przypadku, tuż za podsumowaniem końcowej kwoty, by było to jak najbardziej widoczne. Kod umieściłem tuż za 542 linijką:

<?php
// Rabat Start
if ($db->f('rabat')>0){
?>
<tr>
    <td colspan="3" align="right">&nbsp;</td>
    <td colspan="2" align="right"><hr/></td>
</tr>
<tr>
    <td colspan="4" align="right">Rabat:</td>
    <td align="right"><?php
    echo $db->f('rabat')."%";
    ?>&nbsp;&nbsp;&nbsp;</td>
</tr>
<tr>
    <td colspan="4" align="right">Cena po rabacie:</td>
    <td align="right"><?php
    echo $CURRENCY_DISPLAY->getFullValue($db->f('rabat_total'));
    ?>&nbsp;&nbsp;&nbsp;</td>
</tr>
<?php
}
// Rabat end
?>

Jeśli wszystko wykonałeś poprawnie, w podglądzie zamówienia, które uwzględnia rabat, powinieneś ujrzeć coś takiego:

Rabat został wyświetlony w podsumowaniu zamówienia.

Napisane przeze mnie artykuły miały na celu zaprezentować rozwiązanie problemu rabatów w VM. Jest tutaj sporo niedociągnięć, które każdy powinien poprawić na własne potrzeby. Jak zauważyłeś wszystkie rabaty były ładowane jako tablica w zmiennej. Lepiej byłoby stworzyć plik z rabatami i w każdym modyfikowanym pliku odnosić się właśnie do niego. Wówczas w razie zmian rabatów, nie musielibyśmy modyfikować każdego pliku VM, a tylko ten jeden, przechowujący tablicę rabatów. Poza tym musisz pamiętać, że należy uwzględnić rabaty w panelu administratora w podsumowaniu zamówienia oraz w wysyłanych mailach z podsumowaniem. Wspomnieć należy także o płatnościach on-line. Tutaj także należy pamiętać, by do płatności, w przypadku gdy istnieje rabat, przenieść kwotę rabat_total z zamówienia. Inaczej płatność on-line zostanie wypełniona dla końcowej kwoty zamówienia, bez uwzględnienia rabatów.
Mam nadzieję, że ten artykuł będzie inspiracją przy problemach o podobnej tematyce. Komentarze oczywiście mile widziane :)