Merge branch 'akaunting:master' into master
This commit is contained in:
commit
1c60edb891
@ -132,9 +132,6 @@ abstract class Report
|
|||||||
$input = request('search');
|
$input = request('search');
|
||||||
|
|
||||||
// Remove year as it's handled based on financial start
|
// Remove year as it's handled based on financial start
|
||||||
$search_not_year = 'not year:' . $this->getSearchStringValue('year', '', $input);
|
|
||||||
$input = str_replace($search_not_year, '', $input);
|
|
||||||
|
|
||||||
$search_year = 'year:' . $this->getSearchStringValue('year', '', $input);
|
$search_year = 'year:' . $this->getSearchStringValue('year', '', $input);
|
||||||
$input = str_replace($search_year, '', $input);
|
$input = str_replace($search_year, '', $input);
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ use App\Models\Setting\Category;
|
|||||||
use App\Traits\Charts;
|
use App\Traits\Charts;
|
||||||
use App\Traits\DateTime;
|
use App\Traits\DateTime;
|
||||||
use App\Traits\SearchString;
|
use App\Traits\SearchString;
|
||||||
use App\Traits\Tailwind;
|
|
||||||
use App\Traits\Translations;
|
use App\Traits\Translations;
|
||||||
use App\Utilities\Date;
|
use App\Utilities\Date;
|
||||||
use App\Utilities\Export as ExportHelper;
|
use App\Utilities\Export as ExportHelper;
|
||||||
@ -25,7 +24,7 @@ use Illuminate\Support\Str;
|
|||||||
|
|
||||||
abstract class Report
|
abstract class Report
|
||||||
{
|
{
|
||||||
use Charts, DateTime, SearchString, Tailwind, Translations;
|
use Charts, DateTime, SearchString, Translations;
|
||||||
|
|
||||||
public $model;
|
public $model;
|
||||||
|
|
||||||
@ -236,9 +235,7 @@ abstract class Report
|
|||||||
foreach ($tmp_values as $id => $value) {
|
foreach ($tmp_values as $id => $value) {
|
||||||
$labels[$id] = $this->row_names[$table_key][$id];
|
$labels[$id] = $this->row_names[$table_key][$id];
|
||||||
|
|
||||||
$color = ($group == 'category') ? Category::withSubCategory()->find($id)?->color : '#' . dechex(rand(0x000000, 0xFFFFFF));
|
$colors[$id] = ($group == 'category') ? Category::withSubCategory()->find($id)?->colorHexCode : '#' . dechex(rand(0x000000, 0xFFFFFF));
|
||||||
|
|
||||||
$colors[$id] = $this->getHexCodeOfTailwindClass($color);
|
|
||||||
|
|
||||||
$values[$id] = round(($value * 100 / $total), 0);
|
$values[$id] = round(($value * 100 / $total), 0);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ class Categories extends Controller
|
|||||||
{
|
{
|
||||||
$query = Category::with('sub_categories');
|
$query = Category::with('sub_categories');
|
||||||
|
|
||||||
if (request()->expectsJson()) {
|
if (request()->has('search')) {
|
||||||
$query->withSubcategory();
|
$query->withSubcategory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,5 +30,10 @@ class AddBasis extends Listener
|
|||||||
$event->class->filters['basis'] = $this->getBasis();
|
$event->class->filters['basis'] = $this->getBasis();
|
||||||
$event->class->filters['keys']['basis'] = 'basis';
|
$event->class->filters['keys']['basis'] = 'basis';
|
||||||
$event->class->filters['defaults']['basis'] = $event->class->getSetting('basis', 'accrual');
|
$event->class->filters['defaults']['basis'] = $event->class->getSetting('basis', 'accrual');
|
||||||
|
$event->class->filters['operators']['basis'] = [
|
||||||
|
'equal' => true,
|
||||||
|
'not_equal' => false,
|
||||||
|
'rande' => false,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ use App\Models\Document\Document;
|
|||||||
use App\Relations\HasMany\Category as HasMany;
|
use App\Relations\HasMany\Category as HasMany;
|
||||||
use App\Scopes\Category as Scope;
|
use App\Scopes\Category as Scope;
|
||||||
use App\Traits\Categories;
|
use App\Traits\Categories;
|
||||||
|
use App\Traits\Tailwind;
|
||||||
use App\Traits\Transactions;
|
use App\Traits\Transactions;
|
||||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
@ -15,7 +16,7 @@ use Illuminate\Database\Eloquent\Model as EloquentModel;
|
|||||||
|
|
||||||
class Category extends Model
|
class Category extends Model
|
||||||
{
|
{
|
||||||
use Categories, HasFactory, Transactions;
|
use Categories, HasFactory, Tailwind, Transactions;
|
||||||
|
|
||||||
public const INCOME_TYPE = 'income';
|
public const INCOME_TYPE = 'income';
|
||||||
public const EXPENSE_TYPE = 'expense';
|
public const EXPENSE_TYPE = 'expense';
|
||||||
@ -217,6 +218,14 @@ class Category extends Model
|
|||||||
return $query->withoutGlobalScope(new Scope);
|
return $query->withoutGlobalScope(new Scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the hex code of the color.
|
||||||
|
*/
|
||||||
|
public function getColorHexCodeAttribute(): string
|
||||||
|
{
|
||||||
|
return $this->getHexCodeOfTailwindClass($this->color);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the line actions.
|
* Get the line actions.
|
||||||
*
|
*
|
||||||
|
@ -3,13 +3,10 @@
|
|||||||
namespace App\Traits;
|
namespace App\Traits;
|
||||||
|
|
||||||
use Akaunting\Apexcharts\Chart;
|
use Akaunting\Apexcharts\Chart;
|
||||||
use App\Traits\Tailwind;
|
|
||||||
use Balping\JsonRaw\Raw;
|
use Balping\JsonRaw\Raw;
|
||||||
|
|
||||||
trait Charts
|
trait Charts
|
||||||
{
|
{
|
||||||
use Tailwind;
|
|
||||||
|
|
||||||
public $bar = [
|
public $bar = [
|
||||||
'colors' => [],
|
'colors' => [],
|
||||||
'labels' => [],
|
'labels' => [],
|
||||||
@ -37,8 +34,6 @@ trait Charts
|
|||||||
$label .= ' - ' . $description;
|
$label .= ' - ' . $description;
|
||||||
}
|
}
|
||||||
|
|
||||||
$color = $this->getHexCodeOfTailwindClass($color);
|
|
||||||
|
|
||||||
$this->addToDonut($color, $label, $amount);
|
$this->addToDonut($color, $label, $amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,8 +69,6 @@ trait Charts
|
|||||||
|
|
||||||
public function addToBar($color, $label, $value)
|
public function addToBar($color, $label, $value)
|
||||||
{
|
{
|
||||||
$color = $this->getHexCodeOfTailwindClass($color);
|
|
||||||
|
|
||||||
$this->bar['colors'][] = $color;
|
$this->bar['colors'][] = $color;
|
||||||
$this->bar['labels'][] = $label;
|
$this->bar['labels'][] = $label;
|
||||||
$this->bar['values'][] = (int) $value;
|
$this->bar['values'][] = (int) $value;
|
||||||
|
@ -5,7 +5,6 @@ namespace App\Traits;
|
|||||||
use App\Traits\SearchString;
|
use App\Traits\SearchString;
|
||||||
use Carbon\CarbonPeriod;
|
use Carbon\CarbonPeriod;
|
||||||
use Date;
|
use Date;
|
||||||
use Lorisleiva\LaravelSearchString\SearchStringManager;
|
|
||||||
|
|
||||||
trait DateTime
|
trait DateTime
|
||||||
{
|
{
|
||||||
@ -56,31 +55,7 @@ trait DateTime
|
|||||||
$end = $financial_start->addYear(1)->subDays(1)->endOfDay()->format('Y-m-d H:i:s');
|
$end = $financial_start->addYear(1)->subDays(1)->endOfDay()->format('Y-m-d H:i:s');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Looking year or not year
|
return $query->whereBetween($field, [$start, $end]);
|
||||||
$query_type = 'whereBetween';
|
|
||||||
|
|
||||||
if (request('search')) {
|
|
||||||
$search_string_manager = new SearchStringManager($query->getModel());
|
|
||||||
$parse = $search_string_manager->parse(request('search'));
|
|
||||||
|
|
||||||
if (! empty($parse->expressions)) {
|
|
||||||
foreach ($parse->expressions as $filter) {
|
|
||||||
if (! $filter instanceof \Lorisleiva\LaravelSearchString\AST\NotSymbol) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($filter->expression->key != 'year') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$query_type = 'whereNotBetween';
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $query->{$query_type}($field, [$start, $end]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTimezones()
|
public function getTimezones()
|
||||||
|
@ -22,7 +22,7 @@ class ExpensesByCategory extends Widget
|
|||||||
$amount += $transaction->getAmountConvertedToDefault();
|
$amount += $transaction->getAmountConvertedToDefault();
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->addMoneyToDonut($category->color, $amount, $category->name);
|
$this->addMoneyToDonut($category->colorHexCode, $amount, $category->name);
|
||||||
});
|
});
|
||||||
|
|
||||||
$chart = $this->getDonutChart(trans_choice('general.expenses', 2), '100%', 300, 6);
|
$chart = $this->getDonutChart(trans_choice('general.expenses', 2), '100%', 300, 6);
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<span v-if="filter.operator == '='" class="material-icons text-2xl">drag_handle</span>
|
<span v-if="filter.operator == '='" class="material-icons text-2xl">drag_handle</span>
|
||||||
<span v-else-if="filter.operator == '><'" class="material-icons text-2xl transform rotate-90">height</span>
|
<span v-else-if="filter.operator == '><'" class="material-icons text-2xl transform rotate-90">height</span>
|
||||||
|
|
||||||
<img v-else :src="equal_image" class="w-5 h-5 object-cover block" />
|
<img v-else :src="not_equal_image" class="w-5 h-5 object-cover block" />
|
||||||
|
|
||||||
<i v-if="!filter.value" class="mt-1 ltr:-right-2 rtl:left-0 rtl:right-0 el-tag__close el-icon-close " style="font-size: 16px;" @click="onFilterDelete(index)"></i>
|
<i v-if="!filter.value" class="mt-1 ltr:-right-2 rtl:left-0 rtl:right-0 el-tag__close el-icon-close " style="font-size: 16px;" @click="onFilterDelete(index)"></i>
|
||||||
</span>
|
</span>
|
||||||
@ -80,7 +80,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div :id="'search-field-operator-' + _uid" class="absolute top-12 ltr:left-8 rtl:right-8 py-2 bg-white rounded-md border border-gray-200 shadow-xl z-20 list-none dropdown-menu operator" :class="[{'show': visible.operator}]">
|
<div :id="'search-field-operator-' + _uid" class="absolute top-12 ltr:left-8 rtl:right-8 py-2 bg-white rounded-md border border-gray-200 shadow-xl z-20 list-none dropdown-menu operator" :class="[{'show': visible.operator}]">
|
||||||
<li ref="" class="w-full flex items-center px-2 h-9 leading-9 whitespace-nowrap">
|
<li v-if="equal" ref="" class="w-full flex items-center px-2 h-9 leading-9 whitespace-nowrap">
|
||||||
<button type="button" class="w-full h-full flex items-center rounded-md px-2 text-sm hover:bg-lilac-100" @click="onOperatorSelected('=')">
|
<button type="button" class="w-full h-full flex items-center rounded-md px-2 text-sm hover:bg-lilac-100" @click="onOperatorSelected('=')">
|
||||||
<span class="material-icons text-2xl transform">drag_handle</span>
|
<span class="material-icons text-2xl transform">drag_handle</span>
|
||||||
<span class="text-gray hidden">{{ operatorIsText }}
|
<span class="text-gray hidden">{{ operatorIsText }}
|
||||||
@ -88,9 +88,9 @@
|
|||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li ref="" class="w-full flex items-center px-2 h-9 leading-9 whitespace-nowrap">
|
<li v-if="not_equal" ref="" class="w-full flex items-center px-2 h-9 leading-9 whitespace-nowrap">
|
||||||
<button type="button" class="w-full h-full flex items-center rounded-md px-2 text-sm hover:bg-lilac-100" @click="onOperatorSelected('!=')">
|
<button type="button" class="w-full h-full flex items-center rounded-md px-2 text-sm hover:bg-lilac-100" @click="onOperatorSelected('!=')">
|
||||||
<img :src="equal_image" class="w-6 h-6 block m-auto" />
|
<img :src="not_equal_image" class="w-6 h-6 block m-auto" />
|
||||||
<span class="text-gray hidden">{{ operatorIsNotText }}</span>
|
<span class="text-gray hidden">{{ operatorIsNotText }}</span>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
@ -202,6 +202,8 @@ export default {
|
|||||||
values: false,
|
values: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
equal: true,
|
||||||
|
not_equal: true,
|
||||||
range: false,
|
range: false,
|
||||||
option_values: [],
|
option_values: [],
|
||||||
selected_options: [],
|
selected_options: [],
|
||||||
@ -212,7 +214,7 @@ export default {
|
|||||||
show_date: false,
|
show_date: false,
|
||||||
show_close_icon: false,
|
show_close_icon: false,
|
||||||
show_icon: true,
|
show_icon: true,
|
||||||
equal_image: app_url + "/public/img/tailwind_icons/not-equal.svg",
|
not_equal_image: app_url + "/public/img/tailwind_icons/not-equal.svg",
|
||||||
input_focus: false,
|
input_focus: false,
|
||||||
defaultPlaceholder: this.placeholder,
|
defaultPlaceholder: this.placeholder,
|
||||||
dynamicPlaceholder: this.placeholder,
|
dynamicPlaceholder: this.placeholder,
|
||||||
@ -386,10 +388,12 @@ export default {
|
|||||||
|
|
||||||
onOptionSelected(value) {
|
onOptionSelected(value) {
|
||||||
this.current_value = value;
|
this.current_value = value;
|
||||||
|
this.equal = true;
|
||||||
|
this.not_equal = true;
|
||||||
this.range = false;
|
this.range = false;
|
||||||
|
|
||||||
this.onChangeSearchAndFilterText(this.selectPlaceholder, false);
|
this.onChangeSearchAndFilterText(this.selectPlaceholder, false);
|
||||||
|
|
||||||
let option = false;
|
let option = false;
|
||||||
let option_url = false;
|
let option_url = false;
|
||||||
|
|
||||||
@ -413,6 +417,12 @@ export default {
|
|||||||
this.range = true;
|
this.range = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof this.filter_list[i].operators !== 'undefined' && Object.keys(this.filter_list[i].operators).length) {
|
||||||
|
this.equal = (typeof this.filter_list[i].operators.equal) ? this.filter_list[i].operators.equal : this.equal;
|
||||||
|
this.not_equal = (typeof this.filter_list[i].operators['not_equal']) ? this.filter_list[i].operators['not_equal'] : this.not_equal;
|
||||||
|
this.range = (typeof this.filter_list[i].operators['range']) ? this.filter_list[i].operators['range'] : this.range;
|
||||||
|
}
|
||||||
|
|
||||||
this.selected_options.push(this.filter_list[i]);
|
this.selected_options.push(this.filter_list[i]);
|
||||||
this.filter_list.splice(i, 1);
|
this.filter_list.splice(i, 1);
|
||||||
break;
|
break;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
$filtered = [];
|
$filtered = [];
|
||||||
|
|
||||||
$skipped = [
|
$skipped = [
|
||||||
'keys', 'names', 'types', 'routes', 'defaults'
|
'keys', 'names', 'types', 'routes', 'defaults', 'operators',
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($class->filters as $filter_name => $filter_values) {
|
foreach ($class->filters as $filter_name => $filter_values) {
|
||||||
@ -58,31 +58,46 @@
|
|||||||
$default_value = $class->filters['defaults'][$filter_name];
|
$default_value = $class->filters['defaults'][$filter_name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$operators = [];
|
||||||
|
|
||||||
|
if (isset($class->filters['operators']) && !empty($class->filters['operators'][$filter_name])) {
|
||||||
|
$operators = $class->filters['operators'][$filter_name];
|
||||||
|
}
|
||||||
|
|
||||||
if ($key == 'year') {
|
if ($key == 'year') {
|
||||||
$default_value = \Date::now()->year;
|
$default_value = \Date::now()->year;
|
||||||
|
|
||||||
|
$operators = [
|
||||||
|
'equal' => true,
|
||||||
|
'not_equal' => false,
|
||||||
|
'range' => false,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$filters[] = [
|
$filters[] = [
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
'value' => $value,
|
'value' => $value,
|
||||||
'type' => $type,
|
'type' => $type,
|
||||||
'url' => $url,
|
'url' => $url,
|
||||||
'values' => $filter_values,
|
'values' => $filter_values,
|
||||||
|
'operators' => $operators,
|
||||||
];
|
];
|
||||||
|
|
||||||
if (!is_null($default_value)) {
|
if (! is_null($default_value)) {
|
||||||
$filtered[] = [
|
$filtered[] = [
|
||||||
'option' => $key,
|
'option' => $key,
|
||||||
'operator' => '=',
|
'operator' => '=',
|
||||||
'value' => $default_value,
|
'value' => $default_value,
|
||||||
|
'operators' => $operators,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old($key) || request()->get($key)) {
|
if (old($key) || request()->get($key)) {
|
||||||
$filtered[] = [
|
$filtered[] = [
|
||||||
'option' => $key,
|
'option' => $key,
|
||||||
'operator' => '=',
|
'operator' => '=',
|
||||||
'value' => old($key, request()->get($key)),
|
'value' => old($key, request()->get($key)),
|
||||||
|
'operators' => $operators,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user