Completed
Push — master ( 4b99be...b893a1 )
by Joachim
14:15
created

Report::isDeletable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php declare(strict_types=1);
2
3
namespace Loevgaard\DandomainConsignment\Entity;
4
5
use Assert\Assert;
6
use Doctrine\Common\Collections\ArrayCollection;
7
use Doctrine\Common\Collections\Collection;
8
use Doctrine\ORM\Mapping as ORM;
9
use Knp\DoctrineBehaviors\Model\Timestampable\Timestampable;
10
use Loevgaard\DandomainConsignment\Entity\Generated\ReportInterface;
11
use Loevgaard\DandomainConsignment\Entity\Generated\ReportTrait;
12
use Loevgaard\DandomainFoundation\Entity\Generated\ManufacturerInterface;
13
use Loevgaard\DandomainStock\Entity\Generated\StockMovementInterface;
14
use Money\Currency;
15
use Money\Money;
16
use Symfony\Component\Validator\Constraints as FormAssert;
17
18
/**
19
 * @ORM\Entity()
20
 * @ORM\Table(name="ldc_reports")
21
 * @ORM\HasLifecycleCallbacks()
22
 */
23
class Report implements ReportInterface
24
{
25
    use ReportTrait;
26
    use Timestampable;
27
28
    const STATUS_ERROR = 'error';
29
    const STATUS_PENDING = 'pending';
30
    const STATUS_SUCCESSFUL = 'successful';
31
32
    /**
33
     * @var int
34
     *
35
     * @ORM\Column(type="integer")
36
     * @ORM\GeneratedValue
37
     * @ORM\Id
38
     */
39
    protected $id;
40
41
    /**
42
     * @var ManufacturerInterface
43
     *
44
     * @FormAssert\NotBlank()
45
     *
46
     * @ORM\ManyToOne(targetEntity="Loevgaard\DandomainFoundation\Entity\Manufacturer")
47
     * @ORM\JoinColumn(onDelete="CASCADE", nullable=false)
48
     */
49
    protected $manufacturer;
50
51
    /**
52
     * @var string
53
     *
54
     * @FormAssert\Choice(callback="getStatuses")
55
     *
56
     * @ORM\Column(type="string", length=191)
57
     */
58
    protected $status;
59
60
    /**
61
     * @var string|null
62
     *
63
     * @ORM\Column(type="text", nullable=true)
64
     */
65
    protected $error;
66
67
    /**
68
     * @var StockMovementInterface[]|ArrayCollection
69
     *
70
     * @ORM\ManyToMany(targetEntity="Loevgaard\DandomainStock\Entity\StockMovement")
71
     * @ORM\JoinTable(name="ldc_reports_stock_movements")
72
     * @ORM\OrderBy({"createdAt" = "ASC"})
73
     */
74
    protected $stockMovements;
75
76
    public function __construct()
77
    {
78
        $this->status = self::STATUS_PENDING;
79
        $this->stockMovements = new ArrayCollection();
80
    }
81
82
    public function markAsError(?string $error = null) : void
83
    {
84
        $this->status = self::STATUS_ERROR;
85
        $this->error = $error;
86
    }
87
88
    public function markAsSuccess() : void
89
    {
90
        $this->status = self::STATUS_SUCCESSFUL;
91
        $this->error = null;
92
    }
93
94
    public function isStatus(string $status) : bool
95
    {
96
        return $this->status === $status;
97
    }
98
99
    public function isSuccessful() : bool
100
    {
101
        return $this->isStatus(self::STATUS_SUCCESSFUL);
102
    }
103
104
    public function isError() : bool
105
    {
106
        return $this->isStatus(self::STATUS_ERROR);
107
    }
108
109
    /**
110
     * Returns true if the report can be delivered to the consignor
111
     *
112
     * @return bool
113
     */
114
    public function isDeliverable() : bool
115
    {
116
        return $this->isSuccessful();
117
    }
118
119
    /**
120
     * @ORM\PrePersist()
121
     * @ORM\PreUpdate()
122
     */
123
    public function validate() : void
124
    {
125
        Assert::that($this->manufacturer)->isInstanceOf(ManufacturerInterface::class);
126
        Assert::that($this->status)->choice(self::getStatuses());
127
        Assert::thatNullOr($this->error)->string();
128
        Assert::thatAll($this->stockMovements->toArray())->isInstanceOf(StockMovementInterface::class);
129
    }
130
131
    public static function getStatuses() : array
132
    {
133
        return [
134
            self::STATUS_PENDING => self::STATUS_PENDING,
135
            self::STATUS_SUCCESSFUL => self::STATUS_SUCCESSFUL,
136
            self::STATUS_ERROR => self::STATUS_ERROR
137
        ];
138
    }
139
140
    public function addStockMovement(StockMovementInterface $stockMovement) : ReportInterface
141
    {
142
        if (!$this->stockMovements->contains($stockMovement)) {
143
            $this->stockMovements->add($stockMovement);
144
        }
145
146
        return $this;
147
    }
148
149
    public function removeStockMovement(StockMovementInterface $stockMovement) : ReportInterface
150
    {
151
        $this->stockMovements->removeElement($stockMovement);
152
153
        return $this;
154
    }
155
156
    public function clearStockMovements() : ReportInterface
157
    {
158
        $this->stockMovements->clear();
159
160
        return $this;
161
    }
162
163
    /**
164
     * Returns the total for all stock movements
165
     * Returns a Money object with amount = 0 and $defaultCurrency if there are no stock movements
166
     *
167
     * @param string $defaultCurrency
168
     * @return Money
169
     * @throws \Loevgaard\DandomainStock\Exception\UnsetCurrencyException
170
     */
171
    public function getTotal(string $defaultCurrency = 'DKK') : Money
172
    {
173
        $total = null;
174
175
        foreach ($this->stockMovements as $stockMovement) {
176
            if (!$total) {
177
                $total = new Money(0, new Currency($stockMovement->getCurrency()));
178
            }
179
180
            $total = $total->add($stockMovement->getTotalPrice());
181
        }
182
183
        if (!$total) {
184
            $total = new Money(0, new Currency($defaultCurrency));
185
        }
186
187
        return $total;
188
    }
189
190
    /**
191
     * @return int
192
     */
193
    public function getId(): int
194
    {
195
        return (int)$this->id;
196
    }
197
198
    /**
199
     * @param int $id
200
     * @return ReportInterface
201
     */
202
    public function setId(int $id) : ReportInterface
203
    {
204
        $this->id = $id;
205
        return $this;
206
    }
207
208
    /**
209
     * @return ManufacturerInterface
210
     */
211
    public function getManufacturer(): ?ManufacturerInterface
212
    {
213
        return $this->manufacturer;
214
    }
215
216
    /**
217
     * @param ManufacturerInterface $manufacturer
218
     * @return ReportInterface
219
     */
220
    public function setManufacturer(ManufacturerInterface $manufacturer) : ReportInterface
221
    {
222
        $this->manufacturer = $manufacturer;
223
        return $this;
224
    }
225
226
    /**
227
     * @return string
228
     */
229
    public function getStatus(): ?string
230
    {
231
        return $this->status;
232
    }
233
234
    /**
235
     * @param string $status
236
     * @return ReportInterface
237
     */
238
    public function setStatus(string $status) : ReportInterface
239
    {
240
        $this->status = $status;
241
        return $this;
242
    }
243
244
    /**
245
     * @return null|string
246
     */
247
    public function getError(): ?string
248
    {
249
        return $this->error;
250
    }
251
252
    /**
253
     * @param null|string $error
254
     * @return ReportInterface
255
     */
256
    public function setError(?string $error) : ReportInterface
257
    {
258
        $this->error = $error;
259
        return $this;
260
    }
261
262
    /**
263
     * @return StockMovementInterface[]|ArrayCollection
264
     */
265
    public function getStockMovements() : Collection
266
    {
267
        return $this->stockMovements;
268
    }
269
270
    /**
271
     * @param StockMovementInterface[]|Collection $stockMovements
272
     * @return ReportInterface
273
     */
274
    public function setStockMovements(Collection $stockMovements) : ReportInterface
275
    {
276
        foreach ($stockMovements as $stockMovement) {
277
            $this->addStockMovement($stockMovement);
278
        }
279
280
        return $this;
281
    }
282
}
283