<?php
namespace Roothirsch\ShopBundle\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Roothirsch\CoreBundle\Behaviors\Attributable\AttributeValue\AttributeValueAwareInterface;
use Roothirsch\CoreBundle\Behaviors\Attributable\AttributeValue\AttributeValueAwareTrait;
use Roothirsch\CoreBundle\Behaviors\Attributable\AttributeValue\AttributeValueInterface;
use Roothirsch\CoreBundle\Behaviors\Attributable\Attribute\AttributeInterface;
use Roothirsch\CoreBundle\Behaviors\Attributable\MappedSuperclass\AbstractAttributable;
use Roothirsch\CoreBundle\Entity\Traits\TimetrackedTrait;
use Roothirsch\CoreBundle\UserAware\UserAwareInterface;
use Roothirsch\CoreBundle\UserAware\UserAwareTrait;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Roothirsch\ShopBundle\Entity\Estimate\EstimateAttributeValue;
use Roothirsch\ShopBundle\Entity\Estimate\EstimateAttribute;
/**
* @ORM\Entity(repositoryClass="Roothirsch\ShopBundle\Repository\EstimateRepository")
* @ORM\Table(name="shop_estimate")
* @ApiResource(
* shortName="Shop/Estimate",
* itemOperations={
* "order"={"method"="PUT", "path"="/estimates/{id}/order", "requirements"={"id"=".+"}},
* "get",
* "put",
* "delete"
* },
* collectionOperations={
* "duplicate"={"method"="POST", "path"="/estimates/{id}/duplicate", "requirements"={"id"=".+"}},
* "get",
* "post"
* }
* )
*/
class Estimate extends AbstractAttributable implements UserAwareInterface
{
use UserAwareTrait;
use TimetrackedTrait;
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity=EstimatePosition::class, mappedBy="estimate", orphanRemoval=true, cascade={"persist"})
*/
private $positions;
/**
* @ORM\Column(type="boolean")
*/
private $applyDiscount = true;
/**
* @ORM\Column(type="boolean")
*/
private $applyMwst = false;
/**
* @ORM\Column(type="string", nullable=true)
*/
private $comment;
/**
* @ORM\Column(type="float", nullable=true)
*/
private $totalPrice;
/**
* @ORM\OneToMany(targetEntity=EstimateAttributeValue::class, mappedBy="estimate", orphanRemoval=true, cascade={"persist"})
*/
private $attributeValues;
public function __construct()
{
$this->positions = new ArrayCollection();
$this->attributeValues = new ArrayCollection();
}
public function __clone() {
$this->id = null;
$this->setCreatedAt(new \DateTime());
$this->setUpdatedAt(new \DateTime());
$oldPositions = $this->positions;
$this->positions = new ArrayCollection();
foreach($oldPositions as $oldPosition) {
$this->addPosition(clone $oldPosition);
}
$oldAttributeValues = $this->attributeValues;
$this->attributeValues = new ArrayCollection();
foreach($oldAttributeValues as $oldAttributeValue) {
$this->addAttributeValue(clone $oldAttributeValue);
}
}
public function getAttributes()
{
return $this->attributes;
}
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @param mixed $id
*/
public function setId($id)
{
$this->id = $id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(?string $name): self
{
$this->name = $name;
return $this;
}
/**
* @return Collection|EstimatePosition[]
*/
public function getPositions(): Collection
{
return $this->positions;
}
public function addPosition(EstimatePosition $position): self
{
if (!$this->positions->contains($position)) {
$this->positions[] = $position;
$position->setEstimate($this);
}
return $this;
}
public function removePosition(EstimatePosition $position): self
{
if ($this->positions->removeElement($position)) {
// set the owning side to null (unless already changed)
if ($position->getEstimate() === $this) {
$position->setEstimate(null);
}
}
return $this;
}
/**
* @return bool
*/
public function isApplyDiscount(): bool
{
return $this->applyDiscount;
}
/**
* @param bool $applyDiscount
*/
public function setApplyDiscount(bool $applyDiscount): void
{
$this->applyDiscount = $applyDiscount;
}
/**
* @return bool
*/
public function isApplyMwst(): bool
{
return $this->applyMwst;
}
/**
* @param bool $applyMwst
*/
public function setApplyMwst(bool $applyMwst): void
{
$this->applyMwst = $applyMwst;
}
/**
* @return mixed
*/
public function getComment()
{
return $this->comment;
}
/**
* @param mixed $comment
*/
public function setComment($comment): void
{
$this->comment = $comment;
}
public function getTotal()
{
$total = 0;
/** @var EstimatePosition $position */
foreach ($this->positions as $position) {
if ($position->getState() == 'draft') {
continue;
}
if ($position->getOptional()) {
continue;
}
$total += $position->getTotalWithTax();
}
return $total;
}
public function getTax()
{
if(!$this->isApplyMwst()){
return 1;
}
/** @var EstimateAttribute $tax */
$taxAttribute = $this->getAttribute('tax');
if(!$taxAttribute){
return 1;
}
/** @var EstimateAttributeValue $value */
$value = $this->getAttributeValue($taxAttribute);
$tax = $value->getValue();
if(!is_float($tax)){
$tax = floatval($tax);
}
return (100 + $tax) / 100;
}
public function getTotalPriceBrutto()
{
return $total / 100 * (100 + $tax);
}
public function getArticleCount()
{
$total = 0;
/** @var OrderPosition $position */
foreach ($this->positions as $position) {
if ($position->getState() == 'added') {
$total += count($position->getArticles());
}
}
return $total;
}
/**
* Get the value of totalPrice
*/
public function getTotalPrice()
{
return $this->totalPrice;
}
/**
* Set the value of totalPrice
*
* @return self
*/
public function setTotalPrice($totalPrice)
{
$this->totalPrice = $totalPrice;
return $this;
}
public function newValue(AttributeInterface $attribute): AttributeValueInterface
{
return new EstimateAttributeValue($attribute);
}
public function setAttributeValues(Collection $attributeValues): AttributeValueAwareInterface
{
$this->attributeValues = $attributeValues;
return $this;
}
/**
* @return Collection|EstimateAttributeValue []
*/
public function getAttributeValues(): Collection
{
return $this->attributeValues;
}
public function getHighlightedDiscounts() {
$discounts = [];
/** @var EstimatePosition $position */
foreach($this->positions as $position) {
if ($position->getOptional()) {
continue;
}
foreach($position->getDiscounts() as $discount) {
if (isset($discount['highlight']) && $discount['highlight'] == true) {
if (!isset($discounts[$discount['description']])) {
$discounts[$discount['description']] = $discount;
} else {
$discounts[$discount['description']]['total'] += $discount['total'];
}
}
}
}
return $discounts;
}
public function hasOptionalPositions() {
foreach($this->positions as $position) {
if ($position->getOptional()) {
return true;
}
}
return false;
}
}