<commit_before><?php
/**
 * Chowly Pick. Eat. Save!
 * @copyright	Copyright 2011, <NAME>
 * @copyright	Copyright 2011, Chowly Corporation
 */

namespace chowly\controllers;

use li3_flash_message\extensions\storage\FlashMessage;
use chowly\models\Inventories;
use chowly\models\Venues;
use chowly\models\Offers;
use chowly\models\Purchases;
use chowly\extensions\Utils;
use chowly\extensions\data\InventoryException;
use lithium\net\http\Router;
use lithium\analysis\Logger;
use Swift_MailTransport;
use Swift_Mailer;
use Swift_Message;
use Swift_Attachment;

class CheckoutsController extends \chowly\extensions\action\Controller{

	protected function _init(){
		parent::_init();
		/** TODO: lets wait before requiring this
		if(!$this->request->is('ssl')){
			return $this->redirect(Router::match(
				$this->request->params,
				$this->request,
				array('absolute' => true, 'scheme'=>'https://')
				)
			);
		}*/
	}

	public function confirm(){
		if ($this->Cart->isEmpty()){
			FlashMessage::set("Your cart is currently empty.");
			return $this->redirect("Offers::index");
		}

		$cart_items = $this->Cart->items();
		$conditions = array('_id' => array());

		foreach ($cart_items as $item){
			$conditions['_id'][] = $item->_id;
		}

		$offers = Offers::all(compact('conditions'));

		return compact('offers','cart_items');
	}

	public function checkout(){
		$provinces = Purchases::getProvinces();

		if ($this->Cart->isEmpty()){
			FlashMessage::set("Your cart is currently empty.");
			return $this->redirect("Offers::index");
		}

		if (!$this->Cart->startTransaction()){
			FlashMessage::set("There is a transaction in progress on your cart. Please try again.");
			return $this->redirect("Offers::index");
		}

		//Secure inventory so it does not expire while in checkout.
		$this->_secureInventory();

		$purchase = Purchases::create();
		//TODO: Credit Card data processing...
		if ($this->request->data){
			$purchase->set($this->request->data);
			$purchase->status = 'new';

			if (!$purchase->validates()){
				unset($purchase->cc_number, $purchase->cc_sc);
				$this->Cart->endTransaction();
				return compact('purchase', 'provinces');
			}

			$offers = $this->_getCartOffers();

			//TODO: Log transaction for history/accounting
			try{
				$purchase->process($offers);
			}catch(\Exception $e){
				unset($purchase->cc_number, $purchase->cc_sc);
				Logger::write('notice',
					"C[{$cart->_id}] Could not process purchase due to: " . $e->getMessage(),
					array('name'=>'transactions')
				);
				FlashMessage::set("Some processing errors occured.");

				$this->Cart->endTransaction();
				return compact('purchase', 'provinces');
			}

			unset($purchase->cc_number, $purchase->cc_sc);

			if (!$purchase->isCompleted()){
				Logger::write('notice',
					"C[{$cart->_id}] Transaction failed: {$purchase->error}.",
					array('name'=>'transactions')
				);
				FlashMessage::set("The purchase could not be completed.");

				$this->Cart->endTransaction();
				return compact('purchase', 'provinces');
			}

			$message = "P[{$purchase->_id}] Transaction completed.";
			Logger::write('info', $message, array('name'=>'transactions'));

			$this->_markItemsPurchased($purchase);

			$venues = $this->_getVenues($offers);

			$path = null;
			try{
				$path = Utils::getPdf($purchase, $offers, $venues);
			} catch (\Exception $e){
				Logger::write('error',
					"P[{$purchase->_id}] Could not generate pdf due to: " . $e->getMessage(),
					array('name'=>'transactions')
				);
			}

			$emailSent = $this->_sendEmail($purchase, $path);

			$this->Cart->endTransaction();
			$this->Cart->clearItems();

			$this->_render['template'] = 'success';
			return compact('purchase', 'emailSent');
		}

		$this->Cart->endTransaction();
		return compact('provinces', 'purchase');
	}

	/**
	 * Get the venues associated with the offers.
	 * @param DocumentSet $offers The offers collection to get venues for.
	 * @return DocumentSet A collection of venues.
	 */
	private function _getVenues($offers){
			$conditions = array('_id' => array());
			foreach ($offers as $offer){
				$conditions['_id'][] = $offer->venue_id;
			}
			return Venues::find('all', compact('conditions'));
	}

	/**
	 * Marks cart items as being purchased.
	 * @param var $purchase The purchase entity
	 */
	private function _markItemsPurchased($purchase){
		$items = $this->Cart->items();<commit_msg>Refactored purchase processing to be shorter<commit_after><?php
/**
 * Chowly Pick. Eat. Save!
 * @copyright	Copyright 2011, <NAME>
 * @copyright	Copyright 2011, Chowly Corporation
 */

namespace chowly\controllers;

use li3_flash_message\extensions\storage\FlashMessage;
use chowly\models\Inventories;
use chowly\models\Venues;
use chowly\models\Offers;
use chowly\models\Purchases;
use chowly\extensions\Utils;
use chowly\extensions\data\InventoryException;
use lithium\net\http\Router;
use lithium\analysis\Logger;
use Swift_MailTransport;
use Swift_Mailer;
use Swift_Message;
use Swift_Attachment;

class CheckoutsController extends \chowly\extensions\action\Controller{

	protected function _init(){
		parent::_init();
		/** TODO: lets wait before requiring this
		if(!$this->request->is('ssl')){
			return $this->redirect(Router::match(
				$this->request->params,
				$this->request,
				array('absolute' => true, 'scheme'=>'https://')
				)
			);
		}*/
	}

	public function confirm(){
		if ($this->Cart->isEmpty()){
			FlashMessage::set("Your cart is currently empty.");
			return $this->redirect("Offers::index");
		}

		$cart_items = $this->Cart->items();
		$conditions = array('_id' => array());

		foreach ($cart_items as $item){
			$conditions['_id'][] = $item->_id;
		}

		$offers = Offers::all(compact('conditions'));

		return compact('offers','cart_items');
	}

	public function checkout(){
		$provinces = Purchases::getProvinces();

		if ($this->Cart->isEmpty()){
			FlashMessage::set("Your cart is currently empty.");
			return $this->redirect("Offers::index");
		}

		if (!$this->Cart->startTransaction()){
			FlashMessage::set("There is a transaction in progress on your cart. Please try again.");
			return $this->redirect("Offers::index");
		}

		//Secure inventory so it does not expire while in checkout.
		$this->_secureInventory();

		$purchase = Purchases::create();

		if (!$this->request->data){
			$this->Cart->endTransaction();
			return compact('provinces', 'purchase');
		}

		$purchase->set($this->request->data);
		$purchase->status = 'new';

		if (!$purchase->validates()){
			unset($purchase->cc_number, $purchase->cc_sc);
			$this->Cart->endTransaction();
			return compact('purchase', 'provinces');
		}

		$offers = $this->_getCartOffers();
		//TODO: Credit Card data processing...
		$sucessfull = $this->_processPurchase($purchase, $offers);

		unset($purchase->cc_number, $purchase->cc_sc);

		if(!$sucessfull){
			$this->Cart->endTransaction();
			return compact('purchase', 'provinces');
		}

		$message = "P[{$purchase->_id}] Transaction completed.";
		Logger::write('info', $message, array('name'=>'transactions'));

		$this->_markItemsPurchased($purchase);

		$venues = $this->_getVenues($offers);

		$pdfPath = null;
		try{
			$pdfPath = Utils::getPdf($purchase, $offers, $venues);
		} catch (\Exception $e){
			Logger::write('error',
				"P[{$purchase->_id}] Could not generate pdf due to: " . $e->getMessage(),
				array('name'=>'transactions')
			);
		}

		$emailSent = $this->_sendEmail($purchase, $pdfPath);

		$this->Cart->endTransaction();
		$this->Cart->clearItems();

		$this->_render['template'] = 'success';
		return compact('purchase', 'emailSent', 'pdfPath');
	}

	/**
	 * Purchase processing handling
	 * @param var $purchase The purchase object
	 * @param var $offers The offers being purchased
	 * @return boolean
	 */
	private function _processPurchase($purchase, $offers){

		$processed = false;

		try{
			$processed = $purchase->process($offers);
		}catch(\Exception $e){
			Logger::write('notice',
				"C[{$cart->_id}] Could not process purchase due to: " . $e->getMessage(),
				array('name'=>'transactions')
			);
			FlashMessage::set("Some processing errors occured.");
			return false;
		}
		if (!$purchase->isCompleted()){
			Logger::write('notice',
				"C[{$cart->_id}] Transaction failed: {$purchase->error}.",
				array('name'=>'transactions')
			);
			FlashMessage::set("The purchase could not be completed.");
			return false;
		}

		return true;
	}
	/**
	 * Get the venues associated with the offers.
	 * @param DocumentSet $offers The offers collection to get venues for.
	 * @return DocumentSet A collection of venues.
	 */
	private function _getVenues($offers){
			$conditions = array('_id' => array());
			foreach ($offers as $offer){
				$conditions['_id'][] = $offer->venue_id;
			}
			return Venues::find('all', compact('conditions'));
	}

	/**
	 * Marks cart items as being purchased.
	 * @param var $purchase The purchase entity
	 */
	private function _markItemsPurchased($purchase){
		$items = $this->Cart->items();
{'fraction_non_alphanumeric': 0.17898832684824903, 'fraction_numerical': 0.0020011117287381877, 'mean_word_length': 4.354761904761904, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 140, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3500172', 'n_tokens_mistral': 3290, 'n_tokens_neox': 2816, 'n_words': 633}