| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 | 
							- <?php
 - 
 - namespace App\Concerns;
 - 
 - use App\Enums\Accounting\JournalEntryType;
 - use App\Utilities\Currency\CurrencyAccessor;
 - use App\Utilities\Currency\CurrencyConverter;
 - use Filament\Tables\Actions\Action;
 - 
 - trait HasJournalEntryActions
 - {
 -     public int $debitAmount = 0;
 - 
 -     public int $creditAmount = 0;
 - 
 -     private function formatMoney(int $amount): string
 -     {
 -         return CurrencyConverter::formatCentsToMoney($amount, CurrencyAccessor::getDefaultCurrency());
 -     }
 - 
 -     /**
 -      * Expects formatted simple amount: e.g. 1,000.00 or 1.000,00
 -      *
 -      * Sets debit amount in cents as integer: e.g. 100000
 -      */
 -     public function setDebitAmount(int $amount): void
 -     {
 -         $this->debitAmount = $amount;
 -     }
 - 
 -     /**
 -      * Expects formatted simple amount: e.g. 1,000.00 or 1.000,00
 -      *
 -      * Sets credit amount in cents as integer: e.g. 100000
 -      */
 -     public function setCreditAmount(int $amount): void
 -     {
 -         $this->creditAmount = $amount;
 -     }
 - 
 -     /**
 -      * Returns debit amount in cents as integer: e.g. 100000
 -      */
 -     public function getDebitAmount(): int
 -     {
 -         return $this->debitAmount;
 -     }
 - 
 -     /**
 -      * Returns credit amount in cents as integer: e.g. 100000
 -      */
 -     public function getCreditAmount(): int
 -     {
 -         return $this->creditAmount;
 -     }
 - 
 -     /**
 -      * Expects debit amount in cents as string integer: e.g. 100000
 -      *
 -      * Returns formatted amount: e.g. $1,000.00 or €1.000,00
 -      */
 -     public function getFormattedDebitAmount(): string
 -     {
 -         return $this->formatMoney($this->getDebitAmount());
 -     }
 - 
 -     /**
 -      * Expects credit amount in cents as integer: e.g. 100000
 -      *
 -      * Returns formatted amount: e.g. $1,000.00 or €1.000,00
 -      */
 -     public function getFormattedCreditAmount(): string
 -     {
 -         return $this->formatMoney($this->getCreditAmount());
 -     }
 - 
 -     /**
 -      * Returns balance difference in cents as integer: e.g. 100000
 -      */
 -     public function getBalanceDifference(): int
 -     {
 -         return $this->getDebitAmount() - $this->getCreditAmount();
 -     }
 - 
 -     /**
 -      * Returns formatted balance difference: e.g. $1,000.00 or €1.000,00
 -      */
 -     public function getFormattedBalanceDifference(): string
 -     {
 -         $absoluteDifference = abs($this->getBalanceDifference());
 - 
 -         return $this->formatMoney($absoluteDifference);
 -     }
 - 
 -     /**
 -      * Returns boolean indicating whether the journal entry is balanced
 -      * using the debit and credit integer amounts
 -      */
 -     public function isJournalEntryBalanced(): bool
 -     {
 -         return $this->getDebitAmount() === $this->getCreditAmount();
 -     }
 - 
 -     /**
 -      * Resets debit and credit amounts to '0.00'
 -      */
 -     public function resetJournalEntryAmounts(): void
 -     {
 -         $this->debitAmount = 0;
 -         $this->creditAmount = 0;
 -     }
 - 
 -     public function adjustJournalEntryAmountsForTypeChange(JournalEntryType $newType, JournalEntryType $oldType, ?string $amount): void
 -     {
 -         if ($newType === $oldType) {
 -             return;
 -         }
 - 
 -         $entries = $this instanceof Action
 -             ? ($this->getLivewire()->mountedTableActionsData[0]['journalEntries'] ?? [])
 -             : ($this->getLivewire()->mountedActionsData[0]['journalEntries'] ?? []);
 - 
 -         // Reset the totals
 -         $this->debitAmount = 0;
 -         $this->creditAmount = 0;
 - 
 -         // Recalculate totals from all entries
 -         foreach ($entries as $entry) {
 -             if (empty($entry['type']) || empty($entry['amount'])) {
 -                 continue;
 -             }
 - 
 -             $entryType = JournalEntryType::parse($entry['type']);
 -             $entryAmount = $this->ensureCompleteDecimal($entry['amount']);
 -             $formattedAmount = $this->convertAmountToCents($entryAmount);
 - 
 -             if ($entryType->isDebit()) {
 -                 $this->debitAmount += $formattedAmount;
 -             } else {
 -                 $this->creditAmount += $formattedAmount;
 -             }
 -         }
 -     }
 - 
 -     /**
 -      * Expects the journal entry type,
 -      * the new amount and the old amount as formatted simple amounts: e.g. 1,000.00 or 1.000,00
 -      * It can expect the amounts as partial amounts: e.g. 1,000. or 1.000, (this needs to be handled by this method)
 -      */
 -     public function updateJournalEntryAmount(JournalEntryType $journalEntryType, ?string $newAmount, ?string $oldAmount): void
 -     {
 -         if ($newAmount === $oldAmount) {
 -             return;
 -         }
 - 
 -         $entries = $this instanceof Action
 -             ? ($this->getLivewire()->mountedTableActionsData[0]['journalEntries'] ?? [])
 -             : ($this->getLivewire()->mountedActionsData[0]['journalEntries'] ?? []);
 - 
 -         // Reset the totals
 -         $this->debitAmount = 0;
 -         $this->creditAmount = 0;
 - 
 -         // Recalculate totals from all entries
 -         foreach ($entries as $entry) {
 -             if (empty($entry['type']) || empty($entry['amount'])) {
 -                 continue;
 -             }
 - 
 -             $entryType = JournalEntryType::parse($entry['type']);
 -             $entryAmount = $this->ensureCompleteDecimal($entry['amount']);
 -             $formattedAmount = $this->convertAmountToCents($entryAmount);
 - 
 -             if ($entryType->isDebit()) {
 -                 $this->debitAmount += $formattedAmount;
 -             } else {
 -                 $this->creditAmount += $formattedAmount;
 -             }
 -         }
 -     }
 - 
 -     private function ensureCompleteDecimal(?string $amount): string
 -     {
 -         if ($amount === null) {
 -             return '0';
 -         }
 - 
 -         $currency = currency('USD');
 -         $decimal = $currency->getDecimalMark();
 - 
 -         if (substr($amount, -1) === $decimal) {
 -             return '0';
 -         }
 - 
 -         return $amount;
 -     }
 - 
 -     /**
 -      * Expects formatted simple amount: e.g. 1,000.00 or 1.000,00
 -      *
 -      * Returns sanitized amount in cents as integer: e.g. 100000
 -      */
 -     protected function convertAmountToCents(string $amount): int
 -     {
 -         return CurrencyConverter::convertToCents($amount, 'USD');
 -     }
 - }
 
 
  |