- {{ form_label(form.masterVariant.availableOn) }}
- {{ form_widget(form.masterVariant.availableOn, {'label': false}) }}
+ {{ form_row(form.masterVariant.availableOn) }}
+ {{ form_row(form.masterVariant.availableUntil) }}
{{ form_row(form.masterVariant.availableOnDemand) }}
{{ form_row(form.masterVariant.onHand) }}
diff --git a/src/Sylius/Bundle/WebBundle/Resources/views/Backend/Product/show.html.twig b/src/Sylius/Bundle/WebBundle/Resources/views/Backend/Product/show.html.twig
index 8b8b2c05987..665402fad53 100644
--- a/src/Sylius/Bundle/WebBundle/Resources/views/Backend/Product/show.html.twig
+++ b/src/Sylius/Bundle/WebBundle/Resources/views/Backend/Product/show.html.twig
@@ -71,9 +71,17 @@
{{ 'sylius.product.options'|trans }} |
diff --git a/src/Sylius/Bundle/WebBundle/Resources/views/Backend/ProductVariant/_form.html.twig b/src/Sylius/Bundle/WebBundle/Resources/views/Backend/ProductVariant/_form.html.twig
index 51182dc6ce4..5a22cdb5ec7 100644
--- a/src/Sylius/Bundle/WebBundle/Resources/views/Backend/ProductVariant/_form.html.twig
+++ b/src/Sylius/Bundle/WebBundle/Resources/views/Backend/ProductVariant/_form.html.twig
@@ -15,6 +15,15 @@
{{ form_row(form.availableOn.date, {'label': false}) }}
{{ form_row(form.availableOn.time, {'label': false}) }}
+ {{ form_errors(form.availableOn) }}
+
+
+
{{ form_row(form.price) }}
diff --git a/src/Sylius/Bundle/WebBundle/Resources/views/Backend/ProductVariant/macros.html.twig b/src/Sylius/Bundle/WebBundle/Resources/views/Backend/ProductVariant/macros.html.twig
index c21b1ab3592..092473590ba 100644
--- a/src/Sylius/Bundle/WebBundle/Resources/views/Backend/ProductVariant/macros.html.twig
+++ b/src/Sylius/Bundle/WebBundle/Resources/views/Backend/ProductVariant/macros.html.twig
@@ -10,7 +10,8 @@
id |
{{ 'sylius.variant.sku'|trans }} |
|
- {{ 'sylius.variant.availability'|trans }} |
+ {{ 'sylius.variant.available_on'|trans }} |
+ {{ 'sylius.variant.available_until'|trans }} |
{{ 'sylius.variant.last_update'|trans }} |
{{ 'sylius.variant.options'|trans }} |
{{ 'sylius.variant.available_on_demand'|trans }} |
@@ -29,7 +30,14 @@
{% endif %}
- {{ variant.availableOn|date }} |
+
+
+ {{ variant.availableOn|date }}
+
+ |
+
+ {{ variant.availableUntil == null ? 'sylius.variant.available_unlimited'|trans : variant.availableUntil|date }}
+ |
{{ product.updatedAt|date }} |
diff --git a/src/Sylius/Bundle/WebBundle/Resources/views/Frontend/Product/show.html.twig b/src/Sylius/Bundle/WebBundle/Resources/views/Frontend/Product/show.html.twig
index cd29faf7158..8251115f2ae 100644
--- a/src/Sylius/Bundle/WebBundle/Resources/views/Frontend/Product/show.html.twig
+++ b/src/Sylius/Bundle/WebBundle/Resources/views/Frontend/Product/show.html.twig
@@ -105,7 +105,9 @@
{% endif %}
- {% if not product.hasVariants and not sylius_inventory_is_available(product.masterVariant) %}
+ {% if not product.available %}
+ {{ 'sylius.product.unavailable'|trans }}
+ {% elseif not product.hasVariants and not sylius_inventory_is_available(product.masterVariant) %}
{{ 'sylius.out_of_stock'|trans }}
{% else %}
{{ form_row(form.quantity, {'attr': {'class': 'center-text'}, 'empty_value': '1'}) }}
diff --git a/src/Sylius/Component/Product/Model/Product.php b/src/Sylius/Component/Product/Model/Product.php
index afa51f95e3f..fefef701b5a 100644
--- a/src/Sylius/Component/Product/Model/Product.php
+++ b/src/Sylius/Component/Product/Model/Product.php
@@ -11,6 +11,7 @@
namespace Sylius\Component\Product\Model;
+use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Sylius\Component\Archetype\Model\ArchetypeInterface as BaseArchetypeInterface;
@@ -42,10 +43,18 @@ class Product extends AbstractTranslatable implements ProductInterface
/**
* Available on.
*
- * @var \DateTime
+ * @var DateTime
*/
protected $availableOn;
+
+ /**
+ * Available until.
+ *
+ * @var DateTime
+ */
+ protected $availableUntil;
+
/**
* Attributes.
*
@@ -70,21 +79,21 @@ class Product extends AbstractTranslatable implements ProductInterface
/**
* Creation time.
*
- * @var \DateTime
+ * @var DateTime
*/
protected $createdAt;
/**
* Last update time.
*
- * @var \DateTime
+ * @var DateTime
*/
protected $updatedAt;
/**
* Deletion time.
*
- * @var \DateTime
+ * @var DateTime
*/
protected $deletedAt;
@@ -94,11 +103,12 @@ class Product extends AbstractTranslatable implements ProductInterface
public function __construct()
{
parent::__construct();
- $this->availableOn = new \DateTime();
+ $this->availableOn = new DateTime();
+ $this->availableUntil = null;
$this->attributes = new ArrayCollection();
$this->variants = new ArrayCollection();
$this->options = new ArrayCollection();
- $this->createdAt = new \DateTime();
+ $this->createdAt = new DateTime();
}
/**
@@ -222,7 +232,14 @@ public function setMetaDescription($metaDescription)
*/
public function isAvailable()
{
- return new \DateTime() >= $this->availableOn;
+ $now = new DateTime();
+ return
+ $now >= $this->availableOn
+ && (
+ $this->availableUntil === null ?
+ true :
+ ( $now < $this->availableUntil )
+ );
}
/**
@@ -236,13 +253,29 @@ public function getAvailableOn()
/**
* {@inheritdoc}
*/
- public function setAvailableOn(\DateTime $availableOn = null)
+ public function setAvailableOn(DateTime $availableOn = null)
{
$this->availableOn = $availableOn;
-
return $this;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function getAvailableUntil()
+ {
+ return $this->availableUntil;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setAvailableUntil(DateTime $availableUntil = null)
+ {
+ $this->availableUntil = $availableUntil;
+ return $this;
+ }
+
/**
* {@inheritdoc}
*/
@@ -499,7 +532,7 @@ public function getCreatedAt()
/**
* {@inheritdoc}
*/
- public function setCreatedAt(\DateTime $createdAt)
+ public function setCreatedAt(DateTime $createdAt)
{
$this->createdAt = $createdAt;
@@ -517,7 +550,7 @@ public function getUpdatedAt()
/**
* {@inheritdoc}
*/
- public function setUpdatedAt(\DateTime $updatedAt)
+ public function setUpdatedAt(DateTime $updatedAt)
{
$this->updatedAt = $updatedAt;
@@ -529,7 +562,7 @@ public function setUpdatedAt(\DateTime $updatedAt)
*/
public function isDeleted()
{
- return null !== $this->deletedAt && new \DateTime() >= $this->deletedAt;
+ return null !== $this->deletedAt && new DateTime() >= $this->deletedAt;
}
/**
@@ -543,7 +576,7 @@ public function getDeletedAt()
/**
* {@inheritdoc}
*/
- public function setDeletedAt(\DateTime $deletedAt)
+ public function setDeletedAt(DateTime $deletedAt)
{
$this->deletedAt = $deletedAt;
diff --git a/src/Sylius/Component/Product/Model/ProductInterface.php b/src/Sylius/Component/Product/Model/ProductInterface.php
index 9318ef82880..4cc9df5e175 100644
--- a/src/Sylius/Component/Product/Model/ProductInterface.php
+++ b/src/Sylius/Component/Product/Model/ProductInterface.php
@@ -23,30 +23,44 @@
* @author Gonzalo Vilaseca
*/
interface ProductInterface extends
- ArchetypeSubjectInterface,
- SlugAwareInterface,
- SoftDeletableInterface,
- TimestampableInterface,
- ProductTranslationInterface
+ ArchetypeSubjectInterface,
+ SlugAwareInterface,
+ SoftDeletableInterface,
+ TimestampableInterface,
+ ProductTranslationInterface
{
- /**
- * Check whether the product is available.
- *
- * @return bool
- */
- public function isAvailable();
-
- /**
- * Return available on.
- *
- * @return \DateTime
- */
- public function getAvailableOn();
-
- /**
- * Set available on.
- *
- * @param null|\DateTime $availableOn
- */
- public function setAvailableOn(\DateTime $availableOn = null);
+ /**
+ * Check whether the product is available.
+ *
+ * @return bool
+ */
+ public function isAvailable();
+
+ /**
+ * Return available on.
+ *
+ * @return \DateTime
+ */
+ public function getAvailableOn();
+
+ /**
+ * Set available on.
+ *
+ * @param null|\DateTime $availableOn
+ */
+ public function setAvailableOn(\DateTime $availableOn = null);
+
+ /**
+ * Return available until.
+ *
+ * @return \DateTime
+ */
+ public function getAvailableUntil();
+
+ /**
+ * Set available until.
+ *
+ * @param null|\DateTime $availableUntil
+ */
+ public function setAvailableUntil(\DateTime $availableUntil = null);
}
diff --git a/src/Sylius/Component/Product/Model/Variant.php b/src/Sylius/Component/Product/Model/Variant.php
index 4131676af9d..e7b7bcb379f 100644
--- a/src/Sylius/Component/Product/Model/Variant.php
+++ b/src/Sylius/Component/Product/Model/Variant.php
@@ -11,6 +11,7 @@
namespace Sylius\Component\Product\Model;
+use DateTime;
use Sylius\Component\Variation\Model\Variant as BaseVariant;
use Sylius\Component\Variation\Model\VariantInterface as BaseVariantInterface;
@@ -21,82 +22,119 @@
*/
class Variant extends BaseVariant implements VariantInterface
{
- /**
- * Available on.
- *
- * @var \DateTime
- */
- protected $availableOn;
-
- /**
- * Constructor.
- */
- public function __construct()
- {
- parent::__construct();
-
- $this->availableOn = new \DateTime();
- }
-
- /**
- * {@inheritdoc}
- */
- public function getProduct()
- {
- return parent::getObject();
- }
-
- /**
- * {@inheritdoc}
- */
- public function setProduct(ProductInterface $product = null)
- {
- return parent::setObject($product);
- }
-
- /**
- * {@inheritdoc}
- */
- public function isAvailable()
- {
- return new \DateTime() >= $this->availableOn;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getAvailableOn()
- {
- return $this->availableOn;
- }
-
- /**
- * {@inheritdoc}
- */
- public function setAvailableOn(\DateTime $availableOn = null)
- {
- $this->availableOn = $availableOn;
-
- if ($this->isMaster() && null !== $this->object) {
- $this->getProduct()->setAvailableOn($availableOn);
- }
-
- return $this;
- }
-
- /**
- * {@inheritdoc}
- */
- public function setDefaults(BaseVariantInterface $masterVariant)
- {
- parent::setDefaults($masterVariant);
-
- if (!$masterVariant instanceof VariantInterface) {
- throw new \InvalidArgumentException('Product variants must implement "Sylius\Component\Product\Model\VariantInterface".');
- }
-
- $this->setAvailableOn($masterVariant->getAvailableOn());
-
- return $this;
- }
+ /**
+ * Available on.
+ *
+ * @var \DateTime
+ */
+ protected $availableOn;
+
+ /**
+ * Available until.
+ *
+ * @var DateTime
+ */
+ protected $availableUntil;
+
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ parent::__construct();
+
+ $this->availableOn = new \DateTime();
+ $this->availableUntil = null;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getProduct()
+ {
+ return parent::getObject();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setProduct(ProductInterface $product = null)
+ {
+ return parent::setObject($product);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isAvailable()
+ {
+ $now = new DateTime();
+ return
+ $now >= $this->availableOn
+ && (
+ $this->availableUntil === null ?
+ true :
+ ( $now < $this->availableUntil )
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getAvailableOn()
+ {
+ return $this->availableOn;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setAvailableOn(\DateTime $availableOn = null)
+ {
+ $this->availableOn = $availableOn;
+
+ if ($this->isMaster() && null !== $this->object) {
+ $this->getProduct()->setAvailableOn($availableOn);
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getAvailableUntil()
+ {
+ return $this->availableUntil;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setAvailableUntil(DateTime $availableUntil = null)
+ {
+ $this->availableUntil = $availableUntil;
+
+ if ($this->isMaster() && null !== $this->object) {
+ $this->getProduct()->setAvailableUntil($availableUntil);
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDefaults(BaseVariantInterface $masterVariant)
+ {
+ parent::setDefaults($masterVariant);
+
+ if (!$masterVariant instanceof VariantInterface) {
+ throw new \InvalidArgumentException('Product variants must implement "Sylius\Component\Product\Model\VariantInterface".');
+ }
+
+ $this->setAvailableOn($masterVariant->getAvailableOn());
+
+ return $this;
+ }
}
diff --git a/src/Sylius/Component/Product/Model/VariantInterface.php b/src/Sylius/Component/Product/Model/VariantInterface.php
index c973ac2f42c..41bb5887daa 100644
--- a/src/Sylius/Component/Product/Model/VariantInterface.php
+++ b/src/Sylius/Component/Product/Model/VariantInterface.php
@@ -52,4 +52,18 @@ public function getAvailableOn();
* @param null|\DateTime $availableOn
*/
public function setAvailableOn(\DateTime $availableOn = null);
+
+ /**
+ * Return available until.
+ *
+ * @return \DateTime
+ */
+ public function getAvailableUntil();
+
+ /**
+ * Set available until.
+ *
+ * @param null|\DateTime $availableUntil
+ */
+ public function setAvailableUntil(\DateTime $availableUntil = null);
}
|