src/Finance/Domain/Entity/StudentFee.php line 19

Open in your IDE?
  1. <?php
  2. namespace App\Finance\Domain\Entity;
  3. use App\Finance\Domain\Enum\FeeType;
  4. use App\Finance\Domain\Enum\StudentFeeStatus;
  5. use App\Finance\Domain\Repository\StudentFeeRepository;
  6. use Doctrine\DBAL\Types\Types;
  7. use Doctrine\ORM\Mapping as ORM;
  8. use Symfony\Component\Validator\Constraints as Assert;
  9. #[ORM\Entity(repositoryClass: StudentFeeRepository::class)]
  10. #[ORM\Table(name: 'student_fees')]
  11. #[ORM\Index(columns: ['student_id'], name: 'idx_student_id')]
  12. #[ORM\Index(columns: ['school_year_id'], name: 'idx_school_year_id')]
  13. #[ORM\Index(columns: ['fee_type'], name: 'idx_fee_type')]
  14. #[ORM\Index(columns: ['status'], name: 'idx_status')]
  15. #[ORM\Index(columns: ['due_date'], name: 'idx_due_date')]
  16. class StudentFee
  17. {
  18. #[ORM\Id]
  19. #[ORM\GeneratedValue]
  20. #[ORM\Column(type: Types::INTEGER)]
  21. private ?int $id = null;
  22. #[ORM\Column(type: Types::INTEGER)]
  23. #[Assert\NotNull]
  24. private int $studentId;
  25. #[ORM\Column(type: Types::INTEGER)]
  26. #[Assert\NotNull]
  27. private int $schoolYearId;
  28. #[ORM\Column(type: Types::INTEGER)]
  29. #[Assert\NotNull]
  30. private int $feeDefinitionId;
  31. #[ORM\Column(type: Types::STRING, length: 20, enumType: FeeType::class)]
  32. #[Assert\NotNull]
  33. private FeeType $feeType;
  34. #[ORM\Column(type: Types::STRING, length: 255)]
  35. #[Assert\NotBlank]
  36. private string $name;
  37. #[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 2)]
  38. #[Assert\NotNull]
  39. #[Assert\PositiveOrZero]
  40. private string $amountDue;
  41. #[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 2, options: ['default' => '0.00'])]
  42. private string $amountPaid = '0.00';
  43. #[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 2, options: ['default' => '0.00'])]
  44. private string $balance = '0.00';
  45. #[ORM\Column(type: Types::STRING, length: 20, enumType: StudentFeeStatus::class)]
  46. private StudentFeeStatus $status = StudentFeeStatus::PENDING;
  47. #[ORM\Column(type: Types::DATE_IMMUTABLE, nullable: true)]
  48. private ?\DateTimeImmutable $dueDate = null;
  49. #[ORM\Column(type: Types::INTEGER, nullable: true)]
  50. private ?int $installmentNumber = null;
  51. #[ORM\Column(type: Types::DATETIME_IMMUTABLE)]
  52. private \DateTimeImmutable $createdAt;
  53. #[ORM\Column(type: Types::DATETIME_IMMUTABLE)]
  54. private \DateTimeImmutable $updatedAt;
  55. public function __construct()
  56. {
  57. $this->createdAt = new \DateTimeImmutable();
  58. $this->updatedAt = new \DateTimeImmutable();
  59. }
  60. public function getId(): ?int
  61. {
  62. return $this->id;
  63. }
  64. public function getStudentId(): int
  65. {
  66. return $this->studentId;
  67. }
  68. public function setStudentId(int $studentId): self
  69. {
  70. $this->studentId = $studentId;
  71. $this->updatedAt = new \DateTimeImmutable();
  72. return $this;
  73. }
  74. public function getSchoolYearId(): int
  75. {
  76. return $this->schoolYearId;
  77. }
  78. public function setSchoolYearId(int $schoolYearId): self
  79. {
  80. $this->schoolYearId = $schoolYearId;
  81. $this->updatedAt = new \DateTimeImmutable();
  82. return $this;
  83. }
  84. public function getFeeDefinitionId(): int
  85. {
  86. return $this->feeDefinitionId;
  87. }
  88. public function setFeeDefinitionId(int $feeDefinitionId): self
  89. {
  90. $this->feeDefinitionId = $feeDefinitionId;
  91. $this->updatedAt = new \DateTimeImmutable();
  92. return $this;
  93. }
  94. public function getFeeType(): FeeType
  95. {
  96. return $this->feeType;
  97. }
  98. public function setFeeType(FeeType $feeType): self
  99. {
  100. $this->feeType = $feeType;
  101. $this->updatedAt = new \DateTimeImmutable();
  102. return $this;
  103. }
  104. public function getName(): string
  105. {
  106. return $this->name;
  107. }
  108. public function setName(string $name): self
  109. {
  110. $this->name = $name;
  111. $this->updatedAt = new \DateTimeImmutable();
  112. return $this;
  113. }
  114. public function getAmountDue(): string
  115. {
  116. return $this->amountDue;
  117. }
  118. public function setAmountDue(string $amountDue): self
  119. {
  120. $this->amountDue = $amountDue;
  121. $this->recalculateBalance();
  122. return $this;
  123. }
  124. public function getAmountPaid(): string
  125. {
  126. return $this->amountPaid;
  127. }
  128. public function setAmountPaid(string $amountPaid): self
  129. {
  130. $this->amountPaid = $amountPaid;
  131. $this->recalculateBalance();
  132. return $this;
  133. }
  134. public function getBalance(): string
  135. {
  136. return $this->balance;
  137. }
  138. public function getStatus(): StudentFeeStatus
  139. {
  140. return $this->status;
  141. }
  142. public function setStatus(StudentFeeStatus $status): self
  143. {
  144. $this->status = $status;
  145. $this->updatedAt = new \DateTimeImmutable();
  146. return $this;
  147. }
  148. public function getDueDate(): ?\DateTimeImmutable
  149. {
  150. return $this->dueDate;
  151. }
  152. public function setDueDate(?\DateTimeImmutable $dueDate): self
  153. {
  154. $this->dueDate = $dueDate;
  155. $this->updatedAt = new \DateTimeImmutable();
  156. return $this;
  157. }
  158. public function getInstallmentNumber(): ?int
  159. {
  160. return $this->installmentNumber;
  161. }
  162. public function setInstallmentNumber(?int $installmentNumber): self
  163. {
  164. $this->installmentNumber = $installmentNumber;
  165. $this->updatedAt = new \DateTimeImmutable();
  166. return $this;
  167. }
  168. public function getCreatedAt(): \DateTimeImmutable
  169. {
  170. return $this->createdAt;
  171. }
  172. public function getUpdatedAt(): \DateTimeImmutable
  173. {
  174. return $this->updatedAt;
  175. }
  176. public function recalculateBalance(): void
  177. {
  178. $this->balance = bcsub($this->amountDue, $this->amountPaid, 2);
  179. $this->updateStatus();
  180. $this->updatedAt = new \DateTimeImmutable();
  181. }
  182. private function updateStatus(): void
  183. {
  184. if (bccomp($this->balance, '0.00', 2) <= 0) {
  185. $this->status = StudentFeeStatus::PAID;
  186. } elseif (bccomp($this->amountPaid, '0.00', 2) > 0) {
  187. $this->status = StudentFeeStatus::PARTIAL;
  188. } else {
  189. $this->status = StudentFeeStatus::PENDING;
  190. }
  191. }
  192. public function isLate(): bool
  193. {
  194. if (!$this->dueDate) {
  195. return false;
  196. }
  197. $now = new \DateTimeImmutable();
  198. return $now > $this->dueDate && bccomp($this->balance, '0.00', 2) > 0;
  199. }
  200. }