Skip to content

Commit

Permalink
Merge pull request #101 from andrewdwallo/development-3.x
Browse files Browse the repository at this point in the history
Development 3.x
  • Loading branch information
andrewdwallo authored Jan 30, 2025
2 parents 85b6422 + 955adda commit b183b8c
Show file tree
Hide file tree
Showing 83 changed files with 3,221 additions and 2,553 deletions.
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@



This repo is currently a work in progress — PRs and issues welcome!
A Laravel and Filament-powered accounting platform, crafting a modern and automated solution for financial management.

# Getting started

Expand Down Expand Up @@ -203,7 +203,8 @@ public static function getAllLanguages(): array

## Plaid Integration

To integrate [Plaid](https://plaid.com/) with your application for enhanced financial data connectivity, you must first create an account with Plaid and obtain your credentials. Set your credentials in the `.env` file as follows:
To integrate [Plaid](https://plaid.com/) with your application for enhanced financial data connectivity, you must first
create an account with Plaid and obtain your credentials. Set your credentials in the `.env` file as follows:

```env
PLAID_CLIENT_ID=your-client-id
Expand All @@ -212,9 +213,12 @@ PLAID_ENVIRONMENT=sandbox # Can be sandbox, development, or production
PLAID_WEBHOOK_URL=https://my-static-domain.ngrok-free.app/api/plaid/webhook # Must have /api/plaid/webhook appended
```

The `PLAID_WEBHOOK_URL` is essential as it enables your application to receive real-time updates on transactions from connected bank accounts. This webhook URL must contain a static domain, which can be obtained from services like ngrok that offer a free static domain upon signup. Alternatively, you may use any other service that provides a static domain.
The `PLAID_WEBHOOK_URL` is essential as it enables your application to receive real-time updates on transactions from
connected bank accounts. This webhook URL must contain a static domain, which can be obtained from services like ngrok
that offer a free static domain upon signup. Alternatively, you may use any other service that provides a static domain.

After integrating Plaid, you can connect your account on the "Connected Accounts" page and link your financial institution. Before importing transactions, ensure to run the following command to process the queued transactions:
After integrating Plaid, you can connect your account on the "Connected Accounts" page and link your financial
institution. Before importing transactions, ensure to run the following command to process the queued transactions:

```bash
php artisan queue:work --queue=transactions
Expand Down Expand Up @@ -243,7 +247,6 @@ The testing process automatically handles refreshing and seeding the test databa
migration is required. For more information on how to write and run tests using
Pest, refer to the official documentation: [Pest Documentation](https://pestphp.com/docs).
## Dependencies
- [filamentphp/filament](https://github.com/filamentphp/filament) - A collection of beautiful full-stack components
Expand All @@ -254,7 +257,8 @@ Pest, refer to the official documentation: [Pest Documentation](https://pestphp.
- [akaunting/laravel-money](https://github.com/akaunting/laravel-money) - Currency formatting and conversion package for
Laravel
- [squirephp/squire](https://github.com/squirephp/squire) - A library of static Eloquent models for common fixture data
- [awcodes/filament-table-repeater](https://github.com/awcodes/filament-table-repeater) - A modified version of the Filament Forms Repeater to display it as a table.
- [awcodes/filament-table-repeater](https://github.com/awcodes/filament-table-repeater) - A modified version of the
Filament Forms Repeater to display it as a table.
***Note*** : It is recommended to read the documentation for all dependencies to get yourself familiar with how the
application works.
Expand Down
4 changes: 2 additions & 2 deletions app/Concerns/NotifiesOnDelete.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public static function notifyBeforeDelete(Model $record, string $reason): void

Notification::make()
->danger()
->title(translate('Action Denied'))
->title(translate('Action denied'))
->body(translate(':Name cannot be deleted because it is :reason. Please update settings before deletion.', [
'Name' => $record->getAttribute('name'),
'reason' => $reason,
Expand All @@ -37,7 +37,7 @@ public static function notifyBeforeDeleteMultiple(Collection $records, string $r

Notification::make()
->danger()
->title(translate('Action Denied'))
->title(translate('Action denied'))
->body($message)
->persistent()
->send();
Expand Down
8 changes: 8 additions & 0 deletions app/Contracts/MoneyFormattableDTO.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace App\Contracts;

interface MoneyFormattableDTO
{
public static function fromArray(array $balances): static;
}
15 changes: 14 additions & 1 deletion app/DTO/AccountBalanceDTO.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace App\DTO;

class AccountBalanceDTO
use App\Contracts\MoneyFormattableDTO;

class AccountBalanceDTO implements MoneyFormattableDTO
{
public function __construct(
public ?string $startingBalance,
Expand All @@ -11,4 +13,15 @@ public function __construct(
public ?string $netMovement,
public ?string $endingBalance,
) {}

public static function fromArray(array $balances): static
{
return new static(
startingBalance: $balances['starting_balance'] ?? null,
debitBalance: $balances['debit_balance'] ?? null,
creditBalance: $balances['credit_balance'] ?? null,
netMovement: $balances['net_movement'] ?? null,
endingBalance: $balances['ending_balance'] ?? null,
);
}
}
38 changes: 38 additions & 0 deletions app/DTO/AgingBucketDTO.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace App\DTO;

use App\Contracts\MoneyFormattableDTO;

readonly class AgingBucketDTO implements MoneyFormattableDTO
{
/**
* @param array<string, string> $periods
*/
public function __construct(
public string $current,
public array $periods,
public string $overPeriods,
public string $total,
) {}

public static function fromArray(array $balances): static
{
$periods = [];

// Extract all period balances
foreach ($balances as $key => $value) {
if (str_starts_with($key, 'period_')) {
$periods[$key] = $value;
unset($balances[$key]);
}
}

return new static(
current: $balances['current'],
periods: $periods,
overPeriods: $balances['over_periods'],
total: $balances['total'],
);
}
}
12 changes: 12 additions & 0 deletions app/DTO/ClientReportDTO.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace App\DTO;

readonly class ClientReportDTO
{
public function __construct(
public string $clientName,
public string $clientId,
public AgingBucketDTO $aging,
) {}
}
12 changes: 12 additions & 0 deletions app/DTO/EntityReportDTO.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace App\DTO;

readonly class EntityReportDTO
{
public function __construct(
public string $name,
public string $id,
public AgingBucketDTO $aging,
) {}
}
1 change: 1 addition & 0 deletions app/DTO/ReportDTO.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public function __construct(
*/
public array $categories,
public ?AccountBalanceDTO $overallTotal = null,
public ?AgingBucketDTO $agingSummary = null,
public array $fields = [],
public ?string $reportType = null,
public ?CashFlowOverviewDTO $overview = null,
Expand Down
12 changes: 12 additions & 0 deletions app/DTO/VendorReportDTO.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace App\DTO;

readonly class VendorReportDTO
{
public function __construct(
public string $vendorName,
public string $vendorId,
public AgingBucketDTO $aging,
) {}
}
24 changes: 24 additions & 0 deletions app/Enums/Accounting/DocumentEntityType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace App\Enums\Accounting;

use Filament\Support\Contracts\HasLabel;

enum DocumentEntityType: string implements HasLabel
{
case Client = 'client';
case Vendor = 'vendor';

public function getLabel(): ?string
{
return $this->name;
}

public function getReportTitle(): string
{
return match ($this) {
self::Client => 'Accounts Receivable Aging',
self::Vendor => 'Accounts Payable Aging',
};
}
}
23 changes: 0 additions & 23 deletions app/Enums/Setting/RecordsPerPage.php

This file was deleted.

18 changes: 0 additions & 18 deletions app/Enums/Setting/TableSortDirection.php

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,11 @@ protected function getTimezoneChangeNotification(): Notification
{
return Notification::make()
->info()
->title('Timezone Update Required')
->title('Timezone update required')
->body('You have changed your country or state. Please update your timezone to ensure accurate date and time information.')
->actions([
\Filament\Notifications\Actions\Action::make('updateTimezone')
->label('Update Timezone')
->label('Update timezone')
->url(Localization::getUrl()),
])
->persistent()
Expand Down Expand Up @@ -187,7 +187,7 @@ protected function getNeedsAddressCompletionAlert(): Component
{
return Banner::make('needsAddressCompletion')
->warning()
->title('Address Information Incomplete')
->title('Address information incomplete')
->description('Please complete the required address information for proper business operations.')
->visible(fn (CompanyProfileModel $record) => $record->address->isIncomplete())
->columnSpanFull();
Expand Down
10 changes: 5 additions & 5 deletions app/Filament/Company/Clusters/Settings/Pages/Invoice.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ protected function getContentSection(): Component
->localizeLabel()
->nullable(),
Textarea::make('footer')
->localizeLabel('Footer / Notes')
->localizeLabel('Footer')
->nullable(),
])->columns();
}
Expand Down Expand Up @@ -222,7 +222,7 @@ protected function getTemplateSection(): Component
->options(Template::class),
Select::make('item_name.option')
->softRequired()
->localizeLabel('Item Name')
->localizeLabel('Item name')
->options(InvoiceModel::getAvailableItemNameOptions())
->afterStateUpdated(static function (Get $get, Set $set, $state, $old) {
if ($state !== 'other' && $old === 'other' && filled($get('item_name.custom'))) {
Expand All @@ -240,7 +240,7 @@ protected function getTemplateSection(): Component
->nullable(),
Select::make('unit_name.option')
->softRequired()
->localizeLabel('Unit Name')
->localizeLabel('Unit name')
->options(InvoiceModel::getAvailableUnitNameOptions())
->afterStateUpdated(static function (Get $get, Set $set, $state, $old) {
if ($state !== 'other' && $old === 'other' && filled($get('unit_name.custom'))) {
Expand All @@ -258,7 +258,7 @@ protected function getTemplateSection(): Component
->nullable(),
Select::make('price_name.option')
->softRequired()
->localizeLabel('Price Name')
->localizeLabel('Price name')
->options(InvoiceModel::getAvailablePriceNameOptions())
->afterStateUpdated(static function (Get $get, Set $set, $state, $old) {
if ($state !== 'other' && $old === 'other' && filled($get('price_name.custom'))) {
Expand All @@ -276,7 +276,7 @@ protected function getTemplateSection(): Component
->nullable(),
Select::make('amount_name.option')
->softRequired()
->localizeLabel('Amount Name')
->localizeLabel('Amount name')
->options(InvoiceModel::getAvailableAmountNameOptions())
->afterStateUpdated(static function (Get $get, Set $set, $state, $old) {
if ($state !== 'other' && $old === 'other' && filled($get('amount_name.custom'))) {
Expand Down
10 changes: 5 additions & 5 deletions app/Filament/Company/Clusters/Settings/Pages/Localization.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,9 @@ protected function getDateAndTimeSection(): Component

protected function getFinancialAndFiscalSection(): Component
{
$beforeNumber = translate('Before Number');
$afterNumber = translate('After Number');
$selectPosition = translate('Select Position');
$beforeNumber = translate('Before number');
$afterNumber = translate('After number');
$selectPosition = translate('Select position');

return Section::make('Financial & Fiscal')
->schema([
Expand All @@ -169,7 +169,7 @@ protected function getFinancialAndFiscalSection(): Component
->options(NumberFormat::class),
Select::make('percent_first')
->softRequired()
->localizeLabel('Percent Position')
->localizeLabel('Percent position')
->boolean($beforeNumber, $afterNumber, $selectPosition),
Group::make()
->schema([
Expand Down Expand Up @@ -197,7 +197,7 @@ protected function getFinancialAndFiscalSection(): Component
->columnSpan(2)
->required()
->markAsRequired(false)
->label('Fiscal Year End'),
->label('Fiscal year end'),
])->columns(3),
])->columns();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class CurrencyResource extends Resource

protected static ?string $model = CurrencyModel::class;

protected static ?string $modelLabel = 'Currency';
protected static ?string $modelLabel = 'currency';

protected static ?string $cluster = Settings::class;

Expand Down Expand Up @@ -88,11 +88,11 @@ public static function form(Form $form): Form
->maxLength(5)
->required(),
Forms\Components\Select::make('symbol_first')
->localizeLabel('Symbol Position')
->boolean(translate('Before Amount'), translate('After Amount'), translate('Select a symbol position'))
->localizeLabel('Symbol position')
->boolean(translate('Before amount'), translate('After amount'), translate('Select a symbol position'))
->required(),
Forms\Components\TextInput::make('decimal_mark')
->localizeLabel('Decimal Separator')
->localizeLabel('Decimal separator')
->maxLength(1)
->rule(static function (Forms\Get $get): Closure {
return static function ($attribute, $value, Closure $fail) use ($get) {
Expand Down Expand Up @@ -126,8 +126,8 @@ public static function table(Table $table): Table
->weight(FontWeight::Medium)
->icon(static fn (CurrencyModel $record) => $record->isEnabled() ? 'heroicon-o-lock-closed' : null)
->tooltip(static function (CurrencyModel $record) {
$tooltipMessage = translate('Default :Record', [
'Record' => static::getModelLabel(),
$tooltipMessage = translate('Default :record', [
'record' => static::getModelLabel(),
]);

return $record->isEnabled() ? $tooltipMessage : null;
Expand Down
Loading

0 comments on commit b183b8c

Please sign in to comment.