Provides a means for specifying many variations on a product. Used in combination with ProductAttributes, such as color, size. A variation will specify one particular combination, such as red, and large.
Inheritance: extends DataObject, implements Buyable
Exemplo n.º 1
2
 public function actionGetVariations()
 {
     if (Yii::app()->request->isAjaxRequest && isset($_POST['product'])) {
         $product = Products::model()->findByPk($_POST['product']);
         echo CHtml::hiddenField('product_id', $product->product_id);
         if ($variations = $product->getVariations()) {
             foreach ($variations as $variation) {
                 $field = "Variations[{$variation[0]->specification_id}][]";
                 echo '<div class="shop-variation-element">';
                 echo '<strong>' . CHtml::label($variation[0]->specification->title . '</strong>', $field, array('class' => 'lbl-header'));
                 if ($variation[0]->specification->required) {
                     echo ' <span class="required">*</span>';
                 }
                 echo '<br />';
                 if ($variation[0]->specification->input_type == 'textfield') {
                     echo CHtml::textField($field);
                 } else {
                     if ($variation[0]->specification->input_type == 'select') {
                         // If the specification is required, preselect the first field.
                         // Otherwise  let the customer choose which one to pick
                         // 	$product->variationCount > 1 ? true : false means, that the
                         // widget should display the _absolute_ price if only 1 variation
                         // is available, otherwise the relative (+ X $)
                         echo CHtml::radioButtonList($field, $variation[0]->specification->required ? $variation[0]->id : null, ProductVariation::listData($variation, $product->variationCount > 1 ? true : false), array('template' => '{input} {label}', 'separator' => '<div class="clear"></div>'));
                     }
                 }
                 echo '</div>';
             }
         }
     } else {
         throw new CHttpException(404);
     }
 }
Exemplo n.º 2
0
function getSpecifications($position)
{
    $string = '<table class="specifications">';
    foreach ($position->getSpecifications() as $key => $specification) {
        if ($model = ProductSpecification::model()->findByPk($key)) {
            if ($model->input_type == 'textfield') {
                $title = $model->title;
                $value = $specification[0];
            } else {
                $title = $model->title;
                $productvariation = ProductVariation::model()->findByPk($specification[0]);
                if ($productvariation) {
                    $value = $productvariation->title;
                } else {
                    $value = '';
                }
            }
        } else {
            if ($key == 'image') {
                $title = Shop::t('Filename');
                $value = $specification;
            }
        }
        $string .= sprintf('<tr><td>%s</td><td>%s</td></tr>', @$title, @$value);
    }
    $string .= '</table>';
    return $string;
}
 public function testZeroPriceWithVariations()
 {
     Config::inst()->update('ProductCategory', 'must_have_price', true);
     $products = $this->electronics->ProductsShowable();
     $this->assertEquals(0, $products->count(), 'No product should be returned as there\'s no price set');
     // Create a variation for HDTV
     ProductVariation::create(array('InternalItemID' => '50-Inch', 'Price' => 1200, 'ProductID' => $this->hdtv->ID))->write();
     $products = $this->electronics->ProductsShowable();
     $this->assertDOSEquals(array(array('URLSegment' => 'hdtv')), $products, 'HDTV has a priced extension and should now show up in the list of products');
 }
Exemplo n.º 4
0
 public function getPrice()
 {
     $price = $this->product->price;
     if ($this->specifications) {
         foreach ($this->getSpecifications() as $key => $spec) {
             $price += @ProductVariation::model()->findByPk(@$spec[0])->price_adjustion;
         }
     }
     return $this->amount * $price;
 }
 public function testVariationOrderItem()
 {
     $cart = ShoppingCart::singleton();
     //config
     ProductVariation::config()->title_has_label = true;
     ProductVariation::config()->title_separator = ':';
     ProductVariation::config()->title_glue = ', ';
     $emptyitem = $this->redlarge->Item();
     $this->assertEquals(1, $emptyitem->Quantity, "Items always have a quantity of at least 1.");
     $cart->add($this->redlarge);
     $item = $cart->get($this->redlarge);
     $this->assertTrue((bool) $item, "item exists");
     $this->assertEquals(1, $item->Quantity);
     $this->assertEquals(22, $item->UnitPrice());
     $this->assertEquals("Size:Large, Color:Red", $item->SubTitle());
 }
 public function save()
 {
     ActiveRecordModel::beginTransaction();
     $parent = Product::getInstanceByID($this->request->get('id'), true);
     $items = json_decode($this->request->get('items'), true);
     $types = json_decode($this->request->get('types'), true);
     $variations = json_decode($this->request->get('variations'), true);
     $existingTypes = $existingVariations = $existingItems = array();
     $currency = $this->application->getDefaultCurrencyCode();
     // deleted types
     foreach ($types as $id) {
         if (is_numeric($id)) {
             $existingTypes[] = $id;
         }
     }
     $parent->deleteRelatedRecordSet('ProductVariationType', new ARDeleteFilter(new NotINCond(new ARFieldHandle('ProductVariationType', 'ID'), $existingTypes)));
     // deleted variations
     foreach ($variations as $type => $typeVars) {
         foreach ($typeVars as $id) {
             if (is_numeric($id)) {
                 $existingVariations[] = $id;
             }
         }
     }
     $f = new ARDeleteFilter(new INCond(new ARFieldHandle('ProductVariation', 'typeID'), $existingTypes));
     $f->mergeCondition(new NotINCond(new ARFieldHandle('ProductVariation', 'ID'), $existingVariations));
     ActiveRecordModel::deleteRecordSet('ProductVariation', $f);
     // deleted items
     foreach ($items as $id) {
         if (is_numeric($id)) {
             $existingItems[] = $id;
         }
     }
     $parent->deleteRelatedRecordSet('Product', new ARDeleteFilter(new NotINCond(new ARFieldHandle('Product', 'ID'), $existingItems)));
     // load existing records
     foreach (array('Types' => 'ProductVariationType', 'Variations' => 'ProductVariation', 'Items' => 'Product') as $arr => $class) {
         $var = 'existing' . $arr;
         $array = ${$var};
         if ($array) {
             ActiveRecordModel::getRecordSet($class, new ARSelectFilter(new INCond(new ARFieldHandle($class, 'ID'), $array)));
         }
     }
     $idMap = array();
     // save types
     $request = $this->request->toArray();
     foreach ($types as $index => $id) {
         if (!is_numeric($id)) {
             $type = ProductVariationType::getNewInstance($parent);
             $idMap[$id] = $type;
         } else {
             $type = ActiveRecordModel::getInstanceByID('ProductVariationType', $id);
         }
         $type->setValueByLang('name', null, $request['variationType'][$index]);
         $type->position->set($index);
         if (!empty($request['typeLang_' . $id])) {
             foreach ($request['typeLang_' . $id] as $field => $value) {
                 list($field, $lang) = explode('_', $field, 2);
                 $type->setValueByLang($field, $lang, $value);
             }
         }
         $type->save();
     }
     // save variations
     $tree = array();
     $typeIndex = -1;
     foreach ($variations as $typeID => $typeVars) {
         $type = is_numeric($typeID) ? ActiveRecordModel::getInstanceByID('ProductVariationType', $typeID) : $idMap[$typeID];
         $typeIndex++;
         foreach ($typeVars as $index => $id) {
             if (!is_numeric($id)) {
                 $variation = ProductVariation::getNewInstance($type);
                 $idMap[$id] = $variation;
             } else {
                 $variation = ActiveRecordModel::getInstanceByID('ProductVariation', $id);
             }
             $variation->position->set($index);
             $variation->setValueByLang('name', null, $request['variation'][$id]);
             if (!empty($request['variationLang_' . $id])) {
                 foreach ($request['variationLang_' . $id] as $field => $value) {
                     list($field, $lang) = explode('_', $field, 2);
                     $variation->setValueByLang($field, $lang, $value);
                 }
             }
             $variation->save();
             $tree[$typeIndex][] = $variation;
         }
     }
     $images = array();
     // save items
     foreach ($items as $index => $id) {
         if (!is_numeric($id)) {
             $item = $parent->createChildProduct();
             $idMap[$id] = $item;
         } else {
             $item = ActiveRecordModel::getInstanceByID('Product', $id);
         }
         $item->isEnabled->set(!empty($request['isEnabled'][$id]));
         if (!$request['sku'][$index]) {
             $request['sku'][$index] = $item->sku->get();
         }
         foreach (array('sku', 'stockCount', 'shippingWeight') as $field) {
             if ($item->{$field}->get() || $request[$field][$index]) {
                 $item->{$field}->set($request[$field][$index]);
             }
         }
         $item->setChildSetting('weight', $request['shippingWeightType'][$index]);
         $item->setChildSetting('price', $request['priceType'][$index]);
         if (!strlen($request['priceType'][$index])) {
             $request['price'][$index] = '';
         }
         $item->setPrice($currency, $request['price'][$index]);
         $item->save();
         // assign variations
         $currentVariationValues = $currentVariations = array();
         foreach ($item->getRelatedRecordSet('ProductVariationValue') as $variationValue) {
             $currentVariations[$variationValue->variation->get()->getID()] = $variationValue->variation->get();
             $currentVariationValues[$variationValue->variation->get()->getID()] = $variationValue;
         }
         foreach ($this->getItemVariations($tree, $index) as $variation) {
             if (!isset($currentVariations[$variation->getID()])) {
                 ProductVariationValue::getNewInstance($item, $variation)->save();
             }
             unset($currentVariations[$variation->getID()]);
         }
         foreach ($currentVariations as $deletedVariation) {
             $currentVariationValues[$deletedVariation->getID()]->delete();
         }
         // set image
         if ($_FILES['image']['tmp_name'][$index]) {
             if ($item->defaultImage->get()) {
                 $item->defaultImage->get()->load();
                 $image = $item->defaultImage->get();
             } else {
                 $image = ProductImage::getNewInstance($item);
             }
             $image->save();
             $image->setFile($_FILES['image']['tmp_name'][$index]);
             $image->save();
             $images[$item->getID()] = $image->toArray();
             unset($images[$item->getID()]['Product']);
         }
     }
     ActiveRecordModel::commit();
     // pass ID's for newly created records
     $ids = array();
     foreach ($idMap as $id => $instance) {
         $ids[$id] = $instance->getID();
     }
     $response = new ActionResponse('ids', $ids);
     $response->set('parent', $parent->getID());
     $response->set('images', $images);
     $response->set('variationCount', $parent->getRelatedRecordCount('Product', new ARSelectFilter(new EqualsCond(new ARFieldHandle('Product', 'isEnabled'), true))));
     return $response;
 }
Exemplo n.º 7
0
 //var_dump($products);die();
 foreach ($products as $position => $product) {
     if ($model = Products::model()->findByPk($product['product_id'])) {
         $variations = '';
         if (isset($product['Variations'])) {
             foreach ($product['Variations'] as $specification => $variation) {
                 if ($specification = ProductSpecification::model()->findByPk($specification)) {
                     if ($specification->input_type == 'textfield') {
                         $variation = $variation[0];
                     } else {
                         $variation = ProductVariation::model()->findByPk($variation);
                     }
                     if (Shop::module()->allowPositionLiveChange) {
                         if ($specification->input_type == 'select') {
                             $name = sprintf('variation_%s_%s', $position, $specification->id);
                             $variations .= CHtml::radioButtonList($name, $variation->id, ProductVariation::listData($variation->getVariations(), true));
                             Yii::app()->clientScript->registerScript($name, "\r\n\t\t\t\t\t\t\t\t\t\t\$('[name=\"" . $name . "\"]').click(function(){\r\n\t\t\t\t\t\t\t\t\t\$.ajax({\r\n\t\t\t\t\t\t\t\t\t\t\t'url' : '" . CController::createUrl('//shop/shoppingCart/updateVariation') . "',\r\n\t\t\t\t\t\t\t\t\t\t\t'type' : 'POST',\r\n\t\t\t\t\t\t\t\t\t\t\t'data' : \$(this),\r\n\t\t\t\t\t\t\t\t\t\t\terror: function() {\r\n\t\t\t\t\t\t\t\t\t\t\t\$('#amount_" . $position . "').css('background-color', 'red');\r\n\t\t\t\t\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\t\t\t\t\tsuccess: function(result) {\r\n\t\t\t\t\t\t\t\t\t\t\t\$('.amount_" . $position . "').css('background-color', 'lightgreen');\r\n\t\t\t\t\t\t\t\t\t\t\t\$('.widget_amount_" . $position . "').css('background-color', 'lightgreen');\r\n\t\t\t\t\t\t\t\t\t\t\t\$('.widget_amount_" . $position . "').html(\$('.amount_" . $position . "').val());\r\n\t\t\t\t\t\t\t\t\t\t\t\$('.price_" . $position . "').html(result);\t\r\n\t\t\t\t\t\t\t\t\t\t\t\$('.price_single_" . $position . "').load('" . $this->createUrl('//shop/shoppingCart/getPriceSingle?position=' . $position) . "');\r\n\t\t\t\t\t\t\t\t\t\t\t\$('.price_total').load('" . $this->createUrl('//shop/shoppingCart/getPriceTotal') . "');\r\n\t\t\t\t\t\t\t\t\t\t\t\$('.shipping_costs').load('" . $this->createUrl('//shop/shoppingCart/getShippingCosts') . "');\r\n\r\n\t\t\t\t\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\t\t\t\t\t\$('input:checked').trigger('click');\r\n\t\t\t\t\t\t\t\t\t\t");
                             $variations .= '<br />';
                         }
                     } else {
                         $variations .= $specification . ': ' . $variation . '<br />';
                     }
                 }
                 $img = CHtml::image(Yii::app()->baseUrl . '/' . $variation, '', array('width' => Shop::module()->imageWidthThumb));
             }
         }
         printf('<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td class="text-right price_single_' . $position . '">%s</td><td class="text-right price_' . $position . '">%s</td><td>%s</td></tr>', $img, CHtml::textField('amount_' . $position, $product['amount'], array('size' => 4, 'class' => 'amount_' . $position)), $model->title, $variations, Shop::priceFormat($model->getPrice($product['Variations'])), Shop::priceFormat($model->getPrice($product['Variations'], $product['amount'])), CHtml::link(Shop::t('Remove'), array('//shop/shoppingCart/delete', 'id' => $position), array('confirm' => Shop::t('Are you sure?'))));
         Yii::app()->clientScript->registerScript('amount_' . $position, "\r\n\t\t\t\t\t\$('.amount_" . $position . "').keyup(function() {\r\n\t\t\t\t\t\t\$.ajax({\r\n\t\t\t\t\t\t\turl:'" . $this->createUrl('//shop/shoppingCart/updateAmount') . "',\r\n\t\t\t\t\t\t\tdata: \$('#amount_" . $position . "'),\r\n\t\t\t\t\t\t\tsuccess: function(result) {\r\n\t\t\t\t\t\t\t\$('.amount_" . $position . "').css('background-color', 'lightgreen');\r\n\t\t\t\t\t\t\t\$('.widget_amount_" . $position . "').css('background-color', 'lightgreen');\r\n\t\t\t\t\t\t\t\$('.widget_amount_" . $position . "').html(\$('.amount_" . $position . "').val());\r\n\t\t\t\t\t\t\t\$('.price_" . $position . "').html(result);\t\r\n\t\t\t\t\t\t\t\$('.price_total').load('" . $this->createUrl('//shop/shoppingCart/getPriceTotal') . "');\r\n\t\t\t\t\t\t\t\$('.shipping_costs').load('" . $this->createUrl('//shop/shoppingCart/getShippingCosts') . "');\r\n\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\terror: function() {\r\n\t\t\t\t\t\t\t\$('#amount_" . $position . "').css('background-color', 'red');\r\n\t\t\t\t\t\t\t},\r\n\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t\t\t");
     }
 }
 if ($shippingMethod = Shop::getShippingMethod()) {
Exemplo n.º 8
0
 /**
  * Обновляем информацию о наличии товаров на складе
  * @param  array    $one                - один товар
  * @param  string   $storehouseGuid     - GUID склада в 1С откуда получаем остатки
  */
 public function updateProductAvailability($one, $orderCarrierGuid, $storehouseGuid)
 {
     //проверяем документ "Перемещение Товаров" или "Приходный Ордер На Товары"
     $docProduct = $one['@attributes']['type'] == "StandardODATA.Document_ПеремещениеТоваров_Товары_RowType" ? ['type' => false, 'docName' => 'Перемещение Товаров'] : ['type' => true, 'docName' => 'Приходный Ордер На Товары'];
     $pvar = ProductVariation::model()->find('id_1c = :id_1c', [':id_1c' => $one['d:Номенклатура_Key']]);
     if (!$pvar) {
         $this->log1c("При обработке документа '" . $docProduct['docName'] . "', не найден товар с id_1c = {" . $one['d:Ref_Key'] . "}");
         continue;
     }
     // count balance for pvar
     $pvarBalance = app()->to1c->productBalance($one['d:Номенклатура_Key'], $one['d:Характеристика_Key'], $orderCarrierGuid, $storehouseGuid);
     /**
      * уменьшаем баланс если документ является Перемещением Товаров
      * прибавляем баланс если документ является Приходным Ордером На Товары
      */
     $in_stock = $pvar->in_stock + ($docProduct['type'] ? (int) $pvarBalance : -(int) $pvarBalance);
     //update balance in product variation
     $pvar->edit(['in_stock' => $in_stock], false);
     // count balance for product
     $productBalance = $pvar->bproduct->countBalance();
     $pvar->bproduct->edit(['in_stock' => $productBalance], false);
 }
 /**
  * finds similar ("siblings") variations where one
  * attribute value is NOT the same.
  *
  * @return DataList
  */
 public function MostLikeMe()
 {
     $idArray = array();
     foreach ($this->AttributeValues() as $excludeValue) {
         unset($getAnyArray);
         $getAnyArray = array();
         foreach ($this->AttributeValues() as $innerValue) {
             if ($excludeValue->ID != $innerValue->ID) {
                 $getAnyArray[$innerValue->ID] = $innerValue->ID;
             }
             //find a product variation that has the getAnyArray Values
             $items = ProductVariation::get()->innerJoin("ProductVariation_AttributeValues", "\"ProductVariation\".\"ID\" = \"ProductVariationID\" ")->filter(array("ProductAttributeValueID" => $getAnyArray, "ProductID" => $this->ProductID))->exclude(array("ID" => $this->ID));
             $idArray += $items->map("ID", "ID")->toArray();
         }
     }
     return ProductVariation::get()->filter(array("ID" => $idArray));
 }
Exemplo n.º 10
0
 public function registerVariation(ProductVariation $variation)
 {
     $this->variations[$variation->getID()] = $variation;
 }
 /**
  * returns the matching variation if any
  * @param array $attributes formatted as (TypeID => ValueID, TypeID => ValueID)
  *
  * @return ProductVariation | NULL
  */
 function getVariationByAttributes(array $attributes)
 {
     if (!is_array($attributes) || !count($attributes)) {
         user_error("attributes must be provided as an array of numeric keys and values IDs...", E_USER_NOTICE);
         return null;
     }
     $variations = ProductVariation::get()->filter(array("ProductID" => $this->owner->ID));
     $keyattributes = array_keys($attributes);
     $id = $keyattributes[0];
     foreach ($attributes as $typeid => $valueid) {
         if (!is_numeric($typeid) || !is_numeric($valueid)) {
             user_error("key and value ID must be numeric", E_USER_NOTICE);
             return null;
         }
         $alias = "A{$typeid}";
         $variations = $variations->where("\"{$alias}\".\"ProductAttributeValueID\" = {$valueid}")->innerJoin("ProductVariation_AttributeValues", "\"ProductVariation\".\"ID\" = \"{$alias}\".\"ProductVariationID\"", $alias);
     }
     if ($variation = $variations->First()) {
         return $variation;
     }
     return null;
 }
Exemplo n.º 12
0
    foreach ($variations as $variation) {
        $i++;
        $field = "Variations[{$variation[0]->specification_id}][]";
        echo '<div class="product_variation product_variation_' . $i . '">';
        echo CHtml::label($variation[0]->specification->title, $field, array('class' => 'lbl-header'));
        if ($variation[0]->specification->required) {
            echo ' <span class="required">*</span>';
        }
        echo '<br />';
        if ($variation[0]->specification->input_type == 'textfield') {
            echo CHtml::textField($field);
        } else {
            if ($variation[0]->specification->input_type == 'select') {
                // If the specification is required, preselect the first field. Otherwise
                // let the customer choose which one to pick
                echo CHtml::radioButtonList($field, $variation[0]->specification->required ? $variation[0]->id : null, ProductVariation::listData($variation));
            } else {
                if ($variation[0]->specification->input_type == 'image') {
                    echo CHtml::fileField($field);
                }
            }
        }
        echo '</div>';
        if ($i % 2 == 0) {
            echo '<div style="clear: both;"></div>';
        }
    }
}
echo '<div style="clear: both;"></div>';
echo '<br />';
echo CHtml::hiddenField('product_id', $model->product_id);
Exemplo n.º 13
0
 public function getPrice($variations = null, $amount = 1)
 {
     if ($this->price === null) {
         $price = (double) Shop::module()->defaultPrice;
     } else {
         $price = (double) $this->price;
     }
     if ($this->tax) {
         $price *= $this->tax->percent / 100 + 1;
     }
     if ($variations) {
         foreach ($variations as $key => $variation) {
             if (is_numeric($variation)) {
                 $price += @ProductVariation::model()->findByPk($variation)->getPriceAdjustion();
             }
         }
     }
     return (double) ($price *= $amount);
 }
Exemplo n.º 14
0
 public function getVariations()
 {
     return ProductVariation::model()->findAll('product_id = :pid and specification_id = :sid ', array(':pid' => $this->product_id, ':sid' => $this->specification_id));
 }
 function resaveAllPRoductsVariations_210()
 {
     $explanation = "\r\n\t\t\t<h1>210. Resave All Product Variations to update the FullName and FullSiteTreeSort Field</h1>\r\n\t\t\t<p>Saves all the product variations on the site. You may need to run this task several times.</p>\r\n\t\t";
     if ($this->retrieveInfoOnly) {
         return $explanation;
     } else {
         echo $explanation;
     }
     $count = 0;
     if (class_exists("ProductVariation")) {
         ProductVariation::get()->where("\"FullName\" = '' OR \"FullName\" IS NULL")->sort("ID", "ASC")->limit($this->limit, $this->start);
         if ($variations->count()) {
             foreach ($variations as $variation) {
                 $count++;
                 $variation->write();
                 $this->DBAlterationMessageNow("Saving Variation " . $variation->getTitle());
             }
             return $this->start + $this->limit;
         } else {
             $this->DBAlterationMessageNow("No product variations to update.");
         }
     } else {
         $this->DBAlterationMessageNow("There are not ProductVariations in this project");
     }
     return 0;
 }
Exemplo n.º 16
0
 /**
  * Conditions for whether a product can be purchased:
  *  - global allow purchase is enabled
  *  - product AllowPurchase field is true
  *  - if variations, then one of them needs to be purchasable
  *  - if not variations, selling price must be above 0
  *
  * Other conditions may be added by decorating with the canPurchase function
  *
  * @param Member $member
  * @param int    $quantity
  *
  * @return boolean
  */
 public function canPurchase($member = null, $quantity = 1)
 {
     $global = self::config()->global_allow_purchase;
     if (!$global || !$this->AllowPurchase) {
         return false;
     }
     $allowpurchase = false;
     $extension = self::has_extension("ProductVariationsExtension");
     if ($extension && ProductVariation::get()->filter("ProductID", $this->ID)->first()) {
         foreach ($this->Variations() as $variation) {
             if ($variation->canPurchase($member, $quantity)) {
                 $allowpurchase = true;
                 break;
             }
         }
     } else {
         $allowpurchase = $this->sellingPrice() > 0 || self::config()->allow_zero_price;
     }
     // Standard mechanism for accepting permission changes from decorators
     $permissions = $this->extend('canPurchase', $member, $quantity);
     $permissions[] = $allowpurchase;
     return min($permissions);
 }
 private function addspecialprice()
 {
     $task = new EcommerceTaskCreateMemberGroups();
     $task->run(false);
     $customerGroup = EcommerceRole::get_customer_group();
     if (!$customerGroup) {
         die("could not create customer group");
     }
     $group = new Group();
     $group->Title = "Discount Customers";
     $group->Code = "discountcustomers";
     $group->ParentID = $customerGroup->ID;
     $group->write();
     $member = new Member();
     $member->FirstName = 'Bob';
     $member->Surname = 'Jones';
     $member->Email = '*****@*****.**';
     $member->Password = '******';
     $member->write();
     $member->Groups()->add($group);
     $products = Product::get()->where("ClassName = 'Product'")->sort("RAND()")->limit(2);
     $this->addExamplePages(4, "Special price for particular customers", $products);
     $i = 0;
     foreach ($products as $product) {
         $i++;
         $complexObjectPrice = new ComplexPriceObject();
         if ($i == 1) {
             $complexObjectPrice->Price = $product->Price - 1.5;
         } elseif ($i == 2) {
             $complexObjectPrice->Percentage = 10;
             $complexObjectPrice->Reduction = 2.5;
         } else {
             $complexObjectPrice->Price = $product->Price - 1.5;
             $complexObjectPrice->Percentage = 10;
             $complexObjectPrice->Reduction = 2.5;
         }
         $complexObjectPrice->From = date("Y-m-d h:n:s", strtotime("now"));
         $complexObjectPrice->Until = date("Y-m-d h:n:s", strtotime("next year"));
         $complexObjectPrice->ProductID = $product->ID;
         $complexObjectPrice->write();
         $complexObjectPrice->Groups()->add($group);
         $product->Content = "<p><a href=\"Security/login/?BackURL=" . $product->Link() . "\">Login</a> as bob@silverstripe-ecommerce.com, password: test123 to get a special price. You can then <a href=\"Security/logout/?BackURL=" . $product->Link() . "\">log out</a> again to see the original price.</p>";
         $this->addToTitle($product, "member price", true);
     }
     $variations = ProductVariation::get()->where("ClassName = 'ProductVariation'")->sort("RAND()")->limit(2);
     $i = 0;
     foreach ($variations as $variation) {
         $i++;
         $complexObjectPrice = new ComplexPriceObject();
         if ($i == 1) {
             $complexObjectPrice->Price = $product->Price - 1.5;
         } elseif ($i == 2) {
             $complexObjectPrice->Percentage = 10;
             $complexObjectPrice->Reduction = 2.5;
         } else {
             $complexObjectPrice->Price = $product->Price - 1.5;
             $complexObjectPrice->Percentage = 10;
             $complexObjectPrice->Reduction = 2.5;
         }
         $complexObjectPrice->Price = $variation->Price - 1.5;
         $complexObjectPrice->From = date("Y-m-d h:n:s", strtotime("now"));
         $complexObjectPrice->Until = date("Y-m-d h:n:s", strtotime("next year"));
         $complexObjectPrice->ProductVariationID = $variation->ID;
         $complexObjectPrice->write();
         $complexObjectPrice->Groups()->add($group);
         $product = $variation->Product();
         $this->addExamplePages(4, "Special price for particular customers for product variations {$i}", $product);
         $product->Content = "<p><a href=\"Security/login/?BackURL=" . $product->Link() . "\">Login</a> as bob@jones.com, password: test123 to get a special price</p>";
         $this->addToTitle($product, "member price", true);
     }
 }
 /**
  * TO DO: work out how it works...
  *
  */
 function generateVariationsFromAttributeValues(array $values)
 {
     $cpt = 0;
     $variations = array();
     foreach ($values as $typeID => $typeValues) {
         $this->owner->addAttributeType($typeID);
         $copyVariations = $variations;
         $variations = array();
         foreach ($typeValues as $value) {
             $value = array($value);
             if (count($copyVariations) > 0) {
                 foreach ($copyVariations as $variation) {
                     $variations[] = array_merge($variation, $value);
                 }
             } else {
                 $variations[] = $value;
             }
         }
     }
     foreach ($variations as $variation) {
         sort($variation);
         $str = implode(',', $variation);
         $add = true;
         $productVariationIDs = DB::query("SELECT \"ID\" FROM \"ProductVariation\" WHERE \"ProductID\" = '{$this->owner->ID}'")->column();
         if (count($productVariationIDs) > 0) {
             $productVariationIDs = implode(',', $productVariationIDs);
             $variationValues = DB::query("SELECT GROUP_CONCAT(\"ProductAttributeValueID\" ORDER BY \"ProductAttributeValueID\" SEPARATOR ',') FROM \"ProductVariation_AttributeValues\" WHERE \"ProductVariationID\" IN ({$productVariationIDs}) GROUP BY \"ProductVariationID\"")->column();
             if (in_array($str, $variationValues)) {
                 $add = false;
             }
         }
         if ($add) {
             $cpt++;
             $newVariation = new ProductVariation(array('ProductID' => $this->owner->ID, 'Price' => $this->owner->Price));
             $newVariation->write();
             $newVariation->AttributeValues()->addMany($variation);
         }
     }
     return $cpt;
 }
Exemplo n.º 19
0
 private function importProductVariationValue(Product $product, $index, $name)
 {
     $parent = $product->parent->get();
     $type = $this->getVariationTypeByIndex($parent, $index);
     if (!$type->getID()) {
         $type = $this->importVariationType($parent, $index, '');
     }
     $f = new ARSelectFilter();
     $f->mergeCondition(new EqualsCond(MultiLingualObject::getLangSearchHandle(new ARFieldHandle('ProductVariation', 'name'), $this->application->getDefaultLanguageCode()), $name));
     $values = $type->getRelatedRecordSet('ProductVariation', $f);
     if ($values->size()) {
         $variation = $values->get(0);
     } else {
         $variation = ProductVariation::getNewInstance($type);
         $variation->setValueByLang('name', null, $name);
         $variation->save();
     }
     if (!$product->getID()) {
         $product->save();
     }
     $f = new ARDeleteFilter(new EqualsCond(new ARFieldHandle('ProductVariation', 'typeID'), $type->getID()));
     $product->deleteRelatedRecordSet('ProductVariationValue', $f, array('ProductVariation'));
     ProductVariationValue::getNewInstance($product, $variation)->save();
 }
 function ProductVariationGetPluralName()
 {
     return Convert::raw2att(ProductVariation::get_plural_name());
 }
Exemplo n.º 21
0
 public function getPrice($variations = null, $amount = 1)
 {
     $price = (double) $this->price;
     if ($variations) {
         foreach ($variations as $key => $variation) {
             $price += @ProductVariation::model()->findByPk($variation[0])->price_adjustion;
         }
     }
     (double) ($price *= $amount);
     return $price;
 }
 function variationRow(&$obj, $val, $record)
 {
     $obj->write();
     //make sure product is in DB
     //TODO: or find existing variation
     $variation = DataObject::get_one('ProductVariation', "InternalItemID = '{$val}'");
     if (!$variation) {
         $variation = new ProductVariation();
         $variation->InternalItemID = $val;
         $variation->ProductID = $obj->ID;
         //link to product
         $variation->write();
     }
     $varcols = array('->processVariation', '->processVariation1', '->processVariation2', '->processVariation3', '->processVariation4', '->processVariation5', '->processVariation6');
     foreach ($varcols as $col) {
         if (isset($record[$col])) {
             $parts = explode(":", $record[$col]);
             if (count($parts) == 2) {
                 $attributetype = trim($parts[0]);
                 $attributevalues = explode(",", $parts[1]);
                 //get rid of empty values
                 foreach ($attributevalues as $key => $value) {
                     if (!$value || trim($value) == "") {
                         unset($attributevalues[$key]);
                     }
                 }
                 if (count($attributevalues) == 1) {
                     $attributetype = ProductAttributeType::find_or_make($attributetype);
                     foreach ($attributevalues as $key => $value) {
                         $val = trim($value);
                         if ($val != "" && $val != null) {
                             $attributevalues[$key] = $val;
                         }
                         //remove outside spaces from values
                     }
                     $attributetype->addValues($attributevalues);
                     //create and add values to attribute type
                     $obj->VariationAttributes()->add($attributetype);
                     //add variation attribute type to product
                     //TODO: if existing variation, then remove current values
                     //record vairation attribute values (variation1, 2 etc)
                     foreach ($attributetype->convertArrayToValues($attributevalues) as $value) {
                         $variation->AttributeValues()->add($value);
                         break;
                     }
                 }
             }
         }
     }
     //copy db values into variation (InternalItemID, Price, Stock, etc) ...there will be unknowns from extensions.
     $dbfields = $variation->db();
     foreach ($record as $field => $value) {
         if (isset($dbfields[$field])) {
             $variation->{$field} = $value;
         }
     }
     $variation->write();
 }
 public static function set_current_style_option_code($v)
 {
     self::$current_style_option_code = $v;
 }
 function run($request)
 {
     $productVariationArrayID = array();
     if (empty($_GET["silent"])) {
         $this->verbose = true;
     } else {
         $this->verbose = intval($_GET["silent"]) == 1 ? false : true;
     }
     if (empty($_GET["productid"])) {
         $productID = 0;
     } elseif ($_GET["productid"] == 'all') {
         $productID = -1;
     } else {
         $productID = intval($_GET["productid"]);
     }
     if (empty($_GET["live"])) {
         $live = false;
     } else {
         $live = intval($_GET["live"]) == 1 ? true : false;
     }
     if ($live) {
         if ($this->verbose) {
             DB::alteration_message("this is a live task", "deleted");
         }
     } else {
         if ($this->verbose) {
             DB::alteration_message("this is a test only. If you add a live=1 get variable then you can make it for real ;-)", "created");
         }
     }
     if ($productID == -1) {
         $products = Product::get();
     } else {
         $products = null;
         $product = Product::get()->byID($productID);
         if ($product) {
             $products = new ArrayList();
             $products->push($product);
         }
     }
     if ($products && $products->count()) {
         foreach ($products as $product) {
             $productID = $product->ID;
             if ($products->count()) {
                 if ($this->verbose) {
                     DB::alteration_message("Deleting variations for " . $product->Title, "deleted");
                 }
                 $variations = ProductVariation::get()->filter(array("ProductID" => $productID))->limit(100);
                 if ($variations->count()) {
                     if ($this->verbose) {
                         DB::alteration_message("PRE DELETE COUNT: " . $variations->count());
                     }
                     foreach ($variations as $variation) {
                         if ($this->verbose) {
                             DB::alteration_message("&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Deleting Variation: " . $variation->Title(), "deleted");
                         }
                         if ($live) {
                             $variation->delete();
                         }
                         $productVariationArrayID[$variation->ID] = $variation->ID;
                     }
                     $variations = ProductVariation::get()->filter(array("ProductID" => $productID))->limit(100);
                     if ($live) {
                         if ($variations->count()) {
                             if ($this->verbose) {
                                 DB::alteration_message("POST DELETE COUNT: " . $variations->count());
                             }
                         } else {
                             if ($this->verbose) {
                                 DB::alteration_message("All variations have been deleted: ", "created");
                             }
                         }
                     } else {
                         if ($this->verbose) {
                             DB::alteration_message("This was a test only", "created");
                         }
                     }
                 } else {
                     if ($this->verbose) {
                         DB::alteration_message("There are no variations to delete", "created");
                     }
                 }
                 if ($this->verbose) {
                     DB::alteration_message("Starting cleanup", "created");
                 }
                 if ($live) {
                     $sql = "\r\n\t\t\t\t\t\t\t\t\tDELETE\r\n\t\t\t\t\t\t\t\t\tFROM \"Product_VariationAttributes\"\r\n\t\t\t\t\t\t\t\t\tWHERE \"ProductID\" = " . $productID;
                     if ($this->verbose) {
                         DB::alteration_message("<pre>RUNNING<br />" . $sql . "</pre>");
                     }
                     DB::query($sql);
                     $sql = "\r\n\t\t\t\t\t\t\t\t\tDELETE \"ProductVariation_AttributeValues\"\r\n\t\t\t\t\t\t\t\t\tFROM \"ProductVariation_AttributeValues\"\r\n\t\t\t\t\t\t\t\t\t\tLEFT JOIN \"ProductVariation\"\r\n\t\t\t\t\t\t\t\t\t\t\tON \"ProductVariation_AttributeValues\".\"ProductVariationID\" = \"ProductVariation\".\"ID\"\r\n\t\t\t\t\t\t\t\t\tWHERE \"ProductVariation\".\"ID\" IS NULL";
                     if ($this->verbose) {
                         DB::alteration_message("<pre>RUNNING<br />" . $sql . "</pre>");
                     }
                     DB::query($sql);
                 } else {
                     $sql = "\r\n\t\t\t\t\t\t\t\t\tSELECT COUNT(Product_VariationAttributes.ID)\r\n\t\t\t\t\t\t\t\t\tFROM \"Product_VariationAttributes\"\r\n\t\t\t\t\t\t\t\t\tWHERE \"ProductID\" = " . $productID;
                     if ($this->verbose) {
                         DB::alteration_message("<pre>RUNNING<br />" . $sql . "</pre>");
                     }
                     $result = DB::query($sql);
                     if ($this->verbose) {
                         DB::alteration_message("Would have deleted " . $result->value() . " rows");
                     }
                     $sql = "\r\n\t\t\t\t\t\t\t\t\tSELECT COUNT (\"ProductVariation_AttributeValues\".\"ID\")\r\n\t\t\t\t\t\t\t\t\tFROM \"ProductVariation_AttributeValues\"\r\n\t\t\t\t\t\t\t\t\t\tLEFT JOIN \"ProductVariation\"\r\n\t\t\t\t\t\t\t\t\t\t\tON \"ProductVariation_AttributeValues\".\"ProductVariationID\" = \"ProductVariation\".\"ID\"\r\n\t\t\t\t\t\t\t\t\tWHERE\r\n\t\t\t\t\t\t\t\t\t\t\"ProductVariation\".\"ID\" IS NULL OR\r\n\t\t\t\t\t\t\t\t\t\t\"ProductVariation\".\"ID\" IN(" . implode(",", $productVariationArrayID) . ") ";
                     if ($this->verbose) {
                         DB::alteration_message("<pre>RUNNING<br />" . $sql . "</pre>");
                     }
                     $result = DB::query($sql);
                     if ($this->verbose) {
                         DB::alteration_message("Would have deleted " . $result->value() . " rows");
                     }
                 }
             }
         }
     } else {
         if ($this->verbose) {
             DB::alteration_message("Product does not exist. You can set the product by adding it productid=XXX as a GET variable.  You can also add <i>all</i> to delete ALL product Variations.", "deleted");
         }
     }
     DB::alteration_message("Completed", "created");
 }
Exemplo n.º 25
0
 /**
  * Conditions for whether a product can be purchased:
  *  - global allow purchase is enabled
  *  - product AllowPurchase field is true
  *  - if variations, then one of them needs to be purchasable
  *  - if not variations, selling price must be above 0
  *
  * Other conditions may be added by decorating with the canPurcahse function
  *
  * @param Member $member
  * @param int $quantity
  *
  * @throws ShopBuyableException
  *
  * @return boolean
  */
 public function canPurchase($member = null, $quantity = 1)
 {
     $global = self::config()->global_allow_purchase;
     if (!$global || !$this->AllowPurchase) {
         return false;
     }
     $allowpurchase = false;
     $extension = self::has_extension("ProductVariationsExtension");
     if ($extension && ProductVariation::get()->filter("ProductID", $this->ID)->first()) {
         foreach ($this->Variations() as $variation) {
             try {
                 if ($variation->canPurchase($member, $quantity)) {
                     $allowpurchase = true;
                     break;
                 }
             } catch (ShopBuyableException $e) {
             }
         }
         // if not allowed to buy after any variations then raise the last
         // exception again
         if (!$allowpurchase && isset($e)) {
             throw $e;
             return false;
         }
     } else {
         if ($this->sellingPrice() > 0 || self::config()->allow_zero_price) {
             $allowpurchase = true;
         }
     }
     // Standard mechanism for accepting permission changes from decorators
     $extended = $this->extendedCan('canPurchase', $member, $quantity);
     if ($allowpurchase && $extended !== null) {
         $allowpurchase = $extended;
     }
     return $allowpurchase;
 }
Exemplo n.º 26
0
 public function testVariationMatrix()
 {
     $size = ProductVariationType::getNewInstance($this->product);
     $size->setValueByLang('name', 'en', 'Size');
     $size->save();
     $color = ProductVariationType::getNewInstance($this->product);
     $color->setValueByLang('name', 'en', 'Color');
     $color->save();
     $sizes = $colors = array();
     foreach (array('Small', 'Large') as $name) {
         $variation = ProductVariation::getNewInstance($size);
         $variation->setValueByLang('name', 'en', $name);
         $variation->save();
         $sizes[] = $variation;
     }
     foreach (array('Red', 'Green', 'Blue') as $name) {
         $variation = ProductVariation::getNewInstance($size);
         $variation->setValueByLang('name', 'en', $name);
         $variation->save();
         $colors[] = $variation;
     }
     // create product variations
     $variations = array();
     foreach ($sizes as $sizeVar) {
         foreach ($colors as $colorVar) {
             $child = $this->product->createVariation(array($sizeVar, $colorVar));
             $child->save();
             $variations[$sizeVar->getID()][$colorVar->getID()] = $child;
         }
     }
     $matrix = $this->product->getVariationMatrix();
     //var_dump($matrix);
 }
 /**
  * Generates variations based on selected attributes.
  *
  * @param ProductAttributeType $attributetype
  * @param array                $values
  */
 public function generateVariationsFromAttributes(ProductAttributeType $attributetype, array $values)
 {
     //TODO: introduce transactions here, in case objects get half made etc
     //if product has variation attribute types
     if (!empty($values)) {
         //TODO: get values dataobject set
         $avalues = $attributetype->convertArrayToValues($values);
         $existingvariations = $this->owner->Variations();
         if ($existingvariations->exists()) {
             //delete old variation, and create new ones - to prevent modification of exising variations
             foreach ($existingvariations as $oldvariation) {
                 $oldvalues = $oldvariation->AttributeValues();
                 foreach ($avalues as $value) {
                     $newvariation = $oldvariation->duplicate();
                     $newvariation->InternalItemID = $this->owner->InternalItemID . '-' . $newvariation->ID;
                     $newvariation->AttributeValues()->addMany($oldvalues);
                     $newvariation->AttributeValues()->add($value);
                     $newvariation->write();
                     $existingvariations->add($newvariation);
                 }
                 $existingvariations->remove($oldvariation);
                 $oldvariation->AttributeValues()->removeAll();
                 $oldvariation->delete();
                 $oldvariation->destroy();
                 //TODO: check that old variations actually stick around, as they will be needed for past orders etc
             }
         } else {
             foreach ($avalues as $value) {
                 $variation = ProductVariation::create();
                 $variation->ProductID = $this->owner->ID;
                 $variation->Price = $this->owner->BasePrice;
                 $variation->write();
                 $variation->InternalItemID = $this->owner->InternalItemID . '-' . $variation->ID;
                 $variation->AttributeValues()->add($value);
                 $variation->write();
                 $existingvariations->add($variation);
             }
         }
     }
 }
Exemplo n.º 28
0

<?php 
if ($products) {
    echo '<table cellpadding="0" cellspacing="0" class="shopping_cart">';
    printf('<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th style="width:60px;">%s</th><th style="width:60px;">%s</th><th>%s</th></tr>', Shop::t('Image'), Shop::t('Amount'), Shop::t('Product'), Shop::t('Variation'), Shop::t('Price Single'), Shop::t('Sum'), Shop::t('Actions'));
    foreach ($products as $position => $product) {
        if (@($model = Products::model()->findByPk($product['product_id']))) {
            $variations = '';
            if (isset($product['Variations'])) {
                foreach ($product['Variations'] as $specification => $variation) {
                    $specification = ProductSpecification::model()->findByPk($specification);
                    if ($specification->is_user_input) {
                        $variation = $variation[0];
                    } else {
                        $variation = ProductVariation::model()->findByPk($variation);
                    }
                    $variations .= $specification . ': ' . $variation . '<br />';
                }
            }
            printf('<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td class="text-right">%s</td><td class="text-right price_' . $position . '">%s</td><td>%s</td></tr>', $model->getImage(0, true), CHtml::textField('amount_' . $position, $product['amount'], array('size' => 4, 'class' => 'amount_' . $position)), $model->title, $variations, Shop::priceFormat($model->getPrice(@$product['Variations'])), Shop::priceFormat($model->getPrice(@$product['Variations'], @$product['amount'])), CHtml::link(Shop::t('Remove'), array('//shop/shoppingCart/delete', 'id' => $position), array('confirm' => Shop::t('Are you sure?'))));
            Yii::app()->clientScript->registerScript('amount_' . $position, "\n\t\t\t\t\t\$('.amount_" . $position . "').keyup(function() {\n\t\t\t\t\t\t\$.ajax({\n\t\t\t\t\t\t\turl:'" . $this->createUrl('//shop/shoppingCart/updateAmount') . "',\n\t\t\t\t\t\t\tdata: \$('#amount_" . $position . "'),\n\t\t\t\t\t\t\tsuccess: function(result) {\n\t\t\t\t\t\t\t\$('.amount_" . $position . "').css('background-color', 'lightgreen');\n\t\t\t\t\t\t\t\$('.widget_amount_" . $position . "').css('background-color', 'lightgreen');\n\t\t\t\t\t\t\t\$('.widget_amount_" . $position . "').html(\$('.amount_" . $position . "').val());\n\t\t\t\t\t\t\t\$('.price_" . $position . "').html(result);\t\n\t\t\t\t\t\t\t\$('.price_total').load('" . $this->createUrl('//shop/shoppingCart/getPriceTotal') . "');\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\terror: function() {\n\t\t\t\t\t\t\t\$('#amount_" . $position . "').css('background-color', 'red');\n\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t\t\t");
        }
    }
    if ($shippingMethod = Shop::getShippingMethod()) {
        printf('<tr>
				<td></td>
				<td>1</td>
				<td>%s</td>
				<td></td>
				<td class="text-right">%s</td>