<?php

	/**
	 * Model für eine Bestellung
	 */
	class wpsg_order extends wpsg_model
	{

		var $customer = false; // Kundenobjekt 
		var $bShippingAdress = false; // Wenn true, dann gibt es eine separate Versandadresse 
						
		/* Klassenvariablen */
		var $_innerEu = null;
		var $_shippingZoneID = null;
		var $_arOrderProducts = null;
		
		/**
		 * Lädt die Daten der Bestellung
		 */
		public function load($order_id)
		{

			parent::load($order_id);
			
			@$this->data = &$this->shop->cache->loadOrder($order_id);
			@$this->customer = &$this->shop->cache->loadCustomerObject($this->data['k_id']);			
			$this->bShippingAdress = $this->shop->callMod('wpsg_mod_shippingadress', 'check_different_shippingadress', array($this->data['k_id'], $order_id));
			
			if ($this->data['id'] != $order_id) $this->shop->throwErrorCode('100_1');

			return true;
			
		} // public function load($order_id)
		
		/**
		 * Erstellt einen Eintrag im Bestellprotokoll
		 * @param varchar $subject Text des Betreffs 
		 * @param varchar $text Text der protokolliert werden soll
		 */
		public function log($subject, $text)
		{
			
			$this->db->ImportQuery(WPSG_TBL_OL, array(
				'o_id' => wpsg_q($this->id),
				'cdate' => 'NOW()',
				'title' => wpsg_q($subject),
				'mailtext' => wpsg_q(htmlentities($text, ENT_IGNORE)) 					
			));
			
		} // public function log($subject, $text)
		
		/**
		 * Gibt den letzten Log Eintrag zurück 
		 */
		public function getLastLogEntry()
		{
			
			return $this->db->fetchRow("SELECT * FROM `".WPSG_TBL_OL."` WHERE `o_id` = '".wpsg_q($this->id)."' ORDER BY `cdate` DESC, `id` DESC LIMIT 1 ");
			
		} // public function getLastLogEntry()
		
		/**
		 * Setzt einen Wert in der META Tabelle 
		 */
		public function setMeta($meta_key, $meta_value)
		{
			
			if (is_null($meta_value))
			{
				
				$this->db->Query("DELETE FROM `".WPSG_TBL_META."` WHERE `meta_key` = '".wpsg_q($meta_key)."' AND `target_id` = '".wpsg_q($this->id)."' AND `meta_table` = 'WPSG_TBL_ORDER' ");
				
			}
			else
			{
			
				$nExistsID = $this->db->fetchOne("SELECT M.`id` FROM `".WPSG_TBL_META."` AS M WHERE M.`meta_table` = 'WPSG_TBL_ORDER' AND M.`meta_key` = '".wpsg_q($meta_key)."' AND `target_id` = '".wpsg_q($this->id)."' ");
				
				if (wpsg_isSizedInt($nExistsID))
				{
					
					$this->db->UpdateQuery(WPSG_TBL_META, array(					
						'meta_value' => wpsg_q($meta_value)
					), " `id` = '".wpsg_q($nExistsID)."' ");
					
				}
				else
				{
					
					$this->db->ImportQuery(WPSG_TBL_META, array(
						'target_id' => wpsg_q($this->id),
						'meta_table' => "WPSG_TBL_ORDER",
						'meta_key' => wpsg_q($meta_key),
						'meta_value' => wpsg_q($meta_value)
					));
					
				}
				
			}
			
		} // public function setMeta($meta_key, $meta_value)
		
		/**
		 * Gibt einen META Value zurück
		 */
		public function getMeta($meta_key)
		{
			
			$meta_value = $this->db->fetchOne("SELECT M.`meta_value` FROM `".WPSG_TBL_META."` AS M WHERE M.`meta_table` = 'WPSG_TBL_ORDER' AND M.`meta_key` = '".wpsg_q($meta_key)."' AND `target_id` = '".wpsg_q($this->id)."' ");
			
			return $meta_value;
			
		} // public function getMeta($meta_key)
		
		/**
		 * Gibt den Namen der Versandart zurück
		 * Ist wichtig geworden, da die Versandart aus mehreren Versandarten zusammengesetzt sein kann
		 * Die Methode getShippingName im ShopController funktioniert nur für die Session wenn in arShipping 
		 * schon die zusammengesetzt Versandart drin ist. Die Übersetzung übernimmt aber die getShippingName im ShopController
		 */
		public function getShippingTypName()
		{

			if (preg_match('/(.*)-(.*)/', $this->type_shipping))
			{
				
				// Versandart ist zusammengesetzt
				$arShippingKey = explode('-', $this->type_shipping);
				$arShippingNames = array();
				
				foreach ($arShippingKey as $shipping_key)
				{

					$arShippingNames[] = $this->shop->getShippingName($shipping_key);
					
				}
				
				return implode(' + ', $arShippingNames);
				
			}
			else
			{
				
				return $this->shop->getShippingName($this->type_shipping);
				
			}
			
		} // public function getShippingTypName()
		
		public function getPaymentTaxAmount()
		{
			
			return wpsg_tf($this->mwst_payment);
			
		}
		
		public function getShippingTaxAmount()
		{
			
			return wpsg_tf($this->mwst_shipping);
			
		} // public function getShippingTaxAmount()
		
		/**
		 * Gibt den Wert der Bestellung zurück
		 * Dies ist der Wert, der über die Zahlungsanbieter abgerechnet wird
		 */
		public function getAmount($brutto_netto = WPSG_BRUTTO)
		{
						
			//wpsg_debug($this->data['price_gesamt_netto'].":".$this->data['price_gesamt_brutto']);
			
			if ($brutto_netto == WPSG_BRUTTO)
			{
				
				return wpsg_tf($this->data['price_gesamt_brutto']);
				
			}
			else
			{
			
				return wpsg_tf($this->data['price_gesamt_netto']);
				
			}
			
		} // public function getAmount()
				
		/**
		 * Summe aller MwSt. Beträge der Bestellung
		 */
		public function getTaxAmount()
		{
				
			$tax_return = 0;
			
			foreach ($this->getOrderProducts() as $oOrderProduct) 
			{
				
				$tax_return += $oOrderProduct->getTaxAmount();
				
			}
			
			$tax_return += wpsg_tf($this->data['mwst_shipping']);
			$tax_return += wpsg_tf($this->data['mwst_payment']);
			
			return wpsg_tf($tax_return);
				
		} // public function getTaxAmount()
		 		
		public function getProductAmount($brutto_netto = WPSG_BRUTTO)
		{
				
			//wpsg_debug($this->getAmount($brutto_netto));
			//wpsg_debug($this->getShippingAmount($brutto_netto));
			//wpsg_debug($this->getPaymentAmount($brutto_netto));
			
			return $this->getAmount($brutto_netto) - $this->getShippingAmount($brutto_netto) - $this->getPaymentAmount($brutto_netto); 
				
		} // public function getAmount()
		
		/**
		 * Gibt das Kundenobjekt zurück
		 * @return wpsg_customer Kundenobjekt
		 */
		public function getCustomer()
		{
			
			return $this->customer;
			
		} // public function getCustomer()
		 	
		/**
		 * Gibt die Anzahl zurück, wie oft das Produkt in der Bestellung vorkommt
		 */
		public function getProductCount($product_id)
		{
			
			return $this->db->fetchOne("
				SELECT
					SUM(`menge`)
				FROM
					`".WPSG_TBL_ORDERPRODUCT."`
				WHERE
					`p_id` = '".wpsg_q($product_id)."' AND
					`o_id` = '".wpsg_q($this->id)."'
			");
			
		} // public function getProductCount($product_id)
		
		/**
		 * Gibt einen Array mit allen bestellten Produkten zurück
		 */
		public function getOrderProducts()
		{
			
			if (!is_null($this->_arOrderProducts)) return $this->_arOrderProducts;
			else
			{
			
				$arOpIds = $this->db->fetchAssocField("SELECT OP.`id` FROM `".WPSG_TBL_ORDERPRODUCT."` AS OP WHERE OP.`o_id` = '".wpsg_q($this->id)."' ORDER BY `id` ASC ");
				
				$arReturn = array();
				$number = 1;
				
				foreach ($arOpIds as $order_product_id)
				{
					
					$oOrderProduct = new wpsg_order_product();
					$oOrderProduct->load($order_product_id);
					$oOrderProduct->number = $number;
					
					$arReturn[] = $oOrderProduct;
					
					$number ++;
					
				}
				
				$this->_arOrderProducts = $arReturn;
				
				return $arReturn;
				
			}
			
		} // public function getOrderProducts()
		
		/**
		 * Gibt die Kosten für die Versandart zurück in Euro
		 * Derzeit ist es so, dass 
		 */
		public function getShippingAmount($brutto_netto = WPSG_BRUTTO)
		{			
			
			if ($brutto_netto === WPSG_NETTO)
			{
				
				return wpsg_tf($this->price_shipping_netto);
				
			}
			else
			{
			
				return wpsg_tf($this->price_shipping_brutto);
				
			}
			
		} // public function getShippingAmount()
		
		/**
		 * Gibt die Kosten für die Zahlungsart zurück in Euro 
		 */
		public function getPaymentAmount($brutto_netto = WPSG_BRUTTO)
		{
			
			if ($brutto_netto === WPSG_NETTO)
			{
			
				return wpsg_tf($this->price_payment_netto);
			
			}
			else
			{
					
				return wpsg_tf($this->price_payment_brutto);
			
			} 
			
		} // public function getPaymentAmount()
		
		/**
		 * Gibt die verwendete Zahlungsart der Bestellung zurück
		 */
		public function getPaymentID()
		{
			
			return $this->data['type_payment'];
			
		} // public function getPaymentID()
		
		/**
		 * Gibt einen Array mit ProduktKeys zurück, die in dieser Bestellung bestellt wurden
		 */
		public function getProductKeys()
		{
		
			$order_product_keys = $this->db->fetchAssocField("
				SELECT
					`productkey`
				FROM
					`".WPSG_TBL_ORDERPRODUCT."` 
				WHERE
					`o_id` = '".wpsg_q($this->id)."'	
			");
			
			return $order_product_keys;

		} // public function getProductKeys()

		/**
		 * Gibt das Geschlecht des Rechnungsempfängers zurück
		 * @return String Geschlecht des Rechnungsempfängers
		 */
		public function getInvoiceGender()
		{
			
			return $this->customer->getGender();
			
		} // public function getInvoiceGender()
		
		/**
		 * Gibt den Vornamen des Rechnungsempfängers zurück
		 * @return String Vorname des Rechnungsempfängers
		 */
		public function getInvoiceFirstName()
		{
			
			return $this->customer->getFirstName();
			
		} // public function getInvoiceFirstName()
		
		/**
		 * Gibt den Namen des Rechnungsempfängers zurück
		 * @return String Name des Rechnungsempfängers
		 */
		public function getInvoiceName()
		{
			
			return $this->customer->getName();
			
		} // public function getInvoiceName()
				
		/**
		 * Gibt die Straße der Rechnungsadresse zurück
		 * @return String Straße der Rechnungsanschrift
		 */
		public function getInvoiceStreet()
		{
			
			return $this->customer->getStreet();
			
		} // public function getInvoiceStreet()
		
		/**
		 * Versucht die Hausnummer von der Straße abzutrennen und nur die Straße zurückzugeben
		 * @return String der Reine Straßenname der Rechnungsadresse
		 */
		public function getInvoiceStreetClear()
		{
			
			return $this->customer->getStreetClear();
			
		} // public function getInvoiceStreetClear()
		
		/**
		 * Gibt die Straßennummer der Rechnungsadresse zurück
		 * @return String Hausnummer der Rechnungsanschrift
		 */
		public function getInvoiceStreetNr()
		{
			
			return $this->customer->getStreetNr();
			
		} // public function getInvoiceStreetNr()
		
		/**
		 * Gibt die Postleitzahl der Rechnungsadresse zurück
		 * @return String PLZ der Rechnungsadresse
		 */
		public function getInvoiceZip()
		{
			
			return $this->customer->getZip();
			
		} // public function getInvoiceZip()
		
		/**
		 * Gibt den Ort der Rechnungsadresse zurück
		 * @return String Ort der Rechnungsadresse
		 */
		public function getInvoiceCity()
		{
			
			return $this->customer->getCity();
			 
		} // public function getInvoiceCity()
		
		/**
		 * Gibt die ID des Landes zurück, an die die Rechnung ging
		 * @return \Integer ID des Landes für die Rechnung
		 */
		public function getInvoiceCountry()
		{
				
			return $this->customer->getCountryID();
			
		} // public function getInvoiceCountry()
		
		/**
		 * Gibt das Kürzel des Rechnungslandes zurück
		 */
		public function getInvoiceCountryKuerzel()
		{
				
			return $this->customer->getCountryKuerzel();
				
		} // public function getInvoiceCountryKuerzel()
		
		/**
		 * Gibt den Namen des Landes der Rechnungsadresse zurück
		 */
		public function getInvoiceCountryName()
		{
			
			return $this->customer->getCountryName();
			
		} // public function getInvoiceCountryName()
		
		/**
		 * Gibt das Geschlecht des Empfängers der Bestellung zurück
		 * @return Geschlecht des Empfängers
		 */
		public function getShippingGender()
		{
			
			if ($this->bShippingAdress === true)
			{
				
				if (preg_match('/Frau/i', $this->shipping_title))
				{
					
					return 'f';
					
				}
				else
				{
					
					return 'm';
					
				}
				
			}
			else
			{
				
				return $this->getInvoiceGender();
				
			}
			
		} // public function getShippingGender()
		
		/**
		 * Gibt den Vornamen des Empfängers der Bestellung zurück
		 * @return string Vorname des Empfängers
		 */
		public function getShippingFirstName()
		{
			
			if ($this->bShippingAdress === true)
			{
				
				return $this->shipping_vname;
				
			}
			else
			{
				
				return $this->getInvoiceFirstName();
				
			}
			
		} // public function getShippingFirstName()
		
		/**
		 * Gibt den Namen des Empfängers der Bestellung zurück
		 * @return string Name des Empfängers
		 */
		public function getShippingName()
		{
			
			if ($this->bShippingAdress === true)
			{
				
				return $this->shipping_name;
				
			}
			else
			{
				
				return $this->getInvoiceName();
				
			}
						
		} // public function getShippingName()
		
		/**
		 * Gibt den reinen Straßennamen des Empfängers zurück
		 * @return string reiner Straßenname des Empfängers
		 */
		public function getShippingStreetClear()
		{
			
			if ($this->bShippingAdress === true)
			{
				
			 	return preg_replace('/\040+\d+$/', '', $this->shipping_strasse);
				
			}
			else
			{
				
				return $this->getInvoiceStreetClear();
				
			}
			
		} // public function getShippingStreetClear()
		
		/**
		 * Gibt die komplette Straße des Empfängers der Bestellung zurück (Inklusive Hausnummer)
		 * @return string komplette Straße des Empfängers
		 */
		public function getShippingStreet()
		{
			
			if ($this->bShippingAdress === true)
			{
				
				return $this->shipping_strasse;
				
			}
			else
			{
				
				return $this->getInvoiceStreet();
				
			}
			
		} // public function getShippingStreet()
		
		/**
		 * Gibt die Hausnummer des Empfängers der Bestellung zurück
		 * @return string Hausnummer des Empfängers
		 */
		public function getShippingStreetNr()
		{
			
			if ($this->bShippingAdress === true)
			{
				
				return intval(preg_replace('/(.*)\040/', '', $this->shipping_strasse));
				
			}
			else 
			{
				
				return $this->getInvoiceStreetNr();
				
			}
			
		} // public function getShippingStreetNr()
		
		/**
		 * Gibt die Postleitzahl des Empfängers zurück
		 * @return string Postleitzahl des Empfängers
		 */
		public function getShippingZip()
		{
			
			if ($this->bShippingAdress === true)
			{
				
				return $this->shipping_plz;
								
			}
			else
			{
				
				return $this->getInvoiceZip();
				
			}
			
		} // public function getShippingZip()
		
		/**
		 * Gibt den Wohnort des Empfängers zurück
		 * @return string Ort des Empfängers
		 */
		public function getShippingCity()
		{
			
			if ($this->bShippingAdress === true)
			{
				
				return $this->shipping_ort;
				
			}
			else
			{
				
				return $this->getInvoiceCity();
				
			}
			
		} // public function getShippingCity()
				
		/**
		 * Gibt das Lieferland der Bestellung zurück
		 * @return \Integer ID des Landes, in das die Bestellung geliefert wird
		 */
		public function getShippingCountryID()
		{
			
			if ($this->bShippingAdress)
			{
				
				return $this->shipping_land;
				
			}
			else 
			{
				
				return $this->getInvoiceCountry();
				
			}
			
		} // public function getShippingCountryID()
				
		/**
		 * Gibt das Kuerzel des Lieferlandes zurück
		 */
		public function getShippingCountryKuerzel()
		{
			
			if ($this->bShippingAdress === true)
			{
				
				return $this->db->fetchOne("SELECT `kuerzel` FROM `".WPSG_TBL_LAND."` WHERE `id` = '".wpsg_q($this->getShippingCountryID())."' ");
				
			}
			else
			{
			 
				return $this->getInvoiceCountryKuerzel();
				
			}
			
		} // public function getShippingCountryKuerzel()
		
		public function getShippingCountryName()
		{
			
			if ($this->bShippingAdress === true)
			{
			
				return $this->db->fetchOne("SELECT `name` FROM `".WPSG_TBL_LAND."` WHERE `id` = '".wpsg_q($this->getShippingCountryID())."' ");
			
			}
			else
			{
			
				return $this->getInvoiceCountryName();
			
			}
			
		}
		
		/**
		 * Gibt die ID der Versandzone zurück, in die geliefert wird
		 * @return \Integer ID der Versandzone, in die geliefert wird
		 */
		public function getShippingZoneID()
		{
			
			if (is_null($this->_shippingZoneID))
			{
			
				$this->_shippingZoneID = $this->db->fetchOne("
					SELECT 
						L.`vz` 
					FROM
						`".WPSG_TBL_LAND."` AS L							
					WHERE
						L.`id` = '".wpsg_q($this->getShippingCountryID())."'
				");
				
			}
			
			return $this->_shippingZoneID;
			
		} // public function getShippingZoneID()
		
		/**
		 * Gibt true zurück, wenn die Bestellung in ein Land gesendet wird, dessen Versandzone als "Innergemeinschaftliche Lieferung" markiert ist
		 * @return \Boolean
		 */
		public function isInnerEu()
		{
			
			if (is_null($this->_innerEu))
			{
				
				$innerEu = $this->db->fetchOne("SELECT VZ.`innereu` FROM `".WPSG_TBL_VZ."` AS VZ WHERE VZ.`id` = '".wpsg_q($this->getShippingZoneID())."' ");
				
				if ($innerEu == "1")
				{
					
					$this->_innerEu = true;
					
				}
				else
				{
					
					$this->_innerEu = false;
					
				}
				
			}
			
			return $this->_innerEu;
			
		} // public function isInnerEu()
		
		/**
		 * Speichert die Bestelldaten in die Datenbank
		 */
		public function save()
		{
			
			$this->db->UpdateQuery(WPSG_TBL_ORDER, $this->data, " `id` = '".wpsg_q($this->id)."' ");
			
		} // public function save()

		/**
		 * Löscht eine Bestellung
		 */
		public function delete()
		{
			
			// Module aufrufen, damit sie die Abhängigkeiten löschen können
			$this->shop->callMods('delOrder', array(&$this->id));
				
			// Bestelldaten aus der Bestelltabelle löschen
			$this->db->Query("DELETE FROM `".WPSG_TBL_ORDER."` WHERE `id` = '".wpsg_q($this->id)."' ");
				
			// Bestellte Produkte
			$this->db->Query("DELETE FROM `".WPSG_TBL_ORDERPRODUCT."` WHERE `o_id` = '".wpsg_q($this->id)."' ");
		
			// Log Einträge
			$this->db->Query("DELETE FROM `".WPSG_TBL_OL."` WHERE `o_id` = '".wpsg_q($this->id)."' ");
				
			// Meta Daten
			$this->db->Query("DELETE FROM `".WPSG_TBL_META."` WHERE `meta_table` = 'WPSG_TBL_ORDER' AND `target_id` = '".wpsg_q($this->id)."' ");
				
		} // public function delete()
		
		/**
		 * Gibt einen Array von Bestellungen zurück, die auf den übergebenen Filter passen
		 * @param array $arFilter
		 */
		public static function find($arFilter = array())
		{
			
			$strQueryWHERE = "";
			$strQueryJOIN = "";
			
			if (wpsg_isSizedInt($arFilter['k_id']))
			{
				
				$strQueryWHERE .= " AND O.`k_id` = '".wpsg_q($arFilter['k_id'])."' ";
				
			}
			
			if (wpsg_isSizedInt($arFilter['status']))
			{
				
				$strQueryWHERE .= " AND O.`status` = '".wpsg_q($arFilter['status'])."' ";
				
			}
			else if (wpsg_isSizedArray($arFilter['status']))
			{
				
				$strQueryWHERE .= " AND O.`status` IN (".wpsg_q(implode(',', $arFilter['status'])).") ";
				
			}
			
			if (wpsg_isSizedInt($arFilter['NOTstatus']))
			{
			
				$strQueryWHERE .= " AND O.`status` != '".wpsg_q($arFilter['NOTstatus'])."' ";
			
			}
			else if (wpsg_isSizedArray($arFilter['NOTstatus']))
			{
			
				$strQueryWHERE .= " AND O.`status` NOT IN (".wpsg_q(implode(',', $arFilter['NOTstatus'])).") ";
			
			}
			
			if (wpsg_isSizedInt($arFilter['cdate_from']))
			{
			
				$strQueryWHERE .= " AND O.`cdate` > '".wpsg_date('Y-m-d', $arFilter['cdate_from'])."' ";
			
			}
			
			if (wpsg_isSizedInt($arFilter['product_id']))
			{
				
				$strQueryWHERE .= " AND OP.`p_id` = '".wpsg_q($arFilter['product_id'])."' ";
				$bJoinProducts = true;
				
			}
			
			if ($bJoinProducts === true) $strQueryJOIN = " LEFT JOIN `".WPSG_TBL_ORDERPRODUCT."` AS OP ON (O.`id` = OP.`o_id`) ";
			
			$strQuery = "
				SELECT
					O.`id`
				FROM
					`".WPSG_TBL_ORDER."` AS O
					".$strQueryJOIN."
				WHERE
					1
					".$strQueryWHERE."	
				GROUP BY 
					O.`id`
			";
			 
			$arOrderID = $GLOBALS['wpsg_db']->fetchAssocField($strQuery);
			$arReturn = array();
			
			foreach ($arOrderID as $order_id)
			{
				
				$oOrder = $GLOBALS['wpsg_sc']->cache->loadOrderObject($order_id); 
				$arReturn[] = $oOrder;
				
			}
			
			return $arReturn;
			
		} // public static function find($arFilter = array())
		
	} // class wpsg_mod_order extends wpsg_model

?>