assets/s2diitem.php /// Art: Shop Business Logic /// Inhalt: Klasse special_product, Klasse stock_product, Klasse item /// Beschreibung: Business Logic rund um Artikel /// Benötigt: config.php, db.php /// CCML-Parsing: nein /// ////////////////////////////////////////////////////////////////////////////////////////// /// /// Letzte Änderungen: /// 19.02.2009 Lizenzemail Bugfix Name /// 25.02.2009 Gesamtsummer der Spezialpreise bei Profuktkonfiguration nie kleiner 0 /// 20.03.2009 Korrektur Bestandsverwaltung /// 24.03.2009 Erweiterung Bestandsverwaltung /// 21.09.2009 Korrektur Spezialeingeschaften/Varianten /// 22.09.2009 split -> explode /// 06.10.2009 U.B. neues ProtectDisc Webservice Handling auf DB Server /// 02.11.2009 Linzenzen Link angepasst /// 09.12.2009 Rabattsperre hinzugefügt /// 23.01.2010 ESD Änderungen Uwe Braun eingefügt -> ESDUB /// 10.03.2010 Bestelloptionen /// ////////////////////////////////////////////////////////////////////////////////////////// ///<10.03.2010/7.0.0.11/> if (!defined('SHOP_TO_DATE')) die('Forbidden'); // Klasse Produkt auf dem Server für Bestandsinfo class stock_product extends db { var $id = ''; var $stock = 0; var $live = null; // Konstruktor läd Daten function stock_product($id, $variationa = 1, $variationb = 1) { $this->db(TABLE_STOCK); $this->db_selectobject(array( 'id' => $id, 'variationa' => $variationa, 'variationb' => $variationb, )); if (!$this->live) { $this->id = $id; $this->variationa = $variationa; $this->variationb = $variationb; } } // Bestand einer Variation abfragen function get($variationa = 0, $variationb = 0) { return $this->stock ? floatval($this->stock) : 0; } // Bestand einer Variation setzen function set($num) { $this->stock = $num; $this->store(); } // Bestand einer Aariation um x erhöhen function inc($num) { $this->stock += $num; $this->store(); } // Bestand einer Variation um x veringern function dec($num) { $this->stock -= $num; $this->store(); } // Speichern function store() { if ($this->live) $this->db_update(array( 'stock' => $this->stock, ), array( 'id' => $this->id, 'variationa' => $this->variationa, 'variationb' => $this->variationb, )); else $this->db_insertobject(); } } //////////////////////////////////////////////////////////////////////////// define('MODE_PREFILL', 1); define('MODE_POSTFILL', 2); define('MODE_SWITCH', 5); // Eco-Tax Anpassung Frankreich define('MODE_ECOTAXPREFILL', 3); define('MODE_ECOTAXPOSTFILL', 4); // Klasse Artikel class item extends db { // Eigenschaften in der DB var $order_id; // Bestellnummer bzw. vor Abschluss der Bestellung session_id var $order_status = null; // Wichtig nur nach Bestellung var $uid = ''; // Wichtig auch nach Bestellung var $position; // Wichtig als Unterscheidungskriterium var $position_main = null; // Wichtig als Unterscheidungskriterium, aber nicht nach der Bestellung var $id = null; // Wichtig auch nach Bestellung var $quantity = 0; // Wichtig auch nach Bestellung var $qprecision = 0; // Wichtig auch nach Bestellung var $caption = ""; // Wichtig auch nach Bestellung var $price = 0; // Wichtig auch nach Bestellung var $vat = 0; // Wichtig auch nach Bestellung var $rebatable = 1; // Wichtig auch nach Bestellung var $url = ""; // Wichtig auch nach Bestellung var $unit = ""; // Wichtig auch nach Bestellung var $noship = null; var $weight = 0; // Wichtig auch nach Bestellung var $rebate; // Rabattstaffel var $status = 0; var $minimum = null; var $maximum = null; var $variationa_caption = null; // Wichtig auch nach Bestellung var $variationb_caption = null; // Wichtig auch nach Bestellung var $variationa = 0; var $variationb = 0; var $stockserver = 0; var $stock; var $specialinfo = null; // Konfigurierbare Produkte Info als // Wichtig auch nach Bestellung var $new_quantity = null; var $download_uid = null; // Wichtig auch nach Bestellung var $download_pid = null; // Wichtig auch nach Bestellung var $download_filename = null; // Wichtig auch nach Bestellung var $download_count = null; // Wichtig nur nach Bestellung var $memo = false; // Konstruktoor übernimmt Daten von POST, füllt Vorgefüllten Korb oder läd Artikel aus der DB function item($uid = null, $order_id = null, $position = null, $mode = null, $memo = 0, $quantity = 1) { $this->db(TABLE_ITEMS); $this->uid = $uid; $this->order_id = $order_id; $this->position = $position; $this->memo = $memo; if ($mode === MODE_PREFILL) $this->prefill(); else if ($mode === MODE_POSTFILL) { ///MO44+ ///MO44-< $this->postfill($order_id, $quantity); ///MO44> } else if ($this->uid) { $this->db_selectobject(array( 'uid' => $this->uid, 'order_id' => $this->order_id, 'position' => $this->position, 'memo' => $memo, )); // Eco-Tax Anpassung Frankreich } else if ($mode === MODE_ECOTAXPREFILL) $this->ecotaxprefill($position); else if ($mode === MODE_ECOTAXPOSTFILL) $this->ecotaxpostfill($position); if (!$this->position) { $obj = $this->db_selectone(array('max(position) as pos'), array('order_id' => $this->order_id)); if ($obj) $this->position = $obj->pos + 1; else $this->position = 1; } if ($mode === MODE_SWITCH) $this->memo = $this->memo ? 0 : 1; format::to_abs($this, array('variationa', 'variationb', 'qprecision', 'status', 'stockserver')); format::to_float($this, array('price', 'vat', 'weight'), 2); format::to_float($this, array('quantity', 'minimum', 'maximum'), $this->qprecision); } // Füllung des Warenkorbs durch Formular Übermittlung function postfill($order_id = null, $quantity) { global $myspecialinfo_id; $this->variationa = $va = is_post('variationa'.$this->uid) ? post('variationa'.$this->uid) : 0; $this->variationb = $vb = is_post('variationb'.$this->uid) ? post('variationb'.$this->uid) : 0; if (!file_exists($product_file = DBPATH.$this->uid.'.'.CC_SITE_SCRIPTEXTENSION)) die('No such item '.$product_file); include($product_file); // Konfigurierbare Produkte $specialprice = 0; if ($product_data->has_configuration) { $specials = array(); foreach($product_data->configuration as $special) { if ($value = post("specialvalue".$special->number)) { if ($special->type == PRODUCT_CONFIG_COMBO) $specials[] = rawurlencode($special->caption).'='.rawurlencode($special->options_caption[$value]); else $specials[] = rawurlencode($special->caption).'='.rawurlencode($value); if ($special->type == PRODUCT_CONFIG_COMBO) $specialprice += $special->options_price[$value]; else if ($special->type == PRODUCT_CONFIG_CHECK) $specialprice += $special->price; } } } // Ohne Varianten if ($product_data->variations == 0) { $this->id = $product_data->id; $this->weight = $product_data->weight; $this->status = $product_data->status; $this->stockserver = $product_data->stockserver; $this->stock = $product_data->stock; $this->price = $product_data->price; $this->variationa_caption = null; $this->variationb_caption = null; $this->caption = $product_data->caption; for($i = 1; $i <= 5; $i++) $rebate_sheme[] = $product_data->rebatefrom[$i].'='.($product_data->rebateprice[$i] + $specialprice); // Eine Variante } else if ($product_data->variations == 1) { $this->id = $product_data->id[$va]; $this->weight = $product_data->weight[$va]; $this->status = $product_data->status[$va]; $this->stockserver = $product_data->stockserver[$va]; $this->stock = $product_data->stock; $this->price = $product_data->price[$va]; $this->variationa_caption = $product_data->variationacaption[$va]; $this->variationb_caption = null; $this->caption = $product_data->caption. ' ('.$product_data->attributeacaption.': '.$this->variationa_caption.')'; for($i = 1; $i <= 5; $i++) $rebate_sheme[] = $product_data->rebatefrom[$va][$i].'='.($product_data->rebateprice[$va][$i] + $specialprice); // Zwei Varianten } else if ($product_data->variations == 2) { $this->id = $product_data->id[$va][$vb]; $this->weight = $product_data->weight[$va][$vb]; $this->status = $product_data->status[$va][$vb]; $this->stockserver = $product_data->stockserver[$va][$vb]; $this->stock = $product_data->stock; $this->price = $product_data->price[$va][$vb]; $this->variationa_caption = $product_data->variationacaption[$va]; $this->variationb_caption = $product_data->variationbcaption[$vb]; $this->caption = $product_data->caption. ' ('.$product_data->attributeacaption.': '.$this->variationa_caption. ', '.$product_data->attributebcaption.': '.$this->variationb_caption.')'; for($i = 1; $i <= 5; $i++) $rebate_sheme[] = $product_data->rebatefrom[$va][$vb][$i].'='.($product_data->rebateprice[$va][$vb][$i] + $specialprice); } // Allgemeine Produkteigenschaften $this->rebate = implode("\n", $rebate_sheme); $this->qprecision = $product_data->qprecision; $this->vat = $product_data->vat; $this->rebatable = $product_data->rebatable; $this->url = $product_data->url; $this->unit = $product_data->unit; $this->noship = $product_data->noship ? $product_data->noship : null; $this->minimum = $product_data->minimum > 0 ? $product_data->minimum : null; $this->maximum = $product_data->maximum > 0 ? $product_data->maximum : null; // Konfigurierbare Produkte if ($product_data->has_configuration) { if (count($specials)) { $this->specialinfo = implode("\n", $specials); $this->caption .= ' ('.CC_RESSOURCE_PRODUCTCONFIGURED.')'; $obj = $this->db_selectone(array('position'), array( 'uid' => $this->uid, 'order_id' => $this->order_id, 'specialinfo' => $this->specialinfo, 'variationa' => $this->variationa, 'variationb' => $this->variationb, )); if ($obj) $this->position = $obj->position; } $this->price = max(0, $this->price + $specialprice); } // Digitale Güter if ($product_data->esd) { $this->download_uid = $product_data->downloaduid; $this->download_pid = $product_data->protectid; $this->download_filename = $product_data->downloadfilename; } else { $this->download_uid = null; $this->download_pid = null; $this->download_filename = null; } $this->quantity = null; $this->new_quantity = $quantity; } // Vorgefüllter Warenkorb function prefill() { $this->uid = CC_SITE_PREFILL_UID; $this->id = strlen(CC_SITE_PREFILL_ID) ? CC_SITE_PREFILL_ID : null; $this->qprecision = CC_SITE_PREFILL_PRECISION; $this->caption = CC_SITE_PREFILL_CAPTION; $this->price = CC_SITE_PREFILL_PRICE; $this->normalprice = CC_SITE_PREFILL_PRICE; $this->vat = CC_SITE_PREFILL_VAT; $this->url = CC_SITE_PREFILL_URL; $this->unit = CC_SITE_PREFILL_UNIT; $this->noship = strlen(CC_SITE_PREFILL_NOSHIP) ? CC_SITE_PREFILL_NOSHIP : null; $this->weight = CC_SITE_PREFILL_WEIGHT; $this->status = 1; $this->minimum = floatval(CC_SITE_PREFILL_MINIMUM) > 0 ? CC_SITE_PREFILL_MINIMUM : null; $this->maximum = floatval(CC_SITE_PREFILL_MAXIMUM) > 0 ? CC_SITE_PREFILL_MAXIMUM : null; $this->variationa = 0; $this->variationb = 0; $this->variationa_caption = null; $this->variationb_caption = null; $this->stockserver = CC_SITE_PREFILL_STOCKSERVER; $this->quantity = CC_SITE_PREFILL_DEFAULTQUANTITY; // Eco Tax Anpassung Frankreich if (CC_SITE_LOCALE_FR) { $this->ecotax_amount = floatval(CC_PREFILL_ECOTAX_AMOUNT); $this->ecotax_vat = floatval(CC_PREFILL_ECOTAX_VAT); $this->ecotax_provider = floatval(CC_PREFILL_ECOTAX_PROVIDER); } // Digitale Güter if (defined('CC_SITE_PREFILL_DOWNLOAD_UID')) { $this->download_uid = CC_SITE_PREFILL_DOWNLOAD_UID; $this->download_pid = CC_SITE_PREFILL_DOWNLOAD_PID; $this->download_filename = CC_SITE_PREFILL_DOWNLOAD_FILENAME; } $this->quantity = CC_SITE_PREFILL_DEFAULTQUANTITY; } // Eco Tax Anpassung Frankreich function ecotaxpostfill() { global $myquantity; $this->uid = post('uid', CHECK_ALPHANUM).'eco'; $this->position = time(); $this->caption = str_replace('[p]', post('ecotaxprovider'), CC_RESSOURCE_ECOTAX); $this->price = floatval(post('ecotaxamount', CHECK_REALNUMVALUE)); $this->vat = floatval(post('ecotaxvat', CHECK_REALNUMVALUE)); $this->status = post('status', CHECK_NUM); $this->variationa = is_post('variationa') ? post('variationa') : 0; $this->variationb = is_post('variationb') ? post('variationb') : 0; $this->new_quantity = $myquantity; $this->quantity = null; } // Eco Tax Anpassung Frankreich function ecotaxprefill() { $this->uid = CC_SITE_PREFILL_UID.'eco'; $this->uid_main = CC_SITE_PREFILL_UID; $this->caption = str_replace('[p]', CC_PREFILL_ECOTAX_PROVIDER, CC_RESSOURCE_ECOTAX); $this->price = floatval(CC_PREFILL_ECOTAX_AMOUNT); $this->vat = floatval(CC_PREFILL_ECOTAX_VAT); $this->status = 1; $this->new_quantity = CC_SITE_PREFILL_DEFAULTQUANTITY; } //////////////////////////////////////////////////////////////////////////// // Prüft und formatiert gültige Nachkommastellen function check_quantity() { // Beim schieben zwischen Warenkorb und Merkzettel, keine Parsung if ($this->quantity) return $this->quantity; if ($this->qprecision) { if (!preg_match('/^\d+('.CC_SITE_DECIMALSEPARATOR.'\d{1,'.$this->qprecision.'})?$/', $this->new_quantity)) { $this->quantity = 0; return false; } $this->quantity = round(floatval(str_replace(CC_SITE_DECIMALSEPARATOR, '.', $this->new_quantity)), $this->qprecision); } else { if (preg_match('/[^\d]/', $this->new_quantity)) { $this->quantity = 0; return false; } $this->quantity = floor(floatval($this->new_quantity)); } $this->new_quantity = null; return $this->quantity; } // Maximum und Minumum checken function check_minmax() { $message = ''; // Bei downloadbaren Artikel Menge immer 1 if ($this->quantity != 1 && $this->download_uid) { $this->quantity = 1; $message = CC_RESSOURCE_BASKETMAX; $message = str_replace('[n]', format::quantity(1, $this->qprecision), $message); $message = str_replace('[u]', $this->unit, $message); $message = str_replace('[c]', $this->caption, $message); $message = str_replace('[s]', format::quantity($this->quantity, $this->qprecision), $message); // Zu viel? } else if (($this->quantity > $this->maximum) && $this->maximum && $this->quantity ) { $this->quantity = $this->maximum; $message = CC_RESSOURCE_BASKETMAX; $message = str_replace('[n]', format::quantity($this->maximum, $this->qprecision), $message); $message = str_replace('[u]', $this->unit, $message); $message = str_replace('[c]', $this->caption, $message); $message = str_replace('[s]', format::quantity($this->quantity, $this->qprecision), $message); // Zu wenig? } else if (($this->quantity < $this->minimum) && $this->minimum && $this->quantity || $this->quantity < 0) { $this->quantity = $this->minimum; $message = CC_RESSOURCE_BASKETMIN; $message = str_replace('[n]', format::quantity($this->minimum, $this->qprecision), $message); $message = str_replace('[u]', $this->unit, $message); $message = str_replace('[c]', $this->caption, $message); $message = str_replace('[s]', format::quantity($this->quantity, $this->qprecision), $message); // Ausserhalb des Wertebereichs? } else if ($this->quantity > 9999.999) { $this->quantity = 9999; if ($this->qprecision == 1) $this->quantity += 0.9; else if ($this->qprecision == 2) $this->quantity += 0.99; else if ($this->qprecision == 3) $this->quantity += 0.999; $mode = 1; $message = CC_RESSOURCE_BASKETMAX; $message = str_replace('[n]', format::quantity($this->quantity, $this->qprecision), $message); $message = str_replace('[u]', $this->unit, $message); $message = str_replace('[c]', $this->caption, $message); $message = str_replace('[s]', format::quantity($this->quantity, $this->qprecision), $message); } return $message; } // Berechnung von Mengenrabatten function calc_quantrebate() { if ($this->rebate) { $rebate_from = array(); $rebate_price = array(); foreach(explode("\n", $this->rebate) as $rebates) { $pair = explode('=', $rebates); array_push($rebate_from, round(floatval($pair[0]), $this->qprecision)); array_push($rebate_price, round(floatval($pair[1]), 2)); } for ($i = 0; $i < 5; $i++) if ($rebate_from[$i] > 0 && $this->quantity >= $rebate_from[$i]) $this->price = $rebate_price[$i]; $this->rebate = null; } } // Preis holen function get_price() { return $this->price; } // Gesamtpreis (Menge) function get_priceall() { return round($this->price * $this->quantity, 2); } //////////////////////////////////////////////////////////////////////////// Lizenzvergabe ESD // Lizenz schwebend, Shop betreiber informieren function license_pending($myorder, $hk, $comment) { $license = new abstractdb(TABLE_ESDLICENSES); $license->id = $this->download_uid; $license->order_id = $myorder->order_id; $license->date = date("Y-m-d H:i:s"); $license->hardware_id = $hk; $license->client_comment = $comment; $license->license_pending = LICENSE_PENDING; $license->store(true); // Shopbetreiber informieren $url_client = CC_SITE_HTTPURL.clean_url(CC_URL_OSCLIENTS).'?'.PARAMETER_MODE.'=id&'.PARAMETER_STATUS.'='.$myorder->client->client_id; $url_order = CC_SITE_HTTPURL.clean_url(CC_URL_OSORDERS).'?'.PARAMETER_MODE.'=id&'.PARAMETER_STATUS.'='.$myorder->order_id; $url_license = CC_SITE_HTTPURL.clean_url(CC_URL_OSDOWNLOADS).'?'.PARAMETER_ID.'='.$this->download_uid.'&'.PARAMETER_ORDER.'='.$myorder->order_id; $all_licenses = new abstractdb(TABLE_ESDLICENSES); while($lic = $all_licenses->get(array('*'), array('id' => $this->download_uid, 'order_id' => $myorder->order_id), array('date asc'))) $licenses_text[] = date(CC_SITE_DATEFORMAT, strtotime($lic->date))." $lic->client_comment"; $body = $myorder->client->firstname." ".$myorder->client->lastname."
\n". $myorder->client->street." ".$myorder->client->streetnumber."
\n". $myorder->client->zip." ".$myorder->client->city."
\n". substr($myorder->client->country, 11)."
\n". ($myorder->client->phone ? CC_RESSOURCE_PHONE.": ".$myorder->client->phone."
\n" : ""). ($myorder->client->cellphone ? CC_RESSOURCE_CELLPHONE.": ".$myorder->client->cellphone."
\n" : ""). ''.$url_client.''."

\n\n". ($myorder->order_id ? CC_RESSOURCE_ORDERID.": $myorder->order_id
\n" : ''). ($myorder->order_id ? ''.$url_order.''."

\n\n" : ""). "$this->caption

\n\n". CC_RESSOURCE_LICENSES.":
\n".implode("
\n", $licenses_text)."
\n". ''.$url_license.''; $email = new email(); $email->client_id = $myorder->client->client_id; $email->order_id = $myorder->order_id; $email->from_email = $myorder->client->email; $email->from_plain = $myorder->client->firstname." ".$myorder->client->lastname; $email->to_email = CC_SITE_MAILMESSAGE; $email->subject = CC_RESSOURCE_LICENSEMAILSUBJECT; $email->content_html = $body; $email->content_plain = strip_tags($body); $email->store(); } // Lizenz abgelehnt function license_refuse($order, $hk) { $license = new abstractdb(TABLE_ESDLICENSES, $this->download_uid, array( 'order_id' => $order->order_id, 'hardware_id' => $hk, )); $license->license_pending = LICENSE_REFUSED; $license->store(null, array( 'order_id' => $order->order_id, 'hardware_id' => $hk )); $order->send_license_mail($hk, $license->client_comment, $this->caption, $license->date, CC_RESSOURCE_LICENSEREFUSEDMAIL); } // Lizenz erteilt U.B. 06.09 function license_new($myorder, $hk, $auto, $comment = null) { $log = ""; $error_license = false; // Start ESDUB include(CC_INCLUDE_NUSOAP); $nuclient = new nusoap_client(ESD_WEBSERVICE_URL, 'wsdl'); if ($error_message = $nuclient->getError()) { $error_license = true; $log .= "Fehler bei der Erzeugung des NUSOAP WSDL CLIENTS $error_message\n"; } else { $param = array( 'ProjectId' => $this->download_pid, 'ComputerId'=> $hk, 'RegType' => 0, 'UserName' => CC_SITE_PROTECTDISCUSER, 'Password' => CC_SITE_PROTECTDISCPW, ); $result = $nuclient->call('GetUnlockKey', $param); if ($nuclient->fault) { $error_license = true; $log .= "Fehler beim Absenden von GetUnlockKey: fault\n"; } else { $ubLic = ''; $ubLic = $result['Key']; if ($ubLic == '') { $log .= "Keine Lizenz für diese Hardware-ID erhalten\n"; $error_license = true; } else $error_license = false; } } if (!$error_license) { $license = new abstractdb(TABLE_ESDLICENSES, $this->download_uid, array( 'order_id' => $myorder->order_id, 'hardware_id' => $hk, )); $license->license_code = $result['Key']; $license->license_pending = LICENSE_OK; if ($auto) { $license->id = $this->download_uid; $license->order_id = $myorder->order_id; $license->hardware_id = $hk; $license->date = date("Y-m-d H:i:s"); $license->client_comment = $comment; $license->store(true); $log .= "Lic-Code= $license->license_code \n"; } else { $license->store(null, array( 'order_id' => $myorder->order_id, 'hardware_id' => $hk )); $myorder->send_license_mail($hk, $license->client_comment, $this->caption, $license->date, CC_RESSOURCE_LICENSEACCORDEDMAIL); $log .= "Lic-Code= $license->license_code \n"; } } // Ende ESDUB // Log speichern if (LOG_PAYMENT && $error_license) save_to_file(FILE_PDLOG, "\nProtectDisc Log ".date(CC_SITE_DATEFORMAT." H:i")."\n".$log); return $error_license; } //////////////////////////////////////////////////////////////////////////// function store_download($download_count = 0) { $download = new abstractdb(TABLE_DOWNLOADPRODUCTS, $this->download_uid); // Wenn nicht vorhanden, neu anlegen if (!isset($download->filename)) { $download->id = $this->download_uid; $download->caption = $this->caption; $download->filename = $this->download_filename; $download->pid = $this->download_pid; $download->order_count = 1; $download->download_count = $download_count; $download->store(true); // Ansonsten Zähler erhöhen und Werte aktualisieren } else { $download->order_count++; $download->caption = $this->caption; $download->filename = $this->download_filename; $download->pid = $this->download_pid; $download->download_count++; $download->store(); } } // Artikel speichern oder aktualisieren function store($order_id = null) { if ($order_id && $order_id !== true) { $this->order_id = $order_id; $this->db_insertobject(); } else if ($order_id === true) $this->db_insertobject(); else $this->db_updateobject(array( 'uid' => $this->uid, 'position' => $this->position, 'memo' => $this->memo )); } // Datensätze holen function get($fields, $where, $order = null, $page = null, $perpage = null) { return $this->db_get($fields, $where, $order, $page, $perpage); } // Artikel löschen function delete() { $this->db_delete(array( 'uid' => $this->uid, 'order_id' => $this->order_id, 'position' => $this->position, 'memo' => $this->memo, )); } // Zugeordnete Auftragsnummer ändern für den Übergang zwischen Session Id und Bestellnummer function change_order_id($new_order_id) { $this->db_update(array('order_id' => $new_order_id), array('order_id' => $this->order_id, 'memo' => 0)); $this->order_id = $new_order_id; } } ?>