<?php
namespace App\AtechNet\CoreBundle\Entity;
use App\AtechNet\CoreBundle\DTO\MovementItemWithPrice;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\ManyToOne;
use Doctrine\ORM\Mapping\OneToMany;
use Doctrine\ORM\Mapping\OneToOne;
use Doctrine\ORM\Mapping\OrderBy;
use Doctrine\ORM\Mapping\Table as Table;
use Generator;
use Symfony\Component\Validator\Constraints as Assert;
/**
* StockMovement
*
* @Table(name="stock_movements")
* @Entity(repositoryClass="App\AtechNet\CoreBundle\Repository\StockMovementRepository")
*/
class StockMovement extends AbstractSignedEntity
{
public const int TYPE_IN = 1;
public const int TYPE_OUT = 2;
public const int TYPE_NEUTRAL = 3;
//IN_SUB_TYPE ->
public const int SUB_TYPE_IN_SHIPMENT = 1;
public const int SUB_TYPE_IN_FROM_OTHER_STOCK = 2;
public const int SUB_TYPE_IN_EXCESS_AT_INVENTORY = 4;
public const int SUB_TYPE_IN_CONFIG_CHANGE = 20;
public const int SUB_TYPE_IN_USED_IN_COMPANY = 26;
public const int SUB_TYPE_IN_ORDER_CONFIG_CHANGE = 29;
public const int SUB_TYPE_IN_CREDIT_NOTE = 32;
public const int SUB_TYPE_IN_PRODUCTION = 34;
public const int SUB_TYPE_IN_BUYBACK = 36;
public const int SUB_TYPE_IN_RETURNED_FROM_SUPPLIER = 37;
public const int SUB_TYPE_IN_V2_MIGRATION = 39;
//OUT_SUB_TYPE ->
public const int SUB_TYPE_OUT_BASIC = 7;
public const int SUB_TYPE_OUT_TO_OTHER_STOCK = 8;
public const int SUB_TYPE_OUT_RETURNED_TO_SUPPLIER = 9;
public const int SUB_TYPE_OUT_SHORTAGE_AT_INVENTORY = 10;
public const int SUB_TYPE_OUT_CONSUMPTION = 11;
public const int SUB_TYPE_OUT_CONFIG_CHANGE = 21;
public const int SUB_TYPE_OUT_REMOVED_FROM_STOCK = 22;
public const int SUB_TYPE_OUT_CLAIM = 24;
public const int SUB_TYPE_OUT_USED_IN_COMPANY = 25;
public const int SUB_TYPE_OUT_PRODUCTION = 35;
public const int SUB_TYPE_OUT_CONSUMPTION_IN_PREPARATION = 27;
public const int SUB_TYPE_OUT_ORDER_CONFIG_CHANGE = 30;
public const int SUB_TYPE_OUT_V2_MIGRATION = 40;
public const int SUB_TYPE_OUT_LOSS_IN_TRANSIT = 41;
//NEUTRAL_SUB_TYPE ->
public const int SUB_TYPE_NEUTRAL_RESERVATION = 14;
public const int SUB_TYPE_NEUTRAL_COMMISSION = 15;
public const int SUB_TYPE_NEUTRAL_IN_STOCK = 17;
public const int SUB_TYPE_NEUTRAL_QUARANTINE = 19;
public const int SUB_TYPE_NEUTRAL_USED_WITHIN_COMPANY = 23;
public const int SUB_TYPE_NEUTRAL_IN_PRODUCTION = 31;
public const int SUB_TYPE_NEUTRAL_RE_AIKEN = 33;
public const int SUB_TYPE_NEUTRAL_DONOR = 38;
//LAST_SUB_TYPE_ID = 39
public const string PRODUCT_STATUS_CHANGE_TYPE_INCOMING_TO_IN_STOCK = 'incoming-to-in-stock';
public const string PRODUCT_STATUS_CHANGE_TYPE_IN_STOCK_TO_IN_PRODUCTION = 'in-stock-to-in-production';
/**
* @var Stock
*
* @Assert\NotNull
*
* @ManyToOne(targetEntity="Stock", inversedBy="movements")
* @JoinColumn(name="stock_id", referencedColumnName="id")
*/
private $stock;
/**
* @var Order
*
* @ManyToOne(targetEntity="Order", inversedBy="stockMovements")
* @JoinColumn(name="order_id", referencedColumnName="id", nullable=true)
*/
private $order;
/**
* @var Order
*
* @ManyToOne(targetEntity="Order", inversedBy="configChangeStockMovements")
* @JoinColumn(name="order_config_change_id", referencedColumnName="id", nullable=true)
*/
private $orderConfigChange;
/**
* @var Customer
*
* @Assert\NotNull
*
* @ManyToOne(targetEntity="Customer", inversedBy="movements")
* @JoinColumn(name="merchant_id", referencedColumnName="id")
*/
private $merchant;
/**
* @var StockReview
*
* @ManyToOne(targetEntity="StockReview", inversedBy="stockMovements")
* @JoinColumn(name="stock_review_id", referencedColumnName="id", nullable=true)
*/
private $stockReview;
/**
* @var ArrayCollection
*
* @OneToMany(targetEntity="StockMovementItem", mappedBy="movement", cascade={"persist"}, orphanRemoval=true)
* @OrderBy({"created" = "DESC"})
*/
private $movementItems;
/**
* @var int
*
* @Column(name="type", type="integer")
*/
private $type;
/**
* @var int
*
* @Column(name="sub_type", type="integer")
*/
private $subType;
/**
* @var int
*
* @Column(name="quantity", type="integer")
*/
private $quantity = 0;
/**
* @var string
*
* @Column(name="extra_price", type="decimal", precision=10, scale=2)
*/
private $extraPrice = 0;
/**
* @var string
*
* @Column(name="total_price", type="decimal", precision=10, scale=2)
*/
private $totalPrice = 0;
/**
* @var ArrayCollection
*
* @OneToMany(targetEntity="Document", mappedBy="stockMovement", orphanRemoval=true)
* @OrderBy({"created" = "DESC"})
*/
private $documents;
/**
* @var ArrayCollection
*
* @OneToMany(targetEntity="CustomerBillingoData", mappedBy="stockMovement", orphanRemoval=true)
* @OrderBy({"created" = "DESC"})
*/
private $billingoDocuments;
/**
* @var ArrayCollection
*
* @OneToMany(targetEntity="ProductCommission", mappedBy="stockMovement", orphanRemoval=true)
* @OrderBy({"created" = "DESC"})
*/
private $commissions;
/**
* @var float
*
* @Column(name="vat", type="decimal", precision=10, scale=2)
*/
private $vat = 0;
/**
* @var string
*
* @Column(name="note", type="text", nullable=true)
*/
private $note;
/**
* @var string
*
* @Column(name="shipment_code", type="string", length=255, nullable=true)
*/
private $shipmentCode;
/**
* @var float
*
* @Column(name="exchange_rate", type="float")
*/
private $exchangeRate = 1;
/**
* @var bool
*
* @Column(name="locked_for_non_admins", type="boolean")
*/
private $lockedForNonAdmins = false;
/**
* @var StockMovement
*
* @OneToOne(targetEntity="StockMovement")
* @JoinColumn(name="related_movement_id", referencedColumnName="id")
*/
private $relatedMovement;
/**
* @var ArrayCollection
*
* @OneToMany(targetEntity="StockMovementLog", mappedBy="stockMovement", orphanRemoval=true)
* @OrderBy({"created" = "ASC"})
*/
private $logs;
/**
* @var Shipment|null
*
* @ManyToOne(targetEntity="Shipment", inversedBy="stockMovements")
* @JoinColumn(name="shipment_id", referencedColumnName="id")
*/
private ?Shipment $shipment = null;
/**
* @var bool
*
* @Column(name="shipment_ready", type="boolean")
*/
private $shipmentReady = false;
public function __construct()
{
parent::__construct();
$this->movementItems = new ArrayCollection();
$this->logs = new ArrayCollection();
}
/**
* List of IN sub types on which stock items are added to stock
*
* @return array
*/
public static function getStockInSubTypes(): array
{
return [
'smSubTypeInBasic' => self::SUB_TYPE_IN_SHIPMENT,
'smSubTypeInConsumption' => self::SUB_TYPE_IN_FROM_OTHER_STOCK,
'smSubTypeInReturnedToSupplier' => self::SUB_TYPE_IN_EXCESS_AT_INVENTORY,
];
}
/**
* List of OUT sub types on which stock items are no longer in stock
*
* @return array
*/
public static function getStockOutSubTypes(): array
{
return [
'smSubTypeOutBasic' => self::SUB_TYPE_OUT_BASIC,
'smSubTypeOutConsumption' => self::SUB_TYPE_OUT_CONSUMPTION,
'smSubTypeOutRemovedFromStock' => self::SUB_TYPE_OUT_REMOVED_FROM_STOCK,
'smSubTypeOutReturnedToSupplier' => self::SUB_TYPE_OUT_RETURNED_TO_SUPPLIER,
'smSubTypeOutToOtherStock' => self::SUB_TYPE_OUT_TO_OTHER_STOCK,
];
}
/**
* @param $key
* @return string[]
*/
public static function getSubTypeChoicesForType($key): array
{
$subTypesChoicesWithHierarchy = self::getSubTypeChoicesWithHierarchy();
if (isset($subTypesChoicesWithHierarchy[$key])) {
$subTypesChoicesWithHierarchy[$key];
}
return self::getSubTypeChoicesWithHierarchy()[$key];
}
/**
* @param bool $withTypeTitles
* @return array
*/
public static function getSubTypeChoicesWithHierarchy($withTypeTitles = false): array
{
$subTypeArrayMainKeys = [];
$typeChoices = self::getTypeChoices();
foreach ($typeChoices as $key => $typeChoiceTitle) {
if ($withTypeTitles) {
$subTypeArrayMainKeys[$key] = $typeChoiceTitle;
} else {
$subTypeArrayMainKeys[$key] = $key;
}
}
return [
$subTypeArrayMainKeys[self::TYPE_IN] => [
self::SUB_TYPE_IN_SHIPMENT => 'Shipment',
self::SUB_TYPE_IN_CREDIT_NOTE => 'Credit note',
self::SUB_TYPE_IN_FROM_OTHER_STOCK => 'From other stock',
self::SUB_TYPE_IN_EXCESS_AT_INVENTORY => 'Excess at inventory',
self::SUB_TYPE_IN_CONFIG_CHANGE => 'Config change',
self::SUB_TYPE_IN_USED_IN_COMPANY => 'Used in company',
self::SUB_TYPE_IN_ORDER_CONFIG_CHANGE => 'Order config change',
self::SUB_TYPE_IN_PRODUCTION => 'Production',
self::SUB_TYPE_IN_BUYBACK => 'Buyback',
self::SUB_TYPE_IN_RETURNED_FROM_SUPPLIER => 'Returned from supplier',
self::SUB_TYPE_IN_V2_MIGRATION => 'V2 Migration'
],
$subTypeArrayMainKeys[self::TYPE_OUT] => [
self::SUB_TYPE_OUT_BASIC => 'Basic',
self::SUB_TYPE_OUT_TO_OTHER_STOCK => 'To other stock',
self::SUB_TYPE_OUT_RETURNED_TO_SUPPLIER => 'Returned to supplier',
self::SUB_TYPE_OUT_SHORTAGE_AT_INVENTORY => 'Shortage at inventory',
self::SUB_TYPE_OUT_CONSUMPTION => 'Consumption',
self::SUB_TYPE_OUT_CONFIG_CHANGE => 'Config change',
self::SUB_TYPE_OUT_REMOVED_FROM_STOCK => 'Removed from stock',
self::SUB_TYPE_OUT_CLAIM => 'Claim',
self::SUB_TYPE_OUT_USED_IN_COMPANY => 'Used in company',
self::SUB_TYPE_OUT_CONSUMPTION_IN_PREPARATION => 'Consumption in preparation',
self::SUB_TYPE_OUT_ORDER_CONFIG_CHANGE => 'Order config change',
self::SUB_TYPE_OUT_PRODUCTION => 'Production',
self::SUB_TYPE_OUT_V2_MIGRATION => 'V2 Migration',
self::SUB_TYPE_OUT_LOSS_IN_TRANSIT => 'Loss in transit',
],
$subTypeArrayMainKeys[self::TYPE_NEUTRAL] => [
self::SUB_TYPE_NEUTRAL_RESERVATION => 'Reservation',
self::SUB_TYPE_NEUTRAL_COMMISSION => 'Commission',
self::SUB_TYPE_NEUTRAL_QUARANTINE => 'Quarantine',
self::SUB_TYPE_NEUTRAL_USED_WITHIN_COMPANY => 'Used in company',
self::SUB_TYPE_NEUTRAL_IN_PRODUCTION => 'In Production',
self::SUB_TYPE_NEUTRAL_RE_AIKEN => 'ReAiken',
self::SUB_TYPE_NEUTRAL_DONOR => 'Donor',
],
];
}
/**
* @return array
*/
public static function getTypeChoices(): array
{
return [
self::TYPE_IN => 'In',
self::TYPE_OUT => 'Out',
self::TYPE_NEUTRAL => 'Neutral',
];
}
/**
* @param int $subTypeId
* @return bool|int
*/
public static function getTypeOfSubType($subTypeId)
{
if (is_numeric($subTypeId)) {
foreach (self::getSubTypeChoicesWithHierarchy() as $typeKey => $typeArray) {
if (array_key_exists($subTypeId, $typeArray)) {
return $typeKey;
}
}
}
return false;
}
/**
* @return int[]
*/
public static function getProductStatusChangePairs(): array
{
return [
self::PRODUCT_STATUS_CHANGE_TYPE_INCOMING_TO_IN_STOCK => [
15250 => 22258, // PC
15251 => 22256, // Monitor
15252 => 22257, // Notebook
15253 => 22259, // PC accessory
22181 => 22260, // Smartphone
],
self::PRODUCT_STATUS_CHANGE_TYPE_IN_STOCK_TO_IN_PRODUCTION => [
22258 => 22265, // PC
22256 => 22263, // Monitor
22257 => 22264, // Notebook
22259 => 22266, // PC accessory
22260 => 22262, // Smartphone
],
];
}
/**
* List of product IDs in product production phase
*
* @return int[]
*/
public static function getProductStatusChangeIDs(): array
{
return [
15250,
15251,
15252,
15253,
22181,
22258,
22256,
22257,
22259,
22260,
22262,
22263,
22264,
22265,
22266,
22180,
3099,
3098,
3097,
3100,
];
}
/**
* @return StockReview|null
*/
public function getStockReview(): ?StockReview
{
return $this->stockReview;
}
/**
* @param StockReview $stockReview
*/
public function setStockReview(StockReview $stockReview): void
{
$this->stockReview = $stockReview;
}
/**
* Add StockMovementItem
*
* @param StockMovementItem $movementItem
*/
public function addMovementItem($movementItem)
{
if (!$this->movementItems->contains($movementItem)) {
$this->movementItems->add($movementItem);
}
}
/**
* Remove StockMovementItem
*
* @param StockMovementItem $movementItem
*/
public function removeMovementItem($movementItem)
{
$this->movementItems->removeElement($movementItem);
}
/**
* @return Generator<MovementItemWithPrice>
*/
public function getMovementItemsWithPrice(): Generator
{
foreach ($this->getMovementItems() as $stockMovementItem) {
yield MovementItemWithPrice::fromEntity($stockMovementItem, $this->getExchangeRate(), $this->getVat());
}
}
/**
* @return ArrayCollection
*/
public function getMovementItems()
{
return $this->movementItems;
}
/**
* @param ArrayCollection $movementItems
*/
public function setMovementItems($movementItems)
{
$this->movementItems = $movementItems;
}
/**
* @return float
*/
public function getExchangeRate()
{
return $this->exchangeRate;
}
/**
* @param float $exchangeRate
*/
public function setExchangeRate($exchangeRate)
{
$this->exchangeRate = $exchangeRate;
}
/**
* @return float
*/
public function getVat()
{
return $this->vat;
}
/**
* @param float $vat
*/
public function setVat($vat)
{
$this->vat = $vat;
}
/**
* @param array<StockMovement> $movements
*/
public function getMovementItemsWithPurchasePrice(array $movements): array
{
$result = [];
/** @var StockMovementItem $stockMovementItemOUT */
foreach ($this->getMovementItems() as $stockMovementItemOUT) {
$productOUT = $stockMovementItemOUT->getProduct();
// try to find prices in previous stock movements.
foreach ($movements as $previousStockMovement) {
/** @var StockMovementItem $stockMovementItemIN */
foreach ($previousStockMovement->getMovementItems() as $stockMovementItemIN) {
if ($stockMovementItemIN->getProduct()->getId() != $productOUT->getId()) {
// another product
continue;
}
if (array_key_exists($productOUT->getId(), $result)) {
// we found prices already
continue;
}
// collect prices from found stockItems
$purchasePrices = array_map(
fn(StockItem $stockItemIN) => $stockItemIN->getPurchasePrice(),
$stockMovementItemIN->getItems()->toArray()
);
if ($purchasePrices === []) {
continue;
}
$purchasePrice = array_sum($purchasePrices) / count($purchasePrices);
$purchasePrice = round($purchasePrice, 2);
$result[$productOUT->getId()] = [
'stockMovementItem' => $stockMovementItemOUT,
'product' => $productOUT,
'avgPrice' => $purchasePrice,
'from' => 'previous StockItem',
'items' => $stockMovementItemIN->getItems()->toArray(),
];
}
}
if (!array_key_exists($productOUT->getId(), $result)) {
// price not found in prev. stockMovements
$avgPrice = $productOUT->getAvgPrice();
$result[$productOUT->getId()] = [
'stockMovementItem' => $stockMovementItemOUT,
'product' => $productOUT,
'avgPrice' => $avgPrice,
'from' => 'product avgPrice',
];
}
}
return array_map(
fn(array $row) => MovementItemWithPrice::fromPreviousStockMovementItem(
$row['stockMovementItem'],
$row['avgPrice'],
$this->getVat()
),
$result
);
}
/**
* @return string
*/
public function getExtraVatPrice()
{
return $this->getCompany()->createVatPrice($this->extraPrice, $this->getVat());
}
/**
* @return Company
*/
public function getCompany()
{
return $this->getStock()->getCompany();
}
/**
* @return Stock
*/
public function getStock()
{
return $this->stock;
}
/**
* @param Stock $stock
*/
public function setStock($stock)
{
$this->stock = $stock;
}
/**
* @return float
*/
public function getRoundedExtraVatPrice(): float
{
return $this->getRoundedTotalVatPrice() - $this->getRoundedSubTotalVatPrice();
}
/**
* @return float
*/
public function getRoundedTotalVatPrice(): float
{
if ($this->getQuantity() == 0) {
return 0;
}
return $this->getQuantity() * $this->getCompany()->createVatPrice(
$this->getRoundedTotalPrice() / $this->getQuantity(),
$this->getVat()
);
}
/**
* @return int
*/
public function getQuantity()
{
return $this->quantity;
}
/**
* @param int $quantity
*/
public function setQuantity($quantity)
{
$this->quantity = $quantity;
}
/**
* @return float
*/
public function getRoundedTotalPrice(): float
{
return (float)$this->getRoundedSubTotalPrice() + (float)$this->getExtraPrice();
}
/**
* @return float
*/
public function getRoundedSubTotalPrice(): float
{
if ($this->getQuantity() == 0) {
return 0;
}
return round(($this->getTotalPrice() - $this->getExtraPrice()) / $this->getQuantity(), 2) * $this->getQuantity();
}
/**
* @return string
*/
public function getTotalPrice()
{
return $this->totalPrice;
}
/**
* @param string $totalPrice
*/
public function setTotalPrice($totalPrice)
{
$this->totalPrice = $totalPrice;
}
/**
* @return string
*/
public function getExtraPrice()
{
return $this->extraPrice;
}
/**
* @param string $extraPrice
*/
public function setExtraPrice($extraPrice)
{
$this->extraPrice = $extraPrice;
}
/**
* @return float
*/
public function getRoundedSubTotalVatPrice(): float
{
return $this->getCompany()->createVatPrice($this->getRoundedSubTotalPrice(), $this->getVat());
}
/**
* @return string
*/
public function getTotalVatPrice()
{
return $this->getCompany()->createVatPrice($this->totalPrice, $this->getVat());
}
/**
* @return string
*/
public function getSubTotalVatPrice()
{
return $this->getCompany()->createVatPrice($this->getSubTotalPrice(), $this->getVat());
}
/**
* @return string
*/
public function getSubTotalPrice()
{
return $this->getTotalPrice() - $this->getExtraPrice();
}
/**
* @return int
*/
public function getNote()
{
return $this->note;
}
/**
* @param string $note
*/
public function setNote($note)
{
$this->note = $note;
}
/**
* @return mixed
*/
public function getCurrency()
{
return $this->getMerchant()->getDomain()->getCurrency();
}
/**
* @return Customer
*/
public function getMerchant()
{
return $this->merchant;
}
/**
* @param Customer $merchant
*/
public function setMerchant(Customer $merchant)
{
$this->merchant = $merchant;
}
/**
* @return ArrayCollection
*/
public function getBillingoDocuments()
{
return $this->billingoDocuments;
}
/**
* @param ArrayCollection $billingoDocuments
*/
public function setBillingoDocuments($billingoDocuments)
{
$this->billingoDocuments = $billingoDocuments;
}
/**
* @return ArrayCollection
*/
public function getCommissions()
{
return $this->commissions;
}
/**
* @return StockMovement
*/
public function getRelatedMovement()
{
return $this->relatedMovement;
}
/**
* @param StockMovement $relatedMovement
*/
public function setRelatedMovement($relatedMovement)
{
$this->relatedMovement = $relatedMovement;
}
/**
* @return ArrayCollection
*/
public function getProducts()
{
$products = new ArrayCollection();
foreach ($this->getMovementItems() as $mi) {
$prod = $mi->getProduct();
if (!$products->contains($prod)) {
$products->add($prod);
}
}
return $products;
}
public function getMovementItemsQuantityCount()
{
$total = 0;
foreach ($this->getMovementItems() as $mi) {
$total += $mi->getQuantity();
}
return $total;
}
/**
* 1 = less, 2 = OK, 3 = more
*
* @return int|null
*/
public function isAllStockItemsAdded(): ?int
{
$neededStockItems = $this->getNeededStockItemsCount();
$addedStockItemsCount = $this->getStockItems()->count();
$result = $neededStockItems - $addedStockItemsCount;
if ($result > 0) { // less items than needed
return 1;
} elseif ($result == 0) { // quantity ok
return 2;
} elseif ($result < 0) { // more items than needed
return 3;
}
return null;
}
/**
* @return int
*/
public function getNeededStockItemsCount(): int
{
$quantity = 0;
foreach ($this->getMovementItems() as $mi) {
if ($mi->getProduct()?->isScannable() && $mi->getProduct()->getType()->isScannable()) {
$quantity += $mi->getQuantity();
}
}
return $quantity;
}
/**
* @return int
*/
public function getType()
{
return $this->type;
}
/**
* @param int $type
*/
public function setType($type)
{
$this->type = $type;
}
/**
* @return ArrayCollection
*/
public function getStockItems()
{
$stockItems = new ArrayCollection();
foreach ($this->getMovementItems() as $mi) {
foreach ($mi->getItems() as $si) {
if (!$stockItems->contains($si)) {
$stockItems->add($si);
}
}
}
return $stockItems;
}
/**
* @return mixed
*/
public function getTypeTitle()
{
return self::getTypeChoices()[$this->getType()];
}
/**
* @return mixed
*/
public function getSubTypeTitle()
{
return self::getSubTypeChoices()[$this->getSubType()];
}
/**
* @return array
*/
public static function getSubTypeChoices(): array
{
$subTypes = [];
foreach (self::getSubTypeChoicesWithHierarchy() as $subTypeGroupWithHierarchy) {
foreach ($subTypeGroupWithHierarchy as $key => $subType) {
$subTypes[$key] = $subType;
}
}
return $subTypes;
}
/**
* @return int
*/
public function getSubType()
{
return $this->subType;
}
/**
* @param int $subType
*/
public function setSubType($subType)
{
$this->subType = $subType;
}
/**
* @return bool
*/
public function isLockedForNonAdmins()
{
return $this->lockedForNonAdmins;
}
/**
* @param bool $lockedForNonAdmins
*/
public function setLockedForNonAdmins($lockedForNonAdmins)
{
$this->lockedForNonAdmins = $lockedForNonAdmins;
}
/**
* @return bool
* @throws \Exception
*/
public function isLocked()
{
return ($this->getDocuments()->count() > 0
&& !is_null($this->getDocuments()->first())
&& $this->getDocuments()->first()->isLocked())
|| (
in_array($this->getType(), [self::TYPE_IN, self::TYPE_OUT])
&& $this->getCreated() < (new \DateTime())->setTime(0, 0)
&& $this->getShipmentCode() != '3961'
&& !in_array($this->getId(), [498458,498459])
&& $this->getSubType() != self::SUB_TYPE_IN_SHIPMENT
);
}
/**
* @return ArrayCollection
*/
public function getDocuments()
{
return $this->documents;
}
/**
* @return Order
*/
public function getOrder()
{
return $this->order;
}
/**
* @param Order $order
*/
public function setOrder($order)
{
$this->order = $order;
}
/**
* @return string
*/
public function getExtraVatPricePerItem()
{
return $this->getCompany()->createVatPrice($this->getExtraPricePerItem(), $this->getVat());
}
/**
* @return int
*/
public function getExtraPricePerItem()
{
if ($this->getExtraPrice() != 0 && $this->getQuantity() > 0) {
return number_format($this->getExtraPrice() / $this->getQuantity(), 2, '.', '');
}
return 0;
}
/**
* @return string|null
*/
public function getShipmentCode()
{
return $this->shipmentCode;
}
/**
* @param string|null $shipmentCode
* @return void
*/
public function setShipmentCode(?string $shipmentCode)
{
$this->shipmentCode = $shipmentCode;
}
/**
* @return ArrayCollection
*/
public function getLogs()
{
return $this->logs;
}
/**
* @param ArrayCollection $logs
*/
public function setLogs($logs)
{
$this->logs = $logs;
}
/**
* @param StockMovementLog $log
*/
public function addLog($log)
{
if (!$this->logs->contains($log)) {
$this->logs->add($log);
}
}
/**
* @return Order|null
*/
public function getOrderConfigChange(): ?Order
{
return $this->orderConfigChange;
}
/**
* @param Order|null $orderConfigChange
* @return void
*/
public function setOrderConfigChange(?Order $orderConfigChange): void
{
$this->orderConfigChange = $orderConfigChange;
}
/**
* @return Shipment|null
*/
public function getShipment(): ?Shipment
{
return $this->shipment;
}
/**
* @param Shipment|null $shipment
* @return void
*/
public function setShipment(?Shipment $shipment): void
{
$this->shipment = $shipment;
}
/**
* @return bool
*/
public function isShipmentReady(): bool
{
return $this->shipmentReady;
}
/**
* @param bool $shipmentReady
* @return void
*/
public function setShipmentReady(bool $shipmentReady): void
{
$this->shipmentReady = $shipmentReady;
}
}