/** * Action that gets called before we interface with our payment * method. * * This action is responsible for setting up an order and * saving it into the database (as well as a session) and then hands * the current request over to the relevent payment handler * for final processing. * * @param $request Current request object */ public function index($request) { $cart = ShoppingCart::get(); $data = array(); $payment_data = array(); $handler = $this->payment_handler; // If shopping cart doesn't exist, redirect to base if (!$cart->getItems()->exists() || $this->getPaymentHandler() === null) { return $this->redirect($cart->Link()); } // Get billing and delivery details and merge into an array $billing_data = Session::get("Checkout.BillingDetailsForm.data"); $delivery_data = Session::get("Checkout.DeliveryDetailsForm.data"); // If we have applied free shipping, set that up, else get if (Session::get('Checkout.PostageID') == -1) { $postage = Checkout::CreateFreePostageObject(); } else { $postage = PostageArea::get()->byID(Session::get('Checkout.PostageID')); } // If we are using a complex checkout and do not have correct // details redirect if (!Checkout::config()->simple_checkout && !$cart->isCollection() && (!$postage || !$billing_data || !$delivery_data)) { return $this->redirect(Checkout_Controller::create()->Link()); } if ($cart->isCollection() && !$billing_data) { return $this->redirect(Checkout_Controller::create()->Link()); } // Create an order number $data["OrderNumber"] = substr(chunk_split(Checkout::getRandomNumber(), 4, '-'), 0, -1); // Setup holder for Payment ID $data["PaymentID"] = 0; // Set status $data['Status'] = 'incomplete'; // Assign billing, delivery and postage data if (!Checkout::config()->simple_checkout) { $data = array_merge($data, $billing_data); $data = is_array($delivery_data) ? array_merge($data, $delivery_data) : $data; $checkout_data = Checkout::config()->checkout_data; if (!$cart->isCollection()) { $data['PostageType'] = $postage->Title; $data['PostageCost'] = $postage->Cost; $data['PostageTax'] = $postage->Tax ? $postage->Cost / 100 * $postage->Tax : 0; } if ($cart->getDiscount()) { $data['Discount'] = $cart->getDiscount()->Title; $data['DiscountAmount'] = $cart->DiscountAmount; } // Add full country names if needed if (in_array("CountryFull", $checkout_data)) { $data['CountryFull'] = Checkout::country_name_from_code($data["Country"]); } if (in_array("DeliveryCountryFull", $checkout_data) && array_key_exists("DeliveryCountry", $data)) { $data['DeliveryCountryFull'] = Checkout::country_name_from_code($data["DeliveryCountry"]); } foreach ($checkout_data as $key) { if (array_key_exists($key, $data)) { $payment_data[$key] = $data[$key]; } } } // Set our order data as a generic object $handler->setOrderData(ArrayData::array_to_object($payment_data)); return $handler->handleRequest($request, $this->model); }
/** * Find relevent postage rates, based on supplied: * - Country * - Zip/postal code * - Weight * - Cost * - Number of Items * * This is returned as an ArrayList that can be looped through. * * @return ArrayList */ public function getPostageAreas() { $return = ArrayList::create(); $config = SiteConfig::current_site_config(); $cart = ShoppingCart::get(); $discount = $cart->getDiscount(); $filter_zipcode = strtolower(substr($this->zipcode, 0, 2)); if ($this->include_wildcards) { $filter = array("Country:PartialMatch" => array($this->country_code, "*"), "ZipCode:PartialMatch" => array($filter_zipcode, "*")); } else { $filter = array("Country:PartialMatch" => $this->country_code, "ZipCode:PartialMatch" => $filter_zipcode); } // Find any postage areas that match our filter $postage_areas = $config->PostageAreas()->filter($filter); // Check if any discounts are set with free postage // This is a little hacky at the moment, need to find a nicer // way to add free shipping. if ($discount && $discount->Type == "Free Shipping" && (strpos($discount->Country, $this->country_code) !== false || $discount->Country == "*")) { $postage = Checkout::CreateFreePostageObject(); $return->add($postage); } // Make sure we don't effect any associations foreach ($postage_areas as $item) { $return->add($item); } // Before doing anything else, remove any wildcards (if needed) $exact_country = false; // Find any countries that are exactly matched foreach ($return as $location) { if ($location->Country != "*") { $exact_country = true; } } // If exactly matched, remove any wildcards foreach ($return as $location) { if ($exact_country && $location->Country == "*" && $location->ID != -1) { $return->remove($location); } } // Now we have a list of locations, start checking for additional // rules an remove if not applicable. $total_cost = $this->cost; $total_weight = $this->weight; $total_items = $this->items; $max_cost = 0; $max_weight = 0; $max_items = 0; // First loop through and find items that are invalid foreach ($return as $location) { if ($location->Calculation == "Price" && $total_cost < $location->Unit) { $return->remove($location); } if ($location->Calculation == "Weight" && $total_weight < $location->Unit) { $return->remove($location); } if ($location->Calculation == "Items" && $total_items < $location->Unit) { $return->remove($location); } } // Now find max values based on units foreach ($return as $location) { if ($location->Calculation == "Price" && $location->Unit > $max_cost) { $max_cost = $location->Unit; } if ($location->Calculation == "Weight" && $location->Unit > $max_weight) { $max_weight = $location->Unit; } if ($location->Calculation == "Items" && $location->Unit > $max_items) { $max_items = $location->Unit; } } // Now loop through again and calculate which brackets each // Location fits in foreach ($return as $location) { if ($location->Calculation == "Price" && $location->Unit < $max_cost) { $return->remove($location); } if ($location->Calculation == "Weight" && $location->Unit < $max_weight) { $return->remove($location); } if ($location->Calculation == "Items" && $location->Unit < $max_items) { $return->remove($location); } } return $return; }