diff --git a/app/Abstracts/Http/Controller.php b/app/Abstracts/Http/Controller.php index 8d1beb69d..40f7153e6 100644 --- a/app/Abstracts/Http/Controller.php +++ b/app/Abstracts/Http/Controller.php @@ -153,4 +153,54 @@ abstract class Controller extends BaseController } } } + + public function setActiveTabForCategories(): void + { + if (! request()->has('list_records') && ! request()->has('search')) { + $tab_pins = setting('favorites.tab.' . user()->id, []); + $tab_pins = ! empty($tab_pins) ? json_decode($tab_pins, true) : []; + + if (! empty($tab_pins) && ! empty($tab_pins['categories'])) { + $tab = $tab_pins['categories']; + + if (! empty($tab)) { + + request()->offsetSet('list_records', $tab); + request()->offsetSet('programmatic', '1'); + } + } + } + + if (request()->get('list_records') == 'all') { + return; + } + + $types = $this->getSearchStringValue('type'); + + if (!empty($types)) { + $types = is_string($types) ? explode(',', $types) : $types; + + $tab = config('type.category.' . $types[0] . '.group') ? config('type.category.' . $types[0] . '.group') : 'all'; + + if (!empty($types) && count($types) > 0) { + request()->offsetSet('list_records', $tab); + + $currentSearch = request('search', ''); + $searchParts = array_filter(explode(' ', $currentSearch), function($part) { + return !empty(trim($part)) && !str_starts_with(trim($part), 'type:'); + }); + + $searchParts[] = 'type:' . implode(',', $types); + + request()->offsetSet('search', implode(' ', $searchParts)); + request()->offsetSet('programmatic', '1'); + return; + } + } + + if (empty($tab)) { + request()->offsetSet('list_records', 'all'); + request()->offsetSet('programmatic', '1'); + } + } } diff --git a/app/Http/Controllers/Settings/Categories.php b/app/Http/Controllers/Settings/Categories.php index dd71fa3eb..91be4b6ce 100644 --- a/app/Http/Controllers/Settings/Categories.php +++ b/app/Http/Controllers/Settings/Categories.php @@ -12,10 +12,11 @@ use App\Jobs\Setting\DeleteCategory; use App\Jobs\Setting\UpdateCategory; use App\Models\Setting\Category; use App\Traits\Categories as Helper; +use App\Traits\Modules; class Categories extends Controller { - use Helper; + use Helper, Modules; /** * Display a listing of the resource. @@ -24,17 +25,44 @@ class Categories extends Controller */ public function index() { + $this->setActiveTabForCategories(); + $query = Category::with('sub_categories'); - if (request()->has('search')) { - $query->withSubcategory(); + if (search_string_value('searchable')) { + $query->withSubCategory(); } $types = $this->getCategoryTypes(); - $categories = $query->type(array_keys($types))->collect(); + if (request()->get('list_records') == 'all') { + $query->type(array_keys($types)); + } - return $this->response('settings.categories.index', compact('categories', 'types')); + $categories = $query->collect(); + + $tabs = $this->getCategoryTabs(); + + $tab = request()->get('list_records'); + $tab_active = ! empty($tab) ? 'categories-' . $tab : 'categories-all'; + + $hide_code_column = true; + + $search_string_type = search_string_value('type'); + $selected_types = ! empty($search_string_type) ? explode(',', $search_string_type) : array_keys($types); + + foreach (config('type.category', []) as $type => $config) { + if (! in_array($type, $selected_types)) { + continue; + } + + if (empty($config['hide']) || !in_array('code', $config['hide'])) { + $hide_code_column = false; + break; + } + } + + return $this->response('settings.categories.index', compact('categories', 'types', 'tabs', 'tab_active', 'hide_code_column')); } /** @@ -54,7 +82,7 @@ class Categories extends Controller */ public function create() { - $types = $this->getCategoryTypes(); + $types = $this->getCategoryTypes(true, true); $categories = []; @@ -62,6 +90,8 @@ class Categories extends Controller $categories[$type] = []; } + $has_code = $this->moduleIsEnabled('double-entry'); + Category::enabled()->orderBy('name')->get()->each(function ($category) use (&$categories) { $categories[$category->type][] = [ 'id' => $category->id, @@ -70,7 +100,7 @@ class Categories extends Controller ]; }); - return view('settings.categories.create', compact('types', 'categories')); + return view('settings.categories.create', compact('types', 'categories', 'has_code')); } /** @@ -134,7 +164,7 @@ class Categories extends Controller */ public function edit(Category $category) { - $types = $this->getCategoryTypes(); + $types = $this->getCategoryTypes(true, true); $type_disabled = (Category::where('type', $category->type)->count() == 1) ?: false; @@ -175,7 +205,9 @@ class Categories extends Controller $parent_categories = $categories[$category->type] ?? []; - return view('settings.categories.edit', compact('category', 'types', 'type_disabled', 'categories', 'parent_categories')); + $has_code = $this->moduleIsEnabled('double-entry'); + + return view('settings.categories.edit', compact('category', 'types', 'type_disabled', 'categories', 'parent_categories', 'has_code')); } /** diff --git a/config/setting.php b/config/setting.php index cb7c480a9..4e79fa0d2 100644 --- a/config/setting.php +++ b/config/setting.php @@ -2,10 +2,11 @@ use App\Models\Common\Contact; use App\Models\Banking\Transaction; +use App\Models\Setting\Category; return [ - /* + /* |-------------------------------------------------------------------------- | Enable / Disable auto save |-------------------------------------------------------------------------- @@ -13,7 +14,7 @@ return [ | Auto-save every time the application shuts down | */ - 'auto_save' => env('SETTING_AUTO_SAVE', false), + 'auto_save' => env('SETTING_AUTO_SAVE', false), /* |-------------------------------------------------------------------------- @@ -31,7 +32,7 @@ return [ 'auto_clear' => env('SETTING_CACHE_AUTO_CLEAR', true), ], - /* + /* |-------------------------------------------------------------------------- | Setting driver |-------------------------------------------------------------------------- @@ -41,9 +42,9 @@ return [ | Supported: "database", "json" | */ - 'driver' => env('SETTING_DRIVER', 'database'), + 'driver' => env('SETTING_DRIVER', 'database'), - /* + /* |-------------------------------------------------------------------------- | Database driver |-------------------------------------------------------------------------- @@ -52,14 +53,14 @@ return [ | the default connection. Set the table and column names. | */ - 'database' => [ - 'connection' => env('SETTING_DATABASE_CONNECTION', null), - 'table' => env('SETTING_DATABASE_TABLE', 'settings'), - 'key' => env('SETTING_DATABASE_KEY', 'key'), - 'value' => env('SETTING_DATABASE_VALUE', 'value'), - ], + 'database' => [ + 'connection' => env('SETTING_DATABASE_CONNECTION', null), + 'table' => env('SETTING_DATABASE_TABLE', 'settings'), + 'key' => env('SETTING_DATABASE_KEY', 'key'), + 'value' => env('SETTING_DATABASE_VALUE', 'value'), + ], - /* + /* |-------------------------------------------------------------------------- | JSON driver |-------------------------------------------------------------------------- @@ -67,11 +68,11 @@ return [ | Options for json driver. Enter the full path to the .json file. | */ - 'json' => [ - 'path' => env('SETTING_JSON_PATH', storage_path('settings.json')), - ], + 'json' => [ + 'path' => env('SETTING_JSON_PATH', storage_path('settings.json')), + ], - /* + /* |-------------------------------------------------------------------------- | Override application config values |-------------------------------------------------------------------------- @@ -83,9 +84,9 @@ return [ | "app.locale" => "settings.locale", | */ - 'override' => [ + 'override' => [ - ], + ], /* |-------------------------------------------------------------------------- @@ -168,6 +169,14 @@ return [ 'bill_days' => env('SETTING_FALLBACK_SCHEDULE_BILL_DAYS', '10,5,3,1'), 'time' => env('SETTING_FALLBACK_SCHEDULE_TIME', '09:00'), ], + 'category' => [ + 'type' => [ + 'income' => env('SETTING_FALLBACK_CATEGORY_TYPE_INCOME', Category::INCOME_TYPE), + 'expense' => env('SETTING_FALLBACK_CATEGORY_TYPE_EXPENSE', Category::EXPENSE_TYPE), + 'item' => env('SETTING_FALLBACK_CATEGORY_TYPE_ITEM', Category::ITEM_TYPE), + 'other' => env('SETTING_FALLBACK_CATEGORY_TYPE_OTHER', Category::OTHER_TYPE), + ], + ], 'contact' => [ 'type' => [ 'customer' => env('SETTING_FALLBACK_CONTACT_TYPE_CUSTOMER', Contact::CUSTOMER_TYPE), diff --git a/config/type.php b/config/type.php index c77f0217b..91b1bd7ca 100644 --- a/config/type.php +++ b/config/type.php @@ -10,31 +10,39 @@ return [ // Categories 'category' => [ Category::INCOME_TYPE => [ - 'alias' => '', + 'alias' => '', + 'group' => Category::INCOME_TYPE, 'translation' => [ 'prefix' => 'general', ], + 'hide' => ['code'], ], Category::EXPENSE_TYPE => [ - 'alias' => '', + 'alias' => '', + 'group' => Category::EXPENSE_TYPE, 'translation' => [ 'prefix' => 'general', ], + 'hide' => ['code'], ], Category::ITEM_TYPE => [ - 'alias' => '', + 'alias' => '', + 'group' => Category::ITEM_TYPE, 'translation' => [ 'prefix' => 'general', ], + 'hide' => ['code'], ], Category::OTHER_TYPE => [ - 'alias' => '', + 'alias' => '', + 'group' => Category::OTHER_TYPE, 'translation' => [ 'prefix' => 'general', ], + 'hide' => ['code'], ], ], @@ -58,9 +66,9 @@ return [ 'section_billing_description' => 'customers.form_description.billing', 'section_address_description' => 'customers.form_description.address', ], - 'category_type' => 'income', - 'document_type' => 'invoice', - 'transaction_type' => 'income', + 'category_type' => Category::INCOME_TYPE, + 'document_type' => Document::INVOICE_TYPE, + 'transaction_type' => Transaction::INCOME_TYPE, 'hide' => [], 'class' => [], 'script' => [ @@ -87,9 +95,9 @@ return [ 'section_billing_description' => 'vendors.form_description.billing', 'section_address_description' => 'vendors.form_description.address', ], - 'category_type' => 'expense', - 'document_type' => 'bill', - 'transaction_type' => 'expense', + 'category_type' => Category::EXPENSE_TYPE, + 'document_type' => Document::BILL_TYPE, + 'transaction_type' => Transaction::EXPENSE_TYPE, 'hide' => [], 'class' => [], 'script' => [ @@ -130,9 +138,9 @@ return [ 'setting' => [ 'prefix' => 'invoice', ], - 'category_type' => 'income', - 'transaction_type' => 'income', - 'contact_type' => 'customer', // use contact type + 'category_type' => Category::INCOME_TYPE, + 'transaction_type' => Transaction::INCOME_TYPE, + 'contact_type' => Contact::CUSTOMER_TYPE, // use contact type 'inventory_stock_action' => 'decrease', // decrease stock in stock tracking 'transaction' => [ 'email_template' => 'invoice_payment_customer', // use email template @@ -185,9 +193,9 @@ return [ 'setting' => [ 'prefix' => 'invoice', ], - 'category_type' => 'income', - 'transaction_type' => 'income', - 'contact_type' => 'customer', // use contact type + 'category_type' => Category::INCOME_TYPE, + 'transaction_type' => Transaction::INCOME_TYPE, + 'contact_type' => Contact::CUSTOMER_TYPE, // use contact type 'inventory_stock_action' => 'decrease', // decrease stock in stock tracking 'hide' => [], // for document items 'class' => [], @@ -235,9 +243,9 @@ return [ 'setting' => [ 'prefix' => 'bill', ], - 'category_type' => 'expense', - 'transaction_type' => 'expense', - 'contact_type' => 'vendor', + 'category_type' => Category::EXPENSE_TYPE, + 'transaction_type' => Transaction::EXPENSE_TYPE, + 'contact_type' => Contact::VENDOR_TYPE, 'inventory_stock_action' => 'increase', // increases stock in stock tracking 'transaction' => [ 'email_template' => 'invoice_payment_customer', // use email template @@ -288,9 +296,9 @@ return [ 'setting' => [ 'prefix' => 'bill', ], - 'category_type' => 'expense', - 'transaction_type' => 'expense', - 'contact_type' => 'vendor', + 'category_type' => Category::EXPENSE_TYPE, + 'transaction_type' => Transaction::EXPENSE_TYPE, + 'contact_type' => Contact::VENDOR_TYPE, 'inventory_stock_action' => 'increase', // increases stock in stock tracking 'hide' => [], 'class' => [], @@ -334,8 +342,9 @@ return [ 'related_document_amount' => 'invoices.invoice_amount', 'transactions' => 'general.incomes', ], - 'contact_type' => 'customer', - 'document_type' => 'invoice', + 'category_type' => Category::INCOME_TYPE, + 'contact_type' => Contact::CUSTOMER_TYPE, + 'document_type' => Document::INVOICE_TYPE, 'split_type' => Transaction::INCOME_SPLIT_TYPE, 'email_template' => 'payment_received_customer', 'script' => [ @@ -343,7 +352,7 @@ return [ 'file' => 'transactions', ], ], - + Transaction::INCOME_TYPE => [ 'group' => 'banking', 'route' => [ @@ -365,8 +374,9 @@ return [ 'related_document_amount' => 'invoices.invoice_amount', 'transactions' => 'general.incomes', ], - 'contact_type' => 'customer', - 'document_type' => 'invoice', + 'category_type' => Category::INCOME_TYPE, + 'contact_type' => Contact::CUSTOMER_TYPE, + 'document_type' => Document::INVOICE_TYPE, 'split_type' => Transaction::INCOME_SPLIT_TYPE, 'email_template' => 'payment_received_customer', 'script' => [ @@ -396,8 +406,9 @@ return [ 'related_document_amount' => 'invoices.invoice_amount', 'transactions' => 'general.incomes', ], - 'contact_type' => 'customer', - 'document_type' => 'invoice', + 'category_type' => Category::INCOME_TYPE, + 'contact_type' => Contact::CUSTOMER_TYPE, + 'document_type' => Document::INVOICE_TYPE, 'split_type' => Transaction::INCOME_SPLIT_TYPE, 'email_template' => 'payment_received_customer', 'script' => [ @@ -427,8 +438,9 @@ return [ 'related_document_amount' => 'invoices.invoice_amount', 'transactions' => 'general.incomes', ], - 'contact_type' => 'customer', - 'document_type' => 'invoice', + 'category_type' => Category::INCOME_TYPE, + 'contact_type' => Contact::CUSTOMER_TYPE, + 'document_type' => Document::INVOICE_TYPE, 'email_template' => 'payment_received_customer', 'script' => [ 'folder' => 'banking', @@ -489,8 +501,9 @@ return [ 'prefix' => 'transactions', // this translation file name. 'related_document_amount' => 'bills.bill_amount', ], - 'contact_type' => 'vendor', - 'document_type' => 'bill', + 'category_type' => Category::EXPENSE_TYPE, + 'contact_type' => Contact::VENDOR_TYPE, + 'document_type' => Document::BILL_TYPE, 'split_type' => Transaction::EXPENSE_SPLIT_TYPE, 'email_template' => 'payment_made_vendor', 'script' => [ @@ -519,8 +532,9 @@ return [ 'prefix' => 'transactions', // this translation file name. 'related_document_amount' => 'bills.bill_amount', ], - 'contact_type' => 'vendor', - 'document_type' => 'bill', + 'category_type' => Category::EXPENSE_TYPE, + 'contact_type' => Contact::VENDOR_TYPE, + 'document_type' => Document::BILL_TYPE, 'split_type' => Transaction::EXPENSE_SPLIT_TYPE, 'email_template' => 'payment_made_vendor', 'script' => [ @@ -549,8 +563,9 @@ return [ 'prefix' => 'transactions', // this translation file name. 'related_document_amount' => 'bills.bill_amount', ], - 'contact_type' => 'vendor', - 'document_type' => 'bill', + 'category_type' => Category::EXPENSE_TYPE, + 'contact_type' => Contact::VENDOR_TYPE, + 'document_type' => Document::BILL_TYPE, 'email_template' => 'payment_made_vendor', 'script' => [ 'folder' => 'banking', diff --git a/resources/views/settings/categories/index.blade.php b/resources/views/settings/categories/index.blade.php index 1a971b143..6c6ef9379 100644 --- a/resources/views/settings/categories/index.blade.php +++ b/resources/views/settings/categories/index.blade.php @@ -37,95 +37,167 @@ - - - - - - - - - - - - - - - - - - - - - @foreach($categories as $item) - - - - - - -
- @if ($item->sub_categories->count()) - - - - -
- {{ $item->name }} -
-
- @else -
- circle - - - {{ $item->name }} - -
- @endif - - @if (! $item->enabled) - - @endif -
- - - @if (! empty($types[$item->type])) - {{ $types[$item->type] }} - @else - - @endif - - - - - -
- - @foreach($item->sub_categories as $sub_category) - @include('settings.categories.sub_category', ['parent_category' => $item, 'sub_category' => $sub_category, 'tree_level' => 1]) - @endforeach + + + @foreach($tabs as $tab => $data) + @if ($tab_active == $tab) + + @else + + @endif @endforeach -
-
- + @if ($tab_active == 'categories-all') + + @else + + @endif +
+ + + @php + $name_class = $hide_code_column ? 'w-5/12' : 'w-4/12'; + @endphp + + + + + + + + + + + + @if (!$hide_code_column) + + + + @endif + + + + + + + + + + + {{ trans('general.balance') }} + + + + + + @foreach($categories as $item) + + + + + + @if (!$hide_code_column) + + @if(!empty($item->code)) + {{ $item->code }} + @else + + @endif + + @endif + + +
+ @if ($item->sub_categories->count()) + + + + +
+ {{ $item->name }} +
+
+ @else +
+ circle + + + {{ $item->name }} + +
+ @endif + + @if (! $item->enabled) + + @endif +
+ + + @if (! empty($types[$item->type])) + {{ $types[$item->type] }} + @else + + @endif + + + + + + + + + +
+ + @foreach($item->sub_categories as $sub_category) + @include('settings.categories.sub_category', ['parent_category' => $item, 'sub_category' => $sub_category, 'tree_level' => 1, 'hide_code_column' => $hide_code_column, 'name_class' => $name_class]) + @endforeach + @endforeach +
+
+ + +
+
+ - \ No newline at end of file + diff --git a/resources/views/settings/categories/sub_category.blade.php b/resources/views/settings/categories/sub_category.blade.php index b491a04be..aa015b7cf 100644 --- a/resources/views/settings/categories/sub_category.blade.php +++ b/resources/views/settings/categories/sub_category.blade.php @@ -1,10 +1,64 @@ @if ($sub_category->sub_categories) + @if ($loop->first) + + + + + + @if (!$hide_code_column && (empty(config('type.category.' . $parent_category->type . '.hide', [])) || ! in_array('code', config('type.category.' . $sub_category->type . '.hide')))) + + @if(!empty($parent_category->code)) + {{ $parent_category->code }} + @else + + @endif + + @endif + + +
+ circle + +
+ {{ $parent_category->name }} +
+
+ + @if (! $parent_category->enabled) + + @endif +
+ + + @if (! empty($types[$item->type])) + {{ $types[$item->type] }} + @else + + @endif + + + + + +
+ @endif + - + @if (!$hide_code_column && (empty(config('type.category.' . $sub_category->type . '.hide', [])) || ! in_array('code', config('type.category.' . $sub_category->type . '.hide')))) + + @if(!empty($sub_category->code)) + {{ $sub_category->code }} + @else + + @endif + + @endif + +
@if ($sub_category->sub_categories->count()) @@ -12,31 +66,29 @@ type="button" class="w-4 h-4 flex items-center justify-center mx-2 leading-none align-text-top rounded-lg " node="child-{{ $sub_category->id }}" - onClick="toggleSub('child-{{ $sub_category->id }}', event)" + onClick="toggleSub('child-{{ $sub_category->id }}', event)" > chevron_right
- {{ $sub_category->name }} + {{ $sub_category->name }}
-
- @else -
+ @else circle - +
{{ $sub_category->name }}
-
- @endif + @endif + @if (! $sub_category->enabled) @endif
- + @if (! empty($types[$item->type])) {{ $types[$item->type] }} @else @@ -44,6 +96,10 @@ @endif + + + + @@ -55,6 +111,9 @@ @endphp @foreach($sub_category->sub_categories as $sub_category) - @include('settings.categories.sub_category', ['parent_category' => $parent_category, 'sub_category' => $sub_category, 'tree_level' => $tree_level]) + @php + $sub_category->load(['sub_categories']); + @endphp + @include('settings.categories.sub_category', ['parent_category' => $parent_category, 'sub_category' => $sub_category, 'tree_level' => $tree_level, 'hide_code_column' => $hide_code_column, 'name_class' => $name_class]) @endforeach -@endif \ No newline at end of file +@endif