src/Entity/Invoice.php line 24

Open in your IDE?
  1. <?php
  2. namespace MedBrief\MSR\Entity;
  3. use DH\Auditor\Provider\Doctrine\Auditing\Annotation as Audit;
  4. use Doctrine\Common\Collections\ArrayCollection;
  5. use Doctrine\ORM\Mapping as ORM;
  6. use Gedmo\Mapping\Annotation as Gedmo;
  7. use MedBrief\MSR\Repository\InvoiceRepository;
  8. /**
  9. * Represents an Invoice.
  10. *
  11. * Invoice can contain multiple invoiceItems.
  12. *
  13. * @ORM\Table(name="Invoice")
  14. *
  15. * @ORM\Entity(repositoryClass=InvoiceRepository::class)
  16. *
  17. * @Audit\Auditable
  18. *
  19. * @Audit\Security(view={"ROLE_ALLOWED_TO_AUDIT"})
  20. */
  21. class Invoice
  22. {
  23. // Status constants
  24. public const STATUS_AWAITING_PAYMENT = 1; // Not used
  25. public const STATUS_PAID = 2; // Not used
  26. public const STATUS_CANCELLED = 3; // Not used
  27. public const STATUS_DRAFT = 4;
  28. public const STATUS_SUBMITTED = 5;
  29. // Currently only support one currency for invoices.
  30. public const DEFAULT_CURRENCY = 'GBP';
  31. /**
  32. * @var int
  33. *
  34. * @ORM\Column(name="id", type="integer")
  35. *
  36. * @ORM\Id
  37. *
  38. * @ORM\GeneratedValue(strategy="IDENTITY")
  39. */
  40. protected $id;
  41. /**
  42. * @var string|null
  43. *
  44. * @ORM\Column(name="referenceId", type="string", nullable=true)
  45. */
  46. protected $referenceId;
  47. /**
  48. * @var \DateTime|null
  49. *
  50. * @ORM\Column(name="invoiceDate", type="date", nullable=true)
  51. */
  52. protected $invoiceDate;
  53. /**
  54. * @var int|null
  55. *
  56. * @ORM\Column(name="status", type="integer", nullable=true)
  57. */
  58. protected $status;
  59. /**
  60. * @var \DateTime|null
  61. *
  62. * @ORM\Column(name="dueDate", type="date", nullable=true)
  63. */
  64. protected $dueDate;
  65. /**
  66. * The InvoiceItems associated with this Invoice.
  67. *
  68. * @var ArrayCollection
  69. *
  70. * @ORM\OneToMany(targetEntity="MedBrief\MSR\Entity\InvoiceItem", mappedBy="invoice", cascade={"persist","remove"}, orphanRemoval=true)
  71. */
  72. protected $items;
  73. /**
  74. * Guid provided by accounting system.
  75. *
  76. * @var string|null
  77. *
  78. * @ORM\Column(name="guid", type="string", nullable=true)
  79. */
  80. protected $guid;
  81. /**
  82. * The date the invoice was last synced to Xero.
  83. *
  84. * @var \DateTime|null
  85. *
  86. * @ORM\Column(name="syncDate", type="datetime", nullable=true)
  87. */
  88. protected $syncDate;
  89. /**
  90. * Maintains an identifier for the invoice to the Project it belongs to,
  91. * event after the Project gets deleted.
  92. *
  93. * @var string|null
  94. *
  95. * @ORM\Column(name="projectReferenceNumber", type="string", nullable=true)
  96. */
  97. protected $projectReferenceNumber;
  98. /**
  99. * Maintains an identifier for the invoice to the Project it belongs to,
  100. * event after the Project gets deleted.
  101. *
  102. * @var int|null
  103. *
  104. * @ORM\Column(name="projectId", type="integer", nullable=true)
  105. */
  106. protected $projectId;
  107. /**
  108. * @var \DateTime
  109. *
  110. * @ORM\Column(name="created", type="datetime")
  111. *
  112. * @Gedmo\Timestampable(on="create")
  113. */
  114. protected $created;
  115. /**
  116. * @var \DateTime
  117. *
  118. * @ORM\Column(name="updated", type="datetime")
  119. *
  120. * @Gedmo\Timestampable(on="update")
  121. */
  122. protected $updated;
  123. /**
  124. * The ID of the associated Account
  125. *
  126. * @var int|null
  127. *
  128. * @ORM\Column(name="accountId", type="integer", nullable=true)
  129. */
  130. protected $accountId;
  131. /**
  132. * Constructor
  133. */
  134. public function __construct()
  135. {
  136. // Initialise ArrayCollections
  137. $this->items = new ArrayCollection();
  138. // Assign default dates
  139. $this->invoiceDate = new \DateTime();
  140. $this->dueDate = new \DateTime();
  141. // Set the default status to Draft
  142. $this->status = self::STATUS_DRAFT;
  143. }
  144. /**
  145. * __toString
  146. *
  147. * @return string
  148. */
  149. public function __toString()
  150. {
  151. return (string) $this->getReferenceId();
  152. }
  153. /**
  154. * Get id
  155. *
  156. * @return int
  157. */
  158. public function getId()
  159. {
  160. return $this->id;
  161. }
  162. /**
  163. * Set referenceId
  164. *
  165. * @param string $referenceId
  166. *
  167. * @return Invoice
  168. */
  169. public function setReferenceId($referenceId)
  170. {
  171. $this->referenceId = $referenceId;
  172. return $this;
  173. }
  174. /**
  175. * Get referenceId
  176. *
  177. * @return string
  178. */
  179. public function getReferenceId()
  180. {
  181. return $this->referenceId;
  182. }
  183. /**
  184. * Set created
  185. *
  186. * @param \DateTime $created
  187. *
  188. * @return Invoice
  189. */
  190. public function setCreated($created)
  191. {
  192. $this->created = $created;
  193. return $this;
  194. }
  195. /**
  196. * Get created
  197. *
  198. * @return \DateTime
  199. */
  200. public function getCreated()
  201. {
  202. return $this->created;
  203. }
  204. /**
  205. * Set updated
  206. *
  207. * @param \DateTime $updated
  208. *
  209. * @return Invoice
  210. */
  211. public function setUpdated($updated)
  212. {
  213. $this->updated = $updated;
  214. return $this;
  215. }
  216. /**
  217. * Get updated
  218. *
  219. * @return \DateTime
  220. */
  221. public function getUpdated()
  222. {
  223. return $this->updated;
  224. }
  225. /**
  226. * Add item
  227. *
  228. * @param InvoiceItem $item
  229. *
  230. * @return Invoice
  231. */
  232. public function addItem(InvoiceItem $item)
  233. {
  234. $this->items[] = $item;
  235. return $this;
  236. }
  237. /**
  238. * Remove item
  239. *
  240. * @param InvoiceItem $item
  241. */
  242. public function removeItem(InvoiceItem $item)
  243. {
  244. $this->items->removeElement($item);
  245. }
  246. /**
  247. * Get items
  248. *
  249. * @return \Doctrine\Common\Collections\Collection
  250. */
  251. public function getItems()
  252. {
  253. return $this->items;
  254. }
  255. /**
  256. * Set invoiceDate
  257. *
  258. * @param \DateTime $invoiceDate
  259. *
  260. * @return Invoice
  261. */
  262. public function setInvoiceDate($invoiceDate)
  263. {
  264. $this->invoiceDate = $invoiceDate;
  265. return $this;
  266. }
  267. /**
  268. * Get invoiceDate
  269. *
  270. * @return \DateTime
  271. */
  272. public function getInvoiceDate()
  273. {
  274. return $this->invoiceDate;
  275. }
  276. /**
  277. * Set dueDate
  278. *
  279. * @param \DateTime $dueDate
  280. *
  281. * @return Invoice
  282. */
  283. public function setDueDate($dueDate)
  284. {
  285. $this->dueDate = $dueDate;
  286. return $this;
  287. }
  288. /**
  289. * Get dueDate
  290. *
  291. * @return \DateTime
  292. */
  293. public function getDueDate()
  294. {
  295. return $this->dueDate;
  296. }
  297. /**
  298. * Calculates the total value of the invoice.
  299. *
  300. * @return float
  301. */
  302. public function getTotal()
  303. {
  304. return $this->getTotalExclVat() + $this->getVat();
  305. }
  306. /**
  307. * Calculates the total VAT of the invoice,
  308. * by reducing all the items associated with the Invoice
  309. * to a value by aggregating their individual VAT totals.
  310. *
  311. * @return float
  312. */
  313. public function getVat()
  314. {
  315. return array_reduce($this->getItems()->toArray(), function ($vat, InvoiceItem $item) {
  316. return $vat += $item->getVat();
  317. });
  318. }
  319. /**
  320. * Calculates the total excl VAT of the invoice,
  321. * by reducing all the items associated with the Invoice
  322. * to a value by aggregating their individual VAT exclusive totals.
  323. *
  324. * @return float
  325. */
  326. public function getTotalExclVat()
  327. {
  328. return array_reduce($this->getItems()->toArray(), function ($totalExclVat, InvoiceItem $item) {
  329. return $totalExclVat += $item->getTotalExclVat();
  330. });
  331. }
  332. /**
  333. * Set status
  334. *
  335. * @param int $status
  336. *
  337. * @return Invoice
  338. */
  339. public function setStatus($status)
  340. {
  341. $this->status = $status;
  342. return $this;
  343. }
  344. /**
  345. * Get status
  346. *
  347. * @return int
  348. */
  349. public function getStatus()
  350. {
  351. return $this->status;
  352. }
  353. /**
  354. * Get getStatusOptions
  355. *
  356. * @return array
  357. */
  358. public static function getStatusOptions()
  359. {
  360. return [
  361. self::STATUS_DRAFT => 'Draft',
  362. self::STATUS_AWAITING_PAYMENT => 'Awaiting Payment',
  363. self::STATUS_PAID => 'Paid',
  364. self::STATUS_CANCELLED => 'Cancelled',
  365. self::STATUS_SUBMITTED => 'Submitted',
  366. ];
  367. }
  368. /**
  369. * These statuses indicate that the ServiceRequests that
  370. * belong to these invoices don't need to be invoiced for.
  371. *
  372. * @return array
  373. */
  374. public static function getBilledStatuses()
  375. {
  376. return [
  377. self::STATUS_AWAITING_PAYMENT,
  378. self::STATUS_PAID,
  379. self::STATUS_SUBMITTED,
  380. ];
  381. }
  382. /**
  383. * Convenience method to determine if the Invoice is in a billed
  384. * status.
  385. *
  386. * @return void
  387. */
  388. public function isBilledStatus()
  389. {
  390. return in_array($this->getStatus(), self::getBilledStatuses());
  391. }
  392. /**
  393. * Get getStatusLabel
  394. *
  395. * @return int
  396. */
  397. public function getStatusLabel()
  398. {
  399. $options = self::getStatusOptions();
  400. // For the default label, we use STATUS_AWAITING_PAYMENT
  401. return $options[$this->getStatus()] ?? $options[self::STATUS_AWAITING_PAYMENT];
  402. }
  403. /**
  404. * Convenience function to determine if the Invoice has been paid.
  405. *
  406. * @return bool
  407. */
  408. public function isPaid()
  409. {
  410. return $this->getStatus() === self::STATUS_PAID;
  411. }
  412. /**
  413. * Convenience function to determine if the Invoice has been cancelled.
  414. *
  415. * @return bool
  416. */
  417. public function isCancelled()
  418. {
  419. return $this->getStatus() === self::STATUS_CANCELLED;
  420. }
  421. /**
  422. * Convenience function to determine if the Invoice is awaiting payment.
  423. *
  424. * @return bool
  425. */
  426. public function isAwaitingPayment()
  427. {
  428. return $this->getStatus() === self::STATUS_AWAITING_PAYMENT;
  429. }
  430. /**
  431. * Convenience function to determine if the Invoice is submitted.
  432. *
  433. * @return bool
  434. */
  435. public function isSubmitted()
  436. {
  437. return $this->getStatus() === self::STATUS_SUBMITTED;
  438. }
  439. /**
  440. * Convenience function to determine if the Invoice is draft.
  441. *
  442. * @return bool
  443. */
  444. public function isDraft()
  445. {
  446. return $this->getStatus() === self::STATUS_DRAFT;
  447. }
  448. /**
  449. * Set guid
  450. *
  451. * @param string $guid
  452. *
  453. * @return Invoice
  454. */
  455. public function setGuid($guid)
  456. {
  457. $this->guid = $guid;
  458. return $this;
  459. }
  460. /**
  461. * Get guid
  462. *
  463. * @return string
  464. */
  465. public function getGuid()
  466. {
  467. return $this->guid;
  468. }
  469. /**
  470. * Set syncDate
  471. *
  472. * @param \DateTime $syncDate
  473. *
  474. * @return Invoice
  475. */
  476. public function setSyncDate($syncDate)
  477. {
  478. $this->syncDate = $syncDate;
  479. return $this;
  480. }
  481. /**
  482. * Get syncDate
  483. *
  484. * @return \DateTime
  485. */
  486. public function getSyncDate()
  487. {
  488. return $this->syncDate;
  489. }
  490. /**
  491. * Set projectReferenceNumber
  492. *
  493. * @param string $projectReferenceNumber
  494. *
  495. * @return Invoice
  496. */
  497. public function setProjectReferenceNumber($projectReferenceNumber)
  498. {
  499. $this->projectReferenceNumber = $projectReferenceNumber;
  500. return $this;
  501. }
  502. /**
  503. * Get projectReferenceNumber
  504. *
  505. * @return string
  506. */
  507. public function getProjectReferenceNumber()
  508. {
  509. return $this->projectReferenceNumber;
  510. }
  511. /**
  512. * Set projectId
  513. *
  514. * @param int $projectId
  515. *
  516. * @return Invoice
  517. */
  518. public function setProjectId($projectId)
  519. {
  520. $this->projectId = $projectId;
  521. return $this;
  522. }
  523. /**
  524. * Get projectId
  525. *
  526. * @return int
  527. */
  528. public function getProjectId()
  529. {
  530. return $this->projectId;
  531. }
  532. /**
  533. * Set accountId
  534. *
  535. * @param int $accountId
  536. *
  537. * @return Invoice
  538. */
  539. public function setAccountId($accountId)
  540. {
  541. $this->accountId = $accountId;
  542. return $this;
  543. }
  544. /**
  545. * Get accountId
  546. *
  547. * @return int
  548. */
  549. public function getAccountId()
  550. {
  551. return $this->accountId;
  552. }
  553. }