assets/s2diorder.php
/// Art: Shop Business Logic
/// Inhalt: Klasse order
/// Beschreibung: Business Logic rund um die Bestellung
/// Benötigt: config.php, db.php
/// CCML-Parsing: nein
///
//////////////////////////////////////////////////////////////////////////////////////////
///
/// Letzte Änderungen:
/// 02.03.2009 br Tag in Lizenzemails ergänzt
/// 20.03.2009 Gutschein bis einen Tag verlängert
/// 24.03.2009 Erweiterung Bestandsverwaltung
/// 24.03.2009 Rundung Gesamtpreis
/// 26.03.2009 Tracking URL absolut
/// 27.03.2009 Sript Tags für Textmail
/// shop to date 7
/// 02.09.2009 Moneybookers hinzugefügt
/// 07.12.2009 Warenkorbsperre bei Minderbestand hinzugefügt
/// 11.12.2009 Rabattsperre hinzugefügt
/// 14.12.2009 Rabattcoupons
/// 23.01.2010 Rechnungsnummern hinzugefügt
/// 22.02.2010 PDF Erstellungvariablen hinzugefügt
/// 10.03.2010 Bestelloptionen
/// 27.03.2010 PDF Versand und Erstellung
/// 14.07.2010 Verbesserung unserialize wegen Warning
/// 31.07.2010 Rabattierbare Bestelloptionen
/// 31.07.2010 Bug mit Summenrabatten behoben
/// 31.07.2010 Status auch in Bestellbestätigung
/// 01.08.2010 Status-Email nicht für Bestellung eingegangen
/// 05.08.2010 CRLF für Text Mails
/// 13.08.2010 expected_date formatieren
/// 13.09.2010 pdf email auch bei status neu
/// 28.09.2010 Kauf bei Minderbestand verhindern nur nich bei kein Bestand
/// 04.10.2010 Kauf bei Minderbestand verbessert
/// 11.10.2010 Kauf bei Minderbestand nochmals verändert
/// 25.10.2010 Gutscheincode mehr Zeichen
/// 25.10.2010 Kauf bei Minderbestand nochmals verändert
/// 23.11.2010 Deprecated array_push
///
//////////////////////////////////////////////////////////////////////////////////////////
///<23.11.2010/7.0.2.7>
if (!defined('SHOP_TO_DATE'))
die('Forbidden');
// Klasse Bestellung
class order extends db {
// Eigenschaften (in der DB)
var $order_id = '0'; // Bestellnummer bzw. vor Abschluss der Bestellung session_id
var $order_id_prefix = null; // Präfix Bestellnummer
var $order_date = ''; // Bestelldatum (wichtig nur nach der Bestellung)
var $order_time = ''; // Bestellzeit (wichtig nur nach der Bestellung)
var $bill_id = null; // Eindeutige, fortlaufende Rechnungsnummer (wichtig nur nach der Bestellung)
var $bill_id_prefix = null; // Präfix Rechnungsnummer
var $bill_date = null;
var $b2b = 0;
var $pdf_creation = 0; // PDF Generierung: 0 = aus/manuell, 1 = Bei Bestelleingang, 2 = Bei Versand der Ware
var $currency = '';
// Achtung muss null sein für Ersterkennung, nicht ändern!
var $sumrebate_amount = null; // Summenrabatte
var $sumrebate_absolute = 0;
var $couponrebate_amount = 0; // Gutscheinrabatte
var $couponrebate_absolute = 0;
var $coupon_id = null; // Gutschein
var $coupon_caption = null; // Bezeichnung Gutscheinart
var $shipping_cost = 0;
var $shipping_vat = 0;
var $shipping_caption = '';
var $shipping_trackingurl = null;
var $payment_amount = 0;
var $payment_absolute = 0;
var $payment_vat = 0 ;
var $payment_caption = '';
var $payment_param = null;
var $paymentrebate_amount = 0; // Zahlweisenrabatte
var $paymentrebate_absolute = 0;
var $status = CC_RESSOURCE_ORDERSTATUSSHORT_NEW; // Status der Bestellung
var $shipping_date = null;
var $payment_date = null;
var $expected_date = null;
var $message = null;
var $tracking_id = null;
var $affiliate_id = null;
var $affiliate_subid = null;
var $search_email;
var $search_name;
// Variablen
var $client = null;
var $items = array();
var $vatarray; // Alle Steuergruppen mit gerundeten Werten zum weiterrechnen
var $sm = null; // Versandmethode
var $pm = null; // Bezahlmethode
var $coupon = null;
var $coupondef = null;
var $change_id;
// Konstruktor Initialisierung zugehörige Datenbank
function order($order_id = null, $client = null, $is_session = false) {
global $shipping, $payment;
$this->db(TABLE_ORDERS);
if (!$order_id)
return;
$this->order_id = $order_id;
// Bestellung laden nur bei tatsächlicher Bestellung, nicht für Sessions!
if (!$is_session) {
$this->db_selectobject(array('order_id' => $order_id));
}
// Vor Abschluss der Bestellung
if (!$this->order_date && $client) {
$this->b2b = CC_SITE_B2B;
$this->currency = CC_SITE_CURRENCY;
// Kunde einfügen
$this->client = $client;
// Coupons in Eigenschaft übertragen
$this->coupon = new coupon($this->client->coupon_id);
if ($this->coupon->coupon_id) {
$this->coupondef = new coupondef($this->coupon->coupondef_id);
if (!$this->coupondef->item_uid) {
$this->couponrebate_absolute = $this->coupondef->rebate_absolute;
$this->couponrebate_amount = $this->coupondef->rebate_amount;
} else {
$this->couponrebate_absolute = 0;
$this->couponrebate_amount = 0;
}
$this->coupon_id = $this->coupon->coupon_id;
$this->coupon_caption = $this->coupondef->caption;
} else
$this->coupon = null;
// Nach Abschluss der Bestellung
} else if ($this->order_date) {
// Versand und Bezahlung
$this->sm = new shipping_method();
$this->sm->caption = $this->shipping_caption;
$this->sm->trackingurl = $this->shipping_trackingurl;
$this->sm->vat = $this->shipping_vat;
$this->sm->total = $this->shipping_cost;
$this->pm = new payment_method();
$this->pm->actualprice = null;
$this->pm->caption = $this->payment_caption;
$this->pm->amount = $this->payment_amount;
$this->pm->absolute = $this->payment_absolute;
$this->pm->rebate_amount = $this->paymentrebate_amount;
$this->pm->rebate_absolute = $this->paymentrebate_absolute;
$this->pm->parameter[0] = $this->payment_param;
$this->pm->vat = $this->payment_vat;
// Kunde einfügen
$this->client = new client(null, $this->order_id);
if (!$this->client->client_id)
die('Data corrupt #2');
} else { // Nur Warenkorb
$this->b2b = CC_SITE_B2B;
$this->currency = CC_SITE_CURRENCY;
}
$this->vatarray = new vatarray($this->b2b, isset($this->client->novat) ? $this->client->novat : 0);
format::to_abs($this, array('sumrebate_absolute', 'couponrebate_absolute', 'paymentrebate_absolute'));
format::to_float($this, array('sumrebate_amount', 'couponrebate_amount', 'shipping_vat', 'payment_vat', 'shipping_cost', 'payment_amount', 'paymentrebate_amount'), 2);
// Artikel laden
$item = new item();
$item->db_select(array('uid', 'position', 'memo'), array('order_id' => $this->order_id), array('position asc'));
while ($row = $item->db_fetch())
$this->items[] = new item($row->uid, $this->order_id, $row->position, null, $row->memo);
$item->db_free();
// Vorgefüllter Artikel in den Warenkorb
if (CC_SITE_PREFILL && !count($this->items)) {
$position = $this->add_item(new item(null, null, null, MODE_PREFILL));
// Eco-Tax Anpassung Frankreich, falls Ecotax vorhanden Artikel anlegen
if (CC_SITE_LOCALE_FR && CC_SITE_PREFILL_ECOTAX_PROVIDER)
$this->add_item(new item(null, null, $position, MODE_ECOTAXPREFILL));
}
if (!$this->order_date && $client) {
if ($this->client->payment_uid) {
$payment->calc_prices($this);
$this->pm = $payment->get($this->client->payment_uid);
}
} else if ($this->order_date)
$this->calc_vat();
}
//////////////////////////////////////////////////////////////////////////// Gutscheine
// Gutschein einbuchen
function add_coupon($coupon_id) {
if (!preg_match(CHECK_ALPHANUMCOUPON, $coupon_id))
return CC_RESSOURCE_COUPONINVALID;
$coupon = new coupon($coupon_id);
if (!$coupon->coupondef_id)
return CC_RESSOURCE_COUPONINVALID;
if ($coupon->order_id)
return CC_RESSOURCE_COUPONREDEEMED;
$coupondef = new coupondef($coupon->coupondef_id);
// Bestimmter Kunde
if ($coupon->client_email && $coupon->client_email != $this->client->email)
return CC_RESSOURCE_COUPONCLIENTNOTMET;
// Bestimmter Artikel
if ($coupondef->item_uid && !$this->contains_item($coupondef->item_uid))
return CC_RESSOURCE_COUPONITEMNOTMET;
// Bestimmter Zeitraum
if ($coupondef->date_from && strtotime($coupondef->date_from) > time())
return CC_RESSOURCE_COUPONDATENOTMET;
if ($coupondef->date_until && strtotime($coupondef->date_until) + 86400 < time())
return CC_RESSOURCE_COUPONDATENOTMET;
// Mindestbestellwert
if ($coupondef->subtotal && $this->get_subtotal() < $coupondef->subtotal)
return CC_RESSOURCE_COUPONVALUENOTMET;
// Gutschein im Kundenkonto speichern
$this->client->coupon_id = $coupon_id;
$this->client->store();
$this->coupon_id = $coupon_id;
$this->couponrebate_absolute = $coupondef->rebate_absolute;
$this->couponrebate_amount = $coupondef->rebate_amount;
return false;
}
// Gutschein entfernen
function remove_coupon() {
if ($this->coupon_id) {
$coupon = new coupon($this->coupon_id);
$coupon->store();
$this->client->coupon_id = null;
$this->client->store();
$this->coupon_id = null;
$this->couponrebate_amount = 0;
$this->couponrebate_absolute = 0;
}
}
//////////////////////////////////////////////////////////////////////////// Berechnung
// Tatsächliche Preise von Artikeln und Versand/Bezahlung aktuelisieren
function calc_prices() {
global $filename;
// Artikelpreise aktualisieren
foreach (array_keys($this->items) as $k) {
$item = &$this->items[$k];
// Mengenrabatte
$item->calc_quantrebate();
// Gutscheine mit Artikelrabatten (nicht für Artikel auf Merkzettel)
if (!$item->memo)
if ($this->coupon && $this->coupondef->item_uid == $item->uid) {
$price = floatval($this->coupondef->item_price);
$item->price = max(0, $price);
}
}
// Umsatzsteueranpassung Spanien
// Falls Kunde eingeloggt und für Provins Ersetzungen vorhanden
$adapt = array();
if (CC_SITE_LOCALE_ES && $this->client && $adapt = get_vat_adaption($this->client)) {
foreach (array_keys($this->items) as $k) {
$item = &$this->items[$k];
if (array_key_exists($old = (int) $item->vat, $adapt)) {
$new = $adapt[$old];
$item->vat = $new;
if (!$this->b2b)
$item->price = floor($item->price / (1 + $old / 100) * (1 + $new / 100) * 100) / 100;
}
}
}
// Umsatzsteueranpassung Spanien
if (CC_SITE_LOCALE_ES && count($adapt)) {
$this->get_shipping_cost();
if ($this->sm && array_key_exists($old = (int) $this->sm->vat, $adapt)) {
$new = $adapt[$old];
$this->sm->vat = $new;
if (!$this->b2b)
$this->sm->actualprice = floor($this->sm->actualprice / (1 + $old / 100) * (1 + $new / 100) * 100) / 100;
}
$this->get_payment_cost();
if ($this->pm && array_key_exists($old = (int) $this->pm->vat, $adapt)) {
$new = $adapt[$old];
$this->pm->vat = $new;
if (!$this->b2b)
$this->pm->actualprice = floor($this->pm->actualprice / (1 + $old / 100) * (1 + $new / 100) * 100) / 100;
}
}
// Bestelloptionen zur Artikelliste hinzufügen
global $checkout_sites;
if ($this->client && in_array(FILENAME, $checkout_sites)) {
// Position ermittlen
$db_item = new item();
$obj = $db_item->db_selectone(array('max(position) as pos'), array('order_id' => $this->order_id));
if ($obj)
$position = $obj->pos + 1;
else
$position = 1;
if ($this->client->custom_options)
$custom_values = (array) unserialize($this->client->custom_options);
else
$custom_values = array();
global $customoptions;
foreach ((array) $customoptions as $custom) {
$is_selectedprice = 0;
$custom_item = new item();
$custom_item->vat = $custom->vat;
$custom_item->uid = 'custom';
$custom_item->position = $position++;
$custom_item->unit = 'x';
$custom_item->rebatable = CC_SITE_ORDERSPECIALSREBATABLE;
if ($custom->is_checkbox && isset($custom_values[$custom->caption])) {
$custom_item->price = $custom->price;
$custom_item->caption = $custom->caption;
$custom_item->quantity = 1;
}
if ($custom->is_combo && isset($custom_values[$custom->caption]))
foreach ($custom->combo_options as $option)
if (isset($custom_values[$custom->caption]) && $custom_values[$custom->caption] == $option->caption) {
$custom_item->price = $option->price;
$custom_item->caption = $custom->caption . ': ' . $option->caption;
$custom_item->quantity = 1;
}
if ($custom->is_text && isset($custom_values[$custom->caption])) {
$custom_item->price = 0;
$custom_item->caption = $custom->caption . ': ' . $custom_values[$custom->caption];
$custom_item->quantity = 1;
}
if ($custom_item->quantity) {
array_push($this->items, $custom_item);
}
}
}
}
// Steuern berechnen
function calc_vat($filename = null) {
if ($this->get_subtotal()) {
if ($this->get_subtotal_rebatable() > 0)
$rebate_percent = ($this->get_subtotal_rebatable() - $this->get_rebate()) / $this->get_subtotal_rebatable();
else
$rebate_percent = 0;
// Steuern für Artikel (nicht die auf Merkzettel)
foreach ($this->items as $item) {
if (!$item->memo) {
if ($item->rebatable)
$sum = $item->price * $item->quantity * $rebate_percent;
else
$sum = $item->price * $item->quantity;
$this->vatarray->add($item->vat, $sum, $this->b2b);
}
}
}
if ($filename != CC_FILENAME_BASKET) {
// Steuern für Versandmethode
$cost = $this->get_shipping_cost();
$this->vatarray->add($this->sm->vat, $cost, $this->b2b);
// Steuern für Bezahlmethode
$cost = $this->get_payment_cost();
$this->vatarray->add($this->pm->vat, $cost, $this->b2b);
}
$this->vatarray->sort();
}
// Anzahl der Artikel im Korb aktualisieren
function update_quantity() {
if (!CC_SITE_LOCKOUTOFSTOCK)
return array();
return $this->check_quantity(true);
}
// Anzahl der Artikel im Korb prüfen
function check_quantity($update = false) {
if (!CC_SITE_LOCKOUTOFSTOCK)
return true;
$messages = array();
foreach (array_keys($this->items) as $k) {
$item = &$this->items[$k];
// Nicht für Artikel auf dem Merkzettel
if ($item->memo)
continue;
// gültig
if ($message = $item->check_minmax())
$messages[] = $message;
// Aktuelle Bestands- und Statusdaten des Artikels einlesen
if ($item->stockserver) {
$stock_product = new stock_product($item->uid, $item->variationa ? $item->variationa : 1, $item->variationb ? $item->variationb : 1);
$stock = $stock_product->get();
}
// Falls nicht lieferbar auf Merkzettel setzen.
if (CC_SITE_LOCKOUTOFSTOCK && $item->stockserver && $stock <= 0) {
$messages[] = str_replace('[c]', $item->caption, CC_RESSOURCE_BASKET_OUTOFSTOCKNOTADDED);
if ($update) {
$toggle_item = new item(
$item->uid,
$this->order_id,
$item->position,
MODE_SWITCH,
0
);
$this->drop_item(
$item->position,
0
);
$this->add_item($toggle_item);
}
}
// Nur noch weniger Menge als im Bestand
if (CC_SITE_LOCKOUTOFSTOCK && $item->stockserver && $stock < $item->quantity) {
$item->quantity = $stock;
$messages[] = str_replace('[c]', $item->caption, CC_RESSOURCE_BASKET_OUTOFSTOCKQUANTITYMODIFIED);
}
if ($update)
$item->store();
}
if ($update)
return $messages;
else if (count($messages))
return false;
else
return true;
}
// Artikel und Anzahl im Korb anhand Formular aktualisieren
function calc_quantity() {
$updated = false;
$messages = array();
foreach (array_keys($this->items) as $k) {
$item = &$this->items[$k];
// Nicht für Artikel auf dem Merkzettel
if ($item->memo)
continue;
if (isset($_POST['quantity'.$item->position])) {
$item->new_quantity = post('quantity'.$item->position, CHECK_NUMVALUE);
$prev_quantity = $item->quantity;
$item->quantity = null;
$check = $item->check_quantity();
if ($item->quantity != $prev_quantity) {
if ($check) {
// gültige Menge
if ($message = $item->check_minmax())
$messages[] = $message;
// Aktuelle Bestands- und Statusdaten des Artikels einlesen
if ($item->stockserver) {
$stock_product = new stock_product($item->uid, $item->variationa ? $item->variationa : 1, $item->variationb ? $item->variationb : 1);
$stock = $stock_product->get();
}
// Falls nicht lieferbar auf Merkzettel setzen.
if (CC_SITE_LOCKOUTOFSTOCK && $item->stockserver && $stock <= 0) {
$messages[] = str_replace('[c]', $item->caption, CC_RESSOURCE_BASKET_OUTOFSTOCKNOTADDED);
$toggle_item = new item(
$item->uid,
$this->order_id,
$item->position,
MODE_SWITCH,
0
);
$this->drop_item(
$item->position,
0
);
$this->add_item($toggle_item);
}
// Nur noch weniger Menge als im Bestand
if (CC_SITE_LOCKOUTOFSTOCK && $item->stockserver && $stock < $item->quantity) {
$item->quantity = $stock;
$messages[] = str_replace('[c]', $item->caption, CC_RESSOURCE_BASKET_OUTOFSTOCKQUANTITYMODIFIED);
}
// Eco-Tax Anpassung Frankreich / Abhängige Artikel
if (CC_SITE_LOCALE_FR)
// Menge des abhängigen Artikels mit ändern
$this->update_belonging_items($item);
$item->store();
$updated = true;
} else if ($check === false) {
// Ungültige Menge
$messages[] = CC_RESSOURCE_BASKETNOQUANTITY;
} else {
// Menge 0 = aus Korb entfernen
$drop_position[] = $item->position;
$drop_memo[] = $item->memo;
}
} else
$item->new_quantity = null;
}
}
if (isset($drop_position))
for ($i = 0; $i < count($drop_position); $i++)
$this->drop_item($drop_position[$i], $drop_memo[$i]);
if (count($messages))
return $messages;
else if ($updated)
return array(CC_RESSOURCE_BASKETUPDATED);
return array();
}
//////////////////////////////////////////////////////////////////////////// Artikel
// Eco-Tax Anpassung Frankreich / Abhängige Artikel
// Menge des abhängigen Artikels mit ändern
function update_belonging_items($main_item) {
foreach (array_keys($this->items) as $k) {
$item = &$this->items[$k];
if ($item->position_main == $main_item->position &&
$item->memo == $main_item->memo) {
$item->quantity = $main_item->quantity;
$item->store();
break;
}
}
}
// Überprüft ob Artikel im Warenkorb liegt (nicht auf dem Merkzettel)
function contains_item($uid) {
foreach ($this->items as $item)
if ($item->uid == $uid && !$item->memo)
return true;
return false;
}
// Gibt Artikel zurück
function get_item($uid) {
foreach ($this->items as $item)
if ($item->uid == $uid)
return $item;
return false;
}
// Element aus Korb oder von Merkzettel entfernen
function drop_item($position, $memo) {
$new_items = array();
foreach ($this->items as $item) {
if ($item->position == $position && $item->memo == $memo ||
$item->position_main == $position && $item->memo == $memo) {
$item->delete();
} else
array_push($new_items, $item);
}
$this->items = $new_items;
}
// Ins Körbchen oder auf den Merkzettel legen
function add_item($item) {
global $myquantity;
$messages = array();
// Verfügbar?
if ($item->status == 0)
return ITEMSTATUS_NOTAVAILABLE;
else {
// Durschsuchen ob bereits im Warenkorb vorhanden
if ($item->check_quantity()) {
// Aktuelle Bestands- und Statusinformationen
if ($item->stockserver) {
$stock_product = new stock_product($item->uid, $item->variationa ? $item->variationa : 1, $item->variationb ? $item->variationb : 1);
$stock = $stock_product->get();
}
// Falls nicht lieferbar auf Merkzettel setzen.
if (CC_SITE_LOCKOUTOFSTOCK && $item->stockserver && $stock <= 0 && !$item->memo) {
$item->memo = 1;
$messages[] = str_replace('[c]', $item->caption, CC_RESSOURCE_BASKET_OUTOFSTOCKNOTADDED);
}
$found = -1;
for ($i = 0; $i < count($this->items); $i++) {
if ($this->items[$i]->uid == $item->uid &&
$this->items[$i]->variationa == $item->variationa &&
$this->items[$i]->variationb == $item->variationb &&
$this->items[$i]->memo == $item->memo &&
$this->items[$i]->specialinfo == $item->specialinfo) {
$found = $i;
}
}
// Falls nicht, neuen Artikel speichern
if ($found == -1) {
$found = count($this->items);
$this->items[] = &$item;
if ($message = $item->check_minmax())
$messages[] = $message;
if (CC_SITE_LOCKOUTOFSTOCK && $item->stockserver && $stock < $item->quantity && !$item->memo) {
// Nur noch weniger Menge als im Bestand
$messages[] = str_replace('[c]', $item->caption, CC_RESSOURCE_BASKET_OUTOFSTOCKQUANTITYMODIFIED);
$item->quantity = $stock;
}
$item->store($this->order_id);
$myquantity = $item->quantity;
return $messages;
// ansonsten bereits im Korb, aktualisieren
} else {
$this->items[$found]->quantity += $item->quantity;
// Nur noch weniger Menge als im Bestand
if (CC_SITE_LOCKOUTOFSTOCK && !$item->memo && $this->items[$found]->stockserver && $stock < $this->items[$found]->quantity) {
$this->items[$found]->quantity = $stock;
$messages[] = str_replace('[c]', $item->caption, CC_RESSOURCE_BASKET_OUTOFSTOCKQUANTITYMODIFIED);
}
if ($message = $this->items[$found]->check_minmax())
$messages[] = $message;
// Eco-Tax Anpassung Frankreich / Abhängige Artikel
if (CC_SITE_LOCALE_FR)
// Menge des abhängigen Artikels mit ändern
$this->update_belonging_items($this->items[$found]);
$this->items[$found]->store();
return $messages;
}
} else {
// Ungültige Menge
return ITEMSTATUS_INVALIDNUMBER;
}
}
}
//////////////////////////////////////////////////////////////////////////// Menge, Gewicht, Preis
// Anzahl Artikel im Warenkorb (nicht auf dem Merkzettel)
function get_quantity() {
$quantity = 0;
foreach ($this->items as $item)
// Eco-Tax Anpassung Frankreich / Abhängige Artikel
// Abhängige Artikel nicht mitzählen
if (!$item->position_main && !$item->memo)
$quantity += ($item->qprecision ? 1 : $item->quantity);
return $quantity;
}
// Anzahl Artikel auf dem Merkzettel
function get_memoquantity() {
$quantity = 0;
foreach ($this->items as $item)
// Eco-Tax Anpassung Frankreich / Abhängige Artikel
// Abhängige Artikel nicht mitzählen
if (!$item->position_main && $item->memo)
$quantity += ($item->qprecision ? 1 : $item->quantity);
return $quantity;
}
// Gewicht im Warenkorb (nicht auf dem Merkzettel)
function get_weight() {
$weight = 0;
foreach ($this->items as $item)
if (!$item->memo)
$weight += $item->weight * $item->quantity;
return $weight;
}
// Summe Artikel im Warenkorb (nicht auf dem Merkzettel)
function get_price() {
$price = 0;
foreach ($this->items as $item)
if (!$item->memo)
$price += round($item->price * $item->quantity, 2);
return max($price, 0);
}
// Summe rabattierbarer Artikel im Warenkorb (nicht auf dem Merkzettel)
function get_price_rebatable() {
$price = 0;
foreach ($this->items as $item)
if (!$item->memo && $item->rebatable)
$price += round($item->price * $item->quantity, 2);
return max(0, $price);
}
// Zwischensumme
function get_subtotal() {
return round($this->get_price(), 2);
}
// Tabattierbare Zwischensumme
function get_subtotal_rebatable() {
return round($this->get_price_rebatable(), 2);
}
// Rabatte berechnen (nicht Artikel auf dem Merkzettel)
function get_rebate() {
global $payment;
$subtotal = $this->get_subtotal();
$subtotal_rebatable = $this->get_subtotal_rebatable();
$rebate = 0;
// Summenrabatte
if ($this->sumrebate_amount === null)
$this->set_sumrebate();
if ($this->sumrebate_amount && $this->sumrebate_absolute)
$rebate += min($this->sumrebate_amount, $subtotal_rebatable);
else if ($this->sumrebate_amount)
$rebate += $subtotal_rebatable * $this->sumrebate_amount / 100;
// Kundenrabatte
if ($this->client) {
if ($this->client->rebate_amount && $this->client->rebate_absolute)
$rebate += min($this->client->rebate_amount, $subtotal_rebatable - $rebate);
else if ($this->client->rebate_amount)
$rebate += ($subtotal_rebatable - $rebate) * ($this->client->rebate_amount / 100);
}
// Gutscheinrabatte
if ($this->couponrebate_amount && $this->couponrebate_absolute)
$rebate += min($this->couponrebate_amount, $subtotal_rebatable - $rebate);
else if ($this->couponrebate_amount)
$rebate += ($subtotal_rebatable - $rebate) * ($this->couponrebate_amount / 100);
// Zahlweisenrabatt
if ($this->pm) {
if ($this->pm->rebate_amount && $this->pm->rebate_absolute)
$rebate += min($this->pm->rebate_amount, $subtotal_rebatable - $rebate);
else if ($this->pm->rebate_amount)
$rebate += ($subtotal_rebatable - $rebate) * ($this->pm->rebate_amount / 100);
}
return round($rebate, 2);
}
// Steuern im Warenkorb (nicht auf dem Merkzettel)
function get_totalvat() {
return $this->vatarray->get_total();
}
// Endsumme ohne Versand- oder Bezahlkosten
function get_subtotalprice() {
return $this->get_subtotal() - $this->get_rebate();
}
// Endsumme im Warenkorb (nicht auf dem Merkzettel)
function get_totalprice() {
$totalprice = $this->get_subtotal() - $this->get_rebate() + $this->get_shipping_cost() + $this->get_payment_cost();
if ($this->b2b)
$totalprice += $this->get_totalvat();
return round($totalprice, 2);
}
// Versandkosten berechnen
function get_shipping_cost() {
global $shipping;
if ($this->sm === null) {
$shipping->calc_prices($this);
$this->sm = $shipping->get($this->client->shipping_uid);
$shipping_cost = 0;
if ($this->sm->actualprice > 0) {
if ($this->sm->perpiece)
$shipping_cost = $this->sm->actualprice * $this->get_quantity();
else
$shipping_cost = $this->sm->actualprice;
}
$this->sm->total = $shipping_cost;
return $shipping_cost;
} else
return $this->sm->total;
}
// Bezahlkosten berechnen
function get_payment_cost() {
global $payment;
if ($this->pm->total === null) {
$payment_cost = 0;
if ($this->pm->actualprice !== null)
$payment_cost = $this->pm->actualprice;
else {
if ($this->pm->amount && $this->pm->absolute)
$payment_cost += $this->pm->amount;
else if ($this->pm->amount)
$payment_cost += $this->get_subtotal() * $this->pm->amount / 100;
}
$this->pm->total = $payment_cost;
return $payment_cost;
} else
return $this->pm->total;
}
// Summenrabatte errechnen
function set_sumrebate() {
// Summenrabattstaffel auslesen
function get_sumrebateinfo($subtotal) {
global $sumrebate_from, $sumrebate_amount, $sumrebate_absolute;
for ($i = 5; $i >= 1; $i--) {
if (isset($sumrebate_from[$i])) {
if ($subtotal >= $sumrebate_from[$i])
return array($sumrebate_amount[$i], $sumrebate_absolute[$i]);
}
}
return array(0, 0);
}
$info = get_sumrebateinfo($this->get_subtotal_rebatable());
$this->sumrebate_amount = $info[0];
$this->sumrebate_absolute = $info[1];
}
//////////////////////////////////////////////////////////////////////////// Datenbankl
// Key zum Drucken der Bestellung (wegen Zugang ohne Konto)
function generate_key() {
return md5($this->order_time.$this->order_date.$this->client->password.$this->order_id);
}
// Rechnungsnummer generieren und Datum setzen
function set_bill_data() {
$bill_id = new abstractdb(TABLE_BILLIDS);
if (!$bill_id->db_numrows()) {
$bill_id->bill_id = max(1, CC_SITE_STARTBILLID);
$bill_id->store(true);
} else
$bill_id->bill_id = $bill_id->generate_id();
$this->bill_id = $bill_id->bill_id;
$this->bill_id_prefix = CC_SITE_PREFIXBILLID;
$this->bill_date = date("Y-m-d");
}
// Auftragsnummer generieren und Datum setzen
function set_order_data() {
if (CC_SITE_STARTORDERID) {
$order_id = new abstractdb(TABLE_ORDERIDS);
if (!$order_id->db_numrows()) {
$order_id->order_id = max(1, CC_SITE_STARTORDERID);
$order_id->store(true);
} else
$order_id->order_id = $order_id->generate_id();
$this->order_id = $order_id->order_id;
} else {
list($usec, $sec) = explode(" ", microtime());
$usec = floor((float) $usec * 1000);
$this->order_id = substr($usec.strrev($sec), 0, 9);
}
$this->order_id_prefix = CC_SITE_PREFIXORDERID;
$this->order_date = date("Y-m-d");
$this->order_time = date("H:i:s");
}
// Bestellung zum Speichern kreieren
function create($session) {
$this->set_order_data();
$this->shipping_cost = $this->get_shipping_cost();
if ($this->get_payment_cost()) {
$this->payment_amount = $this->pm->amount;
} else {
$this->payment_amount = 0;
}
$this->payment_absolute = $this->pm->absolute;
$this->paymentrebate_amount = $this->pm->rebate_amount;
$this->paymentrebate_absolute = $this->pm->rebate_absolute;
// PDF Erstellung
$has_esd = false;
foreach ($this->items as $item)
if ($item->download_uid && !$item->memo)
$has_esd = true;
$this->pdf_creation = $has_esd ? $this->pm->pdf_creation_esd : $this->pm->pdf_creation;
$this->shipping_vat = $this->sm->vat;
$this->payment_vat = $this->pm->vat;
$this->shipping_caption = $this->sm->caption;
if ($this->sm->parameter)
$this->shipping_param = $this->sm->parameter;
if ($this->sm->trackingurl)
$this->shipping_trackingurl = $this->sm->trackingurl;
$this->payment_caption = $this->pm->caption;
if ($this->pm->parameter[0])
$this->payment_param = $this->pm->parameter[0];
$this->search_email = $this->client->email;
$this->search_name = $this->client->firstname.' '.$this->client->lastname;
$this->affiliate_id = $session->affiliate_id or null;
$this->affiliate_subid = $session->affiliate_subid or null;
$session->unset_affiliate();
// Gutschein einlösen
if ($this->coupon) {
if ($this->coupon->mode == COUPONMODE_COUPON) {
$this->coupon->order_id = $this->order_id;
$this->coupon->client_id = $this->client->client_id;
$this->coupon->store();
}
$this->client->coupon_id = null;
$this->client->store();
}
// Bestandskontrolle und Artikel mit Bestellnummer versehen, nicht mehr benötigte Felder nullen
foreach ($this->items as $item) {
if ($item->memo)
continue;
if ($item->stockserver) {
$product = new stock_product($item->uid, $item->variationa ? $item->variationa : 1, $item->variationb ? $item->variationb : 1);
$product->dec($item->quantity);
}
$item->change_order_id($this->order_id);
$item->order_status = CC_RESSOURCE_ORDERSTATUSSHORT_NEW;
$item->position_main = null;
$item->noship = null;
$item->rebate = null;
$item->minimum = null;
$item->maximum = null;
$item->stockserver = null;
$item->variationa = 0;
$item->variationb = 0;
if ($item->download_uid)
$item->download_count = 0;
if ($item->uid == 'custom')
$item->store(true);
$item->store();
}
}
// Setz den Status und ggf. Datum Geldeingang oder Versand
function set_status($status, $set_items) {
$old_status = $this->status;
if ($status < CC_RESSOURCE_ORDERSTATUSSHORT_NEW || $status > CC_RESSOURCE_ORDERSTATUSSHORT_SHIPPED)
return false;
// Artikel setzen
if ($set_items) {
$downloads = 0;
foreach ($this->items as $item) {
$item->order_status = $status;
// Bei digitalen Gütern Status direkt auf abgeschlossen setzen
if ($status == CC_RESSOURCE_ORDERSTATUSSHORT_WAITINGITEMS && $item->download_uid) {
$item->order_status = CC_RESSOURCE_ORDERSTATUSSHORT_SHIPPED;
$downloads++;
}
$item->store();
}
// Falls ausschliesslich digitale Güter, auch Bestellstatus auf abgeschlossen setzen
if ($downloads == count($this->items))
$status = CC_RESSOURCE_ORDERSTATUSSHORT_SHIPPED;
}
if ($this->status <= CC_RESSOURCE_ORDERSTATUSSHORT_WAITINGPAYMENT && $status >= CC_RESSOURCE_ORDERSTATUSSHORT_WAITINGITEMS)
$this->payment_date = date("Y-m-d");
else if ($status <= CC_RESSOURCE_ORDERSTATUSSHORT_WAITINGPAYMENT)
$this->payment_date = null;
if ($this->status <= CC_RESSOURCE_ORDERSTATUSSHORT_MANUFACTURING && $status >= CC_RESSOURCE_ORDERSTATUSSHORT_SHIPPED)
$this->shipping_date = date("Y-m-d");
else if ($status <= CC_RESSOURCE_ORDERSTATUSSHORT_MANUFACTURING)
$this->shipping_date = null;
$this->status = $status;
$this->store();
if ($old_status != $this->status)
return true;
else
return false;
}
function send_status_email($pdf_email = false) {
if (!CC_SITE_STATUSEMAILS && !$pdf_email)
return;
// Nicht bei Bestellung eingegangen
if (!$this->status || ($this->status == CC_RESSOURCE_ORDERSTATUSSHORT_NEW && !$pdf_email))
return;
// Template Variablen einlesen
$active = false;
foreach(file(CC_INCLUDE_OSTEMPLATES) as $line) {
$line = trim($line);
if (strlen($line)) {
if ($active) {
if (preg_match("/^\[.*\]$/", $line)) {
if (!preg_match("/^\[Template-Variables-.*\]$/", $line))
$active = false;
} else if (preg_match("/^([a-z_]+)=(.*)$/", $line, $found))
$mailtemplate_vars[$found[1]] = $found[2];
else if (!preg_match("/^;/", $line, $found))
die('Error in file '.CC_INCLUDE_OSTEMPLATES.', unknown command "'.$line.'".');
} else if (preg_match("/^\[Template-Variables-.*\]$/", $line))
$active = true;
}
}
$mailtemplate = new abstractdb(TABLE_TEMPLATES);
$mailtemplate = $mailtemplate->get(array('*'), array('status' => $pdf_email ? $pdf_email : $this->status), null);
// Vorlagenvariablen
foreach ($mailtemplate_vars as $key => $var) {
$orig[] = '/{'.$var.'}/';
if ($key == 'country')
$repl[] = substr($this->client->$key, 11);
else if ($key == 'signature')
$repl[] = str_replace('
', "\n", CC_SITE_SHOPADDRESS);
else if (strstr($key, '_date'))
$repl[] = $this->$key ? date(CC_SITE_DATEFORMAT, strtotime($this->$key)) : '';
else if (in_array($key, array('order_id', 'order_id_prefix', 'tracking_id', 'message', 'expected_date')))
$repl[] = $this->$key ? $this->$key : '';
else if ($key == 'shipping_trackingurl')
$repl[] = CC_SITE_HTTPURL . clean_url($this->$key);
else
$repl[] = $this->client->$key;
}
// Email füllen
$email = new email();
$email->order_id = $this->order_id;
$email->client_id = $this->client->client_id;
$email->to_plain = $this->client->firstname.' '.$this->client->lastname;
$email->from_email = CC_SITE_MAILFROM;
$email->from_plain = CC_SITE_MAILNAME;
$email->to_email = $this->client->email;
$email->subject = $mailtemplate->subject;
$email->content_plain = preg_replace($orig, $repl, $mailtemplate->body);
$orig[] = "/\n/";
$repl[] = "
";
$email->content_html = preg_replace($orig, $repl, $mailtemplate->body);
// Ggf. Rechnung anhängen
if (($pdf_email || $this->status == CC_RESSOURCE_ORDERSTATUSSHORT_SHIPPED && $this->pdf_creation == PDF_CREATION_ONSHIPP) && !CC_SITE_BILLHASLEFTTHEBUILDING) {
include_once(CC_BLOGIC_PDFDOC);
$pdfdoc = new pdfdoc(CC_SITE_FILEKEY, DOCS, $this);
$pdfdoc->verify($pdfdoc->MODE_BILL);
$pdf['filename'] = $pdfdoc->filename($pdfdoc->MODE_BILL);
$pdf['name'] = $pdfdoc->name($pdfdoc->MODE_BILL);
$email->pdf = $pdf;
}
$email->store();
if ($this->message) {
$this->message = null;
$this->store();
}
}
function send_confirmation_emails() {
// HTML-Mail vorbereiten
$html_template = new template(CC_TPL_SUMMARY);
$html_template->show('email');
$html_template->assign(array(
'_shopaddress' => CC_SITE_SHOPADDRESS,
'_pm_email' => $this->pm->email,
));
require(CC_SHOPSCRIPT_OUTPUTFUNCTIONS);
generate_summary($html_template, $this, true);
// Text-Mail vorbereiten
$text_template = new template(CC_TPL_SUMMARYPLAIN);
generate_summary($text_template, $this, true);
$text_template->assign(array(
'_shopaddress' => str_replace('
', "\r\n", CC_SITE_SHOPADDRESS),
'_pm_email' => $this->pm->email,
));
// Email Bestätigung an Betreiber
$email = new email();
$email->order_id = $this->order_id;
$email->client_id = $this->client->client_id;
$email->to_email = CC_SITE_MAILCOPY;
$email->from_email = CC_SITE_MAILFROM;
$email->from_plain = CC_SITE_MAILNAME;
$email->subject = 'FWD: '.CC_SITE_MAILSUBJECT;
$email->content_html = $html_template->getparsed();
$email->content_plain = strip_tags($text_template->getparsed());
// PDF Auftragsbestätigung oder Rechnung
// Direkt Rechnung
$pdf = array();
if ($this->pdf_creation == PDF_CREATION_ONORDER) {
include_once(CC_BLOGIC_PDFDOC);
$pdfdoc = new pdfdoc(CC_SITE_FILEKEY, DOCS, $this);
$pdfdoc->verify($pdfdoc->MODE_BILL);
$pdf['filename'] = $pdfdoc->filename($pdfdoc->MODE_BILL);
$pdf['name'] = $pdfdoc->name($pdfdoc->MODE_BILL);
// Erstmal Auftragsbestätigung
} else if ($this->pdf_creation == PDF_CREATION_ONSHIPP) {
include_once(CC_BLOGIC_PDFDOC);
$pdfdoc = new pdfdoc(CC_SITE_FILEKEY, DOCS, $this);
$pdfdoc->verify($pdfdoc->MODE_CONFIRMATION);
$pdf['filename'] = $pdfdoc->filename($pdfdoc->MODE_CONFIRMATION);
$pdf['name'] = $pdfdoc->name($pdfdoc->MODE_CONFIRMATION);
}
$email->pdf = CC_SITE_BILLHASLEFTTHEBUILDING ? null : $pdf;
if (CC_SITE_MAILCOPY)
$email->store();
// Email an Kunden
$email->to_email = $this->client->email;
$email->to_plain = $this->client->firstname." ".$this->client->lastname;
$email->subject = CC_SITE_MAILSUBJECT;
$email->store();
}
// Kunde über Lizenzvergabe informieren
function send_license_mail($hk, $comment, $caption, $date, $ressource) {
$email = new email();
$email->order_id = $this->order_id;
$email->client_id = $this->client->client_id;
$email->to_plain = $this->client->firstname." ".$this->client->lastname;
$email->to_email = $this->client->email;
$email->from_email = CC_SITE_MAILFROM;
$email->from_plain = CC_SITE_MAILNAME;
$email->subject = CC_RESSOURCE_LICENSEMAILSUBJECT;
$email->content_plain = $ressource;
$email->content_plain = str_replace('[br]', "\n", $email->content_plain);
$email->content_plain = str_replace('[s]', $this->client->salutation, $email->content_plain);
$email->content_plain = str_replace('[fn]', $this->client->firstname, $email->content_plain);
$email->content_plain = str_replace('[ln]', $this->client->lastname, $email->content_plain);
$email->content_plain = str_replace('[i]', $caption, $email->content_plain);
$email->content_plain = str_replace('[od]', date(CC_SITE_DATEFORMAT, strtotime($this->order_date)), $email->content_plain);
$email->content_plain = str_replace('[ld]', date(CC_SITE_DATEFORMAT, strtotime($date)), $email->content_plain);
$email->content_plain = str_replace('[h]', $hk, $email->content_plain);
$email->content_plain = str_replace('[c]', $comment, $email->content_plain);
$email->content_plain = str_replace('[sa]', str_replace('
', "\n", CC_SITE_SHOPADDRESS), $email->content_plain);
$email->store();
}
//////////////////////////////////////////////////////////////////////////// Datenbank
// Bestellungen holen
function get($fields, $where, $order = null, $page = null, $perpage = null) {
return $this->db_get($fields, $where, $order, $page, $perpage);
}
// Bestellungen holen mit join
function getjoin($fields, $where = null, $order = null, $page, $perpage) {
if (!$this->is_result()) {
$from = $perpage * ($page - 1);
$this->db_selectjoin($fields, 'clients', 'order_id', $where, $order, $from, $perpage);
}
$object = $this->db_fetch();
if (!$object) {
$this->db_free();
return $object;
} else {
foreach(get_object_vars($object) as $k => $v) {
$new_k = substr($k, (strpos($k, '.') ? strpos($k, '.') + 1 : 0));
$new_object->$new_k = $v;
}
return $new_object;
}
}
// Bestellung speichern
function store($mode = false) {
$this->generate_change_id();
if ($mode)
$this->db_insertobject();
else
$this->db_updateobject();
}
// Bestellung löschen
function delete() {
$this->db_delete(array('order_id' => $this->order_id));
$this->client->delete();
foreach ($this->items as $item)
$item->delete();
$deleted_ids = new abstractdb(TABLE_DELETED);
$deleted_ids->order_id = $this->order_id;
$this->generate_change_id();
$deleted_ids->change_id = $this->change_id;
$deleted_ids->store(true);
return $this->change_id;
}
}
////////////////////////////////////////////////////////////////////////////
// Klasse Steuern
class vat {
var $percent; // Prozentsatz
var $amount; // Betrag
function vat() {
}
}
// Klasse Steuerfeld
class vatarray {
var $vatarray = array();
var $index = null;
var $b2b;
function vatarray($b2b, $novat) {
$this->b2b = $b2b;
$this->novat = $novat;
}
// Zufügen zum Feld
function add($rate, $price) {
if ($price) {
$found = -1;
for ($i = 0; $i < count($this->vatarray); $i++) {
if ($this->vatarray[$i]->percent == $rate)
$found = $i;
}
if ($found == -1) {
$found = count($this->vatarray);
$vat = new vat();
$vat->percent = $rate;
$vat->amount = 0;
$this->vatarray[] = $vat;
}
if ($this->b2b)
$this->vatarray[$found]->amount += $price * $rate / 100;
else
$this->vatarray[$found]->amount += $price / (100 + $rate) * $rate;
}
}
// Feld sortieren
function sort() {
uasort($this->vatarray, 'sort_vat');
}
// Gesamtsteurn berechnen
function get_total() {
if ($this->novat)
return 0;
$totalvat = 0;
foreach (array_keys($this->vatarray) as $k)
$totalvat += round($this->vatarray[$k]->amount, 2);
return round($totalvat, 2);
}
}
// Callback Funktion zum Sortieren des Steuerfeldes
function sort_vat($a, $b) {
return $a->percent - $b->percent;
}
?>