migrate to gtea from bistbucket
This commit is contained in:
18
public/restaurant/.editorconfig
Normal file
18
public/restaurant/.editorconfig
Normal file
@@ -0,0 +1,18 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
|
||||
[docker-compose.yml]
|
||||
indent_size = 4
|
||||
70
public/restaurant/.env.example
Normal file
70
public/restaurant/.env.example
Normal file
@@ -0,0 +1,70 @@
|
||||
APP_NAME="Mighty Restaurant"
|
||||
APP_ENV=local
|
||||
APP_KEY=base64:pTtyyGt6XClh4fiSLpaiD33fl+trueJg8xbJ5O9xusc=
|
||||
APP_DEBUG=false
|
||||
APP_URL=http://127.0.0.1:8000
|
||||
|
||||
APP_LOCALE=en
|
||||
APP_FALLBACK_LOCALE=en
|
||||
APP_FAKER_LOCALE=en_US
|
||||
|
||||
APP_MAINTENANCE_DRIVER=file
|
||||
# APP_MAINTENANCE_STORE=database
|
||||
|
||||
PHP_CLI_SERVER_WORKERS=4
|
||||
|
||||
BCRYPT_ROUNDS=12
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_STACK=single
|
||||
LOG_DEPRECATIONS_CHANNEL=null
|
||||
LOG_LEVEL=debug
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=codenichebd_restaurant
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=
|
||||
|
||||
SESSION_DRIVER=file
|
||||
SESSION_LIFETIME=120
|
||||
SESSION_ENCRYPT=true
|
||||
SESSION_PATH=/
|
||||
SESSION_DOMAIN=null
|
||||
|
||||
BROADCAST_CONNECTION=log
|
||||
FILESYSTEM_DISK=local
|
||||
QUEUE_CONNECTION=file
|
||||
|
||||
CACHE_STORE=file
|
||||
# CACHE_PREFIX=
|
||||
|
||||
MEMCACHED_HOST=127.0.0.1
|
||||
|
||||
REDIS_CLIENT=phpredis
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=sandbox.smtp.mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_USERNAME=2ec3b6026804f8
|
||||
MAIL_PASSWORD=0e6a7e10c57da7
|
||||
MAIL_FROM_ADDRESS="hello@example.com"
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
AWS_DEFAULT_REGION=us-east-1
|
||||
AWS_BUCKET=
|
||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
|
||||
VITE_APP_NAME="${APP_NAME}"
|
||||
ORDER_CANCEL_LIMIT=5
|
||||
USER_FCM_TOKEN=""
|
||||
|
||||
VERCEL_TOKEN=""
|
||||
VERCEL_PROJECT_ID=""
|
||||
DEVICE_API_KEY=""
|
||||
11
public/restaurant/.gitattributes
vendored
Normal file
11
public/restaurant/.gitattributes
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
* text=auto eol=lf
|
||||
|
||||
*.blade.php diff=html
|
||||
*.css diff=css
|
||||
*.html diff=html
|
||||
*.md diff=markdown
|
||||
*.php diff=php
|
||||
|
||||
/.github export-ignore
|
||||
CHANGELOG.md export-ignore
|
||||
.styleci.yml export-ignore
|
||||
24
public/restaurant/.gitignore
vendored
Normal file
24
public/restaurant/.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
*.log
|
||||
.DS_Store
|
||||
.env
|
||||
.env.backup
|
||||
.env.production
|
||||
.phpactor.json
|
||||
.phpunit.result.cache
|
||||
/.fleet
|
||||
/.idea
|
||||
/.nova
|
||||
/.phpunit.cache
|
||||
/.vscode
|
||||
/.zed
|
||||
/auth.json
|
||||
/node_modules
|
||||
/public/build
|
||||
/public/hot
|
||||
/public/storage
|
||||
/storage/*.key
|
||||
/storage/pail
|
||||
/vendor
|
||||
Homestead.json
|
||||
Homestead.yaml
|
||||
Thumbs.db
|
||||
67
public/restaurant/.htaccess
Normal file
67
public/restaurant/.htaccess
Normal file
@@ -0,0 +1,67 @@
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
|
||||
# Redirect to public folder
|
||||
RewriteRule ^(.*)$ /restaurant/$1 [L]
|
||||
</IfModule>
|
||||
|
||||
# Laravel specific rules
|
||||
<IfModule mod_negotiation.c>
|
||||
Options -MultiViews -Indexes
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_headers.c>
|
||||
<FilesMatch "\.(png|jpg|jpeg|gif|css|js|ico|svg|woff|woff2)$">
|
||||
Header set Cache-Control "max-age=31536000, public"
|
||||
</FilesMatch>
|
||||
</IfModule>
|
||||
|
||||
# Handle front controller
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^ index.php [L]
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_headers.c>
|
||||
<FilesMatch "\.(jpg|jpeg|png|webp|pdf|webm|ogg)$">
|
||||
Header set Access-Control-Allow-Origin "*"
|
||||
</FilesMatch>
|
||||
</IfModule>
|
||||
|
||||
# BEGIN cPanel-generated php ini directives, do not edit
|
||||
# Manual editing of this file may result in unexpected behavior.
|
||||
# To make changes to this file, use the cPanel MultiPHP INI Editor (Home >> Software >> MultiPHP INI Editor)
|
||||
# For more information, read our documentation (https://go.cpanel.net/EA4ModifyINI)
|
||||
<IfModule php7_module>
|
||||
php_flag display_errors Off
|
||||
php_value max_execution_time 30000
|
||||
php_value max_input_time 300
|
||||
php_value max_input_vars 10000
|
||||
php_value memory_limit 1024M
|
||||
php_value post_max_size 1024M
|
||||
php_value session.gc_maxlifetime 1440
|
||||
php_value session.save_path "/var/cpanel/php/sessions/ea-php74"
|
||||
php_value upload_max_filesize 1024M
|
||||
php_flag zlib.output_compression On
|
||||
</IfModule>
|
||||
<IfModule lsapi_module>
|
||||
php_flag display_errors Off
|
||||
php_value max_execution_time 30000
|
||||
php_value max_input_time 300
|
||||
php_value max_input_vars 10000
|
||||
php_value memory_limit 1024M
|
||||
php_value post_max_size 1024M
|
||||
php_value session.gc_maxlifetime 1440
|
||||
php_value session.save_path "/var/cpanel/php/sessions/ea-php74"
|
||||
php_value upload_max_filesize 1024M
|
||||
php_flag zlib.output_compression On
|
||||
</IfModule>
|
||||
# END cPanel-generated php ini directives, do not edit
|
||||
|
||||
# php -- BEGIN cPanel-generated handler, do not edit
|
||||
# Set the “ea-php72” package as the default “PHP” programming language.
|
||||
#<IfModule mime_module>
|
||||
# AddHandler application/x-httpd-ea-php83___lsphp .php .php8 .phtml
|
||||
#</IfModule>
|
||||
# php -- END cPanel-generated handler, do not edit
|
||||
61
public/restaurant/.htaccess2
Normal file
61
public/restaurant/.htaccess2
Normal file
@@ -0,0 +1,61 @@
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
|
||||
# Redirect to public folder
|
||||
RewriteRule ^(.*)$ public/$1 [L]
|
||||
</IfModule>
|
||||
|
||||
# Laravel specific rules
|
||||
<IfModule mod_negotiation.c>
|
||||
Options -MultiViews -Indexes
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_headers.c>
|
||||
<FilesMatch "\.(png|jpg|jpeg|gif|css|js|ico|svg|woff|woff2)$">
|
||||
Header set Cache-Control "max-age=31536000, public"
|
||||
</FilesMatch>
|
||||
</IfModule>
|
||||
|
||||
# Handle front controller
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^ index.php [L]
|
||||
</IfModule>
|
||||
|
||||
# BEGIN cPanel-generated php ini directives, do not edit
|
||||
# Manual editing of this file may result in unexpected behavior.
|
||||
# To make changes to this file, use the cPanel MultiPHP INI Editor (Home >> Software >> MultiPHP INI Editor)
|
||||
# For more information, read our documentation (https://go.cpanel.net/EA4ModifyINI)
|
||||
<IfModule php7_module>
|
||||
php_flag display_errors Off
|
||||
php_value max_execution_time 30000
|
||||
php_value max_input_time 300
|
||||
php_value max_input_vars 10000
|
||||
php_value memory_limit 1024M
|
||||
php_value post_max_size 1024M
|
||||
php_value session.gc_maxlifetime 1440
|
||||
php_value session.save_path "/var/cpanel/php/sessions/ea-php74"
|
||||
php_value upload_max_filesize 1024M
|
||||
php_flag zlib.output_compression On
|
||||
</IfModule>
|
||||
<IfModule lsapi_module>
|
||||
php_flag display_errors Off
|
||||
php_value max_execution_time 30000
|
||||
php_value max_input_time 300
|
||||
php_value max_input_vars 10000
|
||||
php_value memory_limit 1024M
|
||||
php_value post_max_size 1024M
|
||||
php_value session.gc_maxlifetime 1440
|
||||
php_value session.save_path "/var/cpanel/php/sessions/ea-php74"
|
||||
php_value upload_max_filesize 1024M
|
||||
php_flag zlib.output_compression On
|
||||
</IfModule>
|
||||
# END cPanel-generated php ini directives, do not edit
|
||||
|
||||
# php -- BEGIN cPanel-generated handler, do not edit
|
||||
# Set the “ea-php83” package as the default “PHP” programming language.
|
||||
<IfModule mime_module>
|
||||
AddHandler application/x-httpd-ea-php83 .php .php8 .phtml
|
||||
</IfModule>
|
||||
# php -- END cPanel-generated handler, do not edit
|
||||
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Repositories;
|
||||
|
||||
use App\Abstracts\EntityRepository;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Modules\Accounting\Models\Account;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class AccountRepository extends EntityRepository
|
||||
{
|
||||
public string $table = Account::TABLE_NAME;
|
||||
|
||||
protected array $fillableColumns = [
|
||||
'restaurant_id',
|
||||
'name',
|
||||
'code',
|
||||
'type',
|
||||
'opening_balance',
|
||||
'current_balance',
|
||||
'status',
|
||||
];
|
||||
|
||||
protected function getQuery(): Builder
|
||||
{
|
||||
return parent::getQuery();
|
||||
}
|
||||
|
||||
protected function getFilterData(array $filterData = []): array
|
||||
{
|
||||
$defaultArgs = [
|
||||
'perPage' => 10,
|
||||
'search' => '',
|
||||
'orderBy' => 'id',
|
||||
'order' => 'desc',
|
||||
'with_deleted' => false,
|
||||
];
|
||||
|
||||
return array_merge($defaultArgs, $filterData);
|
||||
}
|
||||
|
||||
private function getAccountQuery(): Builder
|
||||
{
|
||||
return $this->getQuery()
|
||||
->select(
|
||||
"{$this->table}.id",
|
||||
"{$this->table}.restaurant_id",
|
||||
"{$this->table}.name",
|
||||
"{$this->table}.code",
|
||||
"{$this->table}.type",
|
||||
"{$this->table}.opening_balance",
|
||||
"{$this->table}.current_balance",
|
||||
"{$this->table}.status",
|
||||
"{$this->table}.created_at",
|
||||
"{$this->table}.updated_at",
|
||||
"{$this->table}.deleted_at"
|
||||
);
|
||||
}
|
||||
|
||||
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
|
||||
{
|
||||
$searchable = "%$searchedText%";
|
||||
|
||||
return $query->where("{$this->table}.name", 'LIKE', $searchable)
|
||||
->orWhere("{$this->table}.status", 'LIKE', $searchable);
|
||||
}
|
||||
|
||||
public function getAll(array $filterData = []): Paginator
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getAccountQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
if (! empty($filter['search'])) {
|
||||
$query = $this->filterSearchQuery($query, $filter['search']);
|
||||
}
|
||||
|
||||
return $query
|
||||
->orderBy($filter['orderBy'], $filter['order'])
|
||||
->paginate($filter['perPage']);
|
||||
}
|
||||
|
||||
public function getCount(array $filterData = []): int
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
|
||||
{
|
||||
$item = $this->getAccountQuery()
|
||||
->where($columnName, $columnValue)
|
||||
->first($selects);
|
||||
|
||||
if (empty($item)) {
|
||||
throw new Exception(
|
||||
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
|
||||
Response::HTTP_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(array $data): object
|
||||
{
|
||||
$data = $this->prepareForDB($data);
|
||||
$id = $this->getQuery()->insertGetId($data);
|
||||
|
||||
return Account::find($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update(int $id, array $data): object
|
||||
{
|
||||
$item = Account::findOrFail($id);
|
||||
$data = $this->prepareForDB($data, $item);
|
||||
parent::update($id, $data);
|
||||
|
||||
return $this->getById($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function prepareForDB(array $data, ?object $item = null): array
|
||||
{
|
||||
$data = parent::prepareForDB($data, $item);
|
||||
|
||||
if (empty($item)) {
|
||||
$data['created_at'] = now();
|
||||
$data['restaurant_id'] = $this->getCurrentRestaurantId();
|
||||
$data['status'] = 1;
|
||||
} else {
|
||||
$data['updated_at'] = now();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getExceptionMessages(): array
|
||||
{
|
||||
return [
|
||||
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'Account does not exist.',
|
||||
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'Account could not be deleted.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Repositories;
|
||||
|
||||
use App\Abstracts\EntityRepository;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Modules\Accounting\Models\DepositCategory;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class DepositCategoryRepository extends EntityRepository
|
||||
{
|
||||
public string $table = DepositCategory::TABLE_NAME;
|
||||
|
||||
protected array $fillableColumns = [
|
||||
'restaurant_id',
|
||||
'name',
|
||||
'status',
|
||||
'created_by',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
];
|
||||
|
||||
protected function getQuery(): Builder
|
||||
{
|
||||
return parent::getQuery();
|
||||
}
|
||||
|
||||
protected function getFilterData(array $filterData = []): array
|
||||
{
|
||||
$defaultArgs = [
|
||||
'perPage' => 10,
|
||||
'search' => '',
|
||||
'orderBy' => 'id',
|
||||
'order' => 'desc',
|
||||
'with_deleted' => false,
|
||||
];
|
||||
|
||||
return array_merge($defaultArgs, $filterData);
|
||||
}
|
||||
|
||||
private function getDepositCategoryQuery(): Builder
|
||||
{
|
||||
return $this->getQuery()
|
||||
->select(
|
||||
"{$this->table}.id",
|
||||
"{$this->table}.restaurant_id",
|
||||
"{$this->table}.name",
|
||||
"{$this->table}.status",
|
||||
"{$this->table}.created_at",
|
||||
"{$this->table}.deleted_at"
|
||||
);
|
||||
}
|
||||
|
||||
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
|
||||
{
|
||||
$searchable = "%$searchedText%";
|
||||
|
||||
return $query->where("{$this->table}.name", 'LIKE', $searchable)
|
||||
->orWhere("{$this->table}.status", 'LIKE', $searchable);
|
||||
}
|
||||
|
||||
public function getAll(array $filterData = []): Paginator
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getDepositCategoryQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
if (! empty($filter['search'])) {
|
||||
$query = $this->filterSearchQuery($query, $filter['search']);
|
||||
}
|
||||
|
||||
return $query
|
||||
->orderBy($filter['orderBy'], $filter['order'])
|
||||
->paginate($filter['perPage']);
|
||||
}
|
||||
|
||||
public function getCount(array $filterData = []): int
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
|
||||
{
|
||||
$item = $this->getDepositCategoryQuery()
|
||||
->where($columnName, $columnValue)
|
||||
->first($selects);
|
||||
|
||||
if (empty($item)) {
|
||||
throw new Exception(
|
||||
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
|
||||
Response::HTTP_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(array $data): object
|
||||
{
|
||||
$data = $this->prepareForDB($data);
|
||||
$id = $this->getQuery()->insertGetId($data);
|
||||
|
||||
return DepositCategory::find($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update(int $id, array $data): object
|
||||
{
|
||||
$item = DepositCategory::findOrFail($id);
|
||||
$data = $this->prepareForDB($data, $item);
|
||||
parent::update($id, $data);
|
||||
|
||||
return $this->getById($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function prepareForDB(array $data, ?object $item = null): array
|
||||
{
|
||||
$data = parent::prepareForDB($data, $item);
|
||||
|
||||
if (empty($item)) {
|
||||
$data['created_at'] = now();
|
||||
$data['restaurant_id'] = $this->getCurrentRestaurantId();
|
||||
$data['status'] = 1;
|
||||
} else {
|
||||
$data['updated_at'] = now();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getExceptionMessages(): array
|
||||
{
|
||||
return [
|
||||
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'DepositCategory does not exist.',
|
||||
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'DepositCategory could not be deleted.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Repositories;
|
||||
|
||||
use App\Abstracts\EntityRepository;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Modules\Accounting\Models\Deposit;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class DepositRepository extends EntityRepository
|
||||
{
|
||||
public string $table = Deposit::TABLE_NAME;
|
||||
|
||||
protected array $fillableColumns = [
|
||||
'restaurant_id',
|
||||
'fund_id',
|
||||
'account_id',
|
||||
'deposit_category_id',
|
||||
'amount',
|
||||
'transaction_date',
|
||||
'voucher_no',
|
||||
'received_from',
|
||||
'note',
|
||||
'created_by',
|
||||
'status',
|
||||
];
|
||||
|
||||
protected function getQuery(): Builder
|
||||
{
|
||||
return parent::getQuery();
|
||||
}
|
||||
|
||||
protected function getFilterData(array $filterData = []): array
|
||||
{
|
||||
$defaultArgs = [
|
||||
'perPage' => 10,
|
||||
'search' => '',
|
||||
'orderBy' => 'id',
|
||||
'order' => 'desc',
|
||||
'with_deleted' => false,
|
||||
];
|
||||
|
||||
return array_merge($defaultArgs, $filterData);
|
||||
}
|
||||
|
||||
private function getDepositQuery(): Builder
|
||||
{
|
||||
return $this->getQuery()
|
||||
->select(
|
||||
"{$this->table}.id",
|
||||
"{$this->table}.restaurant_id",
|
||||
"{$this->table}.fund_id",
|
||||
"{$this->table}.account_id",
|
||||
'accounts.name as account_name',
|
||||
"{$this->table}.deposit_category_id",
|
||||
'deposit_categories.name as category_name',
|
||||
"{$this->table}.amount",
|
||||
"{$this->table}.transaction_date",
|
||||
"{$this->table}.voucher_no",
|
||||
"{$this->table}.received_from",
|
||||
"{$this->table}.note",
|
||||
"{$this->table}.created_by",
|
||||
"{$this->table}.status",
|
||||
"{$this->table}.created_at",
|
||||
"{$this->table}.deleted_at"
|
||||
)
|
||||
->leftJoin('deposit_categories', 'deposit_categories.id', '=', "{$this->table}.deposit_category_id")
|
||||
->leftJoin('accounts', 'accounts.id', '=', "{$this->table}.account_id");
|
||||
}
|
||||
|
||||
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
|
||||
{
|
||||
$searchable = "%$searchedText%";
|
||||
|
||||
return $query->where("{$this->table}.transaction_date", 'LIKE', $searchable)
|
||||
->orWhere("{$this->table}.status", 'LIKE', $searchable);
|
||||
}
|
||||
|
||||
public function getAll(array $filterData = []): Paginator
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getDepositQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
if (! empty($filter['search'])) {
|
||||
$query = $this->filterSearchQuery($query, $filter['search']);
|
||||
}
|
||||
|
||||
return $query
|
||||
->orderBy($filter['orderBy'], $filter['order'])
|
||||
->paginate($filter['perPage']);
|
||||
}
|
||||
|
||||
public function getCount(array $filterData = []): int
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
|
||||
{
|
||||
$item = $this->getDepositQuery()
|
||||
->where($columnName, $columnValue)
|
||||
->first($selects);
|
||||
|
||||
if (empty($item)) {
|
||||
throw new Exception(
|
||||
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
|
||||
Response::HTTP_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(array $data): object
|
||||
{
|
||||
$data = $this->prepareForDB($data);
|
||||
$id = $this->getQuery()->insertGetId($data);
|
||||
|
||||
return Deposit::find($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update(int $id, array $data): object
|
||||
{
|
||||
$item = Deposit::findOrFail($id);
|
||||
$data = $this->prepareForDB($data, $item);
|
||||
parent::update($id, $data);
|
||||
|
||||
return $this->getById($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function prepareForDB(array $data, ?object $item = null): array
|
||||
{
|
||||
$data = parent::prepareForDB($data, $item);
|
||||
|
||||
if (empty($item)) {
|
||||
$data['created_at'] = now();
|
||||
$data['restaurant_id'] = $this->getCurrentRestaurantId();
|
||||
$data['status'] = 1;
|
||||
} else {
|
||||
$data['updated_at'] = now();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getExceptionMessages(): array
|
||||
{
|
||||
return [
|
||||
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'Deposit does not exist.',
|
||||
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'Deposit could not be deleted.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Repositories;
|
||||
|
||||
use App\Abstracts\EntityRepository;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Modules\Accounting\Models\ExpenseCategory;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class ExpenseCategoryRepository extends EntityRepository
|
||||
{
|
||||
public string $table = ExpenseCategory::TABLE_NAME;
|
||||
|
||||
protected array $fillableColumns = [
|
||||
'restaurant_id',
|
||||
'name',
|
||||
'status',
|
||||
'created_by',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
];
|
||||
|
||||
protected function getQuery(): Builder
|
||||
{
|
||||
return parent::getQuery();
|
||||
}
|
||||
|
||||
protected function getFilterData(array $filterData = []): array
|
||||
{
|
||||
$defaultArgs = [
|
||||
'perPage' => 10,
|
||||
'search' => '',
|
||||
'orderBy' => 'id',
|
||||
'order' => 'desc',
|
||||
'with_deleted' => false,
|
||||
];
|
||||
|
||||
return array_merge($defaultArgs, $filterData);
|
||||
}
|
||||
|
||||
private function getExpenseCategoryQuery(): Builder
|
||||
{
|
||||
return $this->getQuery()
|
||||
->select(
|
||||
"{$this->table}.id",
|
||||
"{$this->table}.restaurant_id",
|
||||
"{$this->table}.name",
|
||||
"{$this->table}.status",
|
||||
"{$this->table}.created_at",
|
||||
"{$this->table}.deleted_at"
|
||||
);
|
||||
}
|
||||
|
||||
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
|
||||
{
|
||||
$searchable = "%$searchedText%";
|
||||
|
||||
return $query->where("{$this->table}.name", 'LIKE', $searchable)
|
||||
->orWhere("{$this->table}.status", 'LIKE', $searchable);
|
||||
}
|
||||
|
||||
public function getAll(array $filterData = []): Paginator
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getExpenseCategoryQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
if (! empty($filter['search'])) {
|
||||
$query = $this->filterSearchQuery($query, $filter['search']);
|
||||
}
|
||||
|
||||
return $query
|
||||
->orderBy($filter['orderBy'], $filter['order'])
|
||||
->paginate($filter['perPage']);
|
||||
}
|
||||
|
||||
public function getCount(array $filterData = []): int
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
|
||||
{
|
||||
$item = $this->getExpenseCategoryQuery()
|
||||
->where($columnName, $columnValue)
|
||||
->first($selects);
|
||||
|
||||
if (empty($item)) {
|
||||
throw new Exception(
|
||||
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
|
||||
Response::HTTP_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(array $data): object
|
||||
{
|
||||
$data = $this->prepareForDB($data);
|
||||
$id = $this->getQuery()->insertGetId($data);
|
||||
|
||||
return ExpenseCategory::find($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update(int $id, array $data): object
|
||||
{
|
||||
$item = ExpenseCategory::findOrFail($id);
|
||||
$data = $this->prepareForDB($data, $item);
|
||||
parent::update($id, $data);
|
||||
|
||||
return $this->getById($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function prepareForDB(array $data, ?object $item = null): array
|
||||
{
|
||||
$data = parent::prepareForDB($data, $item);
|
||||
|
||||
if (empty($item)) {
|
||||
$data['created_at'] = now();
|
||||
$data['restaurant_id'] = $this->getCurrentRestaurantId();
|
||||
$data['status'] = 1;
|
||||
} else {
|
||||
$data['updated_at'] = now();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getExceptionMessages(): array
|
||||
{
|
||||
return [
|
||||
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'ExpenseCategory does not exist.',
|
||||
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'ExpenseCategory could not be deleted.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Repositories;
|
||||
|
||||
use App\Abstracts\EntityRepository;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Modules\Accounting\Models\Expense;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class ExpenseRepository extends EntityRepository
|
||||
{
|
||||
public string $table = Expense::TABLE_NAME;
|
||||
|
||||
protected array $fillableColumns = [
|
||||
'restaurant_id',
|
||||
'fund_id',
|
||||
'account_id',
|
||||
'expense_category_id',
|
||||
'amount',
|
||||
'transaction_date',
|
||||
'voucher_no',
|
||||
'received_from',
|
||||
'note',
|
||||
'created_by',
|
||||
'status',
|
||||
];
|
||||
|
||||
protected function getQuery(): Builder
|
||||
{
|
||||
return parent::getQuery();
|
||||
}
|
||||
|
||||
protected function getFilterData(array $filterData = []): array
|
||||
{
|
||||
$defaultArgs = [
|
||||
'perPage' => 10,
|
||||
'search' => '',
|
||||
'orderBy' => 'id',
|
||||
'order' => 'desc',
|
||||
'with_deleted' => false,
|
||||
];
|
||||
|
||||
return array_merge($defaultArgs, $filterData);
|
||||
}
|
||||
|
||||
private function getExpenseQuery(): Builder
|
||||
{
|
||||
return $this->getQuery()
|
||||
->select(
|
||||
"{$this->table}.id",
|
||||
"{$this->table}.restaurant_id",
|
||||
"{$this->table}.fund_id",
|
||||
"{$this->table}.account_id",
|
||||
"{$this->table}.expense_category_id",
|
||||
"{$this->table}.amount",
|
||||
"{$this->table}.transaction_date",
|
||||
"{$this->table}.voucher_no",
|
||||
"{$this->table}.received_from",
|
||||
"{$this->table}.note",
|
||||
"{$this->table}.created_by",
|
||||
"{$this->table}.status",
|
||||
"{$this->table}.created_at",
|
||||
"{$this->table}.deleted_at"
|
||||
);
|
||||
}
|
||||
|
||||
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
|
||||
{
|
||||
$searchable = "%$searchedText%";
|
||||
|
||||
return $query->where("{$this->table}.transaction_date", 'LIKE', $searchable)
|
||||
->orWhere("{$this->table}.status", 'LIKE', $searchable);
|
||||
}
|
||||
|
||||
public function getAll(array $filterData = []): Paginator
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getExpenseQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
if (! empty($filter['search'])) {
|
||||
$query = $this->filterSearchQuery($query, $filter['search']);
|
||||
}
|
||||
|
||||
return $query
|
||||
->orderBy($filter['orderBy'], $filter['order'])
|
||||
->paginate($filter['perPage']);
|
||||
}
|
||||
|
||||
public function getCount(array $filterData = []): int
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
|
||||
{
|
||||
$item = $this->getExpenseQuery()
|
||||
->where($columnName, $columnValue)
|
||||
->first($selects);
|
||||
|
||||
if (empty($item)) {
|
||||
throw new Exception(
|
||||
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
|
||||
Response::HTTP_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(array $data): object
|
||||
{
|
||||
$data = $this->prepareForDB($data);
|
||||
$id = $this->getQuery()->insertGetId($data);
|
||||
|
||||
return Expense::find($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update(int $id, array $data): object
|
||||
{
|
||||
$item = Expense::findOrFail($id);
|
||||
$data = $this->prepareForDB($data, $item);
|
||||
parent::update($id, $data);
|
||||
|
||||
return $this->getById($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function prepareForDB(array $data, ?object $item = null): array
|
||||
{
|
||||
$data = parent::prepareForDB($data, $item);
|
||||
|
||||
if (empty($item)) {
|
||||
$data['created_at'] = now();
|
||||
$data['restaurant_id'] = $this->getCurrentRestaurantId();
|
||||
$data['status'] = 1;
|
||||
} else {
|
||||
$data['updated_at'] = now();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getExceptionMessages(): array
|
||||
{
|
||||
return [
|
||||
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'Expense does not exist.',
|
||||
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'Expense could not be deleted.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Repositories;
|
||||
|
||||
use App\Abstracts\EntityRepository;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Modules\Accounting\Models\Fund;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class FundRepository extends EntityRepository
|
||||
{
|
||||
public string $table = Fund::TABLE_NAME;
|
||||
|
||||
protected array $fillableColumns = [
|
||||
'restaurant_id',
|
||||
'name',
|
||||
'type',
|
||||
'code',
|
||||
'opening_balance',
|
||||
'current_balance',
|
||||
'is_default',
|
||||
'status',
|
||||
];
|
||||
|
||||
protected function getQuery(): Builder
|
||||
{
|
||||
return parent::getQuery();
|
||||
}
|
||||
|
||||
protected function getFilterData(array $filterData = []): array
|
||||
{
|
||||
$defaultArgs = [
|
||||
'perPage' => 10,
|
||||
'search' => '',
|
||||
'orderBy' => 'id',
|
||||
'order' => 'desc',
|
||||
'with_deleted' => false,
|
||||
];
|
||||
|
||||
return array_merge($defaultArgs, $filterData);
|
||||
}
|
||||
|
||||
private function getFundQuery(): Builder
|
||||
{
|
||||
return $this->getQuery()
|
||||
->select(
|
||||
"{$this->table}.id",
|
||||
"{$this->table}.restaurant_id",
|
||||
"{$this->table}.name",
|
||||
"{$this->table}.type",
|
||||
"{$this->table}.code",
|
||||
"{$this->table}.opening_balance",
|
||||
"{$this->table}.current_balance",
|
||||
"{$this->table}.is_default",
|
||||
"{$this->table}.status",
|
||||
"{$this->table}.created_at",
|
||||
"{$this->table}.deleted_at"
|
||||
);
|
||||
}
|
||||
|
||||
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
|
||||
{
|
||||
$searchable = "%$searchedText%";
|
||||
|
||||
return $query->where("{$this->table}.name", 'LIKE', $searchable)
|
||||
->orWhere("{$this->table}.status", 'LIKE', $searchable);
|
||||
}
|
||||
|
||||
public function getAll(array $filterData = []): Paginator
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getFundQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
if (! empty($filter['search'])) {
|
||||
$query = $this->filterSearchQuery($query, $filter['search']);
|
||||
}
|
||||
|
||||
return $query
|
||||
->orderBy($filter['orderBy'], $filter['order'])
|
||||
->paginate($filter['perPage']);
|
||||
}
|
||||
|
||||
public function getCount(array $filterData = []): int
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
|
||||
{
|
||||
$item = $this->getFundQuery()
|
||||
->where($columnName, $columnValue)
|
||||
->first($selects);
|
||||
|
||||
if (empty($item)) {
|
||||
throw new Exception(
|
||||
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
|
||||
Response::HTTP_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(array $data): object
|
||||
{
|
||||
$data = $this->prepareForDB($data);
|
||||
$id = $this->getQuery()->insertGetId($data);
|
||||
|
||||
return Fund::find($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update(int $id, array $data): object
|
||||
{
|
||||
$item = Fund::findOrFail($id);
|
||||
$data = $this->prepareForDB($data, $item);
|
||||
parent::update($id, $data);
|
||||
|
||||
return $this->getById($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function prepareForDB(array $data, ?object $item = null): array
|
||||
{
|
||||
$data = parent::prepareForDB($data, $item);
|
||||
|
||||
if (empty($item)) {
|
||||
$data['created_at'] = now();
|
||||
$data['restaurant_id'] = $this->getCurrentRestaurantId();
|
||||
$data['status'] = 1;
|
||||
} else {
|
||||
$data['updated_at'] = now();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getExceptionMessages(): array
|
||||
{
|
||||
return [
|
||||
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'Fund does not exist.',
|
||||
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'Fund could not be deleted.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Repositories;
|
||||
|
||||
use App\Abstracts\EntityRepository;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Modules\Accounting\Models\FundTransfer;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class FundTransferRepository extends EntityRepository
|
||||
{
|
||||
public string $table = FundTransfer::TABLE_NAME;
|
||||
|
||||
protected array $fillableColumns = [
|
||||
'restaurant_id',
|
||||
'name',
|
||||
'status',
|
||||
'created_by',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
];
|
||||
|
||||
protected function getQuery(): Builder
|
||||
{
|
||||
return parent::getQuery();
|
||||
}
|
||||
|
||||
protected function getFilterData(array $filterData = []): array
|
||||
{
|
||||
$defaultArgs = [
|
||||
'perPage' => 10,
|
||||
'search' => '',
|
||||
'orderBy' => 'id',
|
||||
'order' => 'desc',
|
||||
'with_deleted' => false,
|
||||
];
|
||||
|
||||
return array_merge($defaultArgs, $filterData);
|
||||
}
|
||||
|
||||
private function getFundTransferQuery(): Builder
|
||||
{
|
||||
return $this->getQuery()
|
||||
->select(
|
||||
"{$this->table}.id",
|
||||
"{$this->table}.restaurant_id",
|
||||
"{$this->table}.name",
|
||||
"{$this->table}.status",
|
||||
"{$this->table}.created_at",
|
||||
"{$this->table}.deleted_at"
|
||||
);
|
||||
}
|
||||
|
||||
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
|
||||
{
|
||||
$searchable = "%$searchedText%";
|
||||
|
||||
return $query->where("{$this->table}.name", 'LIKE', $searchable)
|
||||
->orWhere("{$this->table}.status", 'LIKE', $searchable);
|
||||
}
|
||||
|
||||
public function getAll(array $filterData = []): Paginator
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getFundTransferQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
if (! empty($filter['search'])) {
|
||||
$query = $this->filterSearchQuery($query, $filter['search']);
|
||||
}
|
||||
|
||||
return $query
|
||||
->orderBy($filter['orderBy'], $filter['order'])
|
||||
->paginate($filter['perPage']);
|
||||
}
|
||||
|
||||
public function getCount(array $filterData = []): int
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
|
||||
{
|
||||
$item = $this->getFundTransferQuery()
|
||||
->where($columnName, $columnValue)
|
||||
->first($selects);
|
||||
|
||||
if (empty($item)) {
|
||||
throw new Exception(
|
||||
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
|
||||
Response::HTTP_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(array $data): object
|
||||
{
|
||||
$data = $this->prepareForDB($data);
|
||||
$id = $this->getQuery()->insertGetId($data);
|
||||
|
||||
return FundTransfer::find($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update(int $id, array $data): object
|
||||
{
|
||||
$item = FundTransfer::findOrFail($id);
|
||||
$data = $this->prepareForDB($data, $item);
|
||||
parent::update($id, $data);
|
||||
|
||||
return $this->getById($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function prepareForDB(array $data, ?object $item = null): array
|
||||
{
|
||||
$data = parent::prepareForDB($data, $item);
|
||||
|
||||
if (empty($item)) {
|
||||
$data['created_at'] = now();
|
||||
$data['restaurant_id'] = $this->getCurrentRestaurantId();
|
||||
$data['status'] = 1;
|
||||
} else {
|
||||
$data['updated_at'] = now();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getExceptionMessages(): array
|
||||
{
|
||||
return [
|
||||
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'FundTransfer does not exist.',
|
||||
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'FundTransfer could not be deleted.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Repositories;
|
||||
|
||||
use App\Abstracts\EntityRepository;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Modules\Accounting\Models\TipDistribution;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class TipDistributionRepository extends EntityRepository
|
||||
{
|
||||
public string $table = TipDistribution::TABLE_NAME;
|
||||
|
||||
protected array $fillableColumns = [
|
||||
'restaurant_id',
|
||||
'waiter_id',
|
||||
'account_id',
|
||||
'amount',
|
||||
'created_by',
|
||||
'distributed_at',
|
||||
'status',
|
||||
'created_by',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
];
|
||||
|
||||
protected function getQuery(): Builder
|
||||
{
|
||||
return parent::getQuery();
|
||||
}
|
||||
|
||||
protected function getFilterData(array $filterData = []): array
|
||||
{
|
||||
$defaultArgs = [
|
||||
'perPage' => 10,
|
||||
'search' => '',
|
||||
'orderBy' => 'id',
|
||||
'order' => 'desc',
|
||||
'with_deleted' => false,
|
||||
];
|
||||
|
||||
return array_merge($defaultArgs, $filterData);
|
||||
}
|
||||
|
||||
private function getTipDistributionQuery(): Builder
|
||||
{
|
||||
return $this->getQuery()
|
||||
->leftJoin('users as waiter_user', 'waiter_user.id', '=', "{$this->table}.waiter_id")
|
||||
->leftJoin('accounts', 'accounts.id', '=', "{$this->table}.account_id")
|
||||
->leftJoin('users as creator_user', 'creator_user.id', '=', "{$this->table}.created_by")
|
||||
->select(
|
||||
"{$this->table}.id",
|
||||
"{$this->table}.restaurant_id",
|
||||
|
||||
// waiter
|
||||
"{$this->table}.waiter_id",
|
||||
'waiter_user.first_name as waiter_name',
|
||||
|
||||
// account
|
||||
"{$this->table}.account_id",
|
||||
'accounts.name as account_name',
|
||||
|
||||
// tip info
|
||||
"{$this->table}.amount",
|
||||
"{$this->table}.distributed_at",
|
||||
|
||||
// creator
|
||||
"{$this->table}.created_by",
|
||||
'creator_user.first_name as created_by_name',
|
||||
|
||||
// others
|
||||
"{$this->table}.status",
|
||||
"{$this->table}.created_at",
|
||||
"{$this->table}.deleted_at"
|
||||
);
|
||||
}
|
||||
|
||||
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
|
||||
{
|
||||
$searchable = "%$searchedText%";
|
||||
|
||||
return $query->where("{$this->table}.name", 'LIKE', $searchable)
|
||||
->orWhere("{$this->table}.status", 'LIKE', $searchable);
|
||||
}
|
||||
|
||||
public function getAll(array $filterData = []): Paginator
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getTipDistributionQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
if (! empty($filter['search'])) {
|
||||
$query = $this->filterSearchQuery($query, $filter['search']);
|
||||
}
|
||||
|
||||
return $query
|
||||
->orderBy($filter['orderBy'], $filter['order'])
|
||||
->paginate($filter['perPage']);
|
||||
}
|
||||
|
||||
public function getCount(array $filterData = []): int
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
|
||||
{
|
||||
$item = $this->getTipDistributionQuery()
|
||||
->where($columnName, $columnValue)
|
||||
->first($selects);
|
||||
|
||||
if (empty($item)) {
|
||||
throw new Exception(
|
||||
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
|
||||
Response::HTTP_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(array $data): object
|
||||
{
|
||||
$data = $this->prepareForDB($data);
|
||||
$id = $this->getQuery()->insertGetId($data);
|
||||
|
||||
return TipDistribution::find($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update(int $id, array $data): object
|
||||
{
|
||||
$item = TipDistribution::findOrFail($id);
|
||||
$data = $this->prepareForDB($data, $item);
|
||||
parent::update($id, $data);
|
||||
|
||||
return $this->getById($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function prepareForDB(array $data, ?object $item = null): array
|
||||
{
|
||||
$data = parent::prepareForDB($data, $item);
|
||||
|
||||
if (empty($item)) {
|
||||
$data['created_at'] = now();
|
||||
$data['created_by'] = Auth::id();
|
||||
$data['restaurant_id'] = $this->getCurrentRestaurantId();
|
||||
$data['status'] = 1;
|
||||
} else {
|
||||
$data['updated_at'] = now();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getExceptionMessages(): array
|
||||
{
|
||||
return [
|
||||
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'TipDistribution does not exist.',
|
||||
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'TipDistribution could not be deleted.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Repositories;
|
||||
|
||||
use App\Abstracts\EntityRepository;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Modules\Accounting\Models\Tip;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class TipRepository extends EntityRepository
|
||||
{
|
||||
public string $table = Tip::TABLE_NAME;
|
||||
|
||||
protected array $fillableColumns = [
|
||||
'restaurant_id',
|
||||
'waiter_id',
|
||||
'order_id',
|
||||
'amount',
|
||||
'collected_at',
|
||||
'status',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
];
|
||||
|
||||
protected function getQuery(): Builder
|
||||
{
|
||||
return parent::getQuery();
|
||||
}
|
||||
|
||||
protected function getFilterData(array $filterData = []): array
|
||||
{
|
||||
$defaultArgs = [
|
||||
'perPage' => 10,
|
||||
'search' => '',
|
||||
'orderBy' => 'id',
|
||||
'order' => 'desc',
|
||||
'with_deleted' => false,
|
||||
];
|
||||
|
||||
return array_merge($defaultArgs, $filterData);
|
||||
}
|
||||
|
||||
private function getTipQuery(): Builder
|
||||
{
|
||||
return $this->getQuery()
|
||||
->leftJoin('users', 'users.id', '=', "{$this->table}.waiter_id")
|
||||
->leftJoin('orders', 'orders.id', '=', "{$this->table}.order_id")
|
||||
->select(
|
||||
"{$this->table}.id",
|
||||
"{$this->table}.restaurant_id",
|
||||
"{$this->table}.waiter_id",
|
||||
'users.first_name as waiter_name',
|
||||
"{$this->table}.order_id",
|
||||
'orders.order_number as order_number',
|
||||
"{$this->table}.amount",
|
||||
"{$this->table}.collected_at",
|
||||
"{$this->table}.status",
|
||||
"{$this->table}.created_at",
|
||||
"{$this->table}.updated_at",
|
||||
"{$this->table}.deleted_at",
|
||||
);
|
||||
}
|
||||
|
||||
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
|
||||
{
|
||||
$searchable = "%$searchedText%";
|
||||
|
||||
return $query->where("{$this->table}.name", 'LIKE', $searchable)
|
||||
->orWhere("{$this->table}.status", 'LIKE', $searchable);
|
||||
}
|
||||
|
||||
public function getAll(array $filterData = []): Paginator
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getTipQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
if (! empty($filter['search'])) {
|
||||
$query = $this->filterSearchQuery($query, $filter['search']);
|
||||
}
|
||||
|
||||
return $query
|
||||
->orderBy($filter['orderBy'], $filter['order'])
|
||||
->paginate($filter['perPage']);
|
||||
}
|
||||
|
||||
public function getCount(array $filterData = []): int
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
|
||||
{
|
||||
$item = $this->getTipQuery()
|
||||
->where($columnName, $columnValue)
|
||||
->first($selects);
|
||||
|
||||
if (empty($item)) {
|
||||
throw new Exception(
|
||||
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
|
||||
Response::HTTP_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(array $data): object
|
||||
{
|
||||
$data = $this->prepareForDB($data);
|
||||
$id = $this->getQuery()->insertGetId($data);
|
||||
|
||||
return Tip::find($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update(int $id, array $data): object
|
||||
{
|
||||
$item = Tip::findOrFail($id);
|
||||
$data = $this->prepareForDB($data, $item);
|
||||
parent::update($id, $data);
|
||||
|
||||
return $this->getById($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function prepareForDB(array $data, ?object $item = null): array
|
||||
{
|
||||
$data = parent::prepareForDB($data, $item);
|
||||
|
||||
if (empty($item)) {
|
||||
$data['created_at'] = now();
|
||||
$data['restaurant_id'] = $this->getCurrentRestaurantId();
|
||||
} else {
|
||||
if (! empty($data['image']) && $data['image'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['image'] = fileUploader('Accounting/', 'png', $data['image'], $item->image);
|
||||
}
|
||||
|
||||
$data['updated_at'] = now();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getExceptionMessages(): array
|
||||
{
|
||||
return [
|
||||
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'Tip does not exist.',
|
||||
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'Tip could not be deleted.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Controllers\API;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Modules\Accounting\Http\Requests\Account\AccountStoreRequest;
|
||||
use Modules\Accounting\Http\Requests\Account\AccountUpdateRequest;
|
||||
use Modules\Accounting\Repositories\AccountRepository;
|
||||
|
||||
class AccountController extends Controller
|
||||
{
|
||||
public function __construct(private AccountRepository $repo) {}
|
||||
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getAll(request()->all()), 'Account has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function store(AccountStoreRequest $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->create($request->all()), 'Account has been created successfully.');
|
||||
} catch (\Illuminate\Database\QueryException $exception) {
|
||||
return $this->responseError([], 'Database error: '.$exception->getMessage());
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function show(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getById($id), 'Account has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function update(AccountUpdateRequest $request, int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->update($id, $request->all()), 'Account has been updated successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->delete($id), 'Account has been deleted successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Controllers\API;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Modules\Accounting\Http\Requests\DepositCategory\DepositCategoryStoreRequest;
|
||||
use Modules\Accounting\Http\Requests\DepositCategory\DepositCategoryUpdateRequest;
|
||||
use Modules\Accounting\Repositories\DepositCategoryRepository;
|
||||
|
||||
class DepositCategoryController extends Controller
|
||||
{
|
||||
public function __construct(private DepositCategoryRepository $repo) {}
|
||||
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getAll(request()->all()), 'DepositCategory has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function store(DepositCategoryStoreRequest $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->create($request->all()), 'DepositCategory has been created successfully.');
|
||||
} catch (\Illuminate\Database\QueryException $exception) {
|
||||
return $this->responseError([], 'Database error: '.$exception->getMessage());
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function show(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getById($id), 'DepositCategory has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function update(DepositCategoryUpdateRequest $request, int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->update($id, $request->all()), 'DepositCategory has been updated successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->delete($id), 'DepositCategory has been deleted successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Controllers\API;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Modules\Accounting\Http\Requests\Deposit\DepositStoreRequest;
|
||||
use Modules\Accounting\Http\Requests\Deposit\DepositUpdateRequest;
|
||||
use Modules\Accounting\Repositories\DepositRepository;
|
||||
|
||||
class DepositController extends Controller
|
||||
{
|
||||
public function __construct(private DepositRepository $repo) {}
|
||||
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getAll(request()->all()), 'Deposit has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function store(DepositStoreRequest $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->create($request->all()), 'Deposit has been created successfully.');
|
||||
} catch (\Illuminate\Database\QueryException $exception) {
|
||||
return $this->responseError([], 'Database error: '.$exception->getMessage());
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function show(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getById($id), 'Deposit has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function update(DepositUpdateRequest $request, int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->update($id, $request->all()), 'Deposit has been updated successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->delete($id), 'Deposit has been deleted successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Controllers\API;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Modules\Accounting\Http\Requests\ExpenseCategory\ExpenseCategoryStoreRequest;
|
||||
use Modules\Accounting\Http\Requests\ExpenseCategory\ExpenseCategoryUpdateRequest;
|
||||
use Modules\Accounting\Repositories\ExpenseCategoryRepository;
|
||||
|
||||
class ExpenseCategoryController extends Controller
|
||||
{
|
||||
public function __construct(private ExpenseCategoryRepository $repo) {}
|
||||
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getAll(request()->all()), 'ExpenseCategory has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function store(ExpenseCategoryStoreRequest $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->create($request->all()), 'ExpenseCategory has been created successfully.');
|
||||
} catch (\Illuminate\Database\QueryException $exception) {
|
||||
return $this->responseError([], 'Database error: '.$exception->getMessage());
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function show(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getById($id), 'ExpenseCategory has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function update(ExpenseCategoryUpdateRequest $request, int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->update($id, $request->all()), 'ExpenseCategory has been updated successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->delete($id), 'ExpenseCategory has been deleted successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Controllers\API;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Modules\Accounting\Http\Requests\Expense\ExpenseStoreRequest;
|
||||
use Modules\Accounting\Http\Requests\Expense\ExpenseUpdateRequest;
|
||||
use Modules\Accounting\Repositories\ExpenseRepository;
|
||||
|
||||
class ExpenseController extends Controller
|
||||
{
|
||||
public function __construct(private ExpenseRepository $repo) {}
|
||||
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getAll(request()->all()), 'Expense has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function store(ExpenseStoreRequest $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->create($request->all()), 'Expense has been created successfully.');
|
||||
} catch (\Illuminate\Database\QueryException $exception) {
|
||||
return $this->responseError([], 'Database error: '.$exception->getMessage());
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function show(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getById($id), 'Expense has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function update(ExpenseUpdateRequest $request, int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->update($id, $request->all()), 'Expense has been updated successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->delete($id), 'Expense has been deleted successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Controllers\API;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Modules\Accounting\Http\Requests\Fund\FundStoreRequest;
|
||||
use Modules\Accounting\Http\Requests\Fund\FundUpdateRequest;
|
||||
use Modules\Accounting\Repositories\FundRepository;
|
||||
|
||||
class FundController extends Controller
|
||||
{
|
||||
public function __construct(private FundRepository $repo) {}
|
||||
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getAll(request()->all()), 'Fund has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function store(FundStoreRequest $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->create($request->all()), 'Fund has been created successfully.');
|
||||
} catch (\Illuminate\Database\QueryException $exception) {
|
||||
return $this->responseError([], 'Database error: '.$exception->getMessage());
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function show(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getById($id), 'Fund has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function update(FundUpdateRequest $request, int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->update($id, $request->all()), 'Fund has been updated successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->delete($id), 'Fund has been deleted successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Controllers\API;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Modules\Accounting\Http\Requests\FundTransfer\FundTransferStoreRequest;
|
||||
use Modules\Accounting\Http\Requests\FundTransfer\FundTransferUpdateRequest;
|
||||
use Modules\Accounting\Repositories\FundTransferRepository;
|
||||
|
||||
class FundTransferController extends Controller
|
||||
{
|
||||
public function __construct(private FundTransferRepository $repo) {}
|
||||
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getAll(request()->all()), 'FundTransfer has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function store(FundTransferStoreRequest $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->create($request->all()), 'FundTransfer has been created successfully.');
|
||||
} catch (\Illuminate\Database\QueryException $exception) {
|
||||
return $this->responseError([], 'Database error: '.$exception->getMessage());
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function show(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getById($id), 'FundTransfer has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function update(FundTransferUpdateRequest $request, int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->update($id, $request->all()), 'FundTransfer has been updated successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->delete($id), 'FundTransfer has been deleted successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Controllers\API;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Modules\Accounting\Http\Requests\Tip\TipStoreRequest;
|
||||
use Modules\Accounting\Http\Requests\Tip\TipUpdateRequest;
|
||||
use Modules\Accounting\Repositories\TipRepository;
|
||||
|
||||
class TipController extends Controller
|
||||
{
|
||||
public function __construct(private TipRepository $repo) {}
|
||||
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getAll(request()->all()), 'Tip has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function store(TipStoreRequest $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->create($request->all()), 'Tip has been created successfully.');
|
||||
} catch (\Illuminate\Database\QueryException $exception) {
|
||||
return $this->responseError([], 'Database error: '.$exception->getMessage());
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function show(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getById($id), 'Tip has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function update(TipUpdateRequest $request, int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->update($id, $request->all()), 'Tip has been updated successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->delete($id), 'Tip has been deleted successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Controllers\API;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Modules\Accounting\Http\Requests\TipDistribution\TipDistributionStoreRequest;
|
||||
use Modules\Accounting\Http\Requests\TipDistribution\TipDistributionUpdateRequest;
|
||||
use Modules\Accounting\Repositories\TipDistributionRepository;
|
||||
|
||||
class TipDistributionController extends Controller
|
||||
{
|
||||
public function __construct(private TipDistributionRepository $repo) {}
|
||||
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getAll(request()->all()), 'TipDistribution has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function store(TipDistributionStoreRequest $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->create($request->all()), 'TipDistribution has been created successfully.');
|
||||
} catch (\Illuminate\Database\QueryException $exception) {
|
||||
return $this->responseError([], 'Database error: '.$exception->getMessage());
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function show(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->getById($id), 'TipDistribution has been fetched successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function update(TipDistributionUpdateRequest $request, int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->update($id, $request->all()), 'TipDistribution has been updated successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
return $this->responseSuccess($this->repo->delete($id), 'TipDistribution has been deleted successfully.');
|
||||
} catch (Exception $e) {
|
||||
return $this->responseError([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\Account;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class AccountStoreRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|max:255',
|
||||
'code' => ['nullable', 'string', 'max:50'],
|
||||
'type' => 'required|in:asset,liability,equity,income,expense',
|
||||
'opening_balance' => 'nullable|numeric|min:0',
|
||||
'current_balance' => 'nullable|numeric|min:0',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\Account;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class AccountUpdateRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|max:255',
|
||||
'code' => ['nullable', 'string', 'max:50'],
|
||||
'type' => 'required|in:asset,liability,equity,income,expense',
|
||||
'opening_balance' => 'nullable|numeric|min:0',
|
||||
'current_balance' => 'nullable|numeric|min:0',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\Deposit;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class DepositStoreRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'fund_id' => 'required|exists:funds,id',
|
||||
'account_id' => 'nullable|exists:accounts,id',
|
||||
'amount' => 'required|numeric|min:0.01',
|
||||
'transaction_date' => 'required|date',
|
||||
'received_from' => 'nullable|string|max:255',
|
||||
'note' => 'nullable|string',
|
||||
'created_by' => 'nullable|exists:users,id',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\Deposit;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class DepositUpdateRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
$depositId = $this->route('deposit');
|
||||
|
||||
return [
|
||||
'fund_id' => 'required|exists:funds,id',
|
||||
'account_id' => 'nullable|exists:accounts,id',
|
||||
'amount' => 'required|numeric|min:0.01',
|
||||
'transaction_date' => 'required|date',
|
||||
'received_from' => 'nullable|string|max:255',
|
||||
'note' => 'nullable|string',
|
||||
'created_by' => 'nullable|exists:users,id',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\DepositCategory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class DepositCategoryStoreRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|max:255',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\DepositCategory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class DepositCategoryUpdateRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|max:255',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\Expense;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ExpenseStoreRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'account_id' => 'required|exists:accounts,id',
|
||||
'expense_category_id' => 'nullable|exists:expense_categories,id',
|
||||
'amount' => 'required|numeric|min:0.01',
|
||||
'transaction_date' => 'required|date',
|
||||
'details' => 'nullable|string',
|
||||
'created_by' => 'nullable|exists:users,id',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\Expense;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ExpenseUpdateRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
$expenseId = $this->route('expense');
|
||||
|
||||
return [
|
||||
'account_id' => 'required|exists:accounts,id',
|
||||
'expense_category_id' => 'nullable|exists:expense_categories,id',
|
||||
'amount' => 'required|numeric|min:0.01',
|
||||
'transaction_date' => 'required|date',
|
||||
'details' => 'nullable|string',
|
||||
'created_by' => 'nullable|exists:users,id',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\ExpenseCategory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ExpenseCategoryStoreRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|max:255',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\ExpenseCategory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ExpenseCategoryUpdateRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|max:255',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\Fund;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class FundStoreRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|max:255',
|
||||
'code' => ['nullable', 'string', 'max:50'],
|
||||
'type' => 'required|in:asset,liability,equity,income,expense',
|
||||
'opening_balance' => 'nullable|numeric|min:0',
|
||||
'current_balance' => 'nullable|numeric|min:0',
|
||||
'is_default' => 'boolean',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\Fund;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class FundUpdateRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|max:255',
|
||||
'code' => ['nullable', 'string', 'max:50'],
|
||||
'type' => 'required|in:asset,liability,equity,income,expense',
|
||||
'opening_balance' => 'nullable|numeric|min:0',
|
||||
'current_balance' => 'nullable|numeric|min:0',
|
||||
'is_default' => 'boolean',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\FundTransfer;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class FundTransferStoreRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'from_fund_id' => 'required|exists:funds,id',
|
||||
'to_fund_id' => 'required|exists:funds,id|different:from_fund_id',
|
||||
'amount' => 'required|numeric|min:0.01',
|
||||
'transfer_date' => 'required|date',
|
||||
'note' => 'nullable|string',
|
||||
'created_by' => 'nullable|exists:users,id',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'to_fund_id.different' => 'Destination fund must be different from source fund.',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\FundTransfer;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class FundTransferUpdateRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
$transferId = $this->route('fund_transfer');
|
||||
|
||||
return [
|
||||
'from_fund_id' => 'required|exists:funds,id',
|
||||
'to_fund_id' => 'required|exists:funds,id|different:from_fund_id',
|
||||
'amount' => 'required|numeric|min:0.01',
|
||||
'transfer_date' => 'required|date',
|
||||
'note' => 'nullable|string',
|
||||
'created_by' => 'nullable|exists:users,id',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'to_fund_id.different' => 'Destination fund must be different from source fund.',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\Tip;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class TipStoreRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'waiter_id' => 'required|exists:users,id',
|
||||
'order_id' => 'nullable|exists:orders,id',
|
||||
'amount' => 'required|numeric|min:0.01',
|
||||
'collected_at' => 'nullable|date',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\Tip;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class TipUpdateRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
$tipId = $this->route('tip');
|
||||
|
||||
return [
|
||||
'waiter_id' => 'required|exists:users,id',
|
||||
'order_id' => 'nullable|exists:orders,id',
|
||||
'amount' => 'required|numeric|min:0.01',
|
||||
'collected_at' => 'nullable|date',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\TipDistribution;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class TipDistributionStoreRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'waiter_id' => 'required|exists:users,id',
|
||||
'account_id' => 'required|exists:accounts,id',
|
||||
'amount' => 'required|numeric|min:0.01',
|
||||
'distributed_at' => 'nullable|date',
|
||||
'created_by' => 'nullable|exists:users,id',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Http\Requests\TipDistribution;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class TipDistributionUpdateRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
$distributionId = $this->route('tip_distribution');
|
||||
|
||||
return [
|
||||
'waiter_id' => 'required|exists:users,id',
|
||||
'account_id' => 'required|exists:accounts,id',
|
||||
'amount' => 'required|numeric|min:0.01',
|
||||
'distributed_at' => 'nullable|date',
|
||||
'created_by' => 'nullable|exists:users,id',
|
||||
'status' => 'nullable|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
28
public/restaurant/Modules/Accounting/app/Models/Account.php
Normal file
28
public/restaurant/Modules/Accounting/app/Models/Account.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Account extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'restaurant_id',
|
||||
'name',
|
||||
'code',
|
||||
'type',
|
||||
'opening_balance',
|
||||
'current_balance',
|
||||
'status',
|
||||
];
|
||||
|
||||
public const TABLE_NAME = 'accounts';
|
||||
|
||||
protected $table = self::TABLE_NAME;
|
||||
|
||||
public function transactionDetails(): HasMany
|
||||
{
|
||||
return $this->hasMany(TransactionDetail::class);
|
||||
}
|
||||
}
|
||||
28
public/restaurant/Modules/Accounting/app/Models/Deposit.php
Normal file
28
public/restaurant/Modules/Accounting/app/Models/Deposit.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Deposit extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'restaurant_id',
|
||||
'fund_id',
|
||||
'account_id',
|
||||
'deposit_category_id',
|
||||
'amount',
|
||||
'transaction_date',
|
||||
'voucher_no',
|
||||
'received_from',
|
||||
'note',
|
||||
'created_by',
|
||||
'status',
|
||||
];
|
||||
|
||||
protected $dates = ['transaction_date'];
|
||||
|
||||
public const TABLE_NAME = 'deposits';
|
||||
|
||||
protected $table = self::TABLE_NAME;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class DepositCategory extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'restaurant_id',
|
||||
'name',
|
||||
'status',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
];
|
||||
|
||||
public const TABLE_NAME = 'deposit_categories';
|
||||
|
||||
protected $table = self::TABLE_NAME;
|
||||
}
|
||||
28
public/restaurant/Modules/Accounting/app/Models/Expense.php
Normal file
28
public/restaurant/Modules/Accounting/app/Models/Expense.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Expense extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'restaurant_id',
|
||||
'fund_id',
|
||||
'account_id',
|
||||
'expense_category_id',
|
||||
'amount',
|
||||
'transaction_date',
|
||||
'voucher_no',
|
||||
'received_from',
|
||||
'note',
|
||||
'created_by',
|
||||
'status',
|
||||
];
|
||||
|
||||
protected $dates = ['transaction_date'];
|
||||
|
||||
public const TABLE_NAME = 'expenses';
|
||||
|
||||
protected $table = self::TABLE_NAME;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ExpenseCategory extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'restaurant_id',
|
||||
'name',
|
||||
'status',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
];
|
||||
|
||||
public const TABLE_NAME = 'expense_categories';
|
||||
|
||||
protected $table = self::TABLE_NAME;
|
||||
}
|
||||
29
public/restaurant/Modules/Accounting/app/Models/Fund.php
Normal file
29
public/restaurant/Modules/Accounting/app/Models/Fund.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Fund extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'restaurant_id',
|
||||
'name',
|
||||
'type',
|
||||
'code',
|
||||
'opening_balance',
|
||||
'current_balance',
|
||||
'is_default',
|
||||
'status',
|
||||
];
|
||||
|
||||
public const TABLE_NAME = 'funds';
|
||||
|
||||
protected $table = self::TABLE_NAME;
|
||||
|
||||
public function transactions(): HasMany
|
||||
{
|
||||
return $this->hasMany(Transaction::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class FundTransfer extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'restaurant_id',
|
||||
'from_fund_id',
|
||||
'to_fund_id',
|
||||
'amount',
|
||||
'note',
|
||||
'created_by',
|
||||
'transfer_date',
|
||||
];
|
||||
|
||||
protected $dates = ['transfer_date'];
|
||||
|
||||
public const TABLE_NAME = 'fund_transfers';
|
||||
|
||||
protected $table = self::TABLE_NAME;
|
||||
}
|
||||
26
public/restaurant/Modules/Accounting/app/Models/Tip.php
Normal file
26
public/restaurant/Modules/Accounting/app/Models/Tip.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Tip extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'restaurant_id',
|
||||
'waiter_id',
|
||||
'order_id',
|
||||
'amount',
|
||||
'collected_at',
|
||||
'status',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
];
|
||||
|
||||
protected $dates = ['collected_at'];
|
||||
|
||||
public const TABLE_NAME = 'tips';
|
||||
|
||||
protected $table = self::TABLE_NAME;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class TipDistribution extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'restaurant_id',
|
||||
'waiter_id',
|
||||
'account_id',
|
||||
'amount',
|
||||
'created_by',
|
||||
'distributed_at',
|
||||
'status',
|
||||
'created_by',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
];
|
||||
|
||||
protected $dates = ['distributed_at'];
|
||||
|
||||
public const TABLE_NAME = 'tip_distributions';
|
||||
|
||||
protected $table = self::TABLE_NAME;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Transaction extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'restaurant_id',
|
||||
'fund_id',
|
||||
'transaction_type',
|
||||
'transaction_date',
|
||||
'reference_no',
|
||||
'notes',
|
||||
'total_debit',
|
||||
'total_credit',
|
||||
'created_by',
|
||||
];
|
||||
|
||||
protected $dates = ['transaction_date'];
|
||||
|
||||
public const TABLE_NAME = 'transactions';
|
||||
|
||||
protected $table = self::TABLE_NAME;
|
||||
|
||||
public function details(): HasMany
|
||||
{
|
||||
return $this->hasMany(TransactionDetail::class);
|
||||
}
|
||||
|
||||
public function fund(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Fund::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class TransactionDetail extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'restaurant_id',
|
||||
'transaction_id',
|
||||
'account_id',
|
||||
'debit',
|
||||
'credit',
|
||||
'note',
|
||||
];
|
||||
|
||||
public const TABLE_NAME = 'transaction_details';
|
||||
|
||||
protected $table = self::TABLE_NAME;
|
||||
|
||||
public function account(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Account::class);
|
||||
}
|
||||
|
||||
public function transaction(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Transaction::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Nwidart\Modules\Traits\PathNamespace;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
|
||||
class AccountingServiceProvider extends ServiceProvider
|
||||
{
|
||||
use PathNamespace;
|
||||
|
||||
protected string $name = 'Accounting';
|
||||
|
||||
protected string $nameLower = 'accounting';
|
||||
|
||||
/**
|
||||
* Boot the application events.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
$this->registerCommands();
|
||||
$this->registerCommandSchedules();
|
||||
$this->registerTranslations();
|
||||
$this->registerConfig();
|
||||
$this->registerViews();
|
||||
$this->loadMigrationsFrom(module_path($this->name, 'database/migrations'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
$this->app->register(EventServiceProvider::class);
|
||||
$this->app->register(RouteServiceProvider::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register commands in the format of Command::class
|
||||
*/
|
||||
protected function registerCommands(): void
|
||||
{
|
||||
// $this->commands([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register command Schedules.
|
||||
*/
|
||||
protected function registerCommandSchedules(): void
|
||||
{
|
||||
// $this->app->booted(function () {
|
||||
// $schedule = $this->app->make(Schedule::class);
|
||||
// $schedule->command('inspire')->hourly();
|
||||
// });
|
||||
}
|
||||
|
||||
/**
|
||||
* Register translations.
|
||||
*/
|
||||
public function registerTranslations(): void
|
||||
{
|
||||
$langPath = resource_path('lang/modules/'.$this->nameLower);
|
||||
|
||||
if (is_dir($langPath)) {
|
||||
$this->loadTranslationsFrom($langPath, $this->nameLower);
|
||||
$this->loadJsonTranslationsFrom($langPath);
|
||||
} else {
|
||||
$this->loadTranslationsFrom(module_path($this->name, 'lang'), $this->nameLower);
|
||||
$this->loadJsonTranslationsFrom(module_path($this->name, 'lang'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register config.
|
||||
*/
|
||||
protected function registerConfig(): void
|
||||
{
|
||||
$configPath = module_path($this->name, config('modules.paths.generator.config.path'));
|
||||
|
||||
if (is_dir($configPath)) {
|
||||
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($configPath));
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
if ($file->isFile() && $file->getExtension() === 'php') {
|
||||
$config = str_replace($configPath.DIRECTORY_SEPARATOR, '', $file->getPathname());
|
||||
$config_key = str_replace([DIRECTORY_SEPARATOR, '.php'], ['.', ''], $config);
|
||||
$segments = explode('.', $this->nameLower.'.'.$config_key);
|
||||
|
||||
// Remove duplicated adjacent segments
|
||||
$normalized = [];
|
||||
foreach ($segments as $segment) {
|
||||
if (end($normalized) !== $segment) {
|
||||
$normalized[] = $segment;
|
||||
}
|
||||
}
|
||||
|
||||
$key = ($config === 'config.php') ? $this->nameLower : implode('.', $normalized);
|
||||
|
||||
$this->publishes([$file->getPathname() => config_path($config)], 'config');
|
||||
$this->merge_config_from($file->getPathname(), $key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge config from the given path recursively.
|
||||
*/
|
||||
protected function merge_config_from(string $path, string $key): void
|
||||
{
|
||||
$existing = config($key, []);
|
||||
$module_config = require $path;
|
||||
|
||||
config([$key => array_replace_recursive($existing, $module_config)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register views.
|
||||
*/
|
||||
public function registerViews(): void
|
||||
{
|
||||
$viewPath = resource_path('views/modules/'.$this->nameLower);
|
||||
$sourcePath = module_path($this->name, 'resources/views');
|
||||
|
||||
$this->publishes([$sourcePath => $viewPath], ['views', $this->nameLower.'-module-views']);
|
||||
|
||||
$this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), $this->nameLower);
|
||||
|
||||
Blade::componentNamespace(config('modules.namespace').'\\'.$this->name.'\\View\\Components', $this->nameLower);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the services provided by the provider.
|
||||
*/
|
||||
public function provides(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
private function getPublishableViewPaths(): array
|
||||
{
|
||||
$paths = [];
|
||||
foreach (config('view.paths') as $path) {
|
||||
if (is_dir($path.'/modules/'.$this->nameLower)) {
|
||||
$paths[] = $path.'/modules/'.$this->nameLower;
|
||||
}
|
||||
}
|
||||
|
||||
return $paths;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The event handler mappings for the application.
|
||||
*
|
||||
* @var array<string, array<int, string>>
|
||||
*/
|
||||
protected $listen = [];
|
||||
|
||||
/**
|
||||
* Indicates if events should be discovered.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected static $shouldDiscoverEvents = true;
|
||||
|
||||
/**
|
||||
* Configure the proper event listeners for email verification.
|
||||
*/
|
||||
protected function configureEmailVerification(): void {}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
protected string $name = 'Accounting';
|
||||
|
||||
/**
|
||||
* Called before routes are registered.
|
||||
*
|
||||
* Register any model bindings or pattern based filters.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
parent::boot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the routes for the application.
|
||||
*/
|
||||
public function map(): void
|
||||
{
|
||||
$this->mapApiRoutes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the "api" routes for the application.
|
||||
*
|
||||
* These routes are typically stateless.
|
||||
*/
|
||||
protected function mapApiRoutes(): void
|
||||
{
|
||||
Route::middleware('api')->prefix('api')->name('api.')->group(module_path($this->name, '/routes/api.php'));
|
||||
}
|
||||
}
|
||||
30
public/restaurant/Modules/Accounting/composer.json
Normal file
30
public/restaurant/Modules/Accounting/composer.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "nwidart/accounting",
|
||||
"description": "",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Widart",
|
||||
"email": "n.widart@gmail.com"
|
||||
}
|
||||
],
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [],
|
||||
"aliases": {
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Modules\\Accounting\\": "app/",
|
||||
"Modules\\Accounting\\Database\\Factories\\": "database/factories/",
|
||||
"Modules\\Accounting\\Database\\Seeders\\": "database/seeders/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Modules\\Accounting\\Tests\\": "tests/"
|
||||
}
|
||||
}
|
||||
}
|
||||
5
public/restaurant/Modules/Accounting/config/config.php
Normal file
5
public/restaurant/Modules/Accounting/config/config.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'name' => 'Accounting',
|
||||
];
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('accounts', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('restaurant_id')->nullable();
|
||||
$table->string('name');
|
||||
$table->string('code')->nullable();
|
||||
$table->enum('type', ['asset', 'liability', 'equity', 'income', 'expense'])->default('asset');
|
||||
$table->decimal('opening_balance', 15, 2)->default(0);
|
||||
$table->decimal('current_balance', 15, 2)->default(0);
|
||||
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('accounts');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('funds', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('restaurant_id')->nullable();
|
||||
$table->string('name');
|
||||
$table->enum('type', ['asset', 'liability', 'equity', 'income', 'expense'])->default('asset');
|
||||
$table->string('code')->nullable();
|
||||
$table->decimal('opening_balance', 15, 2)->default(0);
|
||||
$table->decimal('current_balance', 15, 2)->default(0);
|
||||
$table->boolean('is_default')->default(false);
|
||||
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('funds');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('transactions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('restaurant_id')->nullable();
|
||||
$table->unsignedBigInteger('fund_id')->nullable()->index();
|
||||
$table->string('transaction_type'); // deposit, payment, journal, sale, purchase, loan, transfer, tip
|
||||
$table->date('transaction_date')->index();
|
||||
$table->string('reference_no')->nullable()->index();
|
||||
$table->text('notes')->nullable();
|
||||
$table->decimal('total_debit', 15, 2)->default(0);
|
||||
$table->decimal('total_credit', 15, 2)->default(0);
|
||||
$table->unsignedBigInteger('created_by')->nullable();
|
||||
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('transactions');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('transaction_details', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('restaurant_id')->nullable();
|
||||
$table->unsignedBigInteger('transaction_id')->index();
|
||||
$table->unsignedBigInteger('account_id')->index();
|
||||
$table->decimal('debit', 15, 2)->default(0);
|
||||
$table->decimal('credit', 15, 2)->default(0);
|
||||
$table->text('note')->nullable();
|
||||
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('transaction_details');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('expense_categories', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('restaurant_id')->nullable();
|
||||
$table->string('name');
|
||||
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('expense_categories');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('expenses', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('restaurant_id')->nullable();
|
||||
$table->unsignedBigInteger('fund_id')->index(); // where money arrived
|
||||
$table->unsignedBigInteger('account_id')->index(); // account used to pay
|
||||
$table->unsignedBigInteger('expense_category_id')->nullable()->index();
|
||||
$table->decimal('amount', 15, 2);
|
||||
$table->date('transaction_date')->index();
|
||||
$table->string('voucher_no')->nullable();
|
||||
$table->string('received_from')->nullable();
|
||||
$table->text('note')->nullable();
|
||||
$table->unsignedBigInteger('created_by')->nullable();
|
||||
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('expenses');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('deposit_categories', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('restaurant_id')->nullable();
|
||||
$table->string('name');
|
||||
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('deposit_categories');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('deposits', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('restaurant_id')->nullable();
|
||||
$table->unsignedBigInteger('fund_id')->index(); // where money arrived
|
||||
$table->unsignedBigInteger('account_id')->index(); // source account (if any)
|
||||
$table->unsignedBigInteger('deposit_category_id')->nullable()->index();
|
||||
$table->decimal('amount', 15, 2);
|
||||
$table->date('transaction_date')->index();
|
||||
$table->string('voucher_no')->nullable();
|
||||
$table->string('received_from')->nullable();
|
||||
$table->text('note')->nullable();
|
||||
$table->unsignedBigInteger('created_by')->nullable();
|
||||
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('deposits');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('fund_transfers', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('restaurant_id')->nullable();
|
||||
$table->unsignedBigInteger('from_fund_id')->index();
|
||||
$table->unsignedBigInteger('to_fund_id')->index();
|
||||
$table->decimal('amount', 15, 2);
|
||||
$table->text('note')->nullable();
|
||||
$table->unsignedBigInteger('created_by')->nullable();
|
||||
$table->date('transfer_date')->index();
|
||||
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('fund_transfers');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('tips', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('restaurant_id')->nullable();
|
||||
$table->unsignedBigInteger('waiter_id')->nullable()->index();
|
||||
$table->unsignedBigInteger('order_id')->nullable()->index();
|
||||
$table->decimal('amount', 15, 2)->default(0);
|
||||
$table->date('collected_at')->nullable();
|
||||
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('tips');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('tip_distributions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('restaurant_id')->nullable();
|
||||
$table->unsignedBigInteger('waiter_id')->index();
|
||||
$table->unsignedBigInteger('account_id')->index();
|
||||
$table->decimal('amount', 15, 2);
|
||||
$table->unsignedBigInteger('created_by')->nullable();
|
||||
$table->date('distributed_at')->nullable();
|
||||
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('tip_distributions');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class AccountingDatabaseSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$this->call([
|
||||
AccountingSeeder::class,
|
||||
FundSeeder::class,
|
||||
DepositCategorySeeder::class,
|
||||
ExpenseCategorySeeder::class,
|
||||
DepositSeeder::class,
|
||||
ExpenseSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Modules\Accounting\Models\Account;
|
||||
|
||||
class AccountingSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// In SaaS onboarding, dynamic restaurant id assigned.
|
||||
// For now, making example default:
|
||||
$restaurantId = 1;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| DEFAULT ACCOUNTS (Chart of Accounts)
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
$defaultAccounts = [
|
||||
['name' => 'Cash', 'type' => 'asset', 'code' => 'AC-001'],
|
||||
['name' => 'Bank', 'type' => 'asset', 'code' => 'AC-002'],
|
||||
['name' => 'Loan Receivable', 'type' => 'asset', 'code' => 'AC-003'],
|
||||
|
||||
['name' => 'Sales', 'type' => 'income', 'code' => 'AC-101'],
|
||||
|
||||
['name' => 'Purchase', 'type' => 'expense', 'code' => 'AC-201'],
|
||||
['name' => 'Operating Expense', 'type' => 'expense', 'code' => 'AC-202'],
|
||||
|
||||
['name' => 'Loan Payable', 'type' => 'liability', 'code' => 'AC-301'],
|
||||
['name' => 'Tips Received', 'type' => 'liability', 'code' => 'AC-302'],
|
||||
];
|
||||
|
||||
foreach ($defaultAccounts as $acc) {
|
||||
Account::updateOrCreate(
|
||||
[
|
||||
'restaurant_id' => $restaurantId,
|
||||
'code' => $acc['code'],
|
||||
],
|
||||
[
|
||||
'name' => $acc['name'],
|
||||
'type' => $acc['type'],
|
||||
'opening_balance' => 0,
|
||||
'current_balance' => 0,
|
||||
'status' => 1,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class DepositCategorySeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
DB::table('deposit_categories')->insert([
|
||||
['restaurant_id' => 1, 'name' => 'Customer Payment'],
|
||||
['restaurant_id' => 1, 'name' => 'Fund Transfer In'],
|
||||
['restaurant_id' => 1, 'name' => 'Sales Revenue'],
|
||||
['restaurant_id' => 1, 'name' => 'Donations'],
|
||||
['restaurant_id' => 1, 'name' => 'Loan Received'],
|
||||
['restaurant_id' => 1, 'name' => 'Service Charge'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Database\Seeders;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Modules\Accounting\Models\Account;
|
||||
use Modules\Accounting\Models\Deposit;
|
||||
use Modules\Accounting\Models\Fund;
|
||||
use Modules\Accounting\Models\Transaction;
|
||||
use Modules\Accounting\Models\TransactionDetail;
|
||||
|
||||
class DepositSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$restaurantId = 1; // example restaurant
|
||||
|
||||
// Sample Deposit Data
|
||||
$deposits = [
|
||||
[
|
||||
'fund_name' => 'Cash', // fund where money arrived
|
||||
'account_code' => 'AC-101', // source account (income/sales)
|
||||
'amount' => 500.00,
|
||||
'transaction_date' => Carbon::now()->subDays(2),
|
||||
'voucher_no' => 'DEP-001',
|
||||
'received_from' => 'Customer A',
|
||||
'note' => 'Cash sale deposit',
|
||||
'created_by' => 1,
|
||||
],
|
||||
[
|
||||
'fund_name' => 'Bank',
|
||||
'account_code' => 'AC-101',
|
||||
'amount' => 1000.00,
|
||||
'transaction_date' => Carbon::now()->subDay(),
|
||||
'voucher_no' => 'DEP-002',
|
||||
'received_from' => 'Customer B',
|
||||
'note' => 'Bank deposit from sales',
|
||||
'created_by' => 1,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($deposits as $dep) {
|
||||
$fund = Fund::where('restaurant_id', $restaurantId)
|
||||
->where('name', $dep['fund_name'])
|
||||
->first();
|
||||
|
||||
$account = Account::where('restaurant_id', $restaurantId)
|
||||
->where('code', $dep['account_code'])
|
||||
->first();
|
||||
|
||||
if (! $fund || ! $account) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($restaurantId, $fund, $account, $dep) {
|
||||
// 1️⃣ Create Deposit
|
||||
$deposit = Deposit::create([
|
||||
'restaurant_id' => $restaurantId,
|
||||
'fund_id' => $fund->id,
|
||||
'account_id' => $account->id,
|
||||
'deposit_category_id' => 1,
|
||||
'amount' => $dep['amount'],
|
||||
'transaction_date' => $dep['transaction_date'],
|
||||
'voucher_no' => $dep['voucher_no'],
|
||||
'received_from' => $dep['received_from'],
|
||||
'note' => $dep['note'],
|
||||
'created_by' => $dep['created_by'],
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
// 2️⃣ Create Transaction
|
||||
$transaction = Transaction::create([
|
||||
'restaurant_id' => $restaurantId,
|
||||
'fund_id' => $fund->id,
|
||||
'transaction_type' => 'deposit',
|
||||
'transaction_date' => $dep['transaction_date'],
|
||||
'reference_no' => $dep['voucher_no'],
|
||||
'notes' => $dep['note'],
|
||||
'total_debit' => 0,
|
||||
'total_credit' => $dep['amount'],
|
||||
'created_by' => $dep['created_by'],
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
// 3️⃣ Transaction Details
|
||||
// Credit to Fund (increase)
|
||||
TransactionDetail::create([
|
||||
'restaurant_id' => $restaurantId,
|
||||
'transaction_id' => $transaction->id,
|
||||
'account_id' => $fund->id, // fund receives money (asset)
|
||||
'debit' => $dep['amount'],
|
||||
'credit' => 0,
|
||||
'note' => $dep['note'].' (Fund)',
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
// Debit from Source Account
|
||||
TransactionDetail::create([
|
||||
'restaurant_id' => $restaurantId,
|
||||
'transaction_id' => $transaction->id,
|
||||
'account_id' => $account->id, // source account (income)
|
||||
'debit' => 0,
|
||||
'credit' => $dep['amount'],
|
||||
'note' => $dep['note'].' (Source Account)',
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
// 4️⃣ Update Fund Balance
|
||||
$fund->increment('current_balance', $dep['amount']);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class ExpenseCategorySeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
DB::table('expense_categories')->insert([
|
||||
['restaurant_id' => 1, 'name' => 'Food Purchase'],
|
||||
['restaurant_id' => 1, 'name' => 'Operating Expense'],
|
||||
['restaurant_id' => 1, 'name' => 'Salaries'],
|
||||
['restaurant_id' => 1, 'name' => 'Marketing'],
|
||||
['restaurant_id' => 1, 'name' => 'Electricity Bill'],
|
||||
['restaurant_id' => 1, 'name' => 'Loan Repayment'],
|
||||
['restaurant_id' => 1, 'name' => 'Fund Transfer Out'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Database\Seeders;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Modules\Accounting\Models\Account;
|
||||
use Modules\Accounting\Models\Expense;
|
||||
use Modules\Accounting\Models\Fund;
|
||||
use Modules\Accounting\Models\Transaction;
|
||||
use Modules\Accounting\Models\TransactionDetail;
|
||||
|
||||
class ExpenseSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$restaurantId = 1; // example restaurant
|
||||
|
||||
// Sample Expense Data
|
||||
$expenses = [
|
||||
[
|
||||
'fund_name' => 'Cash', // fund where money arrived
|
||||
'account_code' => 'AC-101', // source account (income/sales)
|
||||
'amount' => 500.00,
|
||||
'transaction_date' => Carbon::now()->subDays(2),
|
||||
'voucher_no' => 'DEP-001',
|
||||
'received_from' => 'Customer A',
|
||||
'note' => 'Cash sale expense',
|
||||
'created_by' => 1,
|
||||
],
|
||||
[
|
||||
'fund_name' => 'Bank',
|
||||
'account_code' => 'AC-101',
|
||||
'amount' => 1000.00,
|
||||
'transaction_date' => Carbon::now()->subDay(),
|
||||
'voucher_no' => 'DEP-002',
|
||||
'received_from' => 'Customer B',
|
||||
'note' => 'Bank expense from sales',
|
||||
'created_by' => 1,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($expenses as $dep) {
|
||||
$fund = Fund::where('restaurant_id', $restaurantId)
|
||||
->where('name', $dep['fund_name'])
|
||||
->first();
|
||||
|
||||
$account = Account::where('restaurant_id', $restaurantId)
|
||||
->where('code', $dep['account_code'])
|
||||
->first();
|
||||
|
||||
if (! $fund || ! $account) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($restaurantId, $fund, $account, $dep) {
|
||||
// 1️⃣ Create Expense
|
||||
$expense = Expense::create([
|
||||
'restaurant_id' => $restaurantId,
|
||||
'fund_id' => $fund->id,
|
||||
'account_id' => $account->id,
|
||||
'expense_category_id' => 1,
|
||||
'amount' => $dep['amount'],
|
||||
'transaction_date' => $dep['transaction_date'],
|
||||
'voucher_no' => $dep['voucher_no'],
|
||||
'received_from' => $dep['received_from'],
|
||||
'note' => $dep['note'],
|
||||
'created_by' => $dep['created_by'],
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
// 2️⃣ Create Transaction
|
||||
$transaction = Transaction::create([
|
||||
'restaurant_id' => $restaurantId,
|
||||
'fund_id' => $fund->id,
|
||||
'transaction_type' => 'expense',
|
||||
'transaction_date' => $dep['transaction_date'],
|
||||
'reference_no' => $dep['voucher_no'],
|
||||
'notes' => $dep['note'],
|
||||
'total_debit' => 0,
|
||||
'total_credit' => $dep['amount'],
|
||||
'created_by' => $dep['created_by'],
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
// 3️⃣ Transaction Details
|
||||
// Credit to Fund (increase)
|
||||
TransactionDetail::create([
|
||||
'restaurant_id' => $restaurantId,
|
||||
'transaction_id' => $transaction->id,
|
||||
'account_id' => $fund->id, // fund receives money (asset)
|
||||
'debit' => $dep['amount'],
|
||||
'credit' => 0,
|
||||
'note' => $dep['note'].' (Fund)',
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
// Debit from Source Account
|
||||
TransactionDetail::create([
|
||||
'restaurant_id' => $restaurantId,
|
||||
'transaction_id' => $transaction->id,
|
||||
'account_id' => $account->id, // source account (income)
|
||||
'debit' => 0,
|
||||
'credit' => $dep['amount'],
|
||||
'note' => $dep['note'].' (Source Account)',
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
// 4️⃣ Update Fund Balance
|
||||
$fund->increment('current_balance', $dep['amount']);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Accounting\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Modules\Accounting\Models\Fund;
|
||||
|
||||
class FundSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// In SaaS onboarding, dynamic restaurant id assigned.
|
||||
// For now, making example default:
|
||||
$restaurantId = 1;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| DEFAULT FUNDS (Cash Sources)
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
$defaultFunds = [
|
||||
['name' => 'Cash', 'type' => 'asset', 'code' => 'FD-001', 'is_default' => true],
|
||||
['name' => 'Bank', 'type' => 'asset', 'code' => 'FD-002', 'is_default' => false],
|
||||
['name' => 'Wallet', 'type' => 'asset', 'code' => 'FD-003', 'is_default' => false],
|
||||
];
|
||||
|
||||
foreach ($defaultFunds as $fund) {
|
||||
Fund::updateOrCreate(
|
||||
[
|
||||
'restaurant_id' => $restaurantId,
|
||||
'code' => $fund['code'],
|
||||
],
|
||||
[
|
||||
'name' => $fund['name'],
|
||||
'type' => $fund['type'],
|
||||
'opening_balance' => 0,
|
||||
'current_balance' => 0,
|
||||
'is_default' => $fund['is_default'],
|
||||
'status' => 1,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
public/restaurant/Modules/Accounting/module.json
Normal file
11
public/restaurant/Modules/Accounting/module.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "Accounting",
|
||||
"alias": "accounting",
|
||||
"description": "",
|
||||
"keywords": [],
|
||||
"priority": 0,
|
||||
"providers": [
|
||||
"Modules\\Accounting\\Providers\\AccountingServiceProvider"
|
||||
],
|
||||
"files": []
|
||||
}
|
||||
15
public/restaurant/Modules/Accounting/package.json
Normal file
15
public/restaurant/Modules/Accounting/package.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"axios": "^1.1.2",
|
||||
"laravel-vite-plugin": "^0.7.5",
|
||||
"sass": "^1.69.5",
|
||||
"postcss": "^8.3.7",
|
||||
"vite": "^4.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
|
||||
<title>Accounting Module - {{ config('app.name', 'Laravel') }}</title>
|
||||
|
||||
<meta name="description" content="{{ $description ?? '' }}">
|
||||
<meta name="keywords" content="{{ $keywords ?? '' }}">
|
||||
<meta name="author" content="{{ $author ?? '' }}">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.bunny.net">
|
||||
<link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />
|
||||
|
||||
{{-- Vite CSS --}}
|
||||
{{-- {{ module_vite('build-accounting', 'resources/assets/sass/app.scss') }} --}}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{ $slot }}
|
||||
|
||||
{{-- Vite JS --}}
|
||||
{{-- {{ module_vite('build-accounting', 'resources/assets/js/app.js') }} --}}
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,5 @@
|
||||
<x-accounting::layouts.master>
|
||||
<h1>Hello World</h1>
|
||||
|
||||
<p>Module: {!! config('accounting.name') !!}</p>
|
||||
</x-accounting::layouts.master>
|
||||
27
public/restaurant/Modules/Accounting/routes/api.php
Normal file
27
public/restaurant/Modules/Accounting/routes/api.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Modules\Accounting\Http\Controllers\API\AccountController;
|
||||
use Modules\Accounting\Http\Controllers\API\DepositCategoryController;
|
||||
use Modules\Accounting\Http\Controllers\API\DepositController;
|
||||
use Modules\Accounting\Http\Controllers\API\ExpenseCategoryController;
|
||||
use Modules\Accounting\Http\Controllers\API\ExpenseController;
|
||||
use Modules\Accounting\Http\Controllers\API\FundController;
|
||||
use Modules\Accounting\Http\Controllers\API\FundTransferController;
|
||||
use Modules\Accounting\Http\Controllers\API\TipController;
|
||||
use Modules\Accounting\Http\Controllers\API\TipDistributionController;
|
||||
|
||||
Route::prefix('/v1')->group(function () {
|
||||
// Protected Routes (Requires Authentication)
|
||||
Route::middleware(['auth:api'])->group(function () {
|
||||
Route::apiResource('accounts', AccountController::class);
|
||||
Route::apiResource('funds', FundController::class);
|
||||
Route::apiResource('deposit-categories', DepositCategoryController::class);
|
||||
Route::apiResource('deposits', DepositController::class);
|
||||
Route::apiResource('expense-categories', ExpenseCategoryController::class);
|
||||
Route::apiResource('expenses', ExpenseController::class);
|
||||
Route::apiResource('fund-transfers', FundTransferController::class);
|
||||
Route::apiResource('tips', TipController::class);
|
||||
Route::apiResource('tip-distributions', TipDistributionController::class);
|
||||
});
|
||||
});
|
||||
57
public/restaurant/Modules/Accounting/vite.config.js
Normal file
57
public/restaurant/Modules/Accounting/vite.config.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import laravel from 'laravel-vite-plugin';
|
||||
import { readdirSync, statSync } from 'fs';
|
||||
import { join,relative,dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
export default defineConfig({
|
||||
build: {
|
||||
outDir: '../../public/build-accounting',
|
||||
emptyOutDir: true,
|
||||
manifest: true,
|
||||
},
|
||||
plugins: [
|
||||
laravel({
|
||||
publicDirectory: '../../public',
|
||||
buildDirectory: 'build-accounting',
|
||||
input: [
|
||||
__dirname + '/resources/assets/sass/app.scss',
|
||||
__dirname + '/resources/assets/js/app.js'
|
||||
],
|
||||
refresh: true,
|
||||
}),
|
||||
],
|
||||
});
|
||||
// Scen all resources for assets file. Return array
|
||||
//function getFilePaths(dir) {
|
||||
// const filePaths = [];
|
||||
//
|
||||
// function walkDirectory(currentPath) {
|
||||
// const files = readdirSync(currentPath);
|
||||
// for (const file of files) {
|
||||
// const filePath = join(currentPath, file);
|
||||
// const stats = statSync(filePath);
|
||||
// if (stats.isFile() && !file.startsWith('.')) {
|
||||
// const relativePath = 'Modules/Accounting/'+relative(__dirname, filePath);
|
||||
// filePaths.push(relativePath);
|
||||
// } else if (stats.isDirectory()) {
|
||||
// walkDirectory(filePath);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// walkDirectory(dir);
|
||||
// return filePaths;
|
||||
//}
|
||||
|
||||
//const __filename = fileURLToPath(import.meta.url);
|
||||
//const __dirname = dirname(__filename);
|
||||
|
||||
//const assetsDir = join(__dirname, 'resources/assets');
|
||||
//export const paths = getFilePaths(assetsDir);
|
||||
|
||||
|
||||
//export const paths = [
|
||||
// 'Modules/Accounting/resources/assets/sass/app.scss',
|
||||
// 'Modules/Accounting/resources/assets/js/app.js',
|
||||
//];
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Authentication\Interfaces;
|
||||
|
||||
interface PermissionInterface
|
||||
{
|
||||
public function index($request, int $perPage = 50);
|
||||
|
||||
public function getById(int $id);
|
||||
|
||||
public function create(array $data);
|
||||
|
||||
public function update(int $id, array $data);
|
||||
|
||||
public function delete(int $id);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Authentication\Interfaces;
|
||||
|
||||
interface RoleInterface
|
||||
{
|
||||
public function index($request, int $perPage = 50);
|
||||
|
||||
public function getById(int $id);
|
||||
|
||||
public function create(array $data);
|
||||
|
||||
public function update(int $id, array $data);
|
||||
|
||||
public function delete(int $id);
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Authentication\Repositories;
|
||||
|
||||
use App\Abstracts\EntityRepository;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Modules\Authentication\Models\Feedback;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class FeedbackRepository extends EntityRepository
|
||||
{
|
||||
public string $table = Feedback::TABLE_NAME;
|
||||
|
||||
protected array $fillableColumns = [
|
||||
'user_id',
|
||||
'description',
|
||||
'status',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
protected function getQuery(): Builder
|
||||
{
|
||||
return parent::getQuery();
|
||||
}
|
||||
|
||||
public function getAll(array $filterData = []): Paginator
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getFeedbackQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
if (isset($filter['search']) && strlen($filter['search']) > 0) {
|
||||
$query = $this->filterSearchQuery($query, $filter['search']);
|
||||
}
|
||||
|
||||
return $query
|
||||
->orderBy($filter['orderBy'], $filter['order'])
|
||||
->paginate($filter['perPage']);
|
||||
}
|
||||
|
||||
protected function getFilterData(array $filterData = []): array
|
||||
{
|
||||
$defaultArgs = [
|
||||
'perPage' => 10,
|
||||
'search' => '',
|
||||
'orderBy' => 'id',
|
||||
'order' => 'desc',
|
||||
'with_deleted' => false,
|
||||
];
|
||||
|
||||
return array_merge($defaultArgs, $filterData);
|
||||
}
|
||||
|
||||
private function getFeedbackQuery(): Builder
|
||||
{
|
||||
return $this->getQuery()
|
||||
->select(
|
||||
'feedback.id',
|
||||
'feedback.user_id',
|
||||
'feedback.description',
|
||||
'feedback.status',
|
||||
'feedback.created_at'
|
||||
);
|
||||
}
|
||||
|
||||
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
|
||||
{
|
||||
$searchable = "%$searchedText%";
|
||||
|
||||
return $query->where('feedback.user_id', 'LIKE', $searchable)
|
||||
->orWhere('feedback.description', 'LIKE', $searchable)
|
||||
->orWhere('feedback.status', 'LIKE', $searchable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
|
||||
{
|
||||
$user = $this->getFeedbackQuery()
|
||||
->where($columnName, $columnValue)
|
||||
->first();
|
||||
|
||||
if (empty($user)) {
|
||||
throw new Exception(
|
||||
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
|
||||
Response::HTTP_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function getCount(array $filterData = []): int
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
|
||||
$query = $this->getQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(array $data): object
|
||||
{
|
||||
try {
|
||||
$data = $this->prepareForDB($data);
|
||||
$userId = $this->getQuery()->insertGetId($data);
|
||||
$user = Feedback::find($userId);
|
||||
|
||||
return $user;
|
||||
} catch (Exception $exception) {
|
||||
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function prepareForDB(array $data, ?object $item = null): array
|
||||
{
|
||||
$data = parent::prepareForDB($data, $item);
|
||||
if (empty($item)) {
|
||||
$data['created_at'] = now();
|
||||
$data['status'] = 1;
|
||||
} else {
|
||||
$data['updated_at'] = now();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update(int $id, array $data): ?object
|
||||
{
|
||||
try {
|
||||
$user = Feedback::find($id);
|
||||
$data = $this->prepareForDB($data, $user);
|
||||
parent::update($id, $data);
|
||||
|
||||
return $this->getById($id);
|
||||
} catch (Exception $exception) {
|
||||
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getExceptionMessages(): array
|
||||
{
|
||||
$exceptionMessages = parent::getExceptionMessages();
|
||||
|
||||
$userExceptionMessages = [
|
||||
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'Feedback does not exist.',
|
||||
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'Feedback could not be deleted.',
|
||||
];
|
||||
|
||||
return array_merge($exceptionMessages, $userExceptionMessages);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Authentication\Repositories;
|
||||
|
||||
use App\Abstracts\EntityRepository;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Modules\Authentication\Models\RestaurantImageSAASSetting;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class RestaurantImageSAASSettingRepository extends EntityRepository
|
||||
{
|
||||
public string $table = RestaurantImageSAASSetting::TABLE_NAME;
|
||||
|
||||
protected array $fillableColumns = [
|
||||
'header_logo_light_theme',
|
||||
'header_logo_dark_theme',
|
||||
'footer_logo_light_theme',
|
||||
'footer_logo_dark_theme',
|
||||
'banner_image',
|
||||
'status',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
];
|
||||
|
||||
protected function getQuery(): Builder
|
||||
{
|
||||
return parent::getQuery();
|
||||
}
|
||||
|
||||
protected function getFilterData(array $filterData = []): array
|
||||
{
|
||||
$defaultArgs = [
|
||||
'perPage' => 10,
|
||||
'search' => '',
|
||||
'orderBy' => 'id',
|
||||
'order' => 'desc',
|
||||
'with_deleted' => false,
|
||||
];
|
||||
|
||||
return array_merge($defaultArgs, $filterData);
|
||||
}
|
||||
|
||||
private function getRestaurantImageSAASSettingQuery(): Builder
|
||||
{
|
||||
return $this->getQuery()
|
||||
->select(
|
||||
"{$this->table}.id",
|
||||
"{$this->table}.header_logo_light_theme",
|
||||
"{$this->table}.header_logo_dark_theme",
|
||||
"{$this->table}.footer_logo_light_theme",
|
||||
"{$this->table}.footer_logo_dark_theme",
|
||||
"{$this->table}.banner_image",
|
||||
"{$this->table}.status",
|
||||
"{$this->table}.created_at",
|
||||
"{$this->table}.deleted_at"
|
||||
);
|
||||
}
|
||||
|
||||
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
|
||||
{
|
||||
$searchable = "%$searchedText%";
|
||||
|
||||
return $query->where("{$this->table}.name", 'LIKE', $searchable)
|
||||
->orWhere("{$this->table}.status", 'LIKE', $searchable);
|
||||
}
|
||||
|
||||
public function getAll(array $filterData = []): Paginator
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getRestaurantImageSAASSettingQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
if (! empty($filter['search'])) {
|
||||
$query = $this->filterSearchQuery($query, $filter['search']);
|
||||
}
|
||||
|
||||
return $query
|
||||
->orderBy($filter['orderBy'], $filter['order'])
|
||||
->paginate($filter['perPage']);
|
||||
}
|
||||
|
||||
public function getCount(array $filterData = []): int
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
|
||||
{
|
||||
$item = $this->getRestaurantImageSAASSettingQuery()
|
||||
->where($columnName, $columnValue)
|
||||
->first($selects);
|
||||
|
||||
if (empty($item)) {
|
||||
throw new Exception(
|
||||
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
|
||||
Response::HTTP_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(array $data): object
|
||||
{
|
||||
$data = $this->prepareForDB($data);
|
||||
$id = $this->getQuery()->insertGetId($data);
|
||||
|
||||
return RestaurantImageSAASSetting::find($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update(int $id, array $data): object
|
||||
{
|
||||
$item = RestaurantImageSAASSetting::findOrFail($id);
|
||||
$data = $this->prepareForDB($data, $item);
|
||||
parent::update($id, $data);
|
||||
|
||||
return $this->getById($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function prepareForDB(array $data, ?object $item = null): array
|
||||
{
|
||||
$data = parent::prepareForDB($data, $item);
|
||||
|
||||
if (empty($item)) {
|
||||
$data['created_at'] = now();
|
||||
$data['status'] = 1;
|
||||
|
||||
if (! empty($data['header_logo_light_theme']) && $data['header_logo_light_theme'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['header_logo_light_theme'] = fileUploader('restaurant_image_settings/', 'png', $data['header_logo_light_theme']);
|
||||
}
|
||||
|
||||
if (! empty($data['header_logo_dark_theme']) && $data['header_logo_dark_theme'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['header_logo_dark_theme'] = fileUploader('restaurant_image_settings/', 'png', $data['header_logo_dark_theme']);
|
||||
}
|
||||
|
||||
if (! empty($data['footer_logo_light_theme']) && $data['footer_logo_light_theme'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['footer_logo_light_theme'] = fileUploader('restaurant_image_settings/', 'png', $data['footer_logo_light_theme']);
|
||||
}
|
||||
|
||||
if (! empty($data['footer_logo_dark_theme']) && $data['footer_logo_dark_theme'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['footer_logo_dark_theme'] = fileUploader('restaurant_image_settings/', 'png', $data['footer_logo_dark_theme']);
|
||||
}
|
||||
|
||||
if (! empty($data['banner_image']) && $data['banner_image'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['banner_image'] = fileUploader('restaurant_image_settings/', 'png', $data['banner_image']);
|
||||
}
|
||||
} else {
|
||||
if (! empty($data['header_logo_light_theme']) && $data['header_logo_light_theme'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['header_logo_light_theme'] = fileUploader('restaurant_image_settings/', 'png', $data['header_logo_light_theme'], $item->header_logo_light_theme);
|
||||
}
|
||||
|
||||
if (! empty($data['header_logo_dark_theme']) && $data['header_logo_dark_theme'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['header_logo_dark_theme'] = fileUploader('restaurant_image_settings/', 'png', $data['header_logo_dark_theme'], $item->header_logo_dark_theme);
|
||||
}
|
||||
|
||||
if (! empty($data['footer_logo_light_theme']) && $data['footer_logo_light_theme'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['footer_logo_light_theme'] = fileUploader('restaurant_image_settings/', 'png', $data['footer_logo_light_theme'], $item->footer_logo_light_theme);
|
||||
}
|
||||
|
||||
if (! empty($data['footer_logo_dark_theme']) && $data['footer_logo_dark_theme'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['footer_logo_dark_theme'] = fileUploader('restaurant_image_settings/', 'png', $data['footer_logo_dark_theme'], $item->footer_logo_dark_theme);
|
||||
}
|
||||
|
||||
if (! empty($data['banner_image']) && $data['banner_image'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['banner_image'] = fileUploader('restaurant_image_settings/', 'png', $data['banner_image'], $item->banner_image);
|
||||
}
|
||||
|
||||
$data['updated_at'] = now();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getExceptionMessages(): array
|
||||
{
|
||||
return [
|
||||
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'RestaurantImageSAASSetting does not exist.',
|
||||
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'RestaurantImageSAASSetting could not be deleted.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Authentication\Repositories;
|
||||
|
||||
use App\Abstracts\EntityRepository;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Modules\Authentication\Models\RestaurantImageSetting;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class RestaurantImageSettingRepository extends EntityRepository
|
||||
{
|
||||
public string $table = RestaurantImageSetting::TABLE_NAME;
|
||||
|
||||
protected array $fillableColumns = [
|
||||
'restaurant_id',
|
||||
'header_logo_light_theme',
|
||||
'header_logo_dark_theme',
|
||||
'footer_logo_light_theme',
|
||||
'footer_logo_dark_theme',
|
||||
'banner_image',
|
||||
'status',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
];
|
||||
|
||||
protected function getQuery(): Builder
|
||||
{
|
||||
return parent::getQuery();
|
||||
}
|
||||
|
||||
protected function getFilterData(array $filterData = []): array
|
||||
{
|
||||
$defaultArgs = [
|
||||
'perPage' => 10,
|
||||
'search' => '',
|
||||
'orderBy' => 'id',
|
||||
'order' => 'desc',
|
||||
'with_deleted' => false,
|
||||
];
|
||||
|
||||
return array_merge($defaultArgs, $filterData);
|
||||
}
|
||||
|
||||
private function getRestaurantImageSettingQuery(): Builder
|
||||
{
|
||||
return $this->getQuery()
|
||||
->select(
|
||||
"{$this->table}.id",
|
||||
"{$this->table}.restaurant_id",
|
||||
"{$this->table}.header_logo_light_theme",
|
||||
"{$this->table}.header_logo_dark_theme",
|
||||
"{$this->table}.footer_logo_light_theme",
|
||||
"{$this->table}.footer_logo_dark_theme",
|
||||
"{$this->table}.banner_image",
|
||||
"{$this->table}.status",
|
||||
"{$this->table}.created_at",
|
||||
"{$this->table}.deleted_at"
|
||||
);
|
||||
}
|
||||
|
||||
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
|
||||
{
|
||||
$searchable = "%$searchedText%";
|
||||
|
||||
return $query->where("{$this->table}.name", 'LIKE', $searchable)
|
||||
->orWhere("{$this->table}.status", 'LIKE', $searchable);
|
||||
}
|
||||
|
||||
public function getAll(array $filterData = []): Paginator
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getRestaurantImageSettingQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
if (! empty($filter['search'])) {
|
||||
$query = $this->filterSearchQuery($query, $filter['search']);
|
||||
}
|
||||
|
||||
return $query
|
||||
->orderBy($filter['orderBy'], $filter['order'])
|
||||
->paginate($filter['perPage']);
|
||||
}
|
||||
|
||||
public function getCount(array $filterData = []): int
|
||||
{
|
||||
$filter = $this->getFilterData($filterData);
|
||||
$query = $this->getQuery();
|
||||
|
||||
if (! $filter['with_deleted']) {
|
||||
$query->whereNull("{$this->table}.deleted_at");
|
||||
}
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
|
||||
{
|
||||
$item = $this->getRestaurantImageSettingQuery()
|
||||
->where($columnName, $columnValue)
|
||||
->first($selects);
|
||||
|
||||
if (empty($item)) {
|
||||
throw new Exception(
|
||||
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
|
||||
Response::HTTP_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(array $data): object
|
||||
{
|
||||
$data = $this->prepareForDB($data);
|
||||
$id = $this->getQuery()->insertGetId($data);
|
||||
|
||||
return RestaurantImageSetting::find($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function update(int $id, array $data): object
|
||||
{
|
||||
$item = RestaurantImageSetting::findOrFail($id);
|
||||
$data = $this->prepareForDB($data, $item);
|
||||
parent::update($id, $data);
|
||||
|
||||
return $this->getById($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function prepareForDB(array $data, ?object $item = null): array
|
||||
{
|
||||
$data = parent::prepareForDB($data, $item);
|
||||
|
||||
if (empty($item)) {
|
||||
$data['created_at'] = now();
|
||||
$data['restaurant_id'] = $this->getCurrentRestaurantId();
|
||||
$data['status'] = 1;
|
||||
|
||||
if (! empty($data['header_logo_light_theme']) && $data['header_logo_light_theme'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['header_logo_light_theme'] = fileUploader('restaurant_image_settings/', 'png', $data['header_logo_light_theme']);
|
||||
}
|
||||
|
||||
if (! empty($data['header_logo_dark_theme']) && $data['header_logo_dark_theme'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['header_logo_dark_theme'] = fileUploader('restaurant_image_settings/', 'png', $data['header_logo_dark_theme']);
|
||||
}
|
||||
|
||||
if (! empty($data['footer_logo_light_theme']) && $data['footer_logo_light_theme'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['footer_logo_light_theme'] = fileUploader('restaurant_image_settings/', 'png', $data['footer_logo_light_theme']);
|
||||
}
|
||||
|
||||
if (! empty($data['footer_logo_dark_theme']) && $data['footer_logo_dark_theme'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['footer_logo_dark_theme'] = fileUploader('restaurant_image_settings/', 'png', $data['footer_logo_dark_theme']);
|
||||
}
|
||||
|
||||
if (! empty($data['banner_image']) && $data['banner_image'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['banner_image'] = fileUploader('restaurant_image_settings/', 'png', $data['banner_image']);
|
||||
}
|
||||
} else {
|
||||
if (! empty($data['header_logo_light_theme']) && $data['header_logo_light_theme'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['header_logo_light_theme'] = fileUploader('restaurant_image_settings/', 'png', $data['header_logo_light_theme'], $item->header_logo_light_theme);
|
||||
}
|
||||
|
||||
if (! empty($data['header_logo_dark_theme']) && $data['header_logo_dark_theme'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['header_logo_dark_theme'] = fileUploader('restaurant_image_settings/', 'png', $data['header_logo_dark_theme'], $item->header_logo_dark_theme);
|
||||
}
|
||||
|
||||
if (! empty($data['footer_logo_light_theme']) && $data['footer_logo_light_theme'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['footer_logo_light_theme'] = fileUploader('restaurant_image_settings/', 'png', $data['footer_logo_light_theme'], $item->footer_logo_light_theme);
|
||||
}
|
||||
|
||||
if (! empty($data['footer_logo_dark_theme']) && $data['footer_logo_dark_theme'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['footer_logo_dark_theme'] = fileUploader('restaurant_image_settings/', 'png', $data['footer_logo_dark_theme'], $item->footer_logo_dark_theme);
|
||||
}
|
||||
|
||||
if (! empty($data['banner_image']) && $data['banner_image'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$data['banner_image'] = fileUploader('restaurant_image_settings/', 'png', $data['banner_image'], $item->banner_image);
|
||||
}
|
||||
|
||||
$data['updated_at'] = now();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getExceptionMessages(): array
|
||||
{
|
||||
return [
|
||||
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'RestaurantImageSetting does not exist.',
|
||||
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'RestaurantImageSetting could not be deleted.',
|
||||
];
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user