Skip to content

Commit

Permalink
Merge pull request #80 from andrewdwallo/development-3.x
Browse files Browse the repository at this point in the history
Development 3.x
  • Loading branch information
andrewdwallo authored Nov 12, 2024
2 parents 8166db5 + fe175b4 commit 9902962
Show file tree
Hide file tree
Showing 41 changed files with 2,488 additions and 562 deletions.
28 changes: 19 additions & 9 deletions app/Collections/Accounting/JournalEntryCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,40 @@

namespace App\Collections\Accounting;

use App\Enums\Accounting\JournalEntryType;
use App\Models\Accounting\JournalEntry;
use App\Utilities\Currency\CurrencyAccessor;
use App\Utilities\Currency\CurrencyConverter;
use App\ValueObjects\Money;
use Illuminate\Database\Eloquent\Collection;

class JournalEntryCollection extends Collection
{
public function sumDebits(): Money
{
$total = $this->where('type', JournalEntryType::Debit)
->sum(static function (JournalEntry $item) {
return $item->rawValue('amount');
});
$total = $this->reduce(static function ($carry, JournalEntry $item) {
if ($item->type->isDebit()) {
$amountAsInteger = CurrencyConverter::convertToCents($item->amount);

return bcadd($carry, $amountAsInteger, 0);
}

return $carry;
}, 0);

return new Money($total, CurrencyAccessor::getDefaultCurrency());
}

public function sumCredits(): Money
{
$total = $this->where('type', JournalEntryType::Credit)
->sum(static function (JournalEntry $item) {
return $item->rawValue('amount');
});
$total = $this->reduce(static function ($carry, JournalEntry $item) {
if ($item->type->isCredit()) {
$amountAsInteger = CurrencyConverter::convertToCents($item->amount);

return bcadd($carry, $amountAsInteger, 0);
}

return $carry;
}, 0);

return new Money($total, CurrencyAccessor::getDefaultCurrency());
}
Expand Down
4 changes: 4 additions & 0 deletions app/Contracts/ExportableReport.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@ public function getColumns(): array;
public function getPdfView(): string;

public function getAlignmentClass(string $columnName): string;

public function getStartDate(): ?string;

public function getEndDate(): ?string;
}
10 changes: 10 additions & 0 deletions app/DTO/CashFlowOverviewDTO.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace App\DTO;

class CashFlowOverviewDTO
{
public function __construct(
public array $categories,
) {}
}
5 changes: 5 additions & 0 deletions app/DTO/ReportDTO.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace App\DTO;

use Illuminate\Support\Carbon;

class ReportDTO
{
public function __construct(
Expand All @@ -12,5 +14,8 @@ public function __construct(
public ?AccountBalanceDTO $overallTotal = null,
public array $fields = [],
public ?string $reportType = null,
public ?CashFlowOverviewDTO $overview = null,
public ?Carbon $startDate = null,
public ?Carbon $endDate = null,
) {}
}
55 changes: 55 additions & 0 deletions app/Enums/Accounting/AccountType.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,59 @@ public function isUncategorized(): bool
default => false,
};
}

public function isNormalDebitBalance(): bool
{
return in_array($this, [
self::CurrentAsset,
self::NonCurrentAsset,
self::ContraLiability,
self::ContraEquity,
self::ContraRevenue,
self::OperatingExpense,
self::NonOperatingExpense,
self::UncategorizedExpense,
], true);
}

public function isNormalCreditBalance(): bool
{
return ! $this->isNormalDebitBalance();
}

/**
* Determines if the account is a nominal account.
*
* In accounting, nominal accounts are temporary accounts that are closed at the end of each accounting period,
* with their net balances transferred to Retained Earnings (a real account).
*/
public function isNominal(): bool
{
return in_array($this->getCategory(), [
AccountCategory::Revenue,
AccountCategory::Expense,
], true);
}

/**
* Determines if the account is a real account.
*
* In accounting, assets, liabilities, and equity are real accounts which are permanent accounts that retain their balances across accounting periods.
* They are not closed at the end of each accounting period.
*/
public function isReal(): bool
{
return ! $this->isNominal();
}

public function isContra(): bool
{
return in_array($this, [
self::ContraAsset,
self::ContraLiability,
self::ContraEquity,
self::ContraRevenue,
self::ContraExpense,
], true);
}
}
3 changes: 2 additions & 1 deletion app/Filament/Company/Pages/Reports.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use App\Filament\Company\Pages\Reports\AccountBalances;
use App\Filament\Company\Pages\Reports\AccountTransactions;
use App\Filament\Company\Pages\Reports\BalanceSheet;
use App\Filament\Company\Pages\Reports\CashFlowStatement;
use App\Filament\Company\Pages\Reports\IncomeStatement;
use App\Filament\Company\Pages\Reports\TrialBalance;
use App\Infolists\Components\ReportEntry;
Expand Down Expand Up @@ -49,7 +50,7 @@ public function reportsInfolist(Infolist $infolist): Infolist
->description('Shows cash inflows and outflows over a specific period of time.')
->icon('heroicon-o-document-currency-dollar')
->iconColor(Color::Cyan)
->url('#'),
->url(CashFlowStatement::getUrl()),
]),
Section::make('Detailed Reports')
->aside()
Expand Down
18 changes: 9 additions & 9 deletions app/Filament/Company/Pages/Reports/AccountBalances.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,30 +38,30 @@ public function getTable(): array
{
return [
Column::make('account_code')
->label('Account Code')
->toggleable()
->alignment(Alignment::Center),
->label('ACCOUNT CODE')
->toggleable(isToggledHiddenByDefault: true)
->alignment(Alignment::Left),
Column::make('account_name')
->label('Account')
->label('ACCOUNT')
->alignment(Alignment::Left),
Column::make('starting_balance')
->label('Starting Balance')
->label('STARTING BALANCE')
->toggleable()
->alignment(Alignment::Right),
Column::make('debit_balance')
->label('Debit')
->label('DEBIT')
->toggleable()
->alignment(Alignment::Right),
Column::make('credit_balance')
->label('Credit')
->label('CREDIT')
->toggleable()
->alignment(Alignment::Right),
Column::make('net_movement')
->label('Net Movement')
->label('NET MOVEMENT')
->toggleable()
->alignment(Alignment::Right),
Column::make('ending_balance')
->label('Ending Balance')
->label('ENDING BALANCE')
->toggleable()
->alignment(Alignment::Right),
];
Expand Down
36 changes: 26 additions & 10 deletions app/Filament/Company/Pages/Reports/AccountTransactions.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use App\DTO\ReportDTO;
use App\Filament\Company\Pages\Accounting\Transactions;
use App\Models\Accounting\Account;
use App\Models\Accounting\JournalEntry;
use App\Services\ExportService;
use App\Services\ReportService;
use App\Support\Column;
Expand All @@ -18,6 +19,7 @@
use Filament\Tables\Actions\Action;
use Guava\FilamentClusters\Forms\Cluster;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection;
use Symfony\Component\HttpFoundation\StreamedResponse;

Expand Down Expand Up @@ -58,20 +60,20 @@ public function getTable(): array
{
return [
Column::make('date')
->label('Date')
->label('DATE')
->markAsDate()
->alignment(Alignment::Left),
Column::make('description')
->label('Description')
->label('DESCRIPTION')
->alignment(Alignment::Left),
Column::make('debit')
->label('Debit')
->label('DEBIT')
->alignment(Alignment::Right),
Column::make('credit')
->label('Credit')
->label('CREDIT')
->alignment(Alignment::Right),
Column::make('balance')
->label('Running Balance')
->label('RUNNING BALANCE')
->alignment(Alignment::Right),
];
}
Expand Down Expand Up @@ -162,12 +164,26 @@ public function getEmptyStateActions(): array
];
}

public function tableHasEmptyState(): bool
public function hasNoTransactionsForSelectedAccount(): bool
{
if ($this->report) {
return empty($this->report->getCategories());
} else {
return true;
$query = JournalEntry::query();
$selectedAccountId = $this->getFilterState('selectedAccount');

if ($selectedAccountId !== 'all') {
$query->where('account_id', $selectedAccountId);
}

if ($this->getFilterState('startDate') && $this->getFilterState('endDate')) {
$query->whereHas('transaction', function (Builder $query) {
$query->whereBetween('posted_at', [$this->getFormattedStartDate(), $this->getFormattedEndDate()]);
});
}

return $query->doesntExist();
}

public function tableHasEmptyState(): bool
{
return $this->hasNoTransactionsForSelectedAccount();
}
}
10 changes: 5 additions & 5 deletions app/Filament/Company/Pages/Reports/BalanceSheet.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ public function getTable(): array
{
return [
Column::make('account_code')
->label('Account Code')
->toggleable()
->alignment(Alignment::Center),
->label('ACCOUNT CODE')
->toggleable(isToggledHiddenByDefault: true)
->alignment(Alignment::Left),
Column::make('account_name')
->label('Account')
->label('ACCOUNTS')
->alignment(Alignment::Left),
Column::make('ending_balance')
->label('Amount')
->label($this->getDisplayAsOfDate())
->alignment(Alignment::Right),
];
}
Expand Down
23 changes: 23 additions & 0 deletions app/Filament/Company/Pages/Reports/BaseReportPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,29 @@ public function getFormattedAsOfDate(): string
return Carbon::parse($this->getFilterState('asOfDate'))->endOfDay()->toDateTimeString();
}

public function getDisplayAsOfDate(): string
{
return Carbon::parse($this->getFilterState('asOfDate'))->toDefaultDateFormat();
}

public function getDisplayStartDate(): string
{
return Carbon::parse($this->getFilterState('startDate'))->toDefaultDateFormat();
}

public function getDisplayEndDate(): string
{
return Carbon::parse($this->getFilterState('endDate'))->toDefaultDateFormat();
}

public function getDisplayDateRange(): string
{
$startDate = Carbon::parse($this->getFilterState('startDate'));
$endDate = Carbon::parse($this->getFilterState('endDate'));

return $startDate->toDefaultDateFormat() . ' - ' . $endDate->toDefaultDateFormat();
}

protected function getHeaderActions(): array
{
return [
Expand Down
Loading

0 comments on commit 9902962

Please sign in to comment.