Compare commits
56 Commits
950e5613e6
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
993d096283 | ||
|
|
08817af0ca | ||
|
|
afb7cefdda | ||
|
|
08fe589ad6 | ||
|
|
1937e26251 | ||
|
|
1dbc32722a | ||
|
|
a4124ceaa9 | ||
|
|
8b23298196 | ||
|
|
3c251e9c3a | ||
|
|
f635dabbc5 | ||
|
|
e0f459f9ea | ||
|
|
8c414e7e70 | ||
|
|
49226f8aa1 | ||
|
|
77ed347e36 | ||
|
|
4ade74421c | ||
|
|
8e3913bda8 | ||
|
|
fea727daf4 | ||
|
|
cea2749252 | ||
|
|
5992b28eb5 | ||
|
|
e6acea80a0 | ||
|
|
02dbea230c | ||
|
|
07748a7025 | ||
|
|
55d2f61d09 | ||
|
|
aef00b405a | ||
|
|
ac41090ed3 | ||
|
|
ba9c80b9b4 | ||
|
|
618f826e1e | ||
|
|
baf68078a7 | ||
|
|
87fd507618 | ||
|
|
a697100103 | ||
|
|
dd188724be | ||
| 95301dc1d8 | |||
|
|
673a6ce166 | ||
|
|
e57e6d3413 | ||
|
|
feba3f1464 | ||
|
|
6eeedbeeb0 | ||
|
|
b95f23f223 | ||
|
|
90c92650b7 | ||
|
|
2bf12aa4e8 | ||
|
|
df66727379 | ||
| 1d6238e9cb | |||
|
|
d8077f200a | ||
|
|
7899ed75ea | ||
|
|
5d427cdea4 | ||
| 2644be0505 | |||
|
|
9ddb71f03d | ||
| eadcc0b3d7 | |||
|
|
8c6fa6cb08 | ||
|
|
7bcfaff311 | ||
|
|
e04689acca | ||
| 3cf5f6db6a | |||
|
|
f5c8ec04ad | ||
| 7bbe6e2d2a | |||
|
|
fbc01bf1a4 | ||
|
|
ff07f6f810 | ||
|
|
2bd8e99f64 |
11
.devdbrc
Normal file
11
.devdbrc
Normal file
@@ -0,0 +1,11 @@
|
||||
[
|
||||
{
|
||||
"name": "My test MySQL database",
|
||||
"type": "mysql",
|
||||
"host": "192.168.100.105",
|
||||
"port": "3306",
|
||||
"username": "root",
|
||||
"password": "root",
|
||||
"database": "mkm_admin"
|
||||
}
|
||||
]
|
||||
17
.dockerignore
Normal file
17
.dockerignore
Normal file
@@ -0,0 +1,17 @@
|
||||
.git
|
||||
.github
|
||||
.circleci
|
||||
.env
|
||||
.env.local
|
||||
node_modules
|
||||
vendor
|
||||
storage/logs/*
|
||||
storage/framework/cache/*
|
||||
bootstrap/cache/*
|
||||
.phpunit.result.cache
|
||||
.idea
|
||||
.vscode
|
||||
.devcontainer
|
||||
docker-compose.yml
|
||||
Makefile
|
||||
k8s/
|
||||
19
.env.example
19
.env.example
@@ -1,9 +1,9 @@
|
||||
APP_NAME=Laravel
|
||||
APP_NAME='MKM Tax Services'
|
||||
APP_ENV=local
|
||||
APP_KEY=
|
||||
APP_KEY=base64:Tqv7x1T7GGUVfwzcWOwg6fwrp96dkjV4WCgyRYjdyYY=
|
||||
APP_DEBUG=true
|
||||
APP_TIMEZONE=UTC
|
||||
APP_URL=http://localhost
|
||||
APP_URL=http://mkmtaxservices.com.test
|
||||
|
||||
APP_LOCALE=en
|
||||
APP_FALLBACK_LOCALE=en
|
||||
@@ -20,11 +20,14 @@ LOG_DEPRECATIONS_CHANNEL=null
|
||||
LOG_LEVEL=debug
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_HOST=192.168.100.105
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=mkm_admin
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=
|
||||
DB_PASSWORD=root
|
||||
|
||||
DB_QUEUE_TABLE=jobs
|
||||
DB_QUEUE=default
|
||||
|
||||
SESSION_DRIVER=database
|
||||
SESSION_LIFETIME=120
|
||||
@@ -42,12 +45,12 @@ CACHE_PREFIX=
|
||||
MEMCACHED_HOST=127.0.0.1
|
||||
|
||||
REDIS_CLIENT=phpredis
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_HOST=192.168.100.105
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=log
|
||||
MAIL_HOST=127.0.0.1
|
||||
MAIL_HOST=192.168.100.105
|
||||
MAIL_PORT=2525
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
@@ -62,3 +65,5 @@ AWS_BUCKET=
|
||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
|
||||
VITE_APP_NAME="${APP_NAME}"
|
||||
|
||||
OCTANE_SERVER=frankenphp
|
||||
|
||||
40
Dockerfile
Normal file
40
Dockerfile
Normal file
@@ -0,0 +1,40 @@
|
||||
FROM docker.io/alpine:3.21
|
||||
|
||||
RUN apk add --no-cache \
|
||||
php84 \
|
||||
php84-fpm \
|
||||
php84-pdo_mysql \
|
||||
php84-mbstring \
|
||||
php84-exif \
|
||||
php84-pcntl \
|
||||
php84-bcmath \
|
||||
php84-gd \
|
||||
php84-zip \
|
||||
php84-intl \
|
||||
php84-curl \
|
||||
php84-tokenizer \
|
||||
php84-xml \
|
||||
php84-xmlwriter \
|
||||
php84-xmlreader \
|
||||
php84-dom \
|
||||
php84-session \
|
||||
php84-fileinfo \
|
||||
php84-openssl \
|
||||
git \
|
||||
curl
|
||||
|
||||
RUN ln -sf /usr/bin/php84 /usr/bin/php
|
||||
|
||||
WORKDIR /var/www
|
||||
|
||||
# Copy the application files
|
||||
COPY --chown=root:root . .
|
||||
|
||||
COPY --from=docker.io/composer:latest /usr/bin/composer /usr/bin/composer
|
||||
|
||||
RUN rm -rf .circleci .github 2>/dev/null || true && \
|
||||
chmod -R 775 storage bootstrap/cache 2>/dev/null || true
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
CMD ["php", "artisan", "serve", "--host=0.0.0.0", "--port=8000"]
|
||||
21
Makefile
Normal file
21
Makefile
Normal file
@@ -0,0 +1,21 @@
|
||||
IMG := mkm-admin
|
||||
|
||||
build:
|
||||
@echo "Building image from project root..."
|
||||
podman build -t $(IMG) .
|
||||
|
||||
deploy: build
|
||||
@echo "Cleaning up existing deployment if any..."
|
||||
-podman kube down k8s/deployment.yaml >/dev/null 2>&1
|
||||
@echo "Generating merged deployment with ConfigMap..."
|
||||
@sudo kubectl create configmap mkm-admin-config --from-env-file=.env --dry-run=client -o yaml > /tmp/merged_deployment.yaml
|
||||
@echo "---" >> /tmp/merged_deployment.yaml
|
||||
@cat k8s/deployment.yaml >> /tmp/merged_deployment.yaml
|
||||
@echo "Deploying via podman kube play..."
|
||||
podman kube play /tmp/merged_deployment.yaml
|
||||
@rm -f /tmp/merged_deployment.yaml
|
||||
|
||||
stop:
|
||||
-podman kube down k8s/deployment.yaml >/dev/null 2>&1
|
||||
|
||||
.PHONY: build deploy stop
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
namespace App\Actions;
|
||||
|
||||
use Closure;
|
||||
use Spatie\LaravelData\Data;
|
||||
|
||||
abstract class BaseAction
|
||||
{
|
||||
abstract public function __invoke(Data $payload, \Closure $next) ;
|
||||
abstract public function __invoke(Data $payload, Closure $next) ;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
namespace App\Actions\Branch;
|
||||
|
||||
use Closure;
|
||||
use Exception;
|
||||
use LogicException;
|
||||
use App\Actions\BaseAction;
|
||||
use App\Commands\Series\CreateSeriesCommand;
|
||||
use App\DataObjects\CreateBranchDTO;
|
||||
@@ -15,7 +18,7 @@ class StoreBranchSeries extends BaseAction
|
||||
private CreateSeriesCommand $createSeriesCommand
|
||||
) {}
|
||||
|
||||
public function __invoke(CreateBranchDTO|Data $payload, \Closure $next)
|
||||
public function __invoke(CreateBranchDTO|Data $payload, Closure $next)
|
||||
{
|
||||
try {
|
||||
$seriesPayload = CreateSeriesDTO::from(['branch_id' => $payload->branch->id, 'series' => $payload->data['series'], 'is_start' => true]);
|
||||
@@ -23,8 +26,8 @@ class StoreBranchSeries extends BaseAction
|
||||
$payload->series = $this->createSeriesCommand->execute($seriesPayload->toArray());
|
||||
|
||||
return $next($payload);
|
||||
} catch (\Exception $exception) {
|
||||
throw new \LogicException('Failed to create branch series', $exception->getMessage());
|
||||
} catch (Exception $exception) {
|
||||
throw new LogicException('Failed to create branch series', $exception->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
55
app/Actions/Sales/CreateSaleAction.php
Normal file
55
app/Actions/Sales/CreateSaleAction.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Sales;
|
||||
|
||||
use Exception;
|
||||
use App\Actions\Transactions\CreateRecordTransactionsAction;
|
||||
use App\Commands\Sales\CreateSaleCommand;
|
||||
use App\Commands\Series\CreateSeriesCommand;
|
||||
use App\Models\Sale;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CreateSaleAction
|
||||
{
|
||||
/**
|
||||
* Create a new class instance.
|
||||
*/
|
||||
public function __construct(
|
||||
private CreateSaleCommand $createSaleCommand,
|
||||
private CreateSeriesCommand $createSeriesCommand,
|
||||
){ }
|
||||
|
||||
public function __invoke(array $data, array $transactions): Sale
|
||||
{
|
||||
$record = $this->createSaleCommand->execute($data);
|
||||
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
//create transactions for the sale
|
||||
app(CreateRecordTransactionsAction::class)($record, $transactions);
|
||||
|
||||
$accountIds = collect($transactions)
|
||||
->pluck('account_id')
|
||||
->filter()
|
||||
->unique()
|
||||
->values()
|
||||
->all();
|
||||
|
||||
//sync accounts to sale
|
||||
app(SyncAccountsAction::class)($record, $accountIds);
|
||||
|
||||
//increment current_series
|
||||
$this->createSeriesCommand->execute([
|
||||
'branch_id' => $record->branch_id,
|
||||
'series' => $record->reference_number,
|
||||
]);
|
||||
|
||||
DB::commit();
|
||||
} catch (Exception $exception) {
|
||||
DB::rollBack();
|
||||
throw new Exception('Failed to save transactions : '.$exception->getMessage());
|
||||
}
|
||||
|
||||
return $record;
|
||||
}
|
||||
}
|
||||
16
app/Actions/Sales/SyncAccountsAction.php
Normal file
16
app/Actions/Sales/SyncAccountsAction.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Sales;
|
||||
|
||||
use App\Models\Sale;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class SyncAccountsAction
|
||||
{
|
||||
public function __invoke(Sale $sale, array $accounts): void
|
||||
{
|
||||
DB::transaction(function () use ($sale, $accounts) {
|
||||
$sale->accounts()->sync($accounts);
|
||||
}, attempts: 2);
|
||||
}
|
||||
}
|
||||
30
app/Actions/Transactions/CreateRecordTransactionsAction.php
Normal file
30
app/Actions/Transactions/CreateRecordTransactionsAction.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Transactions;
|
||||
|
||||
use App\DataObjects\CreateTransactionDTO;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Pipeline;
|
||||
|
||||
class CreateRecordTransactionsAction
|
||||
{
|
||||
public function __invoke(Model $record, array $transactions): void
|
||||
{
|
||||
foreach ($transactions as $transaction) {
|
||||
$tData = [
|
||||
'branch_id' => $record->branch_id,
|
||||
'happened_on' => $record->happened_on,
|
||||
...$transaction,
|
||||
];
|
||||
|
||||
$payload = new CreateTransactionDTO(data: $tData, transactionable: $record);
|
||||
|
||||
Pipeline::send(passable: $payload)->through(
|
||||
[
|
||||
CreateTransactionAction::class,
|
||||
]
|
||||
)->thenReturn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Actions\Transactions;
|
||||
|
||||
use App\Models\Expense;
|
||||
use App\Actions\Balances\CreateBalanceAction;
|
||||
use App\Actions\BaseAction;
|
||||
use App\Actions\Ledgers\CreateLedgerAction;
|
||||
@@ -24,20 +25,26 @@ class CreateTransactionAction extends BaseAction
|
||||
|
||||
$this->cashAccountLedger($payload);
|
||||
|
||||
if ($payload->transaction->discount !== 0) {
|
||||
$this->discountAccountLedger($payload);
|
||||
}
|
||||
|
||||
return $next($payload);
|
||||
}
|
||||
|
||||
public function transactionAccountLedger($payload): void
|
||||
{
|
||||
$branch = $payload->transaction->branch;
|
||||
$isExpense = $payload->transactionable instanceof \App\Models\Expense;
|
||||
$isExpense = $payload->transactionable instanceof Expense;
|
||||
$type = $isExpense ? 'debit' : 'credit';
|
||||
|
||||
$discount = $payload->transaction->discount ?? 0.00;
|
||||
|
||||
if ($branch->isClientVatable) {
|
||||
//create transaction account ledger
|
||||
$ledgerPayload = new CreateLedgerDTO(
|
||||
branch_id: $payload->transactionable->branch_id,
|
||||
amount: $payload->transaction->net_amount ?? 0.00,
|
||||
amount: $payload->transaction->net_amount + $discount ?? 0.00,
|
||||
transaction: $payload->transaction,
|
||||
account: $payload->transaction->account,
|
||||
type: $type,
|
||||
@@ -96,7 +103,7 @@ class CreateTransactionAction extends BaseAction
|
||||
|
||||
public function withHoldingAccountLedger($payload): void
|
||||
{
|
||||
$isExpense = $payload->transactionable instanceof \App\Models\Expense;
|
||||
$isExpense = $payload->transactionable instanceof Expense;
|
||||
$accountName = $isExpense ? 'Payable Withholding Tax' : 'Creditable Withholding Tax';
|
||||
$type = $isExpense ? 'credit' : 'debit';
|
||||
$clientId = $payload->transactionable->branch->client_id;
|
||||
@@ -122,7 +129,7 @@ class CreateTransactionAction extends BaseAction
|
||||
|
||||
public function cashAccountLedger($payload): void
|
||||
{
|
||||
$isExpense = $payload->transactionable instanceof \App\Models\Expense;
|
||||
$isExpense = $payload->transactionable instanceof Expense;
|
||||
$type = $isExpense ? 'credit' : 'debit';
|
||||
$wht = $isExpense ? ($payload->transaction->payable_withholding_tax ?? 0) : ($payload->transaction->creditable_withholding_tax ?? 0);
|
||||
$amount = ($payload->transaction->gross_amount ?? 0) - $wht;
|
||||
@@ -144,4 +151,28 @@ class CreateTransactionAction extends BaseAction
|
||||
$this->ledgerPipe($ledgerPayload);
|
||||
}
|
||||
}
|
||||
|
||||
public function discountAccountLedger($payload): void
|
||||
{
|
||||
$isExpense = $payload->transactionable instanceof Expense;
|
||||
$type = $isExpense ? 'credit' : 'debit';
|
||||
$amount = $payload->transaction->discount ?? 0.00;
|
||||
$clientId = $payload->transactionable->branch->client_id;
|
||||
|
||||
$discountAccount = Account::query()
|
||||
->where('account', 'Sales Discount')
|
||||
->where('client_id', $clientId)
|
||||
->first();
|
||||
|
||||
if ($discountAccount && $amount > 0) {
|
||||
$ledgerPayload = new CreateLedgerDTO(
|
||||
branch_id: $payload->transactionable->branch_id,
|
||||
amount: $amount,
|
||||
transaction: $payload->transaction,
|
||||
account: $discountAccount,
|
||||
type: $type,
|
||||
);
|
||||
$this->ledgerPipe($ledgerPayload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
namespace App\Actions\Transmittal;
|
||||
|
||||
use Closure;
|
||||
use Exception;
|
||||
use LogicException;
|
||||
use App\Actions\BaseAction;
|
||||
use App\Commands\Transmittal\StoreTransmittalCommand;
|
||||
use App\DataObjects\CreateTransmittalDTO;
|
||||
@@ -15,15 +18,15 @@ class CreateTransmittal extends BaseAction
|
||||
private readonly StoreTransmittalCommand $storeTransmittalCommand
|
||||
) {}
|
||||
|
||||
public function __invoke(CreateTransmittalDTO | Data $payload, \Closure $next)
|
||||
public function __invoke(CreateTransmittalDTO | Data $payload, Closure $next)
|
||||
{
|
||||
try {
|
||||
$payload->transmittal = $this->storeTransmittalCommand->execute(Arr::except($payload->data, ['files']));
|
||||
|
||||
return $next($payload);
|
||||
} catch (\Exception $exception)
|
||||
} catch (Exception $exception)
|
||||
{
|
||||
throw new \LogicException('Error creating transmittal: ' . $exception->getMessage());
|
||||
throw new LogicException('Error creating transmittal: ' . $exception->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
namespace App\Actions\Transmittal;
|
||||
|
||||
use Closure;
|
||||
use Exception;
|
||||
use LogicException;
|
||||
use App\Actions\BaseAction;
|
||||
use App\Commands\Transmittal\StoreCommentCommand;
|
||||
use App\Commands\Transmittal\StoreFileCommand;
|
||||
@@ -22,7 +25,7 @@ class CreateTransmittalFiles extends BaseAction
|
||||
private readonly StoreRemarkCommand $storeRemarkCommand
|
||||
) {}
|
||||
|
||||
public function __invoke(CreateTransmittalDTO | Data $payload, \Closure $next)
|
||||
public function __invoke(CreateTransmittalDTO | Data $payload, Closure $next)
|
||||
{
|
||||
try {
|
||||
$files = Arr::only($payload->data, 'files');
|
||||
@@ -55,9 +58,9 @@ class CreateTransmittalFiles extends BaseAction
|
||||
$payload->files = $filesCreated;
|
||||
|
||||
return $next($payload);
|
||||
} catch (\Exception $exception)
|
||||
} catch (Exception $exception)
|
||||
{
|
||||
throw new \LogicException('Error creating transmittal files: ' . $exception->getMessage());
|
||||
throw new LogicException('Error creating transmittal files: ' . $exception->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
64
app/Commands/Clients/GenerateBaseAccountCommand.php
Normal file
64
app/Commands/Clients/GenerateBaseAccountCommand.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Commands\Clients;
|
||||
|
||||
use App\Commands\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class GenerateBaseAccountCommand
|
||||
{
|
||||
/**
|
||||
* Create a new class instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the command.
|
||||
*/
|
||||
public function execute($client): void
|
||||
{
|
||||
DB::transaction(function () use ($client) {
|
||||
$client->accounts()->createMany([
|
||||
[
|
||||
'account_type_id' => 1,
|
||||
'account' => 'Cash',
|
||||
'normal_balance' => 'debit',
|
||||
],
|
||||
[
|
||||
'account_type_id' => 1,
|
||||
'account' => 'Input Tax',
|
||||
'normal_balance' => 'debit',
|
||||
],
|
||||
[
|
||||
'account_type_id' => 1,
|
||||
'account' => 'Creditable Withholding Tax',
|
||||
'normal_balance' => 'debit',
|
||||
],
|
||||
[
|
||||
'account_type_id' => 2,
|
||||
'account' => 'Output Tax',
|
||||
'normal_balance' => 'credit',
|
||||
],
|
||||
[
|
||||
'account_type_id' => 2,
|
||||
'account' => 'Payable Withholding Tax',
|
||||
'normal_balance' => 'credit',
|
||||
],
|
||||
[
|
||||
'account_type_id' => 5,
|
||||
'account' => 'Vat Exempt Revenue',
|
||||
'normal_balance' => 'credit',
|
||||
],
|
||||
[
|
||||
'account_type_id' => 4,
|
||||
'account' => 'Sales Discount',
|
||||
'normal_balance' => 'debit',
|
||||
],
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
28
app/Commands/Sales/CreateSaleCommand.php
Normal file
28
app/Commands/Sales/CreateSaleCommand.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Commands\Sales;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use App\Commands\Command;
|
||||
use App\DataObjects\CreateSaleDTO;
|
||||
use App\Models\Sale;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CreateSaleCommand implements Command
|
||||
{
|
||||
public function execute(array $data): Sale
|
||||
{
|
||||
return DB::transaction(function () use ($data, &$sale) {
|
||||
$tData = new CreateSaleDTO(
|
||||
reference_number: $data['current_series'],
|
||||
happened_on: Carbon::parse($data['happened_on']),
|
||||
branch_id: $data['branch_id'],
|
||||
user_id: Auth::user()->id,
|
||||
);
|
||||
|
||||
return Sale::create($tData->toArray());
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
29
app/DataObjects/CreateSaleDTO.php
Normal file
29
app/DataObjects/CreateSaleDTO.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\DataObjects;
|
||||
|
||||
use Carbon\Carbon;
|
||||
|
||||
readonly class CreateSaleDTO
|
||||
{
|
||||
/**
|
||||
* Create a new class instance.
|
||||
*/
|
||||
public function __construct(
|
||||
protected string $reference_number,
|
||||
protected Carbon $happened_on,
|
||||
protected int $branch_id,
|
||||
protected int $user_id,
|
||||
)
|
||||
{}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'reference_number' => $this->reference_number,
|
||||
'happened_on' => $this->happened_on,
|
||||
'branch_id' => $this->branch_id,
|
||||
'user_id' => $this->user_id,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exports;
|
||||
|
||||
use App\Models\Transmittal;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Maatwebsite\Excel\Concerns\Exportable;
|
||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||
use Maatwebsite\Excel\Concerns\WithDefaultStyles;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use PhpOffice\PhpSpreadsheet\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Style;
|
||||
|
||||
class TransmittalsExport implements FromCollection, ShouldAutoSize, ShouldQueue, WithDefaultStyles, WithHeadings, WithMapping
|
||||
{
|
||||
use Exportable, Queueable, SerializesModels;
|
||||
|
||||
public function __construct(
|
||||
private readonly array $id
|
||||
) {}
|
||||
|
||||
public function view(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$transmittals = Transmittal::query()->with(['client', 'branch', 'files.notes', 'files.remarks'])->whereIn('id', Arr::flatten($this->id))->get();
|
||||
|
||||
return View::make('transmittal.export.transmittal-export-table')->with(['transmittals' => $transmittals]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function defaultStyles(Style $defaultStyle)
|
||||
{
|
||||
return $defaultStyle->applyFromArray([
|
||||
'alignment' => [
|
||||
'horizontal' => Alignment::HORIZONTAL_CENTER,
|
||||
'vertical' => Alignment::VERTICAL_CENTER,
|
||||
],
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
return [
|
||||
'series',
|
||||
'files',
|
||||
'notes',
|
||||
'remarks',
|
||||
];
|
||||
}
|
||||
|
||||
public function collection()
|
||||
{
|
||||
$transmittals = Transmittal::query()->with(['client', 'branch', 'files.notes', 'files.remarks'])
|
||||
->withCount(['files', 'notes', 'remarks'])->with(['files' => function ($files) {
|
||||
$files->withCount(['notes', 'remarks']);
|
||||
}])
|
||||
->whereIn('id', Arr::flatten($this->id))->get();
|
||||
|
||||
return $transmittals;
|
||||
}
|
||||
|
||||
public function map($transmittal): array
|
||||
{
|
||||
|
||||
$data = [];
|
||||
|
||||
$firstFile = $transmittal->files->first();
|
||||
|
||||
$data[] = [
|
||||
$transmittal->series,
|
||||
$firstFile?->description,
|
||||
$firstFile->notes->first()?->comment,
|
||||
$firstFile->remarks->first()?->remark,
|
||||
];
|
||||
|
||||
//iterate comments and remarks for first file
|
||||
$notes = $firstFile->notes->pluck('comment');
|
||||
$remarks = $firstFile->remarks->pluck('remark');
|
||||
|
||||
$fileNoteCount = count($notes);
|
||||
$fileRemarkCount = count($remarks);
|
||||
|
||||
$fileRowCount = $fileNoteCount;
|
||||
if ($fileRemarkCount > $fileNoteCount) {
|
||||
$fileRowCount = $fileRemarkCount;
|
||||
}
|
||||
|
||||
for ($i = 1; $i < $fileRowCount; $i++) {
|
||||
$data[] = [
|
||||
'',
|
||||
'',
|
||||
$notes[$i] ?? '',
|
||||
$remarks[$i] ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
//file iteration except for first file
|
||||
$fileRowCounter = 0;
|
||||
foreach ($transmittal->files as $file) {
|
||||
$notes = $file->notes->pluck('comment');
|
||||
$remarks = $file->remarks->pluck('remark');
|
||||
|
||||
$fileNoteCount = count($notes);
|
||||
$fileRemarkCount = count($remarks);
|
||||
|
||||
$fileRowCount = $fileNoteCount;
|
||||
if ($fileRemarkCount > $fileNoteCount) {
|
||||
$fileRowCount = $fileRemarkCount;
|
||||
}
|
||||
|
||||
if ($fileRowCounter != 0) {
|
||||
$data[] = [
|
||||
'',
|
||||
$file->description,
|
||||
$file->notes->first()?->comment ?? '',
|
||||
$file->remarks->first()?->remark ?? '',
|
||||
];
|
||||
|
||||
//iterate for remaining notes and remarks
|
||||
for ($i = 1; $i < $fileRowCount; $i++) {
|
||||
$data[] = [
|
||||
'',
|
||||
'',
|
||||
$notes[$i] ?? '',
|
||||
$remarks[$i] ?? '',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$fileRowCounter++;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
142
app/Filament/Exports/TransmittalExcelExport.php
Normal file
142
app/Filament/Exports/TransmittalExcelExport.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Exports;
|
||||
|
||||
use App\Models\Transmittal;
|
||||
use pxlrbt\FilamentExcel\Columns\Column;
|
||||
use pxlrbt\FilamentExcel\Exports\ExcelExport;
|
||||
use Maatwebsite\Excel\Events\AfterSheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||
|
||||
class TransmittalExcelExport extends ExcelExport
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->fromTable()
|
||||
->withFilename('transmittals-' . now()->format('Y-m-d'))
|
||||
->modifyQueryUsing(
|
||||
fn ($query) => $query->with([
|
||||
'client',
|
||||
'branch',
|
||||
'files.notes',
|
||||
'files.remarks',
|
||||
])
|
||||
)
|
||||
->withColumns([
|
||||
Column::make('series')
|
||||
->heading('series'),
|
||||
Column::make('client')
|
||||
->heading('Client')
|
||||
->formatStateUsing(fn (Transmittal $record) => $record->client?->company),
|
||||
Column::make('branch')
|
||||
->heading('Branch')
|
||||
->formatStateUsing(fn (Transmittal $record) => $record->branch?->code),
|
||||
Column::make('files')
|
||||
->heading('files')
|
||||
->formatStateUsing(
|
||||
fn (Transmittal $record) => $record->files
|
||||
->pluck('description')
|
||||
->filter()
|
||||
->join(PHP_EOL)
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
public function registerEvents(): array
|
||||
{
|
||||
$recordIds = $this->getRecordIds();
|
||||
|
||||
return [
|
||||
AfterSheet::class => function (AfterSheet $event) use ($recordIds) {
|
||||
$sheet = $event->sheet->getDelegate();
|
||||
|
||||
$sheet->insertNewRowBefore(1, 2);
|
||||
$sheet->mergeCells('A1:F1');
|
||||
$sheet->getRowDimension(1)->setRowHeight(90);
|
||||
$sheet->getStyle('A1:F1')
|
||||
->getAlignment()
|
||||
->setHorizontal(Alignment::HORIZONTAL_CENTER);
|
||||
|
||||
|
||||
$logo = new Drawing();
|
||||
$logo->setName('MKM Logo');
|
||||
$logo->setDescription('MKM Tax & Accounting Services');
|
||||
$logo->setPath(public_path('images/logo-light.png'));
|
||||
$logo->setHeight(100);
|
||||
$logo->setOffsetX(120);
|
||||
$logo->setOffsetY(10);
|
||||
|
||||
$logo->setCoordinates('A1');
|
||||
$logo->setWorksheet($sheet);
|
||||
|
||||
$transmittal = Transmittal::with(['client', 'branch', 'files.notes', 'files.remarks'])->find($recordIds[0] ?? null);
|
||||
|
||||
if ($transmittal) {
|
||||
$sheet->mergeCells('A2:F2');
|
||||
$sheet->setCellValue('A2', $transmittal->client?->company);
|
||||
|
||||
$sheet->getStyle('A2')->getFont()->setBold(true);
|
||||
$sheet->getStyle('A2')->getAlignment()->setHorizontal('center');
|
||||
}
|
||||
|
||||
// Headings row
|
||||
$sheet->setCellValue('A3', 'series');
|
||||
$sheet->setCellValue('B3', 'Client');
|
||||
$sheet->setCellValue('C3', 'Branch');
|
||||
$sheet->setCellValue('D3', 'files');
|
||||
$sheet->setCellValue('E3', 'notes');
|
||||
$sheet->setCellValue('F3', 'remarks');
|
||||
|
||||
$sheet->getStyle('A3:F3')->getFont()->setBold(true);
|
||||
$sheet->getStyle('A3:F3')->getAlignment()->setHorizontal('center');
|
||||
|
||||
$rows = [];
|
||||
$firstRow = true;
|
||||
|
||||
if ($transmittal) {
|
||||
foreach ($transmittal->files as $file) {
|
||||
$fileNotes = $file->notes->pluck('comment')->values();
|
||||
$fileRemarks = $file->remarks->pluck('remark')->values();
|
||||
|
||||
$maxLines = max(1, $fileNotes->count(), $fileRemarks->count());
|
||||
|
||||
for ($i = 0; $i < $maxLines; $i++) {
|
||||
$rows[] = [
|
||||
'series' => $firstRow ? $transmittal->series : '',
|
||||
'client' => $firstRow ? $transmittal->client?->company : '',
|
||||
'branch' => $firstRow ? $transmittal->branch?->code : '',
|
||||
'file' => $i === 0 ? $file->description : '',
|
||||
'note' => $fileNotes[$i] ?? '',
|
||||
'remark' => $fileRemarks[$i] ?? '',
|
||||
];
|
||||
|
||||
$firstRow = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$currentRow = 4;
|
||||
|
||||
foreach ($rows as $dataRow) {
|
||||
$sheet->setCellValue("A{$currentRow}", $dataRow['series']);
|
||||
$sheet->setCellValue("B{$currentRow}", $dataRow['client']);
|
||||
$sheet->setCellValue("C{$currentRow}", $dataRow['branch']);
|
||||
$sheet->setCellValue("D{$currentRow}", $dataRow['file']);
|
||||
$sheet->setCellValue("E{$currentRow}", $dataRow['note']);
|
||||
$sheet->setCellValue("F{$currentRow}", $dataRow['remark']);
|
||||
|
||||
$currentRow++;
|
||||
}
|
||||
|
||||
$lastRow = max($currentRow - 1, 3);
|
||||
|
||||
$sheet->getStyle("A3:F{$lastRow}")
|
||||
->getBorders()
|
||||
->getAllBorders()
|
||||
->setBorderStyle(Border::BORDER_THIN);
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
namespace App\Filament\Resources\Branches;
|
||||
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use App\Filament\Resources\Branches\Pages\ListBranches;
|
||||
use App\Filament\Resources\Branches\Pages\CreateBranch;
|
||||
use App\Filament\Resources\Branches\Pages\EditBranch;
|
||||
use App\Filament\Resources\BranchResource\Pages;
|
||||
use App\Filament\Resources\BranchResource\RelationManagers\BalancesRelationManager;
|
||||
use App\Filament\Resources\BranchResource\RelationManagers\ExpenseRelationManager;
|
||||
use App\Filament\Resources\Branches\RelationManagers\BalancesRelationManager;
|
||||
use App\Filament\Resources\Branches\RelationManagers\ExpenseRelationManager;
|
||||
use App\Models\Branch;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Support\RawJs;
|
||||
use Filament\Tables;
|
||||
@@ -19,16 +25,16 @@ class BranchResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Branch::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||
|
||||
protected static bool $shouldRegisterNavigation = false;
|
||||
|
||||
protected static ?string $recordTitleAttribute = 'code';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
return $schema
|
||||
->components([
|
||||
Select::make('client_id')->relationship('client', 'id')
|
||||
->getOptionLabelFromRecordUsing(fn ($record) => $record->company)
|
||||
->disabled()
|
||||
@@ -63,12 +69,12 @@ class BranchResource extends Resource
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
@@ -85,9 +91,9 @@ class BranchResource extends Resource
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListBranches::route('/'),
|
||||
'create' => Pages\CreateBranch::route('/create'),
|
||||
'edit' => Pages\EditBranch::route('/{record}/edit'),
|
||||
'index' => ListBranches::route('/'),
|
||||
'create' => CreateBranch::route('/create'),
|
||||
'edit' => EditBranch::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\BranchResource\Pages;
|
||||
namespace App\Filament\Resources\Branches\Pages;
|
||||
|
||||
use App\Filament\Resources\BranchResource;
|
||||
use App\Filament\Resources\Branches\BranchResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\BranchResource\Pages;
|
||||
namespace App\Filament\Resources\Branches\Pages;
|
||||
|
||||
use App\Filament\Resources\BranchResource;
|
||||
use App\Filament\Resources\ClientResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use App\Filament\Resources\Branches\BranchResource;
|
||||
use App\Filament\Resources\Clients\ClientResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
@@ -30,7 +31,7 @@ class EditBranch extends EditRecord
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\BranchResource\Pages;
|
||||
namespace App\Filament\Resources\Branches\Pages;
|
||||
|
||||
use App\Filament\Resources\BranchResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use App\Filament\Resources\Branches\BranchResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
@@ -13,7 +14,7 @@ class ListBranches extends ListRecords
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\BranchResource\RelationManagers;
|
||||
namespace App\Filament\Resources\Branches\RelationManagers;
|
||||
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use App\Models\Account;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
@@ -22,11 +29,11 @@ class AccountsRelationManager extends RelationManager
|
||||
});
|
||||
}
|
||||
|
||||
public function form(Form $form): Form
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('branch_id')
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('branch_id')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
]);
|
||||
@@ -37,25 +44,25 @@ class AccountsRelationManager extends RelationManager
|
||||
return $table
|
||||
->recordTitleAttribute('branch_id')
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('account'),
|
||||
Tables\Columns\TextColumn::make('branch_id'),
|
||||
Tables\Columns\TextColumn::make('normal_balance'),
|
||||
Tables\Columns\TextColumn::make('starting_balance'),
|
||||
Tables\Columns\TextColumn::make('current_balance'),
|
||||
TextColumn::make('account'),
|
||||
TextColumn::make('branch_id'),
|
||||
TextColumn::make('normal_balance'),
|
||||
TextColumn::make('starting_balance'),
|
||||
TextColumn::make('current_balance'),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->headerActions([
|
||||
Tables\Actions\CreateAction::make(),
|
||||
CreateAction::make(),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
@@ -1,13 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\BranchResource\RelationManagers;
|
||||
namespace App\Filament\Resources\Branches\RelationManagers;
|
||||
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Schemas\Components\Grid;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use App\DataObjects\CreateAccountDTO;
|
||||
use App\Models\Account;
|
||||
use App\Models\AccountType;
|
||||
use App\Processes\Account\CreateAccountProcess;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
@@ -32,8 +42,8 @@ class BalancesRelationManager extends RelationManager
|
||||
return $table
|
||||
->recordTitleAttribute('branch_id')
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('account')->sortable(),
|
||||
Tables\Columns\TextColumn::make('accountType.normal_balance')
|
||||
TextColumn::make('account')->sortable(),
|
||||
TextColumn::make('accountType.normal_balance')
|
||||
->badge()
|
||||
->color(fn (string $state): string => match ($state) {
|
||||
'Debit' => 'success',
|
||||
@@ -41,23 +51,23 @@ class BalancesRelationManager extends RelationManager
|
||||
})
|
||||
->sortable()
|
||||
->formatStateUsing(fn ($state): string => ucfirst($state)),
|
||||
Tables\Columns\TextColumn::make('starting_balance')->label('Starting Balance'),
|
||||
Tables\Columns\TextColumn::make('current_balance')->label('Current Balance'),
|
||||
TextColumn::make('starting_balance')->label('Starting Balance'),
|
||||
TextColumn::make('current_balance')->label('Current Balance'),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->headerActions([
|
||||
Tables\Actions\CreateAction::make()
|
||||
CreateAction::make()
|
||||
->using(fn (array $data) => $this->saveAccount($data)),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
@@ -72,24 +82,24 @@ class BalancesRelationManager extends RelationManager
|
||||
return app(CreateAccountProcess::class)->run($payload);
|
||||
}
|
||||
|
||||
public function form(Form $form): Form
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $form
|
||||
->schema($this->getAccountForm())
|
||||
return $schema
|
||||
->components($this->getAccountForm())
|
||||
->columns(1);
|
||||
}
|
||||
|
||||
public function getAccountForm(): array
|
||||
{
|
||||
return [
|
||||
Forms\Components\Grid::make()
|
||||
Grid::make()
|
||||
->schema([
|
||||
Forms\Components\Select::make('account_type_id')
|
||||
Select::make('account_type_id')
|
||||
->label('Account Type')
|
||||
->relationship('accountType', 'type'),
|
||||
Forms\Components\TextInput::make('account'),
|
||||
Forms\Components\Textarea::make('description'),
|
||||
Forms\Components\TextInput::make('starting_balance')
|
||||
TextInput::make('account'),
|
||||
Textarea::make('description'),
|
||||
TextInput::make('starting_balance')
|
||||
->integer(),
|
||||
])->columns(1),
|
||||
];
|
||||
@@ -1,21 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\BranchResource\RelationManagers;
|
||||
namespace App\Filament\Resources\Branches\RelationManagers;
|
||||
|
||||
use App\Filament\Resources\ExpenseResource;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Actions\CreateAction;
|
||||
use App\Filament\Resources\Expenses\Pages\CreateExpense;
|
||||
use App\Filament\Resources\Expenses\ExpenseResource;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Tables\Actions\CreateAction;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class ExpenseRelationManager extends RelationManager
|
||||
{
|
||||
protected static string $relationship = 'expenses';
|
||||
|
||||
public function form(Form $form): Form
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $form
|
||||
->schema(ExpenseResource::getExpenseFormFields());
|
||||
return $schema
|
||||
->components(ExpenseResource::getExpenseFormFields());
|
||||
}
|
||||
|
||||
public function table(Table $table): Table
|
||||
@@ -25,8 +26,8 @@ class ExpenseRelationManager extends RelationManager
|
||||
->columns(ExpenseResource::getTableColumns())
|
||||
->headerActions([
|
||||
CreateAction::make()
|
||||
->mutateFormDataUsing(
|
||||
fn (array $data): array => app(ExpenseResource\Pages\CreateExpense::class)
|
||||
->mutateDataUsing(
|
||||
fn (array $data): array => app(CreateExpense::class)
|
||||
->getFormDataMutation($data)
|
||||
),
|
||||
]);
|
||||
@@ -1,133 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\DataObjects\CreateBranchDTO;
|
||||
use App\Filament\Resources\ClientResource\Pages\EditClient;
|
||||
use App\Filament\Resources\ClientResource\Pages\ListClients;
|
||||
use App\Filament\Resources\ClientResource\Pages\ViewClient;
|
||||
use App\Filament\Resources\ClientResource\Pages\GeneralLedger;
|
||||
use App\Filament\Resources\ClientResource\Pages\TrialBalance;
|
||||
use App\Filament\Resources\ClientResource\RelationManagers\AccountsRelationManager;
|
||||
use App\Filament\Resources\ClientResource\RelationManagers\BranchesRelationManager;
|
||||
use App\Filament\Resources\ClientResource\RelationManagers\ExpensesRelationManager;
|
||||
use App\Filament\Resources\ClientResource\RelationManagers\JournalsRelationManager;
|
||||
use App\Filament\Resources\ClientResource\RelationManagers\SalesRelationManager;
|
||||
use App\Filament\Resources\ClientResource\RelationManagers\TransmittalsRelationManager;
|
||||
use App\Models\Branch;
|
||||
use App\Models\Client;
|
||||
use App\Processes\Branch\CreateBranchProcess;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Filament\Pages\SubNavigationPosition;
|
||||
use Filament\Resources\Pages\Page;
|
||||
|
||||
class ClientResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Client::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-user';
|
||||
|
||||
protected static ?string $recordTitleAttribute = 'company';
|
||||
|
||||
protected static SubNavigationPosition $subNavigationPosition = SubNavigationPosition::Top;
|
||||
|
||||
public static function authorizeView(Model $record): void
|
||||
{
|
||||
parent::authorizeView($record);
|
||||
}
|
||||
|
||||
public static function getRecordSubNavigation(Page $page): array
|
||||
{
|
||||
return $page->generateNavigationItems([
|
||||
ViewClient::class,
|
||||
EditClient::class,
|
||||
GeneralLedger::class,
|
||||
TrialBalance::class,
|
||||
]);
|
||||
}
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('firstname')->label('First Name')->required(),
|
||||
Forms\Components\TextInput::make('middlename')->label('Middle Name')->nullable(),
|
||||
Forms\Components\TextInput::make('lastname')->label('Last Name')->required(),
|
||||
Forms\Components\Grid::make()->schema([
|
||||
Forms\Components\TextInput::make('company')->label('Company')->required(),
|
||||
Forms\Components\Select::make('type_id')
|
||||
->relationship('type', 'type')
|
||||
->label('Type')->required(),
|
||||
])->columns(2),
|
||||
])->columns(3);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('firstname')->label('First Name')->searchable(),
|
||||
Tables\Columns\TextColumn::make('middlename')->label('Middle Name'),
|
||||
Tables\Columns\TextColumn::make('lastname')->label('Last Name'),
|
||||
Tables\Columns\TextColumn::make('company')->label('Company')->searchable(),
|
||||
Tables\Columns\TextColumn::make('type.type')->label('Type'),
|
||||
])
|
||||
->filters([
|
||||
Tables\Filters\Filter::make('Vatable')
|
||||
->query(fn (Builder $query) => $query->orWhereHas('type', function (Builder $query) {
|
||||
$query->where('type', 'Vatable');
|
||||
})),
|
||||
Tables\Filters\Filter::make('Non-Vatable')
|
||||
->query(fn (Builder $query) => $query->orWhereHas('type', function (Builder $query) {
|
||||
$query->where('type', 'Non Vatable');
|
||||
})),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\ViewAction::make(),
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make()->requiresConfirmation(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
AccountsRelationManager::class,
|
||||
BranchesRelationManager::class,
|
||||
TransmittalsRelationManager::class,
|
||||
SalesRelationManager::class,
|
||||
ExpensesRelationManager::class,
|
||||
JournalsRelationManager::class,
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'view' => ViewClient::route('/{record}'),
|
||||
'edit' => EditClient::route('/{record}/edit'),
|
||||
'index' => ListClients::route('/'),
|
||||
'general-ledger' => GeneralLedger::route('/{record}/general-ledger'),
|
||||
'trial-balance' => TrialBalance::route('/{record}/trial-balance'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function saveBranch($data): Branch
|
||||
{
|
||||
$createBranchProcess = new CreateBranchProcess;
|
||||
$payload = new CreateBranchDTO(data: $data);
|
||||
|
||||
return $createBranchProcess->run($payload)->branch;
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ClientResource\RelationManagers;
|
||||
|
||||
use App\Filament\Exports\ClientAccountsExporter;
|
||||
use App\Models\Account;
|
||||
use Filament\Actions\Exports\Enums\ExportFormat;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class AccountsRelationManager extends RelationManager
|
||||
{
|
||||
protected static string $relationship = 'accounts';
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('account')->required(),
|
||||
Forms\Components\Textarea::make('description')->nullable(),
|
||||
Forms\Components\Select::make('account_type_id')
|
||||
->relationship('accountType', 'type')
|
||||
->required(),
|
||||
Forms\Components\Select::make('normal_balance')->options(
|
||||
['debit' => 'Debit', 'credit' => 'Credit']
|
||||
)->required(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->recordTitleAttribute('client_id')
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('account')->description(fn (Account $record): string => $record->description ?? ''),
|
||||
Tables\Columns\TextColumn::make('accountType.type'),
|
||||
Tables\Columns\TextColumn::make('accountType.normal_balance')->label('Normal Balance'),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->headerActions([
|
||||
Tables\Actions\ExportAction::make('Export Accounts')->exporter(ClientAccountsExporter::class)->formats([ExportFormat::Csv]),
|
||||
Tables\Actions\CreateAction::make()->label('New Account')->icon('heroicon-o-plus')->slideOver(),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make()->slideOver(),
|
||||
Tables\Actions\DeleteAction::make()->requiresConfirmation(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make()->icon('heroicon-s-trash')->requiresConfirmation(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ClientResource\RelationManagers;
|
||||
|
||||
use App\Filament\Resources\ExpenseResource;
|
||||
use App\Models\Expense;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class ExpensesRelationManager extends RelationManager
|
||||
{
|
||||
protected static string $relationship = 'expenses';
|
||||
|
||||
protected static ?string $title = 'Expenses';
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([]);
|
||||
}
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->recordTitleAttribute('supplier')
|
||||
->columns([
|
||||
TextColumn::make('supplier'),
|
||||
TextColumn::make('reference_number'),
|
||||
TextColumn::make('voucher_number'),
|
||||
TextColumn::make('branch.code'),
|
||||
TextColumn::make('happened_on'),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->headerActions([
|
||||
Tables\Actions\CreateAction::make()
|
||||
->url(fn () => ExpenseResource::getUrl('create', ['client_id' => $this->getOwnerRecord()->id])),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make()
|
||||
->url(fn (Expense $record) => ExpenseResource::getUrl('edit', ['record' => $record])),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ClientResource\RelationManagers;
|
||||
|
||||
use App\Filament\Resources\SaleResource;
|
||||
use App\Models\Sale;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class SalesRelationManager extends RelationManager
|
||||
{
|
||||
protected static string $relationship = 'sales';
|
||||
|
||||
protected static ?string $title = 'Sales';
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form->schema([]);
|
||||
}
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->recordTitleAttribute('title')
|
||||
->columns([
|
||||
TextColumn::make('id')->label('ID')->sortable(),
|
||||
TextColumn::make('branch.code')->label('Branch')->sortable(),
|
||||
TextColumn::make('happened_on')->label('Date')->date()->sortable(),
|
||||
TextColumn::make('gross_amount')->label('Gross Amount')->numeric()->sortable(),
|
||||
TextColumn::make('exempt')->label('Exempt')->numeric()->sortable(),
|
||||
TextColumn::make('vatable_amount')->label('Vatable Amount')->numeric()->sortable(),
|
||||
TextColumn::make('output_tax')->label('Output Tax')->numeric()->sortable(),
|
||||
TextColumn::make('payable_withholding_tax')->label('Payable Withholding Tax')->numeric()->sortable(),
|
||||
TextColumn::make('discount')->label('Discount')->numeric()->sortable(),
|
||||
TextColumn::make('net_amount')->label('Net Amount')->numeric()->sortable(),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->headerActions([
|
||||
Tables\Actions\CreateAction::make()
|
||||
->url(fn () => SaleResource::getUrl('create', ['client_id' => $this->getOwnerRecord()->id])),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make()
|
||||
->url(fn (Sale $record) => SaleResource::getUrl('edit', ['record' => $record])),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
145
app/Filament/Resources/Clients/ClientResource.php
Normal file
145
app/Filament/Resources/Clients/ClientResource.php
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Clients;
|
||||
|
||||
use Filament\Pages\Enums\SubNavigationPosition;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Schemas\Components\Grid;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\Filter;
|
||||
use Filament\Actions\ViewAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use App\DataObjects\CreateBranchDTO;
|
||||
use App\Filament\Resources\Clients\Pages\EditClient;
|
||||
use App\Filament\Resources\Clients\Pages\ListClients;
|
||||
use App\Filament\Resources\Clients\Pages\ViewClient;
|
||||
use App\Filament\Resources\Clients\Pages\GeneralLedger;
|
||||
use App\Filament\Resources\Clients\Pages\TrialBalance;
|
||||
use App\Filament\Resources\Clients\RelationManagers\AccountsRelationManager;
|
||||
use App\Filament\Resources\Clients\RelationManagers\BranchesRelationManager;
|
||||
use App\Filament\Resources\Clients\RelationManagers\DiscountRelationManager;
|
||||
use App\Filament\Resources\Clients\RelationManagers\ExpensesRelationManager;
|
||||
use App\Filament\Resources\Clients\RelationManagers\JournalsRelationManager;
|
||||
use App\Filament\Resources\Clients\RelationManagers\SalesRelationManager;
|
||||
use App\Filament\Resources\Clients\RelationManagers\TransmittalsRelationManager;
|
||||
use App\Models\Branch;
|
||||
use App\Models\Client;
|
||||
use App\Processes\Branch\CreateBranchProcess;
|
||||
use Filament\Forms;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Filament\Resources\Pages\Page;
|
||||
|
||||
class ClientResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Client::class;
|
||||
|
||||
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-user';
|
||||
|
||||
protected static ?string $recordTitleAttribute = 'company';
|
||||
|
||||
protected static ?\Filament\Pages\Enums\SubNavigationPosition $subNavigationPosition = SubNavigationPosition::Top;
|
||||
|
||||
public static function authorizeView(Model $record): void
|
||||
{
|
||||
parent::authorizeView($record);
|
||||
}
|
||||
|
||||
public static function getRecordSubNavigation(Page $page): array
|
||||
{
|
||||
return $page->generateNavigationItems([
|
||||
ViewClient::class,
|
||||
EditClient::class,
|
||||
GeneralLedger::class,
|
||||
TrialBalance::class,
|
||||
]);
|
||||
}
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('firstname')->label('First Name')->required(),
|
||||
TextInput::make('middlename')->label('Middle Name')->nullable(),
|
||||
TextInput::make('lastname')->label('Last Name')->required(),
|
||||
Grid::make()->schema([
|
||||
TextInput::make('company')->label('Company')->required(),
|
||||
Select::make('type_id')
|
||||
->relationship('type', 'type')
|
||||
->label('Type')->required(),
|
||||
])->columns(2),
|
||||
])->columns(3);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('firstname')->label('First Name')->searchable(),
|
||||
TextColumn::make('middlename')->label('Middle Name'),
|
||||
TextColumn::make('lastname')->label('Last Name'),
|
||||
TextColumn::make('company')->label('Company')->searchable(),
|
||||
TextColumn::make('type.type')->label('Type'),
|
||||
])
|
||||
->filters([
|
||||
Filter::make('Vatable')
|
||||
->query(fn (Builder $query) => $query->orWhereHas('type', function (Builder $query) {
|
||||
$query->where('type', 'Vatable');
|
||||
})),
|
||||
Filter::make('Non-Vatable')
|
||||
->query(fn (Builder $query) => $query->orWhereHas('type', function (Builder $query) {
|
||||
$query->where('type', 'Non Vatable');
|
||||
})),
|
||||
])
|
||||
->recordActions([
|
||||
ViewAction::make(),
|
||||
EditAction::make(),
|
||||
DeleteAction::make()->requiresConfirmation(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
AccountsRelationManager::class,
|
||||
BranchesRelationManager::class,
|
||||
TransmittalsRelationManager::class,
|
||||
SalesRelationManager::class,
|
||||
ExpensesRelationManager::class,
|
||||
JournalsRelationManager::class,
|
||||
DiscountRelationManager::class,
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'view' => ViewClient::route('/{record}'),
|
||||
'edit' => EditClient::route('/{record}/edit'),
|
||||
'index' => ListClients::route('/'),
|
||||
'general-ledger' => GeneralLedger::route('/{record}/general-ledger'),
|
||||
'trial-balance' => TrialBalance::route('/{record}/trial-balance'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function saveBranch($data): Branch
|
||||
{
|
||||
$createBranchProcess = new CreateBranchProcess;
|
||||
$payload = new CreateBranchDTO(data: $data);
|
||||
|
||||
return $createBranchProcess->run($payload)->branch;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ClientResource\Pages;
|
||||
namespace App\Filament\Resources\Clients\Pages;
|
||||
|
||||
use App\Filament\Resources\ClientResource;
|
||||
use App\Filament\Resources\Clients\ClientResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateClient extends CreateRecord
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ClientResource\Pages;
|
||||
namespace App\Filament\Resources\Clients\Pages;
|
||||
|
||||
use App\Filament\Resources\ClientResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use App\Filament\Resources\Clients\ClientResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
@@ -13,7 +14,7 @@ class EditClient extends EditRecord
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make()->icon('heroicon-s-trash')->requiresConfirmation(),
|
||||
DeleteAction::make()->icon('heroicon-s-trash')->requiresConfirmation(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ClientResource\Pages;
|
||||
namespace App\Filament\Resources\Clients\Pages;
|
||||
|
||||
use App\Filament\Resources\ClientResource;
|
||||
use App\Filament\Resources\Clients\ClientResource;
|
||||
use App\Models\Ledger;
|
||||
use Filament\Resources\Pages\Page;
|
||||
use Filament\Tables\Concerns\InteractsWithTable;
|
||||
@@ -14,7 +14,7 @@ use Filament\Tables\Filters\Filter;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Filament\Resources\Pages\Concerns\InteractsWithRecord;
|
||||
use pxlrbt\FilamentExcel\Actions\Tables\ExportAction;
|
||||
use pxlrbt\FilamentExcel\Actions\ExportAction as ExcelExportAction;
|
||||
use pxlrbt\FilamentExcel\Exports\ExcelExport;
|
||||
use pxlrbt\FilamentExcel\Columns\Column;
|
||||
|
||||
@@ -25,9 +25,9 @@ class GeneralLedger extends Page implements HasTable
|
||||
|
||||
protected static string $resource = ClientResource::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected static string $view = 'filament.resources.client-resource.pages.general-ledger';
|
||||
protected string $view = 'filament.resources.client-resource.pages.general-ledger';
|
||||
|
||||
public function mount(int | string $record): void
|
||||
{
|
||||
@@ -79,7 +79,7 @@ class GeneralLedger extends Page implements HasTable
|
||||
->searchable()
|
||||
->preload(),
|
||||
Filter::make('date_range')
|
||||
->form([
|
||||
->schema([
|
||||
DatePicker::make('from'),
|
||||
DatePicker::make('to'),
|
||||
])
|
||||
@@ -108,7 +108,7 @@ class GeneralLedger extends Page implements HasTable
|
||||
'account.account',
|
||||
])
|
||||
->headerActions([
|
||||
ExportAction::make()
|
||||
ExcelExportAction::make()
|
||||
->label('Export General Ledger')
|
||||
->exports([
|
||||
ExcelExport::make()
|
||||
@@ -1,9 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ClientResource\Pages;
|
||||
namespace App\Filament\Resources\Clients\Pages;
|
||||
|
||||
use Filament\Actions\ExportAction;
|
||||
use Filament\Actions\Exports\Enums\ExportFormat;
|
||||
use Filament\Actions\CreateAction;
|
||||
use App\Filament\Exports\ClientExporter;
|
||||
use App\Filament\Resources\ClientResource;
|
||||
use App\Filament\Resources\Clients\ClientResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
@@ -14,12 +17,12 @@ class ListClients extends ListRecords
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\ExportAction::make('Export clients')
|
||||
ExportAction::make('Export clients')
|
||||
->exporter(ClientExporter::class)
|
||||
->formats([
|
||||
Actions\Exports\Enums\ExportFormat::Csv,
|
||||
ExportFormat::Csv,
|
||||
]),
|
||||
Actions\CreateAction::make()->slideOver(),
|
||||
CreateAction::make()->slideOver(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ClientResource\Pages;
|
||||
namespace App\Filament\Resources\Clients\Pages;
|
||||
|
||||
use App\Filament\Resources\ClientResource;
|
||||
use App\Filament\Resources\Clients\ClientResource;
|
||||
use App\Models\Account;
|
||||
use Filament\Resources\Pages\Page;
|
||||
use Filament\Tables\Concerns\InteractsWithTable;
|
||||
@@ -21,9 +21,9 @@ class TrialBalance extends Page implements HasTable
|
||||
|
||||
protected static string $resource = ClientResource::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-scale';
|
||||
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-scale';
|
||||
|
||||
protected static string $view = 'filament.resources.client-resource.pages.trial-balance';
|
||||
protected string $view = 'filament.resources.client-resource.pages.trial-balance';
|
||||
|
||||
public function mount(int | string $record): void
|
||||
{
|
||||
@@ -1,21 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ClientResource\Pages;
|
||||
namespace App\Filament\Resources\Clients\Pages;
|
||||
|
||||
use App\Filament\Resources\ClientResource;
|
||||
use Filament\Infolists\Components\Grid;
|
||||
use Filament\Infolists\Components\Section;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Components\Grid;
|
||||
use App\Filament\Resources\Clients\ClientResource;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Infolists\Infolist;
|
||||
use Filament\Resources\Pages\ViewRecord;
|
||||
|
||||
class ViewClient extends ViewRecord
|
||||
{
|
||||
protected static string $resource = ClientResource::class;
|
||||
|
||||
public function infolist(Infolist $infolist): Infolist
|
||||
public function infolist(Schema $schema): Schema
|
||||
{
|
||||
return $infolist
|
||||
return $schema
|
||||
->schema([
|
||||
Section::make()->schema([
|
||||
Grid::make()->schema([
|
||||
@@ -25,7 +25,7 @@ class ViewClient extends ViewRecord
|
||||
TextEntry::make('company')->label('Company'),
|
||||
TextEntry::make('type.type')->label('Type'),
|
||||
])->columns(3),
|
||||
]),
|
||||
])->columnSpanFull(),
|
||||
|
||||
// Section::make('Branches')->schema([
|
||||
// RepeatableEntry::make('branches')
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Clients\RelationManagers;
|
||||
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\ExportAction;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use App\Commands\Clients\GenerateBaseAccountCommand;
|
||||
use App\Filament\Exports\ClientAccountsExporter;
|
||||
use App\Models\Account;
|
||||
use Filament\Actions\Exports\Enums\ExportFormat;
|
||||
use Filament\Forms;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class AccountsRelationManager extends RelationManager
|
||||
{
|
||||
protected static string $relationship = 'accounts';
|
||||
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('account')->required(),
|
||||
Textarea::make('description')->nullable(),
|
||||
Select::make('account_type_id')
|
||||
->relationship('accountType', 'type')
|
||||
->required(),
|
||||
Select::make('normal_balance')->options(
|
||||
['debit' => 'Debit', 'credit' => 'Credit']
|
||||
)->required(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->recordTitleAttribute('client_id')
|
||||
->columns([
|
||||
TextColumn::make('account')->description(fn (Account $record): string => $record->description ?? ''),
|
||||
TextColumn::make('accountType.type'),
|
||||
TextColumn::make('accountType.normal_balance')->label('Normal Balance'),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->headerActions([
|
||||
Action::make('generate-base-accounts')
|
||||
->requiresConfirmation()
|
||||
->label('Generate Base Accounts')
|
||||
->action(function () {
|
||||
$client = $this->getOwnerRecord();
|
||||
if (! $client ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if($client->accounts()->count() > 0) {
|
||||
return;
|
||||
}
|
||||
app(GenerateBaseAccountCommand::class)->execute($client);
|
||||
}),
|
||||
ExportAction::make('Export Accounts')->exporter(ClientAccountsExporter::class)->formats([ExportFormat::Csv]),
|
||||
CreateAction::make()->label('New Account')->icon('heroicon-o-plus')->slideOver(),
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make()->slideOver(),
|
||||
DeleteAction::make()->requiresConfirmation(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make()->icon('heroicon-s-trash')->requiresConfirmation(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ClientResource\RelationManagers;
|
||||
namespace App\Filament\Resources\Clients\RelationManagers;
|
||||
|
||||
use App\Filament\Resources\BranchResource\Pages\EditBranch;
|
||||
use App\Filament\Resources\ClientResource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Forms\Components\Hidden;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use App\Filament\Resources\Branches\Pages\EditBranch;
|
||||
use App\Filament\Resources\Clients\ClientResource;
|
||||
use App\Models\Branch;
|
||||
use App\Processes\Branch\CreateBranchProcess;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Support\RawJs;
|
||||
use Filament\Tables;
|
||||
@@ -27,19 +35,19 @@ class BranchesRelationManager extends RelationManager
|
||||
$this->createBranchProcess = new CreateBranchProcess;
|
||||
}
|
||||
|
||||
public function form(Form $form): Form
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\Hidden::make('id'),
|
||||
Forms\Components\TextInput::make('code')->required()
|
||||
return $schema
|
||||
->components([
|
||||
Hidden::make('id'),
|
||||
TextInput::make('code')->required()
|
||||
->unique(
|
||||
'branches',
|
||||
'code',
|
||||
ignoreRecord: true,
|
||||
modifyRuleUsing: fn (Unique $rule) => $rule->where('client_id', $this->getOwnerRecord()->id)
|
||||
),
|
||||
Forms\Components\TextInput::make('series')->label('Current Series')
|
||||
TextInput::make('series')->label('Current Series')
|
||||
->required()
|
||||
->numeric()
|
||||
->integer()
|
||||
@@ -56,29 +64,29 @@ class BranchesRelationManager extends RelationManager
|
||||
return $table
|
||||
->recordTitleAttribute('client_id')
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('code')->label('Branch Code'),
|
||||
Tables\Columns\TextColumn::make('current_series')->label('Current Series'),
|
||||
TextColumn::make('code')->label('Branch Code'),
|
||||
TextColumn::make('current_series')->label('Current Series'),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->headerActions([
|
||||
Tables\Actions\CreateAction::make()
|
||||
->mutateFormDataUsing(fn ($data) => $this->appendCientId($data))
|
||||
CreateAction::make()
|
||||
->mutateDataUsing(fn ($data) => $this->appendCientId($data))
|
||||
->using(fn ($data) => $this->saveBranch($data)),
|
||||
])
|
||||
->actions([
|
||||
->recordActions([
|
||||
// Tables\Actions\ViewAction::make()->url(fn ($record) => EditBranch::getUrl(['record' => $record->id])),
|
||||
Tables\Actions\EditAction::make()
|
||||
EditAction::make()
|
||||
->fillForm(fn ($record) => ['id' => $record->id, 'code' => $record->code, 'series' => $record->current_series])
|
||||
->mutateFormDataUsing(fn ($data) => $this->appendCientId($data))
|
||||
->mutateDataUsing(fn ($data) => $this->appendCientId($data))
|
||||
->using(fn ($data) => $this->saveBranch($data))
|
||||
->url(fn ($record) => EditBranch::getUrl(['record' => $record->id])),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Clients\RelationManagers;
|
||||
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Forms;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class DiscountRelationManager extends RelationManager
|
||||
{
|
||||
protected static string $relationship = 'discounts';
|
||||
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('discount')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
]);
|
||||
}
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->recordTitleAttribute('discount')
|
||||
->columns([
|
||||
TextColumn::make('discount'),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->headerActions([
|
||||
CreateAction::make(),
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
DeleteAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Clients\RelationManagers;
|
||||
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Actions\Action;
|
||||
use App\Filament\Resources\Expenses\ExpenseResource;
|
||||
use App\Models\Expense;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class ExpensesRelationManager extends RelationManager
|
||||
{
|
||||
protected static string $relationship = 'expenses';
|
||||
|
||||
protected static ?string $title = 'Expenses';
|
||||
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([]);
|
||||
}
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return ExpenseResource::table($table)->headerActions([
|
||||
Action::make('New Expense')->action('openCreateForm'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function openCreateForm()
|
||||
{
|
||||
return redirect()->route('filament.admin.resources.expenses.create', ['client_id' => $this->getOwnerRecord()->id]);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ClientResource\RelationManagers;
|
||||
namespace App\Filament\Resources\Clients\RelationManagers;
|
||||
|
||||
use Filament\Schemas\Schema;
|
||||
use Closure;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Actions\CreateAction;
|
||||
use App\Models\Account;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use App\Actions\Balances\CreateBalanceAction;
|
||||
use App\Actions\Ledgers\CreateLedgerAction;
|
||||
use App\DataObjects\CreateLedgerDTO;
|
||||
@@ -14,7 +23,6 @@ use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
@@ -29,10 +37,10 @@ class JournalsRelationManager extends RelationManager
|
||||
|
||||
protected static ?string $title = 'Journal Entries (Adjustments)';
|
||||
|
||||
public function form(Form $form): Form
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
return $schema
|
||||
->components([
|
||||
Select::make('branch_id')
|
||||
->label('Branch')
|
||||
->options(fn () => Branch::where('client_id', $this->getOwnerRecord()->id)->pluck('code', 'id'))
|
||||
@@ -78,7 +86,7 @@ class JournalsRelationManager extends RelationManager
|
||||
->minItems(2)
|
||||
->live()
|
||||
->rules([
|
||||
fn (): \Closure => function (string $attribute, $value, \Closure $fail) {
|
||||
fn (): Closure => function (string $attribute, $value, Closure $fail) {
|
||||
$debit = collect($value)->sum('debit_amount');
|
||||
$credit = collect($value)->sum('credit_amount');
|
||||
if (abs($debit - $credit) > 0.01) {
|
||||
@@ -97,18 +105,18 @@ class JournalsRelationManager extends RelationManager
|
||||
return $table
|
||||
->recordTitleAttribute('description')
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('happened_on')
|
||||
TextColumn::make('happened_on')
|
||||
->date()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('series')
|
||||
TextColumn::make('series')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('description')
|
||||
TextColumn::make('description')
|
||||
->limit(50),
|
||||
Tables\Columns\TextColumn::make('total_debit')
|
||||
TextColumn::make('total_debit')
|
||||
->label('Total Debit')
|
||||
->state(fn (Journal $record) => $record->ledgers->sum('debit_amount'))
|
||||
->money('PHP'),
|
||||
Tables\Columns\TextColumn::make('total_credit')
|
||||
TextColumn::make('total_credit')
|
||||
->label('Total Credit')
|
||||
->state(fn (Journal $record) => $record->ledgers->sum('credit_amount'))
|
||||
->money('PHP'),
|
||||
@@ -117,7 +125,7 @@ class JournalsRelationManager extends RelationManager
|
||||
//
|
||||
])
|
||||
->headerActions([
|
||||
Tables\Actions\CreateAction::make()
|
||||
CreateAction::make()
|
||||
->label('Add Adjustment Entry')
|
||||
->using(function (array $data, string $model) {
|
||||
return DB::transaction(function () use ($data, $model) {
|
||||
@@ -134,7 +142,7 @@ class JournalsRelationManager extends RelationManager
|
||||
ledger: null, // Will be created
|
||||
transaction: null, // No transaction
|
||||
journal: $journal,
|
||||
account: \App\Models\Account::find($ledger['account_id']),
|
||||
account: Account::find($ledger['account_id']),
|
||||
type: ($ledger['debit_amount'] > 0) ? 'debit' : 'credit'
|
||||
);
|
||||
|
||||
@@ -148,13 +156,13 @@ class JournalsRelationManager extends RelationManager
|
||||
});
|
||||
}),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Clients\RelationManagers;
|
||||
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Actions\Action;
|
||||
use App\Filament\Resources\Sales\SaleResource;
|
||||
use App\Models\Sale;
|
||||
use Filament\Forms;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class SalesRelationManager extends RelationManager
|
||||
{
|
||||
protected static string $relationship = 'sales';
|
||||
|
||||
protected static ?string $title = 'Sales';
|
||||
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema->components([]);
|
||||
}
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return SaleResource::table($table)->headerActions([
|
||||
Action::make('New Sale')->action('openCreateForm'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function openCreateForm()
|
||||
{
|
||||
return redirect()->route('filament.admin.resources.sales.create', ['client_id' => $this->getOwnerRecord()->id]);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ClientResource\RelationManagers;
|
||||
namespace App\Filament\Resources\Clients\RelationManagers;
|
||||
|
||||
use App\Filament\Resources\TransmittalResource;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Actions\Action;
|
||||
use App\Filament\Resources\Transmittals\TransmittalResource;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
@@ -18,9 +19,9 @@ class TransmittalsRelationManager extends RelationManager
|
||||
return auth()->user()->can('update_transmittal');
|
||||
}
|
||||
|
||||
public function form(Form $form): Form
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return TransmittalResource::form($form)
|
||||
return TransmittalResource::form($schema)
|
||||
->fill(
|
||||
['client_id' => $this->getOwnerRecord()->id]
|
||||
);
|
||||
@@ -29,7 +30,7 @@ class TransmittalsRelationManager extends RelationManager
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return TransmittalResource::table($table)->headerActions([
|
||||
Tables\Actions\Action::make('New Transmittal')->action('openCreateForm'),
|
||||
Action::make('New Transmittal')->action('openCreateForm'),
|
||||
]);
|
||||
}
|
||||
|
||||
82
app/Filament/Resources/Discounts/DiscountResource.php
Normal file
82
app/Filament/Resources/Discounts/DiscountResource.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Discounts;
|
||||
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Hidden;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use App\Filament\Resources\Discounts\Pages\ListDiscounts;
|
||||
use App\Filament\Resources\Discounts\Pages\CreateDiscount;
|
||||
use App\Filament\Resources\Discounts\Pages\EditDiscount;
|
||||
use App\Filament\Resources\DiscountResource\Pages;
|
||||
use App\Filament\Resources\DiscountResource\RelationManagers;
|
||||
use App\Models\Discount;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Get;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class DiscountResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Discount::class;
|
||||
|
||||
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||
|
||||
protected static bool $shouldRegisterNavigation = false;
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('discount')
|
||||
->label('Discount')
|
||||
->required(),
|
||||
Hidden::make('client_id')
|
||||
->default(fn () => request()->client_id),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('discount')
|
||||
->label('Discount')
|
||||
->searchable(),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListDiscounts::route('/'),
|
||||
'create' => CreateDiscount::route('/create'),
|
||||
'edit' => EditDiscount::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
12
app/Filament/Resources/Discounts/Pages/CreateDiscount.php
Normal file
12
app/Filament/Resources/Discounts/Pages/CreateDiscount.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Discounts\Pages;
|
||||
|
||||
use App\Filament\Resources\Discounts\DiscountResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateDiscount extends CreateRecord
|
||||
{
|
||||
protected static string $resource = DiscountResource::class;
|
||||
}
|
||||
20
app/Filament/Resources/Discounts/Pages/EditDiscount.php
Normal file
20
app/Filament/Resources/Discounts/Pages/EditDiscount.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Discounts\Pages;
|
||||
|
||||
use Filament\Actions\DeleteAction;
|
||||
use App\Filament\Resources\Discounts\DiscountResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditDiscount extends EditRecord
|
||||
{
|
||||
protected static string $resource = DiscountResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
20
app/Filament/Resources/Discounts/Pages/ListDiscounts.php
Normal file
20
app/Filament/Resources/Discounts/Pages/ListDiscounts.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Discounts\Pages;
|
||||
|
||||
use Filament\Actions\CreateAction;
|
||||
use App\Filament\Resources\Discounts\DiscountResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListDiscounts extends ListRecords
|
||||
{
|
||||
protected static string $resource = DiscountResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ExpenseResource\Pages;
|
||||
|
||||
use App\Actions\Transactions\CreateTransactionAction;
|
||||
use App\DataObjects\CreateTransactionDTO;
|
||||
use App\Filament\Resources\ExpenseResource;
|
||||
use Exception;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Pipeline;
|
||||
use Symfony\Component\Console\Exception\LogicException;
|
||||
|
||||
class CreateExpense extends CreateRecord
|
||||
{
|
||||
protected static string $resource = ExpenseResource::class;
|
||||
|
||||
protected function mutateFormDataBeforeCreate(array $data): array
|
||||
{
|
||||
|
||||
return $this->getFormDataMutation($data);
|
||||
}
|
||||
|
||||
public function getFormDataMutation(array $data): array
|
||||
{
|
||||
return Arr::except($data, ['client', 'transactions']);
|
||||
}
|
||||
|
||||
protected function afterCreate(): void
|
||||
{
|
||||
$transactions = $this->form->getState()['transactions'] ?? [];
|
||||
|
||||
try {
|
||||
$branch = $this->getRecord()->branch;
|
||||
|
||||
foreach ($transactions as $transaction) {
|
||||
|
||||
$data = [
|
||||
'branch_id' => $branch->id,
|
||||
'happened_on' => $this->getRecord()->happened_on,
|
||||
...$transaction,
|
||||
];
|
||||
|
||||
$payload = new CreateTransactionDTO(data: $data, transactionable: $this->getRecord());
|
||||
|
||||
Pipeline::send(passable: $payload)->through(
|
||||
[
|
||||
CreateTransactionAction::class,
|
||||
]
|
||||
)->thenReturn();
|
||||
}
|
||||
|
||||
$this->commitDatabaseTransaction();
|
||||
} catch (Exception $exception) {
|
||||
$this->rollBackDatabaseTransaction();
|
||||
throw new LogicException('Failed to save transactions : '.$exception->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
namespace App\Filament\Resources\Expenses;
|
||||
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Schemas\Components\Utilities\Get;
|
||||
use Filament\Schemas\Components\Utilities\Set;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use App\Filament\Resources\Expenses\Pages\ListExpenses;
|
||||
use App\Filament\Resources\Expenses\Pages\CreateExpense;
|
||||
use App\Filament\Resources\Expenses\Pages\EditExpense;
|
||||
use App\Commands\Expenses\GenerateVoucher;
|
||||
use App\Filament\Resources\ExpenseResource\Pages;
|
||||
use App\Models\Account;
|
||||
@@ -14,9 +25,6 @@ use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\Hidden;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Forms\Get;
|
||||
use Filament\Forms\Set;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
@@ -29,14 +37,14 @@ class ExpenseResource extends Resource
|
||||
|
||||
protected static bool $isVatable;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-banknotes';
|
||||
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-banknotes';
|
||||
|
||||
protected static bool $shouldRegisterNavigation = false;
|
||||
|
||||
public static function form(Form $form): Form
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return $form
|
||||
->schema(static::getExpenseFormFields());
|
||||
return $schema
|
||||
->components(static::getExpenseFormFields());
|
||||
}
|
||||
|
||||
public static function getExpenseFormFields(): array
|
||||
@@ -195,11 +203,11 @@ class ExpenseResource extends Resource
|
||||
'client_id' => $get('../../client'),
|
||||
]);
|
||||
|
||||
if ($get('../../branch_id')) {
|
||||
$query->whereHas('balances', function ($query) use ($get) {
|
||||
return $query->where('branch_id', $get('../../branch_id'));
|
||||
});
|
||||
}
|
||||
// if ($get('../../branch_id')) {
|
||||
// $query->whereHas('balances', function ($query) use ($get) {
|
||||
// return $query->where('branch_id', $get('../../branch_id'));
|
||||
// });
|
||||
// }
|
||||
|
||||
$query->whereHas('accountType', function ($query) {
|
||||
return $query->where('type', 'Expenses');
|
||||
@@ -208,7 +216,6 @@ class ExpenseResource extends Resource
|
||||
return $query->get()->pluck('account', 'id');
|
||||
}
|
||||
|
||||
#[NoReturn]
|
||||
public static function setDefaultFormValues(Get $get, Set $set, ?string $old, ?string $state): void
|
||||
{
|
||||
|
||||
@@ -253,13 +260,13 @@ class ExpenseResource extends Resource
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
Tables\Actions\EditAction::make(),
|
||||
->recordActions([
|
||||
DeleteAction::make(),
|
||||
EditAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
@@ -267,12 +274,13 @@ class ExpenseResource extends Resource
|
||||
public static function getTableColumns(): array
|
||||
{
|
||||
return [
|
||||
Tables\Columns\TextColumn::make('supplier'),
|
||||
Tables\Columns\TextColumn::make('reference_number'),
|
||||
Tables\Columns\TextColumn::make('voucher_number'),
|
||||
Tables\Columns\TextColumn::make('branch.client.company'),
|
||||
Tables\Columns\TextColumn::make('branch.code'),
|
||||
Tables\Columns\TextColumn::make('happened_on'),
|
||||
TextColumn::make('supplier'),
|
||||
TextColumn::make('reference_number'),
|
||||
TextColumn::make('voucher_number'),
|
||||
TextColumn::make('branch.client.company'),
|
||||
TextColumn::make('branch.code'),
|
||||
TextColumn::make('happened_on'),
|
||||
TextColumn::make('accounts_list')->label('Accounts'),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -286,9 +294,9 @@ class ExpenseResource extends Resource
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListExpenses::route('/'),
|
||||
'create' => Pages\CreateExpense::route('/create'),
|
||||
'edit' => Pages\EditExpense::route('/{record}/edit'),
|
||||
'index' => ListExpenses::route('/'),
|
||||
'create' => CreateExpense::route('/create'),
|
||||
'edit' => EditExpense::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
94
app/Filament/Resources/Expenses/Pages/CreateExpense.php
Normal file
94
app/Filament/Resources/Expenses/Pages/CreateExpense.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Expenses\Pages;
|
||||
|
||||
use App\Actions\Transactions\CreateRecordTransactionsAction;
|
||||
use App\Filament\Resources\Clients\ClientResource;
|
||||
use App\Filament\Resources\Expenses\ExpenseResource;
|
||||
use App\Models\Client;
|
||||
use Exception;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
use Illuminate\Support\Arr;
|
||||
use Symfony\Component\Console\Exception\LogicException;
|
||||
|
||||
class CreateExpense extends CreateRecord
|
||||
{
|
||||
protected static string $resource = ExpenseResource::class;
|
||||
|
||||
public ?int $clientId = null;
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
parent::mount();
|
||||
|
||||
$this->clientId = request()->integer('client_id');
|
||||
}
|
||||
|
||||
public function getBreadcrumbs(): array
|
||||
{
|
||||
$client = $this->getClient();
|
||||
|
||||
if (! $client) {
|
||||
return parent::getBreadcrumbs();
|
||||
}
|
||||
|
||||
return [
|
||||
ClientResource::getUrl('view', ['record' => $client->id]) => $client->company,
|
||||
ClientResource::getUrl('view', ['record' => $client->id]).'?activeRelationManager=4' => 'Expenses',
|
||||
$this->getResource()::getUrl('create', ['client_id' => $client->id]) => 'Create',
|
||||
];
|
||||
}
|
||||
|
||||
protected function getClient(): Client|null
|
||||
{
|
||||
if (! $this->clientId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Client::find($this->clientId);
|
||||
}
|
||||
|
||||
protected function mutateFormDataBeforeCreate(array $data): array
|
||||
{
|
||||
|
||||
return $this->getFormDataMutation($data);
|
||||
}
|
||||
|
||||
public function getFormDataMutation(array $data): array
|
||||
{
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
|
||||
$data['gross_amount'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['gross_amount'] ?? 0));
|
||||
$data['exempt'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['exempt'] ?? 0));
|
||||
$data['zero_rated'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['zero_rated'] ?? 0));
|
||||
$data['vatable_amount'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['vatable_amount'] ?? 0));
|
||||
$data['input_tax'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['input_tax'] ?? 0));
|
||||
$data['payable_withholding_tax'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['payable_withholding_tax'] ?? 0));
|
||||
$data['net_amount'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['net_amount'] ?? 0));
|
||||
|
||||
return Arr::except($data, ['client', 'transactions']);
|
||||
}
|
||||
|
||||
protected function afterCreate(): void
|
||||
{
|
||||
$transactions = $this->form->getState()['transactions'] ?? [];
|
||||
|
||||
try {
|
||||
app(CreateRecordTransactionsAction::class)($this->getRecord(), $transactions);
|
||||
|
||||
$accountIds = collect($transactions)
|
||||
->pluck('account_id')
|
||||
->filter()
|
||||
->unique()
|
||||
->values()
|
||||
->all();
|
||||
|
||||
$this->getRecord()->accounts()->sync($accountIds);
|
||||
|
||||
$this->commitDatabaseTransaction();
|
||||
} catch (Exception $exception) {
|
||||
$this->rollBackDatabaseTransaction();
|
||||
throw new LogicException('Failed to save transactions : '.$exception->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ExpenseResource\Pages;
|
||||
namespace App\Filament\Resources\Expenses\Pages;
|
||||
|
||||
use App\Filament\Resources\ExpenseResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use App\Filament\Resources\Expenses\ExpenseResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
@@ -13,7 +14,7 @@ class EditExpense extends EditRecord
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ExpenseResource\Pages;
|
||||
namespace App\Filament\Resources\Expenses\Pages;
|
||||
|
||||
use App\Filament\Resources\ExpenseResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use App\Filament\Resources\Expenses\ExpenseResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
@@ -13,7 +14,7 @@ class ListExpenses extends ListRecords
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Shield\RoleResource\Pages;
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Filament\Resources\Shield\RoleResource;
|
||||
namespace App\Filament\Resources\Roles\Pages;
|
||||
|
||||
use App\Filament\Resources\Roles\Roles\RoleResource;
|
||||
use BezhanSalleh\FilamentShield\Support\Utils;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
use Illuminate\Support\Arr;
|
||||
@@ -10,29 +12,30 @@ use Illuminate\Support\Collection;
|
||||
|
||||
class CreateRole extends CreateRecord
|
||||
{
|
||||
protected static string $resource = RoleResource::class;
|
||||
|
||||
public Collection $permissions;
|
||||
|
||||
protected static string $resource = RoleResource::class;
|
||||
|
||||
protected function mutateFormDataBeforeCreate(array $data): array
|
||||
{
|
||||
$this->permissions = collect($data)
|
||||
->filter(function ($permission, $key) {
|
||||
return ! in_array($key, ['name', 'guard_name', 'select_all']);
|
||||
})
|
||||
->filter(fn (mixed $permission, string $key): bool => ! in_array($key, ['name', 'guard_name', 'select_all', Utils::getTenantModelForeignKey()]))
|
||||
->values()
|
||||
->flatten()
|
||||
->unique();
|
||||
|
||||
if (Utils::isTenancyEnabled() && Arr::has($data, Utils::getTenantModelForeignKey()) && filled($data[Utils::getTenantModelForeignKey()])) {
|
||||
return Arr::only($data, ['name', 'guard_name', Utils::getTenantModelForeignKey()]);
|
||||
}
|
||||
|
||||
return Arr::only($data, ['name', 'guard_name']);
|
||||
}
|
||||
|
||||
protected function afterCreate(): void
|
||||
{
|
||||
$permissionModels = collect();
|
||||
$this->permissions->each(function ($permission) use ($permissionModels) {
|
||||
$this->permissions->each(function (string $permission) use ($permissionModels): void {
|
||||
$permissionModels->push(Utils::getPermissionModel()::firstOrCreate([
|
||||
/** @phpstan-ignore-next-line */
|
||||
'name' => $permission,
|
||||
'guard_name' => $this->data['guard_name'],
|
||||
]));
|
||||
@@ -1,50 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Shield\RoleResource\Pages;
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Filament\Resources\Shield\RoleResource;
|
||||
namespace App\Filament\Resources\Roles\Pages;
|
||||
|
||||
use App\Filament\Resources\Roles\Roles\RoleResource;
|
||||
use BezhanSalleh\FilamentShield\Support\Utils;
|
||||
use Filament\Actions;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class EditRole extends EditRecord
|
||||
{
|
||||
protected static string $resource = RoleResource::class;
|
||||
|
||||
public Collection $permissions;
|
||||
|
||||
protected static string $resource = RoleResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function mutateFormDataBeforeSave(array $data): array
|
||||
{
|
||||
$this->permissions = collect($data)
|
||||
->filter(function ($permission, $key) {
|
||||
return ! in_array($key, ['name', 'guard_name', 'select_all']);
|
||||
})
|
||||
->filter(fn (mixed $permission, string $key): bool => ! in_array($key, ['name', 'guard_name', 'select_all', Utils::getTenantModelForeignKey()]))
|
||||
->values()
|
||||
->flatten()
|
||||
->unique();
|
||||
|
||||
if (Utils::isTenancyEnabled() && Arr::has($data, Utils::getTenantModelForeignKey()) && filled($data[Utils::getTenantModelForeignKey()])) {
|
||||
return Arr::only($data, ['name', 'guard_name', Utils::getTenantModelForeignKey()]);
|
||||
}
|
||||
|
||||
return Arr::only($data, ['name', 'guard_name']);
|
||||
}
|
||||
|
||||
protected function afterSave(): void
|
||||
{
|
||||
$permissionModels = collect();
|
||||
$this->permissions->each(function ($permission) use ($permissionModels) {
|
||||
$this->permissions->each(function (string $permission) use ($permissionModels): void {
|
||||
$permissionModels->push(Utils::getPermissionModel()::firstOrCreate([
|
||||
'name' => $permission,
|
||||
'guard_name' => $this->data['guard_name'],
|
||||
]));
|
||||
});
|
||||
|
||||
// @phpstan-ignore-next-line
|
||||
$this->record->syncPermissions($permissionModels);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Shield\RoleResource\Pages;
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Filament\Resources\Shield\RoleResource;
|
||||
use Filament\Actions;
|
||||
namespace App\Filament\Resources\Roles\Pages;
|
||||
|
||||
use App\Filament\Resources\Roles\Roles\RoleResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListRoles extends ListRecords
|
||||
@@ -13,7 +15,7 @@ class ListRoles extends ListRecords
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Shield\RoleResource\Pages;
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Filament\Resources\Shield\RoleResource;
|
||||
use Filament\Actions;
|
||||
namespace App\Filament\Resources\Roles\Pages;
|
||||
|
||||
use App\Filament\Resources\Roles\Roles\RoleResource;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Resources\Pages\ViewRecord;
|
||||
|
||||
class ViewRole extends ViewRecord
|
||||
@@ -13,7 +15,7 @@ class ViewRole extends ViewRecord
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\EditAction::make(),
|
||||
EditAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
165
app/Filament/Resources/Roles/Roles/RoleResource.php
Normal file
165
app/Filament/Resources/Roles/Roles/RoleResource.php
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Filament\Resources\Roles\Roles;
|
||||
|
||||
use BezhanSalleh\FilamentShield\FilamentShieldPlugin;
|
||||
use App\Filament\Resources\Roles\Pages\CreateRole;
|
||||
use App\Filament\Resources\Roles\Pages\EditRole;
|
||||
use App\Filament\Resources\Roles\Pages\ListRoles;
|
||||
use App\Filament\Resources\Roles\Pages\ViewRole;
|
||||
use BezhanSalleh\FilamentShield\Support\Utils;
|
||||
use BezhanSalleh\FilamentShield\Traits\HasShieldFormComponents;
|
||||
use BezhanSalleh\PluginEssentials\Concerns\Resource as Essentials;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Panel;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Components\Grid;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rules\Unique;
|
||||
|
||||
class RoleResource extends Resource
|
||||
{
|
||||
use Essentials\BelongsToParent;
|
||||
use Essentials\BelongsToTenant;
|
||||
use Essentials\HasGlobalSearch;
|
||||
use Essentials\HasLabels;
|
||||
use Essentials\HasNavigation;
|
||||
use HasShieldFormComponents;
|
||||
|
||||
protected static ?string $recordTitleAttribute = 'name';
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Grid::make()
|
||||
->schema([
|
||||
Section::make()
|
||||
->schema([
|
||||
TextInput::make('name')
|
||||
->label(__('filament-shield::filament-shield.field.name'))
|
||||
->unique(
|
||||
ignoreRecord: true, /** @phpstan-ignore-next-line */
|
||||
modifyRuleUsing: fn (Unique $rule): Unique => Utils::isTenancyEnabled() ? $rule->where(Utils::getTenantModelForeignKey(), Filament::getTenant()?->id) : $rule
|
||||
)
|
||||
->required()
|
||||
->maxLength(255),
|
||||
|
||||
TextInput::make('guard_name')
|
||||
->label(__('filament-shield::filament-shield.field.guard_name'))
|
||||
->default(Utils::getFilamentAuthGuard())
|
||||
->nullable()
|
||||
->maxLength(255),
|
||||
|
||||
Select::make(config('permission.column_names.team_foreign_key'))
|
||||
->label(__('filament-shield::filament-shield.field.team'))
|
||||
->placeholder(__('filament-shield::filament-shield.field.team.placeholder'))
|
||||
/** @phpstan-ignore-next-line */
|
||||
->default(Filament::getTenant()?->id)
|
||||
->options(fn (): array => in_array(Utils::getTenantModel(), [null, '', '0'], true) ? [] : Utils::getTenantModel()::pluck('name', 'id')->toArray())
|
||||
->visible(fn (): bool => static::shield()->isCentralApp() && Utils::isTenancyEnabled())
|
||||
->dehydrated(fn (): bool => static::shield()->isCentralApp() && Utils::isTenancyEnabled()),
|
||||
static::getSelectAllFormComponent(),
|
||||
|
||||
])
|
||||
->columns([
|
||||
'sm' => 2,
|
||||
'lg' => 3,
|
||||
])
|
||||
->columnSpanFull(),
|
||||
])
|
||||
->columnSpanFull(),
|
||||
static::getShieldFormComponents(),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('name')
|
||||
->weight(FontWeight::Medium)
|
||||
->label(__('filament-shield::filament-shield.column.name'))
|
||||
->formatStateUsing(fn (string $state): string => Str::headline($state))
|
||||
->searchable(),
|
||||
TextColumn::make('guard_name')
|
||||
->badge()
|
||||
->color('warning')
|
||||
->label(__('filament-shield::filament-shield.column.guard_name')),
|
||||
TextColumn::make('team.name')
|
||||
->default('Global')
|
||||
->badge()
|
||||
->color(fn (mixed $state): string => str($state)->contains('Global') ? 'gray' : 'primary')
|
||||
->label(__('filament-shield::filament-shield.column.team'))
|
||||
->searchable()
|
||||
->visible(fn (): bool => static::shield()->isCentralApp() && Utils::isTenancyEnabled()),
|
||||
TextColumn::make('permissions_count')
|
||||
->badge()
|
||||
->label(__('filament-shield::filament-shield.column.permissions'))
|
||||
->counts('permissions')
|
||||
->color('primary'),
|
||||
TextColumn::make('updated_at')
|
||||
->label(__('filament-shield::filament-shield.column.updated_at'))
|
||||
->dateTime(),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
DeleteAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
DeleteBulkAction::make(),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListRoles::route('/'),
|
||||
'create' => CreateRole::route('/create'),
|
||||
'view' => ViewRole::route('/{record}'),
|
||||
'edit' => EditRole::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getModel(): string
|
||||
{
|
||||
return Utils::getRoleModel();
|
||||
}
|
||||
|
||||
public static function getSlug(?Panel $panel = null): string
|
||||
{
|
||||
return Utils::getResourceSlug();
|
||||
}
|
||||
|
||||
public static function getCluster(): ?string
|
||||
{
|
||||
return Utils::getResourceCluster();
|
||||
}
|
||||
|
||||
public static function getEssentialsPlugin(): ?FilamentShieldPlugin
|
||||
{
|
||||
return FilamentShieldPlugin::get();
|
||||
}
|
||||
}
|
||||
@@ -1,262 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Resources\SaleResource\Pages;
|
||||
use App\Models\Account;
|
||||
use App\Models\Branch;
|
||||
use App\Models\Client;
|
||||
use App\Models\Sale;
|
||||
use Awcodes\TableRepeater\Components\TableRepeater;
|
||||
use Awcodes\TableRepeater\Header;
|
||||
use Filament\Forms\Components\Checkbox;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\Hidden;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Forms\Get;
|
||||
use Filament\Forms\Set;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class SaleResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Sale::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-currency-dollar';
|
||||
|
||||
protected static bool $shouldRegisterNavigation = false;
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Select::make('client')
|
||||
->default(request()->query('client_id'))
|
||||
->options(Client::query()->get()->pluck('company', 'id'))
|
||||
->afterStateUpdated(function ($set, $get) {
|
||||
$set('branch_id', '');
|
||||
})
|
||||
->required()
|
||||
->live(),
|
||||
Select::make('branch_id')
|
||||
->relationship('branch', 'code')
|
||||
->options(fn ($get) => Branch::query()->where('client_id', $get('client'))->get()->pluck('code', 'id'))
|
||||
->required()
|
||||
->afterStateUpdated(function ($set, $get) {
|
||||
$set('current_series', static::getSeries($get));
|
||||
$set('transactions.*.branch_id', $get('branch_id'));
|
||||
})
|
||||
->live(),
|
||||
TextInput::make('current_series')
|
||||
->label('Series')
|
||||
->disabled(),
|
||||
DatePicker::make('happened_on')->label('Date')
|
||||
->required()
|
||||
->afterStateUpdated(function ($set, $get) {
|
||||
$set('transactions.*.happened_on', $get('happened_on'));
|
||||
})
|
||||
->native(false),
|
||||
Checkbox::make('with_discount')->label('With Discount?')->default(false)->live(),
|
||||
|
||||
TableRepeater::make('transactions')
|
||||
->headers(fn (Get $get): array => static::getTransactionTableHeader($get))
|
||||
->relationship('transactions')
|
||||
->schema(fn (Get $get): array => static::getTransactionTableFormSchema($get))
|
||||
->visible(fn (Get $get) => $get('branch_id') != null)
|
||||
->columnSpan('full'),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getSeries(Get $get): string
|
||||
{
|
||||
$branch = Branch::find($get('branch_id'));
|
||||
|
||||
if ($branch) {
|
||||
$currentSeries = $branch->current_series;
|
||||
|
||||
return str_pad($currentSeries + 1, 6, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
private static function getTransactionTableHeader(Get $get): array
|
||||
{
|
||||
if ($get('with_discount')) {
|
||||
return [
|
||||
Header::make('Charge Account'),
|
||||
Header::make('Description'),
|
||||
Header::make('Gross Amount'),
|
||||
Header::make('Exempt'),
|
||||
Header::make('Vatable Amount'),
|
||||
Header::make('Output Tax'),
|
||||
Header::make('Withholding Tax'),
|
||||
Header::make('Discount'),
|
||||
Header::make('Net Amount'),
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
Header::make('Charge Account'),
|
||||
Header::make('Description'),
|
||||
Header::make('Gross Amount'),
|
||||
Header::make('Exempt'),
|
||||
Header::make('Vatable Amount'),
|
||||
Header::make('Output Tax'),
|
||||
Header::make('Withholding Tax'),
|
||||
Header::make('Net Amount'),
|
||||
];
|
||||
}
|
||||
|
||||
private static function getTransactionTableFormSchema(Get $get): array
|
||||
{
|
||||
return [
|
||||
Select::make('account_id')->options(fn ($get) => static::getAccountOptions($get)),
|
||||
TextInput::make('description')->label('Description'),
|
||||
Hidden::make('branch_id')->default(fn (Get $get) => $get('../../branch_id')),
|
||||
TextInput::make('gross_amount')
|
||||
->numeric()
|
||||
->live(false, 500)
|
||||
->afterStateUpdated(function (Get $get, Set $set, ?string $old, ?string $state) {
|
||||
static::setDefaultFormValues($get, $set, $old, $state);
|
||||
})->default(0),
|
||||
TextInput::make('exempt')
|
||||
->numeric()
|
||||
->live()
|
||||
->afterStateUpdated(function (Get $get, Set $set, ?string $old, ?string $state) {
|
||||
static::setDefaultFormValues($get, $set, $old, $state);
|
||||
})->default(0),
|
||||
TextInput::make('vatable_amount')
|
||||
->numeric()
|
||||
->nullable()
|
||||
->live()
|
||||
->readOnly()
|
||||
->default(0),
|
||||
Hidden::make('happened_on')->default(fn (Get $get) => $get('../../happened_on')),
|
||||
Hidden::make('with_discount')->default(fn (Get $get) => $get('../../with_discount')),
|
||||
TextInput::make('output_tax')
|
||||
->numeric()
|
||||
->live()
|
||||
->afterStateUpdated(function (Get $get, Set $set, ?string $old, ?string $state) {
|
||||
|
||||
static::setDefaultFormValues($get, $set, $old, $state);
|
||||
})->default(0),
|
||||
TextInput::make('payable_withholding_tax')
|
||||
->numeric()
|
||||
->live()
|
||||
->afterStateUpdated(function (Get $get, Set $set, ?string $old, ?string $state) {
|
||||
|
||||
static::setDefaultFormValues($get, $set, $old, $state);
|
||||
})->default(0),
|
||||
TextInput::make('discount')
|
||||
->numeric()
|
||||
->readOnly()
|
||||
->visible(fn (Get $get) => $get('../../with_discount'))
|
||||
->live(),
|
||||
TextInput::make('net_amount')->numeric()->default(0),
|
||||
];
|
||||
}
|
||||
|
||||
private static function getAccountOptions($get)
|
||||
{
|
||||
$query = Account::query();
|
||||
|
||||
$query->where([
|
||||
'client_id' => $get('../../client'),
|
||||
]);
|
||||
|
||||
if ($get('../../branch_id')) {
|
||||
$query->whereHas('balances', function ($query) use ($get) {
|
||||
return $query->where('branch_id', $get('../../branch_id'));
|
||||
});
|
||||
}
|
||||
|
||||
$query->whereHas('accountType', function ($query) {
|
||||
return $query->where('type', 'Revenue');
|
||||
});
|
||||
|
||||
return $query->get()->pluck('account', 'id');
|
||||
}
|
||||
|
||||
private static function setDefaultFormValues(Get $get, Set $set, ?string $old, ?string $state)
|
||||
{
|
||||
$exempt = (float) $get('exempt');
|
||||
$withHoldingTax = (float) $get('payable_withholding_tax');
|
||||
$vatableSales = $get('gross_amount');
|
||||
$vatableAmount = 0;
|
||||
if ($vatableSales) {
|
||||
$vatableAmount = $vatableSales / 1.12;
|
||||
}
|
||||
|
||||
$discount = $exempt * .20;
|
||||
$outputTax = $vatableAmount * 0.12;
|
||||
|
||||
//default net amount
|
||||
$netAmount = (int) $vatableSales - $get('payable_withholding_tax');
|
||||
|
||||
//net amount if vatable
|
||||
if (ExpenseResource::getIsVatable($get)) {
|
||||
$netAmount = ($vatableAmount + $exempt) - $withHoldingTax;
|
||||
}
|
||||
|
||||
//if discounted
|
||||
if ($get('../../with_discount')) {
|
||||
$netAmount = $netAmount - $discount;
|
||||
}
|
||||
|
||||
$set('output_tax', number_format($outputTax, 2, '.', ''));
|
||||
$set('discount', number_format($discount, 2, '.', ''));
|
||||
$set('vatable_amount', number_format($vatableAmount, 2, '.', ''));
|
||||
$set('net_amount', number_format($netAmount, 2, '.', ''));
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('id')->label('ID')->sortable(),
|
||||
TextColumn::make('client.name')->label('Client')->sortable(),
|
||||
TextColumn::make('branch.name')->label('Branch')->sortable(),
|
||||
TextColumn::make('happened_on')->label('Date')->date()->sortable(),
|
||||
TextColumn::make('gross_amount')->label('Gross Amount')->numeric()->sortable(),
|
||||
TextColumn::make('exempt')->label('Exempt')->numeric()->sortable(),
|
||||
TextColumn::make('vatable_amount')->label('Vatable Amount')->numeric()->sortable(),
|
||||
TextColumn::make('output_tax')->label('Output Tax')->numeric()->sortable(),
|
||||
TextColumn::make('payable_withholding_tax')->label('Payable Withholding Tax')->numeric()->sortable(),
|
||||
TextColumn::make('discount')->label('Discount')->numeric()->sortable(),
|
||||
TextColumn::make('net_amount')->label('Net Amount')->numeric()->sortable(),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListSales::route('/'),
|
||||
'create' => Pages\CreateSale::route('/create'),
|
||||
'edit' => Pages\EditSale::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\SaleResource\Pages;
|
||||
|
||||
use App\Actions\Transactions\CreateTransactionAction;
|
||||
use App\DataObjects\CreateTransactionDTO;
|
||||
use App\Filament\Resources\SaleResource;
|
||||
use App\Models\Branch;
|
||||
use App\Models\Sale;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Pipeline;
|
||||
|
||||
class CreateSale extends CreateRecord
|
||||
{
|
||||
protected static string $resource = SaleResource::class;
|
||||
|
||||
protected function mutateFormDataBeforeCreate(array $data): array
|
||||
{
|
||||
return $this->getFormDataMutation($data);
|
||||
}
|
||||
|
||||
protected function handleRecordCreation(array $data): Model
|
||||
{
|
||||
$transactions = $this->data['transactions'] ?? [];
|
||||
return $this->processCreate($data, $transactions);
|
||||
}
|
||||
|
||||
public function getFormDataMutation(array $data): array
|
||||
{
|
||||
return Arr::except($data, ['client', 'transactions', 'with_discount']);
|
||||
}
|
||||
|
||||
public function processCreate(array $data, array $transactions): Model
|
||||
{
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
$record = Sale::create($data);
|
||||
$branch = $record->branch;
|
||||
|
||||
foreach ($transactions as $transaction) {
|
||||
$tData = [
|
||||
'branch_id' => $branch->id,
|
||||
'happened_on' => $record->happened_on,
|
||||
...$transaction,
|
||||
];
|
||||
|
||||
$payload = new CreateTransactionDTO(data: $tData, transactionable: $record);
|
||||
|
||||
Pipeline::send(passable: $payload)->through(
|
||||
[
|
||||
CreateTransactionAction::class,
|
||||
]
|
||||
)->thenReturn();
|
||||
}
|
||||
DB::commit();
|
||||
} catch (\Exception $exception) {
|
||||
DB::rollBack();
|
||||
throw new \Exception('Failed to save transactions : '.$exception->getMessage());
|
||||
}
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
protected function afterCreate(): void
|
||||
{
|
||||
$branch = Branch::find($this->data['branch_id']);
|
||||
}
|
||||
}
|
||||
101
app/Filament/Resources/Sales/Pages/CreateSale.php
Normal file
101
app/Filament/Resources/Sales/Pages/CreateSale.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Sales\Pages;
|
||||
|
||||
use App\Actions\Sales\CreateSaleAction;
|
||||
use App\Actions\Sales\SyncAccountsAction;
|
||||
use App\Actions\Transactions\CreateRecordTransactionsAction;
|
||||
use App\Commands\Clients\GenerateBaseAccountCommand;
|
||||
use App\Filament\Resources\Clients\ClientResource;
|
||||
use App\Filament\Resources\Sales\SaleResource;
|
||||
use App\Models\Branch;
|
||||
use App\Models\Client;
|
||||
use App\Models\Sale;
|
||||
use App\Services\Sales\SaleService;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\Actions;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CreateSale extends CreateRecord
|
||||
{
|
||||
protected static string $resource = SaleResource::class;
|
||||
|
||||
public ?int $clientId = null;
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
parent::mount();
|
||||
|
||||
$this->clientId = request()->integer('client_id');
|
||||
}
|
||||
|
||||
public function getBreadcrumbs(): array
|
||||
{
|
||||
$client = $this->getClient();
|
||||
|
||||
if (! $client) {
|
||||
return parent::getBreadcrumbs();
|
||||
}
|
||||
|
||||
return [
|
||||
ClientResource::getUrl('view', ['record' => $client->id]) => $client->company,
|
||||
ClientResource::getUrl('view', ['record' => $client->id]).'?activeRelationManager=3' => 'Sales',
|
||||
$this->getResource()::getUrl('create', ['client_id' => $client->id]) => 'Create',
|
||||
];
|
||||
}
|
||||
|
||||
protected function getClient(): Client|null
|
||||
{
|
||||
if (! $this->clientId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Client::find($this->clientId);
|
||||
}
|
||||
|
||||
protected function mutateFormDataBeforeCreate(array $data): array
|
||||
{
|
||||
return $this->getFormDataMutation($data);
|
||||
}
|
||||
|
||||
protected function handleRecordCreation(array $data): Model
|
||||
{
|
||||
$transactions = $this->data['transactions'] ?? [];
|
||||
return $this->processCreate($data, $transactions);
|
||||
}
|
||||
|
||||
public function getFormDataMutation(array $data): array
|
||||
{
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
|
||||
$data['gross_amount'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['gross_amount'] ?? 0));
|
||||
$data['exempt'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['exempt'] ?? 0));
|
||||
$data['vatable_amount'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['vatable_amount'] ?? 0));
|
||||
$data['output_tax'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['output_tax'] ?? 0));
|
||||
$data['payable_withholding_tax'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['payable_withholding_tax'] ?? 0));
|
||||
$discount = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['discount'] ?? 0));
|
||||
$data['discount'] = $discount;
|
||||
$data['net_amount'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['net_amount'] ?? 0)) + $discount;
|
||||
|
||||
return Arr::except($data, ['client', 'transactions']);
|
||||
}
|
||||
|
||||
public function processCreate(array $data, array $transactions): Model
|
||||
{
|
||||
$record = app(CreateSaleAction::class)($this->getFormDataMutation($data), $transactions);
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
protected function getRedirectUrl(): string
|
||||
{
|
||||
$client = $this->getClient();
|
||||
if (! $client) {
|
||||
return parent::getRedirectUrl();
|
||||
}
|
||||
return ClientResource::getUrl('view', ['record' => $client->id]).'?activeRelationManager=3';
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\SaleResource\Pages;
|
||||
namespace App\Filament\Resources\Sales\Pages;
|
||||
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Exception;
|
||||
use App\Actions\Transactions\CreateTransactionAction;
|
||||
use App\DataObjects\CreateTransactionDTO;
|
||||
use App\Filament\Resources\SaleResource;
|
||||
use App\Filament\Resources\Sales\SaleResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
@@ -19,7 +21,7 @@ class EditSale extends EditRecord
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -36,6 +38,16 @@ class EditSale extends EditRecord
|
||||
|
||||
public function getFormDataMutation(array $data): array
|
||||
{
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
|
||||
$data['gross_amount'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['gross_amount'] ?? 0));
|
||||
$data['exempt'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['exempt'] ?? 0));
|
||||
$data['vatable_amount'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['vatable_amount'] ?? 0));
|
||||
$data['output_tax'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['output_tax'] ?? 0));
|
||||
$data['payable_withholding_tax'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['payable_withholding_tax'] ?? 0));
|
||||
$data['discount'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['discount'] ?? 0));
|
||||
$data['net_amount'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['net_amount'] ?? 0));
|
||||
|
||||
return Arr::except($data, ['client', 'transactions', 'with_discount']);
|
||||
}
|
||||
|
||||
@@ -71,10 +83,20 @@ class EditSale extends EditRecord
|
||||
]
|
||||
)->thenReturn();
|
||||
}
|
||||
|
||||
$accountIds = collect($transactions)
|
||||
->pluck('account_id')
|
||||
->filter()
|
||||
->unique()
|
||||
->values()
|
||||
->all();
|
||||
|
||||
$record->accounts()->sync($accountIds);
|
||||
|
||||
DB::commit();
|
||||
} catch (\Exception $exception) {
|
||||
} catch (Exception $exception) {
|
||||
DB::rollBack();
|
||||
throw new \Exception('Failed to save transactions : '.$exception->getMessage());
|
||||
throw new Exception('Failed to save transactions : '.$exception->getMessage());
|
||||
}
|
||||
|
||||
return $record;
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\SaleResource\Pages;
|
||||
namespace App\Filament\Resources\Sales\Pages;
|
||||
|
||||
use App\Filament\Resources\SaleResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use App\Filament\Resources\Sales\SaleResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
@@ -13,7 +14,7 @@ class ListSales extends ListRecords
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
90
app/Filament/Resources/Sales/SaleResource.php
Normal file
90
app/Filament/Resources/Sales/SaleResource.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Sales;
|
||||
|
||||
use App\Filament\Resources\Expenses\ExpenseResource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Schemas\Components\Utilities\Get;
|
||||
use Filament\Schemas\Components\Utilities\Set;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use App\Filament\Resources\Sales\Pages\ListSales;
|
||||
use App\Filament\Resources\Sales\Pages\CreateSale;
|
||||
use App\Filament\Resources\Sales\Pages\EditSale;
|
||||
use App\Filament\Resources\SaleResource\Pages;
|
||||
use App\Filament\Resources\Sales\Schemas\CreateSaleSchema;
|
||||
use App\Models\Account;
|
||||
use App\Models\Branch;
|
||||
use App\Models\Client;
|
||||
use App\Models\Discount;
|
||||
use App\Models\Sale;
|
||||
use Filament\Forms\Components\Checkbox;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\Hidden;
|
||||
use Filament\Forms\Components\Repeater;
|
||||
use Filament\Forms\Components\Repeater\TableColumn;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Icetalker\FilamentTableRepeater\Forms\Components\TableRepeater;
|
||||
|
||||
class SaleResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Sale::class;
|
||||
|
||||
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-currency-dollar';
|
||||
|
||||
protected static bool $shouldRegisterNavigation = false;
|
||||
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return (new CreateSaleSchema())->configure($schema);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('branch.code')->label('Branch')->sortable(),
|
||||
TextColumn::make('reference_number')->label('Reference Number')->sortable(),
|
||||
TextColumn::make('happened_on')->label('Date')->date()->sortable(),
|
||||
TextColumn::make('user.name')->label('Created By')->sortable(),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListSales::route('/'),
|
||||
'create' => CreateSale::route('/create'),
|
||||
'edit' => EditSale::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
193
app/Filament/Resources/Sales/Schemas/CreateSaleSchema.php
Normal file
193
app/Filament/Resources/Sales/Schemas/CreateSaleSchema.php
Normal file
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Sales\Schemas;
|
||||
|
||||
use App\Filament\Resources\Expenses\ExpenseResource;
|
||||
use App\Models\Account;
|
||||
use App\Models\Branch;
|
||||
use App\Models\Client;
|
||||
use App\Models\Discount;
|
||||
use Filament\Forms\Components\Checkbox;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\Hidden;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Schemas\Components\Utilities\Get;
|
||||
use Filament\Schemas\Components\Utilities\Set;
|
||||
use Filament\Schemas\Schema;
|
||||
use Icetalker\FilamentTableRepeater\Forms\Components\TableRepeater;
|
||||
|
||||
class CreateSaleSchema
|
||||
{
|
||||
/**
|
||||
* Create a new class instance.
|
||||
*/
|
||||
public function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Select::make('client')
|
||||
->default(fn () => request()->integer('client_id'))
|
||||
->options(Client::query()->get()->pluck('company', 'id'))
|
||||
->afterStateUpdated(function ($set, $get) {
|
||||
$set('branch_id', '');
|
||||
})
|
||||
->required()
|
||||
->live(),
|
||||
Select::make('branch_id')
|
||||
->relationship('branch', 'code')
|
||||
->options(fn ($get) => Branch::query()->where('client_id', $get('client'))->get()->pluck('code', 'id'))
|
||||
->required()
|
||||
->afterStateUpdated(function ($set, $get) {
|
||||
$set('current_series', $this->getSeries($get));
|
||||
$set('transactions.*.branch_id', $get('branch_id'));
|
||||
})
|
||||
->live(),
|
||||
TextInput::make('current_series')
|
||||
->label('Series')
|
||||
->readOnly(),
|
||||
DatePicker::make('happened_on')->label('Date')
|
||||
->required()
|
||||
->afterStateUpdated(function ($set, $get) {
|
||||
$set('transactions.*.happened_on', $get('happened_on'));
|
||||
})
|
||||
->native(false),
|
||||
Checkbox::make('with_discount')->label('With Discount?')->default(false)->live(),
|
||||
|
||||
TableRepeater::make('transactions')
|
||||
->relationship('transactions')
|
||||
->schema([
|
||||
Select::make('account_id')->options(fn (Get $get) => $this->getAccountOptions($get)),
|
||||
TextInput::make('description')->label('Description'),
|
||||
|
||||
TextInput::make('gross_amount')
|
||||
->numeric()
|
||||
->live(false, 500)
|
||||
->afterStateUpdated(function (Get $get, Set $set, ?string $old, ?string $state) {
|
||||
$this->setDefaultFormValues($get, $set, $old, $state);
|
||||
})->default(0),
|
||||
|
||||
TextInput::make('vatable_amount')
|
||||
->numeric()
|
||||
->required(),
|
||||
TextInput::make('vatable_amount')
|
||||
->numeric()
|
||||
->required(),
|
||||
|
||||
TextInput::make('output_tax')
|
||||
->numeric()
|
||||
->live()
|
||||
->afterStateUpdated(function (Get $get, Set $set, ?string $old, ?string $state) {
|
||||
|
||||
$this->setDefaultFormValues($get, $set, $old, $state);
|
||||
})->default(0),
|
||||
TextInput::make('payable_withholding_tax')
|
||||
->numeric()
|
||||
->live()
|
||||
->afterStateUpdated(function (Get $get, Set $set, ?string $old, ?string $state) {
|
||||
$this->setDefaultFormValues($get, $set, $old, $state);
|
||||
})->default(0),
|
||||
TextInput::make('discount')
|
||||
->numeric()
|
||||
->disabled(fn (Get $get) => !$get('../../with_discount'))
|
||||
->live(),
|
||||
Select::make('discount_type')
|
||||
->options(fn (Get $get) => $this->getDiscountOptions($get))
|
||||
->disabled(fn (Get $get) => !$get('../../with_discount'))
|
||||
->required(fn (Get $get) => $get('../../with_discount')),
|
||||
TextInput::make('net_amount')->numeric()->default(0),
|
||||
Hidden::make('branch_id')->default(fn (Get $get) => $get('../../branch_id')),
|
||||
Hidden::make('happened_on')->default(fn (Get $get) => $get('../../happened_on')),
|
||||
Hidden::make('with_discount')->default(fn (Get $get) => $get('../../with_discount')),
|
||||
Hidden::make('exempt')->default(0),
|
||||
])
|
||||
->visible(fn (Get $get) => $get('branch_id') != null)
|
||||
->reorderable()
|
||||
->cloneable()
|
||||
->collapsible()
|
||||
->minItems(1)
|
||||
->columnSpan('full'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function getSeries(Get $get): string
|
||||
{
|
||||
$branch = Branch::find($get('branch_id'));
|
||||
|
||||
if ($branch) {
|
||||
$currentSeries = $branch->current_series;
|
||||
|
||||
return str_pad($currentSeries + 1, 6, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
public function getTableComponents(Get $get): array
|
||||
{
|
||||
return [
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
private function setDefaultFormValues(Get $get, Set $set, ?string $old, ?string $state)
|
||||
{
|
||||
$exempt = (float) $get('exempt');
|
||||
$withHoldingTax = (float) $get('payable_withholding_tax');
|
||||
$vatableSales = $get('gross_amount');
|
||||
$vatableAmount = 0;
|
||||
if ($vatableSales) {
|
||||
$vatableAmount = $vatableSales / 1.12;
|
||||
}
|
||||
|
||||
$discount = $exempt * .20;
|
||||
$outputTax = $vatableAmount * 0.12;
|
||||
|
||||
// default net amount
|
||||
$netAmount = (int) $vatableSales - $get('payable_withholding_tax');
|
||||
|
||||
// net amount if vatable
|
||||
if (ExpenseResource::getIsVatable($get)) {
|
||||
$netAmount = ($vatableAmount + $exempt) - $withHoldingTax;
|
||||
}
|
||||
|
||||
// if discounted
|
||||
if ($get('../../with_discount')) {
|
||||
$netAmount = $netAmount - $discount;
|
||||
}
|
||||
|
||||
$set('output_tax', number_format($outputTax, 2, '.', ''));
|
||||
// $set('discount', number_format($discount, 2, '.', ''));
|
||||
$set('vatable_amount', number_format($vatableAmount, 2, '.', ''));
|
||||
$set('net_amount', number_format($netAmount, 2, '.', ''));
|
||||
}
|
||||
|
||||
private function getDiscountOptions(Get $get)
|
||||
{
|
||||
$query = Discount::query()->where('client_id', $get('../../client'));
|
||||
|
||||
return $query->pluck('discount', 'id');
|
||||
}
|
||||
|
||||
private function getAccountOptions($get)
|
||||
{
|
||||
$query = Account::query();
|
||||
|
||||
$query->where([
|
||||
'client_id' => $get('../../client'),
|
||||
]);
|
||||
|
||||
// if ($get('../../branch_id')) {
|
||||
// $query->whereHas('balances', function ($query) use ($get) {
|
||||
// return $query->where('branch_id', $get('../../branch_id'));
|
||||
// });
|
||||
// }
|
||||
|
||||
$query->whereHas('accountType', function ($query) {
|
||||
return $query->where('type', 'Revenue');
|
||||
});
|
||||
|
||||
return $query->get()->pluck('account', 'id');
|
||||
}
|
||||
}
|
||||
@@ -1,400 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Shield;
|
||||
|
||||
use App\Filament\Resources\Shield\RoleResource\Pages;
|
||||
use BezhanSalleh\FilamentShield\Contracts\HasShieldPermissions;
|
||||
use BezhanSalleh\FilamentShield\Facades\FilamentShield;
|
||||
use BezhanSalleh\FilamentShield\FilamentShieldPlugin;
|
||||
use BezhanSalleh\FilamentShield\Forms\ShieldSelectAllToggle;
|
||||
use BezhanSalleh\FilamentShield\Support\Utils;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Components\Component;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\HtmlString;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class RoleResource extends Resource implements HasShieldPermissions
|
||||
{
|
||||
protected static ?string $recordTitleAttribute = 'name';
|
||||
|
||||
public static function getPermissionPrefixes(): array
|
||||
{
|
||||
return [
|
||||
'view',
|
||||
'view_any',
|
||||
'create',
|
||||
'update',
|
||||
'delete',
|
||||
'delete_any',
|
||||
];
|
||||
}
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\Grid::make()
|
||||
->schema([
|
||||
Forms\Components\Section::make()
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('name')
|
||||
->label(__('filament-shield::filament-shield.field.name'))
|
||||
->unique(ignoreRecord: true)
|
||||
->required()
|
||||
->maxLength(255),
|
||||
|
||||
Forms\Components\TextInput::make('guard_name')
|
||||
->label(__('filament-shield::filament-shield.field.guard_name'))
|
||||
->default(Utils::getFilamentAuthGuard())
|
||||
->nullable()
|
||||
->maxLength(255),
|
||||
|
||||
ShieldSelectAllToggle::make('select_all')
|
||||
->onIcon('heroicon-s-shield-check')
|
||||
->offIcon('heroicon-s-shield-exclamation')
|
||||
->label(__('filament-shield::filament-shield.field.select_all.name'))
|
||||
->helperText(fn (): HtmlString => new HtmlString(__('filament-shield::filament-shield.field.select_all.message')))
|
||||
->dehydrated(fn ($state): bool => $state),
|
||||
|
||||
])
|
||||
->columns([
|
||||
'sm' => 2,
|
||||
'lg' => 3,
|
||||
]),
|
||||
]),
|
||||
Forms\Components\Tabs::make('Permissions')
|
||||
->contained()
|
||||
->tabs([
|
||||
static::getTabFormComponentForResources(),
|
||||
static::getTabFormComponentForPage(),
|
||||
static::getTabFormComponentForWidget(),
|
||||
static::getTabFormComponentForCustomPermissions(),
|
||||
])
|
||||
->columnSpan('full'),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('name')
|
||||
->badge()
|
||||
->label(__('filament-shield::filament-shield.column.name'))
|
||||
->formatStateUsing(fn ($state): string => Str::headline($state))
|
||||
->colors(['primary'])
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('guard_name')
|
||||
->badge()
|
||||
->label(__('filament-shield::filament-shield.column.guard_name')),
|
||||
Tables\Columns\TextColumn::make('permissions_count')
|
||||
->badge()
|
||||
->label(__('filament-shield::filament-shield.column.permissions'))
|
||||
->counts('permissions')
|
||||
->colors(['success']),
|
||||
Tables\Columns\TextColumn::make('updated_at')
|
||||
->label(__('filament-shield::filament-shield.column.updated_at'))
|
||||
->dateTime(),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListRoles::route('/'),
|
||||
'create' => Pages\CreateRole::route('/create'),
|
||||
'view' => Pages\ViewRole::route('/{record}'),
|
||||
'edit' => Pages\EditRole::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getCluster(): ?string
|
||||
{
|
||||
return Utils::getResourceCluster() ?? static::$cluster;
|
||||
}
|
||||
|
||||
public static function getModel(): string
|
||||
{
|
||||
return Utils::getRoleModel();
|
||||
}
|
||||
|
||||
public static function getModelLabel(): string
|
||||
{
|
||||
return __('filament-shield::filament-shield.resource.label.role');
|
||||
}
|
||||
|
||||
public static function getPluralModelLabel(): string
|
||||
{
|
||||
return __('filament-shield::filament-shield.resource.label.roles');
|
||||
}
|
||||
|
||||
public static function shouldRegisterNavigation(): bool
|
||||
{
|
||||
return Utils::isResourceNavigationRegistered();
|
||||
}
|
||||
|
||||
public static function getNavigationGroup(): ?string
|
||||
{
|
||||
return 'Security Settings';
|
||||
}
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return __('filament-shield::filament-shield.nav.role.label');
|
||||
}
|
||||
|
||||
public static function getNavigationIcon(): string
|
||||
{
|
||||
return __('filament-shield::filament-shield.nav.role.icon');
|
||||
}
|
||||
|
||||
public static function getNavigationSort(): ?int
|
||||
{
|
||||
return Utils::getResourceNavigationSort();
|
||||
}
|
||||
|
||||
public static function getSlug(): string
|
||||
{
|
||||
return Utils::getResourceSlug();
|
||||
}
|
||||
|
||||
public static function getNavigationBadge(): ?string
|
||||
{
|
||||
return Utils::isResourceNavigationBadgeEnabled()
|
||||
? strval(static::getEloquentQuery()->count())
|
||||
: null;
|
||||
}
|
||||
|
||||
public static function isScopedToTenant(): bool
|
||||
{
|
||||
return Utils::isScopedToTenant();
|
||||
}
|
||||
|
||||
public static function canGloballySearch(): bool
|
||||
{
|
||||
return Utils::isResourceGloballySearchable() && count(static::getGloballySearchableAttributes()) && static::canViewAny();
|
||||
}
|
||||
|
||||
public static function getResourceEntitiesSchema(): ?array
|
||||
{
|
||||
return collect(FilamentShield::getResources())
|
||||
->sortKeys()
|
||||
->map(function ($entity) {
|
||||
$sectionLabel = strval(
|
||||
static::shield()->hasLocalizedPermissionLabels()
|
||||
? FilamentShield::getLocalizedResourceLabel($entity['fqcn'])
|
||||
: $entity['model']
|
||||
);
|
||||
|
||||
return Forms\Components\Section::make($sectionLabel)
|
||||
->description(fn () => new HtmlString('<span style="word-break: break-word;">'.Utils::showModelPath($entity['fqcn']).'</span>'))
|
||||
->compact()
|
||||
->schema([
|
||||
static::getCheckBoxListComponentForResource($entity),
|
||||
])
|
||||
->columnSpan(static::shield()->getSectionColumnSpan())
|
||||
->collapsible();
|
||||
})
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public static function getResourceTabBadgeCount(): ?int
|
||||
{
|
||||
return collect(FilamentShield::getResources())
|
||||
->map(fn ($resource) => count(static::getResourcePermissionOptions($resource)))
|
||||
->sum();
|
||||
}
|
||||
|
||||
public static function getResourcePermissionOptions(array $entity): array
|
||||
{
|
||||
return collect(Utils::getResourcePermissionPrefixes($entity['fqcn']))
|
||||
->flatMap(function ($permission) use ($entity) {
|
||||
$name = $permission.'_'.$entity['resource'];
|
||||
$label = static::shield()->hasLocalizedPermissionLabels()
|
||||
? FilamentShield::getLocalizedResourcePermissionLabel($permission)
|
||||
: $name;
|
||||
|
||||
return [
|
||||
$name => $label,
|
||||
];
|
||||
})
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public static function setPermissionStateForRecordPermissions(Component $component, string $operation, array $permissions, ?Model $record): void
|
||||
{
|
||||
|
||||
if (in_array($operation, ['edit', 'view'])) {
|
||||
|
||||
if (blank($record)) {
|
||||
return;
|
||||
}
|
||||
if ($component->isVisible() && count($permissions) > 0) {
|
||||
$component->state(
|
||||
collect($permissions)
|
||||
/** @phpstan-ignore-next-line */
|
||||
->filter(fn ($value, $key) => $record->checkPermissionTo($key))
|
||||
->keys()
|
||||
->toArray()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function getPageOptions(): array
|
||||
{
|
||||
return collect(FilamentShield::getPages())
|
||||
->flatMap(fn ($page) => [
|
||||
$page['permission'] => static::shield()->hasLocalizedPermissionLabels()
|
||||
? FilamentShield::getLocalizedPageLabel($page['class'])
|
||||
: $page['permission'],
|
||||
])
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public static function getWidgetOptions(): array
|
||||
{
|
||||
return collect(FilamentShield::getWidgets())
|
||||
->flatMap(fn ($widget) => [
|
||||
$widget['permission'] => static::shield()->hasLocalizedPermissionLabels()
|
||||
? FilamentShield::getLocalizedWidgetLabel($widget['class'])
|
||||
: $widget['permission'],
|
||||
])
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public static function getCustomPermissionOptions(): ?array
|
||||
{
|
||||
return FilamentShield::getCustomPermissions()
|
||||
->mapWithKeys(fn ($customPermission) => [
|
||||
$customPermission => static::shield()->hasLocalizedPermissionLabels() ? str($customPermission)->headline()->toString() : $customPermission,
|
||||
])
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public static function getTabFormComponentForResources(): Component
|
||||
{
|
||||
return static::shield()->hasSimpleResourcePermissionView()
|
||||
? static::getTabFormComponentForSimpleResourcePermissionsView()
|
||||
: Forms\Components\Tabs\Tab::make('resources')
|
||||
->label(__('filament-shield::filament-shield.resources'))
|
||||
->visible(fn (): bool => (bool) Utils::isResourceEntityEnabled())
|
||||
->badge(static::getResourceTabBadgeCount())
|
||||
->schema([
|
||||
Forms\Components\Grid::make()
|
||||
->schema(static::getResourceEntitiesSchema())
|
||||
->columns(static::shield()->getGridColumns()),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getCheckBoxListComponentForResource(array $entity): Component
|
||||
{
|
||||
$permissionsArray = static::getResourcePermissionOptions($entity);
|
||||
|
||||
return static::getCheckboxListFormComponent($entity['resource'], $permissionsArray, false);
|
||||
}
|
||||
|
||||
public static function getTabFormComponentForPage(): Component
|
||||
{
|
||||
$options = static::getPageOptions();
|
||||
$count = count($options);
|
||||
|
||||
return Forms\Components\Tabs\Tab::make('pages')
|
||||
->label(__('filament-shield::filament-shield.pages'))
|
||||
->visible(fn (): bool => (bool) Utils::isPageEntityEnabled() && $count > 0)
|
||||
->badge($count)
|
||||
->schema([
|
||||
static::getCheckboxListFormComponent('pages_tab', $options),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getTabFormComponentForWidget(): Component
|
||||
{
|
||||
$options = static::getWidgetOptions();
|
||||
$count = count($options);
|
||||
|
||||
return Forms\Components\Tabs\Tab::make('widgets')
|
||||
->label(__('filament-shield::filament-shield.widgets'))
|
||||
->visible(fn (): bool => (bool) Utils::isWidgetEntityEnabled() && $count > 0)
|
||||
->badge($count)
|
||||
->schema([
|
||||
static::getCheckboxListFormComponent('widgets_tab', $options),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getTabFormComponentForCustomPermissions(): Component
|
||||
{
|
||||
$options = static::getCustomPermissionOptions();
|
||||
$count = count($options);
|
||||
|
||||
return Forms\Components\Tabs\Tab::make('custom')
|
||||
->label(__('filament-shield::filament-shield.custom'))
|
||||
->visible(fn (): bool => (bool) Utils::isCustomPermissionEntityEnabled() && $count > 0)
|
||||
->badge($count)
|
||||
->schema([
|
||||
static::getCheckboxListFormComponent('custom_permissions', $options),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getTabFormComponentForSimpleResourcePermissionsView(): Component
|
||||
{
|
||||
$options = FilamentShield::getAllResourcePermissions();
|
||||
$count = count($options);
|
||||
|
||||
return Forms\Components\Tabs\Tab::make('resources')
|
||||
->label(__('filament-shield::filament-shield.resources'))
|
||||
->visible(fn (): bool => (bool) Utils::isResourceEntityEnabled() && $count > 0)
|
||||
->badge($count)
|
||||
->schema([
|
||||
static::getCheckboxListFormComponent('resources_tab', $options),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getCheckboxListFormComponent(string $name, array $options, bool $searchable = true): Component
|
||||
{
|
||||
return Forms\Components\CheckboxList::make($name)
|
||||
->label('')
|
||||
->options(fn (): array => $options)
|
||||
->searchable($searchable)
|
||||
->afterStateHydrated(
|
||||
fn (Component $component, string $operation, ?Model $record) => static::setPermissionStateForRecordPermissions(
|
||||
component: $component,
|
||||
operation: $operation,
|
||||
permissions: $options,
|
||||
record: $record
|
||||
)
|
||||
)
|
||||
->dehydrated(fn ($state) => ! blank($state))
|
||||
->bulkToggleable()
|
||||
->gridDirection('row')
|
||||
->columns(static::shield()->getCheckboxListColumns())
|
||||
->columnSpan(static::shield()->getCheckboxListColumnSpan());
|
||||
}
|
||||
|
||||
public static function shield(): FilamentShieldPlugin
|
||||
{
|
||||
return FilamentShieldPlugin::get();
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\TransmittalResource\Pages;
|
||||
|
||||
use App\Filament\Resources\TransmittalResource;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
use Throwable;
|
||||
|
||||
class CreateTransmittal extends CreateRecord
|
||||
{
|
||||
protected static string $resource = TransmittalResource::class;
|
||||
|
||||
public bool $willExport = false;
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function createAndExport(): void
|
||||
{
|
||||
$this->willExport = true;
|
||||
$this->create();
|
||||
}
|
||||
|
||||
public function afterCreate()
|
||||
{
|
||||
if ($this->willExport) {
|
||||
TransmittalResource::exportTransmittal([$this->record->id]);
|
||||
}
|
||||
}
|
||||
|
||||
public function getCreatedNotificationMessage(): ?string
|
||||
{
|
||||
if ($this->willExport) {
|
||||
return 'Transmittal Was Created Successfully!, Check your notification for file download link';
|
||||
}
|
||||
|
||||
return 'Transmittal Was Created Successfully!';
|
||||
}
|
||||
|
||||
protected function getFormActions(): array
|
||||
{
|
||||
return [
|
||||
$this->getCreateFormAction(),
|
||||
$this->getCreateAnotherFormAction(),
|
||||
Action::make('Create and Export')->action('createAndExport')->color('success'),
|
||||
$this->getCancelFormAction(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getRedirectUrl(): string
|
||||
{
|
||||
return $this->previousUrl ?? $this->getResource()::getUrl('index');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Transmittals\Pages;
|
||||
|
||||
use App\Filament\Resources\Transmittals\TransmittalResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateTransmittal extends CreateRecord
|
||||
{
|
||||
protected static string $resource = TransmittalResource::class;
|
||||
|
||||
protected function getRedirectUrl(): string
|
||||
{
|
||||
return $this->previousUrl ?? $this->getResource()::getUrl('index');
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\TransmittalResource\Pages;
|
||||
namespace App\Filament\Resources\Transmittals\Pages;
|
||||
|
||||
use App\Filament\Resources\TransmittalResource;
|
||||
use Filament\Actions\ViewAction;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use App\Filament\Resources\Transmittals\TransmittalResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
@@ -13,8 +15,8 @@ class EditTransmittal extends EditRecord
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\ViewAction::make(),
|
||||
Actions\DeleteAction::make(),
|
||||
ViewAction::make(),
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\TransmittalResource\Pages;
|
||||
namespace App\Filament\Resources\Transmittals\Pages;
|
||||
|
||||
use App\Filament\Resources\TransmittalResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use App\Filament\Resources\Transmittals\TransmittalResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
@@ -13,7 +14,7 @@ class ListTransmittals extends ListRecords
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\TransmittalResource\Pages;
|
||||
namespace App\Filament\Resources\Transmittals\Pages;
|
||||
|
||||
use App\Filament\Resources\TransmittalResource;
|
||||
use Filament\Actions\EditAction;
|
||||
use App\Filament\Resources\Transmittals\TransmittalResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ViewRecord;
|
||||
|
||||
@@ -13,7 +14,7 @@ class ViewTransmittal extends ViewRecord
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\EditAction::make(),
|
||||
EditAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
namespace App\Filament\Resources\Transmittals;
|
||||
|
||||
use Filament\Tables\Columns\Layout\Split;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Columns\Layout\Stack;
|
||||
use Filament\Tables\Columns\Layout\View;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\ViewAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Schemas\Schema;
|
||||
use App\Filament\Resources\Transmittals\Pages\ListTransmittals;
|
||||
use App\Filament\Resources\Transmittals\Pages\CreateTransmittal;
|
||||
use App\Filament\Resources\Transmittals\Pages\ViewTransmittal;
|
||||
use App\Filament\Resources\Transmittals\Pages\EditTransmittal;
|
||||
use App\Commands\Transmittal\GenerateTransmittalSeries;
|
||||
use App\Commands\Transmittal\StoreTransmittalCommand;
|
||||
use App\Exports\TransmittalsExport;
|
||||
use App\Filament\Resources\TransmittalResource\Pages;
|
||||
use App\Jobs\ExportCompleteJob;
|
||||
use App\Filament\Exports\TransmittalExcelExport;
|
||||
use App\Models\Branch;
|
||||
use App\Models\Client;
|
||||
use App\Models\Transmittal;
|
||||
@@ -17,22 +31,20 @@ use Filament\Forms\Components\Repeater;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Malzariey\FilamentDaterangepickerFilter\Filters\DateRangeFilter;
|
||||
|
||||
class TransmittalResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Transmittal::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||
|
||||
public static function getEloquentQuery(): Builder
|
||||
{
|
||||
@@ -43,8 +55,8 @@ class TransmittalResource extends Resource
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\Layout\Split::make([
|
||||
Tables\Columns\TextColumn::make('series')
|
||||
Split::make([
|
||||
TextColumn::make('series')
|
||||
->searchable(query: function (Builder $query, string $search): Builder {
|
||||
$wildcardSearch = '%' . str_replace(' ', '%', $search) . '%';
|
||||
|
||||
@@ -61,15 +73,15 @@ class TransmittalResource extends Resource
|
||||
->label('Series')
|
||||
->weight(FontWeight::Bold)
|
||||
->columnSpan(2),
|
||||
Tables\Columns\Layout\Stack::make([
|
||||
Tables\Columns\TextColumn::make('client.company')
|
||||
Stack::make([
|
||||
TextColumn::make('client.company')
|
||||
->searchable(query: function (Builder $query, string $search): Builder {
|
||||
return $query->whereHas('client', function (Builder $query) use ($search) {
|
||||
$query->where('company', 'like', '%' . str_replace(' ', '%', $search) . '%');
|
||||
});
|
||||
})
|
||||
->weight(FontWeight::SemiBold)->label('Client'),
|
||||
Tables\Columns\TextColumn::make('branch.code')
|
||||
TextColumn::make('branch.code')
|
||||
->searchable(query: function (Builder $query, string $search): Builder {
|
||||
return $query->whereHas('branch', function (Builder $query) use ($search) {
|
||||
$query->where('code', 'like', '%' . str_replace(' ', '%', $search) . '%');
|
||||
@@ -78,7 +90,7 @@ class TransmittalResource extends Resource
|
||||
->label('Branch'),
|
||||
]),
|
||||
]),
|
||||
Tables\Columns\Layout\View::make('transmittal.tables.collapsible-files-component')->collapsible(),
|
||||
View::make('transmittal.tables.collapsible-files-component')->collapsible(),
|
||||
])
|
||||
->filters([
|
||||
SelectFilter::make('client_id')->label('Client filter')->options(function () {
|
||||
@@ -97,14 +109,10 @@ class TransmittalResource extends Resource
|
||||
])
|
||||
->heading('Transmittals')
|
||||
->description('Click on toggle button at the end of table row to show additional details.')
|
||||
->actions(static::getTableActions())
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
Tables\Actions\BulkAction::make('Bulk Export')->action(function ($records) {
|
||||
|
||||
static::exportTransmittal(Arr::flatten($records->pluck('id')));
|
||||
}),
|
||||
->recordActions(static::getTableActions())
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
@@ -112,9 +120,20 @@ class TransmittalResource extends Resource
|
||||
public static function getTableActions(): array
|
||||
{
|
||||
return [
|
||||
Tables\Actions\Action::make('Export')->action(fn ($record) => static::exportTransmittal([$record->id])),
|
||||
Tables\Actions\ViewAction::make(),
|
||||
Tables\Actions\Action::make('Update Status')
|
||||
Action::make('Export')
|
||||
->label('Export as Excel')
|
||||
->icon('heroicon-o-arrow-down-tray')
|
||||
->action(function (Transmittal $record, $livewire) {
|
||||
$export = TransmittalExcelExport::make('transmittal');
|
||||
|
||||
return app()->call([$export, 'hydrate'], [
|
||||
'livewire' => $livewire,
|
||||
'records' => collect([$record]),
|
||||
'formData' => null,
|
||||
])->export();
|
||||
}),
|
||||
ViewAction::make(),
|
||||
Action::make('Update Status')
|
||||
->fillForm(function ($record) {
|
||||
return [
|
||||
'user_id' => $record->user_id,
|
||||
@@ -123,7 +142,7 @@ class TransmittalResource extends Resource
|
||||
'received_by' => $record->received_by,
|
||||
];
|
||||
})
|
||||
->form([
|
||||
->schema([
|
||||
Select::make('user_id')->label('Dispatch By')
|
||||
->relationship('user', 'name')
|
||||
->searchable()
|
||||
@@ -139,42 +158,22 @@ class TransmittalResource extends Resource
|
||||
})
|
||||
->icon('heroicon-o-pencil-square')
|
||||
->slideOver()
|
||||
->hidden(! auth()->user()->can('update_transmittal')),
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
->hidden(! Auth::user()->can('update_transmittal')),
|
||||
EditAction::make(),
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
public static function exportTransmittal(array $id): void
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
$recipient = auth()->user();
|
||||
|
||||
static::generateExportNotification();
|
||||
|
||||
(new TransmittalsExport([$id]))->store('public/transmittal-export.xlsx')->chain([
|
||||
app(ExportCompleteJob::class, ['user' => $recipient]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function generateExportNotification(): Notification
|
||||
{
|
||||
|
||||
return Notification::make()
|
||||
->title('Your export will be ready. check your notification for file download link.')
|
||||
->success()
|
||||
->send();
|
||||
}
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema(static::getFormSchema());
|
||||
return $schema
|
||||
->components(static::getFormSchema());
|
||||
}
|
||||
|
||||
public static function getFormSchema(): array
|
||||
{
|
||||
return [
|
||||
Forms\Components\Select::make('client_id')
|
||||
Select::make('client_id')
|
||||
->options(function () {
|
||||
return Client::query()->get()->pluck('company', 'id');
|
||||
})
|
||||
@@ -182,11 +181,11 @@ class TransmittalResource extends Resource
|
||||
->reactive()
|
||||
->required()
|
||||
->required()->columnSpan(3),
|
||||
Forms\Components\Select::make('branch_id')->label('Branch')->relationship('branch')->options(function (callable $get) {
|
||||
Select::make('branch_id')->label('Branch')->relationship('branch')->options(function (callable $get) {
|
||||
return Branch::query()->where('client_id', $get('client_id'))->get()->pluck('code', 'id');
|
||||
})->required(),
|
||||
Forms\Components\TextInput::make('series')->readOnly()->default((new GenerateTransmittalSeries)->execute([]))->unique('transmittals', ignoreRecord: true),
|
||||
Forms\Components\DatePicker::make('date_created')
|
||||
TextInput::make('series')->readOnly()->default((new GenerateTransmittalSeries)->execute([]))->unique('transmittals', ignoreRecord: true),
|
||||
DatePicker::make('date_created')
|
||||
->native(false)
|
||||
->required()->default(now()),
|
||||
|
||||
@@ -199,13 +198,13 @@ class TransmittalResource extends Resource
|
||||
->relationship('notes')
|
||||
->label('Note')
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('comment')->label('Note')->required(),
|
||||
TextInput::make('comment')->label('Note')->required(),
|
||||
]),
|
||||
Repeater::make('remarks')
|
||||
->relationship('remarks')
|
||||
->label('Remarks')
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('remark')->label('Remark')->required(),
|
||||
TextInput::make('remark')->label('Remark')->required(),
|
||||
]),
|
||||
])
|
||||
->columns(3)
|
||||
@@ -223,10 +222,10 @@ class TransmittalResource extends Resource
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListTransmittals::route('/'),
|
||||
'create' => Pages\CreateTransmittal::route('/create'),
|
||||
'view' => Pages\ViewTransmittal::route('/{record}'),
|
||||
'edit' => Pages\EditTransmittal::route('/{record}/edit'),
|
||||
'index' => ListTransmittals::route('/'),
|
||||
'create' => CreateTransmittal::route('/create'),
|
||||
'view' => ViewTransmittal::route('/{record}'),
|
||||
'edit' => EditTransmittal::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\UserResource\Pages;
|
||||
namespace App\Filament\Resources\Users\Pages;
|
||||
|
||||
use App\Filament\Resources\UserResource;
|
||||
use App\Filament\Resources\Users\UserResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateUser extends CreateRecord
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\UserResource\Pages;
|
||||
namespace App\Filament\Resources\Users\Pages;
|
||||
|
||||
use App\Filament\Resources\UserResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use App\Filament\Resources\Users\UserResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
@@ -13,7 +14,7 @@ class EditUser extends EditRecord
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\UserResource\Pages;
|
||||
namespace App\Filament\Resources\Users\Pages;
|
||||
|
||||
use App\Filament\Resources\UserResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use App\Filament\Resources\Users\UserResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
@@ -13,7 +14,7 @@ class ListUsers extends ListRecords
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make()->icon('heroicon-o-user-plus')->slideOver(),
|
||||
CreateAction::make()->icon('heroicon-o-user-plus')->slideOver(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
namespace App\Filament\Resources\Users;
|
||||
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Forms\Components\CheckboxList;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use App\Filament\Resources\Users\Pages\ListUsers;
|
||||
use App\Filament\Admin\Resources\UserResource\Pages;
|
||||
use App\Filament\Admin\Resources\UserResource\RelationManagers;
|
||||
use App\Models\User;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
@@ -16,21 +23,21 @@ class UserResource extends Resource
|
||||
{
|
||||
protected static ?string $model = User::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-user-group';
|
||||
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-user-group';
|
||||
|
||||
protected static ?string $navigationGroup = 'Security Settings';
|
||||
protected static string | \UnitEnum | null $navigationGroup = 'Security Settings';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return $form
|
||||
return $schema
|
||||
->columns([
|
||||
'default' => 2,
|
||||
])
|
||||
->schema([
|
||||
->components([
|
||||
TextInput::make('name')->required()->columnSpan(2),
|
||||
TextInput::make('email')->required()->email()->columnSpan(fn () : int => $form->getOperation() === 'edit' ? 2 : 1),
|
||||
TextInput::make('email')->required()->email()->columnSpan(fn () : int => $schema->getOperation() === 'edit' ? 2 : 1),
|
||||
TextInput::make('password')->required()->password()->hiddenOn('edit'),
|
||||
Forms\Components\CheckboxList::make('roles')
|
||||
CheckboxList::make('roles')
|
||||
->relationship('roles', 'name')
|
||||
->searchable()
|
||||
]);
|
||||
@@ -40,20 +47,20 @@ class UserResource extends Resource
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('name')->searchable(),
|
||||
Tables\Columns\TextColumn::make('email')->searchable(),
|
||||
TextColumn::make('name')->searchable(),
|
||||
TextColumn::make('email')->searchable(),
|
||||
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make()->slideOver(),
|
||||
Tables\Actions\DeleteAction::make()->requiresConfirmation()
|
||||
->recordActions([
|
||||
EditAction::make()->slideOver(),
|
||||
DeleteAction::make()->requiresConfirmation()
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
@@ -68,7 +75,7 @@ class UserResource extends Resource
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => \App\Filament\Resources\UserResource\Pages\ListUsers::route('/'),
|
||||
'index' => ListUsers::route('/'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use Filament\Notifications\Actions\Action as NotificationAction;
|
||||
use Filament\Actions\Action;
|
||||
use App\Models\Transmittal;
|
||||
use App\Models\User;
|
||||
use Barryvdh\DomPDF\Facade\Pdf;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
@@ -13,30 +16,41 @@ use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class ExportCompleteJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithQueue;
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*/
|
||||
public function __construct(private $user)
|
||||
public function __construct(private User $user, private array $ids)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
Notification::make()->success()
|
||||
$this->user->refresh();
|
||||
|
||||
$transmittals = Transmittal::query()
|
||||
->with(['client', 'branch', 'files.notes', 'files.remarks'])
|
||||
->whereIn('id', $this->ids)
|
||||
->get();
|
||||
|
||||
$pdf = Pdf::loadView('transmittal.export.transmittal-export-pdf', [
|
||||
'transmittals' => $transmittals,
|
||||
]);
|
||||
|
||||
$filename = 'transmittal-export-'.$this->user->id.'-'.now()->format('YmdHis').'.pdf';
|
||||
|
||||
Storage::disk('public')->put($filename, $pdf->output());
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Export Completed')
|
||||
->actions([
|
||||
NotificationAction::make('download_transmittal-export.xlsx')
|
||||
->label('Download File')
|
||||
->url(url: Storage::url('public/transmittal-export.xlsx') ,shouldOpenInNewTab: true)
|
||||
->markAsRead(),
|
||||
]
|
||||
)
|
||||
Action::make('download_transmittal_export')
|
||||
->label('Download PDF File')
|
||||
->url(Storage::url($filename), true)
|
||||
->markAsRead(),
|
||||
])
|
||||
->sendToDatabase($this->user);
|
||||
}
|
||||
}
|
||||
|
||||
28
app/Jobs/TestQueueJob.php
Normal file
28
app/Jobs/TestQueueJob.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class TestQueueJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithQueue;
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
Log::info('TestQueueJob executed');
|
||||
}
|
||||
}
|
||||
|
||||
58
app/Jobs/TransmittalPDFExportJob.php
Normal file
58
app/Jobs/TransmittalPDFExportJob.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use Filament\Actions\Action;
|
||||
use App\Models\Transmittal;
|
||||
use App\Models\User;
|
||||
use Barryvdh\DomPDF\Facade\Pdf;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Foundation\Queue\Queueable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class TransmittalPDFExportJob implements ShouldQueue
|
||||
{
|
||||
use Queueable, Dispatchable, InteractsWithQueue, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*/
|
||||
public function __construct(private User $user, private array $ids)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$this->user->refresh();
|
||||
|
||||
$transmittals = Transmittal::query()
|
||||
->with(['client', 'branch', 'files.notes', 'files.remarks'])
|
||||
->whereIn('id', $this->ids)
|
||||
->get();
|
||||
|
||||
$pdf = Pdf::loadView('transmittal.export.transmittal-export-pdf', [
|
||||
'transmittals' => $transmittals,
|
||||
]);
|
||||
|
||||
$filename = 'transmittal-export-'.$this->user->id.'-'.now()->format('YmdHis').'.pdf';
|
||||
|
||||
Storage::disk('public')->put($filename, $pdf->output());
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Export Completed')
|
||||
->actions([
|
||||
Action::make('download_transmittal_export')
|
||||
->label('Download PDF File')
|
||||
->url(Storage::url($filename), true)
|
||||
->markAsRead(),
|
||||
])
|
||||
->sendToDatabase($this->user);
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ class LoginForm extends Form
|
||||
/**
|
||||
* Attempt to authenticate the request's credentials.
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function authenticate(): void
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use App\Observers\AccountObserver;
|
||||
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
@@ -47,7 +48,7 @@ class Account extends Model
|
||||
return $this->hasMany(Balance::class);
|
||||
}
|
||||
|
||||
public function latestBalance(): \Illuminate\Database\Eloquent\Relations\HasOne
|
||||
public function latestBalance(): HasOne
|
||||
{
|
||||
return $this->hasOne(Balance::class)->latestOfMany();
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class AccountType extends Model
|
||||
/**
|
||||
* Get all of the accounts for the AccountType
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
* @return HasMany
|
||||
*/
|
||||
public function accounts(): HasMany
|
||||
{
|
||||
|
||||
@@ -20,7 +20,7 @@ class Balance extends Model
|
||||
/**
|
||||
* Get the ledger that owns the Balance
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function ledger(): BelongsTo
|
||||
{
|
||||
|
||||
@@ -78,4 +78,9 @@ class Client extends Model
|
||||
{
|
||||
return $this->hasManyThrough(Journal::class, Branch::class);
|
||||
}
|
||||
|
||||
public function discounts(): HasMany
|
||||
{
|
||||
return $this->hasMany(Discount::class);
|
||||
}
|
||||
}
|
||||
|
||||
10
app/Models/Discount.php
Normal file
10
app/Models/Discount.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Discount extends Model
|
||||
{
|
||||
protected $fillable = ['discount'];
|
||||
}
|
||||
@@ -5,6 +5,7 @@ namespace App\Models;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
|
||||
class Expense extends Model
|
||||
@@ -43,4 +44,14 @@ class Expense extends Model
|
||||
{
|
||||
return $this->belongsTo(Branch::class);
|
||||
}
|
||||
|
||||
public function accounts(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Account::class, 'account_expense')->withTimestamps();
|
||||
}
|
||||
|
||||
public function getAccountsListAttribute(): string
|
||||
{
|
||||
return $this->accounts->pluck('account')->implode(', ');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ class Ledger extends Model
|
||||
/**
|
||||
* Get all of the balances for the Ledger
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
* @return HasMany
|
||||
*/
|
||||
public function balances(): HasMany
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ class PermissionType extends Model
|
||||
/**
|
||||
* Get all of the permissions for the PermissionType
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
* @return HasMany
|
||||
*/
|
||||
public function permissions(): HasMany
|
||||
{
|
||||
|
||||
@@ -5,13 +5,21 @@ namespace App\Models;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
|
||||
class Sale extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = [];
|
||||
protected $fillable = [
|
||||
'branch_id',
|
||||
'user_id',
|
||||
'client_id',
|
||||
'happened_on',
|
||||
'reference_number',
|
||||
'buyer'
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'happened_on' => 'date:Y-m-d',
|
||||
@@ -43,4 +51,19 @@ class Sale extends Model
|
||||
{
|
||||
return $this->belongsTo(Branch::class);
|
||||
}
|
||||
|
||||
public function accounts(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Account::class, 'account_sale')->withTimestamps();
|
||||
}
|
||||
|
||||
public function getAccountsListAttribute(): string
|
||||
{
|
||||
return $this->accounts->pluck('account')->implode(', ');
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Observers;
|
||||
|
||||
use App\Commands\Clients\GenerateBaseAccountCommand;
|
||||
use App\Models\Client;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
@@ -12,45 +13,7 @@ class ClientObserver
|
||||
*/
|
||||
public function created(Client $client): void
|
||||
{
|
||||
DB::transaction(function () use ($client) {
|
||||
$client->accounts()->createMany([
|
||||
[
|
||||
'account_type_id' => 1,
|
||||
'account' => 'Cash',
|
||||
'normal_balance' => 'debit',
|
||||
],
|
||||
[
|
||||
'account_type_id' => 1,
|
||||
'account' => 'Input Tax',
|
||||
'normal_balance' => 'debit',
|
||||
],
|
||||
[
|
||||
'account_type_id' => 1,
|
||||
'account' => 'Creditable Withholding Tax',
|
||||
'normal_balance' => 'debit',
|
||||
],
|
||||
[
|
||||
'account_type_id' => 2,
|
||||
'account' => 'Output Tax',
|
||||
'normal_balance' => 'credit',
|
||||
],
|
||||
[
|
||||
'account_type_id' => 2,
|
||||
'account' => 'Payable Withholding Tax',
|
||||
'normal_balance' => 'credit',
|
||||
],
|
||||
[
|
||||
'account_type_id' => 5,
|
||||
'account' => 'Vat Exempt Revenue',
|
||||
'normal_balance' => 'credit',
|
||||
],
|
||||
[
|
||||
'account_type_id' => 4,
|
||||
'account' => 'Sales Discount',
|
||||
'normal_balance' => 'debit',
|
||||
],
|
||||
]);
|
||||
});
|
||||
app(GenerateBaseAccountCommand::class)->execute($client);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,108 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use App\Models\Branch;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class BranchPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('view_any_branch');
|
||||
return $authUser->can('ViewAny:Branch');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, Branch $branch): bool
|
||||
public function view(AuthUser $authUser, Branch $branch): bool
|
||||
{
|
||||
return $user->can('view_branch');
|
||||
return $authUser->can('View:Branch');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('create_branch');
|
||||
return $authUser->can('Create:Branch');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, Branch $branch): bool
|
||||
public function update(AuthUser $authUser, Branch $branch): bool
|
||||
{
|
||||
return $user->can('update_branch');
|
||||
return $authUser->can('Update:Branch');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, Branch $branch): bool
|
||||
public function delete(AuthUser $authUser, Branch $branch): bool
|
||||
{
|
||||
return $user->can('delete_branch');
|
||||
return $authUser->can('Delete:Branch');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk delete.
|
||||
*/
|
||||
public function deleteAny(User $user): bool
|
||||
public function restore(AuthUser $authUser, Branch $branch): bool
|
||||
{
|
||||
return $user->can('delete_any_branch');
|
||||
return $authUser->can('Restore:Branch');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete.
|
||||
*/
|
||||
public function forceDelete(User $user, Branch $branch): bool
|
||||
public function forceDelete(AuthUser $authUser, Branch $branch): bool
|
||||
{
|
||||
return $user->can('force_delete_branch');
|
||||
return $authUser->can('ForceDelete:Branch');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently bulk delete.
|
||||
*/
|
||||
public function forceDeleteAny(User $user): bool
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('force_delete_any_branch');
|
||||
return $authUser->can('ForceDeleteAny:Branch');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore.
|
||||
*/
|
||||
public function restore(User $user, Branch $branch): bool
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('restore_branch');
|
||||
return $authUser->can('RestoreAny:Branch');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk restore.
|
||||
*/
|
||||
public function restoreAny(User $user): bool
|
||||
public function replicate(AuthUser $authUser, Branch $branch): bool
|
||||
{
|
||||
return $user->can('restore_any_branch');
|
||||
return $authUser->can('Replicate:Branch');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can replicate.
|
||||
*/
|
||||
public function replicate(User $user, Branch $branch): bool
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('replicate_branch');
|
||||
return $authUser->can('Reorder:Branch');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can reorder.
|
||||
*/
|
||||
public function reorder(User $user): bool
|
||||
{
|
||||
return $user->can('reorder_branch');
|
||||
}
|
||||
}
|
||||
@@ -1,108 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use App\Models\Client;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class ClientPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('view_any_client');
|
||||
return $authUser->can('ViewAny:Client');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, Client $client): bool
|
||||
public function view(AuthUser $authUser, Client $client): bool
|
||||
{
|
||||
return $user->can('view_client');
|
||||
return $authUser->can('View:Client');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('create_client');
|
||||
return $authUser->can('Create:Client');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, Client $client): bool
|
||||
public function update(AuthUser $authUser, Client $client): bool
|
||||
{
|
||||
return $user->can('update_client');
|
||||
return $authUser->can('Update:Client');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, Client $client): bool
|
||||
public function delete(AuthUser $authUser, Client $client): bool
|
||||
{
|
||||
return $user->can('delete_client');
|
||||
return $authUser->can('Delete:Client');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk delete.
|
||||
*/
|
||||
public function deleteAny(User $user): bool
|
||||
public function restore(AuthUser $authUser, Client $client): bool
|
||||
{
|
||||
return $user->can('delete_any_client');
|
||||
return $authUser->can('Restore:Client');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete.
|
||||
*/
|
||||
public function forceDelete(User $user, Client $client): bool
|
||||
public function forceDelete(AuthUser $authUser, Client $client): bool
|
||||
{
|
||||
return $user->can('force_delete_client');
|
||||
return $authUser->can('ForceDelete:Client');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently bulk delete.
|
||||
*/
|
||||
public function forceDeleteAny(User $user): bool
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('force_delete_any_client');
|
||||
return $authUser->can('ForceDeleteAny:Client');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore.
|
||||
*/
|
||||
public function restore(User $user, Client $client): bool
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('restore_client');
|
||||
return $authUser->can('RestoreAny:Client');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk restore.
|
||||
*/
|
||||
public function restoreAny(User $user): bool
|
||||
public function replicate(AuthUser $authUser, Client $client): bool
|
||||
{
|
||||
return $user->can('restore_any_client');
|
||||
return $authUser->can('Replicate:Client');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can replicate.
|
||||
*/
|
||||
public function replicate(User $user, Client $client): bool
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('replicate_client');
|
||||
return $authUser->can('Reorder:Client');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can reorder.
|
||||
*/
|
||||
public function reorder(User $user): bool
|
||||
{
|
||||
return $user->can('reorder_client');
|
||||
}
|
||||
}
|
||||
70
app/Policies/DiscountPolicy.php
Normal file
70
app/Policies/DiscountPolicy.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use App\Models\Discount;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class DiscountPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:Discount');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, Discount $discount): bool
|
||||
{
|
||||
return $authUser->can('View:Discount');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:Discount');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, Discount $discount): bool
|
||||
{
|
||||
return $authUser->can('Update:Discount');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, Discount $discount): bool
|
||||
{
|
||||
return $authUser->can('Delete:Discount');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, Discount $discount): bool
|
||||
{
|
||||
return $authUser->can('Restore:Discount');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, Discount $discount): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:Discount');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:Discount');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:Discount');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, Discount $discount): bool
|
||||
{
|
||||
return $authUser->can('Replicate:Discount');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:Discount');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,108 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use App\Models\Expense;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class ExpensePolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('view_any_expense');
|
||||
return $authUser->can('ViewAny:Expense');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, Expense $expense): bool
|
||||
public function view(AuthUser $authUser, Expense $expense): bool
|
||||
{
|
||||
return $user->can('view_expense');
|
||||
return $authUser->can('View:Expense');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('create_expense');
|
||||
return $authUser->can('Create:Expense');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, Expense $expense): bool
|
||||
public function update(AuthUser $authUser, Expense $expense): bool
|
||||
{
|
||||
return $user->can('update_expense');
|
||||
return $authUser->can('Update:Expense');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, Expense $expense): bool
|
||||
public function delete(AuthUser $authUser, Expense $expense): bool
|
||||
{
|
||||
return $user->can('delete_expense');
|
||||
return $authUser->can('Delete:Expense');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk delete.
|
||||
*/
|
||||
public function deleteAny(User $user): bool
|
||||
public function restore(AuthUser $authUser, Expense $expense): bool
|
||||
{
|
||||
return $user->can('delete_any_expense');
|
||||
return $authUser->can('Restore:Expense');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete.
|
||||
*/
|
||||
public function forceDelete(User $user, Expense $expense): bool
|
||||
public function forceDelete(AuthUser $authUser, Expense $expense): bool
|
||||
{
|
||||
return $user->can('force_delete_expense');
|
||||
return $authUser->can('ForceDelete:Expense');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently bulk delete.
|
||||
*/
|
||||
public function forceDeleteAny(User $user): bool
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('force_delete_any_expense');
|
||||
return $authUser->can('ForceDeleteAny:Expense');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore.
|
||||
*/
|
||||
public function restore(User $user, Expense $expense): bool
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('restore_expense');
|
||||
return $authUser->can('RestoreAny:Expense');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk restore.
|
||||
*/
|
||||
public function restoreAny(User $user): bool
|
||||
public function replicate(AuthUser $authUser, Expense $expense): bool
|
||||
{
|
||||
return $user->can('restore_any_expense');
|
||||
return $authUser->can('Replicate:Expense');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can replicate.
|
||||
*/
|
||||
public function replicate(User $user, Expense $expense): bool
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('replicate_expense');
|
||||
return $authUser->can('Reorder:Expense');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can reorder.
|
||||
*/
|
||||
public function reorder(User $user): bool
|
||||
{
|
||||
return $user->can('reorder_expense');
|
||||
}
|
||||
}
|
||||
@@ -1,108 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use Spatie\Permission\Models\Role;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class RolePolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('view_any_shield::role');
|
||||
return $authUser->can('ViewAny:Role');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, Role $role): bool
|
||||
public function view(AuthUser $authUser, Role $role): bool
|
||||
{
|
||||
return $user->can('view_shield::role');
|
||||
return $authUser->can('View:Role');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('create_shield::role');
|
||||
return $authUser->can('Create:Role');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, Role $role): bool
|
||||
public function update(AuthUser $authUser, Role $role): bool
|
||||
{
|
||||
return $user->can('update_shield::role');
|
||||
return $authUser->can('Update:Role');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, Role $role): bool
|
||||
public function delete(AuthUser $authUser, Role $role): bool
|
||||
{
|
||||
return $user->can('delete_shield::role');
|
||||
return $authUser->can('Delete:Role');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk delete.
|
||||
*/
|
||||
public function deleteAny(User $user): bool
|
||||
public function restore(AuthUser $authUser, Role $role): bool
|
||||
{
|
||||
return $user->can('delete_any_shield::role');
|
||||
return $authUser->can('Restore:Role');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete.
|
||||
*/
|
||||
public function forceDelete(User $user, Role $role): bool
|
||||
public function forceDelete(AuthUser $authUser, Role $role): bool
|
||||
{
|
||||
return $user->can('{{ ForceDelete }}');
|
||||
return $authUser->can('ForceDelete:Role');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently bulk delete.
|
||||
*/
|
||||
public function forceDeleteAny(User $user): bool
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('{{ ForceDeleteAny }}');
|
||||
return $authUser->can('ForceDeleteAny:Role');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore.
|
||||
*/
|
||||
public function restore(User $user, Role $role): bool
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('{{ Restore }}');
|
||||
return $authUser->can('RestoreAny:Role');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk restore.
|
||||
*/
|
||||
public function restoreAny(User $user): bool
|
||||
public function replicate(AuthUser $authUser, Role $role): bool
|
||||
{
|
||||
return $user->can('{{ RestoreAny }}');
|
||||
return $authUser->can('Replicate:Role');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can replicate.
|
||||
*/
|
||||
public function replicate(User $user, Role $role): bool
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('{{ Replicate }}');
|
||||
return $authUser->can('Reorder:Role');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can reorder.
|
||||
*/
|
||||
public function reorder(User $user): bool
|
||||
{
|
||||
return $user->can('{{ Reorder }}');
|
||||
}
|
||||
}
|
||||
@@ -1,108 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use App\Models\Sale;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class SalePolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('view_any_sale');
|
||||
return $authUser->can('ViewAny:Sale');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, Sale $sale): bool
|
||||
public function view(AuthUser $authUser, Sale $sale): bool
|
||||
{
|
||||
return $user->can('view_sale');
|
||||
return $authUser->can('View:Sale');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('create_sale');
|
||||
return $authUser->can('Create:Sale');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, Sale $sale): bool
|
||||
public function update(AuthUser $authUser, Sale $sale): bool
|
||||
{
|
||||
return $user->can('update_sale');
|
||||
return $authUser->can('Update:Sale');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, Sale $sale): bool
|
||||
public function delete(AuthUser $authUser, Sale $sale): bool
|
||||
{
|
||||
return $user->can('delete_sale');
|
||||
return $authUser->can('Delete:Sale');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk delete.
|
||||
*/
|
||||
public function deleteAny(User $user): bool
|
||||
public function restore(AuthUser $authUser, Sale $sale): bool
|
||||
{
|
||||
return $user->can('delete_any_sale');
|
||||
return $authUser->can('Restore:Sale');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete.
|
||||
*/
|
||||
public function forceDelete(User $user, Sale $sale): bool
|
||||
public function forceDelete(AuthUser $authUser, Sale $sale): bool
|
||||
{
|
||||
return $user->can('force_delete_sale');
|
||||
return $authUser->can('ForceDelete:Sale');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently bulk delete.
|
||||
*/
|
||||
public function forceDeleteAny(User $user): bool
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('force_delete_any_sale');
|
||||
return $authUser->can('ForceDeleteAny:Sale');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore.
|
||||
*/
|
||||
public function restore(User $user, Sale $sale): bool
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('restore_sale');
|
||||
return $authUser->can('RestoreAny:Sale');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk restore.
|
||||
*/
|
||||
public function restoreAny(User $user): bool
|
||||
public function replicate(AuthUser $authUser, Sale $sale): bool
|
||||
{
|
||||
return $user->can('restore_any_sale');
|
||||
return $authUser->can('Replicate:Sale');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can replicate.
|
||||
*/
|
||||
public function replicate(User $user, Sale $sale): bool
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('replicate_sale');
|
||||
return $authUser->can('Reorder:Sale');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can reorder.
|
||||
*/
|
||||
public function reorder(User $user): bool
|
||||
{
|
||||
return $user->can('reorder_sale');
|
||||
}
|
||||
}
|
||||
@@ -1,108 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use App\Models\Transmittal;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class TransmittalPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('view_any_transmittal');
|
||||
return $authUser->can('ViewAny:Transmittal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, Transmittal $transmittal): bool
|
||||
public function view(AuthUser $authUser, Transmittal $transmittal): bool
|
||||
{
|
||||
return $user->can('view_transmittal');
|
||||
return $authUser->can('View:Transmittal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('create_transmittal');
|
||||
return $authUser->can('Create:Transmittal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, Transmittal $transmittal): bool
|
||||
public function update(AuthUser $authUser, Transmittal $transmittal): bool
|
||||
{
|
||||
return $user->can('update_transmittal');
|
||||
return $authUser->can('Update:Transmittal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, Transmittal $transmittal): bool
|
||||
public function delete(AuthUser $authUser, Transmittal $transmittal): bool
|
||||
{
|
||||
return $user->can('delete_transmittal');
|
||||
return $authUser->can('Delete:Transmittal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk delete.
|
||||
*/
|
||||
public function deleteAny(User $user): bool
|
||||
public function restore(AuthUser $authUser, Transmittal $transmittal): bool
|
||||
{
|
||||
return $user->can('delete_any_transmittal');
|
||||
return $authUser->can('Restore:Transmittal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete.
|
||||
*/
|
||||
public function forceDelete(User $user, Transmittal $transmittal): bool
|
||||
public function forceDelete(AuthUser $authUser, Transmittal $transmittal): bool
|
||||
{
|
||||
return $user->can('force_delete_transmittal');
|
||||
return $authUser->can('ForceDelete:Transmittal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently bulk delete.
|
||||
*/
|
||||
public function forceDeleteAny(User $user): bool
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('force_delete_any_transmittal');
|
||||
return $authUser->can('ForceDeleteAny:Transmittal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore.
|
||||
*/
|
||||
public function restore(User $user, Transmittal $transmittal): bool
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('restore_transmittal');
|
||||
return $authUser->can('RestoreAny:Transmittal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk restore.
|
||||
*/
|
||||
public function restoreAny(User $user): bool
|
||||
public function replicate(AuthUser $authUser, Transmittal $transmittal): bool
|
||||
{
|
||||
return $user->can('restore_any_transmittal');
|
||||
return $authUser->can('Replicate:Transmittal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can replicate.
|
||||
*/
|
||||
public function replicate(User $user, Transmittal $transmittal): bool
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('replicate_transmittal');
|
||||
return $authUser->can('Reorder:Transmittal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can reorder.
|
||||
*/
|
||||
public function reorder(User $user): bool
|
||||
{
|
||||
return $user->can('reorder_transmittal');
|
||||
}
|
||||
}
|
||||
@@ -2,106 +2,66 @@
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class UserPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('view_any_user');
|
||||
return $authUser->can('ViewAny:User');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user): bool
|
||||
public function view(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('view_user');
|
||||
return $authUser->can('View:User');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('create_user');
|
||||
return $authUser->can('Create:User');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user): bool
|
||||
public function update(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('update_user');
|
||||
return $authUser->can('Update:User');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user): bool
|
||||
public function delete(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('delete_user');
|
||||
return $authUser->can('Delete:User');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk delete.
|
||||
*/
|
||||
public function deleteAny(User $user): bool
|
||||
public function restore(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('delete_any_user');
|
||||
return $authUser->can('Restore:User');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete.
|
||||
*/
|
||||
public function forceDelete(User $user): bool
|
||||
public function forceDelete(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('force_delete_user');
|
||||
return $authUser->can('ForceDelete:User');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently bulk delete.
|
||||
*/
|
||||
public function forceDeleteAny(User $user): bool
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('force_delete_any_user');
|
||||
return $authUser->can('ForceDeleteAny:User');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore.
|
||||
*/
|
||||
public function restore(User $user): bool
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('restore_user');
|
||||
return $authUser->can('RestoreAny:User');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk restore.
|
||||
*/
|
||||
public function restoreAny(User $user): bool
|
||||
public function replicate(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('restore_any_user');
|
||||
return $authUser->can('Replicate:User');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk restore.
|
||||
*/
|
||||
public function replicate(User $user): bool
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $user->can('replicate_user');
|
||||
return $authUser->can('Reorder:User');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can reorder.
|
||||
*/
|
||||
public function reorder(User $user): bool
|
||||
{
|
||||
return $user->can('reorder_user');
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Providers\Filament;
|
||||
|
||||
use Filament\Pages\Dashboard;
|
||||
use Filament\Widgets\AccountWidget;
|
||||
use BezhanSalleh\FilamentShield\FilamentShieldPlugin;
|
||||
use Filament\Navigation\NavigationItem;
|
||||
use Filament\Http\Middleware\Authenticate;
|
||||
@@ -18,6 +20,7 @@ use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
|
||||
use Illuminate\Routing\Middleware\SubstituteBindings;
|
||||
use Illuminate\Session\Middleware\AuthenticateSession;
|
||||
use Illuminate\Session\Middleware\StartSession;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\View\Middleware\ShareErrorsFromSession;
|
||||
|
||||
class AdminPanelProvider extends PanelProvider
|
||||
@@ -38,19 +41,19 @@ class AdminPanelProvider extends PanelProvider
|
||||
->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources')
|
||||
->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages')
|
||||
->pages([
|
||||
Pages\Dashboard::class,
|
||||
Dashboard::class,
|
||||
])
|
||||
->navigationItems([
|
||||
NavigationItem::make('Horizon')
|
||||
->url(fn (): string => url(config('horizon.path')))
|
||||
->icon('heroicon-o-queue-list')
|
||||
->group('System')
|
||||
->visible(fn (): bool => auth()->user()?->hasRole('super_admin') ?? false),
|
||||
->visible(fn (): bool => Auth::user()?->hasRole('super_admin') ?? false),
|
||||
])
|
||||
->databaseNotifications()
|
||||
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
|
||||
->widgets([
|
||||
Widgets\AccountWidget::class,
|
||||
AccountWidget::class,
|
||||
])
|
||||
->middleware([
|
||||
EncryptCookies::class,
|
||||
|
||||
@@ -9,23 +9,25 @@
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.2",
|
||||
"awcodes/filament-table-repeater": "^3.0",
|
||||
"bezhansalleh/filament-shield": "^3.2",
|
||||
"filament/filament": "^3.2",
|
||||
"barryvdh/laravel-dompdf": "^2.0",
|
||||
"bezhansalleh/filament-shield": "^4.1",
|
||||
"filament/filament": "~4.0",
|
||||
"icetalker/filament-table-repeater": "^2.0",
|
||||
"laravel/framework": "^11.9",
|
||||
"laravel/horizon": "^5.44",
|
||||
"laravel/tinker": "^2.9",
|
||||
"livewire/livewire": "^3.4",
|
||||
"livewire/volt": "^1.0",
|
||||
"maatwebsite/excel": "^3.1",
|
||||
"malzariey/filament-daterangepicker-filter": "^2.8",
|
||||
"pxlrbt/filament-excel": "^2.3",
|
||||
"malzariey/filament-daterangepicker-filter": "^4.0",
|
||||
"pxlrbt/filament-excel": "^3.0",
|
||||
"spatie/laravel-data": "^4.7",
|
||||
"staudenmeir/belongs-to-through": "^2.16",
|
||||
"yemenopensource/filament-excel": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.23",
|
||||
"filament/upgrade": "4.0",
|
||||
"laravel/boost": "^2.1",
|
||||
"laravel/breeze": "^2.1",
|
||||
"laravel/pint": "^1.13",
|
||||
|
||||
1991
composer.lock
generated
1991
composer.lock
generated
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user