src/AtechNet/CoreBundle/Entity/StockItem.php line 29

Open in your IDE?
  1. <?php
  2. namespace App\AtechNet\CoreBundle\Entity;
  3. use App\AtechNet\CoreBundle\Repository\StockItemRepository;
  4. use Doctrine\Common\Collections\ArrayCollection;
  5. use Doctrine\ORM\Mapping\Column;
  6. use Doctrine\ORM\Mapping\Entity;
  7. use Doctrine\ORM\Mapping\Index;
  8. use Doctrine\ORM\Mapping\JoinColumn;
  9. use Doctrine\ORM\Mapping\ManyToMany;
  10. use Doctrine\ORM\Mapping\ManyToOne;
  11. use Doctrine\ORM\Mapping\OneToMany;
  12. use Doctrine\ORM\Mapping\OneToOne;
  13. use Doctrine\ORM\Mapping\OrderBy;
  14. use Doctrine\ORM\Mapping\Table as Table;
  15. use Symfony\Component\Validator\Constraints as Assert;
  16. /**
  17.  * Stock
  18.  *
  19.  * @Table(name="stock_items", indexes={
  20.  *     @Index(name="search_serial_number", columns={"serial_number"}),
  21.  *     @Index(name="search_aiken_code", columns={"aiken_code"}), 
  22.  *     @Index(name="idx_in_stock", columns={"in_stock"})
  23.  * })
  24.  * @Entity(repositoryClass="App\AtechNet\CoreBundle\Repository\StockItemRepository")
  25.  */
  26. class StockItem extends AbstractSignedEntity
  27. {
  28.     public const int QUALITY_GOLD = 1;
  29.     public const int QUALITY_SILVER = 2;
  30.     public const int QUALITY_BRONZE = 3;
  31.     public const int QUALITY_PLATINUM = 5;
  32.     public const int QUALITY_NEW = 6;
  33.     public const int QUALITY_BAZAAR = 7;
  34.     public const string PREFIX_FOR_SELECTED_ITEMS = 'aiken codes selected by customer: ';
  35.     public const string SERIAL_PREFIX_AT = 'AT';
  36.     public const string SERIAL_PREFIX = 'FRB';
  37.     public const int SERIAL_SUFFIX_SIZE = 4;
  38.     public const string TEMPORARY_SERIAL_PREFIX = 'TMPR';
  39.     public const int TEMPORARY_SERIAL_SUFFIX_SIZE = 5;
  40.     public const BATTERY_STATE_NEW = 1;
  41.     public const BATTERY_STATE_USED = 10;
  42.     public const BATTERY_STATE_NO_INFO = 999;
  43.     public const array KEYBOARD_LANGUAGE_VALID_VALUE_LIST = [
  44.         'BE' =>    'BEL',
  45.         'CZ' =>    'CZE',
  46.         'DE' =>    'DEU',
  47.         'DK' =>    'DNK',
  48.         'DN' =>    'DNK',
  49.         'EN' =>    'GBR',
  50.         'ES' =>    'ESP',
  51.         'FI' =>    'FIN',
  52.         'FR' =>    'FRA',
  53.         'IE' =>    'GBR',
  54.         'IT' =>    'ITA',
  55.         'NL' =>    'NDL',
  56.         'PL' =>    'POL',
  57.         'PO' =>    'POL',
  58.         'PT' =>    'PRT',
  59.         'RU' =>    'RUS',
  60.         'SE' =>    'SWE',
  61.         'SK' =>    'SVK',
  62.         'SWE' => 'SWE',
  63.         'UK' =>    'GBR',
  64.         'US' =>    'USA',
  65.         'SW' => 'SWF'
  66.     ];
  67.     /**
  68.      * @var ArrayCollection
  69.      *
  70.      * @ManyToMany(targetEntity="StockMovementItem", mappedBy="items")
  71.      * @OrderBy({"created" = "DESC"})
  72.      */
  73.     private $movementItems;
  74.     /**
  75.      * @var AikenShipmentItem
  76.      *
  77.      * @OneToOne(targetEntity="AikenShipmentItem")
  78.      * @JoinColumn(name="aiken_shipment_item_id", referencedColumnName="id", nullable=true)
  79.      */
  80.     private $aikenShipmentItem;
  81.     /**
  82.      * @var string
  83.      *
  84.      * @Column(name="serial_number", type="string", length=64, nullable=true)
  85.      */
  86.     private $serialNumber;
  87.     /**
  88.      * @var string
  89.      *
  90.      * @Column(name="purchase_price", type="decimal", precision=10, scale=2)
  91.      */
  92.     private $purchasePrice = 0;
  93.     /**
  94.      * @var string
  95.      *
  96.      * @Column(name="selling_price", type="decimal", precision=10, scale=2)
  97.      */
  98.     private $sellingPrice = 0;
  99.     /**
  100.      * @var int
  101.      *
  102.      * @Column(name="quality", type="integer")
  103.      */
  104.     private $quality = 0;
  105.     /**
  106.      * @var int|null
  107.      *
  108.      * @Column(name="quality_points", type="integer", nullable=true)
  109.      */
  110.     private ?int $qualityPoints = null;
  111.     /**
  112.      * @var string
  113.      *
  114.      * @Column(name="aiken_code", type="string", length=32, nullable=true )
  115.      */
  116.     private $aikenCode;
  117.     /**
  118.      * @var string
  119.      *
  120.      * @Column(name="note", type="text", nullable=true)
  121.      */
  122.     private $note;
  123.     /**
  124.      * @var bool
  125.      *
  126.      * @Column(name="in_stock", type="boolean")
  127.      */
  128.     private $inStock = true;
  129.     /**
  130.      * @var bool
  131.      *
  132.      * @Column(name="available", type="boolean")
  133.      */
  134.     private bool $available = true;
  135.     /**
  136.      * @var ?bool
  137.      *
  138.      * @Column(name="long_i_key", type="boolean", nullable=true)
  139.      */
  140.     private ?bool $longIKey;
  141.     /**
  142.      * @var ?bool
  143.      *
  144.      * @Column(name="keyboard_backlight", type="boolean", nullable=true)
  145.      */
  146.     private ?bool $keyboardBacklight;
  147.     /**
  148.      * @var string
  149.      *
  150.      * @Column(name="battery_duration", type="string", length=32, nullable=true )
  151.      */
  152.     private $batteryDuration;
  153.     /**
  154.      * @var string
  155.      *
  156.      * @Column(name="battery_percentage_1", type="string", length=32, nullable=true)
  157.      */
  158.     private $batteryPercentage1;
  159.     /**
  160.      * @var string
  161.      *
  162.      * @Column(name="battery_percentage_2", type="string", length=32, nullable=true)
  163.      */
  164.     private $batteryPercentage2;
  165.     /**
  166.      * @var int
  167.      *
  168.      * @Column(name="battery_cycle_count_1", type="integer", nullable=true)
  169.      */
  170.     private $batteryCycleCount1;
  171.     /**
  172.      * @var int
  173.      *
  174.      * @Column(name="battery_cycle_count_2", type="integer", nullable=true)
  175.      */
  176.     private $batteryCycleCount2;
  177.     /**
  178.      * @var string
  179.      *
  180.      * @Column(name="keyboard_language", type="string", length=12, nullable=true )
  181.      */
  182.     private $keyboardLanguage;
  183.     /**
  184.      * @var bool
  185.      *
  186.      * @Column(name="pen_for_touch", type="boolean", nullable=true)
  187.      */
  188.     private $pen_for_touchscreen;
  189.     /**
  190.      * @var bool
  191.      *
  192.      * @Column(name="trackpoint", type="boolean", nullable=true)
  193.      */
  194.     private $trackpoint;
  195.     /**
  196.      * @var bool
  197.      *
  198.      * @Column(name="fingerprint_reader", type="boolean", nullable=false, options={"default": false})
  199.      */
  200.     private bool $fingerprintReader = false;
  201.     /**
  202.      * @var string
  203.      *
  204.      * @Column(name="error_codes", type="string", length=256, nullable=true)
  205.      */
  206.     private $errorCodes;
  207.     /**
  208.      * @var User
  209.      *
  210.      * @Assert\NotNull
  211.      *
  212.      * @ManyToOne(targetEntity="User", inversedBy="testedItems")
  213.      * @JoinColumn(name="tester_id", referencedColumnName="id", nullable=true)
  214.      */
  215.     private $tester;
  216.     /**
  217.      * @var int
  218.      *
  219.      * @Column(name="sort_index", type="integer")
  220.      */
  221.     private $sortIndex = 0;
  222.     /**
  223.      * @var Album
  224.      *
  225.      * @OneToOne(targetEntity="Album", cascade={"persist", "remove"})
  226.      * @JoinColumn(name="photo_album_id", referencedColumnName="id")
  227.      */
  228.     private $album;
  229.     /**
  230.      * @var ArrayCollection
  231.      *
  232.      * @OneToMany(targetEntity="StockItemInStockDay", mappedBy="stockItem", orphanRemoval=true)
  233.      * @OrderBy({"created" = "DESC"})
  234.      */
  235.     private $inStockDays;
  236.     /**
  237.      * @var ArrayCollection
  238.      *
  239.      * @OneToMany(targetEntity="StockItemPosition", mappedBy="stockItem", orphanRemoval=true)
  240.      * @OrderBy({"created" = "DESC"})
  241.      */
  242.     private $positions;
  243.     /**
  244.      * @var StockPosition
  245.      *
  246.      * @ManyToOne(targetEntity="StockPosition")
  247.      * @JoinColumn(name="last_stock_position_id", referencedColumnName="id", nullable=true)
  248.      */
  249.     private $lastKnownStockPosition;
  250.     public function __construct()
  251.     {
  252.         parent::__construct();
  253.         $this->movementItems = new ArrayCollection();
  254.     }
  255.     /**
  256.      * @return array
  257.      */
  258.     public static function getQualityTitleChoices(): array
  259.     {
  260.         return [
  261.             self::QUALITY_NEW => 'New',
  262.             self::QUALITY_PLATINUM => 'Platinum',
  263.             self::QUALITY_GOLD => 'Gold',
  264.             self::QUALITY_SILVER => 'Silver',
  265.             self::QUALITY_BRONZE => 'Bronze',
  266.             self::QUALITY_BAZAAR => 'Bazaar'
  267.         ];
  268.     }
  269.     public static function getQualityValue(): array
  270.     {
  271.         return [
  272.             'new'       => 6, 
  273.             'platinum'  => 5, 
  274.             'gold'      => 4, 
  275.             'silver'    => 3, 
  276.             'bronze'    => 2, 
  277.             'bazaar'    => 1
  278.         ];
  279.     }
  280.     /**
  281.      * @param $i
  282.      * @return string
  283.      */
  284.     public static function getSerialSuffix($i): string
  285.     {
  286.         return str_pad($i, StockItem::SERIAL_SUFFIX_SIZE, '0', STR_PAD_LEFT);
  287.     }
  288.     /**
  289.      * @param $i
  290.      * @return string
  291.      */
  292.     public static function getTemporarySerialSuffix($i): string
  293.     {
  294.         return str_pad($i, StockItem::TEMPORARY_SERIAL_SUFFIX_SIZE, '0', STR_PAD_LEFT);
  295.     }
  296.     public function getPurchasePriceCalculated()
  297.     {
  298.         return StockItemRepository::getPurchasePrices(null, $this, false);
  299.     }
  300.     /**
  301.      * @return Product
  302.      */
  303.     public function getProduct()
  304.     {
  305.         return $this->getLastMovementItem() == null ? null : $this->getLastMovementItem()->getProduct();
  306.     }
  307.     /**
  308.      * @return Product|null
  309.      */
  310.     public function getPreviousProduct(): ?Product
  311.     {
  312.         $movementItems = $this->getMovementItems();
  313.         if ( $movementItems->count() > 0 ) {
  314.             return $movementItems->get(1)?->getProduct();
  315.         }
  316.         return null;
  317.     }
  318.     /**
  319.      * @return StockMovementItem|null
  320.      */
  321.     public function getLastMovementItem()
  322.     {
  323.         $movementItems = $this->getMovementItems();
  324.         return $movementItems->count() > 0 ? $movementItems->first() : null;
  325.     }
  326.     public function getLastMovementItemForGetStockItemsFunction()
  327.     {
  328.         $movementItems = $this->getMovementItems();
  329.         return $movementItems->count() > 0 ? $movementItems->last() : null;
  330.     }
  331.     /**
  332.      * @return ArrayCollection
  333.      */
  334.     public function getMovementItems()
  335.     {
  336.         return $this->movementItems;
  337.     }
  338.     /**
  339.      * @return StockMovementItem|null
  340.      */
  341.     public function getFirstMovementItem()
  342.     {
  343.         $movementItems = $this->getMovementItems();
  344.         return $movementItems->count() > 0 ? $movementItems->last() : null;
  345.     }
  346.     public function getFirstMovementItemForGetStockItemsFunction()
  347.     {
  348.         $movementItems = $this->getMovementItems();
  349.         return $movementItems->count() > 0 ? $movementItems->first() : null;
  350.     }
  351.     /**
  352.      * @return StockMovement|null
  353.      */
  354.     public function getFirstMovement()
  355.     {
  356.         $movements = $this->getMovements();
  357.         if ($movements->count() > 0) {
  358.             return $movements->last();
  359.         }
  360.         return null;
  361.     }
  362.     /**
  363.      * @return ArrayCollection
  364.      */
  365.     public function getMovements()
  366.     {
  367.         $movements = new ArrayCollection();
  368.         foreach ($this->getMovementItems() as $movementItem) {
  369.             $movement = $movementItem->getMovement();
  370.             if (!$movements->contains($movement)) {
  371.                 $movements->add($movement);
  372.             }
  373.         }
  374.         return $movements;
  375.     }
  376.     /**
  377.      * @param StockMovementItem $stockMovementItem
  378.      * @return float
  379.      */
  380.     public function getLastPurchasePrice(StockMovementItem $stockMovementItem): float
  381.     {
  382.         foreach ($this->movementItems as $index => $movementItem) {
  383.             if ($movementItem->getId() == $stockMovementItem->getId()) {
  384.                 // Increase
  385.                 $increaseWith = 1;
  386.                 do {
  387.                     // Previous Stock Movement Item
  388.                     $previousStockMovementItem = $this->movementItems->get(($index + $increaseWith));
  389.                     if ($previousStockMovementItem) {
  390.                         // Need a In Stock Movement
  391.                         $stockMovement = $previousStockMovementItem->getMovement();
  392.                         if ($stockMovement->getType() == StockMovement::TYPE_IN) {
  393.                             // Exchange Currency
  394.                             $exchangeCurrency = $stockMovement->getMerchant()->getDomain()->getCurrencyTextCode();
  395.                             // Exchange Rate
  396.                             $exchangeRate = 1;
  397.                             if ($exchangeCurrency !== 'EUR') {
  398.                                 $exchangeRate = (float)$stockMovement->getExchangeRate();
  399.                             }
  400.                             if ((float)$exchangeRate <= 0) {
  401.                                 $exchangeRate = 1;
  402.                             }
  403.                             // Converted Price
  404.                             return round(($previousStockMovementItem->getTotalPricePerItem() / $exchangeRate), 2);
  405.                         }
  406.                     }
  407.                     // Increase
  408.                     $increaseWith++;
  409.                 } while ($previousStockMovementItem);
  410.             }
  411.         }
  412.         return .0;
  413.     }
  414.     /**
  415.      * @param StockMovementItem $stockMovementItem
  416.      * @return array
  417.      */
  418.     public function getLastPurchasePriceWithCurrency(StockMovementItem $stockMovementItem): array
  419.     {
  420.         foreach ($this->movementItems as $index => $movementItem) {
  421.             if ($movementItem->getId() == $stockMovementItem->getId()) {
  422.                 // Increase
  423.                 $increaseWith = 1;
  424.                 do {
  425.                     // Previous Stock Movement Item
  426.                     $previousStockMovementItem = $this->movementItems->get(($index + $increaseWith));
  427.                     if ($previousStockMovementItem) {
  428.                         // Need a In Stock Movement
  429.                         $stockMovement = $previousStockMovementItem->getMovement();
  430.                         if ($stockMovement->getType() == StockMovement::TYPE_IN) {
  431.                             return [
  432.                                 'currency' => $stockMovement->getMerchant()->getDomain()->getCurrencyTextCode(),
  433.                                 'value' => $previousStockMovementItem->getTotalPricePerItem(),
  434.                             ];
  435.                         }
  436.                     }
  437.                     // Increase
  438.                     $increaseWith++;
  439.                 } while ($previousStockMovementItem);
  440.             }
  441.         }
  442.         return [];
  443.     }
  444.     /**
  445.      * @return AikenShipmentItem
  446.      */
  447.     public function getAikenShipmentItem()
  448.     {
  449.         return $this->aikenShipmentItem;
  450.     }
  451.     /**
  452.      * @param AikenShipmentItem $aikenShipmentItem
  453.      */
  454.     public function setAikenShipmentItem($aikenShipmentItem)
  455.     {
  456.         $this->aikenShipmentItem = $aikenShipmentItem;
  457.     }
  458.     /**
  459.      * @return string
  460.      */
  461.     public function getAikenCode()
  462.     {
  463.         return $this->aikenCode;
  464.     }
  465.     /**
  466.      * @param string $aikenCode
  467.      */
  468.     public function setAikenCode($aikenCode)
  469.     {
  470.         $this->aikenCode = $aikenCode;
  471.     }
  472.     /**
  473.      * @return string
  474.      */
  475.     public function getSerialNumber()
  476.     {
  477.         return $this->serialNumber;
  478.     }
  479.     /**
  480.      * @param string $serialNumber
  481.      */
  482.     public function setSerialNumber($serialNumber)
  483.     {
  484.         $this->serialNumber = $serialNumber;
  485.     }
  486.     /**
  487.      * @return string
  488.      */
  489.     public function getPurchasePrice()
  490.     {
  491.         return $this->purchasePrice;
  492.     }
  493.     /**
  494.      * @param string $purchasePrice
  495.      */
  496.     public function setPurchasePrice(string $purchasePrice): void
  497.     {
  498.         $this->purchasePrice = $purchasePrice;
  499.     }
  500.     /**
  501.      * @return string
  502.      */
  503.     public function getSellingVatPricePerItem(): string
  504.     {
  505.         return $this->getCompany()->createVatPrice($this->getSellingPrice(), $this->getVat());
  506.     }
  507.     /**
  508.      * @return Company|null
  509.      */
  510.     public function getCompany(): ?Company
  511.     {
  512.         if (!is_null($this->getLastMovement())) {
  513.             return $this->getLastMovement()->getStock()->getCompany();
  514.         }
  515.         return null;
  516.     }
  517.     /**
  518.      * @return StockMovement|null
  519.      */
  520.     public function getLastMovement(): ?StockMovement
  521.     {
  522.         $movements = $this->getMovements();
  523.         if ($movements->count() > 0) {
  524.             return $movements->first();
  525.         }
  526.         return null;
  527.     }
  528.     /**
  529.      * @return string
  530.      */
  531.     public function getSellingPrice(): int|string
  532.     {
  533.         return $this->sellingPrice;
  534.     }
  535.     /**
  536.      * @param string $sellingPrice
  537.      */
  538.     public function setSellingPrice(string $sellingPrice): void
  539.     {
  540.         $this->sellingPrice = $sellingPrice;
  541.     }
  542.     /**
  543.      * @return int
  544.      */
  545.     public function getVat(): int
  546.     {
  547.         return $this->getLastMovementItem()->getVat();
  548.     }
  549.     /**
  550.      * @return int
  551.      */
  552.     public function getQuality(): int
  553.     {
  554.         return $this->quality;
  555.     }
  556.     /**
  557.      * @param int $quality
  558.      */
  559.     public function setQuality(int $quality): void
  560.     {
  561.         $this->quality = $quality;
  562.     }
  563.     /**
  564.      * @return int|null
  565.      */
  566.     public function getQualityPoints(): ?int
  567.     {
  568.         return $this->qualityPoints;
  569.     }
  570.     /**
  571.      * @param int|null $qualityPoints
  572.      * @return void
  573.      */
  574.     public function setQualityPoints(?int $qualityPoints): void
  575.     {
  576.         $this->qualityPoints = $qualityPoints;
  577.     }
  578.     /**
  579.      * @return string|null
  580.      */
  581.     public function getNote(): ?string
  582.     {
  583.         return $this->note;
  584.     }
  585.     /**
  586.      * @param string|null $note
  587.      */
  588.     public function setNote(?string $note)
  589.     {
  590.         $this->note = $note;
  591.     }
  592.     /**
  593.      * @return boolean
  594.      */
  595.     public function isInStock()
  596.     {
  597.         return $this->inStock;
  598.     }
  599.     /**
  600.      * @param boolean $inStock
  601.      */
  602.     public function setInStock($inStock)
  603.     {
  604.         $this->inStock = $inStock;
  605.     }
  606.     /**
  607.      * @return User
  608.      */
  609.     public function getTester()
  610.     {
  611.         return $this->tester;
  612.     }
  613.     /**
  614.      * @param User $tester
  615.      */
  616.     public function setTester($tester)
  617.     {
  618.         $this->tester = $tester;
  619.     }
  620.     /**
  621.      * @return bool
  622.      */
  623.     public function isAvailable()
  624.     {
  625.         return $this->available;
  626.     }
  627.     /**
  628.      * @param bool $available
  629.      */
  630.     public function setAvailable($available)
  631.     {
  632.         $this->available = $available;
  633.     }
  634.     /**
  635.      * @return int
  636.      */
  637.     public function getSortIndex()
  638.     {
  639.         return $this->sortIndex;
  640.     }
  641.     /**
  642.      * @param int $sortIndex
  643.      */
  644.     public function setSortIndex($sortIndex)
  645.     {
  646.         $this->sortIndex = $sortIndex;
  647.     }
  648.     /**
  649.      * @return mixed
  650.      */
  651.     public function getCurrency()
  652.     {
  653.         if (!is_null($this->getCompany())) {
  654.             return $this->getCompany()->getCurrency();
  655.         }
  656.         return null;
  657.     }
  658.     /**
  659.      * @return mixed|string
  660.      */
  661.     public function getQualityString()
  662.     {
  663.         if ($this->quality == 0) {
  664.             return '-';
  665.         }
  666.         return $this->getProduct()?->getProductModel()?->isProductV2()
  667.             ? self::getV2QualityChoices()[$this->quality]
  668.             : self::getQualityChoices()[$this->quality];
  669.     }
  670.     /**
  671.      * @return array
  672.      */
  673.     public static function getQualityChoices(): array
  674.     {
  675.         return [
  676.             self::QUALITY_NEW => 'N',
  677.             self::QUALITY_PLATINUM => 'P',
  678.             self::QUALITY_GOLD => 'G',
  679.             self::QUALITY_SILVER => 'S',
  680.             self::QUALITY_BRONZE => 'B',
  681.             self::QUALITY_BAZAAR => 'C'
  682.         ];
  683.     }
  684.     /**
  685.      * @return array<int, string>
  686.      */
  687.     public static function getV2QualityChoices(): array
  688.     {
  689.         return [
  690.             self::QUALITY_NEW    => 'New',
  691.             self::QUALITY_GOLD   => 'A',
  692.             self::QUALITY_SILVER => 'B',
  693.             self::QUALITY_BRONZE => 'C',
  694.             self::QUALITY_BAZAAR => 'D',
  695.         ];
  696.     }
  697.     /**
  698.      * @return ArrayCollection
  699.      */
  700.     public function getInStockDays()
  701.     {
  702.         return $this->inStockDays;
  703.     }
  704.     /**
  705.      * @param ArrayCollection $inStockDays
  706.      */
  707.     public function setInStockDays($inStockDays)
  708.     {
  709.         $this->inStockDays = $inStockDays;
  710.     }
  711.     /**
  712.      * @return bool
  713.      */
  714.     public function hasLongIKey(): ?bool
  715.     {
  716.         return $this->longIKey == true;
  717.     }
  718.     /**
  719.      * @param ?bool $longIKey
  720.      */
  721.     public function setLongIKey(?bool $longIKey)
  722.     {
  723.         $this->longIKey = $longIKey;
  724.     }
  725.     /**
  726.      * @return bool
  727.      */
  728.     public function hasKeyboardBacklight(): bool
  729.     {
  730.         return $this->keyboardBacklight == true;
  731.     }
  732.     /**
  733.      * @param ?bool $keyboardBacklight
  734.      */
  735.     public function setKeyboardBacklight(?bool $keyboardBacklight)
  736.     {
  737.         $this->keyboardBacklight = $keyboardBacklight;
  738.     }
  739.     /**
  740.      * @return string
  741.      */
  742.     public function getBatteryDuration()
  743.     {
  744.         return $this->batteryDuration;
  745.     }
  746.     /**
  747.      * @param string $batteryDuration
  748.      */
  749.     public function setBatteryDuration($batteryDuration)
  750.     {
  751.         $this->batteryDuration = $batteryDuration;
  752.     }
  753.     /**
  754.      * @return string|null
  755.      */
  756.     public function getBatteryPercentage1(): ?string
  757.     {
  758.         return $this->batteryPercentage1;
  759.     }
  760.     /**
  761.      * @param string|null $batteryPercentage1
  762.      * @return $this
  763.      */
  764.     public function setBatteryPercentage1(?string $batteryPercentage1): self
  765.     {
  766.         $this->batteryPercentage1 = $batteryPercentage1;
  767.         return $this;
  768.     }
  769.     /**
  770.      * @return string|null
  771.      */
  772.     public function getBatteryPercentage2(): ?string
  773.     {
  774.         return $this->batteryPercentage2;
  775.     }
  776.     /**
  777.      * @param string|null $batteryPercentage2
  778.      * @return $this
  779.      */
  780.     public function setBatteryPercentage2(?string $batteryPercentage2): self
  781.     {
  782.         $this->batteryPercentage2 = $batteryPercentage2;
  783.         return $this;
  784.     }
  785.     public function getBatteryCycleCount1(): ?int
  786.     {
  787.         return $this->batteryCycleCount1;
  788.     }
  789.     public function setBatteryCycleCount1(?int $batteryCycleCount1): self
  790.     {
  791.         $this->batteryCycleCount1 = $batteryCycleCount1;
  792.         return $this;
  793.     }
  794.     public function getBatteryCycleCount2(): ?int
  795.     {
  796.         return $this->batteryCycleCount2;
  797.     }
  798.     public function setBatteryCycleCount2(?int $batteryCycleCount): self
  799.     {
  800.         $this->batteryCycleCount2 = $batteryCycleCount;
  801.         return $this;
  802.     }
  803.     /**
  804.      * @return string
  805.      */
  806.     public function getKeyboardLanguage()
  807.     {
  808.         return $this->keyboardLanguage;
  809.     }
  810.     /**
  811.      * @param string $keyboardLanguage
  812.      */
  813.     public function setKeyboardLanguage($keyboardLanguage)
  814.     {
  815.         $this->keyboardLanguage = $keyboardLanguage;
  816.     }
  817.     /**
  818.      * @return string
  819.      */
  820.     public function getErrorCodes()
  821.     {
  822.         return $this->errorCodes;
  823.     }
  824.     /**
  825.      * @param string $errorCodes
  826.      */
  827.     public function setErrorCodes($errorCodes)
  828.     {
  829.         $this->errorCodes = $errorCodes;
  830.     }
  831.     /**
  832.      * @param string $errorCode
  833.      * 
  834.      * @return bool
  835.      */
  836.     public function hasErrorCode(string $errorCode): bool
  837.     {
  838.         $errorCodes = explode(' ', $this->errorCodes);
  839.         return in_array($errorCode, $errorCodes);
  840.     }
  841.     /**
  842.      * @return bool true if requests can be made from the last position by their group.
  843.      */
  844.     public function lastPositionSupportsRequests(): bool
  845.     {
  846.         return $this->getLastPosition()
  847.             ?->getStockPosition()
  848.             ?->getStockPositionGroup()
  849.             ?->supportsRequests() ?? false;
  850.     }
  851.     /**
  852.      * @return StockItemPosition|null
  853.      */
  854.     public function getLastPosition(): ?StockItemPosition
  855.     {
  856.         return $this->getPositions()->count() > 0 ? $this->getPositions()->first() : null;
  857.     }
  858.     /**
  859.      * @return ArrayCollection
  860.      */
  861.     public function getPositions()
  862.     {
  863.         return $this->positions;
  864.     }
  865.     /**
  866.      * @return StockItemPosition|null
  867.      */
  868.     public function getPreviousPosition(): ?StockItemPosition
  869.     {
  870.         return $this->getPositions()->count() > 1 ? $this->getPositions()[1] : null;
  871.     }
  872.     /**
  873.      * @return bool|null
  874.      */
  875.     public function isPenForTouchscreen(): ?bool
  876.     {
  877.         return $this->pen_for_touchscreen;
  878.     }
  879.     /**
  880.      * @param ?bool $pen_for_touchscreen
  881.      */
  882.     public function setPenForTouchscreen(?bool $pen_for_touchscreen): void
  883.     {
  884.         $this->pen_for_touchscreen = $pen_for_touchscreen;
  885.     }
  886.     /**
  887.      * @return bool|null
  888.      */
  889.     public function isTrackpoint(): ?bool
  890.     {
  891.         return $this->trackpoint;
  892.     }
  893.     /**
  894.      * @param ?bool $trackpoint
  895.      */
  896.     public function setTrackpoint(?bool $trackpoint): void
  897.     {
  898.         $this->trackpoint = $trackpoint;
  899.     }
  900.     /**
  901.      * @return Album
  902.      */
  903.     public function getAlbum()
  904.     {
  905.         return $this->album;
  906.     }
  907.     /**
  908.      * @param Album|null $album
  909.      */
  910.     public function setAlbum(?Album $album)
  911.     {
  912.         $this->album = $album;
  913.     }
  914.     /**
  915.      * @return StockPosition|null
  916.      */
  917.     public function getLastKnownStockPosition(): ?StockPosition
  918.     {
  919.         return $this->lastKnownStockPosition;
  920.     }
  921.     /**
  922.      * @param StockPosition|null
  923.      *
  924.      * @return void
  925.      */
  926.     public function setLastKnownStockPosition(?StockPosition $stockPosition = null): void
  927.     {
  928.         $this->lastKnownStockPosition = $stockPosition;
  929.     }
  930.     public function getBattery1State()
  931.     {
  932.         return $this->getBatteryState($this->getBatteryPercentage1(), $this->getBatteryCycleCount1());
  933.     }
  934.     public function getBattery2State()
  935.     {
  936.         return $this->getBatteryState($this->getBatteryPercentage2(), $this->getBatteryCycleCount2());
  937.     }
  938.     private function getBatteryState(?string $percentageString, ?int $cyclesCount)
  939.     {
  940.         $percentage = str_replace('%', '', $percentageString);
  941.         $percentage = trim($percentage);
  942.         $percentage = intval($percentage);
  943.         if ($percentageString && $cyclesCount) {
  944.             if ($cyclesCount < 5 && $percentage >= 98) {
  945.                 return self::BATTERY_STATE_NEW;
  946.             }
  947.             return self::BATTERY_STATE_USED;
  948.         } else {
  949.             return self::BATTERY_STATE_NO_INFO;
  950.         }
  951.     }
  952.     /**
  953.      * @return Order|null
  954.      */
  955.     public function getOrder(): ?Order {
  956.         $order = $this->getLastMovementItem()?->getMovement()?->getOrder();
  957.         if ( $order ) {
  958.             return $order;
  959.         }
  960.         $order = $this->getLastMovementItem()?->getMovement()?->getOrderConfigChange();
  961.         if ( $order ) {
  962.             return $order;
  963.         }
  964.         foreach ( $this->getMovements() as $movement ) {
  965.             if ( $movement->getType() == StockMovement::TYPE_NEUTRAL ) {
  966.                 return $movement->getOrder();
  967.             }
  968.         }
  969.         return null;
  970.     }
  971.     public function getProductModelVariationId(bool $getStockItemsFunction = false): ?int
  972.     {
  973.         $lastMovementItem = $getStockItemsFunction
  974.             ? $this->getLastMovementItemForGetStockItemsFunction()
  975.             : $this->getLastMovementItem();
  976.         if (is_null($lastMovementItem)) {
  977.             return null;
  978.         }
  979.         if ($lastMovementItem->getMovement()->getType() == StockMovement::TYPE_NEUTRAL) {
  980.             $movementItems = $this->getMovementItems();
  981.             if ($movementItems->count() > 1) {
  982.                 $previousMovementItem = $movementItems->get(1);
  983.                 return $previousMovementItem?->getProductModelVariationId();
  984.             }
  985.         }
  986.         return $lastMovementItem->getProductModelVariationId();
  987.     }
  988.     /**
  989.      * @param bool $getStockItemsFunction
  990.      * @return PersonalizationAttributeOptionCombination|null
  991.      */
  992.     public function getPersonalizationAttributeOptionCombination(bool $getStockItemsFunction = false): PersonalizationAttributeOptionCombination|null
  993.     {
  994.         $lastMovementItem = $getStockItemsFunction
  995.             ? $this->getLastMovementItemForGetStockItemsFunction()
  996.             : $this->getLastMovementItem();
  997.         if (is_null($lastMovementItem)) {
  998.             return null;
  999.         }
  1000.         if ($lastMovementItem->getMovement()->getType() == StockMovement::TYPE_NEUTRAL) {
  1001.             $movementItems = $this->getMovementItems();
  1002.             if ($movementItems->count() > 1) {
  1003.                 $previousMovementItem = $movementItems->get(1);
  1004.                 return $previousMovementItem?->getPersonalizationAttributeOptionCombination();
  1005.             }
  1006.         }
  1007.         return $lastMovementItem->getPersonalizationAttributeOptionCombination();
  1008.     }
  1009.     /**
  1010.      * @return string|null
  1011.      */
  1012.     public function getReprintLanguageCode(): ?string
  1013.     {
  1014.         $languageCode = mb_strtoupper(trim($this->keyboardLanguage));
  1015.         if ( mb_strlen($languageCode) == 3 ) {
  1016.             return $languageCode;
  1017.         }
  1018.         if ( $languageCode === 'SK-CZ' ) {
  1019.             return $languageCode;
  1020.         }
  1021.         return StockItem::KEYBOARD_LANGUAGE_VALID_VALUE_LIST[$languageCode] ?? null;
  1022.     }
  1023.     /**
  1024.      * @return bool
  1025.      */
  1026.     public function isFingerprintReader(): bool
  1027.     {
  1028.         return $this->fingerprintReader;
  1029.     }
  1030.     /**
  1031.      * @param bool $fingerprintReader
  1032.      *
  1033.      * @return void
  1034.      */
  1035.     public function setFingerprintReader(bool $fingerprintReader): void
  1036.     {
  1037.         $this->fingerprintReader = $fingerprintReader;
  1038.     }
  1039. }