示例#1
0
 public function testCreateAndRetrieve()
 {
     // set up currency
     if (ActiveRecord::objectExists('Currency', 'USD')) {
         $this->usd = Currency::getInstanceByID('USD', Currency::LOAD_DATA);
     } else {
         $this->usd = Currency::getNewInstance('USD');
         $this->usd->setAsDefault();
         $this->usd->save();
     }
     $products = array();
     for ($k = 0; $k <= 2; $k++) {
         $products[$k] = Product::getNewInstance($this->root);
         $products[$k]->setPrice($this->usd, $k + 1);
         $products[$k]->save();
         $bundled = ProductBundle::getNewInstance($this->container, $products[$k]);
         $bundled->save();
     }
     $list = ProductBundle::getBundledProductSet($this->container);
     $this->assertEqual($list->size(), count($products));
     foreach ($list as $index => $item) {
         $this->assertSame($item->relatedProduct->get(), $products[$index]);
     }
     $this->assertEqual(ProductBundle::getTotalBundlePrice($this->container, $this->usd), 6);
 }
示例#2
0
 /**
  * !Running tests not involving initOrder() method will not recreate Currency,
  * but setUp() method is wiping all Currecy records,
  *
  * Store frontend is not working without Currency object
  *
  * As workround this method can be called from test suite to recreate Currency
  *
  * @todo: reorganize tests to call DELETE FROM Currency only when setUpCurrency() method is called.
  *
  */
 protected function setUpCurrency()
 {
     if (ActiveRecord::objectExists('Currency', 'USD')) {
         $this->usd = Currency::getInstanceByID('USD', Currency::LOAD_DATA);
     } else {
         $this->usd = Currency::getNewInstance('USD');
         $this->usd->setAsDefault();
         $this->usd->save();
     }
 }
示例#3
0
 public function process()
 {
     try {
         $usd = Currency::getInstanceByID('USD', true);
     } catch (Exception $e) {
         return;
     }
     if (!$usd->isEnabled->get()) {
         return;
     }
     $app = ActiveRecordModel::getApplication();
     $request = $app->getRequest();
     $request->set('currency', $usd->getID());
     $app->getRouter()->removeAutoAppendVariable('currency');
 }
示例#4
0
 protected function getInstance($record, CsvImportProfile $profile)
 {
     $fields = $profile->getSortedFields();
     if (isset($fields['Currency']['ID'])) {
         try {
             $instance = Currency::getInstanceByID($record[$fields['Currency']['ID']], true);
         } catch (ARNotFoundException $e) {
         }
     } else {
         return;
     }
     if (empty($instance)) {
         $instance = Currency::getNewInstance($record[$fields['Currency']['ID']]);
     }
     $this->setLastImportedRecordName($instance->getID());
     return $instance;
 }
示例#5
0
 private function createOrder()
 {
     $user = User::getNewInstance('*****@*****.**');
     $user->save();
     $currency = Currency::getInstanceByID('USD');
     $product = Product::getNewInstance(Category::getRootNode());
     $product->isEnabled->set(true);
     $product->stockCount->set(100);
     $product->setPrice($currency, 100);
     $product->setValueByLang('name', null, 'Test name');
     $product->setValueByLang('shortDescription', null, 'Really short description');
     $product->save();
     $order = CustomerOrder::getNewInstance($user);
     $order->addProduct($product, 1);
     $order->save();
     return $order;
 }
示例#6
0
 public function __get($name)
 {
     if ($inst = parent::__get($name)) {
         return $inst;
     }
     switch ($name) {
         case 'order':
             ClassLoader::import('application.model.order.SessionOrder');
             $this->order = SessionOrder::getOrder();
             // check if order currency matches the request currency
             if (!$this->order->currency->get() || $this->order->currency->get()->getID() != $this->getRequestCurrency()) {
                 $this->order->changeCurrency(Currency::getInstanceByID($this->getRequestCurrency()));
             }
             return $this->order;
             break;
         default:
             break;
     }
 }
示例#7
0
 public function setConfig()
 {
     if (!$this->buildConfigValidator()->isValid()) {
         return new ActionRedirectResponse('install', 'config');
     }
     Language::deleteCache();
     // site name
     $this->config->setValueByLang('STORE_NAME', $this->request->get('language'), $this->request->get('name'));
     $this->config->save();
     ClassLoader::import('application.model.Currency');
     // create currency
     if (ActiveRecord::objectExists('Currency', $this->request->get('curr'))) {
         $currency = Currency::getInstanceByID($this->request->get('curr'), Currency::LOAD_DATA);
     } else {
         $currency = ActiveRecord::getNewInstance('Currency');
         $currency->setID($this->request->get('curr'));
         $currency->isEnabled->set(true);
         $currency->isDefault->set(true);
         $currency->save(ActiveRecord::PERFORM_INSERT);
     }
     ClassLoader::import('application.model.system.Language');
     // create language
     if (ActiveRecord::objectExists('Language', $this->request->get('language'))) {
         $language = Language::getInstanceByID($this->request->get('language'), Language::LOAD_DATA);
     } else {
         $language = ActiveRecord::getNewInstance('Language');
         $language->setID($this->request->get('language'));
         $language->save(ActiveRecord::PERFORM_INSERT);
         $language->isEnabled->set(true);
         $language->isDefault->set(true);
         $language->save();
     }
     // set root category name to "LiveCart"
     ClassLoader::import('application.model.category.Category');
     $root = Category::getInstanceById(Category::ROOT_ID, Category::LOAD_DATA);
     $root->setValueByLang('name', $language->getID(), 'LiveCart');
     $root->save();
     // create a default shipping service
     ClassLoader::import('application.model.delivery.DeliveryZone');
     ClassLoader::import('application.model.delivery.ShippingService');
     ClassLoader::import('application.model.delivery.ShippingRate');
     $service = ShippingService::getNewInstance(DeliveryZone::getDefaultZoneInstance(), 'Default Service', ShippingService::SUBTOTAL_BASED);
     $service->save();
     $rate = ShippingRate::getNewInstance($service, 0, 100000);
     $rate->flatCharge->set(10);
     $rate->save();
     // create a couple of blank static pages
     ClassLoader::import('application.model.staticpage.StaticPage');
     $page = StaticPage::getNewInstance();
     $page->setValueByLang('title', $language->getID(), 'Contact Info');
     $page->setValueByLang('text', $language->getID(), 'Enter your contact information here');
     $page->menu->set(array('INFORMATION' => true));
     $page->save();
     $page = StaticPage::getNewInstance();
     $page->setValueByLang('title', $language->getID(), 'Shipping Policy');
     $page->setValueByLang('text', $language->getID(), 'Enter your shipping rate & policy information here');
     $page->menu->set(array('INFORMATION' => true));
     $page->save();
     // create an example site news post
     ClassLoader::import('application.model.sitenews.NewsPost');
     $news = ActiveRecordModel::getNewInstance('NewsPost');
     $news->setValueByLang('title', $language->getID(), 'Our store is open');
     $news->setValueByLang('text', $language->getID(), 'Powered by LiveCart software, we have gone live! Of course, we will have to go to <a href="../backend">the backend area</a> and add some categories and products first...');
     $news->setValueByLang('moreText', $language->getID(), 'Do not forget to delete this post when you actually go live :)');
     $news->isEnabled->set(true);
     $news->save();
     return new ActionRedirectResponse('install', 'finish');
 }
示例#8
0
 public function index()
 {
     $this->loadLanguageFile('Category');
     $product = Product::getInstanceByID($this->request->get('id'), Product::LOAD_DATA, array('ProductImage', 'Manufacturer', 'Category'));
     $this->product = $product;
     if (!$product->isEnabled->get() || $product->parent->get()) {
         throw new ARNotFoundException('Product', $product->getID());
     }
     $product->loadPricing();
     $this->category = $product->getCategory();
     $this->categoryID = $product->getCategory()->getID();
     // get category path for breadcrumb
     $path = $product->category->get()->getPathNodeArray();
     include_once ClassLoader::getRealPath('application.helper.smarty') . '/function.categoryUrl.php';
     include_once ClassLoader::getRealPath('application.helper.smarty') . '/function.productUrl.php';
     foreach ($path as $nodeArray) {
         $url = createCategoryUrl(array('data' => $nodeArray), $this->application);
         if ($nodeArray['isEnabled']) {
             $this->addBreadCrumb($nodeArray['name_lang'], $url);
         }
     }
     // add filters to breadcrumb
     CategoryController::getAppliedFilters();
     // for root category products
     if (!isset($nodeArray)) {
         $nodeArray = array();
     }
     $params = array('data' => $nodeArray, 'filters' => array());
     foreach ($this->filters as $filter) {
         $f = $filter->toArray();
         $params['filters'][] = $f;
         $url = createCategoryUrl($params, $this->application);
         $this->addBreadCrumb($f['name_lang'], $url);
     }
     $productArray = $product->toArray();
     $handle = empty($productArray['URL']) ? $productArray['name_lang'] : $productArray['URL'];
     $this->redirect301($this->request->get('producthandle'), createHandleString($handle));
     //ProductSpecification::loadSpecificationForProductArray($productArray);
     // filter empty attributes
     foreach ($productArray['attributes'] as $key => $attr) {
         if (empty($attr['value']) && empty($attr['values']) && empty($attr['value_lang'])) {
             unset($productArray['attributes'][$key]);
         }
     }
     // attribute summary
     $productArray['listAttributes'] = array();
     foreach ($productArray['attributes'] as $key => $attr) {
         if ($attr['SpecField']['isDisplayedInList']) {
             $productArray['listAttributes'][] = $attr;
         }
         if (!$attr['SpecField']['isDisplayed']) {
             unset($productArray['attributes'][$key]);
         }
     }
     // add product title to breacrumb
     $this->addBreadCrumb($productArray['name_lang'], createProductUrl(array('product' => $productArray), $this->application));
     // manufacturer filter
     if ($product->manufacturer->get()) {
         $manFilter = new ManufacturerFilter($product->manufacturer->get()->getID(), $product->manufacturer->get()->name->get());
     }
     // get category page route
     end($this->breadCrumb);
     $last = prev($this->breadCrumb);
     $catRoute = $this->router->getRouteFromUrl($last['url']);
     $response = new ActionResponse();
     $response->set('product', $productArray);
     $response->set('category', $productArray['Category']);
     $response->set('quantity', $this->getQuantities($product));
     $response->set('currency', $this->request->get('currency', $this->application->getDefaultCurrencyCode()));
     $response->set('catRoute', $catRoute);
     // ratings
     if ($this->config->get('ENABLE_RATINGS')) {
         if ($product->ratingCount->get() > 0) {
             // rating summaries
             ClassLoader::import('application.model.product.ProductRatingSummary');
             $response->set('rating', ProductRatingSummary::getProductRatingsArray($product));
         }
         ClassLoader::import('application.model.category.ProductRatingType');
         $ratingTypes = ProductRatingType::getProductRatingTypeArray($product);
         $response->set('ratingTypes', $ratingTypes);
         $response->set('ratingForm', $this->buildRatingForm($ratingTypes, $product));
         $response->set('isRated', $this->isRated($product));
         $response->set('isLoginRequiredToRate', $this->isLoginRequiredToRate());
         $response->set('isPurchaseRequiredToRate', $this->isPurchaseRequiredToRate($product));
     }
     // add to cart form
     $response->set('cartForm', $this->buildAddToCartForm($this->getOptions(), $this->getVariations()));
     // related products
     $related = $this->getRelatedProducts($product);
     // items purchased together
     $together = $product->getProductsPurchasedTogether($this->config->get('NUM_PURCHASED_TOGETHER'), true);
     $spec = array();
     foreach ($related as $key => $group) {
         foreach ($related[$key] as $i => &$prod) {
             $spec[] =& $related[$key][$i];
         }
     }
     foreach ($together as &$prod) {
         $spec[] =& $prod;
     }
     ProductSpecification::loadSpecificationForRecordSetArray($spec);
     $response->set('related', $related);
     $response->set('together', $together);
     if (isset($manFilter)) {
         $response->set('manufacturerFilter', $manFilter);
     }
     $response->set('variations', $this->getVariations());
     // reviews
     if ($this->config->get('ENABLE_REVIEWS') && $product->reviewCount->get() && ($numReviews = $this->config->get('NUM_REVIEWS_IN_PRODUCT_PAGE'))) {
         $f = new ARSelectFilter(new EqualsCond(new ARFieldHandle('ProductReview', 'isEnabled'), true));
         $f->setLimit($numReviews);
         $reviews = $product->getRelatedRecordSetArray('ProductReview', $f);
         $this->pullRatingDetailsForReviewArray($reviews);
         $response->set('reviews', $reviews);
     }
     // bundled products
     if ($product->isBundle()) {
         $bundleData = ProductBundle::getBundledProductArray($product);
         $bundledProducts = array();
         foreach ($bundleData as &$bundled) {
             $bundledProducts[] =& $bundled['RelatedProduct'];
         }
         ProductPrice::loadPricesForRecordSetArray($bundledProducts);
         $response->set('bundleData', $bundleData);
         $currency = Currency::getInstanceByID($this->getRequestCurrency());
         $total = ProductBundle::getTotalBundlePrice($product, $currency);
         $response->set('bundleTotal', $currency->getFormattedPrice($total));
         $saving = $total - $product->getPrice($currency);
         $response->set('bundleSavingTotal', $currency->getFormattedPrice($saving));
         $response->set('bundleSavingPercent', $total ? round($saving / $total * 100) : 0);
     }
     // contact form
     if ($this->config->get('PRODUCT_INQUIRY_FORM')) {
         $response->set('contactForm', $this->buildContactForm());
     }
     // display theme
     if ($theme = CategoryPresentation::getThemeByProduct($product)) {
         if ($theme->getTheme()) {
             $this->application->setTheme($theme->getTheme());
         }
         $response->set('presentation', $theme->toFlatArray());
     }
     // product images
     $images = $product->getImageArray();
     if ($theme && $theme->isVariationImages->get()) {
         if ($variations = $this->getVariations()) {
             foreach ($variations['products'] as $prod) {
                 if (!empty($prod['DefaultImage']['ID'])) {
                     $images[] = $prod['DefaultImage'];
                 }
             }
         }
     }
     $response->set('images', $images);
     // discounted pricing
     $response->set('quantityPricing', $product->getPricingHandler()->getDiscountPrices($this->user, $this->getRequestCurrency()));
     $response->set('files', $this->getPublicFiles());
     // additional categories
     $f = new ARSelectFilter();
     $f->setOrder(new ARFieldHandle('Category', 'lft'));
     $f->mergeCondition(new EqualsCond(new ARFieldHandle('Category', 'isEnabled'), true));
     $pathC = new OrChainCondition();
     $pathF = new ARSelectFilter($pathC);
     $categories = array();
     foreach ($product->getRelatedRecordSetArray('ProductCategory', $f, array('Category')) as $cat) {
         $categories[] = array($cat['Category']);
         $cond = new OperatorCond(new ARFieldHandle('Category', 'lft'), $cat['Category']['lft'], "<");
         $cond->addAND(new OperatorCond(new ARFieldHandle('Category', 'rgt'), $cat['Category']['rgt'], ">"));
         $pathC->addAnd($cond);
     }
     if ($categories) {
         $pathF->setOrder(new ARFieldHandle('Category', 'lft'), 'DESC');
         $pathF->mergeCondition(new EqualsCond(new ARFieldHandle('Category', 'isEnabled'), true));
         foreach (ActiveRecordModel::getRecordSetArray('Category', $pathF, array('Category')) as $parent) {
             if (!$parent['isEnabled']) {
                 continue;
             }
             foreach ($categories as &$cat) {
                 if ($cat[0]['lft'] > $parent['lft'] && $cat[0]['rgt'] < $parent['rgt'] && $parent['ID'] > Category::ROOT_ID) {
                     $cat[] = $parent;
                 }
             }
         }
         foreach ($categories as &$cat) {
             $cat = array_reverse($cat);
         }
         $response->set('additionalCategories', $categories);
     }
     $response->set('enlargeProductThumbnailOnMouseOver', $this->config->get('_ENLARGE_PRODUCT_THUMBNAILS_ON') == 'P_THUMB_ENLARGE_MOUSEOVER');
     return $response;
 }
示例#9
0
 /**
  * @role update
  */
 public function save()
 {
     $currency = Currency::getInstanceByID($this->request->get('id'), Currency::LOAD_DATA);
     $currency->loadRequestData($this->request);
     $currency->rounding->set(serialize(json_decode($this->request->get('rounding'), true)));
     $currency->save();
     return new JSONResponse(false, 'success');
 }
示例#10
0
 public static function transformArray($array, ARSchema $schema)
 {
     $array = parent::transformArray($array, $schema);
     try {
         $array['formattedAmount'] = Currency::getInstanceByID($array['Currency']['ID'])->getFormattedPrice($array['amount']);
         $array['formattedRealAmount'] = Currency::getInstanceByID($array['RealCurrency']['ID'])->getFormattedPrice($array['realAmount']);
     } catch (ARNotFoundException $e) {
     }
     $array['methodName'] = self::getApplication()->getLocale()->translator()->translate($array['method']);
     $array['serializedData'] = unserialize($array['serializedData']);
     $array['ccLastDigits'] = self::decrypt($array['ccLastDigits']);
     if (strlen($array['ccCVV']) > 0) {
         $array['ccCVV'] = self::decrypt($array['ccCVV']);
     }
     return $array;
 }
 private function save(RecurringProductPeriod $rpp)
 {
     $request = $this->getRequest();
     $validator = $this->createFormValidator($rpp->toArray());
     if ($validator->isValid()) {
         $rpp->loadRequestData($this->request);
         // null value is not set by loadRequestData()..
         $rebillCount = $this->request->get('rebillCount');
         $rebillCount = floor($rebillCount);
         $rpp->rebillCount->set(is_numeric($rebillCount) && $rebillCount <= 0 ? $rebillCount : NULL);
         $rpp->save();
         $product = $rpp->product->get();
         $currencies = array();
         foreach ($this->application->getCurrencyArray(true) as $currency) {
             if (array_key_exists($currency, $currencies) == false) {
                 $currencies[$currency] = Currency::getInstanceByID($currency);
             }
             foreach (array(ProductPrice::TYPE_SETUP_PRICE => $request->get('ProductPrice_setup_price_' . $currency), ProductPrice::TYPE_PERIOD_PRICE => $request->get('ProductPrice_period_price_' . $currency)) as $type => $value) {
                 $price = ProductPrice::getInstance($product, $currencies[$currency], $rpp, $type);
                 if (strlen($value) == 0 && $price->isExistingRecord()) {
                     $price->delete();
                 } else {
                     $price->price->set($value);
                     $price->save();
                 }
             }
         }
         return new JSONResponse(array('rpp' => $rpp->toArray()), 'success');
     } else {
         return new JSONResponse(array('errors' => $validator->getErrorList()), 'failure', $this->translate('_could_not_save_recurring_product_period_entry'));
     }
 }
示例#12
0
 public static function transformArray($array, ARSchema $schema)
 {
     $array = parent::transformArray($array, $schema);
     $currency = Currency::getInstanceByID($array['currencyID']);
     $array['serializedRules'] = unserialize($array['serializedRules']);
     if ($array['serializedRules'] && !is_array($array['serializedRules'])) {
         $array['serializedRules'] = array();
     }
     if ($array['serializedRules'] && is_array($array['serializedRules'])) {
         $ruleController = self::getApplication()->getBusinessRuleController();
         $quantities = array_keys($array['serializedRules']);
         $nextQuant = array();
         foreach ($quantities as $key => $quant) {
             $nextQuant[$quant] = isset($quantities[$key + 1]) ? $quantities[$key + 1] - 1 : null;
         }
         foreach ($array['serializedRules'] as $quantity => $prices) {
             foreach ($prices as $group => $price) {
                 $originalPrice = $currency->roundPrice($price);
                 $product = isset($array['Product']) ? $array['Product'] : Product::getInstanceByID($array['productID']);
                 $price = $ruleController->getProductPrice($product, $originalPrice);
                 $array['quantityPrices'][$group][$quantity] = array('originalPrice' => $originalPrice, 'price' => $price, 'originalFormattedPrice' => $currency->getFormattedPrice($originalPrice), 'formattedPrice' => $currency->getFormattedPrice($price), 'from' => $quantity, 'to' => $nextQuant[$quantity]);
             }
         }
     }
     return $array;
 }
示例#13
0
 public function getDiscountPrices(User $user, $currency)
 {
     if (!$currency instanceof Currency) {
         $currency = Currency::getInstanceByID($currency);
     }
     $price = $this->getPrice($currency);
     if (!$price->getPrice()) {
         $price = $this->getPriceByCurrencyCode($this->application->getDefaultCurrencyCode());
     }
     $prices = array();
     foreach ($price->getUserPrices($user) as $quant => $pr) {
         $pr = $currency->convertAmount($price->currency->get(), $pr);
         $pr = $this->application->getDisplayTaxPrice($pr, $this->product);
         $prices[$quant] = array('price' => $pr, 'formattedPrice' => $currency->getFormattedPrice($pr), 'from' => $quant);
     }
     foreach ($prices as $quant => &$price) {
         if (isset($previousPrice)) {
             $previousPrice['to'] = $quant - 1;
         }
         $previousPrice =& $price;
     }
     return $prices;
 }
示例#14
0
 public static function includeProductPrice(Product $product, &$options)
 {
     $prices = $product->getPricingHandler()->toArray();
     $prices = $prices['calculated'];
     foreach ($options as &$option) {
         if (!empty($option['choices'])) {
             foreach ($option['choices'] as &$choice) {
                 foreach ($prices as $currency => $price) {
                     $instance = Currency::getInstanceByID($currency);
                     $choice['formattedTotalPrice'][$currency] = $instance->getFormattedPrice($price + $instance->convertAmountFromDefaultCurrency($choice['priceDiff']));
                 }
             }
         }
     }
 }
示例#15
0
 public function getPriceDiff($currencyCode, $basePrice = false)
 {
     $basePrice = false === $basePrice ? $this->priceDiff->get() : $basePrice;
     return ProductPrice::convertPrice(Currency::getInstanceByID($currencyCode), $basePrice);
 }
示例#16
0
 public function toArray($currencyID = null)
 {
     $array = parent::toArray();
     $rs = ProductPrice::getRecurringProductPeriodPrices($this, $currencyID);
     $currencies = array();
     if ($rs && $rs->size()) {
         $mapping = array(ProductPrice::TYPE_PERIOD_PRICE => 'ProductPrice_period', ProductPrice::TYPE_SETUP_PRICE => 'ProductPrice_setup');
         while (false != ($item = $rs->shift())) {
             $itemArray = $item->toArray();
             if ($itemArray['type'] == ProductPrice::TYPE_SETUP_PRICE || $itemArray['type'] == ProductPrice::TYPE_PERIOD_PRICE) {
                 $array[$mapping[$itemArray['type']]][$itemArray['currencyID']] = $itemArray;
                 if (array_key_exists($itemArray['currencyID'], $currencies) == false) {
                     $currencies[$itemArray['currencyID']] = Currency::getInstanceByID($itemArray['currencyID']);
                 }
                 $array[$mapping[$itemArray['type']]]['formated_price'][$itemArray['currencyID']] = $currencies[$itemArray['currencyID']]->getFormattedPrice($itemArray['price']);
             }
         }
     }
     return $array;
 }
示例#17
0
 public function toArray()
 {
     $array = parent::toArray();
     $currencyID = $array['OrderedItem']['CustomerOrder']['currencyID'];
     $currency = Currency::getInstanceByID($currencyID);
     $array['ProductPrice_setup']['formated_price'][$currencyID] = $currency->getFormattedPrice($array['setupPrice']);
     $array['ProductPrice_period']['formated_price'][$currencyID] = $currency->getFormattedPrice($array['periodPrice']);
     return $array;
 }
示例#18
0
 public function getVariationMatrix()
 {
     $ids = $prices = array();
     foreach ($this as $record) {
         $id = $record->getParent()->getID();
         $ids[] = $id;
         $prices[$id] = $record->getParent()->getPricingHandler()->toArray();
         $parents[$id] = $record->getParent()->toArray();
     }
     $f = new ARSelectFilter(new INCond(new ARFieldHandle('Product', 'parentID'), $ids));
     $children = ActiveRecordModel::getRecordSetArray('Product', $f, array('ProductImage'));
     if (!$children) {
         return array();
     }
     foreach ($children as &$child) {
         $child['Parent'] = $parents[$child['parentID']];
     }
     ProductPrice::loadPricesForRecordSetArray($children);
     $ids = array();
     foreach ($children as &$child) {
         $ids[] = $child['ID'];
         $products[$child['ID']] =& $child;
     }
     // calculate final children prices
     foreach ($children as &$child) {
         $setting = $child['childSettings']['price'];
         $child['finalPrice'] = $child['finalFormattedPrice'] = array();
         $parent = $prices[$child['parentID']];
         foreach ($parent['calculated'] as $id => $price) {
             $currency = Currency::getInstanceByID($id);
             $priceField = 'price_' . $id;
             if (!isset($child[$priceField])) {
                 $child[$priceField] = 0;
             }
             $child['finalPrice'][$id] = $child[$priceField];
             $child['finalPrice'][$id] = $currency->roundPrice($child['finalPrice'][$id]);
             $child['finalFormattedPrice'][$id] = $currency->getFormattedPrice($child['finalPrice'][$id]);
         }
     }
     $f = new ARSelectFilter(new INCond(new ARFieldHandle('ProductVariationValue', 'productID'), $ids));
     $f->setOrder(new ARFieldHandle('ProductVariationType', 'position'));
     $f->setOrder(new ARFieldHandle('ProductVariation', 'position'));
     $productValues = array();
     $variations = array();
     $values = ActiveRecordModel::getRecordSetArray('ProductVariationValue', $f, array('ProductVariation', 'ProductVariationType'));
     foreach ($values as &$value) {
         $type = $value['ProductVariationType'];
         $parentID = $type['productID'];
         if (!isset($variations[$parentID][$type['ID']])) {
             $variations[$parentID][$type['ID']] = $type;
             $variations[$parentID][$type['ID']]['variations'] = array();
         }
         $variations[$parentID][$type['ID']]['variations'][] = $value;
         $productValues[$parentID][$value['productID']][$value['variationID']] =& $value;
     }
     $matrix = array();
     foreach ($productValues as $parentID => &$allValues) {
         foreach ($allValues as $product => &$values) {
             $matrix[$parentID][implode('-', array_keys($values))] = $products[$product];
         }
     }
     return array('products' => $matrix, 'variations' => $variations);
 }