akaunting 3.0 (the last dance)

This commit is contained in:
Burak Civan 2022-06-01 10:15:55 +03:00
parent cead09f6d4
commit d9c0764572
3812 changed files with 126831 additions and 102949 deletions

View File

@ -19,7 +19,10 @@ BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_CONNECTION=sync
LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
MAIL_MAILER=mail
MAIL_HOST=localhost
@ -33,3 +36,6 @@ MAIL_FROM_ADDRESS=null
FIREWALL_ENABLED=false
MODEL_CACHE_ENABLED=false
DEBUGBAR_EDITOR=vscode
IGNITION_EDITOR=vscode

14
.git-ftp-ignore Normal file
View File

@ -0,0 +1,14 @@
.gitignore
.gitattributes
.git-ftp-ignore
.git-ftp-include
.git-ftp-log
.gitlab-ci.yml
.ftpquota
.git/*
.github/*
.public/js/*
.vendor/*
.node_modules/*
composer.lock

View File

@ -1,7 +1,7 @@
name: Tests
on:
push:
push:
pull_request:
schedule:
- cron: '0 0 * * *'
@ -15,7 +15,7 @@ jobs:
strategy:
matrix:
php: ['7.3', '7.4']
php: ['8.0', '8.1']
steps:
- name: Checkout code

2
.gitignore vendored
View File

@ -85,7 +85,6 @@ Homestead.json
Homestead.yaml
npm-debug.log
.env
.env.example
robots.txt
_ide_helper.php
_ide_helper_models.php
@ -95,3 +94,4 @@ _ide_helper_models.php
modules/*
!modules/.gitkeep
.laravelstatsrc
.DS_Store

View File

@ -6,7 +6,7 @@
[![Tests](https://img.shields.io/github/workflow/status/akaunting/akaunting/Tests?label=tests)](https://github.com/akaunting/akaunting/actions)
[![License](https://img.shields.io/github/license/akaunting/akaunting?label=license)](LICENSE.txt)
Akaunting is a free, open source and online accounting software designed for small businesses and freelancers. It is built with modern technologies such as Laravel, VueJS, Bootstrap 4, RESTful API etc. Thanks to its modular structure, Akaunting provides an awesome App Store for users and developers.
Akaunting is a free, open source and online accounting software designed for small businesses and freelancers. It is built with modern technologies such as Laravel, VueJS, Tailwind, RESTful API etc. Thanks to its modular structure, Akaunting provides an awesome App Store for users and developers.
* [Home](https://akaunting.com) - The house of Akaunting
* [Forum](https://akaunting.com/forum) - Ask for support
@ -17,7 +17,7 @@ Akaunting is a free, open source and online accounting software designed for sma
## Requirements
* PHP 7.3 or higher
* PHP 8.0 or higher
* Database (eg: MySQL, PostgreSQL, SQLite)
* Web Server (eg: Apache, Nginx, IIS)
* [Other libraries](https://akaunting.com/docs/requirements)
@ -65,16 +65,6 @@ Please review [our security policy](https://github.com/akaunting/akaunting/secur
* [Cüneyt Şentürk](https://github.com/cuneytsenturk)
* [All Contributors](../../contributors)
## Partners
Each of our partners can help you craft a beautiful, well-architected project. Feel free to get in [contact](https://akaunting.com/contact) with us to become a partner.
* [Creative Tim](https://www.creative-tim.com) is our design partner since Akaunting 2.0 version. They create beautiful UI Kits, Templates, and Dashboards built on top of Bootstrap, Vue.js, React, Angular, Node.js, and Laravel.
## Sponsors
Support Akaunting by becoming a sponsor on [Patreon](https://www.patreon.com/akaunting). Your logo will show up here with a link to your website.
## License
Akaunting is released under the [GPLv3 license](LICENSE.txt).

View File

@ -18,28 +18,54 @@ abstract class BulkAction
public $model = false;
public $actions = [
'enable' => [
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-common-items',
'enable' => [
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-common-items',
],
'disable' => [
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-common-items',
'disable' => [
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-common-items',
],
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-common-items',
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-common-items',
],
'export' => [
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download'
'export' => [
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download'
],
];
public $icons = [
'enable' => 'check_circle',
'disable' => 'hide_source',
'delete' => 'delete',
'export' => 'file_download',
'reconcile' => 'published_with_changes',
'unreconcile' => 'layers_clear',
'received' => 'call_received',
'cancelled' => 'cancel',
'sent' => 'send',
'approved' => 'approval',
'refused' => 'do_not_disturb_on',
'issued' => 'mark_email_read',
'confirmed' => 'thumb_up_alt',
];
public $messages = [
'general' => 'bulk_actions.success.general',
'enable' => 'messages.success.enabled',
'disable' => 'messages.success.disabled',
'delete' => 'messages.success.deleted',
'duplicate' => 'messages.success.duplicated',
'invite' => 'messages.success.invited',
'end' => 'messages.success.ended',
];
public function getSelectedRecords($request, $relationships = null)
{
if (empty($relationships)) {

View File

@ -5,6 +5,7 @@ namespace App\Abstracts;
use App\Models\Auth\User;
use App\Models\Common\Company;
use App\Traits\Jobs;
use Closure;
use Illuminate\Database\Eloquent\Factories\Factory as BaseFactory;
use Illuminate\Database\Eloquent\Model as EloquentModel;
@ -28,16 +29,46 @@ abstract class Factory extends BaseFactory
config(['mail.default' => 'array']);
$this->user = User::first();
$this->company = $this->user->companies()->first();
// TODO: this location was put to make US | for "gmail.co.uk" issue
$this->faker = \Faker\Factory::create();
company($this->company->id)->makeCurrent();
$this->setUser();
$this->setCompany();
}
public function getCompanyUsers(): array
{
return $this->company->users()->enabled()->get()->pluck('id')->toArray();
}
public function company(int $id): static
{
return $this->state([
'company_id' => $id,
]);
}
public function setUser(): void
{
$this->user = User::first();
}
public function setCompany(): void
{
$company_id = $this->getRawAttribute('company_id');
$this->company = !empty($company_id) ? Company::find($company_id) : $this->user->companies()->first();
$this->company->makeCurrent();
app('url')->defaults(['company_id' => company_id()]);
}
public function getCompanyUsers()
public function getRawAttribute($key)
{
return $this->company->users()->enabled()->get()->pluck('id')->toArray();
$raw = $this->state([])->getExpandedAttributes(null);
return $raw[$key] ?? null;
}
}

View File

@ -5,16 +5,18 @@ namespace App\Abstracts\Http;
use App\Traits\Jobs;
use App\Traits\Permissions;
use App\Traits\Relationships;
use Dingo\Api\Exception\ResourceException;
use Dingo\Api\Routing\Helpers;
use App\Exceptions\Http\Resource as ResourceException;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\Controller as BaseController;
use Symfony\Component\HttpKernel\Exception\HttpException;
abstract class ApiController extends BaseController
{
use AuthorizesRequests, Jobs, Helpers, Permissions, Relationships, ValidatesRequests;
use AuthorizesRequests, Jobs, Permissions, Relationships, ValidatesRequests;
/**
* Instantiate a new controller instance.
@ -39,4 +41,146 @@ abstract class ApiController extends BaseController
return redirect()->to($this->getRedirectUrl())->withInput($request->input())->withErrors($errors, $this->errorBag());
}
/**
* Respond with a location and a created resource.
*
* @param string $location
* @param object $resource
*
* @return \Illuminate\Http\JsonResponse
*/
public function created($location, $resource): JsonResponse
{
return $resource
->response()
->setStatusCode(201)
->header('Location', $location);
}
/**
* Respond with a location and an accepted resource.
*
* @param string $location
* @param object $resource
*
* @return \Illuminate\Http\JsonResponse
*/
public function accepted($location, $resource): JsonResponse
{
return $resource
->response()
->setStatusCode(202)
->header('Location', $location);
}
/**
* Respond with empty content.
*
* @return \Illuminate\Http\Response
*/
public function noContent(): Response
{
return (new Response)
->setStatusCode(204);
}
/**
* Return an error response.
*
* @param string $message
* @param int $statusCode
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
*
* @return void
*/
public function error($message, $statusCode)
{
throw new HttpException($statusCode, $message);
}
/**
* Return a 404 not found error.
*
* @param string $message
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
*
* @return void
*/
public function errorNotFound($message = 'Not Found')
{
$this->error($message, 404);
}
/**
* Return a 400 bad request error.
*
* @param string $message
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
*
* @return void
*/
public function errorBadRequest($message = 'Bad Request')
{
$this->error($message, 400);
}
/**
* Return a 403 forbidden error.
*
* @param string $message
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
*
* @return void
*/
public function errorForbidden($message = 'Forbidden')
{
$this->error($message, 403);
}
/**
* Return a 500 internal server error.
*
* @param string $message
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
*
* @return void
*/
public function errorInternal($message = 'Internal Error')
{
$this->error($message, 500);
}
/**
* Return a 401 unauthorized error.
*
* @param string $message
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
*
* @return void
*/
public function errorUnauthorized($message = 'Unauthorized')
{
$this->error($message, 401);
}
/**
* Return a 405 method not allowed error.
*
* @param string $message
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
*
* @return void
*/
public function errorMethodNotAllowed($message = 'Method Not Allowed')
{
$this->error($message, 405);
}
}

View File

@ -25,7 +25,7 @@ abstract class FormRequest extends BaseFormRequest
* @param string $offset
* @return bool
*/
public function offsetExists($offset)
public function offsetExists($offset): bool
{
return Arr::has(
$this->route() ? $this->all() + $this->route()->parameters() : $this->all(),

View File

@ -41,16 +41,18 @@ abstract class PaymentController extends BaseController
});
}
public function show(Document $invoice, PaymentRequest $request)
public function show(Document $invoice, PaymentRequest $request, $cards = [])
{
$this->setContactFirstLastName($invoice);
$confirm_url = $this->getConfirmUrl($invoice);
$html = view('partials.portal.payment_method.' . $this->type, [
$html = view('components.payment_method.' . $this->type, [
'setting' => $this->setting,
'invoice' => $invoice,
'confirm_url' => $confirm_url,
'store_card' => !empty($this->setting['store_card']) ? true : false,
'cards' => $cards,
])->render();
return response()->json([
@ -101,15 +103,15 @@ abstract class PaymentController extends BaseController
flash($message)->success();
$invoice_url = $this->getInvoiceUrl($invoice);
$finish_url = $this->getFinishUrl($invoice);
if ($force_redirect || ($this->type == 'redirect')) {
return redirect($invoice_url);
return redirect($finish_url);
}
return response()->json([
'error' => $message,
'redirect' => $invoice_url,
'redirect' => $finish_url,
'success' => true,
'data' => false,
]);
@ -122,6 +124,13 @@ abstract class PaymentController extends BaseController
: URL::signedRoute('signed.invoices.show', [$invoice->id]);
}
public function getFinishUrl($invoice)
{
return request()->isPortal($invoice->company_id)
? route('portal.invoices.finish', $invoice->id)
: URL::signedRoute('signed.invoices.finish', [$invoice->id]);
}
public function getConfirmUrl($invoice)
{
return $this->getModuleUrl($invoice, 'confirm');

View File

@ -0,0 +1,161 @@
<?php
namespace App\Abstracts\Http;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Setting\Setting as Request;
use App\Models\Common\Company;
use App\Models\Setting\Currency;
use App\Traits\DateTime;
use App\Traits\Uploads;
use App\Utilities\Installer;
use Illuminate\Support\Str;
abstract class SettingController extends Controller
{
use DateTime, Uploads;
public $redirect_route = '';
public $skip_keys = ['company_id', '_method', '_token', '_prefix'];
public $file_keys = ['company.logo', 'invoice.logo'];
public $uploaded_file_keys = ['company.uploaded_logo', 'invoice.uploaded_logo'];
/**
* Update the specified resource in storage.
*
* @param Request $request
*
* @return Response
*/
public function update(Request $request)
{
$fields = $request->all();
$prefix = $request->get('_prefix', 'general');
$company_id = $request->get('company_id');
if (empty($company_id)) {
$company_id = company_id();
}
$company = Company::find($company_id);
$total_companies = Company::count();
foreach ($fields as $key => $value) {
$real_key = $prefix . '.' . $key;
// Don't process unwanted keys
if (in_array($key, $this->skip_keys)) {
continue;
}
// change dropzone middleware already uploaded file
if (in_array($real_key, $this->uploaded_file_keys)) {
continue;
}
// Process file uploads
if (in_array($real_key, $this->file_keys)) {
// Upload attachment
if ($request->file($key)) {
$media = $this->getMedia($request->file($key), 'settings');
$company->attachMedia($media, Str::snake($real_key));
$value = $media->id;
}
// Prevent reset
if (empty($value)) {
continue;
}
}
if ($real_key == 'default.locale') {
if (!in_array($value, config('language.allowed'))) {
continue;
}
user()->setAttribute('locale', $value)->save();
}
if ($real_key == 'default.currency') {
$currencies = Currency::enabled()->pluck('code')->toArray();
if (!in_array($value, $currencies)) {
continue;
}
$currency = Currency::code($value)->first();
$currency->rate = '1';
$currency->save();
}
// If only 1 company
if ($total_companies == 1) {
$this->oneCompany($real_key, $value);
}
setting()->set($real_key, $value);
}
// Save all settings
setting()->save();
$message = trans('messages.success.updated', ['type' => trans_choice('general.settings', 2)]);
$redirect_url = !empty($this->redirect_route) ? route($this->redirect_route) : url()->previous();
$response = [
'status' => null,
'success' => true,
'error' => false,
'message' => $message,
'data' => null,
'redirect' => $redirect_url,
];
flash($message)->success();
return response()->json($response);
}
protected function oneCompany($real_key, $value)
{
switch ($real_key) {
case 'company.name':
Installer::updateEnv(['MAIL_FROM_NAME' => '"' . $value . '"']);
break;
case 'company.email':
Installer::updateEnv(['MAIL_FROM_ADDRESS' => '"' . $value . '"']);
break;
case 'default.locale':
Installer::updateEnv(['APP_LOCALE' => '"' . $value . '"']);
break;
case 'schedule.time':
Installer::updateEnv(['APP_SCHEDULE_TIME' => '"' . $value . '"']);
break;
case 'email.protocol':
Installer::updateEnv(['MAIL_MAILER' => '"' . $value . '"']);
break;
case 'email.smtp_host':
Installer::updateEnv(['MAIL_HOST' => '"' . $value . '"']);
break;
case 'email.smtp_port':
Installer::updateEnv(['MAIL_PORT' => '"' . $value . '"']);
break;
case 'email.smtp_username':
Installer::updateEnv(['MAIL_USERNAME' => '"' . $value . '"']);
break;
case 'email.smtp_password':
Installer::updateEnv(['MAIL_PASSWORD' => '"' . $value . '"']);
break;
case 'email.smtp_encryption':
Installer::updateEnv(['MAIL_ENCRYPTION' => '"' . $value . '"']);
break;
}
}
}

View File

@ -84,7 +84,7 @@ abstract class Report
public function getCategories($types, $limit = false)
{
$model = Category::type($types)->orderBy('name');
$model = Category::withSubCategory()->type($types)->orderBy('name');
if ($limit !== false) {
$model->take(setting('default.select_limit'));
@ -183,14 +183,69 @@ abstract class Report
public function setRowNamesAndValues($event, $rows)
{
$nodes = [];
foreach ($event->class->dates as $date) {
foreach ($event->class->tables as $table) {
foreach ($event->class->tables as $table_key => $table_name) {
foreach ($rows as $id => $name) {
$event->class->row_names[$table][$id] = $name;
$event->class->row_values[$table][$id][$date] = 0;
$event->class->row_names[$table_key][$id] = $name;
$event->class->row_values[$table_key][$id][$date] = 0;
$nodes[$id] = null;
}
}
}
$this->setTreeNodes($event, $nodes);
}
public function setTreeNodes($event, $nodes)
{
foreach ($event->class->tables as $table_key => $table_name) {
foreach ($nodes as $id => $node) {
$event->class->row_tree_nodes[$table_key][$id] = $node;
}
}
}
public function getCategoriesNodes($categories)
{
$nodes = [];
foreach ($categories as $id => $name) {
$category = Category::withSubCategory()->find($id);
if (!is_null($category->parent_id)) {
unset($categories[$id]);
continue;
}
$nodes[$id] = $this->getSubCategories($category);
}
return $nodes;
}
public function getSubCategories($category)
{
if ($category->sub_categories->count() == 0) {
return null;
}
$sub_categories = [];
foreach ($category->sub_categories as $sub_category) {
$sub_category->load('sub_categories');
$sub_categories[$sub_category->id] = $this->getSubCategories($sub_category);
}
if (!empty($sub_categories)) {
$sub_categories[$category->id] = null;
}
return $sub_categories;
}
public function getFormattedDate($event, $date)

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@
namespace App\Abstracts;
use Akaunting\Sortable\Traits\Sortable;
use App\Events\Common\SearchStringApplied;
use App\Events\Common\SearchStringApplying;
use App\Traits\DateTime;
@ -9,9 +10,9 @@ use App\Traits\Owners;
use App\Traits\Sources;
use App\Traits\Tenants;
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model as Eloquent;
use Illuminate\Database\Eloquent\SoftDeletes;
use Kyslik\ColumnSortable\Sortable;
use Laratrust\Contracts\Ownable;
use Lorisleiva\LaravelSearchString\Concerns\SearchString;
@ -30,30 +31,18 @@ abstract class Model extends Eloquent implements Ownable
public $allAttributes = [];
/**
* Create a new Eloquent model instance.
* Fill the model with an array of attributes.
*
* @param array $attributes
* @return void
* @return $this
*
* @throws \Illuminate\Database\Eloquent\MassAssignmentException
*/
public function __construct(array $attributes = [])
public function fill(array $attributes)
{
$this->allAttributes = $attributes;
parent::__construct($attributes);
}
/**
* Update the model in the database.
*
* @param array $attributes
* @param array $options
* @return bool
*/
public function update(array $attributes = [], array $options = [])
{
$this->allAttributes = $attributes;
return parent::update($attributes, $options);
return parent::fill($attributes);
}
/**
@ -231,6 +220,16 @@ abstract class Model extends Eloquent implements Ownable
return $query->where($this->qualifyColumn('created_by'), '<>', user_id());
}
public function scopeIsRecurring(Builder $query): Builder
{
return $query->where($this->qualifyColumn('type'), 'like', '%-recurring');
}
public function scopeIsNotRecurring(Builder $query): Builder
{
return $query->where($this->qualifyColumn('type'), 'not like', '%-recurring');
}
public function ownerKey($owner)
{
if ($this->isNotOwnable()) {

View File

@ -6,11 +6,19 @@ use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification as BaseNotification;
use Illuminate\Support\Str;
abstract class Notification extends BaseNotification implements ShouldQueue
{
use Queueable;
/**
* Custom mail subject, body, etc.
*
* @var array
*/
public $custom_mail;
/**
* Create a notification instance.
*/
@ -33,31 +41,38 @@ abstract class Notification extends BaseNotification implements ShouldQueue
/**
* Initialise the mail representation of the notification.
*
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function initMessage()
public function initMailMessage(): MailMessage
{
app('url')->defaults(['company_id' => company_id()]);
$message = (new MailMessage)
->from(config('mail.from.address'), config('mail.from.name'))
->subject($this->getSubject())
->view('partials.email.body', ['body' => $this->getBody()]);
->view('components.email.body', ['body' => $this->getBody()]);
if (!empty($this->custom_mail['cc'])) {
$message->cc($this->custom_mail['cc']);
}
return $message;
}
public function getSubject()
public function getSubject(): string
{
return $this->replaceTags($this->template->subject);
return !empty($this->custom_mail['subject'])
? $this->custom_mail['subject']
: $this->replaceTags($this->template->subject);
}
public function getBody()
{
return $this->replaceTags($this->template->body);
$body = !empty($this->custom_mail['body']) ? $this->custom_mail['body'] : $this->replaceTags($this->template->body);
return $body . $this->getFooter();
}
public function replaceTags($content)
public function replaceTags(string $content): string
{
$pattern = $this->getTagsPattern();
$replacement = $this->applyQuote($this->getTagsReplacement());
@ -65,7 +80,16 @@ abstract class Notification extends BaseNotification implements ShouldQueue
return $this->revertQuote(preg_replace($pattern, $replacement, $content));
}
public function getTagsPattern()
public function getFooter()
{
$url = 'https://akaunting.com/lp/accounting-software?utm_source=email&utm_medium=software&utm_campaign=footer&utm_content=' . $this->template->alias;
$get_started = '<a href="' . $url . '" style="color: #676ba2; text-decoration: none;">' . trans('footer.get_started') . '</a>';
return view('components.email.footer', compact('url', 'get_started'));
}
public function getTagsPattern(): array
{
$pattern = [];
@ -76,17 +100,35 @@ abstract class Notification extends BaseNotification implements ShouldQueue
return $pattern;
}
public function getTags()
public function getTags(): array
{
return [];
}
public function getTagsReplacement()
public function getTagsReplacement(): array
{
return [];
}
public function applyQuote($vars)
public function getTagsBinding(): array
{
$bindings = [];
$tags = $this->getTags();
$replacements = $this->getTagsReplacement();
$wrappers = ['{', '}'];
foreach ($tags as $index => $tag) {
$key = Str::replace($wrappers, '', $tag);
$bindings[$key] = $replacements[$index];
}
return $bindings;
}
public function applyQuote(array $vars): array
{
$new_vars = [];
@ -97,8 +139,16 @@ abstract class Notification extends BaseNotification implements ShouldQueue
return $new_vars;
}
public function revertQuote($content)
public function revertQuote(string $content): string
{
return str_replace('\\', '', $content);
}
/**
* @deprecated 3.0
*/
public function initMessage()
{
return $this->initMailMessage();
}
}

View File

@ -2,9 +2,9 @@
namespace App\Abstracts;
use Monooso\Unobserve\CanMute;
use Akaunting\MutableObserver\Traits\Mutable;
abstract class Observer
{
use CanMute;
use Mutable;
}

View File

@ -2,6 +2,7 @@
namespace App\Abstracts;
use Akaunting\Apexcharts\Charts as Apexcharts;
use App\Events\Report\DataLoaded;
use App\Events\Report\DataLoading;
use App\Events\Report\FilterApplying;
@ -12,17 +13,18 @@ use App\Events\Report\RowsShowing;
use App\Exports\Common\Reports as Export;
use App\Models\Common\Report as Model;
use App\Models\Document\Document;
use App\Models\Setting\Category;
use App\Traits\Charts;
use App\Traits\DateTime;
use App\Traits\SearchString;
use App\Utilities\Chartjs;
use App\Traits\Translations;
use App\Utilities\Date;
use App\Utilities\Export as ExportHelper;
use Illuminate\Support\Str;
abstract class Report
{
use Charts, DateTime, SearchString;
use Charts, DateTime, SearchString, Translations;
public $model;
@ -30,7 +32,9 @@ abstract class Report
public $category = 'reports.income_expense';
public $icon = 'fa fa-chart-pie';
public $icon = 'donut_small';
public $type = 'detail';
public $has_money = true;
@ -53,23 +57,21 @@ abstract class Report
public $loaded = false;
public $chart = [
'line' => [
'width' => '0',
'height' => '300',
'options' => [
'color' => '#6da252',
'legend' => [
'display' => false,
],
'bar' => [
'colors' => [
'#6da252',
],
],
'dates' => [],
'datasets' => [],
'donut' => [
//
],
];
public $column_name_width = 'report-column-name';
public $column_value_width = 'report-column-value';
public $row_tree_nodes = [];
public function __construct(Model $model = null, $load_data = true)
{
$this->setGroups();
@ -126,6 +128,18 @@ abstract class Report
return trans($this->category);
}
public function getCategoryDescription()
{
if (!empty($this->category_description)) {
return trans($this->category_description);
}
return $this->findTranslation([
$this->category . '_desc',
$this->category . '_description',
]);
}
public function getIcon()
{
return $this->icon;
@ -152,47 +166,77 @@ abstract class Report
return $total;
}
public function getChart()
public function getCharts($table_key)
{
$chart = new Chartjs();
return [
'bar' => $this->getBarChart($table_key),
'donut' => $this->getDonutChart($table_key),
];
}
if (!$type = $this->getSetting('chart')) {
public function getBarChart($table_key)
{
$chart = new Apexcharts();
if (empty($this->chart)) {
return $chart;
}
$config = $this->chart[$type];
$options = !empty($this->chart[$table_key]) ? $this->chart[$table_key]['bar'] : $this->chart['bar'];
$default_options = $this->getLineChartOptions();
$chart->setType('bar')
->setOptions($options)
->setLabels(array_values($this->dates))
->setDataset($this->tables[$table_key], 'column', array_values($this->footer_totals[$table_key]));
$options = array_merge($default_options, (array) $config['options']);
return $chart;
}
$chart->type($type)
->width((int) $config['width'])
->height((int) $config['height'])
->options($options)
->labels(!empty($config['dates']) ? array_values($config['dates']) : array_values($this->dates));
public function getDonutChart($table_key)
{
$chart = new Apexcharts();
if (!empty($config['datasets'])) {
foreach ($config['datasets'] as $dataset) {
$chart->dataset($dataset['name'], 'line', array_values($dataset['totals']))
->backgroundColor(isset($dataset['backgroundColor']) ? $dataset['backgroundColor'] : '#6da252')
->color(isset($dataset['color']) ? $dataset['color'] : '#6da252')
->options((array) $dataset['options'])
->fill(false);
}
} else {
foreach ($this->footer_totals as $total) {
$chart->dataset($this->model->name, 'line', array_values($total))
->backgroundColor(isset($config['backgroundColor']) ? $config['backgroundColor'] : '#6da252')
->color(isset($config['color']) ? $config['color'] : '#6da252')
->options([
'borderWidth' => 4,
'pointStyle' => 'line',
])
->fill(false);
if (empty($this->chart)) {
return $chart;
}
$tmp_values = [];
if (! empty($this->row_values[$table_key])) {
foreach ($this->row_values[$table_key] as $id => $dates) {
$tmp_values[$id] = 0;
foreach ($dates as $date) {
$tmp_values[$id] += $date;
}
}
}
$tmp_values = collect($tmp_values)->sort()->reverse()->take(10)->all();
$total = array_sum($tmp_values);
$total = !empty($total) ? $total : 1;
$group = $this->getSetting('group');
$labels = $colors = $values = [];
foreach ($tmp_values as $id => $value) {
$labels[$id] = $this->row_names[$table_key][$id];
$colors[$id] = ($group == 'category') ? Category::find($id)?->color : '#' . dechex(rand(0x000000, 0xFFFFFF));
$values[$id] = round(($value * 100 / $total), 0);
}
$options = !empty($this->chart[$table_key]) ? $this->chart[$table_key]['donut'] : $this->chart['donut'];
$chart->setType('donut')
->setOptions($options)
->setLabels(array_values($labels))
->setColors(array_values($colors))
->setDataset($this->tables[$table_key], 'donut', array_values($values));
return $chart;
}
@ -208,7 +252,7 @@ abstract class Report
public function export()
{
return ExportHelper::toExcel(new Export($this->views['content'], $this), $this->model->name);
return ExportHelper::toExcel(new Export($this->views[$this->type], $this), $this->model->name);
}
public function setColumnWidth()
@ -221,10 +265,10 @@ abstract class Report
switch ($period) {
case 'quarterly':
$width = 'col-sm-2';
$width = 'w-2/12 col-2';
break;
case 'yearly':
$width = 'col-sm-4';
$width = 'w-4/12 col-4';
break;
}
@ -243,31 +287,41 @@ abstract class Report
public function setViews()
{
$this->views = [
'chart' => 'partials.reports.chart',
'content' => 'partials.reports.content',
'content.header' => 'partials.reports.content.header',
'content.footer' => 'partials.reports.content.footer',
'show' => 'partials.reports.show',
'header' => 'partials.reports.header',
'filter' => 'partials.reports.filter',
'print' => 'partials.reports.print',
'table' => 'partials.reports.table',
'table.footer' => 'partials.reports.table.footer',
'table.header' => 'partials.reports.table.header',
'table.rows' => 'partials.reports.table.rows',
'show' => 'components.reports.show',
'print' => 'components.reports.print',
'filter' => 'components.reports.filter',
'detail' => 'components.reports.detail',
'detail.content.header' => 'components.reports.detail.content.header',
'detail.content.footer' => 'components.reports.detail.content.footer',
'detail.table' => 'components.reports.detail.table',
'detail.table.header' => 'components.reports.detail.table.header',
'detail.table.body' => 'components.reports.detail.table.body',
'detail.table.row' => 'components.reports.detail.table.row',
'detail.table.footer' => 'components.reports.detail.table.footer',
'summary' => 'components.reports.summary',
'summary.content.header' => 'components.reports.summary.content.header',
'summary.content.footer' => 'components.reports.summary.content.footer',
'summary.table' => 'components.reports.summary.table',
'summary.table.header' => 'components.reports.summary.table.header',
'summary.table.body' => 'components.reports.summary.table.body',
'summary.table.row' => 'components.reports.summary.table.row',
'summary.table.footer' => 'components.reports.summary.table.footer',
'summary.chart' => 'components.reports.summary.chart',
];
}
public function setTables()
{
$this->tables = [
'default' => 'default',
'default' => trans_choice('general.totals', 1),
];
}
public function setDates()
{
if (!$period = $this->getSetting('period')) {
if (! $period = $this->getSetting('period')) {
return;
}
@ -299,8 +353,8 @@ abstract class Report
$this->dates[] = $date;
foreach ($this->tables as $table) {
$this->footer_totals[$table][$date] = 0;
foreach ($this->tables as $table_key => $table_name) {
$this->footer_totals[$table_key][$date] = 0;
}
}
}
@ -498,13 +552,17 @@ abstract class Report
return $this->model->settings->$name ?? $default;
}
public function getBasis()
{
return $this->getSearchStringValue('basis', $this->getSetting('basis'));
}
public function getFields()
{
return [
$this->getGroupField(),
$this->getPeriodField(),
$this->getBasisField(),
$this->getChartField(),
];
}
@ -513,7 +571,7 @@ abstract class Report
$this->setGroups();
return [
'type' => 'selectGroup',
'type' => 'select',
'name' => 'group',
'title' => trans('general.group_by'),
'icon' => 'folder',
@ -528,7 +586,7 @@ abstract class Report
public function getPeriodField()
{
return [
'type' => 'selectGroup',
'type' => 'select',
'name' => 'period',
'title' => trans('general.period'),
'icon' => 'calendar',
@ -547,7 +605,7 @@ abstract class Report
public function getBasisField()
{
return [
'type' => 'selectGroup',
'type' => 'select',
'name' => 'basis',
'title' => trans('general.basis'),
'icon' => 'file',
@ -561,22 +619,4 @@ abstract class Report
],
];
}
public function getChartField()
{
return [
'type' => 'selectGroup',
'name' => 'chart',
'title' => trans_choice('general.charts', 1),
'icon' => 'chart-pie',
'values' => [
'0' => trans('general.disabled'),
'line' => trans('reports.charts.line'),
],
'selected' => '0',
'attributes' => [
'required' => 'required',
],
];
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace App\Abstracts\View;
use Illuminate\View\Component as BaseComponent;
abstract class Component extends BaseComponent
{
public function getParentData($key, $default = null)
{
return app('view')->getConsumableComponentData($key, $default);
}
}

View File

@ -0,0 +1,503 @@
<?php
namespace App\Abstracts\View\Components\Contacts;
use App\Abstracts\View\Component;
use App\Traits\ViewComponents;
abstract class Form extends Component
{
use ViewComponents;
public const OBJECT_TYPE = 'contact';
public const DEFAULT_TYPE = 'customer';
public const DEFAULT_PLURAL_TYPE = 'customers';
/* -- Main Start -- */
public $type;
public $contact;
public $model;
/* -- Main End -- */
/* -- Content Start -- */
public $formId;
public $formRoute;
public $formMethod;
/** @var bool */
public $hideSectionGeneral;
/** @var bool */
public $hideSectionBilling;
/** @var bool */
public $hideSectionAddress;
/** @var string */
public $textSectionGeneralTitle;
/** @var string */
public $textSectionGeneralDescription;
/** @var bool */
public $hideName;
/** @var string */
public $textName;
/** @var string */
public $classNameFromGroupClass;
/** @var bool */
public $hideEmail;
/** @var string */
public $textEmail;
/** @var bool */
public $hidePhone;
/** @var string */
public $textPhone;
/** @var bool */
public $hideWebsite;
/** @var string */
public $textWebsite;
/** @var bool */
public $hideReference;
/** @var string */
public $textReference;
/** @var bool */
public $hideCanLogin;
/** @var bool */
public $hideLogo;
/** @var string */
public $textSectionBillingTitle;
/** @var string */
public $textSectionBillingDescription;
/** @var bool */
public $hideTaxNumber;
/** @var string */
public $textTaxNumber;
/** @var bool */
public $hideCurrency;
/** @var string */
public $textSectionAddressTitle;
/** @var string */
public $textSectionAddressDescription;
/** @var bool */
public $hideAddress;
/** @var string */
public $textAddress;
/** @var bool */
public $hideCity;
/** @var string */
public $textCity;
/** @var bool */
public $hideZipCode;
/** @var string */
public $textZipCode;
/** @var bool */
public $hideState;
/** @var string */
public $textState;
/** @var bool */
public $hideCountry;
/** @var string */
public $cancelRoute;
/* -- Content End -- */
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(
string $type, $model = false, $contact = false,
string $formId = 'contact', $formRoute = '', $formMethod = '',
bool $hideSectionGeneral = false, bool $hideSectionBilling = false, bool $hideSectionAddress = false,
string $textSectionGeneralTitle = '', string $textSectionGeneralDescription = '',
bool $hideName = false, string $textName = '', string $classNameFromGroupClass = '',
bool $hideEmail = false, string $textEmail = '',
bool $hidePhone = false, string $textPhone = '',
bool $hideWebsite = false, string $textWebsite = '',
bool $hideReference = false, string $textReference = '',
bool $hideCanLogin = false,
bool $hideLogo = false,
string $textSectionBillingTitle = '', string $textSectionBillingDescription = '',
bool $hideTaxNumber = false, string $textTaxNumber = '',
bool $hideCurrency = false,
string $textSectionAddressTitle = '', string $textSectionAddressDescription = '',
bool $hideAddress = false, string $textAddress = '',
bool $hideCity = false, string $textCity = '',
bool $hideZipCode = false, string $textZipCode = '',
bool $hideState = false, string $textState = '',
bool $hideCountry = false,
string $cancelRoute = ''
) {
$this->type = $type;
$this->model = ! empty($model) ? $model : $contact;
$this->contact = $this->model;
/* -- Content Start -- */
$this->formId = $formId;
$this->formRoute = $this->getFormRoute($type, $formRoute, $this->model);
$this->formMethod = $this->getFormMethod($type, $formMethod, $this->model);
$this->hideSectionGeneral = $hideSectionGeneral;
$this->hideSectionBilling = $hideSectionBilling;
$this->hideSectionAddress = $hideSectionAddress;
/* -- General Start -- */
$this->textSectionGeneralTitle = $this->getTextSectionGeneralTitle($type, $textSectionGeneralTitle);
$this->textSectionGeneralDescription = $this->getTextSectionGeneralDescription($type, $textSectionGeneralDescription);
$this->hideName = $hideName;
$this->textName = $this->getTextName($type, $textName);
$this->classNameFromGroupClass = $this->getClassNameFormGroupClass($type, $classNameFromGroupClass);
$this->hideEmail = $hideEmail;
$this->textEmail = $this->getTextEmail($type, $textEmail);
$this->hidePhone = $hidePhone;
$this->textPhone = $this->getTextPhone($type, $textPhone);
$this->hideWebsite = $hideWebsite;
$this->textWebsite = $this->getTextWebsite($type, $textWebsite);
$this->hideReference = $hideReference;
$this->textReference = $this->getTextReference($type, $textReference);
$this->hideCanLogin = $hideCanLogin;
$this->hideLogo = $hideLogo;
/* -- General End -- */
/* -- Billing Start -- */
$this->textSectionBillingTitle = $this->getTextSectionBillingTitle($type, $textSectionBillingTitle);
$this->textSectionBillingDescription = $this->getTextSectionBillingDescription($type, $textSectionBillingDescription);
$this->hideTaxNumber = $hideTaxNumber;
$this->textTaxNumber = $this->getTextTaxNumber($type, $textTaxNumber);
$this->hideCurrency = $hideCurrency;
/* -- Billing End -- */
/* -- Address Start -- */
$this->textSectionAddressTitle = $this->getTextSectionAddressTitle($type, $textSectionAddressTitle);
$this->textSectionAddressDescription = $this->getTextSectionAddressDescription($type, $textSectionAddressDescription);
$this->hideAddress = $hideAddress;
$this->textAddress = $this->getTextAddress($type, $textAddress);
$this->hideCity = $hideCity;
$this->textCity = $this->getTextCity($type, $textCity);
$this->hideZipCode = $hideZipCode;
$this->textZipCode = $this->getTextZipCode($type, $textZipCode);
$this->hideState = $hideState;
$this->textState = $this->getTextState($type, $textState);
$this->hideState = $hideTaxNumber;
/* -- Address End -- */
/* -- Buttons Start -- */
$this->cancelRoute = $this->getCancelRoute($type, $cancelRoute);
/* -- Buttons End -- */
/* -- Content End -- */
// Set Parent data
$this->setParentData();
}
/* -- Content Start -- */
/* -- General Start -- */
protected function getTextSectionGeneralTitle($type, $textSectionGeneralTitle)
{
if (! empty($textSectionGeneralTitle)) {
return $textSectionGeneralTitle;
}
$translation = $this->getTextFromConfig($type, 'section_general_title', 'general');
if (! empty($translation)) {
return $translation;
}
return 'general.general';
}
protected function getTextSectionGeneralDescription($type, $textSectionGeneralDescription)
{
if (! empty($textSectionGeneralDescription)) {
return $textSectionGeneralDescription;
}
$translation = $this->getTextFromConfig($type, 'section_general_description', 'form_description.general');
if (! empty($translation)) {
return $translation;
}
return 'customers.form_description.general';
}
protected function getTextName($type, $textName)
{
if (! empty($textName)) {
return $textName;
}
$translation = $this->getTextFromConfig($type, 'name', 'name');
if (! empty($translation)) {
return $translation;
}
return 'general.name';
}
protected function getClassNameFormGroupClass($type, $classNameFromGroupClass)
{
if (! empty($classNameFromGroupClass)) {
return $classNameFromGroupClass;
}
$class = $this->getClassFromConfig($type, 'name');
if (! empty($class)) {
return $class;
}
return 'sm:col-span-6';
}
protected function getTextEmail($type, $textEmail)
{
if (! empty($textEmail)) {
return $textEmail;
}
$translation = $this->getTextFromConfig($type, 'email', 'email');
if (! empty($translation)) {
return $translation;
}
return 'general.email';
}
protected function getTextPhone($type, $textPhone)
{
if (! empty($textPhone)) {
return $textPhone;
}
$translation = $this->getTextFromConfig($type, 'phone', 'phone');
if (! empty($translation)) {
return $translation;
}
return 'general.phone';
}
protected function getTextWebsite($type, $textWebsite)
{
if (! empty($textWebsite)) {
return $textWebsite;
}
$translation = $this->getTextFromConfig($type, 'website', 'website');
if (! empty($translation)) {
return $translation;
}
return 'general.website';
}
protected function getTextReference($type, $textReference)
{
if (! empty($textReference)) {
return $textReference;
}
$translation = $this->getTextFromConfig($type, 'reference', 'reference');
if (! empty($translation)) {
return $translation;
}
return 'general.reference';
}
/* -- General End -- */
/* -- Billing Start -- */
protected function getTextSectionBillingTitle($type, $textSectionBillingTitle)
{
if (! empty($textSectionBillingTitle)) {
return $textSectionBillingTitle;
}
$translation = $this->getTextFromConfig($type, 'section_billing_title');
if (! empty($translation)) {
return $translation;
}
return 'items.billing';
}
protected function getTextSectionBillingDescription($type, $textSectionBillingDescription)
{
if (! empty($textSectionBillingDescription)) {
return $textSectionBillingDescription;
}
$translation = $this->getTextFromConfig($type, 'section_billing_description');
if (! empty($translation)) {
return $translation;
}
return 'customers.form_description.billing';
}
protected function getTextTaxNumber($type, $textTaxNumber)
{
if (! empty($textTaxNumber)) {
return $textTaxNumber;
}
$translation = $this->getTextFromConfig($type, 'tax_number', 'tax_number');
if (! empty($translation)) {
return $translation;
}
return 'general.tax_number';
}
/* -- Billing End -- */
/* -- Address Start -- */
protected function getTextSectionAddressTitle($type, $textSectionAddressTitle)
{
if (! empty($textSectionAddressTitle)) {
return $textSectionAddressTitle;
}
$translation = $this->getTextFromConfig($type, 'section_address_title', 'address');
if (! empty($translation)) {
return $translation;
}
return 'general.address';
}
protected function getTextSectionAddressDescription($type, $textSectionAddressDescription)
{
if (! empty($textSectionAddressDescription)) {
return $textSectionAddressDescription;
}
$translation = $this->getTextFromConfig($type, 'section_address_description');
if (! empty($translation)) {
return $translation;
}
return 'customers.form_description.address';
}
protected function getTextAddress($type, $textAddress)
{
if (! empty($textAddress)) {
return $textAddress;
}
$translation = $this->getTextFromConfig($type, 'address', 'address');
if (! empty($translation)) {
return $translation;
}
return 'general.address';
}
protected function getTextCity($type, $textCity)
{
if (! empty($textCity)) {
return $textCity;
}
$translation = $this->getTextFromConfig($type, 'city', 'cities');
if (! empty($translation)) {
return $translation;
}
return 'general.cities';
}
protected function getTextZipCode($type, $textZipCode)
{
if (! empty($textZipCode)) {
return $textZipCode;
}
$translation = $this->getTextFromConfig($type, 'zip_code', 'zip_code');
if (! empty($translation)) {
return $translation;
}
return 'general.zip_code';
}
protected function getTextState($type, $textState)
{
if (! empty($textState)) {
return $textState;
}
$translation = $this->getTextFromConfig($type, 'state', 'state');
if (! empty($translation)) {
return $translation;
}
return 'general.state';
}
/* -- Address End -- */
/* -- Content End -- */
}

View File

@ -0,0 +1,492 @@
<?php
namespace App\Abstracts\View\Components\Contacts;
use App\Abstracts\View\Component;
use App\Traits\Documents;
use App\Traits\ViewComponents;
abstract class Index extends Component
{
use Documents, ViewComponents;
public const OBJECT_TYPE = 'contact';
public const DEFAULT_TYPE = 'customer';
public const DEFAULT_PLURAL_TYPE = 'customers';
/* -- Main Start -- */
/** @var string */
public $type;
public $contacts;
/** @var string */
public $textPage;
/** @var string */
public $group;
/** @var string */
public $page;
public $permissionCreate;
/* -- Main End -- */
/* -- Buttons Start -- */
public $checkPermissionCreate;
/** @var bool */
public $hideCreate;
/** @var bool */
public $hideImport;
/** @var bool */
public $hideExport;
/** @var string */
public $createRoute;
/** @var string */
public $importRoute;
/** @var array */
public $importRouteParameters;
/** @var string */
public $exportRoute;
/* -- Buttons End -- */
/* -- Content Start -- */
/** @var bool */
public $hideEmptyPage;
/** @var bool */
public $hideSummary;
public $summaryItems;
/** @var bool */
public $hideSearchString;
/** @var bool */
public $hideBulkAction;
/** @var string */
public $searchStringModel;
/** @var string */
public $bulkActionClass;
/** @var array */
public $bulkActionRouteParameters;
/** @var string */
public $searchRoute;
/** @var string */
public $classBulkAction;
/** @var bool */
public $showPicture;
/** @var bool */
public $hideName;
/** @var bool */
public $hideTaxNumber;
/** @var string */
public $classNameAndTaxNumber;
/** @var string */
public $textName;
/** @var string */
public $textTaxNumber;
/** @var bool */
public $hideEmail;
/** @var bool */
public $hidePhone;
/** @var string */
public $classEmailAndPhone;
/** @var string */
public $textEmail;
/** @var string */
public $textPhone;
/** @var bool */
public $hideCountry;
/** @var bool */
public $hideCurrencyCode;
/** @var string */
public $classCountryAndCurrencyCode;
/** @var string */
public $textCountry;
/** @var string */
public $textCurrencyCode;
/** @var bool */
public $hideOpen;
/** @var bool */
public $hideOverdue;
/** @var string */
public $classOpenAndOverdue;
/** @var string */
public $textOpen;
/** @var string */
public $textOverdue;
/* -- Content End -- */
/* -- Empty Start -- */
/** @var string */
public $imageEmptyPage;
/** @var string */
public $textEmptyPage;
/** @var string */
public $urlDocsPath;
/** @var string */
public $routeButtonShow;
/* -- Empty End -- */
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(
string $type, $contacts = [], string $textPage = '', string $group = '', string $page = '',
string $permissionCreate = '', string $permissionUpdate = '', string $permissionDelete = '',
bool $checkPermissionCreate = true,
bool $hideCreate = false, bool $hideImport = false, bool $hideExport = false,
string $createRoute = '', string $importRoute = '', array $importRouteParameters = [], string $exportRoute = '',
bool $hideEmptyPage = false, bool $hideSummary = false, $summaryItems = [], bool $hideSearchString = false, bool $hideBulkAction = false,
string $searchStringModel = '', string $bulkActionClass = '', array $bulkActions = [], array $bulkActionRouteParameters = [], string $searchRoute = '',
string $classBulkAction = '',
bool $showPicture = false, bool $hideName = false, bool $hideTaxNumber = false, string $classNameAndTaxNumber = '', string $textName = '', string $textTaxNumber = '',
bool $hideEmail = false, bool $hidePhone = false, string $classEmailAndPhone = '', string $textEmail = '', string $textPhone = '',
bool $hideCountry = false, bool $hideCurrencyCode = false, string $classCountryAndCurrencyCode = '', string $textCountry = '', string $textCurrencyCode = '',
bool $hideOpen = false, bool $hideOverdue = false, string $classOpenAndOverdue = '', string $textOpen = '', string $textOverdue = '',
string $imageEmptyPage = '', string $textEmptyPage = '', string $urlDocsPath = '', string $routeButtonShow = '',
) {
/* -- Main Start -- */
$this->type = $type;
$this->group = $this->getGroup($type, $group);
$this->page = $this->getPage($type, $page);
$this->contacts = ($contacts) ? $contacts : collect();
$this->textPage = $this->getTextPage($type, $textPage);
$this->permissionCreate = $this->getPermissionCreate($type, $permissionCreate);
$this->permissionUpdate = $this->getPermissionUpdate($type, $permissionUpdate);
$this->permissionDelete = $this->getPermissionDelete($type, $permissionDelete);
/* -- Main End -- */
/* -- Buttons Start -- */
$this->checkPermissionCreate = $checkPermissionCreate;
$this->hideCreate = $hideCreate;
$this->hideImport = $hideImport;
$this->hideExport = $hideExport;
$this->routeButtonShow = $this->getRouteButtonShow($type, $routeButtonShow);
$this->createRoute = $this->getCreateRoute($type, $createRoute);
$this->importRoute = $this->getImportRoute($importRoute);
$this->importRouteParameters = $this->getImportRouteParameters($type, $importRouteParameters);
$this->exportRoute = $this->getExportRoute($type, $exportRoute);
/* -- Buttons End -- */
/* -- Content Start -- */
$this->hideEmptyPage = $hideEmptyPage;
$this->hideSummary = $hideSummary;
$this->summaryItems = $this->getSummaryItems($type, $summaryItems);
$this->hideSearchString = $hideSearchString;
$this->hideBulkAction = $hideBulkAction;
$this->searchStringModel = $this->getSearchStringModel($type, $searchStringModel);
$this->bulkActionClass = $this->getBulkActionClass($type, $bulkActionClass);
$this->bulkActionRouteParameters = $this->getBulkActionRouteParameters($type, $bulkActionRouteParameters);
$this->searchRoute = $this->getIndexRoute($type, $searchRoute);
$this->classBulkAction = $this->getClassBulkAction($type, $classBulkAction);
$this->showPicture = $showPicture;
$this->hideName = $hideName;
$this->hideTaxNumber = $hideTaxNumber;
$this->classNameAndTaxNumber = $this->getClassNameAndTaxNumber($type, $classNameAndTaxNumber);
$this->textName = $this->getTextName($type, $textName);
$this->textTaxNumber = $this->getTextTaxNumber($type, $textTaxNumber);
$this->hideEmail = $hideEmail;
$this->hidePhone = $hidePhone;
$this->classEmailAndPhone = $this->getClassEmailAndPhone($type, $classEmailAndPhone);
$this->textEmail = $this->getTextEmail($type, $textEmail);
$this->textPhone = $this->getTextPhone($type, $textPhone);
$this->hideCountry = $hideCountry;
$this->hideCurrencyCode = $hideCurrencyCode;
$this->classCountryAndCurrencyCode = $this->getClassCountryAndCurrencyCode($type, $classCountryAndCurrencyCode);
$this->textCountry = $this->getTextCountry($type, $textCountry);
$this->textCurrencyCode = $this->getTextCurrencyCode($type, $textCurrencyCode);
$this->hideOpen = $hideOpen;
$this->hideOverdue = $hideOverdue;
$this->classOpenAndOverdue = $this->getClassOpenAndOverdue($type, $classOpenAndOverdue);
$this->textOpen = $this->getTextOpen($type, $textOpen);
$this->textOverdue = $this->getTextOverdue($type, $textOverdue);
/* -- Content End -- */
/* -- Empty Start -- */
$this->imageEmptyPage = $this->getImageEmptyPage($type, $imageEmptyPage);
$this->textEmptyPage = $this->getTextEmptyPage($type, $textEmptyPage);
$this->urlDocsPath = $this->getUrlDocsPath($type, $urlDocsPath);
/* -- Empty End -- */
// Set Parent data
$this->setParentData();
}
public function getSummaryItems($type, $summaryItems)
{
if (! empty($summaryItems)) {
return $summaryItems;
}
$route = $this->getIndexRoute($type, null);
$document_type = config('type.contact.' . $type . '.document_type', 'invoice');
$totals = $this->getTotalsForFutureDocuments($document_type);
$items = [];
foreach ($totals as $key => $total) {
$items[] = [
'title' => ($key == 'overdue') ? trans('general.overdue') : trans('documents.statuses.' . $key),
'href' => route($route, ['search' => 'status:' . $key]),
'amount' => money($total, setting('default.currency'), true),
];
}
return $items;
}
/* -- Content Start -- */
protected function getClassNameAndTaxNumber($type, $classNameAndTaxNumber)
{
if (! empty($classNameAndTaxNumber)) {
return $classNameAndTaxNumber;
}
$class = $this->getClassFromConfig($type, 'name_and_tax_number');
if (! empty($class)) {
return $class;
}
return 'w-6/12 sm:w-3/12 truncate';
}
protected function getTextName($type, $textName)
{
if (! empty($textName)) {
return $textName;
}
$translation = $this->getTextFromConfig($type, 'name', 'name');
if (! empty($translation)) {
return $translation;
}
return 'general.name';
}
protected function getTextTaxNumber($type, $textTaxNumber)
{
if (! empty($textTaxNumber)) {
return $textTaxNumber;
}
$translation = $this->getTextFromConfig($type, 'tax_number', 'tax_number');
if (! empty($translation)) {
return $translation;
}
return 'general.tax_number';
}
protected function getClassEmailAndPhone($type, $classEmailAndPhone)
{
if (! empty($classEmailAndPhone)) {
return $classEmailAndPhone;
}
$class = $this->getClassFromConfig($type, 'email_and_phone');
if (! empty($class)) {
return $class;
}
return 'w-3/12 hidden sm:table-cell';
}
protected function getTextEmail($type, $textEmail)
{
if (! empty($textEmail)) {
return $textEmail;
}
$translation = $this->getTextFromConfig($type, 'email', 'email');
if (! empty($translation)) {
return $translation;
}
return 'general.email';
}
protected function getTextPhone($type, $textPhone)
{
if (! empty($textPhone)) {
return $textPhone;
}
$translation = $this->getTextFromConfig($type, 'phone', 'phone');
if (! empty($translation)) {
return $translation;
}
return 'general.phone';
}
protected function getClassCountryAndCurrencyCode($type, $classCountryAndCurrencyCode)
{
if (! empty($classCountryAndCurrencyCode)) {
return $classCountryAndCurrencyCode;
}
$class = $this->getClassFromConfig($type, 'country_and_currency_code');
if (! empty($class)) {
return $class;
}
return 'w-3/12 hidden sm:table-cell';
}
protected function getTextCountry($type, $textCountry)
{
if (! empty($textCountry)) {
return $textCountry;
}
$translation = $this->getTextFromConfig($type, 'country', 'countries');
if (! empty($translation)) {
return $translation;
}
return 'general.countries';
}
protected function getTextCurrencyCode($type, $textCurrencyCode)
{
if (! empty($textCurrencyCode)) {
return $textCurrencyCode;
}
$translation = $this->getTextFromConfig($type, 'currency_code', 'currencies');
if (! empty($translation)) {
return $translation;
}
return 'general.currencies';
}
protected function getClassOpenAndOverdue($type, $classOpenAndOverdue)
{
if (! empty($classOpenAndOverdue)) {
return $classOpenAndOverdue;
}
$class = $this->getClassFromConfig($type, 'open_and_overdue');
if (! empty($class)) {
return $class;
}
return 'w-6/12 sm:w-3/12';
}
protected function getTextOpen($type, $textOpen)
{
if (! empty($textOpen)) {
return $textOpen;
}
$translation = $this->getTextFromConfig($type, 'open', 'open');
if (! empty($translation)) {
return $translation;
}
return 'general.open';
}
protected function getTextOverdue($type, $textOverdue)
{
if (! empty($textOverdue)) {
return $textOverdue;
}
$translation = $this->getTextFromConfig($type, 'overdue', 'overdue');
if (! empty($translation)) {
return $translation;
}
return 'general.overdue';
}
protected function getRouteButtonShow($type, $routeButtonShow)
{
if (!empty($routeButtonShow)) {
return $routeButtonShow;
}
//example route parameter.
$parameter = 1;
$route = $this->getRouteFromConfig($type, 'show', $parameter);
if (!empty($route)) {
return $route;
}
return 'customer.show';
}
/* -- Content End -- */
}

View File

@ -0,0 +1,316 @@
<?php
namespace App\Abstracts\View\Components\Contacts;
use App\Abstracts\View\Component;
use App\Traits\ViewComponents;
abstract class Show extends Component
{
use ViewComponents;
public const OBJECT_TYPE = 'contact';
public const DEFAULT_TYPE = 'customer';
public const DEFAULT_PLURAL_TYPE = 'customers';
/* -- Main Start -- */
public $type;
public $contact;
public $model;
public $permissionCreate;
public $permissionUpdate;
public $permissionDelete;
/* -- Main End -- */
/* -- Buttons Start -- */
public $hideNewDropdown;
public $hideButtonDocument;
public $hideButtonTransaction;
public $permissionCreateDocument;
public $permissionCreateTransaction;
public $routeButtonDocument;
public $routeButtonTransaction;
public $textDocument;
public $textTransaction;
public $hideButtonEdit;
public $routeButtonEdit;
public $hideActionsDropdown;
public $hideButtonDuplicate;
public $routeButtonDuplicate;
public $hideButtonDelete;
public $routeButtonDelete;
public $textDeleteModal;
/* -- Buttons End -- */
/* -- Profile Start -- */
public $hideTopLeft;
public $hideAvatar;
public $hideEmail;
public $hidePhone;
public $hideTopRight;
public $hideOverdue;
public $hideOpen;
public $hidePaid;
public $hideBottomLeft;
public $hideAddress;
public $hideTaxNumber;
public $hideWebsite;
public $hideReference;
public $hideUser;
public $hideBottomRight;
/* -- Profile End -- */
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(
string $type, $model = false, $contact = false,
string $permissionCreate = '', string $permissionUpdate = '', string $permissionDelete = '',
bool $hideNewDropdown = false, bool $hideButtonDocument = false, $hideButtonTransaction = false,
string $permissionCreateDocument = '', string $permissionCreateTransaction = '',
$routeButtonDocument = '', $routeButtonTransaction = '',
string $textDocument = '', string $textTransaction = '',
bool $hideButtonEdit = false, $routeButtonEdit = '',
bool $hideActionsDropdown = false, bool $hideButtonDuplicate = false, $routeButtonDuplicate = '',
bool $hideButtonDelete = false, $routeButtonDelete = '', $textDeleteModal = '',
bool $hideTopLeft = false, bool $hideAvatar = false, bool $hideEmail = false, bool $hidePhone = false,
bool $hideTopRight = false, bool $hideOverdue = false, bool $hideOpen = false, bool $hidePaid = false,
bool $hideBottomLeft = false, bool $hideAddress = false, bool $hideTaxNumber = false , bool $hideWebsite = false, bool $hideReference = false, bool $hideUser = false,
bool $hideBottomRight = false
) {
/* -- Main Start -- */
$this->type = $type;
$this->model = ! empty($model) ? $model : $contact;
$this->contact = $this->model;
$this->permissionCreate = $this->getPermissionCreate($type, $permissionCreate);
$this->permissionUpdate = $this->getPermissionUpdate($type, $permissionUpdate);
$this->permissionDelete = $this->getPermissionDelete($type, $permissionDelete);
/* -- Main End -- */
/* -- Buttons Start -- */
$this->hideNewDropdown = $hideNewDropdown;
$this->hideButtonDocument = $hideButtonDocument;
$this->hideButtonTransaction = $hideButtonTransaction;
$this->permissionCreateDocument = $this->getPermissionCreateDocument($type, $permissionCreateDocument);
$this->permissionCreateTransaction = $this->getPermissionCreateTransaction($type, $permissionCreateTransaction);
$this->routeButtonDocument = $this->getCreateDocumentRoute($type, $routeButtonDocument);
$this->routeButtonTransaction = $this->getCreateTransactionRoute($type, $routeButtonTransaction);
$this->textDocument = $this->getTextDocument($type, $textDocument);
$this->textTransaction = $this->getTextTransaction($type, $textTransaction);
$this->hideButtonEdit = $hideButtonEdit;
$this->routeButtonEdit = $this->getEditRoute($type, $routeButtonEdit);
$this->hideActionsDropdown = $hideActionsDropdown;
$this->hideButtonDuplicate = $hideButtonDuplicate;
$this->routeButtonDuplicate = $this->getDuplicateRoute($type, $routeButtonDuplicate);
$this->hideButtonDelete = $hideButtonDelete;
$this->routeButtonDelete = $this->getDeleteRoute($type, $routeButtonDelete);
$this->textDeleteModal = $this->getTextDeleteModal($type, $textDeleteModal);
/* -- Buttons End -- */
/* -- Profile Start -- */
$this->hideProfile = $hideTopLeft;
$this->hideAvatar = $hideAvatar;
$this->hideEmail = $hideEmail;
$this->hidePhone = $hidePhone;
$this->hideDetails = $hideTopRight;
$this->hideOverdue = $hideOverdue;
$this->hideOpen = $hideOpen;
$this->hidePaid = $hidePaid;
$this->hideSummary = $hideBottomLeft;
$this->hideAddress = $hideAddress;
$this->hideTaxNumber = $hideTaxNumber;
$this->hideWebsite = $hideWebsite;
$this->hideReference = $hideReference;
$this->hideUser = $hideUser;
$this->hideContent = $hideBottomRight;
/* -- Profile End -- */
}
protected function getPermissionCreateDocument($type, $permissionCreateDocument)
{
if (! empty($permissionCreateDocument)) {
return $permissionCreateDocument;
}
$document_type = config('type.contact.' . $type . '.document_type', 'invoice');
$permission = '';
$config_key = 'create';
// if set config trasnlation config_key
if ($permission = config('type.document.' . $document_type . '.permission.' . $config_key)) {
return $permission;
}
$alias = config('type.document.' . $document_type . '.alias');
$group = config('type.document.' . $document_type . '.group');
$prefix = config('type.document.' . $document_type . '.permission.prefix');
$permission = $config_key . '-';
// if use module set module alias
if (! empty($alias)) {
$permission .= $alias . '-';
}
// if controller in folder it must
if (! empty($group)) {
$permission .= $group . '-';
}
$permission .= $prefix;
$permissionCreateDocument = $permission;
return $permissionCreateDocument;
}
protected function getPermissionCreateTransaction($type, $permissionCreateTransaction)
{
if (! empty($permissionCreateTransaction)) {
return $permissionCreateTransaction;
}
$permissionCreateTransaction = 'create-banking-transactions';
return $permissionCreateTransaction;
}
protected function getCreateDocumentRoute($type, $routeButtonDocument)
{
if (! empty($routeButtonDocument)) {
return $routeButtonDocument;
}
$prefix = config('type.contact.' . $type . '.route.prefix');
$document_type = config('type.contact.' . $type . '.document_type');
return $prefix . '.create-' . $document_type;
}
protected function getCreateTransactionRoute($type, $routeButtonDocument)
{
if (! empty($routeButtonDocument)) {
return $routeButtonDocument;
}
$prefix = config('type.contact.' . $type . '.route.prefix');
$transaction_type = config('type.contact.' . $type . '.transaction_type');
return $prefix . '.create-' . $transaction_type;
}
protected function getTextDocument($type, $textDocument)
{
if (! empty($textDocument)) {
return $textDocument;
}
$document_type = config('type.contact.' . $type . '.document_type');
switch ($document_type) {
case 'invoice':
$text = 'general.invoices';
break;
case 'bill':
$text = 'general.bills';
break;
default:
$text = config('type.contact.' . $type . '.translation.prefix') . '.' . config('type.contact.' . $type . '.route.prefix');
}
return $text;
}
protected function getTextTransaction($type, $textTransaction)
{
if (! empty($textTransaction)) {
return $textTransaction;
}
$document_type = config('type.contact.' . $type . '.document_type');
switch ($document_type) {
case 'invoice':
$text = 'general.incomes';
break;
case 'bill':
$text = 'general.expenses';
break;
default:
$text = config('type.contact.' . $type . '.translation.prefix') . '.' . config('type.contact.' . $type . '.transaction_type') . 's';
}
return $text;
}
protected function getTextDeleteModal($type, $textDeleteModal)
{
if (! empty($textDeleteModal)) {
return $textDeleteModal;
}
$document_type = config('type.contact.' . $type . '.document_type');
switch ($document_type) {
case 'invoice':
$text = 'general.incomes';
break;
case 'bill':
$text = 'general.expenses';
break;
default:
$text = config('type.contact.' . $type . '.translation.prefix') . '.' . config('type.contact.' . $type . '.transaction_type') . 's';
}
return $text;
}
}

View File

@ -1,175 +0,0 @@
<?php
namespace App\Abstracts\View\Components;
use Illuminate\View\Component;
use Illuminate\Support\Str;
abstract class Document extends Component
{
public function getTextFromConfig($type, $config_key, $default_key = '', $trans_type = 'trans')
{
$translation = '';
// if set config translation config_key
if ($translation = config('type.' . $type . '.translation.' . $config_key)) {
return $translation;
}
$alias = config('type.' . $type . '.alias');
$prefix = config('type.' . $type . '.translation.prefix');
if (!empty($alias)) {
$alias .= '::';
}
// This magic trans key..
$translations = [
'general' => $alias . 'general.' . $default_key,
'prefix' => $alias . $prefix . '.' . $default_key,
'config_general' => $alias . 'general.' . $config_key,
'config_prefix' => $alias . $prefix . '.' . $config_key,
];
switch ($trans_type) {
case 'trans':
foreach ($translations as $trans) {
if (trans($trans) !== $trans) {
return $trans;
}
}
break;
case 'trans_choice':
foreach ($translations as $trans_choice) {
if (trans_choice($trans_choice, 1) !== $trans_choice) {
return $trans_choice;
}
}
break;
}
return $translation;
}
public function getRouteFromConfig($type, $config_key, $config_parameters = [])
{
$route = '';
// if set config trasnlation config_key
if ($route = config('type.' . $type . '.route.' . $config_key)) {
return $route;
}
$alias = config('type.' . $type . '.alias');
$prefix = config('type.' . $type . '.route.prefix');
// if use module set module alias
if (!empty($alias)) {
$route .= $alias . '.';
}
if (!empty($prefix)) {
$route .= $prefix . '.';
}
$route .= $config_key;
try {
route($route, $config_parameters);
} catch (\Exception $e) {
try {
$route = Str::plural($type, 2) . '.' . $config_key;
route($route, $config_parameters);
} catch (\Exception $e) {
$route = '';
}
}
return $route;
}
public function getPermissionFromConfig($type, $config_key)
{
$permission = '';
// if set config trasnlation config_key
if ($permission = config('type.' . $type . '.permission.' . $config_key)) {
return $permission;
}
$alias = config('type.' . $type . '.alias');
$group = config('type.' . $type . '.group');
$prefix = config('type.' . $type . '.permission.prefix');
$permission = $config_key . '-';
// if use module set module alias
if (!empty($alias)) {
$permission .= $alias . '-';
}
// if controller in folder it must
if (!empty($group)) {
$permission .= $group . '-';
}
$permission .= $prefix;
return $permission;
}
public function getHideFromConfig($type, $config_key)
{
$hide = false;
$hides = config('type.' . $type . '.hide');
if (!empty($hides) && (in_array($config_key, $hides))) {
$hide = true;
}
return $hide;
}
public function getClassFromConfig($type, $config_key)
{
$class_key = 'type.' . $type . '.class.' . $config_key;
return config($class_key, '');
}
public function getCategoryFromConfig($type)
{
$category_type = '';
// if set config trasnlation config_key
if ($category_type = config('type.' . $type . '.category_type')) {
return $category_type;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$category_type = 'expense';
break;
case 'item':
$category_type = 'item';
break;
case 'other':
$category_type = 'other';
break;
case 'transfer':
$category_type = 'transfer';
break;
default:
$category_type = 'income';
break;
}
return $category_type;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,666 +0,0 @@
<?php
namespace App\Abstracts\View\Components;
use App\Abstracts\View\Components\Document as Base;
use App\Models\Common\Media;
use App\Traits\DateTime;
use App\Traits\Documents;
use File;
use Illuminate\Support\Facades\Log;
use Image;
use Intervention\Image\Exception\NotReadableException;
use Storage;
use Illuminate\Support\Str;
abstract class DocumentTemplate extends Base
{
use DateTime;
use Documents;
public $type;
public $item;
public $document;
/** @var string */
public $documentTemplate;
public $date_format;
public $logo;
public $backgroundColor;
public $hideFooter;
public $hideCompanyLogo;
public $hideCompanyDetails;
public $hideCompanyName;
public $hideCompanyAddress;
public $hideCompanyTaxNumber;
public $hideCompanyPhone;
public $hideCompanyEmail;
public $hideContactInfo;
public $hideContactName;
public $hideContactAddress;
public $hideContactTaxNumber;
public $hideContactPhone;
public $hideContactEmail;
public $hideOrderNumber;
public $hideDocumentNumber;
public $hideIssuedAt;
public $hideDueAt;
/** @var string */
public $textDocumentTitle;
/** @var string */
public $textDocumentSubheading;
public $textContactInfo;
/** @var string */
public $textIssuedAt;
/** @var string */
public $textDueAt;
/** @var string */
public $textDocumentNumber;
/** @var string */
public $textOrderNumber;
public $hideItems;
public $hideName;
public $hideDescription;
public $hideQuantity;
public $hidePrice;
public $hideDiscount;
public $hideAmount;
/** @var string */
public $textItems;
/** @var string */
public $textQuantity;
/** @var string */
public $textPrice;
/** @var string */
public $textAmount;
public $hideNote;
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(
$type, $document, $item = false, $documentTemplate = '', $logo = '', $backgroundColor = '',
bool $hideFooter = false, bool $hideCompanyLogo = false, bool $hideCompanyDetails = false,
bool $hideCompanyName = false, bool $hideCompanyAddress = false, bool $hideCompanyTaxNumber = false, bool $hideCompanyPhone = false, bool $hideCompanyEmail = false, bool $hideContactInfo = false,
bool $hideContactName = false, bool $hideContactAddress = false, bool $hideContactTaxNumber = false, bool $hideContactPhone = false, bool $hideContactEmail = false,
bool $hideOrderNumber = false, bool $hideDocumentNumber = false, bool $hideIssuedAt = false, bool $hideDueAt = false,
string $textDocumentTitle = '', string $textDocumentSubheading = '',
string $textContactInfo = '', string $textDocumentNumber = '', string $textOrderNumber = '', string $textIssuedAt = '', string $textDueAt = '',
bool $hideItems = false, bool $hideName = false, bool $hideDescription = false, bool $hideQuantity = false, bool $hidePrice = false, bool $hideDiscount = false, bool $hideAmount = false, bool $hideNote = false,
string $textItems = '', string $textQuantity = '', string $textPrice = '', string $textAmount = ''
) {
$this->type = $type;
$this->item = $item;
$this->document = $document;
$this->documentTemplate = $this->getDocumentTemplate($type, $documentTemplate);
$this->logo = $this->getLogo($logo);
$this->backgroundColor = $this->getBackgroundColor($type, $backgroundColor);
$this->hideFooter = $hideFooter;
$this->hideCompanyLogo = $hideCompanyLogo;
$this->hideCompanyDetails = $hideCompanyDetails;
$this->hideCompanyName = $hideCompanyName;
$this->hideCompanyAddress = $hideCompanyAddress;
$this->hideCompanyTaxNumber = $hideCompanyTaxNumber;
$this->hideCompanyPhone = $hideCompanyPhone;
$this->hideCompanyEmail = $hideCompanyEmail;
$this->hideContactInfo = $hideContactInfo;
$this->hideContactName = $hideContactName;
$this->hideContactAddress = $hideContactAddress;
$this->hideContactTaxNumber = $hideContactTaxNumber;
$this->hideContactPhone = $hideContactPhone;
$this->hideContactEmail = $hideContactEmail;
$this->hideOrderNumber = $hideOrderNumber;
$this->hideDocumentNumber = $hideDocumentNumber;
$this->hideIssuedAt = $hideIssuedAt;
$this->hideDueAt = $hideDueAt;
$this->textDocumentTitle = $this->getTextDocumentTitle($type, $textDocumentTitle);
$this->textDocumentSubheading = $this->gettextDocumentSubheading($type, $textDocumentSubheading);
$this->textContactInfo = $this->getTextContactInfo($type, $textContactInfo);
$this->textIssuedAt = $this->getTextIssuedAt($type, $textIssuedAt);
$this->textDocumentNumber = $this->getTextDocumentNumber($type, $textDocumentNumber);
$this->textDueAt = $this->getTextDueAt($type, $textDueAt);
$this->textOrderNumber = $this->getTextOrderNumber($type, $textOrderNumber);
$this->hideItems = $this->getHideItems($type, $hideItems, $hideName, $hideDescription);
$this->hideName = $this->getHideName($type, $hideName);
$this->hideDescription = $this->getHideDescription($type, $hideDescription);
$this->hideQuantity = $this->getHideQuantity($type, $hideQuantity);
$this->hidePrice = $this->getHidePrice($type, $hidePrice);
$this->hideDiscount = $this->getHideDiscount($type, $hideDiscount);
$this->hideAmount = $this->getHideAmount($type, $hideAmount);
$this->hideNote = $hideNote;
$this->textItems = $this->getTextItems($type, $textItems);
$this->textQuantity = $this->getTextQuantity($type, $textQuantity);
$this->textPrice = $this->getTextPrice($type, $textPrice);
$this->textAmount = $this->getTextAmount($type, $textAmount);
}
protected function getDocumentTemplate($type, $documentTemplate)
{
if (!empty($documentTemplate)) {
return $documentTemplate;
}
if ($template = config('type.' . $type . 'template', false)) {
return $template;
}
$documentTemplate = setting($this->getSettingKey($type, 'template'), 'default');
return $documentTemplate;
}
protected function getLogo($logo)
{
if (!empty($logo)) {
return $logo;
}
$media_id = (!empty($this->document->contact->logo) && !empty($this->document->contact->logo->id)) ? $this->document->contact->logo->id : setting('company.logo');
$media = Media::find($media_id);
if (!empty($media)) {
$path = $media->getDiskPath();
if (Storage::missing($path)) {
return $logo;
}
} else {
$path = base_path('public/img/company.png');
}
try {
$image = Image::cache(function($image) use ($media, $path) {
$width = setting('invoice.logo_size_width');
$height = setting('invoice.logo_size_height');
if ($media) {
$image->make(Storage::get($path))->resize($width, $height)->encode();
} else {
$image->make($path)->resize($width, $height)->encode();
}
});
} catch (NotReadableException | \Exception $e) {
Log::info('Company ID: ' . company_id() . ' components/documentshow.php exception.');
Log::info($e->getMessage());
$path = base_path('public/img/company.png');
$image = Image::cache(function($image) use ($path) {
$width = setting('invoice.logo_size_width');
$height = setting('invoice.logo_size_height');
$image->make($path)->resize($width, $height)->encode();
});
}
if (empty($image)) {
return $logo;
}
$extension = File::extension($path);
return 'data:image/' . $extension . ';base64,' . base64_encode($image);
}
protected function getBackgroundColor($type, $backgroundColor)
{
if (!empty($backgroundColor)) {
return $backgroundColor;
}
if ($background_color = config('type.' . $type . 'color', false)) {
return $background_color;
}
$backgroundColor = setting($this->getSettingKey($type, 'color'), '#55588b');
return $backgroundColor;
}
protected function getTextDocumentTitle($type, $textDocumentTitle)
{
if (!empty($textDocumentTitle)) {
return $textDocumentTitle;
}
$key = $this->getSettingKey($type, 'title');
if (!empty(setting($key))) {
return setting($key);
}
$translation = $this->getTextFromConfig($type, 'document_title', Str::plural($type));
if (!empty($translation)) {
return trans_choice($translation, 1);
}
return setting('invoice.title');
}
protected function getTextDocumentSubheading($type, $textDocumentSubheading)
{
if (!empty($textDocumentSubheading)) {
return $textDocumentSubheading;
}
$key = $this->getSettingKey($type, 'subheading');
if (!empty(setting($key))) {
return setting($key);
}
$translation = $this->getTextFromConfig($type, 'document_subheading', 'subheading');
if (!empty($translation)) {
return trans($translation);
}
return false;
}
protected function getTextDocumentNumber($type, $textDocumentNumber)
{
if (!empty($textDocumentNumber)) {
return $textDocumentNumber;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$default_key = 'bill_number';
break;
default:
$default_key = 'invoice_number';
break;
}
$translation = $this->getTextFromConfig($type, 'document_number', $default_key);
if (!empty($translation)) {
return $translation;
}
return 'general.numbers';
}
protected function getTextOrderNumber($type, $textOrderNumber)
{
if (!empty($textOrderNumber)) {
return $textOrderNumber;
}
$translation = $this->getTextFromConfig($type, 'order_number');
if (!empty($translation)) {
return $translation;
}
return 'invoices.order_number';
}
protected function getTextContactInfo($type, $textContactInfo)
{
if (!empty($textContactInfo)) {
return $textContactInfo;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$default_key = 'bill_from';
break;
default:
$default_key = 'bill_to';
break;
}
$translation = $this->getTextFromConfig($type, 'contact_info', $default_key);
if (!empty($translation)) {
return $translation;
}
return 'invoices.bill_to';
}
protected function getTextIssuedAt($type, $textIssuedAt)
{
if (!empty($textIssuedAt)) {
return $textIssuedAt;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$default_key = 'bill_date';
break;
default:
$default_key = 'invoice_date';
break;
}
$translation = $this->getTextFromConfig($type, 'issued_at', $default_key);
if (!empty($translation)) {
return $translation;
}
return 'invoices.invoice_date';
}
protected function getTextDueAt($type, $textDueAt)
{
if (!empty($textDueAt)) {
return $textDueAt;
}
$translation = $this->getTextFromConfig($type, 'due_at', 'due_date');
if (!empty($translation)) {
return $translation;
}
return 'invoices.due_date';
}
protected function getTextItems($type, $textItems)
{
if (!empty($textItems)) {
return $textItems;
}
// if you use settting translation
if (setting($this->getSettingKey($type, 'item_name'), 'items') === 'custom') {
if (empty($textItems = setting($this->getSettingKey($type, 'item_name_input')))) {
$textItems = 'general.items';
}
return $textItems;
}
if (setting($this->getSettingKey($type, 'item_name')) !== null &&
(trans(setting($this->getSettingKey($type, 'item_name'))) != setting($this->getSettingKey($type, 'item_name')))
) {
return setting($this->getSettingKey($type, 'item_name'));
}
$translation = $this->getTextFromConfig($type, 'items');
if (!empty($translation)) {
return $translation;
}
return 'general.items';
}
protected function getTextQuantity($type, $textQuantity)
{
if (!empty($textQuantity)) {
return $textQuantity;
}
// if you use settting translation
if (setting($this->getSettingKey($type, 'quantity_name'), 'quantity') === 'custom') {
if (empty($textQuantity = setting($this->getSettingKey($type, 'quantity_name_input')))) {
$textQuantity = 'invoices.quantity';
}
return $textQuantity;
}
if (setting($this->getSettingKey($type, 'quantity_name')) !== null &&
(trans(setting($this->getSettingKey($type, 'quantity_name'))) != setting($this->getSettingKey($type, 'quantity_name')))
) {
return setting($this->getSettingKey($type, 'quantity_name'));
}
$translation = $this->getTextFromConfig($type, 'quantity');
if (!empty($translation)) {
return $translation;
}
return 'invoices.quantity';
}
protected function getTextPrice($type, $textPrice)
{
if (!empty($textPrice)) {
return $textPrice;
}
// if you use settting translation
if (setting($this->getSettingKey($type, 'price_name'), 'price') === 'custom') {
if (empty($textPrice = setting($this->getSettingKey($type, 'price_name_input')))) {
$textPrice = 'invoices.price';
}
return $textPrice;
}
if (setting($this->getSettingKey($type, 'price_name')) !== null &&
(trans(setting($this->getSettingKey($type, 'price_name'))) != setting($this->getSettingKey($type, 'price_name')))
) {
return setting($this->getSettingKey($type, 'price_name'));
}
$translation = $this->getTextFromConfig($type, 'price');
if (!empty($translation)) {
return $translation;
}
return 'invoices.price';
}
protected function getTextAmount($type, $textAmount)
{
if (!empty($textAmount)) {
return $textAmount;
}
$translation = $this->getTextFromConfig($type, 'amount');
if (!empty($translation)) {
return $translation;
}
return 'general.amount';
}
protected function getHideItems($type, $hideItems, $hideName, $hideDescription)
{
if (!empty($hideItems)) {
return $hideItems;
}
$hide = $this->getHideFromConfig($type, 'items');
if ($hide) {
return $hide;
}
$hideItems = ($this->getHideName($type, $hideName) & $this->getHideDescription($type, $hideDescription)) ? true : false;
return $hideItems;
}
protected function getHideName($type, $hideName)
{
if (!empty($hideName)) {
return $hideName;
}
// if you use settting translation
if ($hideName = setting($this->getSettingKey($type, 'hide_item_name'), false)) {
return $hideName;
}
$hide = $this->getHideFromConfig($type, 'name');
if ($hide) {
return $hide;
}
// @todo what return value invoice or always false??
return setting('invoice.hide_item_name', $hideName);
}
protected function getHideDescription($type, $hideDescription)
{
if (!empty($hideDescription)) {
return $hideDescription;
}
// if you use settting translation
if ($hideDescription = setting($this->getSettingKey($type, 'hide_item_description'), false)) {
return $hideDescription;
}
$hide = $this->getHideFromConfig($type, 'description');
if ($hide) {
return $hide;
}
// @todo what return value invoice or always false??
return setting('invoice.hide_item_description', $hideDescription);
}
protected function getHideQuantity($type, $hideQuantity)
{
if (!empty($hideQuantity)) {
return $hideQuantity;
}
// if you use settting translation
if ($hideQuantity = setting($this->getSettingKey($type, 'hide_quantity'), false)) {
return $hideQuantity;
}
$hide = $this->getHideFromConfig($type, 'quantity');
if ($hide) {
return $hide;
}
// @todo what return value invoice or always false??
return setting('invoice.hide_quantity', $hideQuantity);
}
protected function getHidePrice($type, $hidePrice)
{
if (!empty($hidePrice)) {
return $hidePrice;
}
// if you use settting translation
if ($hidePrice = setting($this->getSettingKey($type, 'hide_price'), false)) {
return $hidePrice;
}
$hide = $this->getHideFromConfig($type, 'price');
if ($hide) {
return $hide;
}
// @todo what return value invoice or always false??
return setting('invoice.hide_price', $hidePrice);
}
protected function getHideDiscount($type, $hideDiscount)
{
if (!empty($hideDiscount)) {
return $hideDiscount;
}
// if you use settting translation
if ($hideDiscount = setting($this->getSettingKey($type, 'hide_discount'), false)) {
return $hideDiscount;
}
$hide = $this->getHideFromConfig($type, 'discount');
if ($hide) {
return $hide;
}
// @todo what return value invoice or always false??
return setting('invoice.hide_discount', $hideDiscount);
}
protected function getHideAmount($type, $hideAmount)
{
if (!empty($hideAmount)) {
return $hideAmount;
}
// if you use settting translation
if ($hideAmount = setting($this->getSettingKey($type, 'hide_amount'), false)) {
return $hideAmount;
}
$hide = $this->getHideFromConfig($type, 'amount');
if ($hide) {
return $hide;
}
// @todo what return value invoice or always false??
return setting('invoice.hide_amount', $hideAmount);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,642 @@
<?php
namespace App\Abstracts\View\Components\Documents;
use Akaunting\Module\Module;
use App\Abstracts\View\Component;
use App\Events\Common\BulkActionsAdding;
use App\Traits\Documents;
use App\Traits\Modules;
use App\Traits\ViewComponents;
use Illuminate\Support\Str;
use Illuminate\View\View;
abstract class Index extends Component
{
use Documents, Modules, ViewComponents;
public const OBJECT_TYPE = 'document';
public const DEFAULT_TYPE = 'invoice';
public const DEFAULT_PLURAL_TYPE = 'invoices';
/* -- Main Start -- */
/** @var string */
public $type;
/** @var string */
public $alias;
public $documents;
/** @var string */
public $group;
/** @var string */
public $page;
/** @var string */
public $textTabDocument;
/** @var string */
public $routeTabDocument;
/** @var string */
public $routeTabRecurring;
/** @var string */
public $textPage;
/** @var string */
public $permissionCreate;
/** @var string */
public $permissionUpdate;
/** @var string */
public $permissionDelete;
/* -- Main End -- */
/* -- Buttons Start -- */
/** @var bool */
public $hideAcceptPayment;
/** @var bool */
public $checkPermissionCreate;
/** @var bool */
public $hideCreate;
/** @var bool */
public $hideImport;
/** @var bool */
public $hideExport;
/** @var string */
public $createRoute;
/** @var string */
public $importRoute;
/** @var array */
public $importRouteParameters;
/** @var string */
public $exportRoute;
/* -- Buttons End -- */
/* -- Content Start -- */
/** @var bool */
public $hideEmptyPage;
/** @var array */
public $emptyPageButtons;
/** @var string */
public $imageEmptyPage;
/** @var string */
public $textEmptyPage;
/** @var string */
public $urlDocsPath;
/** @var bool */
public $hideSummary;
/** @var array */
public $summaryItems;
/** @var bool */
public $withoutTabs;
/** @var string */
public $tabActive;
/** @var bool */
public $hideRecurringTemplates;
/** @var bool */
public $hideSearchString;
/** @var bool */
public $hideBulkAction;
/** @var string */
public $searchStringModel;
/** @var string */
public $bulkActionClass;
/** @var array */
public $bulkActionRouteParameters;
/** @var string */
public $searchRoute;
/** @var string */
public $classBulkAction;
/** @var bool */
public $hideDueAt;
/** @var bool */
public $hideIssuedAt;
/** @var string */
public $classDueAtAndIssueAt;
/** @var string */
public $textDueAt;
/** @var string */
public $textIssuedAt;
/** @var bool */
public $hideStatus;
/** @var string */
public $classStatus;
/** @var bool */
public $hideContactName;
/** @var bool */
public $hideDocumentNumber;
/** @var string */
public $classContactNameAndDocumentNumber;
/** @var string */
public $textContactName;
/** @var string */
public $showContactRoute;
/** @var string */
public $textDocumentNumber;
/** @var bool */
public $hideAmount;
/** @var string */
public $classAmount;
/** @var bool */
public $hideShow;
/** @var string */
public $showRoute;
/** @var bool */
public $hideEdit;
/** @var string */
public $editRoute;
/** @var bool */
public $hideDuplicate;
/** @var string */
public $duplicateRoute;
/** @var string */
public $textDocumentStatus;
/** @var bool */
public $checkButtonReconciled;
/** @var bool */
public $checkButtonCancelled;
/* -- Content End -- */
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(
string $type, string $alias = '', $documents = [], string $group = '', string $page = '', string $textTabDocument = '', string $textPage = '',
string $routeTabDocument = '', string $routeTabRecurring = '',
string $permissionCreate = '', string $permissionUpdate = '', string $permissionDelete = '',
bool $hideAcceptPayment = false, bool $checkPermissionCreate = true,
bool $hideCreate = false, bool $hideImport = false, bool $hideExport = false,
string $createRoute = '', string $importRoute = '', array $importRouteParameters = [], string $exportRoute = '',
bool $hideEmptyPage = false, array $emptyPageButtons = [], string $imageEmptyPage = '', string $textEmptyPage = '', string $urlDocsPath = '',
bool $hideSummary = false, array $summaryItems = [],
bool $withoutTabs = false, string $tabActive = '', bool $hideRecurringTemplates = false,
bool $hideSearchString = false, bool $hideBulkAction = false,
string $searchStringModel = '', string $bulkActionClass = '', array $bulkActions = [], array $bulkActionRouteParameters = [], string $searchRoute = '', string $classBulkAction = '',
bool $hideDueAt = false, bool $hideIssuedAt = false, string $classDueAtAndIssueAt = '', string $textDueAt = '', string $textIssuedAt = '',
bool $hideStatus = false, string $classStatus = '',
bool $hideContactName = false, bool $hideDocumentNumber = false, string $classContactNameAndDocumentNumber = '', string $textContactName = '', string $showContactRoute = '', string $textDocumentNumber = '',
bool $hideAmount = false, string $classAmount = '',
bool $hideShow = false, string $showRoute = '', bool $hideEdit = false, string $editRoute = '', bool $hideDuplicate = false, string $duplicateRoute = '',
string $textDocumentStatus = '',
bool $checkButtonReconciled = true, bool $checkButtonCancelled = true
) {
/* -- Main Start -- */
$this->type = $type;
$this->alias = $this->getAlias($type, $alias);
$this->documents = ($documents) ? $documents : collect();
$this->group = $this->getGroup($type, $group);
$this->page = $this->getPage($type, $page);
$this->textTabDocument = $this->getTextTabDocument($type, $textTabDocument);
$this->textPage = $this->getTextPage($type, $textPage);
$this->permissionCreate = $this->getPermissionCreate($type, $permissionCreate);
$this->permissionUpdate = $this->getPermissionUpdate($type, $permissionUpdate);
$this->permissionDelete = $this->getPermissionDelete($type, $permissionDelete);
$this->routeTabDocument = $this->getRouteTabDocument($type, $routeTabDocument);
$this->routeTabRecurring = $this->getRouteTabRecurring($type, $routeTabRecurring);
/* -- Main End -- */
/* -- Buttons Start -- */
$this->hideAcceptPayment = $hideAcceptPayment;
$this->checkPermissionCreate = $checkPermissionCreate;
$this->hideCreate = $hideCreate;
$this->hideImport = $hideImport;
$this->hideExport = $hideExport;
$this->createRoute = $this->getCreateRoute($type, $createRoute);
$this->importRoute = $this->getImportRoute($importRoute);
$this->importRouteParameters = $this->getImportRouteParameters($type, $importRouteParameters);
$this->exportRoute = $this->getExportRoute($type, $exportRoute);
/* -- Buttons End -- */
/* -- Content Start -- */
/* -- Empty Page Start -- */
$this->hideEmptyPage = $hideEmptyPage;
$this->emptyPageButtons = $this->getEmptyPageButtons($type, $emptyPageButtons);
$this->imageEmptyPage = $this->getImageEmptyPage($type, $imageEmptyPage);
$this->textEmptyPage = $this->getTextEmptyPage($type, $textEmptyPage);
$this->urlDocsPath = $this->getUrlDocsPath($type, $urlDocsPath);
/* -- Empty Page End -- */
/* -- Summary Start -- */
$this->hideSummary = $hideSummary;
$this->summaryItems = $this->getSummaryItems($type, $summaryItems);
/* -- Sumamry End -- */
/* Container Start */
$this->withoutTabs = $withoutTabs;
$this->tabActive = $this->getTabActive($type, $tabActive);
$this->hideRecurringTemplates = $hideRecurringTemplates;
$this->hideSearchString = $hideSearchString;
$this->hideBulkAction = $hideBulkAction;
$this->searchStringModel = $this->getSearchStringModel($type, $searchStringModel);
$this->bulkActionClass = $this->getBulkActionClass($type, $bulkActionClass);
$this->bulkActionRouteParameters = $this->getBulkActionRouteParameters($type, $bulkActionRouteParameters);
$this->searchRoute = $this->getIndexRoute($type, $searchRoute);
$this->classBulkAction = $this->getClassBulkAction($type, $classBulkAction);
/* Document Start */
$this->hideDueAt = $hideDueAt;
$this->hideIssuedAt = $hideIssuedAt;
$this->classDueAtAndIssueAt = $this->getClassDueAtAndIssueAt($type, $classDueAtAndIssueAt);
$this->textDueAt = $this->getTextDueAt($type, $textDueAt);
$this->textIssuedAt = $this->getTextIssuedAt($type, $textIssuedAt);
$this->hideStatus = $hideStatus;
$this->classStatus = $this->getClassStatus($type, $classStatus);
$this->hideContactName = $hideContactName;
$this->hideDocumentNumber = $hideDocumentNumber;
$this->classContactNameAndDocumentNumber = $this->getClassContactNameAndDocumentNumber($type, $classContactNameAndDocumentNumber);
$this->textContactName = $this->getTextContactName($type, $textContactName);
$this->showContactRoute = $this->getShowContactRoute($type, $showContactRoute);
$this->textDocumentNumber = $this->getTextDocumentNumber($type, $textDocumentNumber);
$this->hideAmount = $hideAmount;
$this->classAmount = $this->getClassAmount($type, $classAmount);
$this->hideShow = $hideShow;
$this->showRoute = $this->getShowRoute($type, $showRoute);
$this->hideEdit = $hideEdit;
$this->editRoute = $this->getEditRoute($type, $editRoute);
$this->hideDuplicate = $hideDuplicate;
$this->duplicateRoute = $this->getDuplicateRoute($type, $duplicateRoute);
$this->textDocumentStatus = $this->getTextDocumentStatus($type, $textDocumentStatus);
$this->checkButtonReconciled = $checkButtonReconciled;
$this->checkButtonCancelled = $checkButtonCancelled;
/* Document End */
/* Container End */
/* -- Content End -- */
// Set Parent data
$this->setParentData();
}
protected function getEmptyPageButtons($type, $emptyPageButtons)
{
if (! empty($emptyPageButtons)) {
return $emptyPageButtons;
}
$prefix = config('type.' . static::OBJECT_TYPE . '.' . $type . '.route.prefix', 'invoices');
$buttons = [];
if (! $this->hideCreate) {
$route = $this->getRouteFromConfig($type, 'create');
$buttons[] = [
'permission' => $this->permissionCreate,
'url' => route($this->createRoute),
'text' => trans('general.title.new', ['type' => trans_choice($this->textPage ?? 'general.' . $prefix, 1)]),
'description' => trans('general.empty.actions.new', ['type' => strtolower(trans_choice($this->textPage ?? 'general.' . $prefix, 1))]),
'active_badge' => true,
];
}
if (! $this->hideImport) {
$route = $this->getRouteFromConfig($type, 'import');
$buttons[] = [
'permission' => $this->permissionCreate,
'url' => route($this->importRoute, $this->importRouteParameters),
'text' => trans('import.title', ['type' => trans_choice($this->textPage ?? 'general.' . $prefix, 1)]),
'description' => trans('general.empty.actions.import', ['type' => strtolower(trans_choice($this->textPage ?? 'general.' . $prefix, 1))]),
];
}
return $buttons;
}
public function getSummaryItems($type, $summaryItems)
{
if (! empty($summaryItems)) {
return $summaryItems;
}
$route = $this->getIndexRoute($type, null);
$totals = $this->getTotalsForFutureDocuments($type);
$items = [];
foreach ($totals as $key => $total) {
$title = ($key == 'overdue') ? trans('general.overdue') : trans('documents.statuses.' . $key);
$href = route($route, ['search' => 'status:' . $key]);
$amount = money($total, setting('default.currency'), true);
$items[] = [
'title' => $title,
'href' => $href,
'amount' => $amount,
];
}
return $items;
}
protected function getTextTabDocument($type, $textTabDocument)
{
if (! empty($textTabDocument)) {
return $textTabDocument;
}
$default_key = config('type.' . static::OBJECT_TYPE . '.' . $type . '.translation.prefix');
$translation = $this->getTextFromConfig($type, 'tab_document', $default_key);
if (! empty($translation)) {
return $translation;
}
return 'general.invoices';
}
public function getTabActive($type, $tabActive)
{
if (! empty($tabActive)) {
return $tabActive;
}
return $type;
}
protected function getRouteTabDocument($type, $routeTabDocument)
{
if (! empty($routeTabDocument)) {
return $routeTabDocument;
}
$route = $this->getRouteFromConfig($type, 'document', 'invoices');
if (! empty($route)) {
return $route;
}
return 'invoices.index';
}
protected function getRouteTabRecurring($type, $routeTabDocument)
{
if (! empty($routeTabDocument)) {
return $routeTabDocument;
}
$route = $this->getRouteFromConfig($type, 'recurring', 'recurring-invoices');
if (! empty($route)) {
return $route;
}
return 'recurring-invoices.index';
}
protected function getClassDueAtAndIssueAt($type, $classDueAtAndIssueAt)
{
if (! empty($classDueAtAndIssueAt)) {
return $classDueAtAndIssueAt;
}
$class = $this->getClassFromConfig($type, 'due_at_and_issue_at');
if (! empty($class)) {
return $class;
}
return 'w-4/12 table-title hidden sm:table-cell';
}
protected function getTextDueAt($type, $textDueAt)
{
if (! empty($textDueAt)) {
return $textDueAt;
}
$translation = $this->getTextFromConfig($type, 'due_at', 'due_date');
if (! empty($translation)) {
return $translation;
}
return 'invoices.due_date';
}
protected function getTextIssuedAt($type, $textIssuedAt)
{
if (! empty($textIssuedAt)) {
return $textIssuedAt;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$default_key = 'bill_date';
break;
default:
$default_key = 'invoice_date';
break;
}
$translation = $this->getTextFromConfig($type, 'issued_at', $default_key);
if (! empty($translation)) {
return $translation;
}
return 'invoices.invoice_date';
}
protected function getClassStatus($type, $classStatus)
{
if (! empty($classStatus)) {
return $classStatus;
}
$class = $this->getClassFromConfig($type, 'status');
if (! empty($class)) {
return $class;
}
return 'w-3/12 table-title hidden sm:table-cell';
}
protected function getClassContactNameAndDocumentNumber($type, $classContactNameAndDocumentNumber)
{
if (! empty($classContactNameAndDocumentNumber)) {
return $classContactNameAndDocumentNumber;
}
$class = $this->getClassFromConfig($type, 'contact_name');
if (! empty($class)) {
return $class;
}
return 'w-6/12 sm:w-3/12 table-title';
}
protected function getTextContactName($type, $textContactName)
{
if (! empty($textContactName)) {
return $textContactName;
}
$default_key = Str::plural(config('type.' . static::OBJECT_TYPE . '.' . $type . '.contact_type'), 2);
$translation = $this->getTextFromConfig($type, 'contact_name', $default_key, 'trans_choice');
if (! empty($translation)) {
return $translation;
}
return 'general.customers';
}
protected function getShowContactRoute($type, $showContactRoute)
{
if (! empty($showContactRoute)) {
return $showContactRoute;
}
if (! empty($showRoute)) {
return $showRoute;
}
$route = $this->getRouteFromConfig($type, 'contact.show', 1);
if (!empty($route)) {
return $route;
}
$default_key = Str::plural(config('type.' . static::OBJECT_TYPE . '.' . $type . '.contact_type'), 2);
return $default_key . '.show';
}
protected function getTextDocumentNumber($type, $textDocumentNumber)
{
if (! empty($textDocumentNumber)) {
return $textDocumentNumber;
}
$translation = $this->getTextFromConfig($type, 'document_number', 'numbers');
if (! empty($translation)) {
return $translation;
}
return 'general.numbers';
}
protected function getClassAmount($type, $classAmount)
{
if (! empty($classAmount)) {
return $classAmount;
}
$class = $this->getClassFromConfig($type, 'amount');
if (! empty($class)) {
return $class;
}
return 'w-6/12 sm:w-2/12';
}
protected function getTextDocumentStatus($type, $textDocumentStatus)
{
if (! empty($textDocumentStatus)) {
return $textDocumentStatus;
}
$translation = $this->getTextFromConfig($type, 'document_status', 'statuses.');
if (! empty($translation)) {
return $translation;
}
$alias = config('type.' . static::OBJECT_TYPE . '.' . $type . '.alias');
if (! empty($alias)) {
$translation = $alias . '::' . config('type.' . static::OBJECT_TYPE . '.' . $type . '.translation.prefix') . '.statuses';
if (is_array(trans($translation))) {
return $translation . '.';
}
}
return 'documents.statuses.';
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,679 @@
<?php
namespace App\Abstracts\View\Components\Documents;
use App\Abstracts\View\Component;
use App\Models\Common\Media;
use App\Traits\DateTime;
use App\Traits\Documents;
use App\Traits\ViewComponents;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Intervention\Image\Exception\NotReadableException;
use Image;
abstract class Template extends Component
{
use DateTime, Documents, ViewComponents;
public const OBJECT_TYPE = 'document';
public const DEFAULT_TYPE = 'invoice';
public const DEFAULT_PLURAL_TYPE = 'invoices';
public $type;
public $item;
public $document;
/** @var string */
public $documentTemplate;
public $date_format;
public $logo;
public $backgroundColor;
public $hideFooter;
public $hideCompanyLogo;
public $hideCompanyDetails;
public $hideCompanyName;
public $hideCompanyAddress;
public $hideCompanyTaxNumber;
public $hideCompanyPhone;
public $hideCompanyEmail;
public $hideContactInfo;
public $hideContactName;
public $hideContactAddress;
public $hideContactTaxNumber;
public $hideContactPhone;
public $hideContactEmail;
public $hideOrderNumber;
public $hideDocumentNumber;
public $hideIssuedAt;
public $hideDueAt;
/** @var string */
public $textDocumentTitle;
/** @var string */
public $textDocumentSubheading;
public $textContactInfo;
/** @var string */
public $textIssuedAt;
/** @var string */
public $textDueAt;
/** @var string */
public $textDocumentNumber;
/** @var string */
public $textOrderNumber;
public $hideItems;
public $hideName;
public $hideDescription;
public $hideQuantity;
public $hidePrice;
public $hideDiscount;
public $hideAmount;
/** @var string */
public $textItems;
/** @var string */
public $textQuantity;
/** @var string */
public $textPrice;
/** @var string */
public $textAmount;
public $hideNote;
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(
$type, $document, $item = false, $documentTemplate = '', $logo = '', $backgroundColor = '',
bool $hideFooter = false, bool $hideCompanyLogo = false, bool $hideCompanyDetails = false,
bool $hideCompanyName = false, bool $hideCompanyAddress = false, bool $hideCompanyTaxNumber = false, bool $hideCompanyPhone = false, bool $hideCompanyEmail = false, bool $hideContactInfo = false,
bool $hideContactName = false, bool $hideContactAddress = false, bool $hideContactTaxNumber = false, bool $hideContactPhone = false, bool $hideContactEmail = false,
bool $hideOrderNumber = false, bool $hideDocumentNumber = false, bool $hideIssuedAt = false, bool $hideDueAt = false,
string $textDocumentTitle = '', string $textDocumentSubheading = '',
string $textContactInfo = '', string $textDocumentNumber = '', string $textOrderNumber = '', string $textIssuedAt = '', string $textDueAt = '',
bool $hideItems = false, bool $hideName = false, bool $hideDescription = false, bool $hideQuantity = false, bool $hidePrice = false, bool $hideDiscount = false, bool $hideAmount = false, bool $hideNote = false,
string $textItems = '', string $textQuantity = '', string $textPrice = '', string $textAmount = ''
) {
$this->type = $type;
$this->item = $item;
$this->document = $document;
$this->documentTemplate = $this->getDocumentTemplate($type, $documentTemplate);
$this->logo = $this->getLogo($logo);
$this->backgroundColor = $this->getBackgroundColor($type, $backgroundColor);
$this->hideFooter = $hideFooter;
$this->hideCompanyLogo = $hideCompanyLogo;
$this->hideCompanyDetails = $hideCompanyDetails;
$this->hideCompanyName = $hideCompanyName;
$this->hideCompanyAddress = $hideCompanyAddress;
$this->hideCompanyTaxNumber = $hideCompanyTaxNumber;
$this->hideCompanyPhone = $hideCompanyPhone;
$this->hideCompanyEmail = $hideCompanyEmail;
$this->hideContactInfo = $hideContactInfo;
$this->hideContactName = $hideContactName;
$this->hideContactAddress = $hideContactAddress;
$this->hideContactTaxNumber = $hideContactTaxNumber;
$this->hideContactPhone = $hideContactPhone;
$this->hideContactEmail = $hideContactEmail;
$this->hideOrderNumber = $hideOrderNumber;
$this->hideDocumentNumber = $hideDocumentNumber;
$this->hideIssuedAt = $hideIssuedAt;
$this->hideDueAt = $hideDueAt;
$this->textDocumentTitle = $this->getTextDocumentTitle($type, $textDocumentTitle);
$this->textDocumentSubheading = $this->gettextDocumentSubheading($type, $textDocumentSubheading);
$this->textContactInfo = $this->getTextContactInfo($type, $textContactInfo);
$this->textIssuedAt = $this->getTextIssuedAt($type, $textIssuedAt);
$this->textDocumentNumber = $this->getTextDocumentNumber($type, $textDocumentNumber);
$this->textDueAt = $this->getTextDueAt($type, $textDueAt);
$this->textOrderNumber = $this->getTextOrderNumber($type, $textOrderNumber);
$this->hideItems = $this->getHideItems($type, $hideItems, $hideName, $hideDescription);
$this->hideName = $this->getHideName($type, $hideName);
$this->hideDescription = $this->getHideDescription($type, $hideDescription);
$this->hideQuantity = $this->getHideQuantity($type, $hideQuantity);
$this->hidePrice = $this->getHidePrice($type, $hidePrice);
$this->hideDiscount = $this->getHideDiscount($type, $hideDiscount);
$this->hideAmount = $this->getHideAmount($type, $hideAmount);
$this->hideNote = $hideNote;
$this->textItems = $this->getTextItems($type, $textItems);
$this->textQuantity = $this->getTextQuantity($type, $textQuantity);
$this->textPrice = $this->getTextPrice($type, $textPrice);
$this->textAmount = $this->getTextAmount($type, $textAmount);
// Set Parent data
//$this->setParentData();
}
protected function getDocumentTemplate($type, $documentTemplate)
{
if (! empty($documentTemplate)) {
return $documentTemplate;
}
if ($template = config('type.document.' . $type . '.template', false)) {
return $template;
}
$documentTemplate = setting($this->getSettingKey($type, 'template'), 'default');
return $documentTemplate;
}
protected function getLogo($logo)
{
if (! empty($logo)) {
return $logo;
}
$media_id = (! empty($this->document->contact->logo) && ! empty($this->document->contact->logo->id)) ? $this->document->contact->logo->id : setting('company.logo');
$media = Media::find($media_id);
if (! empty($media)) {
$path = $media->getDiskPath();
if (Storage::missing($path)) {
return $logo;
}
} else {
$path = base_path('public/img/company.png');
}
try {
$image = Image::cache(function($image) use ($media, $path) {
$width = setting('invoice.logo_size_width');
$height = setting('invoice.logo_size_height');
if ($media) {
$image->make(Storage::get($path))->resize($width, $height)->encode();
} else {
$image->make($path)->resize($width, $height)->encode();
}
});
} catch (NotReadableException | \Exception $e) {
Log::info('Company ID: ' . company_id() . ' components/documentshow.php exception.');
Log::info($e->getMessage());
$path = base_path('public/img/company.png');
$image = Image::cache(function($image) use ($path) {
$width = setting('invoice.logo_size_width');
$height = setting('invoice.logo_size_height');
$image->make($path)->resize($width, $height)->encode();
});
}
if (empty($image)) {
return $logo;
}
$extension = File::extension($path);
return 'data:image/' . $extension . ';base64,' . base64_encode($image);
}
protected function getBackgroundColor($type, $backgroundColor)
{
if (! empty($backgroundColor)) {
return $backgroundColor;
}
if ($background_color = config('type.document.' . $type . '.color', false)) {
return $background_color;
}
if (! empty($alias = config('type.document.' . $type . '.alias'))) {
$type = $alias . '.' . str_replace('-', '_', $type);
}
$backgroundColor = setting($this->getSettingKey($type, 'color'), '#55588b');
return $backgroundColor;
}
protected function getTextDocumentTitle($type, $textDocumentTitle)
{
if (! empty($textDocumentTitle)) {
return $textDocumentTitle;
}
$key = $this->getSettingKey($type, 'title');
if (! empty(setting($key))) {
return setting($key);
}
$translation = $this->getTextFromConfig($type, 'document_title', Str::plural($type));
if (! empty($translation)) {
return trans_choice($translation, 1);
}
return setting('invoice.title');
}
protected function getTextDocumentSubheading($type, $textDocumentSubheading)
{
if (! empty($textDocumentSubheading)) {
return $textDocumentSubheading;
}
$key = $this->getSettingKey($type, 'subheading');
if (! empty(setting($key))) {
return setting($key);
}
$translation = $this->getTextFromConfig($type, 'document_subheading', 'subheading');
if (! empty($translation)) {
return trans($translation);
}
return false;
}
protected function getTextDocumentNumber($type, $textDocumentNumber)
{
if (! empty($textDocumentNumber)) {
return $textDocumentNumber;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$default_key = 'bill_number';
break;
default:
$default_key = 'invoice_number';
break;
}
$translation = $this->getTextFromConfig($type, 'document_number', $default_key);
if (! empty($translation)) {
return $translation;
}
return 'general.numbers';
}
protected function getTextOrderNumber($type, $textOrderNumber)
{
if (! empty($textOrderNumber)) {
return $textOrderNumber;
}
$translation = $this->getTextFromConfig($type, 'order_number');
if (! empty($translation)) {
return $translation;
}
return 'invoices.order_number';
}
protected function getTextContactInfo($type, $textContactInfo)
{
if (! empty($textContactInfo)) {
return $textContactInfo;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$default_key = 'bill_from';
break;
default:
$default_key = 'bill_to';
break;
}
$translation = $this->getTextFromConfig($type, 'contact_info', $default_key);
if (! empty($translation)) {
return $translation;
}
return 'invoices.bill_to';
}
protected function getTextIssuedAt($type, $textIssuedAt)
{
if (! empty($textIssuedAt)) {
return $textIssuedAt;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$default_key = 'bill_date';
break;
default:
$default_key = 'invoice_date';
break;
}
$translation = $this->getTextFromConfig($type, 'issued_at', $default_key);
if (! empty($translation)) {
return $translation;
}
return 'invoices.invoice_date';
}
protected function getTextDueAt($type, $textDueAt)
{
if (! empty($textDueAt)) {
return $textDueAt;
}
$translation = $this->getTextFromConfig($type, 'due_at', 'due_date');
if (! empty($translation)) {
return $translation;
}
return 'invoices.due_date';
}
protected function getTextItems($type, $textItems)
{
if (! empty($textItems)) {
return $textItems;
}
// if you use settting translation
if (setting($this->getSettingKey($type, 'item_name'), 'items') === 'custom') {
if (empty($textItems = setting($this->getSettingKey($type, 'item_name_input')))) {
$textItems = 'general.items';
}
return $textItems;
}
if (setting($this->getSettingKey($type, 'item_name')) !== null
&& (trans(setting($this->getSettingKey($type, 'item_name'))) != setting($this->getSettingKey($type, 'item_name')))
) {
return setting($this->getSettingKey($type, 'item_name'));
}
$translation = $this->getTextFromConfig($type, 'items');
if (! empty($translation)) {
return $translation;
}
return 'general.items';
}
protected function getTextQuantity($type, $textQuantity)
{
if (! empty($textQuantity)) {
return $textQuantity;
}
// if you use settting translation
if (setting($this->getSettingKey($type, 'quantity_name'), 'quantity') === 'custom') {
if (empty($textQuantity = setting($this->getSettingKey($type, 'quantity_name_input')))) {
$textQuantity = 'invoices.quantity';
}
return $textQuantity;
}
if (setting($this->getSettingKey($type, 'quantity_name')) !== null
&& (trans(setting($this->getSettingKey($type, 'quantity_name'))) != setting($this->getSettingKey($type, 'quantity_name')))
) {
return setting($this->getSettingKey($type, 'quantity_name'));
}
$translation = $this->getTextFromConfig($type, 'quantity');
if (! empty($translation)) {
return $translation;
}
return 'invoices.quantity';
}
protected function getTextPrice($type, $textPrice)
{
if (! empty($textPrice)) {
return $textPrice;
}
// if you use settting translation
if (setting($this->getSettingKey($type, 'price_name'), 'price') === 'custom') {
if (empty($textPrice = setting($this->getSettingKey($type, 'price_name_input')))) {
$textPrice = 'invoices.price';
}
return $textPrice;
}
if (setting($this->getSettingKey($type, 'price_name')) !== null
&& (trans(setting($this->getSettingKey($type, 'price_name'))) != setting($this->getSettingKey($type, 'price_name')))
) {
return setting($this->getSettingKey($type, 'price_name'));
}
$translation = $this->getTextFromConfig($type, 'price');
if (! empty($translation)) {
return $translation;
}
return 'invoices.price';
}
protected function getTextAmount($type, $textAmount)
{
if (! empty($textAmount)) {
return $textAmount;
}
$translation = $this->getTextFromConfig($type, 'amount');
if (! empty($translation)) {
return $translation;
}
return 'general.amount';
}
protected function getHideItems($type, $hideItems, $hideName, $hideDescription)
{
if (! empty($hideItems)) {
return $hideItems;
}
$hide = $this->getHideFromConfig($type, 'items');
if ($hide) {
return $hide;
}
$hideItems = ($this->getHideName($type, $hideName) & $this->getHideDescription($type, $hideDescription)) ? true : false;
return $hideItems;
}
protected function getHideName($type, $hideName)
{
if (! empty($hideName)) {
return $hideName;
}
// if you use settting translation
if ($hideName = setting($this->getSettingKey($type, 'hide_item_name'), false)) {
return $hideName;
}
$hide = $this->getHideFromConfig($type, 'name');
if ($hide) {
return $hide;
}
// @todo what return value invoice or always false??
return setting('invoice.hide_item_name', $hideName);
}
protected function getHideDescription($type, $hideDescription)
{
if (! empty($hideDescription)) {
return $hideDescription;
}
// if you use settting translation
if ($hideDescription = setting($this->getSettingKey($type, 'hide_item_description'), false)) {
return $hideDescription;
}
$hide = $this->getHideFromConfig($type, 'description');
if ($hide) {
return $hide;
}
// @todo what return value invoice or always false??
return setting('invoice.hide_item_description', $hideDescription);
}
protected function getHideQuantity($type, $hideQuantity)
{
if (! empty($hideQuantity)) {
return $hideQuantity;
}
// if you use settting translation
if ($hideQuantity = setting($this->getSettingKey($type, 'hide_quantity'), false)) {
return $hideQuantity;
}
$hide = $this->getHideFromConfig($type, 'quantity');
if ($hide) {
return $hide;
}
// @todo what return value invoice or always false??
return setting('invoice.hide_quantity', $hideQuantity);
}
protected function getHidePrice($type, $hidePrice)
{
if (! empty($hidePrice)) {
return $hidePrice;
}
// if you use settting translation
if ($hidePrice = setting($this->getSettingKey($type, 'hide_price'), false)) {
return $hidePrice;
}
$hide = $this->getHideFromConfig($type, 'price');
if ($hide) {
return $hide;
}
// @todo what return value invoice or always false??
return setting('invoice.hide_price', $hidePrice);
}
protected function getHideDiscount($type, $hideDiscount)
{
if (! empty($hideDiscount)) {
return $hideDiscount;
}
// if you use settting translation
if ($hideDiscount = setting($this->getSettingKey($type, 'hide_discount'), false)) {
return $hideDiscount;
}
$hide = $this->getHideFromConfig($type, 'discount');
if ($hide) {
return $hide;
}
// @todo what return value invoice or always false??
return setting('invoice.hide_discount', $hideDiscount);
}
protected function getHideAmount($type, $hideAmount)
{
if (! empty($hideAmount)) {
return $hideAmount;
}
// if you use settting translation
if ($hideAmount = setting($this->getSettingKey($type, 'hide_amount'), false)) {
return $hideAmount;
}
$hide = $this->getHideFromConfig($type, 'amount');
if ($hide) {
return $hide;
}
// @todo what return value invoice or always false??
return setting('invoice.hide_amount', $hideAmount);
}
}

View File

@ -0,0 +1,307 @@
<?php
namespace App\Abstracts\View\Components;
use App\Abstracts\View\Component;
use Illuminate\Support\Collection;
abstract class Form extends Component
{
/** @var string */
public $type;
/** @var string */
public $name;
/** @var string */
public $label;
/** @var string */
public $id;
public $value;
/** @var string */
public $valueKey;
/** @var string */
public $placeholder;
/** @var array */
public $options;
/** @var array */
public $option;
/** @var string */
public $optionKey;
/** @var string */
public $optionValue;
/** @var string */
public $checked;
/** @var string */
public $checkedKey;
/** @var string */
public $selected;
/** @var string */
public $selectedKey;
/** @var string */
public $rows;
/** @var bool */
public $remote;
/** @var bool */
public $multiple;
/** @var bool */
public $addNew;
/** @var bool */
public $group;
/** @var bool */
public $disabled;
/** @var bool */
public $readonly;
/** @var bool */
public $required;
/** @var bool */
public $notRequired;
/** @var string */
public $formGroupClass = 'sm:col-span-3';
/** @var string */
public $inputGroupClass = '';
/** @var array */
public $custom_attributes = [];
/** @var array */
public $dynamicAttributes = [];
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(
string $name = '', string $type = 'text', string $label = '', string $id = null, $value = '', $valueKey = null, string $placeholder = '',
$options = [], $option = [], string $optionKey = 'id', string $optionValue = 'name', $checked = null, $checkedKey = null, $selected = null, $selectedKey = null, $rows = '3',
$remote = false, $multiple = false, $addNew = false, $group = false,
bool $disabled = false, bool $readonly = false, bool $required = true, bool $notRequired = false,
string $formGroupClass = '', string $inputGroupClass = '',
$dynamicAttributes = '',
) {
$this->type = $this->getType($type);
$this->name = $this->getName($name);
$this->label = $label;
$this->id = $id ?? $name;
$this->value = $this->getValue($value, $valueKey);
$this->placeholder = $this->getPlaceholder($placeholder);
$this->rows = $rows;
$this->remote = $remote;
$this->multiple = $multiple;
$this->addNew = $addNew;
$this->group = $group;
$this->disabled = $disabled;
$this->readonly = $readonly;
$this->required = $this->getRequired($required, $notRequired);
$this->options = $this->getOptions($options);
$this->option = $option;
$this->optionKey = $optionKey;
$this->optionValue = $optionValue;
$this->checked = $this->getChecked($checked, $checkedKey);
$this->selected = $this->getSelected($selected, $selectedKey);
$this->formGroupClass = $this->getFromGroupClass($formGroupClass);
$this->inputGroupClass = $this->getInputGroupClass($inputGroupClass);
$this->custom_attributes = $this->getCustomAttributes();
$this->setDynamicAttributes($dynamicAttributes);
}
protected function getType($type)
{
if (! empty($type) && (! empty($this->type) && $type != 'text')) {
return $type;
}
if (! empty($this->type)) {
return $this->type;
}
}
protected function getName($name)
{
if (! empty($name)) {
return $name;
}
return $this->name;
}
protected function getValue($value, $valueKey)
{
if ($value != '') {
return $value;
}
if (empty($valueKey)) {
$valueKey = $this->name;
}
if (empty($valueKey)) {
return '';
}
// set model value.
$model = $this->getParentData('model');
$value_keys = explode('.', $valueKey);
if (count($value_keys) > 1) {
$valueKey = $value_keys[0];
}
if (! empty($model->{$valueKey})) {
$value = $model->{$valueKey};
}
if ($model instanceof Collection) {
$value = $model->get($valueKey);
}
if (count($value_keys) > 1) {
$value = $value[0]->{$value_keys[1]};
}
if (empty($value) && request()->has($valueKey)) {
$value = request()->get($valueKey);
}
return old($valueKey, $value);
}
protected function getPlaceholder($placeholder)
{
if (! empty($placeholder)) {
return $placeholder;
}
$label = $this->label;
if (! empty($this->label) && ! empty($this->label->contents)) {
$label = $this->name;
}
return trans('general.form.enter', ['field' => $label]);
}
protected function getOptions($options)
{
if (! empty($options)) {
if (is_array($options) && ! $this->group) {
$o = collect();
foreach ($options as $key => $value) {
if (is_array($value)) {
$o->push((object) $value);
} else {
$o->push((object) [
'id' => $key,
'name' => $value,
]);
}
}
$options = $o;
}
return $options;
}
return [];
}
protected function getChecked($checked, $checkedKey)
{
return $this->getValue($checked, $checkedKey);
}
protected function getSelected($selected, $selectedKey)
{
return $this->getValue($selected, $selectedKey);
}
protected function getRequired($required, $notRequired)
{
if (! empty($notRequired)) {
return false;
}
return $required;
}
protected function getFromGroupClass($formGroupClass)
{
if (! empty($formGroupClass)) {
return $formGroupClass;
}
return $this->formGroupClass;
}
protected function getInputGroupClass($inputGroupClass)
{
if (! empty($inputGroupClass)) {
return $inputGroupClass;
}
return $this->inputGroupClass;
}
protected function getCustomAttributes()
{
$attributes = [];
if (! empty($this->required)) {
$attributes['required'] = $this->required;
}
if (! empty($this->disabled)) {
$attributes['disabled'] = $this->disabled;
}
if (! empty($this->readonly)) {
$attributes['readonly'] = $this->readonly;
}
foreach ($this->custom_attributes as $key => $value) {
$attributes[$key] = $value;
}
return $attributes;
}
protected function setDynamicAttributes($dynamicAttributes)
{
if (! empty($dynamicAttributes)) {
$this->dynamicAttributes = $dynamicAttributes;
}
}
}

View File

@ -1,175 +0,0 @@
<?php
namespace App\Abstracts\View\Components;
use Illuminate\View\Component;
use Illuminate\Support\Str;
abstract class Transaction extends Component
{
public function getTextFromConfig($type, $config_key, $default_key = '', $trans_type = 'trans')
{
$translation = '';
// if set config translation config_key
if ($translation = config('type.' . $type . '.translation.' . $config_key)) {
return $translation;
}
$alias = config('type.' . $type . '.alias');
$prefix = config('type.' . $type . '.translation.prefix');
if (!empty($alias)) {
$alias .= '::';
}
// This magic trans key..
$translations = [
'general' => $alias . 'general.' . $default_key,
'prefix' => $alias . $prefix . '.' . $default_key,
'config_general' => $alias . 'general.' . $config_key,
'config_prefix' => $alias . $prefix . '.' . $config_key,
];
switch ($trans_type) {
case 'trans':
foreach ($translations as $trans) {
if (trans($trans) !== $trans) {
return $trans;
}
}
break;
case 'trans_choice':
foreach ($translations as $trans_choice) {
if (trans_choice($trans_choice, 1) !== $trans_choice) {
return $trans_choice;
}
}
break;
}
return $translation;
}
public function getRouteFromConfig($type, $config_key, $config_parameters = [])
{
$route = '';
// if set config trasnlation config_key
if ($route = config('type.' . $type . '.route.' . $config_key)) {
return $route;
}
$alias = config('type.' . $type . '.alias');
$prefix = config('type.' . $type . '.route.prefix');
// if use module set module alias
if (!empty($alias)) {
$route .= $alias . '.';
}
if (!empty($prefix)) {
$route .= $prefix . '.';
}
$route .= $config_key;
try {
route($route, $config_parameters);
} catch (\Exception $e) {
try {
$route = Str::plural($type, 2) . '.' . $config_key;
route($route, $config_parameters);
} catch (\Exception $e) {
$route = '';
}
}
return $route;
}
public function getPermissionFromConfig($type, $config_key)
{
$permission = '';
// if set config trasnlation config_key
if ($permission = config('type.' . $type . '.permission.' . $config_key)) {
return $permission;
}
$alias = config('type.' . $type . '.alias');
$group = config('type.' . $type . '.group');
$prefix = config('type.' . $type . '.permission.prefix');
$permission = $config_key . '-';
// if use module set module alias
if (!empty($alias)) {
$permission .= $alias . '-';
}
// if controller in folder it must
if (!empty($group)) {
$permission .= $group . '-';
}
$permission .= $prefix;
return $permission;
}
public function getHideFromConfig($type, $config_key)
{
$hide = false;
$hides = config('type.' . $type . '.hide');
if (!empty($hides) && (in_array($config_key, $hides))) {
$hide = true;
}
return $hide;
}
public function getClassFromConfig($type, $config_key)
{
$class_key = 'type.' . $type . '.class.' . $config_key;
return config($class_key, '');
}
public function getCategoryFromConfig($type)
{
$category_type = '';
// if set config trasnlation config_key
if ($category_type = config('type.' . $type . '.category_type')) {
return $category_type;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$category_type = 'expense';
break;
case 'item':
$category_type = 'item';
break;
case 'other':
$category_type = 'other';
break;
case 'transfer':
$category_type = 'transfer';
break;
default:
$category_type = 'income';
break;
}
return $category_type;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,632 +0,0 @@
<?php
namespace App\Abstracts\View\Components;
use App\Abstracts\View\Components\Transaction as Base;
use App\Models\Common\Media;
use App\Traits\DateTime;
use App\Traits\Transactions;
use App\Utilities\Modules;
use File;
use Illuminate\Support\Facades\Log;
use Image;
use Intervention\Image\Exception\NotReadableException;
use Storage;
use Illuminate\Support\Str;
abstract class TransactionTemplate extends Base
{
use DateTime;
use Transactions;
/** @var string */
public $type;
public $transaction;
public $logo;
/** @var array */
public $payment_methods;
/** @var bool */
public $hideCompany;
/** @var bool */
public $hideCompanyLogo;
/** @var bool */
public $hideCompanyDetails;
/** @var bool */
public $hideCompanyName;
/** @var bool */
public $hideCompanyAddress;
/** @var bool */
public $hideCompanyTaxNumber;
/** @var bool */
public $hideCompanyPhone;
/** @var bool */
public $hideCompanyEmail;
/** @var bool */
public $hideContentTitle;
/** @var bool */
public $hidePaidAt;
/** @var bool */
public $hideAccount;
/** @var bool */
public $hideCategory;
/** @var bool */
public $hidePaymentMethods;
/** @var bool */
public $hideReference;
/** @var bool */
public $hideDescription;
/** @var bool */
public $hideAmount;
/** @var string */
public $textContentTitle;
/** @var string */
public $textPaidAt;
/** @var string */
public $textAccount;
/** @var string */
public $textCategory;
/** @var string */
public $textPaymentMethods;
/** @var string */
public $textReference;
/** @var string */
public $textDescription;
/** @var string */
public $textAmount;
/** @var string */
public $textPaidBy;
/** @var string */
public $textContactInfo;
/** @var bool */
public $hideContact;
/** @var bool */
public $hideContactInfo;
/** @var bool */
public $hideContactName;
/** @var bool */
public $hideContactAddress;
/** @var bool */
public $hideContactTaxNumber;
/** @var bool */
public $hideContactPhone;
/** @var bool */
public $hideContactEmail;
/** @var bool */
public $hideRelated;
/** @var bool */
public $hideRelatedDocumentNumber;
/** @var bool */
public $hideRelatedContact;
/** @var bool */
public $hideRelatedDocumentDate;
/** @var bool */
public $hideRelatedDocumentAmount;
/** @var bool */
public $hideRelatedAmount;
/** @var string */
public $textRelatedTransansaction;
/** @var string */
public $textRelatedDocumentNumber;
/** @var string */
public $textRelatedContact;
/** @var string */
public $textRelatedDocumentDate;
/** @var string */
public $textRelatedDocumentAmount;
/** @var string */
public $textRelatedAmount;
/** @var string */
public $routeDocumentShow;
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(
$type, $transaction, $logo = '', array $payment_methods = [],
bool $hideCompany = false, bool $hideCompanyLogo = false, bool $hideCompanyDetails = false, bool $hideCompanyName = false, bool $hideCompanyAddress = false,
bool $hideCompanyTaxNumber = false, bool $hideCompanyPhone = false, bool $hideCompanyEmail = false,
bool $hideContentTitle = false,bool $hidePaidAt = false, bool $hideAccount = false, bool $hideCategory = false, bool $hidePaymentMethods = false, bool $hideReference = false, bool $hideDescription = false,
bool $hideAmount = false,
string $textContentTitle = '', string $textPaidAt = '', string $textAccount = '', string $textCategory = '', string $textPaymentMethods = '', string $textReference = '', string $textDescription = '',
string $textAmount = '', string $textPaidBy = '', string $textContactInfo = '',
bool $hideContact = false, bool $hideContactInfo = false, bool $hideContactName = false, bool $hideContactAddress = false, bool $hideContactTaxNumber = false,
bool $hideContactPhone = false, bool $hideContactEmail = false,
bool $hideRelated = false, bool $hideRelatedDocumentNumber = false, bool $hideRelatedContact = false, bool $hideRelatedDocumentDate = false, bool $hideRelatedDocumentAmount = false, bool $hideRelatedAmount = false,
string $textRelatedTransansaction = '', string $textRelatedDocumentNumber = '', string $textRelatedContact = '', string $textRelatedDocumentDate = '', string $textRelatedDocumentAmount = '', string $textRelatedAmount = '',
string $routeDocumentShow = ''
) {
$this->type = $type;
$this->transaction = $transaction;
$this->logo = $this->getLogo($logo);
$this->payment_methods = ($payment_methods) ?: Modules::getPaymentMethods('all');
// Company Information Hide checker
$this->hideCompany = $hideCompany;
$this->hideCompanyLogo = $hideCompanyLogo;
$this->hideCompanyDetails = $hideCompanyDetails;
$this->hideCompanyName = $hideCompanyName;
$this->hideCompanyAddress = $hideCompanyAddress;
$this->hideCompanyTaxNumber = $hideCompanyTaxNumber;
$this->hideCompanyPhone = $hideCompanyPhone;
$this->hideCompanyEmail = $hideCompanyEmail;
// Transaction Information Hide checker
$this->hideContentTitle = $hideContentTitle;
$this->hidePaidAt = $hidePaidAt;
$this->hideAccount = $hideAccount;
$this->hideCategory = $hideCategory;
$this->hidePaymentMethods = $hidePaymentMethods;
$this->hideReference = $hideReference;
$this->hideDescription = $hideDescription;
$this->hideAmount = $hideAmount;
// Transaction Information Text
$this->textContentTitle = $this->getTextContentTitle($type, $textContentTitle);
$this->textPaidAt = $this->getTextPaidAt($type, $textPaidAt);
$this->textAccount = $this->getTextAccount($type, $textAccount);
$this->textCategory = $this->getTextCategory($type, $textCategory);
$this->textPaymentMethods = $this->getTextPaymentMethods($type, $textPaymentMethods);
$this->textReference = $this->getTextReference($type, $textReference);
$this->textDescription = $this->getTextDescription($type, $textDescription);
$this->textAmount = $this->getTextAmount($type, $textAmount);
$this->textPaidBy = $this->getTextPaidBy($type, $textPaidBy);
$this->textContactInfo = $this->getTextContactInfo($type, $textContactInfo);
// Contact Information Hide checker
$this->hideContact = $hideContact;
$this->hideContactInfo = $hideContactInfo;
$this->hideContactName = $hideContactName;
$this->hideContactAddress = $hideContactAddress;
$this->hideContactTaxNumber = $hideContactTaxNumber;
$this->hideContactPhone = $hideContactPhone;
$this->hideContactEmail = $hideContactEmail;
// Related Information Hide checker
$this->hideRelated = $hideRelated;
$this->hideRelatedDocumentNumber = $hideRelatedDocumentNumber;
$this->hideRelatedContact = $hideRelatedContact;
$this->hideRelatedDocumentDate = $hideRelatedDocumentDate;
$this->hideRelatedDocumentAmount = $hideRelatedDocumentAmount;
$this->hideRelatedAmount = $hideRelatedAmount;
// Related Information Text
$this->textRelatedTransansaction = $this->getTextRelatedTransansaction($type, $textRelatedTransansaction);
$this->textRelatedDocumentNumber = $this->getTextRelatedDocumentNumber($type, $textRelatedDocumentNumber);
$this->textRelatedContact = $this->getTextRelatedContact($type, $textRelatedContact);
$this->textRelatedDocumentDate = $this->getTextRelatedDocumentDate($type, $textRelatedDocumentDate);
$this->textRelatedDocumentAmount = $this->getTextRelatedDocumentAmount($type, $textRelatedDocumentAmount);
$this->textRelatedAmount = $this->getTextRelatedAmount($type, $textRelatedAmount);
$this->routeDocumentShow = $this->routeDocumentShow($type, $routeDocumentShow);
}
protected function getTextContactInfo($type, $textContactInfo)
{
if (!empty($textContactInfo)) {
return $textContactInfo;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$textContactInfo = 'bills.bill_from';
break;
default:
$textContactInfo = 'invoices.bill_to';
break;
}
return $textContactInfo;
}
protected function getLogo($logo)
{
if (!empty($logo)) {
return $logo;
}
$media_id = (!empty($this->transaction->contact->logo) && !empty($this->transaction->contact->logo->id)) ? $this->transaction->contact->logo->id : setting('company.logo');
$media = Media::find($media_id);
if (!empty($media)) {
$path = $media->getDiskPath();
if (Storage::missing($path)) {
return $logo;
}
} else {
$path = base_path('public/img/company.png');
}
try {
$image = Image::cache(function($image) use ($media, $path) {
$width = setting('invoice.logo_size_width');
$height = setting('invoice.logo_size_height');
if ($media) {
$image->make(Storage::get($path))->resize($width, $height)->encode();
} else {
$image->make($path)->resize($width, $height)->encode();
}
});
} catch (NotReadableException | \Exception $e) {
Log::info('Company ID: ' . company_id() . ' components/transactionshow.php exception.');
Log::info($e->getMessage());
$path = base_path('public/img/company.png');
$image = Image::cache(function($image) use ($path) {
$width = setting('invoice.logo_size_width');
$height = setting('invoice.logo_size_height');
$image->make($path)->resize($width, $height)->encode();
});
}
if (empty($image)) {
return $logo;
}
$extension = File::extension($path);
return 'data:image/' . $extension . ';base64,' . base64_encode($image);
}
protected function getTextContentTitle($type, $textContentTitle)
{
if (!empty($textContentTitle)) {
return $textContentTitle;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$default_key = 'payment_made';
break;
default:
$default_key = 'revenue_received';
break;
}
$translation = $this->getTextFromConfig($type, $type . '_made', $default_key);
if (!empty($translation)) {
return $translation;
}
return 'revenues.revenue_received';
}
protected function getTextPaidAt($type, $textPaidAt)
{
if (!empty($textPaidAt)) {
return $textPaidAt;
}
$translation = $this->getTextFromConfig($type, 'paid_at', 'date');
if (!empty($translation)) {
return $translation;
}
return 'general.date';
}
protected function getTextAccount($type, $textAccount)
{
if (!empty($textAccount)) {
return $textAccount;
}
$translation = $this->getTextFromConfig($type, 'accounts', 'accounts', 'trans_choice');
if (!empty($translation)) {
return $translation;
}
return 'general.accounts';
}
protected function getTextCategory($type, $textCategory)
{
if (!empty($textCategory)) {
return $textCategory;
}
$translation = $this->getTextFromConfig($type, 'categories', 'categories', 'trans_choice');
if (!empty($translation)) {
return $translation;
}
return 'general.categories';
}
protected function getTextPaymentMethods($type, $textPaymentMethods)
{
if (!empty($textPaymentMethods)) {
return $textPaymentMethods;
}
$translation = $this->getTextFromConfig($type, 'payment_methods', 'payment_methods', 'trans_choice');
if (!empty($translation)) {
return $translation;
}
return 'general.payment_methods';
}
protected function getTextReference($type, $textReference)
{
if (!empty($textReference)) {
return $textReference;
}
$translation = $this->getTextFromConfig($type, 'reference', 'reference');
if (!empty($translation)) {
return $translation;
}
return 'general.reference';
}
protected function getTextDescription($type, $textDescription)
{
if (!empty($textDescription)) {
return $textDescription;
}
$translation = $this->getTextFromConfig($type, 'description', 'description');
if (!empty($translation)) {
return $translation;
}
return 'general.description';
}
protected function getTextAmount($type, $textAmount)
{
if (!empty($textAmount)) {
return $textAmount;
}
$translation = $this->getTextFromConfig($type, 'amount', 'amount');
if (!empty($translation)) {
return $translation;
}
return 'general.amount';
}
protected function getTextPaidBy($type, $textPaidBy)
{
if (!empty($textPaidBy)) {
return $textPaidBy;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$default_key = 'paid_to';
break;
default:
$default_key = 'paid_by';
break;
}
$translation = $this->getTextFromConfig($type, 'paid_to_by', $default_key);
if (!empty($translation)) {
return $translation;
}
return 'revenues.paid_by';
}
protected function getTextRelatedTransansaction($type, $textRelatedTransansaction)
{
if (!empty($textRelatedTransansaction)) {
return $textRelatedTransansaction;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$default_key = 'related_bill';
break;
default:
$default_key = 'related_invoice';
break;
}
$translation = $this->getTextFromConfig($type, 'related_type', $default_key);
if (!empty($translation)) {
return $translation;
}
return 'revenues.related_invoice';
}
protected function getTextRelatedDocumentNumber($type, $textRelatedDocumentNumber)
{
if (!empty($textRelatedDocumentNumber)) {
return $textRelatedDocumentNumber;
}
$translation = $this->getTextFromConfig($type, 'related_document_number', 'numbers');
if (!empty($translation)) {
return $translation;
}
return 'general.numbers';
}
protected function getTextRelatedContact($type, $textRelatedContact)
{
if (!empty($textRelatedContact)) {
return $textRelatedContact;
}
$default_key = Str::plural(config('type.' . $type . '.contact_type'), 2);
$translation = $this->getTextFromConfig($type, 'related_contact', $default_key, 'trans_choice');
if (!empty($translation)) {
return $translation;
}
return 'general.customers';
}
protected function getTextRelatedDocumentDate($type, $textRelatedDocumentDate)
{
if (!empty($textRelatedDocumentDate)) {
return $textRelatedDocumentDate;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$default_key = 'bill_date';
break;
default:
$default_key = 'invoice_date';
break;
}
$translation = $this->getTextFromConfig($type, 'related_document_date', $default_key);
if (!empty($translation)) {
return $translation;
}
return 'invoices.invoice_date';
}
protected function getTextRelatedDocumentAmount($type, $textRelatedDocumentAmount)
{
if (!empty($textRelatedDocumentAmount)) {
return $textRelatedDocumentAmount;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$default_key = 'bill_amount';
break;
default:
$default_key = 'invoice_amount';
break;
}
$translation = $this->getTextFromConfig($type, 'related_document_amount', $default_key);
if (!empty($translation)) {
return $translation;
}
return 'general.amount';
}
protected function getTextRelatedAmount($type, $textRelatedAmount)
{
if (!empty($textRelatedAmount)) {
return $textRelatedAmount;
}
$translation = $this->getTextFromConfig($type, 'related_amount', 'amount');
if (!empty($translation)) {
return $translation;
}
return 'general.amount';
}
protected function routeDocumentShow($type, $routeDocumentShow)
{
if (!empty($routeDocumentShow)) {
return $routeDocumentShow;
}
if (!$this->transaction->document) {
return $routeDocumentShow;
}
//example route parameter.
$parameter = 1;
$route = $this->getRouteFromConfig($this->transaction->document->type, 'show', $parameter);
if (!empty($route)) {
return $route;
}
return 'invoices.show';
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,653 @@
<?php
namespace App\Abstracts\View\Components\Transactions;
use App\Abstracts\View\Component;
use App\Models\Common\Media;
use App\Traits\DateTime;
use App\Traits\Transactions;
use App\Utilities\Modules;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Intervention\Image\Facades\Image;
use Intervention\Image\Exception\NotReadableException;
use App\Traits\ViewComponents;
abstract class Template extends Component
{
use DateTime, Transactions, ViewComponents;
public const OBJECT_TYPE = 'transaction';
public const DEFAULT_TYPE = 'transaction';
public const DEFAULT_PLURAL_TYPE = 'transactions';
/** @var string */
public $type;
public $transaction;
public $logo;
/** @var array */
public $payment_methods;
/** @var bool */
public $hideCompany;
/** @var bool */
public $hideCompanyLogo;
/** @var bool */
public $hideCompanyDetails;
/** @var bool */
public $hideCompanyName;
/** @var bool */
public $hideCompanyAddress;
/** @var bool */
public $hideCompanyTaxNumber;
/** @var bool */
public $hideCompanyPhone;
/** @var bool */
public $hideCompanyEmail;
/** @var bool */
public $hideContentTitle;
/** @var bool */
public $hideNumber;
/** @var bool */
public $hidePaidAt;
/** @var bool */
public $hideAccount;
/** @var bool */
public $hideCategory;
/** @var bool */
public $hidePaymentMethods;
/** @var bool */
public $hideReference;
/** @var bool */
public $hideDescription;
/** @var bool */
public $hideAmount;
/** @var string */
public $textContentTitle;
/** @var string */
public $textNumber;
/** @var string */
public $textPaidAt;
/** @var string */
public $textAccount;
/** @var string */
public $textCategory;
/** @var string */
public $textPaymentMethods;
/** @var string */
public $textReference;
/** @var string */
public $textDescription;
/** @var string */
public $textAmount;
/** @var string */
public $textPaidBy;
/** @var string */
public $textContactInfo;
/** @var bool */
public $hideContact;
/** @var bool */
public $hideContactInfo;
/** @var bool */
public $hideContactName;
/** @var bool */
public $hideContactAddress;
/** @var bool */
public $hideContactTaxNumber;
/** @var bool */
public $hideContactPhone;
/** @var bool */
public $hideContactEmail;
/** @var bool */
public $hideRelated;
/** @var bool */
public $hideRelatedDocumentNumber;
/** @var bool */
public $hideRelatedContact;
/** @var bool */
public $hideRelatedDocumentDate;
/** @var bool */
public $hideRelatedDocumentAmount;
/** @var bool */
public $hideRelatedAmount;
/** @var string */
public $textRelatedTransansaction;
/** @var string */
public $textRelatedDocumentNumber;
/** @var string */
public $textRelatedContact;
/** @var string */
public $textRelatedDocumentDate;
/** @var string */
public $textRelatedDocumentAmount;
/** @var string */
public $textRelatedAmount;
/** @var string */
public $routeDocumentShow;
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(
$type, $transaction, $logo = '', array $payment_methods = [],
bool $hideCompany = false, bool $hideCompanyLogo = false, bool $hideCompanyDetails = false, bool $hideCompanyName = false, bool $hideCompanyAddress = false,
bool $hideCompanyTaxNumber = false, bool $hideCompanyPhone = false, bool $hideCompanyEmail = false,
bool $hideContentTitle = false, bool $hideNumber = false, bool $hidePaidAt = false, bool $hideAccount = false, bool $hideCategory = false, bool $hidePaymentMethods = false, bool $hideReference = false,
bool $hideDescription = false, bool $hideAmount = false,
string $textContentTitle = '', string $textNumber = '', string $textPaidAt = '', string $textAccount = '', string $textCategory = '', string $textPaymentMethods = '', string $textReference = '',
string $textDescription = '', string $textAmount = '', string $textPaidBy = '', string $textContactInfo = '',
bool $hideContact = false, bool $hideContactInfo = false, bool $hideContactName = false, bool $hideContactAddress = false, bool $hideContactTaxNumber = false,
bool $hideContactPhone = false, bool $hideContactEmail = false,
bool $hideRelated = false, bool $hideRelatedDocumentNumber = false, bool $hideRelatedContact = false, bool $hideRelatedDocumentDate = false, bool $hideRelatedDocumentAmount = false, bool $hideRelatedAmount = false,
string $textRelatedTransansaction = '', string $textRelatedDocumentNumber = '', string $textRelatedContact = '', string $textRelatedDocumentDate = '', string $textRelatedDocumentAmount = '', string $textRelatedAmount = '',
string $routeDocumentShow = ''
) {
$this->type = $type;
$this->transaction = $transaction;
$this->logo = $this->getLogo($logo);
$this->payment_methods = ($payment_methods) ?: Modules::getPaymentMethods('all');
// Company Information Hide checker
$this->hideCompany = $hideCompany;
$this->hideCompanyLogo = $hideCompanyLogo;
$this->hideCompanyDetails = $hideCompanyDetails;
$this->hideCompanyName = $hideCompanyName;
$this->hideCompanyAddress = $hideCompanyAddress;
$this->hideCompanyTaxNumber = $hideCompanyTaxNumber;
$this->hideCompanyPhone = $hideCompanyPhone;
$this->hideCompanyEmail = $hideCompanyEmail;
// Transaction Information Hide checker
$this->hideContentTitle = $hideContentTitle;
$this->hideNumber = $hideNumber;
$this->hidePaidAt = $hidePaidAt;
$this->hideAccount = $hideAccount;
$this->hideCategory = $hideCategory;
$this->hidePaymentMethods = $hidePaymentMethods;
$this->hideReference = $hideReference;
$this->hideDescription = $hideDescription;
$this->hideAmount = $hideAmount;
// Transaction Information Text
$this->textContentTitle = $this->getTextContentTitle($type, $textContentTitle);
$this->textNumber = $this->getTextNumber($type, $textNumber);
$this->textPaidAt = $this->getTextPaidAt($type, $textPaidAt);
$this->textAccount = $this->getTextAccount($type, $textAccount);
$this->textCategory = $this->getTextCategory($type, $textCategory);
$this->textPaymentMethods = $this->getTextPaymentMethods($type, $textPaymentMethods);
$this->textReference = $this->getTextReference($type, $textReference);
$this->textDescription = $this->getTextDescription($type, $textDescription);
$this->textAmount = $this->getTextAmount($type, $textAmount);
$this->textPaidBy = $this->getTextPaidBy($type, $textPaidBy);
$this->textContactInfo = $this->getTextContactInfo($type, $textContactInfo);
// Contact Information Hide checker
$this->hideContact = $hideContact;
$this->hideContactInfo = $hideContactInfo;
$this->hideContactName = $hideContactName;
$this->hideContactAddress = $hideContactAddress;
$this->hideContactTaxNumber = $hideContactTaxNumber;
$this->hideContactPhone = $hideContactPhone;
$this->hideContactEmail = $hideContactEmail;
// Related Information Hide checker
$this->hideRelated = $hideRelated;
$this->hideRelatedDocumentNumber = $hideRelatedDocumentNumber;
$this->hideRelatedContact = $hideRelatedContact;
$this->hideRelatedDocumentDate = $hideRelatedDocumentDate;
$this->hideRelatedDocumentAmount = $hideRelatedDocumentAmount;
$this->hideRelatedAmount = $hideRelatedAmount;
// Related Information Text
$this->textRelatedTransansaction = $this->getTextRelatedTransansaction($type, $textRelatedTransansaction);
$this->textRelatedDocumentNumber = $this->getTextRelatedDocumentNumber($type, $textRelatedDocumentNumber);
$this->textRelatedContact = $this->getTextRelatedContact($type, $textRelatedContact);
$this->textRelatedDocumentDate = $this->getTextRelatedDocumentDate($type, $textRelatedDocumentDate);
$this->textRelatedDocumentAmount = $this->getTextRelatedDocumentAmount($type, $textRelatedDocumentAmount);
$this->textRelatedAmount = $this->getTextRelatedAmount($type, $textRelatedAmount);
$this->routeDocumentShow = $this->routeDocumentShow($type, $routeDocumentShow);
}
protected function getLogo($logo)
{
if (!empty($logo)) {
return $logo;
}
$media_id = (!empty($this->transaction->contact->logo) && !empty($this->transaction->contact->logo->id)) ? $this->transaction->contact->logo->id : setting('company.logo');
$media = Media::find($media_id);
if (!empty($media)) {
$path = $media->getDiskPath();
if (Storage::missing($path)) {
return $logo;
}
} else {
$path = base_path('public/img/company.png');
}
try {
$image = Image::cache(function($image) use ($media, $path) {
$width = setting('invoice.logo_size_width');
$height = setting('invoice.logo_size_height');
if ($media) {
$image->make(Storage::get($path))->resize($width, $height)->encode();
} else {
$image->make($path)->resize($width, $height)->encode();
}
});
} catch (NotReadableException | \Exception $e) {
Log::info('Company ID: ' . company_id() . ' components/transactionshow.php exception.');
Log::info($e->getMessage());
$path = base_path('public/img/company.png');
$image = Image::cache(function($image) use ($path) {
$width = setting('invoice.logo_size_width');
$height = setting('invoice.logo_size_height');
$image->make($path)->resize($width, $height)->encode();
});
}
if (empty($image)) {
return $logo;
}
$extension = File::extension($path);
return 'data:image/' . $extension . ';base64,' . base64_encode($image);
}
protected function getTextContentTitle($type, $textContentTitle)
{
if (!empty($textContentTitle)) {
return $textContentTitle;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$default_key = 'payment_made';
break;
default:
$default_key = 'receipts';
break;
}
$translation = $this->getTextFromConfig($type, $type . '_made', $default_key);
if (!empty($translation)) {
return $translation;
}
return 'general.receipts';
}
protected function getTextNumber($type, $textNumber)
{
if (!empty($textNumber)) {
return $textNumber;
}
return 'general.numbers';
}
protected function getTextPaidAt($type, $textPaidAt)
{
if (!empty($textPaidAt)) {
return $textPaidAt;
}
$translation = $this->getTextFromConfig($type, 'paid_at', 'date');
if (!empty($translation)) {
return $translation;
}
return 'general.date';
}
protected function getTextAccount($type, $textAccount)
{
if (!empty($textAccount)) {
return $textAccount;
}
$translation = $this->getTextFromConfig($type, 'accounts', 'accounts', 'trans_choice');
if (!empty($translation)) {
return $translation;
}
return 'general.accounts';
}
protected function getTextCategory($type, $textCategory)
{
if (!empty($textCategory)) {
return $textCategory;
}
$translation = $this->getTextFromConfig($type, 'categories', 'categories', 'trans_choice');
if (!empty($translation)) {
return $translation;
}
return 'general.categories';
}
protected function getTextPaymentMethods($type, $textPaymentMethods)
{
if (!empty($textPaymentMethods)) {
return $textPaymentMethods;
}
$translation = $this->getTextFromConfig($type, 'payment_methods', 'payment_methods', 'trans_choice');
if (!empty($translation)) {
return $translation;
}
return 'general.payment_methods';
}
protected function getTextReference($type, $textReference)
{
if (!empty($textReference)) {
return $textReference;
}
$translation = $this->getTextFromConfig($type, 'reference', 'reference');
if (!empty($translation)) {
return $translation;
}
return 'general.reference';
}
protected function getTextDescription($type, $textDescription)
{
if (!empty($textDescription)) {
return $textDescription;
}
$translation = $this->getTextFromConfig($type, 'description', 'description');
if (!empty($translation)) {
return $translation;
}
return 'general.description';
}
protected function getTextAmount($type, $textAmount)
{
if (!empty($textAmount)) {
return $textAmount;
}
$translation = $this->getTextFromConfig($type, 'amount', 'amount');
if (!empty($translation)) {
return $translation;
}
return 'general.amount';
}
protected function getTextPaidBy($type, $textPaidBy)
{
if (!empty($textPaidBy)) {
return $textPaidBy;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$default_key = 'paid_to';
break;
default:
$default_key = 'paid_by';
break;
}
$translation = $this->getTextFromConfig($type, 'paid_to_by', $default_key);
if (!empty($translation)) {
return $translation;
}
return 'transactions.paid_by';
}
protected function getTextContactInfo($type, $textContactInfo)
{
if (!empty($textContactInfo)) {
return $textContactInfo;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$textContactInfo = 'bills.bill_from';
break;
default:
$textContactInfo = 'invoices.bill_to';
break;
}
return $textContactInfo;
}
protected function getTextRelatedTransansaction($type, $textRelatedTransansaction)
{
if (!empty($textRelatedTransansaction)) {
return $textRelatedTransansaction;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$default_key = 'related_bill';
break;
default:
$default_key = 'related_invoice';
break;
}
$translation = $this->getTextFromConfig($type, 'related_type', $default_key);
if (!empty($translation)) {
return $translation;
}
return 'transactions.related_invoice';
}
protected function getTextRelatedDocumentNumber($type, $textRelatedDocumentNumber)
{
if (!empty($textRelatedDocumentNumber)) {
return $textRelatedDocumentNumber;
}
$translation = $this->getTextFromConfig($type, 'related_document_number', 'numbers');
if (!empty($translation)) {
return $translation;
}
return 'general.numbers';
}
protected function getTextRelatedContact($type, $textRelatedContact)
{
if (!empty($textRelatedContact)) {
return $textRelatedContact;
}
$default_key = Str::plural(config('type.transaction.' . $type . '.contact_type'), 2);
$translation = $this->getTextFromConfig($type, 'related_contact', $default_key, 'trans_choice');
if (!empty($translation)) {
return $translation;
}
return 'general.customers';
}
protected function getTextRelatedDocumentDate($type, $textRelatedDocumentDate)
{
if (!empty($textRelatedDocumentDate)) {
return $textRelatedDocumentDate;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$default_key = 'bill_date';
break;
default:
$default_key = 'invoice_date';
break;
}
$translation = $this->getTextFromConfig($type, 'related_document_date', $default_key);
if (!empty($translation)) {
return $translation;
}
return 'invoices.invoice_date';
}
protected function getTextRelatedDocumentAmount($type, $textRelatedDocumentAmount)
{
if (!empty($textRelatedDocumentAmount)) {
return $textRelatedDocumentAmount;
}
switch ($type) {
case 'bill':
case 'expense':
case 'purchase':
$default_key = 'bill_amount';
break;
default:
$default_key = 'invoice_amount';
break;
}
$translation = $this->getTextFromConfig($type, 'related_document_amount', $default_key);
if (!empty($translation)) {
return $translation;
}
return 'general.amount';
}
protected function getTextRelatedAmount($type, $textRelatedAmount)
{
if (!empty($textRelatedAmount)) {
return $textRelatedAmount;
}
$translation = $this->getTextFromConfig($type, 'related_amount', 'amount');
if (!empty($translation)) {
return $translation;
}
return 'general.amount';
}
protected function routeDocumentShow($type, $routeDocumentShow)
{
if (!empty($routeDocumentShow)) {
return $routeDocumentShow;
}
if (!$this->transaction->document) {
return $routeDocumentShow;
}
//example route parameter.
$parameter = 1;
$route = $this->getRouteFromConfig($this->transaction->document->type, 'show', $parameter);
if (!empty($route)) {
return $route;
}
return 'invoices.show';
}
}

View File

@ -1,747 +0,0 @@
<?php
namespace App\Abstracts\View\Components;
use App\Models\Common\Media;
use App\Traits\DateTime;
use App\Traits\Transactions;
use App\Utilities\Modules;
use File;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Str;
use Image;
use Intervention\Image\Exception\NotReadableException;
use Illuminate\Support\Facades\Storage;
use Illuminate\View\Component;
abstract class TransferShow extends Component
{
use DateTime, Transactions;
public $transfer;
/** @var string */
public $transferTemplate;
/** @var array */
public $payment_methods;
public $date_format;
/** @var bool */
public $hideButtonAddNew;
/** @var bool */
public $hideButtonMoreActions;
/** @var bool */
public $hideButtonEdit;
/** @var bool */
public $hideButtonDuplicate;
/** @var bool */
public $hideButtonPrint;
/** @var bool */
public $hideButtonShare;
/** @var bool */
public $hideButtonEmail;
/** @var bool */
public $hideButtonPdf;
/** @var bool */
public $hideButtonDelete;
/** @var bool */
public $hideButtonGroupDivider1;
/** @var bool */
public $hideButtonGroupDivider2;
/** @var bool */
public $hideButtonGroupDivider3;
/** @var string */
public $permissionCreate;
/** @var string */
public $permissionUpdate;
/** @var string */
public $permissionDelete;
/** @var string */
public $routeButtonAddNew;
/** @var string */
public $routeButtonEdit;
/** @var string */
public $routeButtonDuplicate;
/** @var string */
public $routeButtonPrint;
/** @var string */
public $signedUrl;
/** @var string */
public $routeButtonEmail;
/** @var string */
public $routeButtonPdf;
/** @var string */
public $hideButtonTemplate;
/** @var string */
public $routeButtonDelete;
/** @var string */
public $routeFromAccountShow;
/** @var string */
public $routeToAccountShow;
/** @var string */
public $textDeleteModal;
/** @var bool */
public $hideHeader;
/** @var bool */
public $hideHeaderFromAccount;
/** @var bool */
public $hideHeaderToAccount;
/** @var bool */
public $hideHeaderAmount;
/** @var bool */
public $hideHeaderPaidAt;
/** @var string */
public $textHeaderFromAccount;
/** @var string */
public $textHeaderToAccount;
/** @var string */
public $textHeaderAmount;
/** @var string */
public $textHeaderPaidAt;
/** @var string */
public $classHeaderFromAccount;
/** @var string */
public $classHeaderToAccount;
/** @var string */
public $classHeaderAmount;
/** @var string */
public $classHeaderPaidAt;
/** @var bool */
public $hideFromAccount;
/** @var bool */
public $hideFromAccountTitle;
/** @var bool */
public $hideFromAccountName;
/** @var bool */
public $hideFromAccountNumber;
/** @var bool */
public $hideFromAccountBankName;
/** @var bool */
public $hideFromAccountBankPhone;
/** @var bool */
public $hideFromAccountBankAddress;
/** @var string */
public $textFromAccountTitle;
/** @var string */
public $textFromAccountNumber;
/** @var bool */
public $hideToAccount;
/** @var bool */
public $hideToAccountTitle;
/** @var bool */
public $hideToAccountName;
/** @var bool */
public $hideToAccountNumber;
/** @var bool */
public $hideToAccountBankName;
/** @var bool */
public $hideToAccountBankPhone;
/** @var bool */
public $hideToAccountBankAddress;
/** @var string */
public $textToAccountTitle;
/** @var string */
public $textToAccountNumber;
/** @var bool */
public $hideDetails;
/** @var bool */
public $hideDetailTitle;
/** @var bool */
public $hideDetailDate;
/** @var bool */
public $hideDetailPaymentMethod;
/** @var bool */
public $hideDetailReference;
/** @var bool */
public $hideDetailDescription;
/** @var bool */
public $hideDetailAmount;
/** @var string */
public $textDetailTitle;
/** @var string */
public $textDetailDate;
/** @var string */
public $textDetailPaymentMethod;
/** @var string */
public $textDetailReference;
/** @var string */
public $textDetailDescription;
/** @var string */
public $textDetailAmount;
/** @var bool */
public $hideAttachment;
public $attachment;
/** @var bool */
public $hideFooter;
/** @var bool */
public $hideFooterHistories;
public $histories;
/** @var string */
public $textHistories;
/** @var string */
public $classFooterHistories;
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(
$transfer, $transferTemplate = '', array $payment_methods = [],
bool $hideButtonAddNew = false, bool $hideButtonMoreActions = false, bool $hideButtonEdit = false, bool $hideButtonDuplicate = false, bool $hideButtonPrint = false, bool $hideButtonShare = false,
bool $hideButtonEmail = false, bool $hideButtonPdf = false, bool $hideButtonTemplate = false, bool $hideButtonDelete = false,
bool $hideButtonGroupDivider1 = false, bool $hideButtonGroupDivider2 = false, bool $hideButtonGroupDivider3 = false,
string $permissionCreate = '', string $permissionUpdate = '', string $permissionDelete = '',
string $routeButtonAddNew = '', string $routeButtonEdit = '', string $routeButtonDuplicate = '', string $routeButtonPrint = '', string $signedUrl = '',
string $routeButtonEmail = '', string $routeButtonPdf = '', string $routeButtonDelete = '', string $routeFromAccountShow = '', string $routeToAccountShow = '',
string $textDeleteModal = '',
bool $hideHeader = false, bool $hideHeaderFromAccount = false, bool $hideHeaderToAccount = false, bool $hideHeaderAmount = false, bool $hideHeaderPaidAt = false,
string $textHeaderFromAccount = '', string $textHeaderToAccount = '', string $textHeaderAmount = '', string $textHeaderPaidAt = '',
string $classHeaderFromAccount = '', string $classHeaderToAccount = '', string $classHeaderAmount = '', string $classHeaderPaidAt = '',
bool $hideFromAccount = false, bool $hideFromAccountTitle = false, bool $hideFromAccountName = false, bool $hideFromAccountNumber = false,
bool $hideFromAccountBankName = false, bool $hideFromAccountBankPhone = false, bool $hideFromAccountBankAddress = false,
string $textFromAccountTitle = '', string $textFromAccountNumber = '',
bool $hideToAccount = false, bool $hideToAccountTitle = false, bool $hideToAccountName = false, bool $hideToAccountNumber = false,
bool $hideToAccountBankName = false, bool $hideToAccountBankPhone = false, bool $hideToAccountBankAddress = false,
string $textToAccountTitle = '', string $textToAccountNumber = '',
bool $hideDetails = false, bool $hideDetailTitle = false, bool $hideDetailDate = false, bool $hideDetailPaymentMethod = false,
bool $hideDetailReference = false, bool $hideDetailDescription = false, bool $hideDetailAmount = false,
string $textDetailTitle = '', string $textDetailDate = '', string $textDetailPaymentMethod = '', string $textDetailReference = '',
string $textDetailDescription = '', string $textDetailAmount = '',
bool $hideAttachment = false, $attachment = [],
bool $hideFooter = false, bool $hideFooterHistories = false, $histories = [],
string $textHistories = '', string $classFooterHistories = ''
) {
$this->transfer = $transfer;
$this->transferTemplate = $this->getTransferTemplate($transferTemplate);
$this->payment_methods = ($payment_methods) ?: Modules::getPaymentMethods('all');
$this->date_format = $this->getCompanyDateFormat();
// Navbar Hide
$this->hideButtonAddNew = $hideButtonAddNew;
$this->hideButtonMoreActions = $hideButtonMoreActions;
$this->hideButtonEdit = $hideButtonEdit;
$this->hideButtonDuplicate = $hideButtonDuplicate;
$this->hideButtonPrint = $hideButtonPrint;
$this->hideButtonShare = $hideButtonShare;
$this->hideButtonEmail = $hideButtonEmail;
$this->hideButtonPdf = $hideButtonPdf;
$this->hideButtonTemplate = $hideButtonTemplate;
$this->hideButtonDelete = $hideButtonDelete;
$this->hideButtonGroupDivider1 = $hideButtonGroupDivider1;
$this->hideButtonGroupDivider2 = $hideButtonGroupDivider2;
$this->hideButtonGroupDivider3 = $hideButtonGroupDivider3;
// Navbar Permission
$this->permissionCreate = $this->getPermissionCreate($permissionCreate);
$this->permissionUpdate = $this->getPermissionUpdate($permissionUpdate);
$this->permissionDelete = $this->getPermissionDelete($permissionDelete);
// Navbar route
$this->routeButtonAddNew = $this->getRouteButtonAddNew($routeButtonAddNew);
$this->routeButtonEdit = $this->getRouteButtonEdit($routeButtonEdit);
$this->routeButtonDuplicate = $this->getRouteButtonDuplicate($routeButtonDuplicate);
$this->routeButtonPrint = $this->getRouteButtonPrint($routeButtonPrint);
$this->signedUrl = $this->getSignedUrl($signedUrl);
$this->routeButtonEmail = $this->getRouteButtonEmail($routeButtonEmail);
$this->routeButtonPdf = $this->getRouteButtonPdf($routeButtonPdf);
$this->routeButtonDelete = $this->getRouteButtonDelete($routeButtonDelete);
$this->routeFromAccountShow = $this->getRouteFromAccountShow($routeFromAccountShow);
$this->routeToAccountShow = $this->getRouteToAccountShow($routeToAccountShow);
// Navbar Text
$this->textDeleteModal = $textDeleteModal;
// Header Hide
$this->hideHeader = $hideHeader;
$this->hideHeaderFromAccount = $hideHeaderFromAccount;
$this->hideHeaderToAccount = $hideHeaderToAccount;
$this->hideHeaderToAccount = $hideHeaderToAccount;
$this->hideHeaderAmount = $hideHeaderAmount;
$this->hideHeaderPaidAt = $hideHeaderPaidAt;
// Header Text
$this->textHeaderFromAccount = $this->getTextHeaderFromAccount($textHeaderFromAccount);
$this->textHeaderToAccount = $this->getTextHeaderToAccount($textHeaderToAccount);
$this->textHeaderAmount = $this->getTextHeaderAmount($textHeaderAmount);
$this->textHeaderPaidAt = $this->gettextHeaderPaidAt($textHeaderPaidAt);
// Header Class
$this->classHeaderFromAccount = $this->getclassHeaderFromAccount($classHeaderFromAccount);
$this->classHeaderToAccount = $this->getClassHeaderToAccount($classHeaderToAccount);
$this->classHeaderAmount = $this->getClassHeaderAmount($classHeaderAmount);
$this->classHeaderPaidAt = $this->getclassHeaderPaidAt($classHeaderPaidAt);
// From account Hide
$this->hideFromAccount = $hideFromAccount;
$this->hideFromAccountTitle = $hideFromAccountTitle;
$this->hideFromAccountName = $hideFromAccountName;
$this->hideFromAccountNumber = $hideFromAccountNumber;
$this->hideFromAccountBankName = $hideFromAccountBankName;
$this->hideFromAccountBankPhone = $hideFromAccountBankPhone;
$this->hideFromAccountBankAddress = $hideFromAccountBankAddress;
// From account text
$this->textFromAccountTitle = $this->getTextFromAccountTitle($textFromAccountTitle);
$this->textFromAccountNumber = $this->getTextFromAccountNumber($textFromAccountNumber);
// To account Hide
$this->hideToAccount = $hideToAccount;
$this->hideToAccountTitle = $hideToAccountTitle;
$this->hideToAccountName = $hideToAccountName;
$this->hideToAccountNumber = $hideToAccountNumber;
$this->hideToAccountBankName = $hideToAccountBankName;
$this->hideToAccountBankPhone = $hideToAccountBankPhone;
$this->hideToAccountBankAddress = $hideToAccountBankAddress;
// To account text
$this->textToAccountTitle = $this->getTextToAccountTitle($textToAccountTitle);
$this->textToAccountNumber = $this->getTextToAccountNumber($textToAccountNumber);
// Detail Information Hide checker
$this->hideDetails = $hideDetails;
$this->hideDetailTitle = $hideDetailTitle;
$this->hideDetailDate = $hideDetailDate;
$this->hideDetailPaymentMethod = $hideDetailPaymentMethod;
$this->hideDetailReference = $hideDetailReference;
$this->hideDetailDescription = $hideDetailDescription;
$this->hideDetailAmount = $hideDetailAmount;
// Related Information Text
$this->textDetailTitle = $this->getTextDetailTitle($textDetailTitle);
$this->textDetailDate = $this->getTextDetailDate($textDetailDate);
$this->textDetailPaymentMethod = $this->getTextDetailPaymentMethod($textDetailPaymentMethod);
$this->textDetailReference = $this->getTextDetailReference($textDetailReference);
$this->textDetailDescription = $this->getTextDetailDescription($textDetailDescription);
$this->textDetailAmount = $this->getTextDetailAmount($textDetailAmount);
// Hide Attachment
$this->hideAttachment = $hideAttachment;
// Attachment data..
$this->attachment = '';
if (!empty($attachment)) {
$this->attachment = $attachment;
} else if (!empty($transfer)) {
$this->attachment = $transfer->attachment;
}
// Histories Hide
$this->hideFooter = $hideFooter;
$this->hideFooterHistories = $hideFooterHistories;
// Histories
$this->histories = $this->getHistories($histories);
$this->textHistories = $this->getTextHistories($textHistories);
$this->classFooterHistories = $this->getClassFooterHistories($classFooterHistories);
}
protected function getTransferTemplate($transferTemplate)
{
if (!empty($transferTemplate)) {
return $transferTemplate;
}
return setting('transfer.template');
}
protected function getRouteButtonAddNew($routeButtonAddNew)
{
if (!empty($routeButtonAddNew)) {
return $routeButtonAddNew;
}
return 'transfers.create';
}
protected function getRouteButtonEdit($routeButtonEdit)
{
if (!empty($routeButtonEdit)) {
return $routeButtonEdit;
}
return 'transfers.edit';
}
protected function getRouteButtonDuplicate($routeButtonDuplicate)
{
if (!empty($routeButtonDuplicate)) {
return $routeButtonDuplicate;
}
return 'transfers.duplicate';
}
protected function getRouteButtonPrint($routeButtonPrint)
{
if (!empty($routeButtonPrint)) {
return $routeButtonPrint;
}
return 'transfers.print';
}
protected function getSignedUrl($signedUrl)
{
if (!empty($signedUrl)) {
return $signedUrl;
}
try {
$signedUrl = URL::signedRoute('signed.transfer.show', [$this->transfer->id]);
} catch (\Exception $e) {
$signedUrl = false;
}
return $signedUrl;
}
protected function getRouteButtonEmail($routeButtonEmail)
{
if (!empty($routeButtonEmail)) {
return $routeButtonEmail;
}
return 'transfers.email';
}
protected function getRouteButtonPdf($routeButtonPdf)
{
if (!empty($routeButtonPdf)) {
return $routeButtonPdf;
}
return 'transfers.pdf';
}
protected function getRouteButtonDelete($routeButtonDelete)
{
if (!empty($routeButtonDelete)) {
return $routeButtonDelete;
}
return 'transfers.destroy';
}
protected function getRouteFromAccountShow($routeFromAccountShow)
{
if (!empty($routeFromAccountShow)) {
return $routeFromAccountShow;
}
return 'accounts.show';
}
protected function getRouteToAccountShow($routeToAccountShow)
{
if (!empty($routeToAccountShow)) {
return $routeToAccountShow;
}
return 'accounts.show';
}
protected function getPermissionCreate($permissionCreate)
{
if (!empty($permissionCreate)) {
return $permissionCreate;
}
return 'create-banking-transfers';
}
protected function getPermissionUpdate($permissionUpdate)
{
if (!empty($permissionUpdate)) {
return $permissionUpdate;
}
return 'update-banking-transfers';
}
protected function getPermissionDelete($permissionDelete)
{
if (!empty($permissionDelete)) {
return $permissionDelete;
}
return 'delete-banking-transfers';
}
protected function getTextHeaderFromAccount($textHeaderFromAccount)
{
if (!empty($textHeaderFromAccount)) {
return $textHeaderFromAccount;
}
return 'transfers.from_account';
}
protected function getTextHeaderToAccount($textHeaderToAccount)
{
if (!empty($textHeaderToAccount)) {
return $textHeaderToAccount;
}
return 'transfers.to_account';
}
protected function getTextHeaderAmount($textHeaderAmount)
{
if (!empty($textHeaderAmount)) {
return $textHeaderAmount;
}
return 'general.amount';
}
protected function getTextHeaderPaidAt($textHeaderPaidAt)
{
if (!empty($textHeaderPaidAt)) {
return $textHeaderPaidAt;
}
return 'general.date';
}
protected function getClassHeaderFromAccount($classHeaderFromAccount)
{
if (!empty($classHeaderFromAccount)) {
return $classHeaderFromAccount;
}
return 'col-4 col-lg-2';
}
protected function getClassHeaderToAccount($classHeaderToAccount)
{
if (!empty($classHeaderToAccount)) {
return $classHeaderToAccount;
}
return 'col-4 col-lg-6';
}
protected function getClassHeaderAmount($classHeaderAmount)
{
if (!empty($classHeaderAmount)) {
return $classHeaderAmount;
}
return 'col-4 col-lg-2 float-right';
}
protected function getClassHeaderPaidAt($classHeaderPaidAt)
{
if (!empty($classHeaderPaidAt)) {
return $classHeaderPaidAt;
}
return 'col-4 col-lg-2';
}
protected function getTextFromAccountTitle($textToAccountTitle)
{
if (!empty($textToAccountTitle)) {
return $textToAccountTitle;
}
return 'transfers.from_account';
}
protected function getTextFromAccountNumber($textFromAccountNumber)
{
if (!empty($textFromAccountNumber)) {
return $textFromAccountNumber;
}
return 'accounts.number';
}
protected function getTextToAccountTitle($textFromAccountTitle)
{
if (!empty($textFromAccountTitle)) {
return $textFromAccountTitle;
}
return 'transfers.to_account';
}
protected function getTextToAccountNumber($textToAccountNumber)
{
if (!empty($textToAccountNumber)) {
return $textToAccountNumber;
}
return 'accounts.number';
}
protected function getTextDetailTitle($textDetailTitle)
{
if (!empty($textDetailTitle)) {
return $textDetailTitle;
}
return 'transfers.details';
}
protected function getTextDetailDate($textDetailDate)
{
if (!empty($textDetailDate)) {
return $textDetailDate;
}
return 'general.date';
}
protected function getTextDetailPaymentMethod($textDetailPaymentMethod)
{
if (!empty($textDetailPaymentMethod)) {
return $textDetailPaymentMethod;
}
return 'general.payment_methods';
}
protected function getTextDetailReference($textDetailReference)
{
if (!empty($textDetailReference)) {
return $textDetailReference;
}
return 'general.reference';
}
protected function getTextDetailDescription($textDetailDescription)
{
if (!empty($textDetailDescription)) {
return $textDetailDescription;
}
return 'general.description';
}
protected function getTextDetailAmount($textDetailAmount)
{
if (!empty($textDetailAmount)) {
return $textDetailAmount;
}
return 'general.amount';
}
protected function getHistories($histories)
{
if (!empty($histories)) {
return $histories;
}
$histories[] = $this->transfer;
return $histories;
}
protected function getTextHistories($textHistories)
{
if (!empty($textHistories)) {
return $textHistories;
}
return 'invoices.histories';
}
protected function getClassFooterHistories($classFooterHistories)
{
if (!empty($classFooterHistories)) {
return $classFooterHistories;
}
return 'col-sm-6 col-md-6 col-lg-6 col-xl-6';
}
}

View File

@ -1,278 +0,0 @@
<?php
namespace App\Abstracts\View\Components;
use App\Abstracts\View\Components\Transfer as Base;
use App\Models\Common\Media;
use App\Traits\DateTime;
use App\Traits\Transactions;
use App\Utilities\Modules;
use File;
use Illuminate\Support\Facades\Log;
use Image;
use Intervention\Image\Exception\NotReadableException;
use Storage;
use Illuminate\Support\Str;
use Illuminate\View\Component;
abstract class TransferTemplate extends Component
{
use DateTime;
use Transactions;
public $transfer;
/** @var array */
public $payment_methods;
/** @var bool */
public $hideFromAccount;
/** @var bool */
public $hideFromAccountTitle;
/** @var bool */
public $hideFromAccountName;
/** @var bool */
public $hideFromAccountNumber;
/** @var bool */
public $hideFromAccountBankName;
/** @var bool */
public $hideFromAccountBankPhone;
/** @var bool */
public $hideFromAccountBankAddress;
/** @var string */
public $textFromAccountTitle;
/** @var string */
public $textFromAccountNumber;
/** @var bool */
public $hideToAccount;
/** @var bool */
public $hideToAccountTitle;
/** @var bool */
public $hideToAccountName;
/** @var bool */
public $hideToAccountNumber;
/** @var bool */
public $hideToAccountBankName;
/** @var bool */
public $hideToAccountBankPhone;
/** @var bool */
public $hideToAccountBankAddress;
/** @var string */
public $textToAccountTitle;
/** @var string */
public $textToAccountNumber;
/** @var bool */
public $hideDetails;
/** @var bool */
public $hideDetailTitle;
/** @var bool */
public $hideDetailDate;
/** @var bool */
public $hideDetailPaymentMethod;
/** @var bool */
public $hideDetailReference;
/** @var bool */
public $hideDetailDescription;
/** @var bool */
public $hideDetailAmount;
/** @var string */
public $textDetailTitle;
/** @var string */
public $textDetailDate;
/** @var string */
public $textDetailPaymentMethod;
/** @var string */
public $textDetailReference;
/** @var string */
public $textDetailDescription;
/** @var string */
public $textDetailAmount;
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(
$transfer, array $payment_methods = [],
bool $hideFromAccount = false, bool $hideFromAccountTitle = false, bool $hideFromAccountName = false, bool $hideFromAccountNumber = false,
bool $hideFromAccountBankName = false, bool $hideFromAccountBankPhone = false, bool $hideFromAccountBankAddress = false,
string $textFromAccountTitle = '', string $textFromAccountNumber = '',
bool $hideToAccount = false, bool $hideToAccountTitle = false, bool $hideToAccountName = false, bool $hideToAccountNumber = false,
bool $hideToAccountBankName = false, bool $hideToAccountBankPhone = false, bool $hideToAccountBankAddress = false,
string $textToAccountTitle = '', string $textToAccountNumber = '',
bool $hideDetails = false, bool $hideDetailTitle = false, bool $hideDetailDate = false, bool $hideDetailPaymentMethod = false,
bool $hideDetailReference = false, bool $hideDetailDescription = false, bool $hideDetailAmount = false,
string $textDetailTitle = '', string $textDetailDate = '', string $textDetailPaymentMethod = '', string $textDetailReference = '',
string $textDetailDescription = '', string $textDetailAmount = ''
) {
$this->transfer = $transfer;
$this->payment_methods = ($payment_methods) ?: Modules::getPaymentMethods('all');
// From account Hide
$this->hideFromAccount = $hideFromAccount;
$this->hideFromAccountTitle = $hideFromAccountTitle;
$this->hideFromAccountName = $hideFromAccountName;
$this->hideFromAccountNumber = $hideFromAccountNumber;
$this->hideFromAccountBankName = $hideFromAccountBankName;
$this->hideFromAccountBankPhone = $hideFromAccountBankPhone;
$this->hideFromAccountBankAddress = $hideFromAccountBankAddress;
// From account text
$this->textFromAccountTitle = $this->getTextFromAccountTitle($textFromAccountTitle);
$this->textFromAccountNumber = $this->getTextFromAccountNumber($textFromAccountNumber);
// To account Hide
$this->hideToAccount = $hideToAccount;
$this->hideToAccountTitle = $hideToAccountTitle;
$this->hideToAccountName = $hideToAccountName;
$this->hideToAccountNumber = $hideToAccountNumber;
$this->hideToAccountBankName = $hideToAccountBankName;
$this->hideToAccountBankPhone = $hideToAccountBankPhone;
$this->hideToAccountBankAddress = $hideToAccountBankAddress;
// To account text
$this->textToAccountTitle = $this->getTextToAccountTitle($textToAccountTitle);
$this->textToAccountNumber = $this->getTextToAccountNumber($textToAccountNumber);
// Detail Information Hide checker
$this->hideDetails = $hideDetails;
$this->hideDetailTitle = $hideDetailTitle;
$this->hideDetailDate = $hideDetailDate;
$this->hideDetailPaymentMethod = $hideDetailPaymentMethod;
$this->hideDetailReference = $hideDetailReference;
$this->hideDetailDescription = $hideDetailDescription;
$this->hideDetailAmount = $hideDetailAmount;
// Related Information Text
$this->textDetailTitle = $this->getTextDetailTitle($textDetailTitle);
$this->textDetailDate = $this->getTextDetailDate($textDetailDate);
$this->textDetailPaymentMethod = $this->getTextDetailPaymentMethod($textDetailPaymentMethod);
$this->textDetailReference = $this->getTextDetailReference($textDetailReference);
$this->textDetailDescription = $this->getTextDetailDescription($textDetailDescription);
$this->textDetailAmount = $this->getTextDetailAmount($textDetailAmount);
}
protected function getTextFromAccountTitle($textToAccountTitle)
{
if (!empty($textToAccountTitle)) {
return $textToAccountTitle;
}
return 'transfers.from_account';
}
protected function getTextFromAccountNumber($textFromAccountNumber)
{
if (!empty($textFromAccountNumber)) {
return $textFromAccountNumber;
}
return 'accounts.number';
}
protected function getTextToAccountTitle($textFromAccountTitle)
{
if (!empty($textFromAccountTitle)) {
return $textFromAccountTitle;
}
return 'transfers.to_account';
}
protected function getTextToAccountNumber($textToAccountNumber)
{
if (!empty($textToAccountNumber)) {
return $textToAccountNumber;
}
return 'accounts.number';
}
protected function getTextDetailTitle($textDetailTitle)
{
if (!empty($textDetailTitle)) {
return $textDetailTitle;
}
return 'transfers.details';
}
protected function getTextDetailDate($textDetailDate)
{
if (!empty($textDetailDate)) {
return $textDetailDate;
}
return 'general.date';
}
protected function getTextDetailPaymentMethod($textDetailPaymentMethod)
{
if (!empty($textDetailPaymentMethod)) {
return $textDetailPaymentMethod;
}
return 'general.payment_methods';
}
protected function getTextDetailReference($textDetailReference)
{
if (!empty($textDetailReference)) {
return $textDetailReference;
}
return 'general.reference';
}
protected function getTextDetailDescription($textDetailDescription)
{
if (!empty($textDetailDescription)) {
return $textDetailDescription;
}
return 'general.description';
}
protected function getTextDetailAmount($textDetailAmount)
{
if (!empty($textDetailAmount)) {
return $textDetailAmount;
}
return 'general.amount';
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace App\Abstracts\View\Components\Transfers;
use App\Abstracts\View\Component;
use App\Traits\ViewComponents;
abstract class Show extends Component
{
use ViewComponents;
public $model;
public $transfer;
public $template;
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(
$model = false, $transfer = false, string $template = ''
) {
$this->model = $model;
$this->transfer = $this->getTransfer($model, $transfer);
$this->template = ! empty($template) ? $template : setting('transfer.template');
// Set Parent data
$this->setParentData();
}
protected function getTransfer($model, $transfer)
{
if (! empty($model)) {
return $model;
}
if (! empty($transfer)) {
return $transfer;
}
return false;
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace App\Abstracts\View\Components\Transfers;
use App\Abstracts\View\Component;
use App\Traits\ViewComponents;
abstract class Template extends Component
{
use ViewComponents;
public $model;
public $transfer;
public $template;
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(
$model = false, $transfer = false, string $template = ''
) {
$this->model = $model;
$this->transfer = $this->getTransfer($model, $transfer);
$this->template = ! empty($template) ? $template : setting('transfer.template');
// Set Parent data
$this->setParentData();
}
protected function getTransfer($model, $transfer)
{
if (! empty($model)) {
return $model;
}
if (! empty($transfer)) {
return $transfer;
}
return false;
}
}

View File

@ -2,8 +2,11 @@
namespace App\Abstracts;
use App\Models\Common\Report;
use App\Traits\Charts;
use App\Utilities\Date;
use App\Utilities\Reports;
use Illuminate\Support\Str;
abstract class Widget
{
@ -14,11 +17,15 @@ abstract class Widget
public $default_name = '';
public $default_settings = [
'width' => 'col-md-4',
'width' => 'w-full lg:w-2/4 px-12 my-8',
];
public $description = '';
public $report_class = '';
public $views = [
'header' => 'partials.widgets.standard_header',
'header' => 'components.widgets.header',
];
public function __construct($model = null)
@ -36,6 +43,47 @@ abstract class Widget
return $this->default_settings;
}
public function getDescription()
{
return trans($this->description);
}
public function getReportUrl(): string
{
$empty_url = '';
if (empty($this->report_class)) {
return $empty_url;
}
if (Reports::isModule($this->report_class) && Reports::isModuleDisabled($this->report_class)) {
$alias = Reports::getModuleAlias($this->report_class);
return route('apps.app.show', [
'alias' => $alias,
'utm_source' => 'widget',
'utm_medium' => 'app',
'utm_campaign' => Str::snake(Str::camel($alias)),
]);
}
if (! class_exists($this->report_class)) {
return $empty_url;
}
if (Reports::cannotRead($this->report_class)) {
return $empty_url;
}
$model = Report::where('class', $this->report_class)->first();
if (! $model instanceof Report) {
return route('reports.create');
}
return route('reports.show', $model->id);
}
public function getViews()
{
return $this->views;

73
app/Builders/Category.php Normal file
View File

@ -0,0 +1,73 @@
<?php
namespace App\Builders;
use GeneaLabs\LaravelModelCaching\CachedBuilder;
use Illuminate\Pagination\Paginator;
class Category extends CachedBuilder
{
/**
* Execute the query as a "select" statement.
*
* @param array|string $columns
* @return \Illuminate\Support\Collection
*/
public function get($columns = ['*'])
{
$collection = parent::get($columns);
return $collection->withChildren('sub_categories', function ($list, $parent, $relation, $level, $addChildren) {
$parent->load($relation);
$parent->level = $level;
$list->push($parent);
if ($parent->$relation->count() == 0) {
return;
}
foreach ($parent->$relation as $item) {
$addChildren($list, $item, $relation, $level + 1, $addChildren);
}
});
}
/**
* Get the categories excluding their children.
*
* @param array|string $columns
* @return \Illuminate\Support\Collection
*/
public function getWithoutChildren($columns = ['*'])
{
return parent::get($columns);
}
/**
* Paginate the given query.
*
* @param int|null $perPage
* @param array $columns
* @param string $pageName
* @param int|null $page
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
*
* @throws \InvalidArgumentException
*/
public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
{
$page = $page ?: Paginator::resolveCurrentPage($pageName);
$perPage = $perPage ?: $this->model->getPerPage();
$results = ($total = $this->toBase()->getCountForPagination())
? $this->forPage($page, $perPage)->getWithoutChildren($columns)
: $this->model->newCollection();
return $this->paginator($results, $total, $perPage, $page, [
'path' => Paginator::resolveCurrentPath(),
'pageName' => $pageName,
]);
}
}

View File

@ -1,19 +0,0 @@
<?php
namespace App\BulkActions\Auth;
use App\Abstracts\BulkAction;
use App\Models\Auth\Permission;
class Permissions extends BulkAction
{
public $model = Permission::class;
public $actions = [
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-auth-permissions',
],
];
}

View File

@ -1,19 +0,0 @@
<?php
namespace App\BulkActions\Auth;
use App\Abstracts\BulkAction;
use App\Models\Auth\Role;
class Roles extends BulkAction
{
public $model = Role::class;
public $actions = [
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-auth-roles',
],
];
}

View File

@ -11,21 +11,31 @@ class Users extends BulkAction
{
public $model = User::class;
public $text = 'general.users';
public $path = [
'group' => 'auth',
'type' => 'users',
];
public $actions = [
'enable' => [
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-auth-users',
'enable' => [
'icon' => 'check_circle',
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-auth-users',
],
'disable' => [
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-auth-users',
'disable' => [
'icon' => 'hide_source',
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-auth-users',
],
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-auth-users',
'delete' => [
'icon' => 'delete',
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-auth-users',
],
];

View File

@ -11,21 +11,31 @@ class Accounts extends BulkAction
{
public $model = Account::class;
public $text = 'general.accounts';
public $path = [
'group' => 'banking',
'type' => 'accounts',
];
public $actions = [
'enable' => [
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-banking-accounts',
'enable' => [
'icon' => 'check_circle',
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-banking-accounts',
],
'disable' => [
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-banking-accounts',
'disable' => [
'icon' => 'hide_source',
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-banking-accounts',
],
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-banking-accounts',
'delete' => [
'icon' => 'delete',
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-banking-accounts',
],
];

View File

@ -10,21 +10,31 @@ class Reconciliations extends BulkAction
{
public $model = Reconciliation::class;
public $text = 'general.reconciliations';
public $path = [
'group' => 'banking',
'type' => 'reconciliations',
];
public $actions = [
'reconcile' => [
'name' => 'reconciliations.reconcile',
'message' => 'bulk_actions.message.reconcile',
'permission' => 'update-banking-reconciliations',
'reconcile' => [
'icon' => 'published_with_changes',
'name' => 'reconciliations.reconcile',
'message' => 'bulk_actions.message.reconcile',
'permission' => 'update-banking-reconciliations',
],
'unreconcile' => [
'name' => 'reconciliations.unreconcile',
'message' => 'bulk_actions.message.unreconcile',
'permission' => 'update-banking-reconciliations',
'unreconcile' => [
'icon' => 'layers_clear',
'name' => 'reconciliations.unreconcile',
'message' => 'bulk_actions.message.unreconcile',
'permission' => 'update-banking-reconciliations',
],
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-banking-reconciliations',
'delete' => [
'icon' => 'delete',
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-banking-reconciliations',
],
];

View File

@ -10,16 +10,25 @@ class Transactions extends BulkAction
{
public $model = Transaction::class;
public $text = 'general.transactions';
public $path = [
'group' => 'banking',
'type' => 'transactions',
];
public $actions = [
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-banking-transactions',
'delete' => [
'icon' => 'delete',
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-banking-transactions',
],
'export' => [
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download',
'export' => [
'icon' => 'file_download',
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download',
],
];

View File

@ -11,16 +11,25 @@ class Transfers extends BulkAction
{
public $model = Transfer::class;
public $text = 'general.transfers';
public $path = [
'group' => 'banking',
'type' => 'transfers',
];
public $actions = [
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-banking-transfers',
'delete' => [
'icon' => 'delete',
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-banking-transfers',
],
'export' => [
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download',
'export' => [
'icon' => 'file_download',
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download',
],
];

View File

@ -11,16 +11,25 @@ class Companies extends BulkAction
{
public $model = Company::class;
public $text = 'general.companies';
public $path = [
'group' => 'common',
'type' => 'companies',
];
public $actions = [
'enable' => [
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-common-companies',
'enable' => [
'icon' => 'check_circle',
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-common-companies',
],
'disable' => [
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-common-companies',
'disable' => [
'icon' => 'hide_source',
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-common-companies',
],
];

View File

@ -11,21 +11,31 @@ class Dashboards extends BulkAction
{
public $model = Dashboard::class;
public $text = 'general.dashboards';
public $path = [
'group' => 'common',
'type' => 'dashboards',
];
public $actions = [
'enable' => [
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-common-dashboards',
'enable' => [
'icon' => 'check_circle',
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-common-dashboards',
],
'disable' => [
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-common-dashboards',
'disable' => [
'icon' => 'hide_source',
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-common-dashboards',
],
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-common-dashboards',
'delete' => [
'icon' => 'delete',
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-common-dashboards',
],
];

View File

@ -11,30 +11,41 @@ class Items extends BulkAction
{
public $model = Item::class;
public $text = 'general.items';
public $path = [
'group' => 'common',
'type' => 'items',
];
public $actions = [
'enable' => [
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'path' => ['group' => 'common', 'type' => 'items'],
'type' => '*',
'permission' => 'update-common-items',
'enable' => [
'icon' => 'check_circle',
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'path' => ['group' => 'common', 'type' => 'items'],
'type' => '*',
'permission' => 'update-common-items',
],
'disable' => [
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'path' => ['group' => 'common', 'type' => 'items'],
'type' => '*',
'permission' => 'update-common-items',
'disable' => [
'icon' => 'hide_source',
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'path' => ['group' => 'common', 'type' => 'items'],
'type' => '*',
'permission' => 'update-common-items',
],
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-common-items',
'delete' => [
'icon' => 'delete',
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-common-items',
],
'export' => [
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download',
'export' => [
'icon' => 'file_download',
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download',
],
];

View File

@ -15,46 +15,39 @@ class Bills extends BulkAction
{
public $model = Document::class;
public $actions = [
'paid' => [
'name' => 'bills.mark_paid',
'message' => 'bulk_actions.message.paid',
'permission' => 'update-purchases-bills',
],
'received' => [
'name' => 'bills.mark_received',
'message' => 'bulk_actions.message.received',
'permission' => 'update-purchases-bills',
],
'cancelled' => [
'name' => 'general.cancel',
'message' => 'bulk_actions.message.cancelled',
'permission' => 'update-purchases-bills',
],
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-purchases-bills',
],
'export' => [
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download',
],
public $text = 'general.bills';
public $path = [
'group' => 'purchases',
'type' => 'bills',
];
public function paid($request)
{
$bills = $this->getSelectedRecords($request);
foreach ($bills as $bill) {
if ($bill->status == 'paid') {
continue;
}
$this->dispatch(new CreateBankingDocumentTransaction($bill, ['type' => 'expense']));
}
}
public $actions = [
'received' => [
'icon' => 'send',
'name' => 'bills.mark_received',
'message' => 'bulk_actions.message.received',
'permission' => 'update-purchases-bills',
],
'cancelled' => [
'icon' => 'cancel',
'name' => 'general.cancel',
'message' => 'bulk_actions.message.cancelled',
'permission' => 'update-purchases-bills',
],
'delete' => [
'icon' => 'delete',
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-purchases-bills',
],
'export' => [
'icon' => 'file_download',
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download',
],
];
public function received($request)
{

View File

@ -1,37 +0,0 @@
<?php
namespace App\BulkActions\Purchases;
use App\Abstracts\BulkAction;
use App\Exports\Purchases\Payments as Export;
use App\Models\Banking\Transaction;
class Payments extends BulkAction
{
public $model = Transaction::class;
public $actions = [
'export' => [
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download',
],
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-purchases-payments',
],
];
public function destroy($request)
{
$this->deleteTransactions($request);
}
public function export($request)
{
$selected = $this->getSelectedInput($request);
return $this->exportExcel(new Export($selected), trans_choice('general.payments', 2));
}
}

View File

@ -10,26 +10,37 @@ class Vendors extends BulkAction
{
public $model = Contact::class;
public $text = 'general.vendors';
public $path = [
'group' => 'purchases',
'type' => 'vendors',
];
public $actions = [
'enable' => [
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-purchases-vendors',
'enable' => [
'icon' => 'check_circle',
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-purchases-vendors',
],
'disable' => [
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-purchases-vendors',
'disable' => [
'icon' => 'hide_source',
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-purchases-vendors',
],
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-purchases-vendors',
'delete' => [
'icon' => 'delete',
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-purchases-vendors',
],
'export' => [
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download',
'export' => [
'icon' => 'file_download',
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download',
],
];

View File

@ -10,26 +10,37 @@ class Customers extends BulkAction
{
public $model = Contact::class;
public $text = 'general.customers';
public $path = [
'group' => 'sales',
'type' => 'customers',
];
public $actions = [
'enable' => [
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-sales-customers',
'enable' => [
'icon' => 'check_circle',
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-sales-customers',
],
'disable' => [
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-sales-customers',
'disable' => [
'icon' => 'hide_source',
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-sales-customers',
],
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-sales-customers',
'delete' => [
'icon' => 'delete',
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-sales-customers',
],
'export' => [
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download',
'export' => [
'icon' => 'file_download',
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download',
],
];

View File

@ -15,46 +15,39 @@ class Invoices extends BulkAction
{
public $model = Document::class;
public $actions = [
'paid' => [
'name' => 'invoices.mark_paid',
'message' => 'bulk_actions.message.paid',
'permission' => 'update-sales-invoices',
],
'sent' => [
'name' => 'invoices.mark_sent',
'message' => 'bulk_actions.message.sent',
'permission' => 'update-sales-invoices',
],
'cancelled' => [
'name' => 'general.cancel',
'message' => 'bulk_actions.message.cancelled',
'permission' => 'update-sales-invoices',
],
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-sales-invoices',
],
'export' => [
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download',
],
public $text = 'general.invoices';
public $path = [
'group' => 'sales',
'type' => 'invoices',
];
public function paid($request)
{
$invoices = $this->getSelectedRecords($request);
foreach ($invoices as $invoice) {
if ($invoice->status == 'paid') {
continue;
}
event(new PaymentReceived($invoice, ['type' => 'income']));
}
}
public $actions = [
'sent' => [
'icon' => 'send',
'name' => 'invoices.mark_sent',
'message' => 'bulk_actions.message.sent',
'permission' => 'update-sales-invoices',
],
'cancelled' => [
'icon' => 'cancel',
'name' => 'general.cancel',
'message' => 'bulk_actions.message.cancelled',
'permission' => 'update-sales-invoices',
],
'delete' => [
'icon' => 'delete',
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-sales-invoices',
],
'export' => [
'icon' => 'file_download',
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download',
],
];
public function sent($request)
{

View File

@ -1,37 +0,0 @@
<?php
namespace App\BulkActions\Sales;
use App\Abstracts\BulkAction;
use App\Exports\Sales\Revenues as Export;
use App\Models\Banking\Transaction;
class Revenues extends BulkAction
{
public $model = Transaction::class;
public $actions = [
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-sales-revenues',
],
'export' => [
'name' => 'general.export',
'message' => 'bulk_actions.message.export',
'type' => 'download',
],
];
public function destroy($request)
{
$this->deleteTransactions($request);
}
public function export($request)
{
$selected = $this->getSelectedInput($request);
return $this->exportExcel(new Export($selected), trans_choice('general.revenues', 2));
}
}

View File

@ -11,21 +11,31 @@ class Categories extends BulkAction
{
public $model = Category::class;
public $text = 'general.categories';
public $path = [
'group' => 'settings',
'type' => 'categories',
];
public $actions = [
'enable' => [
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-settings-categories',
'enable' => [
'icon' => 'check_circle',
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-settings-categories',
],
'disable' => [
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-settings-categories',
'disable' => [
'icon' => 'hide_source',
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-settings-categories',
],
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-settings-categories',
'delete' => [
'icon' => 'delete',
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-settings-categories',
],
];

View File

@ -11,21 +11,31 @@ class Currencies extends BulkAction
{
public $model = Currency::class;
public $text = 'general.currencies';
public $path = [
'group' => 'settings',
'type' => 'currencies',
];
public $actions = [
'enable' => [
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-settings-currencies',
'enable' => [
'icon' => 'check_circle',
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-settings-currencies',
],
'disable' => [
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-settings-currencies',
'disable' => [
'icon' => 'hide_source',
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-settings-currencies',
],
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-settings-currencies',
'delete' => [
'icon' => 'delete',
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-settings-currencies',
],
];

View File

@ -11,21 +11,31 @@ class Taxes extends BulkAction
{
public $model = Tax::class;
public $text = 'general.taxes';
public $path = [
'group' => 'settings',
'type' => 'taxes',
];
public $actions = [
'enable' => [
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-settings-taxes',
'enable' => [
'icon' => 'check_circle',
'name' => 'general.enable',
'message' => 'bulk_actions.message.enable',
'permission' => 'update-settings-taxes',
],
'disable' => [
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-settings-taxes',
'disable' => [
'icon' => 'hide_source',
'name' => 'general.disable',
'message' => 'bulk_actions.message.disable',
'permission' => 'update-settings-taxes',
],
'delete' => [
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-settings-taxes',
'delete' => [
'icon' => 'delete',
'name' => 'general.delete',
'message' => 'bulk_actions.message.delete',
'permission' => 'delete-settings-taxes',
],
];

View File

@ -8,6 +8,7 @@ use App\Models\Document\Document;
use App\Notifications\Purchase\Bill as Notification;
use App\Utilities\Date;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder;
class BillReminder extends Command
{
@ -35,22 +36,29 @@ class BillReminder extends Command
// Disable model cache
config(['laravel-model-caching.enabled' => false]);
$today = Date::today();
$start_date = $today->copy()->subWeek()->toDateString() . ' 00:00:00';
$end_date = $today->copy()->addMonth()->toDateString() . ' 23:59:59';
// Get all companies
$companies = Company::enabled()->with('bills')->cursor();
$companies = Company::whereHas('bills', function (Builder $query) use ($start_date, $end_date) {
$query->allCompanies();
$query->whereBetween('due_at', [$start_date, $end_date]);
$query->accrued();
$query->notPaid();
})
->enabled()
->cursor();
foreach ($companies as $company) {
// Has company bills
if (!$company->bills->count()) {
continue;
}
$this->info('Sending bill reminders for ' . $company->name . ' company.');
// Set company
$company->makeCurrent();
// Don't send reminders if disabled
if (!setting('schedule.send_bill_reminder')) {
if (! setting('schedule.send_bill_reminder')) {
$this->info('Bill reminders disabled by ' . $company->name . '.');
continue;
@ -74,9 +82,11 @@ class BillReminder extends Command
$date = Date::today()->addDays($day)->toDateString();
// Get upcoming bills
$bills = Document::bill()->with('contact')->accrued()->notPaid()->due($date)->cursor();
$bills = Document::with('contact')->bill()->accrued()->notPaid()->due($date)->cursor();
foreach ($bills as $bill) {
$this->info($bill->document_number . ' bill reminded.');
try {
event(new DocumentReminded($bill, Notification::class));
} catch (\Throwable $e) {

View File

@ -2,9 +2,10 @@
namespace App\Console\Commands;
use Session;
use App\Utilities\Installer;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
class Install extends Command
{
@ -74,15 +75,17 @@ class Install extends Command
Installer::createDefaultEnvFile();
$this->line('Creating database tables');
if (!$this->createDatabaseTables()) {
if (! $this->createDatabaseTables()) {
return self::CMD_ERROR;
}
$this->line('Creating company');
Installer::createCompany($this->company_name, $this->company_email, $this->locale);
DB::transaction(function () {
$this->line('Creating company');
Installer::createCompany($this->company_name, $this->company_email, $this->locale);
$this->line('Creating admin');
Installer::createUser($this->admin_email, $this->admin_password, $this->locale);
$this->line('Creating admin');
Installer::createUser($this->admin_email, $this->admin_password, $this->locale);
});
$this->line('Applying the final touches');
Installer::finalTouches();

View File

@ -8,6 +8,7 @@ use App\Models\Document\Document;
use App\Notifications\Sale\Invoice as Notification;
use App\Utilities\Date;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder;
class InvoiceReminder extends Command
{
@ -35,22 +36,29 @@ class InvoiceReminder extends Command
// Disable model cache
config(['laravel-model-caching.enabled' => false]);
$today = Date::today();
$start_date = $today->copy()->subMonth()->toDateString() . ' 00:00:00';
$end_date = $today->copy()->addWeek()->toDateString() . ' 23:59:59';
// Get all companies
$companies = Company::enabled()->with('invoices')->cursor();
$companies = Company::whereHas('invoices', function (Builder $query) use ($start_date, $end_date) {
$query->allCompanies();
$query->whereBetween('due_at', [$start_date, $end_date]);
$query->accrued();
$query->notPaid();
})
->enabled()
->cursor();
foreach ($companies as $company) {
// Has company invoices
if (!$company->invoices->count()) {
continue;
}
$this->info('Sending invoice reminders for ' . $company->name . ' company.');
// Set company
$company->makeCurrent();
// Don't send reminders if disabled
if (!setting('schedule.send_invoice_reminder')) {
if (! setting('schedule.send_invoice_reminder')) {
$this->info('Invoice reminders disabled by ' . $company->name . '.');
continue;
@ -74,9 +82,11 @@ class InvoiceReminder extends Command
$date = Date::today()->subDays($day)->toDateString();
// Get upcoming invoices
$invoices = Document::invoice()->with('contact')->accrued()->notPaid()->due($date)->cursor();
$invoices = Document::with('contact')->invoice()->accrued()->notPaid()->due($date)->cursor();
foreach ($invoices as $invoice) {
$this->info($invoice->document_number . ' invoice reminded.');
try {
event(new DocumentReminded($invoice, Notification::class));
} catch (\Throwable $e) {

View File

@ -12,6 +12,9 @@ use App\Models\Common\Recurring;
use App\Models\Document\Document;
use App\Utilities\Date;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class RecurringCheck extends Command
{
@ -36,25 +39,40 @@ class RecurringCheck extends Command
*/
public function handle()
{
// Bind to container
app()->instance(static::class, $this);
// Disable model cache
config(['laravel-model-caching.enabled' => false]);
// Get all recurring
$recurring = Recurring::allCompanies()->with('company')->get();
$recurring = Recurring::with('company')
/*->whereHas('recurable', function (Builder $query) {
$query->allCompanies();
})*/
->active()
->allCompanies()
->cursor();
$this->info('Creating recurring records ' . $recurring->count());
//$this->info('Total recurring: ' . $recurring->count());
$today = Date::today();
foreach ($recurring as $recur) {
if (empty($recur->company)) {
$this->info('Missing company.');
$recur->delete();
continue;
}
$this->info('Creating records for ' . $recur->id . ' recurring...');
$company_name = !empty($recur->company->name) ? $recur->company->name : 'Missing Company Name : ' . $recur->company->id;
$this->info('Creating recurring records for ' . $company_name . ' company...');
// Check if company is disabled
if (!$recur->company->enabled) {
if (! $recur->company->enabled) {
$this->info($company_name . ' company is disabled. Skipping...');
if (Date::parse($recur->company->updated_at)->format('Y-m-d') > Date::now()->subMonth(3)->format('Y-m-d')) {
@ -75,7 +93,7 @@ class RecurringCheck extends Command
}
}
if (!$has_active_users) {
if (! $has_active_users) {
$this->info('No active users for ' . $company_name . ' company. Skipping...');
$recur->delete();
@ -85,31 +103,46 @@ class RecurringCheck extends Command
company($recur->company_id)->makeCurrent();
$today = Date::today();
if (! $model = $recur->recurable) {
$this->info('Missing model.');
$recur->delete();
if (!$model = $recur->recurable) {
continue;
}
$schedules = $recur->getRecurringSchedule();
$children_count = $this->getChildrenCount($model);
$schedules = $recur->getRecurringSchedule();
$schedule_count = $schedules->count();
// All recurring created, including today
if ($children_count > ($schedule_count - 1)) {
$this->info('All recurring created.');
$recur->update(['status' => Recurring::COMPLETE_STATUS]);
continue;
}
// Recur only today
if ($children_count == ($schedule_count - 1)) {
$this->info('Recur only today.');
$this->recur($model, $recur->recurable_type, $today);
$recur->update(['status' => Recurring::COMPLETE_STATUS]);
continue;
}
// Recur all schedules, previously failed
// Don't create records for the future
$schedules = $schedules->endsBefore($recur->getRecurringRuleTomorrowDate());
// Recur all schedules, including the previously failed ones
foreach ($schedules as $schedule) {
$this->info('Recur all schedules.');
$schedule_date = Date::parse($schedule->getStart()->format('Y-m-d'));
$this->recur($model, $recur->recurable_type, $schedule_date);
@ -117,13 +150,16 @@ class RecurringCheck extends Command
}
Company::forgetCurrent();
// Remove from container
app()->forgetInstance(static::class);
}
protected function recur($model, $type, $schedule_date)
{
\DB::transaction(function () use ($model, $type, $schedule_date) {
/** @var Document $clone */
if (!$clone = $this->getClone($model, $schedule_date)) {
DB::transaction(function () use ($model, $type, $schedule_date) {
/** @var Document|Transaction $clone */
if (! $clone = $this->getClone($model, $schedule_date)) {
return;
}
@ -185,13 +221,12 @@ class RecurringCheck extends Command
$clone = $model->duplicate();
$date_field = $this->getDateField($model);
// Days between issued and due date
$diff_days = Date::parse($clone->due_at)->diffInDays(Date::parse($clone->$date_field));
$diff_days = Date::parse($model->due_at)->diffInDays(Date::parse($model->issued_at));
$clone->type = $this->getRealType($clone->type);
$clone->parent_id = $model->id;
$clone->$date_field = $schedule_date->format('Y-m-d');
$clone->issued_at = $schedule_date->format('Y-m-d');
$clone->due_at = $schedule_date->copy()->addDays($diff_days)->format('Y-m-d');
$clone->created_from = 'core::recurring';
$clone->save();
@ -213,6 +248,7 @@ class RecurringCheck extends Command
$clone = $model->duplicate();
$clone->type = $this->getRealType($clone->type);
$clone->parent_id = $model->id;
$clone->paid_at = $schedule_date->format('Y-m-d');
$clone->created_from = 'core::recurring';
@ -230,9 +266,7 @@ class RecurringCheck extends Command
return true;
}
$table = $this->getTable($model);
$already_cloned = \DB::table($table)
$already_cloned = DB::table($model->getTable())
->where('parent_id', $model->id)
->whereDate($date_field, $schedule_date)
->value('id');
@ -247,9 +281,7 @@ class RecurringCheck extends Command
protected function getChildrenCount($model)
{
$table = $this->getTable($model);
return \DB::table($table)
return DB::table($model->getTable())
->where('parent_id', $model->id)
->count();
}
@ -265,14 +297,8 @@ class RecurringCheck extends Command
}
}
protected function getTable($model)
public function getRealType(string $recurring_type): string
{
if ($model instanceof Transaction) {
return 'transactions';
}
if ($model instanceof Document) {
return 'documents';
}
return Str::replace('-recurring', '', $recurring_type);
}
}

View File

@ -1,83 +0,0 @@
<?php
namespace App\Console\Commands;
use App\Models\Common\Company;
use App\Models\Common\Report;
use App\Utilities\Reports as Utility;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;
class ReportCache extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'report:cache';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Calculate and cache reports';
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
// Disable model cache
config(['laravel-model-caching.enabled' => false]);
// Get all companies
$companies = Company::enabled()->withCount('reports')->cursor();
foreach ($companies as $company) {
// Has company reports
if (!$company->reports_count) {
continue;
}
$this->info('Calculating reports for ' . $company->name . ' company.');
// Set company
$company->makeCurrent();
$this->cacheReportsOfCurrentCompany();
}
Company::forgetCurrent();
}
protected function cacheReportsOfCurrentCompany()
{
$reports = Report::orderBy('name')->get();
foreach ($reports as $report) {
try {
$class = Utility::getClassInstance($report, false);
if (empty($class)) {
continue;
}
$ttl = 3600 * 6; // 6 hours
Cache::forget('reports.totals.' . $report->id);
Cache::remember('reports.totals.' . $report->id, $ttl, function () use ($class) {
return $class->getGrandTotal();
});
} catch (\Throwable $e) {
$this->error($e->getMessage());
report($e);
}
}
}
}

2
app/Console/Commands/SampleData.php Executable file → Normal file
View File

@ -12,7 +12,7 @@ class SampleData extends Command
*
* @var string
*/
protected $signature = 'sample-data:seed {--count=100 : total records for each item}';
protected $signature = 'sample-data:seed {--count=100 : total records for each item} {--company=1 : the company id}';
/**
* The console command description.

View File

@ -0,0 +1,43 @@
<?php
namespace App\Console\Commands;
use App\Events\Install\UpdateFinished;
use Illuminate\Console\Command;
class UpdateDb extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'update:db {alias=core} {company=1} {new=3.0.0} {old=2.1.36}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Allows to update Akaunting database manually';
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$alias = $this->argument('alias');
$company_id = $this->argument('company');
$new = $this->argument('new');
$old = $this->argument('old');
company($company_id)->makeCurrent();
// Disable model cache during update
config(['laravel-model-caching.enabled' => false]);
event(new UpdateFinished($alias, $new, $old));
}
}

View File

@ -29,7 +29,6 @@ class Kernel extends ConsoleKernel
$schedule_time = config('app.schedule_time');
$schedule->command('report:cache')->everySixHours();
$schedule->command('reminder:invoice')->dailyAt($schedule_time);
$schedule->command('reminder:bill')->dailyAt($schedule_time);
$schedule->command('recurring:check')->dailyAt($schedule_time);

View File

@ -2,7 +2,7 @@
namespace $NAMESPACE$;
use Illuminate\View\Component;
use App\Abstracts\View\Component;
class $CLASS$ extends Component
{

View File

@ -2,16 +2,16 @@
"private": true,
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch-poll": "npm run watch -- --watch-poll",
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
"production": "mix --production"
},
"devDependencies": {
"cross-env": "^5.2.1",
"laravel-mix": "^4.1.4",
"laravel-mix-merge-manifest": "^0.1.2"
"laravel-mix": "^6.0.39",
"resolve-url-loader": "^5.0.0"
}
}

View File

@ -14,6 +14,7 @@ class $NAME$ extends Provider
*/
public function register()
{
//$this->loadConfig();
$this->loadRoutes();
}
@ -28,7 +29,6 @@ class $NAME$ extends Provider
$this->loadViewComponents();
$this->loadTranslations();
$this->loadMigrations();
//$this->loadConfig();
}
/**

View File

@ -1,9 +1,9 @@
@extends('layouts.admin')
<x-layouts.admin>
<x-slot name="content">
<h1>Hello World</h1>
@section('content')
<h1>Hello World</h1>
<p>
This view is loaded from module: {!! config('$ALIAS$.name') !!}
</p>
@stop
<p>
This view is loaded from module: {!! config('$ALIAS$.name') !!}
</p>
</x-slot>
</x-layouts.admin>

View File

@ -11,5 +11,10 @@ const mix = require('laravel-mix');
|
*/
mix.js('Resources/assets/js/$ALIAS$.js', 'Resources/assets/js/$ALIAS$.min.js')
.sass('./../../resources/assets/sass/argon.scss', './../../public/css');
mix.options({
terser: {
extractComments: false,
}
})
.js('Resources/assets/js/$ALIAS$.js', 'Resources/assets/js/$ALIAS$.min.js')
.vue();

View File

@ -0,0 +1,20 @@
<?php
namespace App\Events\Auth;
use App\Abstracts\Event;
class InvitationCreated extends Event
{
public $invitation;
/**
* Create a new event instance.
*
* @param $invitation
*/
public function __construct($invitation)
{
$this->invitation = $invitation;
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Events\Auth;
use App\Abstracts\Event;
class RoleCreated extends Event
{
public $role;
public $request;
/**
* Create a new event instance.
*
* @param $role
* @param $request
*/
public function __construct($role, $request)
{
$this->role = $role;
$this->request = $request;
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Events\Auth;
use Illuminate\Queue\SerializesModels;
class RoleCreating
{
use SerializesModels;
public $request;
/**
* Create a new event instance.
*
* @param $request
*/
public function __construct($request)
{
$this->request = $request;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Events\Auth;
use App\Abstracts\Event;
class RoleDeleted extends Event
{
public $role;
/**
* Create a new event instance.
*
* @param $role
*/
public function __construct($role)
{
$this->role = $role;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Events\Auth;
use App\Abstracts\Event;
class RoleDeleting extends Event
{
public $role;
/**
* Create a new event instance.
*
* @param $role
*/
public function __construct($role)
{
$this->role = $role;
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Events\Auth;
use App\Abstracts\Event;
class RoleUpdated extends Event
{
public $role;
public $request;
/**
* Create a new event instance.
*
* @param $role
* @param $request
*/
public function __construct($role, $request)
{
$this->role = $role;
$this->request = $request;
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Events\Auth;
use App\Abstracts\Event;
class RoleUpdating extends Event
{
public $role;
public $request;
/**
* Create a new event instance.
*
* @param $role
* @param $request
*/
public function __construct($role, $request)
{
$this->role = $role;
$this->request = $request;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Events\Auth;
use App\Abstracts\Event;
class UserDeleted extends Event
{
public $user;
/**
* Create a new event instance.
*
* @param $user
*/
public function __construct($user)
{
$this->user = $user;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Events\Auth;
use App\Abstracts\Event;
class UserDeleting extends Event
{
public $user;
/**
* Create a new event instance.
*
* @param $user
*/
public function __construct($user)
{
$this->user = $user;
}
}

View File

@ -3,6 +3,7 @@
namespace App\Events\Banking;
use App\Abstracts\Event;
use App\Models\Banking\Transaction;
class TransactionCreated extends Event
{
@ -13,7 +14,7 @@ class TransactionCreated extends Event
*
* @param $transaction
*/
public function __construct($transaction)
public function __construct(Transaction $transaction)
{
$this->transaction = $transaction;
}

View File

@ -3,9 +3,12 @@
namespace App\Events\Document;
use App\Abstracts\Event;
use App\Traits\Transactions;
class PaymentReceived extends Event
{
use Transactions;
public $document;
public $request;
@ -18,6 +21,11 @@ class PaymentReceived extends Event
public function __construct($document, $request = [])
{
$this->document = $document;
if (empty($request['number'])) {
$request['number'] = $this->getNextTransactionNumber();
}
$this->request = $request;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Events\Menu;
use App\Abstracts\Event;
class NewwCreated extends Event
{
public $menu;
/**
* Create a new event instance.
*
* @param $menu
*/
public function __construct($menu)
{
$this->menu = $menu;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Events\Menu;
use App\Abstracts\Event;
class NotificationsCreated extends Event
{
public $notifications;
/**
* Create a new event instance.
*
* @param $notifications
*/
public function __construct($notifications)
{
$this->notifications = $notifications;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Events\Menu;
use App\Abstracts\Event;
class ProfileCreated extends Event
{
public $menu;
/**
* Create a new event instance.
*
* @param $menu
*/
public function __construct($menu)
{
$this->menu = $menu;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Events\Menu;
use App\Abstracts\Event;
class SettingsCreated extends Event
{
public $menu;
/**
* Create a new event instance.
*
* @param $menu
*/
public function __construct($menu)
{
$this->menu = $menu;
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Events\Module;
use App\Abstracts\Event;
class Disabling extends Event
{
public $alias;
public $company_id;
/**
* Create a new event instance.
*
* @param $alias
* @param $company_id
*/
public function __construct($alias, $company_id)
{
$this->alias = $alias;
$this->company_id = $company_id;
}
}

View File

@ -1,20 +0,0 @@
<?php
namespace App\Events\Module;
use App\Abstracts\Event;
class SettingShowing extends Event
{
public $modules;
/**
* Create a new event instance.
*
* @param $modules
*/
public function __construct($modules)
{
$this->modules = $modules;
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Events\Module;
use App\Abstracts\Event;
class Uninstalling extends Event
{
public $alias;
public $company_id;
/**
* Create a new event instance.
*
* @param $alias
* @param $company_id
*/
public function __construct($alias, $company_id)
{
$this->alias = $alias;
$this->company_id = $company_id;
}
}

View File

@ -2,11 +2,16 @@
namespace App\Exceptions;
use App\Exceptions\Http\Resource as ResourceException;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\Exceptions\ThrottleRequestsException;
use Illuminate\Http\Response;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Symfony\Component\Debug\Exception\FatalThrowableError;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Throwable;
@ -55,8 +60,12 @@ class Handler extends ExceptionHandler
*/
public function render($request, Throwable $exception)
{
if ($request->isApi()) {
return $this->handleApiExceptions($request, $exception);
}
if (config('app.debug') === false) {
return $this->handleExceptions($request, $exception);
return $this->handleWebExceptions($request, $exception);
}
return parent::render($request, $exception);
@ -81,7 +90,7 @@ class Handler extends ExceptionHandler
: redirect()->to($exception->redirectTo() ?? route('login'));
}
private function handleExceptions($request, $exception)
protected function handleWebExceptions($request, $exception)
{
if ($exception instanceof NotFoundHttpException) {
// ajax 404 json feedback
@ -137,4 +146,142 @@ class Handler extends ExceptionHandler
return parent::render($request, $exception);
}
protected function handleApiExceptions($request, $exception): Response
{
$replacements = $this->prepareApiReplacements($exception);
$response = config('api.error_format');
array_walk_recursive($response, function (&$value, $key) use ($replacements) {
if (Str::startsWith($value, ':') && isset($replacements[$value])) {
$value = $replacements[$value];
}
});
$response = $this->recursivelyRemoveEmptyApiReplacements($response);
return new Response($response, $this->getStatusCode($exception), $this->getHeaders($exception));
}
/**
* Prepare the replacements array by gathering the keys and values.
*
* @param Throwable $exception
*
* @return array
*/
protected function prepareApiReplacements(Throwable $exception): array
{
$code = $this->getStatusCode($exception);
if (! $message = $exception->getMessage()) {
$message = sprintf('%d %s', $code, Response::$statusTexts[$code]);
}
$replacements = [
':message' => $message,
':status_code' => $code,
];
if ($exception instanceof ResourceException && $exception->hasErrors()) {
$replacements[':errors'] = $exception->getErrors();
}
if ($exception instanceof ValidationException) {
$replacements[':errors'] = $exception->errors();
$replacements[':status_code'] = $exception->status;
}
if ($code = $exception->getCode()) {
$replacements[':code'] = $code;
}
if (config('api.debug')) {
$replacements[':debug'] = [
'line' => $exception->getLine(),
'file' => $exception->getFile(),
'class' => get_class($exception),
'trace' => explode("\n", $exception->getTraceAsString()),
];
// Attach trace of previous exception, if exists
if (! is_null($exception->getPrevious())) {
$currentTrace = $replacements[':debug']['trace'];
$replacements[':debug']['trace'] = [
'previous' => explode("\n", $exception->getPrevious()->getTraceAsString()),
'current' => $currentTrace,
];
}
}
return $replacements;
}
/**
* Recursively remove any empty replacement values in the response array.
*
* @param array $input
*
* @return array
*/
protected function recursivelyRemoveEmptyApiReplacements(array $input)
{
foreach ($input as &$value) {
if (is_array($value)) {
$value = $this->recursivelyRemoveEmptyApiReplacements($value);
}
}
return array_filter($input, function ($value) {
if (is_string($value)) {
return ! Str::startsWith($value, ':');
}
return true;
});
}
/**
* Get the status code from the exception.
*
* @param Throwable $exception
*
* @return int
*/
protected function getStatusCode(Throwable $exception): int
{
$code = null;
if ($exception instanceof ValidationException) {
$code = $exception->status;
} elseif ($exception instanceof HttpExceptionInterface) {
$code = $exception->getStatusCode();
} else {
// By default throw 500
$code = 500;
}
// Be extra defensive
if ($code < 100 || $code > 599) {
$code = 500;
}
return $code;
}
/**
* Get the headers from the exception.
*
* @param Throwable $exception
*
* @return array
*/
protected function getHeaders(Throwable $exception): array
{
return ($exception instanceof HttpExceptionInterface)
? $exception->getHeaders()
: [];
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\Exceptions\Http;
use Exception;
use Illuminate\Support\MessageBag;
use Symfony\Component\HttpKernel\Exception\HttpException;
class Resource extends HttpException
{
/**
* MessageBag errors.
*
* @var \Illuminate\Support\MessageBag
*/
protected $errors;
/**
* Create a new resource exception instance.
*
* @param string $message
* @param \Illuminate\Support\MessageBag|array $errors
* @param \Exception $previous
* @param array $headers
* @param int $code
*
* @return void
*/
public function __construct($message = null, $errors = null, Exception $previous = null, $headers = [], $code = 0)
{
if (is_null($errors)) {
$this->errors = new MessageBag;
} else {
$this->errors = is_array($errors) ? new MessageBag($errors) : $errors;
}
parent::__construct(422, $message, $previous, $headers, $code);
}
/**
* Get the errors message bag.
*
* @return \Illuminate\Support\MessageBag
*/
public function getErrors()
{
return $this->errors;
}
/**
* Determine if message bag has any errors.
*
* @return bool
*/
public function hasErrors()
{
return ! $this->errors->isEmpty();
}
}

View File

@ -11,7 +11,7 @@ class Transactions extends Export implements WithColumnFormatting
{
public function collection()
{
return Model::with('account', 'category', 'contact', 'document')->collectForExport($this->ids, ['paid_at' => 'desc']);
return Model::with('account', 'category', 'contact', 'document')->isNotRecurring()->collectForExport($this->ids, ['paid_at' => 'desc']);
}
public function map($model): array
@ -28,6 +28,7 @@ class Transactions extends Export implements WithColumnFormatting
{
return [
'type',
'number',
'paid_at',
'amount',
'currency_code',

View File

@ -23,6 +23,7 @@ class Items extends Export
{
return [
'name',
'type',
'description',
'sale_price',
'purchase_price',

View File

@ -1,51 +0,0 @@
<?php
namespace App\Exports\Purchases;
use App\Abstracts\Export;
use App\Models\Banking\Transaction as Model;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
class Payments extends Export implements WithColumnFormatting
{
public function collection()
{
return Model::with('account', 'bill', 'category', 'contact')->expense()->collectForExport($this->ids, ['paid_at' => 'desc']);
}
public function map($model): array
{
$model->account_name = $model->account->name;
$model->bill_number = $model->bill->document_number ?? 0;
$model->contact_email = $model->contact->email;
$model->category_name = $model->category->name;
return parent::map($model);
}
public function fields(): array
{
return [
'paid_at',
'amount',
'currency_code',
'currency_rate',
'account_name',
'bill_number',
'contact_email',
'category_name',
'description',
'payment_method',
'reference',
'reconciled',
];
}
public function columnFormats(): array
{
return [
'A' => NumberFormat::FORMAT_DATE_YYYYMMDD,
];
}
}

View File

@ -26,6 +26,7 @@ class BillTransactions extends Export implements WithColumnFormatting
$model->account_name = $model->account->name;
$model->category_name = $model->category->name;
$model->contact_email = $model->contact->email;
$model->transaction_number = $model->number;
return parent::map($model);
}
@ -34,6 +35,7 @@ class BillTransactions extends Export implements WithColumnFormatting
{
return [
'bill_number',
'transaction_number',
'paid_at',
'amount',
'currency_code',

View File

@ -11,7 +11,7 @@ class Bills extends Export implements WithColumnFormatting
{
public function collection()
{
return Model::with('category')->bill()->collectForExport($this->ids, ['document_number' => 'desc']);
return Model::with('category')->bill()->isNotRecurring()->collectForExport($this->ids, ['document_number' => 'desc']);
}
public function map($model): array

View File

@ -1,51 +0,0 @@
<?php
namespace App\Exports\Sales;
use App\Abstracts\Export;
use App\Models\Banking\Transaction as Model;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
class Revenues extends Export implements WithColumnFormatting
{
public function collection()
{
return Model::with('account', 'category', 'contact', 'invoice')->income()->collectForExport($this->ids, ['paid_at' => 'desc']);
}
public function map($model): array
{
$model->account_name = $model->account->name;
$model->invoice_number = $model->invoice->document_number ?? 0;
$model->contact_email = $model->contact->email;
$model->category_name = $model->category->name;
return parent::map($model);
}
public function fields(): array
{
return [
'paid_at',
'amount',
'currency_code',
'currency_rate',
'account_name',
'invoice_number',
'contact_email',
'category_name',
'description',
'payment_method',
'reference',
'reconciled',
];
}
public function columnFormats(): array
{
return [
'A' => NumberFormat::FORMAT_DATE_YYYYMMDD,
];
}
}

Some files were not shown because too many files have changed in this diff Show More