/**
  * 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 = new ProductVariation();
                 $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);
             }
         }
     }
 }
 /**
  * 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;
 }
 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();
 }
 private function addvariations()
 {
     $colourObject = ProductAttributeType::get()->where("\"Name\" = 'Colour'")->First();
     if (!$colourObject) {
         $colourObject = new ProductAttributeType();
         $colourObject->Name = "Colour";
         $colourObject->Label = "Colour";
         $colourObject->IsColour = true;
         $colourObject->Sort = 100;
         $colourObject->write();
     }
     if ($colourObject) {
         $redObject = ProductAttributeValue::get()->where("\"Value\" = 'red'")->First();
         if (!$redObject) {
             $redObject = new ProductAttributeValue();
             $redObject->Value = "red";
             $redObject->RGBCode = "ff0000";
             $redObject->ContrastRGBCode = "BFC1C1";
             $redObject->TypeID = $colourObject->ID;
             $redObject->Sort = 100;
             $redObject->write();
         }
         $blueObject = ProductAttributeValue::get()->where("\"Value\" = 'blue'")->First();
         if (!$blueObject) {
             $blueObject = new ProductAttributeValue();
             $blueObject->Value = "blue";
             $blueObject->RGBCode = "0000ff";
             $blueObject->ContrastRGBCode = "BFC1C1";
             $blueObject->TypeID = $colourObject->ID;
             $blueObject->Sort = 110;
             $blueObject->write();
         }
     } else {
         die("COULD NOT CREATE COLOUR OBJECT");
     }
     $sizeObject = ProductAttributeType::get()->filter("Name", 'Size')->First();
     if (!$sizeObject) {
         $sizeObject = new ProductAttributeType();
         $sizeObject->Name = "Size";
         $sizeObject->Label = "Size";
         $sizeObject->Sort = 110;
         $sizeObject->write();
     }
     if ($sizeObject) {
         $smallObject = ProductAttributeValue::get()->where("\"Value\" = 'S'")->First();
         if (!$smallObject) {
             $smallObject = new ProductAttributeValue();
             $smallObject->Value = "S";
             $smallObject->TypeID = $sizeObject->ID;
             $smallObject->Sort = 100;
             $smallObject->write();
         }
         $xtraLargeObject = ProductAttributeValue::get()->where("\"Value\" = 'XL'")->First();
         if (!$xtraLargeObject) {
             $xtraLargeObject = new ProductAttributeValue();
             $xtraLargeObject->Value = "XL";
             $xtraLargeObject->TypeID = $sizeObject->ID;
             $xtraLargeObject->Sort = 110;
             $xtraLargeObject->write();
         }
     } else {
         die("COULD NOT CREATE SIZE OBJECT");
     }
     $products = Product::get()->where("ClassName = 'Product'")->sort("RAND()")->limit(2);
     $this->addExamplePages(1, "products with variations (size, colour, etc...)", $products);
     if ($products->count() && $colourObject && $sizeObject) {
         $variationCombos = array(array("Size" => $xtraLargeObject, "Colour" => $redObject), array("Size" => $xtraLargeObject, "Colour" => $blueObject), array("Size" => $smallObject, "Colour" => $redObject), array("Size" => $smallObject, "Colour" => $blueObject));
         foreach ($products as $product) {
             $existingAttributeTypes = $product->VariationAttributes();
             $existingAttributeTypes->add($sizeObject);
             $existingAttributeTypes->add($colourObject);
             $this->addToTitle($product, "with variation", false);
             $product->Content .= "<p>On this page you can see two example of how you customers can add variations to their products (form / table)... In a real-life shop you would probably choose one or the other.</p>";
             $product->write();
             $product->Publish('Stage', 'Live');
             $product->flushCache();
             $descriptionOptions = array("", "Per Month", "", "", "Per Year", "This option has limited warranty");
             if (!ProductVariation::get()->where("ProductID  = " . $product->ID)->count()) {
                 foreach ($variationCombos as $variationCombo) {
                     $productVariation = new ProductVariation();
                     $productVariation->ProductID = $product->ID;
                     $productVariation->Price = $product->Price * 2;
                     $productVariation->Description = $descriptionOptions[rand(0, 5)];
                     $productVariation->ImageID = rand(0, 1) ? 0 : $this->getRandomImageID();
                     $productVariation->write();
                     $existingAttributeValues = $productVariation->AttributeValues();
                     $existingAttributeValues->add($variationCombo["Size"]);
                     $existingAttributeValues->add($variationCombo["Colour"]);
                     DB::alteration_message(" Creating variation for " . $product->Title . " // COLOUR " . $variationCombo["Colour"]->Value . " SIZE " . $variationCombo["Size"]->Value, "created");
                 }
             }
         }
     }
 }