mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 17:10:53 +00:00
[Variable] Sku removal in favour of code
This commit is contained in:
parent
24b00718ba
commit
6d81c125cf
38 changed files with 233 additions and 168 deletions
|
|
@ -90,6 +90,7 @@ Feature: Product variants
|
|||
Scenario: Generating only missing variants of product with multiple options
|
||||
Given I am creating variant of "Sylius T-Shirt"
|
||||
When I fill in "Price" with "19.99"
|
||||
And I fill in "Code" with "T_SHIRT"
|
||||
And I select "L" from "T-Shirt size"
|
||||
And I select "Red" from "T-Shirt color"
|
||||
And I press "Create"
|
||||
|
|
@ -101,6 +102,7 @@ Feature: Product variants
|
|||
Scenario: Creating a product variant by selecting option
|
||||
Given I am creating variant of "Black T-Shirt"
|
||||
When I fill in "Price" with "19.99"
|
||||
And I fill in "Code" with "T_SHIRT"
|
||||
And I select "L" from "T-Shirt size"
|
||||
And I press "Create"
|
||||
Then I should be on the page of product "Black T-Shirt"
|
||||
|
|
@ -109,6 +111,7 @@ Feature: Product variants
|
|||
Scenario: Creating a product variant by selecting multiple options
|
||||
Given I am creating variant of "Sylius T-Shirt"
|
||||
When I fill in "Price" with "19.99"
|
||||
And I fill in "Code" with "T_SHIRT"
|
||||
And I select "L" from "T-Shirt size"
|
||||
And I select "Red" from "T-Shirt color"
|
||||
And I press "Create"
|
||||
|
|
|
|||
|
|
@ -76,10 +76,11 @@ Feature: Products
|
|||
Scenario: Creating simple product without any attributes and options
|
||||
Given I am on the product creation page
|
||||
When I fill in the following:
|
||||
| Name | Book about Everything |
|
||||
| Code | TEE_CODE |
|
||||
| Description | Interesting description |
|
||||
| Price | 29.99 |
|
||||
| Name | Book about Everything |
|
||||
| sylius_product_legacy_code | TEE_CODE |
|
||||
| sylius_product_legacy_masterVariant_code | TEE_CODE |
|
||||
| Description | Interesting description |
|
||||
| Price | 29.99 |
|
||||
And I press "Create"
|
||||
Then I should be on the page of product "Book about Everything"
|
||||
And I should see "Product has been successfully created"
|
||||
|
|
@ -87,10 +88,11 @@ Feature: Products
|
|||
Scenario: Prices are saved correctly
|
||||
Given I am on the product creation page
|
||||
When I fill in the following:
|
||||
| Name | Book about Everything |
|
||||
| Code | TEE_CODE |
|
||||
| Description | Interesting description |
|
||||
| Price | 4.10 |
|
||||
| Name | Book about Everything |
|
||||
| sylius_product_legacy_code | TEE_CODE |
|
||||
| sylius_product_legacy_masterVariant_code | TEE_CODE |
|
||||
| Description | Interesting description |
|
||||
| Price | 4.10 |
|
||||
And I press "Create"
|
||||
Then I should be on the page of product "Book about Everything"
|
||||
And I should see "Product has been successfully created"
|
||||
|
|
@ -99,10 +101,11 @@ Feature: Products
|
|||
Scenario: Creating product with options
|
||||
Given I am on the product creation page
|
||||
When I fill in the following:
|
||||
| Name | Manchester United tee |
|
||||
| Code | TEE_CODE |
|
||||
| Description | Interesting description |
|
||||
| Price | 59.99 |
|
||||
| Name | Manchester United tee |
|
||||
| sylius_product_legacy_code | TEE_CODE |
|
||||
| sylius_product_legacy_masterVariant_code | TEE_CODE |
|
||||
| Description | Interesting description |
|
||||
| Price | 59.99 |
|
||||
And I select "T-Shirt size" from "Options"
|
||||
And I press "Create"
|
||||
Then I should be on the page of product "Manchester United tee"
|
||||
|
|
@ -113,10 +116,11 @@ Feature: Products
|
|||
Scenario: Creating product with association
|
||||
Given I am on the product creation page
|
||||
When I fill in the following:
|
||||
| Name | Manchester United tee |
|
||||
| Code | TEE_CODE |
|
||||
| Description | Interesting description |
|
||||
| Price | 59.99 |
|
||||
| Name | Manchester United tee |
|
||||
| sylius_product_legacy_code | TEE_CODE |
|
||||
| sylius_product_legacy_masterVariant_code | TEE_CODE |
|
||||
| Description | Interesting description |
|
||||
| Price | 59.99 |
|
||||
And go to "Association" tab
|
||||
And I click "Add association"
|
||||
And I select "Up sell" from "Association type"
|
||||
|
|
@ -131,10 +135,11 @@ Feature: Products
|
|||
Scenario: Creating product with string attribute
|
||||
Given I am on the product creation page
|
||||
When I fill in the following:
|
||||
| Name | Manchester United tee |
|
||||
| Code | TEE_CODE |
|
||||
| Description | Interesting description |
|
||||
| Price | 59.99 |
|
||||
| Name | Manchester United tee |
|
||||
| sylius_product_legacy_code | TEE_CODE |
|
||||
| sylius_product_legacy_masterVariant_code | TEE_CODE |
|
||||
| Description | Interesting description |
|
||||
| Price | 59.99 |
|
||||
And go to "Attributes" tab
|
||||
And I add "T-Shirt fabric" attribute
|
||||
And I fill in "T-Shirt fabric" with "Polyester"
|
||||
|
|
@ -146,10 +151,11 @@ Feature: Products
|
|||
Scenario: Creating product with checkbox attribute
|
||||
Given I am on the product creation page
|
||||
When I fill in the following:
|
||||
| Name | Manchester United tee |
|
||||
| Code | TEE_CODE |
|
||||
| Description | Interesting description |
|
||||
| Price | 59.99 |
|
||||
| Name | Manchester United tee |
|
||||
| sylius_product_legacy_code | TEE_CODE |
|
||||
| sylius_product_legacy_masterVariant_code | TEE_CODE |
|
||||
| Description | Interesting description |
|
||||
| Price | 59.99 |
|
||||
And go to "Attributes" tab
|
||||
And I add "T-Shirt fare trade" attribute
|
||||
And I check "T-Shirt fare trade"
|
||||
|
|
@ -161,10 +167,11 @@ Feature: Products
|
|||
Scenario: Creating product with multiple attributes
|
||||
Given I am on the product creation page
|
||||
When I fill in the following:
|
||||
| Name | FC Barcelona tee |
|
||||
| Code | TEE_CODE |
|
||||
| Description | Interesting description |
|
||||
| Price | 59.99 |
|
||||
| Name | FC Barcelona tee |
|
||||
| sylius_product_legacy_code | TEE_CODE |
|
||||
| sylius_product_legacy_masterVariant_code | TEE_CODE |
|
||||
| Description | Interesting description |
|
||||
| Price | 59.99 |
|
||||
And go to "Attributes" tab
|
||||
And I add following attributes:
|
||||
| T-Shirt fabric |
|
||||
|
|
@ -181,10 +188,11 @@ Feature: Products
|
|||
Scenario: Created product does not pass validation
|
||||
Given I am on the product creation page
|
||||
When I fill in the following:
|
||||
| Name | FC Barcelona tee |
|
||||
| Code | TEE_CODE |
|
||||
| Description | Interesting description |
|
||||
| Price | 59.99 |
|
||||
| Name | FC Barcelona tee |
|
||||
| sylius_product_legacy_code | TEE_CODE |
|
||||
| sylius_product_legacy_masterVariant_code | TEE_CODE |
|
||||
| Description | Interesting description |
|
||||
| Price | 59.99 |
|
||||
And I go to "Attributes" tab
|
||||
And I add "T-Shirt fabric" attribute
|
||||
And I fill in "T-Shirt fabric" with "X"
|
||||
|
|
@ -196,10 +204,11 @@ Feature: Products
|
|||
Scenario: Created products appear in the list
|
||||
Given I am on the product creation page
|
||||
And I fill in the following:
|
||||
| Name | Manchester United tee |
|
||||
| Description | Interesting description |
|
||||
| Price | 59.99 |
|
||||
| Code | BOSTON_TEE |
|
||||
| Name | Manchester United tee |
|
||||
| Description | Interesting description |
|
||||
| Price | 59.99 |
|
||||
| sylius_product_legacy_code | BOSTON_TEE |
|
||||
| sylius_product_legacy_masterVariant_code | BOSTON_TEE |
|
||||
And I press "Create"
|
||||
When I go to the product index page
|
||||
Then I should see 5 products in the list
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ Feature: Products filter
|
|||
|
||||
Scenario: Filtering products by SKU
|
||||
Given I am on the product index page
|
||||
When I fill in "SKU" with "555"
|
||||
When I fill in "Code" with "555"
|
||||
And I press "Filter"
|
||||
Then I should be on the product index page
|
||||
And I should see 1 product in the list
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@ Feature: Products
|
|||
Given I am on the product creation page
|
||||
And I fill in the following:
|
||||
| Price | 29.99 |
|
||||
| Code | SOY_PRODUCT |
|
||||
| sylius_product_legacy_code | SOY_PRODUCT |
|
||||
| sylius_product_legacy_masterVariant_code | SOY_PRODUCT |
|
||||
| sylius_product_legacy_translations_es_ES_name | Soy i18n |
|
||||
| sylius_product_legacy_translations_es_ES_description | Conmemorando el dia i18n |
|
||||
| sylius_product_legacy_translations_en_US_name | I am i18n |
|
||||
|
|
|
|||
|
|
@ -29,10 +29,11 @@ Feature: Orm indexer event listener
|
|||
Scenario: Creating simple product and indexing it
|
||||
Given I am on the product creation page
|
||||
When I fill in the following:
|
||||
| Name | Index test product |
|
||||
| Code | TEST_PRODUCT |
|
||||
| Description | Interesting description |
|
||||
| Price | 29.99 |
|
||||
| Name | Index test product |
|
||||
| sylius_product_legacy_code | TEST_PRODUCT |
|
||||
| sylius_product_legacy_masterVariant_code | TEST_PRODUCT |
|
||||
| Description | Interesting description |
|
||||
| Price | 29.99 |
|
||||
And I press "Create"
|
||||
Then I should be on the page of product "Index test product"
|
||||
And I should see "Product has been successfully created"
|
||||
|
|
|
|||
|
|
@ -62,10 +62,11 @@ Feature: Hierarchical Role based access control (HRBAC)
|
|||
Given I am logged in as "Catalog Manager"
|
||||
And I am on the product creation page
|
||||
When I fill in the following:
|
||||
| Name | Book about Everything |
|
||||
| Description | Interesting description |
|
||||
| Price | 29.99 |
|
||||
| Code | OMNI_BOOK |
|
||||
| Name | Book about Everything |
|
||||
| Description | Interesting description |
|
||||
| Price | 29.99 |
|
||||
| sylius_product_legacy_code | OMNI_BOOK |
|
||||
| sylius_product_legacy_masterVariant_code | OMNI_BOOK |
|
||||
And I press "Create"
|
||||
Then I should be on the page of product "Book about Everything"
|
||||
And I should see "Product has been successfully created"
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ final class ProductContext implements Context
|
|||
$variant = $this->productVariantFactory->createNew();
|
||||
|
||||
$variant->setPresentation($variantHash['name']);
|
||||
$variant->setCode($this->convertToCode($variantHash['name']));
|
||||
$variant->setPrice($this->getPriceFromString(str_replace(['$', '€', '£'], '', $variantHash['price'])));
|
||||
$variant->setProduct($product);
|
||||
$product->addVariant($variant);
|
||||
|
|
@ -329,6 +330,7 @@ final class ProductContext implements Context
|
|||
|
||||
$variant->addOption($optionValue);
|
||||
$variant->setPrice($price);
|
||||
$variant->setCode(sprintf("%s_%s", $product->getCode(), $optionValueName));
|
||||
|
||||
$product->addVariant($variant);
|
||||
$this->objectManager->flush();
|
||||
|
|
|
|||
|
|
@ -801,6 +801,7 @@ class CoreContext extends DefaultContext
|
|||
|
||||
foreach ($product->getVariants() as $variant) {
|
||||
$variant->setPrice($product->getMasterVariant()->getPrice());
|
||||
$variant->setCode($this->faker->unique->uuid);
|
||||
}
|
||||
|
||||
$this->getEntityManager()->persist($product);
|
||||
|
|
|
|||
|
|
@ -110,10 +110,10 @@ class ProductRepository extends BaseProductRepository implements ProductReposito
|
|||
->setParameter('name', '%'.$criteria['name'].'%')
|
||||
;
|
||||
}
|
||||
if (!empty($criteria['sku'])) {
|
||||
if (!empty($criteria['code'])) {
|
||||
$queryBuilder
|
||||
->andWhere('variant.sku = :sku')
|
||||
->setParameter('sku', $criteria['sku'])
|
||||
->andWhere('variant.code = :code')
|
||||
->setParameter('code', $criteria['code'])
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,11 +33,11 @@ class ProductFilterType extends AbstractType
|
|||
'placeholder' => 'sylius.form.product_filter.name',
|
||||
],
|
||||
])
|
||||
->add('sku', 'text', [
|
||||
->add('code', 'text', [
|
||||
'required' => false,
|
||||
'label' => 'sylius.form.product_filter.sku',
|
||||
'label' => 'sylius.form.product_filter.code',
|
||||
'attr' => [
|
||||
'placeholder' => 'sylius.form.product_filter.sku',
|
||||
'placeholder' => 'sylius.form.product_filter.code',
|
||||
],
|
||||
])
|
||||
;
|
||||
|
|
|
|||
|
|
@ -27,9 +27,6 @@ class ProductVariantType extends BaseVariantType
|
|||
parent::buildForm($builder, $options);
|
||||
|
||||
$builder
|
||||
->add('sku', 'text', [
|
||||
'label' => 'sylius.form.variant.sku',
|
||||
])
|
||||
->add('price', 'sylius_money', [
|
||||
'label' => 'sylius.form.variant.price',
|
||||
])
|
||||
|
|
|
|||
|
|
@ -19,13 +19,9 @@
|
|||
|
||||
<mapped-superclass name="Sylius\Component\Core\Model\ProductVariant" table="sylius_product_variant">
|
||||
<indexes>
|
||||
<index columns="sku" />
|
||||
<index columns="sold" />
|
||||
</indexes>
|
||||
|
||||
<field name="sku" column="sku" type="string" nullable="true">
|
||||
<gedmo:versioned/>
|
||||
</field>
|
||||
<field name="onHold" column="on_hold" type="integer" />
|
||||
<field name="onHand" column="on_hand" type="integer" />
|
||||
<field name="sold" column="sold" type="integer" />
|
||||
|
|
|
|||
|
|
@ -26,11 +26,6 @@
|
|||
</class>
|
||||
|
||||
<class name="Sylius\Component\Core\Model\ProductVariant">
|
||||
<constraint name="Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity">
|
||||
<option name="fields">sku</option>
|
||||
<option name="message">sylius.product_variant.sku.unique</option>
|
||||
<option name="groups">sylius</option>
|
||||
</constraint>
|
||||
<property name="price">
|
||||
<constraint name="NotBlank">
|
||||
<option name="message">sylius.product_variant.price.not_blank</option>
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ sylius:
|
|||
main_taxon: Main taxon
|
||||
product_filter:
|
||||
name: Name
|
||||
sku: SKU
|
||||
code: Code
|
||||
product_variant:
|
||||
tax_category: Tax category
|
||||
settings:
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ class LoadProductsData extends DataFixture
|
|||
foreach ($product->getVariants() as $variant) {
|
||||
$variant->setAvailableOn($this->faker->dateTimeThisYear);
|
||||
$variant->setPrice($this->faker->randomNumber(4));
|
||||
$variant->setSku($this->getUniqueSku());
|
||||
$variant->setCode($this->getUniqueCode());
|
||||
$variant->setOnHand($this->faker->randomNumber(1));
|
||||
|
||||
$this->setReference('Sylius.Variant-'.$this->totalVariants, $variant);
|
||||
|
|
@ -268,14 +268,14 @@ class LoadProductsData extends DataFixture
|
|||
* Adds master variant to product.
|
||||
*
|
||||
* @param ProductInterface $product
|
||||
* @param string $sku
|
||||
* @param string $code
|
||||
*/
|
||||
protected function addMasterVariant(ProductInterface $product, $sku = null)
|
||||
protected function addMasterVariant(ProductInterface $product, $code = null)
|
||||
{
|
||||
$variant = $product->getMasterVariant();
|
||||
$variant->setProduct($product);
|
||||
$variant->setPrice($this->faker->randomNumber(4));
|
||||
$variant->setSku(null === $sku ? $this->getUniqueSku() : $sku);
|
||||
$variant->setCode(null === $code ? $this->getUniqueCode() : $code);
|
||||
$variant->setAvailableOn($this->faker->dateTimeThisYear);
|
||||
$variant->setOnHand($this->faker->randomNumber(1));
|
||||
$variant->setTaxCategory($this->getTaxCategory('taxable'));
|
||||
|
|
@ -295,8 +295,8 @@ class LoadProductsData extends DataFixture
|
|||
* Adds attribute to product with given value.
|
||||
*
|
||||
* @param ProductInterface $product
|
||||
* @param string $code
|
||||
* @param string $value
|
||||
* @param string $code
|
||||
* @param string $value
|
||||
*/
|
||||
protected function addAttribute(ProductInterface $product, $code, $value)
|
||||
{
|
||||
|
|
@ -313,7 +313,7 @@ class LoadProductsData extends DataFixture
|
|||
* Adds taxons to given product.
|
||||
*
|
||||
* @param ProductInterface $product
|
||||
* @param array $taxonCodes
|
||||
* @param array $taxonCodes
|
||||
*/
|
||||
protected function setTaxons(ProductInterface $product, array $taxonCodes)
|
||||
{
|
||||
|
|
@ -330,7 +330,7 @@ class LoadProductsData extends DataFixture
|
|||
* Set channels.
|
||||
*
|
||||
* @param ProductInterface $product
|
||||
* @param array $channelCodes
|
||||
* @param array $channelCodes
|
||||
*/
|
||||
protected function setChannels(ProductInterface $product, array $channelCodes)
|
||||
{
|
||||
|
|
@ -352,13 +352,11 @@ class LoadProductsData extends DataFixture
|
|||
/**
|
||||
* Get unique SKU.
|
||||
*
|
||||
* @param int $length
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getUniqueSku($length = 5)
|
||||
protected function getUniqueCode()
|
||||
{
|
||||
return $this->faker->unique()->randomNumber($length);
|
||||
return $this->faker->unique()->uuid();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ class ProductContext extends DefaultContext
|
|||
$product->setCode($code);
|
||||
|
||||
$product->getMasterVariant()->setPrice((int) round($data['price'] * 100));
|
||||
$product->getMasterVariant()->setCode($code);
|
||||
|
||||
if (!empty($data['options'])) {
|
||||
foreach (explode(',', $data['options']) as $option) {
|
||||
|
|
@ -59,10 +60,6 @@ class ProductContext extends DefaultContext
|
|||
$product->addAttribute($attributeValue);
|
||||
}
|
||||
|
||||
if (isset($data['sku'])) {
|
||||
$product->setSku($data['sku']);
|
||||
}
|
||||
|
||||
if (isset($data['description'])) {
|
||||
$product->setDescription($data['description']);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,4 +33,15 @@ class VariantRepository extends EntityRepository implements VariantRepositoryInt
|
|||
->getOneOrNullResult()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createQueryBuilderWithProduct($productId)
|
||||
{
|
||||
return $this->createQueryBuilder('o')
|
||||
->where('o.object = :productId')
|
||||
->setParameter('productId', $productId)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Bundle\ProductBundle\Form\EventSubscriber;
|
||||
|
||||
use Sylius\Component\Product\Model\ProductInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
/**
|
||||
* @author Łukasz Chruściel <lukasz.chrusciel@lakion.com>
|
||||
*/
|
||||
class ProductOptionFieldSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
FormEvents::PRE_SET_DATA => 'preSetData',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormEvent $event
|
||||
*/
|
||||
public function preSetData(FormEvent $event)
|
||||
{
|
||||
/** @var ProductInterface $product */
|
||||
$product = $event->getData();
|
||||
|
||||
Assert::isInstanceOf($product, ProductInterface::class);
|
||||
|
||||
if (!$product->isSimple()) {
|
||||
$form = $event->getForm();
|
||||
|
||||
/** Options should be disabled for configurable product if it has at least one defined variant */
|
||||
$disableOptions = (null !== $product->getMasterVariant()) && (false === $product->hasVariants());
|
||||
|
||||
$form->add(
|
||||
'options',
|
||||
'sylius_product_option_choice', [
|
||||
'required' => false,
|
||||
'disabled' => $disableOptions,
|
||||
'multiple' => true,
|
||||
'label' => 'sylius.form.product.options',
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ use Webmozart\Assert\Assert;
|
|||
/**
|
||||
* @author Łukasz Chruściel <lukasz.chrusciel@lakion.com>
|
||||
*/
|
||||
class ConfigurableProductSubscriber implements EventSubscriberInterface
|
||||
class SimpleProductSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
@ -29,6 +29,7 @@ class ConfigurableProductSubscriber implements EventSubscriberInterface
|
|||
{
|
||||
return [
|
||||
FormEvents::PRE_SET_DATA => 'preSetData',
|
||||
FormEvents::PRE_SUBMIT => 'preSubmit',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -43,20 +44,25 @@ class ConfigurableProductSubscriber implements EventSubscriberInterface
|
|||
Assert::isInstanceOf($product, ProductInterface::class);
|
||||
|
||||
if ($product->isSimple()) {
|
||||
$form = $event->getForm();
|
||||
|
||||
$form->add('masterVariant', 'sylius_product_variant', ['master' => true]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormEvent $event
|
||||
*/
|
||||
public function preSubmit(FormEvent $event)
|
||||
{
|
||||
$data = $event->getData();
|
||||
|
||||
if (empty($data) || !array_key_exists('masterVariant', $data) || !array_key_exists('code', $data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$form = $event->getForm();
|
||||
$form->remove('masterVariant');
|
||||
$data['masterVariant']['code'] = $data['code'];
|
||||
|
||||
/** Options should be disabled for configurable product if it has at least one defined variant */
|
||||
$disableOptions = (null !== $product->getMasterVariant()) && (false === $product->hasVariants());
|
||||
|
||||
$form->add('options', 'sylius_product_option_choice', [
|
||||
'required' => false,
|
||||
'disabled' => $disableOptions,
|
||||
'multiple' => true,
|
||||
'label' => 'sylius.form.product.options',
|
||||
]);
|
||||
$event->setData($data);
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,8 @@
|
|||
|
||||
namespace Sylius\Bundle\ProductBundle\Form\Type;
|
||||
|
||||
use Sylius\Bundle\ProductBundle\Form\EventSubscriber\ConfigurableProductSubscriber;
|
||||
use Sylius\Bundle\ProductBundle\Form\EventSubscriber\ProductOptionFieldSubscriber;
|
||||
use Sylius\Bundle\ProductBundle\Form\EventSubscriber\SimpleProductSubscriber;
|
||||
use Sylius\Bundle\ResourceBundle\Form\EventSubscriber\AddCodeFormSubscriber;
|
||||
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
|
@ -28,11 +29,9 @@ class ProductType extends AbstractResourceType
|
|||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('masterVariant', 'sylius_product_variant', [
|
||||
'master' => true,
|
||||
])
|
||||
->addEventSubscriber(new AddCodeFormSubscriber())
|
||||
->addEventSubscriber(new ConfigurableProductSubscriber())
|
||||
->addEventSubscriber(new ProductOptionFieldSubscriber())
|
||||
->addEventSubscriber(new SimpleProductSubscriber())
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
namespace Sylius\Bundle\VariationBundle\Form\Type;
|
||||
|
||||
use Sylius\Bundle\ResourceBundle\Form\EventSubscriber\AddCodeFormSubscriber;
|
||||
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
|
||||
use Sylius\Bundle\VariationBundle\Form\EventListener\BuildVariantFormSubscriber;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
|
@ -48,6 +49,7 @@ class VariantType extends AbstractResourceType
|
|||
'required' => false,
|
||||
'label' => 'sylius.form.variant.presentation',
|
||||
])
|
||||
->addEventSubscriber(new AddCodeFormSubscriber())
|
||||
;
|
||||
|
||||
if (!$options['master']) {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
<generator strategy="AUTO" />
|
||||
</id>
|
||||
|
||||
<field name="code" column="code" type="string" unique="true" nullable="false"/>
|
||||
|
||||
<field name="master" column="is_master" type="boolean" />
|
||||
<field name="presentation" column="presentation" type="string" nullable="true" />
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th>{{ sylius_resource_sort('id', '#id') }}</th>
|
||||
<th>{{ sylius_resource_sort('sku', 'sylius.ui.sku'|trans) }}</th>
|
||||
<th>{{ sylius_resource_sort('code', 'sylius.ui.code'|trans) }}</th>
|
||||
<th>{{ sylius_resource_sort('name', 'sylius.ui.name'|trans) }}</th>
|
||||
<th>{{ sylius_resource_sort('onHand', 'sylius.stockable.on_hand'|trans) }}</th>
|
||||
<th>{{ sylius_resource_sort('onHold', 'sylius.ui.on_hold'|trans) }}</th>
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
{{ product.id }}
|
||||
</td>
|
||||
<td>
|
||||
{{ product.sku }}
|
||||
{{ product.code }}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ path('sylius_backend_product_show', {'id': product.id}) }}" class="btn btn-link">
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@
|
|||
</a>
|
||||
{% if product.hasOptions %}
|
||||
<ul class="list-unstyled">
|
||||
<li class="sku"><strong>{{ 'sylius.ui.sku'|trans }}</strong>: <code>{{ variant.sku|default('SKU') }}</code></li>
|
||||
<li class="code"><strong>{{ 'sylius.ui.code'|trans }}</strong>: <code>{{ variant.code|default('SKU') }}</code></li>
|
||||
{% for option in variant.options %}
|
||||
<li><strong>{{ option.presentation }}</strong>: {{ option.value }}</li>
|
||||
{% endfor %}
|
||||
|
|
@ -246,7 +246,7 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>{{ 'sylius.ui.sku'|trans }}</th>
|
||||
<th>{{ 'sylius.ui.code'|trans }}</th>
|
||||
<th>{{ 'sylius.ui.name'|trans }}</th>
|
||||
<th>{{ 'sylius.ui.inventory_state'|trans }}</th>
|
||||
<th>{{ 'sylius.ui.shipping_state'|trans }}</th>
|
||||
|
|
@ -259,7 +259,7 @@
|
|||
{% for unit in order.itemUnits %}
|
||||
<tr>
|
||||
<td>{{ loop.index }}</td>
|
||||
<td>{{ unit.stockable.sku }}</td>
|
||||
<td>{{ unit.stockable.code }}</td>
|
||||
<td>{{ unit.inventoryName }}</td>
|
||||
<td>{{ unit.inventoryState|humanize }}</td>
|
||||
<td>{{ unit.shippingState|humanize }}</td>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<div class="tab-pane active" id="main">
|
||||
{{ form_row(form.translations, {'attr': {'class': 'input-lg'}}) }}
|
||||
{{ form_row(form.masterVariant.sku) }}
|
||||
{{ form_row(form.masterVariant.code) }}
|
||||
{{ form_row(form.code) }}
|
||||
<hr />
|
||||
<div class="row">
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
<form method="get" action="" class="form-inline form-filter">
|
||||
{{ form_row(form.name) }}
|
||||
{{ form_row(form.sku) }}
|
||||
{{ form_row(form.code) }}
|
||||
<button type="submit" class="btn btn-primary"><i class="glyphicon glyphicon-search"></i> {{ 'sylius.ui.filter'|trans }}</button>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@
|
|||
{% endif %}
|
||||
</h5>
|
||||
<div class="media-body">
|
||||
{% if product.sku %}
|
||||
<strong>{{ 'sylius.ui.sku'|trans }}: </strong> <code class="sku">{{ product.sku }}</code>
|
||||
{% if product.code %}
|
||||
<strong>{{ 'sylius.ui.code'|trans }}: </strong> <code class="code">{{ product.code }}</code>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@
|
|||
<td>{{ product.id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'sylius.ui.sku'|trans }}</td>
|
||||
<td>{{ product.sku }}</td>
|
||||
<td>{{ 'sylius.ui.code'|trans }}</td>
|
||||
<td>{{ product.code }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'sylius.ui.name'|trans }}</td>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
{% endfor %}
|
||||
{% endif %}
|
||||
{{ form_row(form.presentation) }}
|
||||
{{ form_row(form.sku) }}
|
||||
{{ form_row(form.code) }}
|
||||
|
||||
{{ form_row(form.availableOn) }}
|
||||
{{ form_row(form.availableUntil) }}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th>id</th>
|
||||
<th>{{ 'sylius.ui.sku'|trans }}</th>
|
||||
<th>{{ 'sylius.ui.code'|trans }}</th>
|
||||
<th></th>
|
||||
<th>{{ 'sylius.ui.availability'|trans }}</th>
|
||||
<th>{{ 'sylius.ui.last_update'|trans }}</th>
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
{% set product = variant.product %}
|
||||
<tr id="{{ variant.id }}">
|
||||
<td>{{ variant.id }}</td>
|
||||
<td>{{ variant.sku ?: '-' }}</td>
|
||||
<td>{{ variant.code ?: '-' }}</td>
|
||||
<td>{% if variant.images.count > 0 %}
|
||||
<img class="img-polaroid" src="{{ variant.images.offsetGet(0).path|imagine_filter('sylius_small') }}" />
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -94,22 +94,6 @@ class Product extends BaseProduct implements ProductInterface, ReviewableProduct
|
|||
return $this->getMetadataClassIdentifier().'-'.$this->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSku()
|
||||
{
|
||||
return $this->getMasterVariant()->getSku();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setSku($sku)
|
||||
{
|
||||
$this->getMasterVariant()->setSku($sku);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -44,16 +44,6 @@ interface ProductInterface extends
|
|||
|
||||
const METADATA_CLASS_IDENTIFIER = 'Product';
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSku();
|
||||
|
||||
/**
|
||||
* @param string $sku
|
||||
*/
|
||||
public function setSku($sku);
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -23,11 +23,6 @@ use Sylius\Component\Variation\Model\VariantInterface as BaseVariantInterface;
|
|||
*/
|
||||
class ProductVariant extends BaseVariant implements ProductVariantInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sku;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
|
|
@ -141,22 +136,6 @@ class ProductVariant extends BaseVariant implements ProductVariantInterface
|
|||
return $this->getMetadataClassIdentifier().'-'.$this->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSku()
|
||||
{
|
||||
return $this->sku;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setSku($sku)
|
||||
{
|
||||
$this->sku = $sku;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -189,17 +189,17 @@ class ProductVariantSpec extends ObjectBehavior
|
|||
$this->getShippingHeight()->shouldReturn(110);
|
||||
}
|
||||
|
||||
function it_has_no_sku_by_default()
|
||||
function it_has_no_code_by_default()
|
||||
{
|
||||
$this->getSku()->shouldReturn(null);
|
||||
$this->getCode()->shouldReturn(null);
|
||||
}
|
||||
|
||||
function its_sku_is_mutable()
|
||||
function its_code_is_mutable()
|
||||
{
|
||||
$sku = 'dummy-sku123';
|
||||
|
||||
$this->setSku($sku);
|
||||
$this->getSku()->shouldReturn($sku);
|
||||
$this->setCode($sku);
|
||||
$this->getCode()->shouldReturn($sku);
|
||||
}
|
||||
|
||||
function it_does_not_have_tax_category_by_default()
|
||||
|
|
|
|||
|
|
@ -25,4 +25,11 @@ interface VariantRepositoryInterface extends RepositoryInterface
|
|||
* @return VariantInterface|null
|
||||
*/
|
||||
public function findOneByName($name);
|
||||
|
||||
/**
|
||||
* @param mixed $productId
|
||||
*
|
||||
* @return QueryBuilder
|
||||
*/
|
||||
public function createQueryBuilderWithProduct($productId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,11 @@ class Variant implements VariantInterface
|
|||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $code;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
|
|
@ -61,6 +66,22 @@ class Variant implements VariantInterface
|
|||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $code
|
||||
*/
|
||||
public function setCode($code)
|
||||
{
|
||||
$this->code = $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -12,13 +12,14 @@
|
|||
namespace Sylius\Component\Variation\Model;
|
||||
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Sylius\Component\Resource\Model\CodeAwareInterface;
|
||||
use Sylius\Component\Resource\Model\ResourceInterface;
|
||||
use Sylius\Component\Resource\Model\TimestampableInterface;
|
||||
|
||||
/**
|
||||
* @author Paweł Jędrzejewski <pawel@sylius.org>
|
||||
*/
|
||||
interface VariantInterface extends TimestampableInterface, ResourceInterface
|
||||
interface VariantInterface extends TimestampableInterface, ResourceInterface, CodeAwareInterface
|
||||
{
|
||||
/**
|
||||
* Checks whether variant is master.
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
Sylius\Component\Core\Model\ProductVariant:
|
||||
productVariant1:
|
||||
master: true
|
||||
code: MUG_1
|
||||
productVariant2:
|
||||
master: true
|
||||
code: MUG_2
|
||||
productVariant3:
|
||||
master: true
|
||||
code: MUG_3
|
||||
|
||||
Sylius\Component\Core\Model\Product:
|
||||
product1:
|
||||
|
|
@ -14,7 +17,6 @@ Sylius\Component\Core\Model\Product:
|
|||
variants: [@productVariant1]
|
||||
setPrice: [20]
|
||||
code: MUG_SW
|
||||
setSku: [mug1]
|
||||
product2:
|
||||
updatedAt: 2015-10-04
|
||||
currentLocale: en_US
|
||||
|
|
@ -22,7 +24,6 @@ Sylius\Component\Core\Model\Product:
|
|||
variants: [@productVariant2]
|
||||
setPrice: [20]
|
||||
code: MUG_LOTR
|
||||
setSku: [mug2]
|
||||
product3:
|
||||
updatedAt: 2015-10-05
|
||||
currentLocale: en_US
|
||||
|
|
@ -30,7 +31,6 @@ Sylius\Component\Core\Model\Product:
|
|||
variants: [@productVariant3]
|
||||
setPrice: [20]
|
||||
code: MUG_BB
|
||||
setSku: [mug3]
|
||||
|
||||
Sylius\Component\Core\Model\ProductTranslation:
|
||||
productTranslation1:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue