<?php

	require_once WPSG_PATH_MOD.'mod_statistics/wpsg_statisticabstract.php';
	
	/**
	 * Klasse zur Ermittlung Statistik für die Umsätze
	 * @author 	robert
	 * @since	11.01.2013
	 */
	class wpsg_topsellertosales extends wpsg_statisticabstract
	{
		
		public function calculateSonstiges($arData, &$arFinalData)
		{
			foreach ($arData as $index => $record)
			{
				if (!in_array($index, array_keys($arFinalData['records'])))
				{
					$arFinalData['records'][$this->shop->get_option('wpsg_mod_statistics_topproductcount')]['p_id'] = '';
					$arFinalData['records'][$this->shop->get_option('wpsg_mod_statistics_topproductcount')]['mod_vp_varkey'] = '';
					$arFinalData['records'][$this->shop->get_option('wpsg_mod_statistics_topproductcount')]['total'] += $record['total'];
					$arFinalData['records'][$this->shop->get_option('wpsg_mod_statistics_topproductcount')]['amount'] += $record['amount'];
					$arFinalData['records'][$this->shop->get_option('wpsg_mod_statistics_topproductcount')]['name'] = __('Sonstige', 'wpsg');
					$arFinalData['records'][$this->shop->get_option('wpsg_mod_statistics_topproductcount')]['mod_varianten'] = '';			
				}
			}
			
			return $arFinalData;
		}
		
		/**
		 * Maximalen Wert für Skalierung der y2-Achse ermitteln
		 * @param	array	$arData
		 * @return	double
		 */
		public function retrieveMaxMenge($arData)
		{
			$y2max = 0;
			
			foreach ($arData['records'] as $record)
			{
				if ($record['amount'] > $y2max)
				{
					$y2max = $record['amount'];
				}
			}
			
			$factor = 1;
			
			$factor = str_pad($factor, strlen($y2max), '0');
			
			$y2max = (ceil($y2max/$factor) * $factor);
			
			$factor = 1;
			
			$factor = str_pad($factor, strlen(intval(ceil($y2max/100))), '0');
			
			$y2maxPadding = (ceil(intval(ceil($y2max/100))/$factor) * $factor);
			
			return $y2max + (5 * strlen($y2max) * $y2maxPadding);		
		}
		
		/**
		 * Rückgabe aller Statistikdaten
		 * @internal Bezug -> Jahr
		 * @return array
		 */
		public function getAll($point = 0, $params = array())
		{
			
			$arAllData = $this->db->fetchAssoc(" 
					SELECT 
						OP.`p_id`,
						OP.`mod_vp_varkey`,
						SUM(OP.`price` * OP.`menge`) AS total,
						SUM(OP.`menge`) AS amount,
						P.`name`
						".(($this->shop->hasMod('wpsg_mod_varianten'))?', P.`mod_varianten`':'')."
				  	FROM 
				  		`".WPSG_TBL_ORDERPRODUCT."` AS OP
				  		LEFT JOIN `".WPSG_TBL_ORDER."` AS O ON(O.`id` = OP.`o_id`) 
				  		LEFT JOIN `".WPSG_TBL_PRODUCTS."` AS P ON(P.`id` = OP.`p_id`) 
				  	WHERE
				  		O.`type_payment` != '' AND 
				  		O.`type_payment` IS NOT NULL AND 
				  		O.`status` IN(".$this->observeStatuscodes.")
				  	GROUP BY
				  		OP.`p_id`, OP.`mod_vp_varkey`
				  	ORDER BY 
				  		total DESC
			");
			
			$arData['records'] = array_slice($arAllData, 0, $this->shop->get_option('wpsg_mod_statistics_topproductcount'));
			
			$this->calculateSonstiges($arAllData, $arData);
			
			$arData['records'] = $this->calculate($arData['records']);
			
			$arData['y2max'] = $this->retrieveMaxMenge($arData);
			
			$this->addSorting($arData, $params['order'], ((!wpsg_isSizedString($params['sort']))?'name':$params['sort']));
			
			return $arData;
		}	
		
		/**
		 * Rückgabe der Statistik auf ein Jahr bezogen
		 * @internal Bezug -> Monat
		 * @param int Bezugspunkt (0 aktuelles Jahr, -1 letztes Jahr)
		 * @return array
		 */
		public function getYear($point = 0, $params = array())
		{
			
			if ($point == '0')
			{
				$year = date('Y');
			}
			else if ($point == '-1')
			{
				$year = date('Y') - 1;
			}
			else
			{
				$year = $point;	
			}
			
			$arAllData = $this->db->fetchAssoc("SELECT 
													OP.`p_id`,
													OP.`mod_vp_varkey`,
													SUM(OP.`price` * OP.`menge`) AS total,
													SUM(OP.`menge`) AS amount,
													P.`name`".(($this->shop->hasMod('wpsg_mod_varianten'))?', P.`mod_varianten`':'')."
											   FROM 
											  		`".WPSG_TBL_ORDERPRODUCT."` AS OP
											  		LEFT JOIN `".WPSG_TBL_ORDER."` AS O ON(O.`id` = OP.`o_id`) 
											  		LEFT JOIN `".WPSG_TBL_PRODUCTS."` AS P ON(P.`id` = OP.`p_id`) 
											   WHERE
											  		O.`type_payment` != '' AND 
											  		O.`type_payment` IS NOT NULL AND 
											  		O.`status` IN(".$this->observeStatuscodes.") AND 
											  		YEAR ( O.`cdate` ) = '".$year."'
											   GROUP BY
											  		OP.`p_id`, OP.`mod_vp_varkey`
											   ORDER BY 
											  		total DESC");
			
			$arData['records'] = array_slice($arAllData, 0, $this->shop->get_option('wpsg_mod_statistics_topproductcount'));
			
			$this->calculateSonstiges($arAllData, $arData);
			
			$arData['records'] = $this->calculate($arData['records']);
			
			$arData['y2max'] = $this->retrieveMaxMenge($arData);
			
			$arData['template'] = 'all';
			
			$this->addSorting($arData, $params['order'], ((!wpsg_isSizedString($params['sort']))?'name':$params['sort']));
			
			return $arData;
			
		}
		
		/**
		 * Rückgabe der Statistik auf ein Quartal bezogen
		 * @param string
		 * @internal Bezug -> Monat 
		 * @return array
		 */
		public function getQuarter($point = 0, $params = array())
		{
			
			$arQuarter = array(	'1' => array(1, 2, 3),
								'2'	=> array(4, 5, 6),
								'3'	=> array(7, 8, 9),
								'4' => array(10, 11, 12));
			
			if ($point == '0')
			{
				$year = date('Y');
				$month = date('n');
			}
			else if ($point == '-1')
			{
				$year = date('Y');
				$month = date('n');
				
				foreach ($arQuarter as $index => $quarter)
				{
					if (in_array($month, $quarter))
					{
						if (isset($actQuarter[$index - 1]))
						{
							$quarterFirstMonth = $arQuarter[$index - 1][0];	
						}
						else
						{
							$quarterFirstMonth = $arQuarter[count($arQuarter)][0];	
							$year--;
						}
					}
				}
				
				$month = $quarterFirstMonth;
			}
			
			foreach ($arQuarter as $index => $quarter)
			{
				if (in_array($month, $quarter))
				{
					
					$actQuarter = $index;
					
					$lastMonth = $arQuarter[$index][count($arQuarter[$index]) - 1];
					
					$daysLastMonth = wpsg_getDaysofMonth($lastMonth, $year);
					
					$dayLastMonthTS = mktime(0, 0, 0, $lastMonth, $daysLastMonth, $year);
					
					$firstMonth = array_shift($arQuarter[$index]);
					
					$dayFirstMonthTS = mktime(0, 0, 0, $firstMonth, 1, $year);
					
				}
			}
			
			$arAllData = $this->db->fetchAssoc("SELECT 
													OP.`p_id`,
													OP.`mod_vp_varkey`,
													SUM(OP.`price` * OP.`menge`) AS total,
													SUM(OP.`menge`) AS amount,
													P.`name`".(($this->shop->hasMod('wpsg_mod_varianten'))?', P.`mod_varianten`':'')."
											   FROM 
											  		`".WPSG_TBL_ORDERPRODUCT."` AS OP
											  		LEFT JOIN `".WPSG_TBL_ORDER."` AS O ON(O.`id` = OP.`o_id`) 
											  		LEFT JOIN `".WPSG_TBL_PRODUCTS."` AS P ON(P.`id` = OP.`p_id`) 
											   WHERE
											  		O.`type_payment` != '' AND 
											  		O.`type_payment` IS NOT NULL AND 
											  		O.`status` IN(".$this->observeStatuscodes.") AND 
											  		O.`cdate` >= '".date('Y-m-d H:i:s', $dayFirstMonthTS)."' AND 
											  		O.`cdate` <= '".date('Y-m-d H:i:s', $dayLastMonthTS)."'
											   GROUP BY
											  		OP.`p_id`, OP.`mod_vp_varkey`
											   ORDER BY 
											  		total DESC");
			
			$arData['records'] = array_slice($arAllData, 0, $this->shop->get_option('wpsg_mod_statistics_topproductcount'));
			
			$this->calculateSonstiges($arAllData, $arData);
			
			$arData['records'] = $this->calculate($arData['records']);
			
			$arData['y2max'] = $this->retrieveMaxMenge($arData);
			
			$arData['template'] = 'all';
			
			$this->addSorting($arData, $params['order'], ((!wpsg_isSizedString($params['sort']))?'name':$params['sort']));
			
			return $arData;
			
		}
		
		/**
		 * Rückgabe der Statistik auf einen Monat bezogen
		 * @internal Bezug -> Tag 
		 * @param string
		 * @return array
		 */
		public function getMonth($point = 0, $params = array())
		{
			
			if ($point == '0')
			{
				$year = date('Y');
				$month = date('n');
			}
			else if ($point == '-1')
			{
				$year = date('Y');
				$month = date('n') - 1;
				
				if ($month == 0)
				{
					$month = 12;
					$year--;
				}
			}
			
			$arAllData = $this->db->fetchAssoc("SELECT 
													OP.`p_id`,
													OP.`mod_vp_varkey`,
													SUM(OP.`price` * OP.`menge`) AS total,
													SUM(OP.`menge`) AS amount,
													P.`name`
													".(($this->shop->hasMod('wpsg_mod_varianten'))?', P.`mod_varianten`':'')."
											    FROM 
											  		`".WPSG_TBL_ORDERPRODUCT."` AS OP
											  		LEFT JOIN `".WPSG_TBL_ORDER."` AS O ON(O.`id` = OP.`o_id`) 
											  		LEFT JOIN `".WPSG_TBL_PRODUCTS."` AS P ON(P.`id` = OP.`p_id`) 
											    WHERE
											  		O.`type_payment` != '' AND 
											  		O.`type_payment` IS NOT NULL AND 
											  		O.`status` IN(".$this->observeStatuscodes.") AND 
											  		YEAR ( O.`cdate` ) = '".$year."' AND 
											  		MONTH ( O.`cdate` ) = '".$month."'
											    GROUP BY
											  		OP.`p_id`, OP.`mod_vp_varkey`
											    ORDER BY 
											  		total DESC");
			
			$arData['records'] = array_slice($arAllData, 0, $this->shop->get_option('wpsg_mod_statistics_topproductcount'));
			
			$this->calculateSonstiges($arAllData, $arData);
			
			$arData['records'] = $this->calculate($arData['records']);
			
			$arData['y2max'] = $this->retrieveMaxMenge($arData);
			
			$arData['template'] = 'all';
			
			$this->addSorting($arData, $params['order'], ((!wpsg_isSizedString($params['sort']))?'name':$params['sort']));
			
			return $arData;
			
		}
		
		/**
		 * Rückgabe der Statistik auf eine Woche bezogen
		 * @internal Bezug -> Tag 
		 * @param string
		 * @return array
		 */
		public function getWeek($point = 0, $params = array())
		{
			
			$adjustment = 1;
			
			if ($point == '0')
			{
				$weekday = date("w", time());
			
				$firstDayofWeek = time() - (($weekday - $adjustment)*86400);
				$lastDayofWeek = time() + ((6 + $adjustment - $weekday) * 86400);
			}
			else if ($point == '-1') 
			{
				
				$time = time() - (6*86400);
				
				$weekday = date("w", $time);
			
				$firstDayofWeek = $time - (($weekday - $adjustment)*86400);
				$lastDayofWeek = $time + ((6 + $adjustment - $weekday) * 86400);
			}
			
			$arAllData = $this->db->fetchAssoc("SELECT 
													OP.`p_id`,
													OP.`mod_vp_varkey`,
													SUM(OP.`price` * OP.`menge`) AS total,
													SUM(OP.`menge`) AS amount,
													P.`name`
													".(($this->shop->hasMod('wpsg_mod_varianten'))?', P.`mod_varianten`':'')."
											    FROM 
											  		`".WPSG_TBL_ORDERPRODUCT."` AS OP
											  		LEFT JOIN `".WPSG_TBL_ORDER."` AS O ON(O.`id` = OP.`o_id`) 
											  		LEFT JOIN `".WPSG_TBL_PRODUCTS."` AS P ON(P.`id` = OP.`p_id`) 
											    WHERE
											  		O.`type_payment` != '' AND 
											  		O.`type_payment` IS NOT NULL AND 
											  		O.`status` IN(".$this->observeStatuscodes.") AND 
											  		O.`cdate`	>= '".date('Y-m-d 00:00:00', $firstDayofWeek)."' AND 
											  		O.`cdate` <= '".date('Y-m-d 23:59:59', $lastDayofWeek)."'
											    GROUP BY
											  		OP.`p_id`, OP.`mod_vp_varkey`
											    ORDER BY 
											  		total DESC");
			
			$arData['records'] = array_slice($arAllData, 0, $this->shop->get_option('wpsg_mod_statistics_topproductcount'));
			
			$this->calculateSonstiges($arAllData, $arData);
			
			$arData['records'] = $this->calculate($arData['records']);
			
			$arData['y2max'] = $this->retrieveMaxMenge($arData);
			
			$arData['template'] = 'all';
			
			$this->addSorting($arData, $params['order'], ((!wpsg_isSizedString($params['sort']))?'name':$params['sort']));
			
			return $arData;
			
		}
		
		/**
		 * Rückgabe der Statistik auf einen Tag bezogen
		 * @internal Bezug -> Stunde 
		 * @param string
		 * @return array
		 */
		public function getDay($point = 0, $params = array())
		{
			
			if ($point == '0')
			{
				$day = time();
			}
			else if ($point == '-1')
			{
				$day = time() - 86400;
			}
			
			$arAllData = $this->db->fetchAssoc("SELECT 
													OP.`p_id`,
													OP.`mod_vp_varkey`,
													SUM(OP.`price` * OP.`menge`) AS total,
													SUM(OP.`menge`) AS amount,
													P.`name`
													".(($this->shop->hasMod('wpsg_mod_varianten'))?', P.`mod_varianten`':'')."
											    FROM 
											  		`".WPSG_TBL_ORDERPRODUCT."` AS OP
											  		LEFT JOIN `".WPSG_TBL_ORDER."` AS O ON(O.`id` = OP.`o_id`) 
											  		LEFT JOIN `".WPSG_TBL_PRODUCTS."` AS P ON(P.`id` = OP.`p_id`) 
											    WHERE
											  		O.`type_payment` != '' AND 
											  		O.`type_payment` IS NOT NULL AND 
											  		O.`status` IN(".$this->observeStatuscodes.") AND 
											  		YEAR( O.`cdate` ) = '".date('Y', $day)."' AND 
								  					MONTH ( O.`cdate` ) = '".date('m', $day)."' AND 
								  					DAY (O.`cdate`) = '".date('d', $day)."'
											    GROUP BY
											  		OP.`p_id`, OP.`mod_vp_varkey`
											    ORDER BY 
											  		total DESC");
			
			$arData['records'] = array_slice($arAllData, 0, $this->shop->get_option('wpsg_mod_statistics_topproductcount'));
			
			$this->calculateSonstiges($arAllData, $arData);
			
			$arData['records'] = $this->calculate($arData['records']);
			
			$arData['y2max'] = $this->retrieveMaxMenge($arData);
			
			$arData['template'] = 'all';
			
			$this->addSorting($arData, $params['order'], ((!wpsg_isSizedString($params['sort']))?'name':$params['sort']));
			
			return $arData;
	 		
		}
		
		/**
		 * Rückgabe der Statistik bezogen auf einen benutzerdefinierten Zeitraum
		 * @internal Bezug -> Tag 
		 * @param string
		 * @return array
		 */
		public function getCustomRange($point = 0, $params = array())
		{
	
			$start = wpsg_fieldarray_todate($_REQUEST['filter']['day'][0]);
			$end = wpsg_fieldarray_todate($_REQUEST['filter']['day'][1]);
			
			$arAllData = $this->db->fetchAssoc("SELECT 
													OP.`p_id`,
													OP.`mod_vp_varkey`,
													SUM(OP.`price` * OP.`menge`) AS total,
													SUM(OP.`menge`) AS amount,
													P.`name`
													".(($this->shop->hasMod('wpsg_mod_varianten'))?', P.`mod_varianten`':'')."
											    FROM 
											  		`".WPSG_TBL_ORDERPRODUCT."` AS OP
											  		LEFT JOIN `".WPSG_TBL_ORDER."` AS O ON(O.`id` = OP.`o_id`) 
											  		LEFT JOIN `".WPSG_TBL_PRODUCTS."` AS P ON(P.`id` = OP.`p_id`) 
											    WHERE
											  		O.`type_payment` != '' AND 
											  		O.`type_payment` IS NOT NULL AND 
											  		O.`status` IN(".$this->observeStatuscodes.") AND 
											  		O.`cdate`	>= '".date('Y-m-d 00:00:00', $start)."' AND 
											  		O.`cdate` <= '".date('Y-m-d 23:59:59', $end)."'
											    GROUP BY
											  		OP.`p_id`, OP.`mod_vp_varkey`
											    ORDER BY 
											  		total DESC");
			
			$arData['records'] = array_slice($arAllData, 0, $this->shop->get_option('wpsg_mod_statistics_topproductcount'));
			
			$this->calculateSonstiges($arAllData, $arData);
			
			$arData['records'] = $this->calculate($arData['records']);
			
			$arData['y2max'] = $this->retrieveMaxMenge($arData);
			
			$arData['template'] = 'all';
			
			$this->addSorting($arData, $params['order'], ((!wpsg_isSizedString($params['sort']))?'name':$params['sort']));
			
			return $arData;
	
		}
		
		/**
		 * prozentuale Angaben für Pie-Chart korrigieren (< 1% = 1%)
		 * @param 	array	$arData
		 * @return	array
		 */
		protected function calculate($arData =array())
		{
			
			$arTempData = array();
			
			if (wpsg_isSizedArray($arData))
			{
			
				foreach ($arData as $data)
				{
					
					if (is_string($data['mod_vp_varkey']) && strlen($data['mod_vp_varkey']))
					{
						
						$arVariantenInfo = $this->shop->callMod('wpsg_mod_varianten', 'getVariantenInfoArray', array($data['mod_vp_varkey']));
						
						if (wpsg_isSizedArray($arVariantenInfo))
						{
							$data['name'] .= ' '.$arVariantenInfo['key'];
						}
					}
		
					$arTempData[] = $data;
		
					$totalSales += $data['total']; 
					
					$totalAmount += $data['amount'];
					
				}
				
				if (wpsg_isSizedArray($arTempData))
				{
					foreach ($arTempData as $index => $data)
					{
						$arTempData[$index]['percent-sales'] = round(($data['total'] * 100)/$totalSales, 2);	
						$arTempData[$index]['percent-amount'] = round(($data['amount'] * 100)/$totalAmount, 2);	
						
						/*if ($arTempData[$index]['percent-sales'] < 1)
						{
							$arTempData[$index]['percent-sales'] = 1;
						}*/
						
					}	
				}
				
			}
			
			return $arTempData;
			
		}
		
}

?>