Merge branch 'master' into invoice_template
This commit is contained in:
commit
e1075f166b
@ -27,6 +27,9 @@ abstract class Form extends Component
|
||||
/** @var string */
|
||||
public $placeholder;
|
||||
|
||||
/** @var string */
|
||||
public $searchText;
|
||||
|
||||
/** @var array */
|
||||
public $options;
|
||||
|
||||
@ -39,6 +42,9 @@ abstract class Form extends Component
|
||||
/** @var string */
|
||||
public $optionValue;
|
||||
|
||||
/** @var array */
|
||||
public $fullOptions;
|
||||
|
||||
/** @var string */
|
||||
public $checked;
|
||||
|
||||
@ -66,6 +72,9 @@ abstract class Form extends Component
|
||||
/** @var bool */
|
||||
public $group;
|
||||
|
||||
/** @var bool */
|
||||
public $searchable;
|
||||
|
||||
/** @var bool */
|
||||
public $disabled;
|
||||
|
||||
@ -99,10 +108,10 @@ abstract class Form extends Component
|
||||
* @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',
|
||||
string $name = '', string $type = 'text', string $label = '', string $id = null, $value = '', $valueKey = null, string $placeholder = '', string $searchText = '',
|
||||
$options = [], $option = [], string $optionKey = 'id', string $optionValue = 'name', $fullOptions = [], $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,
|
||||
bool $searchable = false, bool $disabled = false, bool $readonly = false, bool $required = true, bool $notRequired = false,
|
||||
string $formGroupClass = '', string $inputGroupClass = '',
|
||||
$dynamicAttributes = '',
|
||||
bool $hideCurrency = false
|
||||
@ -113,6 +122,7 @@ abstract class Form extends Component
|
||||
$this->id = $id ?? $name;
|
||||
$this->value = $this->getValue($value, $valueKey);
|
||||
$this->placeholder = $this->getPlaceholder($placeholder);
|
||||
$this->searchText = $this->getSearchText($searchText);
|
||||
$this->rows = $rows;
|
||||
|
||||
$this->remote = $remote;
|
||||
@ -120,6 +130,7 @@ abstract class Form extends Component
|
||||
$this->addNew = $addNew;
|
||||
$this->group = $group;
|
||||
|
||||
$this->searchable = $searchable;
|
||||
$this->disabled = $disabled;
|
||||
$this->readonly = $readonly;
|
||||
$this->required = $this->getRequired($required, $notRequired);
|
||||
@ -128,6 +139,7 @@ abstract class Form extends Component
|
||||
$this->option = $option;
|
||||
$this->optionKey = $optionKey;
|
||||
$this->optionValue = $optionValue;
|
||||
$this->fullOptions = $this->getFullOptions($fullOptions, $options, $searchable);
|
||||
$this->checked = $this->getChecked($checked, $checkedKey);
|
||||
$this->selected = $this->getSelected($selected, $selectedKey);
|
||||
|
||||
@ -222,6 +234,15 @@ abstract class Form extends Component
|
||||
return trans('general.form.enter', ['field' => $label]);
|
||||
}
|
||||
|
||||
protected function getSearchText($searchText)
|
||||
{
|
||||
if (! empty($searchText)) {
|
||||
return $searchText;
|
||||
}
|
||||
|
||||
return trans('general.search_placeholder');
|
||||
}
|
||||
|
||||
protected function getOptions($options)
|
||||
{
|
||||
if (! empty($options)) {
|
||||
@ -248,6 +269,21 @@ abstract class Form extends Component
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function getFullOptions($fullOptions, $options, $searchable)
|
||||
{
|
||||
if (! empty($fullOptions)) {
|
||||
return $fullOptions;
|
||||
}
|
||||
|
||||
if ($searchable && empty($fullOptions)) {
|
||||
$this->options = $this->options->take(setting('default.select_limit'));
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function getChecked($checked, $checkedKey)
|
||||
{
|
||||
return $this->getValue($checked, $checkedKey);
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Akaunting\Money\Exceptions\UnexpectedAmountException;
|
||||
use App\Exceptions\Http\Resource as ResourceException;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
@ -10,6 +11,7 @@ use Illuminate\Http\Exceptions\ThrottleRequestsException;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\View\ViewException;
|
||||
use Symfony\Component\Debug\Exception\FatalThrowableError;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
@ -17,21 +19,31 @@ use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* A list of exception types with their corresponding custom log levels.
|
||||
*
|
||||
* @var array<class-string<\Throwable>, \Psr\Log\LogLevel::*>
|
||||
*/
|
||||
protected $levels = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the exception types that are not reported.
|
||||
*
|
||||
* @var array
|
||||
* @var array<int, class-string<\Throwable>>
|
||||
*/
|
||||
protected $dontReport = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the inputs that are never flashed for validation exceptions.
|
||||
* A list of the inputs that are never flashed to the session on validation exceptions.
|
||||
*
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $dontFlash = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
@ -95,7 +107,9 @@ class Handler extends ExceptionHandler
|
||||
if ($exception instanceof NotFoundHttpException) {
|
||||
// ajax 404 json feedback
|
||||
if ($request->ajax()) {
|
||||
return response()->json(['error' => 'Not Found'], 404);
|
||||
return response()->json([
|
||||
'error' => trans('errors.header.404'),
|
||||
], 404);
|
||||
}
|
||||
|
||||
flash(trans('errors.body.page_not_found'))->error()->important();
|
||||
@ -109,7 +123,9 @@ class Handler extends ExceptionHandler
|
||||
if ($exception instanceof ModelNotFoundException) {
|
||||
// ajax 404 json feedback
|
||||
if ($request->ajax()) {
|
||||
return response()->json(['error' => 'Not Found'], 404);
|
||||
return response()->json([
|
||||
'error' => trans('errors.header.404'),
|
||||
], 404);
|
||||
}
|
||||
|
||||
try {
|
||||
@ -130,7 +146,9 @@ class Handler extends ExceptionHandler
|
||||
if ($exception instanceof FatalThrowableError) {
|
||||
// ajax 500 json feedback
|
||||
if ($request->ajax()) {
|
||||
return response()->json(['error' => 'Error Page'], 500);
|
||||
return response()->json([
|
||||
'error' => trans('errors.header.500'),
|
||||
], 500);
|
||||
}
|
||||
|
||||
// normal 500 view page feedback
|
||||
@ -140,7 +158,25 @@ class Handler extends ExceptionHandler
|
||||
if ($exception instanceof ThrottleRequestsException) {
|
||||
// ajax 500 json feedback
|
||||
if ($request->ajax()) {
|
||||
return response()->json(['error' => $exception->getMessage()], 429);
|
||||
return response()->json([
|
||||
'error' => $exception->getMessage(),
|
||||
], 429);
|
||||
}
|
||||
}
|
||||
|
||||
if ($exception instanceof ViewException) {
|
||||
$real_exception = $this->getRealException($exception, ViewException::class);
|
||||
|
||||
if ($real_exception instanceof UnexpectedAmountException) {
|
||||
if ($request->ajax()) {
|
||||
return response()->json([
|
||||
'error' => trans('errors.message.amount'),
|
||||
], 500);
|
||||
}
|
||||
|
||||
return response()->view('errors.500', [
|
||||
'message' => trans('errors.message.amount'),
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,10 +309,6 @@ class Handler extends ExceptionHandler
|
||||
|
||||
/**
|
||||
* Get the headers from the exception.
|
||||
*
|
||||
* @param Throwable $exception
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getHeaders(Throwable $exception): array
|
||||
{
|
||||
@ -284,4 +316,18 @@ class Handler extends ExceptionHandler
|
||||
? $exception->getHeaders()
|
||||
: [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the real exception.
|
||||
*/
|
||||
protected function getRealException(Throwable $exception, string $current): Throwable
|
||||
{
|
||||
$previous = $exception->getPrevious() ?? $exception;
|
||||
|
||||
while (($previous instanceof $current) && $previous->getPrevious()) {
|
||||
$previous = $previous->getPrevious();
|
||||
}
|
||||
|
||||
return $previous;
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,10 @@
|
||||
namespace App\Http\Controllers\Modals;
|
||||
|
||||
use App\Abstracts\Http\Controller;
|
||||
use App\Jobs\Setting\CreateCategory;
|
||||
use Illuminate\Http\Request as IRequest;
|
||||
use App\Http\Requests\Setting\Category as Request;
|
||||
use App\Jobs\Setting\CreateCategory;
|
||||
use App\Models\Setting\Category;
|
||||
use Illuminate\Http\Request as IRequest;
|
||||
|
||||
class Categories extends Controller
|
||||
{
|
||||
@ -30,7 +31,17 @@ class Categories extends Controller
|
||||
{
|
||||
$type = $request->get('type', 'item');
|
||||
|
||||
$html = view('modals.categories.create', compact('type'))->render();
|
||||
$categories = collect();
|
||||
|
||||
Category::type($type)->enabled()->orderBy('name')->get()->each(function ($category) use (&$categories) {
|
||||
$categories->push([
|
||||
'id' => $category->id,
|
||||
'title' => $category->name,
|
||||
'level' => $category->level,
|
||||
]);
|
||||
});
|
||||
|
||||
$html = view('modals.categories.create', compact('type', 'categories'))->render();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
|
@ -3,9 +3,12 @@
|
||||
namespace App\Http\Controllers\Modules;
|
||||
|
||||
use App\Abstracts\Http\Controller;
|
||||
use App\Traits\Modules;
|
||||
|
||||
class My extends Controller
|
||||
{
|
||||
use Modules;
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
@ -13,6 +16,9 @@ class My extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return $this->response('modules.my.index');
|
||||
$purchase = $this->getMyModules(['query' => ['limit' => 16]]);
|
||||
$installed = $this->getInstalledModules();
|
||||
|
||||
return $this->response('modules.my.index', compact('purchase', 'installed'));
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ namespace App\Models\Banking;
|
||||
|
||||
use App\Abstracts\Model;
|
||||
use App\Models\Common\Media as MediaModel;
|
||||
use App\Models\Setting\Category;
|
||||
use App\Scopes\Transaction as Scope;
|
||||
use App\Traits\Currencies;
|
||||
use App\Traits\DateTime;
|
||||
|
@ -28,7 +28,7 @@ trait Charts
|
||||
|
||||
public function addMoneyToDonut($color, $amount, $description = '')
|
||||
{
|
||||
$label = money($amount, setting('default.currency'), true)->format();
|
||||
$label = money($amount, setting('default.currency'), true)->formatForHumans();
|
||||
|
||||
if (!empty($description)) {
|
||||
$label .= ' - ' . $description;
|
||||
|
@ -29,7 +29,7 @@ class Category extends Form
|
||||
$this->path = route('modals.categories.create', ['type' => $this->type]);
|
||||
$this->remoteAction = route('categories.index', ['search' => 'type:' . $this->type . ' enabled:1']);
|
||||
|
||||
$this->categories = Model::type($this->type)->enabled()->orderBy('name')->take(setting('default.select_limit'))->get();
|
||||
$this->categories = Model::type($this->type)->enabled()->orderBy('name')->take(setting('default.select_limit'))->pluck('name', 'id');
|
||||
|
||||
$model = $this->getParentData('model');
|
||||
|
||||
|
@ -35,7 +35,7 @@ class Contact extends Form
|
||||
|
||||
$this->label = trans_choice('general.' . Str::plural($this->type), 1);
|
||||
|
||||
$this->contacts = Model::type($this->type)->enabled()->orderBy('name')->take(setting('default.select_limit'))->get();
|
||||
$this->contacts = Model::type($this->type)->enabled()->orderBy('name')->take(setting('default.select_limit'))->pluck('name', 'id');
|
||||
|
||||
$model = $this->getParentData('model');
|
||||
|
||||
|
90
composer.lock
generated
90
composer.lock
generated
@ -413,16 +413,16 @@
|
||||
},
|
||||
{
|
||||
"name": "akaunting/laravel-money",
|
||||
"version": "3.1.1",
|
||||
"version": "3.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/akaunting/laravel-money.git",
|
||||
"reference": "daf8ca8dc91b5a08d31dbf0788e2a4723185451f"
|
||||
"reference": "cbc66d1dc457c169f6081e0ae6c661b499dad301"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/akaunting/laravel-money/zipball/daf8ca8dc91b5a08d31dbf0788e2a4723185451f",
|
||||
"reference": "daf8ca8dc91b5a08d31dbf0788e2a4723185451f",
|
||||
"url": "https://api.github.com/repos/akaunting/laravel-money/zipball/cbc66d1dc457c169f6081e0ae6c661b499dad301",
|
||||
"reference": "cbc66d1dc457c169f6081e0ae6c661b499dad301",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -475,9 +475,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/akaunting/laravel-money/issues",
|
||||
"source": "https://github.com/akaunting/laravel-money/tree/3.1.1"
|
||||
"source": "https://github.com/akaunting/laravel-money/tree/3.1.2"
|
||||
},
|
||||
"time": "2022-07-20T09:28:53+00:00"
|
||||
"time": "2022-07-27T08:16:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "akaunting/laravel-mutable-observer",
|
||||
@ -907,16 +907,16 @@
|
||||
},
|
||||
{
|
||||
"name": "aws/aws-sdk-php",
|
||||
"version": "3.231.9",
|
||||
"version": "3.231.14",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/aws/aws-sdk-php.git",
|
||||
"reference": "fbda3e544226b44f79ead89de78f220d30ef3796"
|
||||
"reference": "6b79b9c8204813d9674ffa7badcd567d7f608165"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/fbda3e544226b44f79ead89de78f220d30ef3796",
|
||||
"reference": "fbda3e544226b44f79ead89de78f220d30ef3796",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/6b79b9c8204813d9674ffa7badcd567d7f608165",
|
||||
"reference": "6b79b9c8204813d9674ffa7badcd567d7f608165",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -993,9 +993,9 @@
|
||||
"support": {
|
||||
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
|
||||
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.231.9"
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.231.14"
|
||||
},
|
||||
"time": "2022-07-19T18:14:37+00:00"
|
||||
"time": "2022-07-26T18:20:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "balping/json-raw-encoder",
|
||||
@ -4473,16 +4473,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v9.21.0",
|
||||
"version": "v9.22.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/framework.git",
|
||||
"reference": "a8a529d371faaa38bde087aa6171a5b53a6a8760"
|
||||
"reference": "b3b3dd43b9899f23df6d1d3e5390bd4662947a46"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/a8a529d371faaa38bde087aa6171a5b53a6a8760",
|
||||
"reference": "a8a529d371faaa38bde087aa6171a5b53a6a8760",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/b3b3dd43b9899f23df6d1d3e5390bd4662947a46",
|
||||
"reference": "b3b3dd43b9899f23df6d1d3e5390bd4662947a46",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -4649,7 +4649,7 @@
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2022-07-19T14:12:19+00:00"
|
||||
"time": "2022-07-26T16:16:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/sanctum",
|
||||
@ -5227,16 +5227,16 @@
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem",
|
||||
"version": "3.1.1",
|
||||
"version": "3.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/flysystem.git",
|
||||
"reference": "1a941703dfb649f9b821e7bc425e782f576a805e"
|
||||
"reference": "ed0ecc7f9b5c2f4a9872185846974a808a3b052a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/1a941703dfb649f9b821e7bc425e782f576a805e",
|
||||
"reference": "1a941703dfb649f9b821e7bc425e782f576a805e",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/ed0ecc7f9b5c2f4a9872185846974a808a3b052a",
|
||||
"reference": "ed0ecc7f9b5c2f4a9872185846974a808a3b052a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -5297,7 +5297,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/flysystem/issues",
|
||||
"source": "https://github.com/thephpleague/flysystem/tree/3.1.1"
|
||||
"source": "https://github.com/thephpleague/flysystem/tree/3.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -5313,20 +5313,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-07-18T09:59:40+00:00"
|
||||
"time": "2022-07-26T07:26:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem-aws-s3-v3",
|
||||
"version": "3.1.1",
|
||||
"version": "3.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git",
|
||||
"reference": "fa46ce9fbad9bfc73d8b160ffeb2c1793fe9c73b"
|
||||
"reference": "257893ef7398b3c9255b26dff8b0118bb93fc5ff"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/fa46ce9fbad9bfc73d8b160ffeb2c1793fe9c73b",
|
||||
"reference": "fa46ce9fbad9bfc73d8b160ffeb2c1793fe9c73b",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/257893ef7398b3c9255b26dff8b0118bb93fc5ff",
|
||||
"reference": "257893ef7398b3c9255b26dff8b0118bb93fc5ff",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -5367,7 +5367,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/flysystem-aws-s3-v3/issues",
|
||||
"source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.1.1"
|
||||
"source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -5383,7 +5383,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-07-18T09:31:34+00:00"
|
||||
"time": "2022-07-26T07:22:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/mime-type-detection",
|
||||
@ -6231,16 +6231,16 @@
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "2.7.0",
|
||||
"version": "2.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Seldaek/monolog.git",
|
||||
"reference": "5579edf28aee1190a798bfa5be8bc16c563bd524"
|
||||
"reference": "720488632c590286b88b80e62aa3d3d551ad4a50"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/5579edf28aee1190a798bfa5be8bc16c563bd524",
|
||||
"reference": "5579edf28aee1190a798bfa5be8bc16c563bd524",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/720488632c590286b88b80e62aa3d3d551ad4a50",
|
||||
"reference": "720488632c590286b88b80e62aa3d3d551ad4a50",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -6260,11 +6260,10 @@
|
||||
"guzzlehttp/psr7": "^2.2",
|
||||
"mongodb/mongodb": "^1.8",
|
||||
"php-amqplib/php-amqplib": "~2.4 || ^3",
|
||||
"php-console/php-console": "^3.1.3",
|
||||
"phpspec/prophecy": "^1.15",
|
||||
"phpstan/phpstan": "^0.12.91",
|
||||
"phpunit/phpunit": "^8.5.14",
|
||||
"predis/predis": "^1.1",
|
||||
"predis/predis": "^1.1 || ^2.0",
|
||||
"rollbar/rollbar": "^1.3 || ^2 || ^3",
|
||||
"ruflin/elastica": "^7",
|
||||
"swiftmailer/swiftmailer": "^5.3|^6.0",
|
||||
@ -6284,7 +6283,6 @@
|
||||
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
|
||||
"mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
|
||||
"php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
|
||||
"php-console/php-console": "Allow sending log messages to Google Chrome",
|
||||
"rollbar/rollbar": "Allow sending log messages to Rollbar",
|
||||
"ruflin/elastica": "Allow sending log messages to an Elastic Search server"
|
||||
},
|
||||
@ -6319,7 +6317,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Seldaek/monolog/issues",
|
||||
"source": "https://github.com/Seldaek/monolog/tree/2.7.0"
|
||||
"source": "https://github.com/Seldaek/monolog/tree/2.8.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -6331,7 +6329,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-06-09T08:59:12+00:00"
|
||||
"time": "2022-07-24T11:55:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mtdowling/jmespath.php",
|
||||
@ -11676,16 +11674,16 @@
|
||||
},
|
||||
{
|
||||
"name": "fakerphp/faker",
|
||||
"version": "v1.19.0",
|
||||
"version": "v1.20.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/FakerPHP/Faker.git",
|
||||
"reference": "d7f08a622b3346766325488aa32ddc93ccdecc75"
|
||||
"reference": "37f751c67a5372d4e26353bd9384bc03744ec77b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/FakerPHP/Faker/zipball/d7f08a622b3346766325488aa32ddc93ccdecc75",
|
||||
"reference": "d7f08a622b3346766325488aa32ddc93ccdecc75",
|
||||
"url": "https://api.github.com/repos/FakerPHP/Faker/zipball/37f751c67a5372d4e26353bd9384bc03744ec77b",
|
||||
"reference": "37f751c67a5372d4e26353bd9384bc03744ec77b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -11712,7 +11710,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "v1.19-dev"
|
||||
"dev-main": "v1.20-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -11737,9 +11735,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/FakerPHP/Faker/issues",
|
||||
"source": "https://github.com/FakerPHP/Faker/tree/v1.19.0"
|
||||
"source": "https://github.com/FakerPHP/Faker/tree/v1.20.0"
|
||||
},
|
||||
"time": "2022-02-02T17:38:57+00:00"
|
||||
"time": "2022-07-20T13:12:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "filp/whoops",
|
||||
@ -14216,5 +14214,5 @@
|
||||
"ext-zip": "*"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.3.0"
|
||||
"plugin-api-version": "2.2.0"
|
||||
}
|
||||
|
@ -320,6 +320,32 @@ return [
|
||||
],
|
||||
],
|
||||
|
||||
Transaction::INCOME_TRANSFER_TYPE => [
|
||||
'group' => 'banking',
|
||||
'route' => [
|
||||
'prefix' => 'transactions', // core use with group + prefix, module ex. estimates
|
||||
'parameter' => 'transaction', // banking/transactions/{parameter}/edit
|
||||
//'create' => 'transactions.create', // if you change route, you can write full path
|
||||
],
|
||||
'permission' => [
|
||||
'prefix' => 'transactions',
|
||||
//'create' => 'create-banking-transactions',
|
||||
],
|
||||
'translation' => [
|
||||
'prefix' => 'transactions', // this translation file name.
|
||||
'related_document_amount' => 'invoices.invoice_amount',
|
||||
'transactions' => 'general.incomes',
|
||||
],
|
||||
'contact_type' => 'customer',
|
||||
'document_type' => 'invoice',
|
||||
'split_type' => Transaction::INCOME_SPLIT_TYPE,
|
||||
'email_template' => 'payment_received_customer',
|
||||
'script' => [
|
||||
'folder' => 'banking',
|
||||
'file' => 'transactions',
|
||||
],
|
||||
],
|
||||
|
||||
Transaction::INCOME_RECURRING_TYPE => [
|
||||
'group' => 'banking',
|
||||
'route' => [
|
||||
@ -373,6 +399,31 @@ return [
|
||||
],
|
||||
],
|
||||
|
||||
Transaction::EXPENSE_TRANSFER_TYPE => [
|
||||
'group' => 'banking',
|
||||
'route' => [
|
||||
'prefix' => 'transactions', // core use with group + prefix, module ex. estimates
|
||||
'parameter' => 'transaction', // banking/transactions/{parameter}/edit
|
||||
//'create' => 'transactions.create', // if you change route, you can write full path
|
||||
],
|
||||
'permission' => [
|
||||
'prefix' => 'transactions',
|
||||
//'create' => 'create-banking-transactions',
|
||||
],
|
||||
'translation' => [
|
||||
'prefix' => 'transactions', // this translation file name.
|
||||
'related_document_amount' => 'bills.bill_amount',
|
||||
],
|
||||
'contact_type' => 'vendor',
|
||||
'document_type' => 'bill',
|
||||
'split_type' => Transaction::EXPENSE_SPLIT_TYPE,
|
||||
'email_template' => 'payment_made_vendor',
|
||||
'script' => [
|
||||
'folder' => 'banking',
|
||||
'file' => 'transactions',
|
||||
],
|
||||
],
|
||||
|
||||
Transaction::EXPENSE_RECURRING_TYPE => [
|
||||
'group' => 'banking',
|
||||
'route' => [
|
||||
|
12822
public/css/app.css
vendored
12822
public/css/app.css
vendored
File diff suppressed because it is too large
Load Diff
@ -10,8 +10,10 @@
|
||||
]"
|
||||
:error="formError">
|
||||
|
||||
<el-select v-model="selected" :placeholder="placeholder" filterable
|
||||
<el-select v-model="selected" :placeholder="dynamicPlaceholder" filterable
|
||||
@change="change" @visible-change="visibleChange" @remove-tag="removeTag" @clear="clear" @blur="blur" @focus="focus"
|
||||
:remote="remote"
|
||||
:remote-method="serchableMethod"
|
||||
:clearable="clearable"
|
||||
:disabled="disabled"
|
||||
:multiple="multiple"
|
||||
@ -66,7 +68,7 @@
|
||||
</template>
|
||||
|
||||
<el-option v-if="!group" v-for="(option, index) in sortedOptions"
|
||||
:key="index"
|
||||
:key="option.key"
|
||||
:disabled="disabledOptions.includes(option.key)"
|
||||
:label="option.value"
|
||||
:value="option.key">
|
||||
@ -81,7 +83,7 @@
|
||||
:label="group_options.key">
|
||||
<el-option
|
||||
v-for="(option, option_index) in group_options.value"
|
||||
:key="option_index"
|
||||
:key="option.key"
|
||||
:disabled="disabledOptions.includes(option.key)"
|
||||
:label="option.value"
|
||||
:value="option.key">
|
||||
@ -189,6 +191,8 @@ export default {
|
||||
|
||||
dynamicOptions: null,
|
||||
|
||||
fullOptions: null,
|
||||
|
||||
disabledOptions: {
|
||||
type: Array,
|
||||
default: function () {
|
||||
@ -283,10 +287,23 @@ export default {
|
||||
default: 'No Matchign Data',
|
||||
description: "Selectbox search option not found item message"
|
||||
},
|
||||
|
||||
searchable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
description: "Selectbox searchable"
|
||||
},
|
||||
|
||||
searchText: {
|
||||
type: String,
|
||||
default: '',
|
||||
description: "Selectbox input search placeholder text"
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
dynamicPlaceholder: this.placeholder,
|
||||
add_new: {
|
||||
text: this.addNew.text,
|
||||
show: false,
|
||||
@ -301,18 +318,26 @@ export default {
|
||||
|
||||
form: {},
|
||||
sorted_options: [],
|
||||
full_options:[],
|
||||
new_options: {},
|
||||
loading: false,
|
||||
remote: false,
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.setSortedOptions();
|
||||
|
||||
if (this.searchable) {
|
||||
this.remote = true;
|
||||
|
||||
this.setFullOptions();
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
sortedOptions() {
|
||||
if (!this.sortOptions) {
|
||||
if (! this.sortOptions) {
|
||||
return this.sorted_options
|
||||
}
|
||||
|
||||
@ -344,7 +369,6 @@ export default {
|
||||
} catch (e) {
|
||||
this.selected = this.model;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (this.multiple && !this.selected.length) {
|
||||
@ -453,6 +477,82 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
setFullOptions() {
|
||||
// Reset full_options
|
||||
this.full_options = [];
|
||||
|
||||
let created_options = (this.dynamicOptions) ? this.dynamicOptions : this.fullOptions;
|
||||
|
||||
if (this.group) {
|
||||
// Option set sort_option data
|
||||
if (!Array.isArray(created_options)) {
|
||||
for (const [index, options] of Object.entries(created_options)) {
|
||||
let values = [];
|
||||
|
||||
for (const [key, value] of Object.entries(options)) {
|
||||
values.push({
|
||||
key: key,
|
||||
value: value,
|
||||
level: 0
|
||||
});
|
||||
}
|
||||
|
||||
this.full_options.push({
|
||||
key: index,
|
||||
value: values
|
||||
});
|
||||
}
|
||||
} else {
|
||||
created_options.forEach(function (option, index) {
|
||||
if (typeof(option) == 'string') {
|
||||
this.full_options.push({
|
||||
index: index,
|
||||
key: index.toString(),
|
||||
value: option,
|
||||
level: 0
|
||||
});
|
||||
} else {
|
||||
this.full_options.push({
|
||||
index: index,
|
||||
key: option.id.toString(),
|
||||
value: (option.title) ? option.title : (option.display_name) ? option.display_name : option.name,
|
||||
level: (option.level) ? option.level : 0
|
||||
});
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
} else {
|
||||
// Option set sort_option data
|
||||
if (!Array.isArray(created_options)) {
|
||||
for (const [key, value] of Object.entries(created_options)) {
|
||||
this.full_options.push({
|
||||
key: key,
|
||||
value: value,
|
||||
level: 0
|
||||
});
|
||||
}
|
||||
} else {
|
||||
created_options.forEach(function (option, index) {
|
||||
if (typeof(option) == 'string') {
|
||||
this.full_options.push({
|
||||
index: index,
|
||||
key: index.toString(),
|
||||
value: option,
|
||||
level: 0
|
||||
});
|
||||
} else {
|
||||
this.full_options.push({
|
||||
index: index,
|
||||
key: option.id.toString(),
|
||||
value: (option.title) ? option.title : (option.display_name) ? option.display_name : option.name,
|
||||
level: (option.level) ? option.level : 0
|
||||
});
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
change() {
|
||||
// This controll added add new changed..
|
||||
if (typeof(this.selected) === 'object' && typeof(this.selected.type) !== 'undefined') {
|
||||
@ -531,6 +631,30 @@ export default {
|
||||
|
||||
visibleChange(event) {
|
||||
this.$emit('visible-change', event);
|
||||
|
||||
this.dynamicPlaceholder = this.placeholder;
|
||||
|
||||
if (event && this.searchText) {
|
||||
this.dynamicPlaceholder = this.searchText;
|
||||
}
|
||||
|
||||
if (this.searchable) {
|
||||
let selected = this.selected;
|
||||
this.sorted_options = [];
|
||||
|
||||
this.setSortedOptions();
|
||||
|
||||
for (const [key, value] of Object.entries(this.full_options)) {
|
||||
if (selected == value.key) {
|
||||
this.sorted_options.push({
|
||||
index: value.index,
|
||||
key: value.key,
|
||||
value: value.value,
|
||||
level: value.level
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
removeTag(event) {
|
||||
@ -724,6 +848,23 @@ export default {
|
||||
addModal() {
|
||||
|
||||
},
|
||||
|
||||
serchableMethod(query) {
|
||||
if (query !== '') {
|
||||
this.loading = true;
|
||||
|
||||
setTimeout(() => {
|
||||
this.loading = false;
|
||||
|
||||
this.sorted_options = this.full_options.filter(item => {
|
||||
return item.value.toLowerCase()
|
||||
.indexOf(query.toLowerCase()) > -1;
|
||||
});
|
||||
}, 200);
|
||||
} else {
|
||||
this.setSortedOptions();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
|
@ -11,7 +11,7 @@
|
||||
]"
|
||||
:error="formError">
|
||||
|
||||
<el-select v-model="selected" :placeholder="placeholder" filterable remote reserve-keyword
|
||||
<el-select v-model="selected" :placeholder="dynamicPlaceholder" filterable remote reserve-keyword
|
||||
@change="change" @visible-change="visibleChange" @remove-tag="removeTag" @clear="clear" @blur="blur" @focus="focus"
|
||||
:clearable="clearable"
|
||||
:disabled="disabled"
|
||||
@ -111,7 +111,7 @@
|
||||
</base-input>
|
||||
|
||||
<span v-else>
|
||||
<el-select v-model="selected" :placeholder="placeholder" filterable remote reserve-keyword
|
||||
<el-select v-model="selected" :placeholder="dynamicPlaceholder" filterable remote reserve-keyword
|
||||
@change="change" @visible-change="visibleChange" @remove-tag="removeTag" @clear="clear" @blur="blur" @focus="focus"
|
||||
:clearable="clearable"
|
||||
:disabled="disabled"
|
||||
@ -288,6 +288,8 @@ export default {
|
||||
|
||||
dynamicOptions: null,
|
||||
|
||||
fullOptions: null,
|
||||
|
||||
disabledOptions: {
|
||||
type: Array,
|
||||
default: function () {
|
||||
@ -389,11 +391,24 @@ export default {
|
||||
description: "Selectbox search option not found item message"
|
||||
},
|
||||
|
||||
searchable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
description: "Selectbox searchable"
|
||||
},
|
||||
|
||||
searchText: {
|
||||
type: String,
|
||||
default: '',
|
||||
description: "Selectbox input search placeholder text"
|
||||
},
|
||||
|
||||
remoteAction: {
|
||||
type: String,
|
||||
default: null,
|
||||
description: "Selectbox remote action path"
|
||||
},
|
||||
|
||||
currencyCode: {
|
||||
type: String,
|
||||
default: 'USD',
|
||||
@ -403,6 +418,7 @@ export default {
|
||||
|
||||
data() {
|
||||
return {
|
||||
dynamicPlaceholder: this.placeholder,
|
||||
add_new: {
|
||||
text: this.addNew.text,
|
||||
show: false,
|
||||
@ -417,6 +433,7 @@ export default {
|
||||
|
||||
form: {},
|
||||
sorted_options: [],
|
||||
full_options:[],
|
||||
new_options: {},
|
||||
loading: false,
|
||||
}
|
||||
@ -424,11 +441,15 @@ export default {
|
||||
|
||||
created() {
|
||||
this.setSortedOptions();
|
||||
|
||||
if (this.searchable) {
|
||||
this.setFullOptions();
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
sortedOptions() {
|
||||
if (!this.sortOptions) {
|
||||
if (! this.sortOptions) {
|
||||
return this.sorted_options;
|
||||
}
|
||||
|
||||
@ -460,7 +481,6 @@ export default {
|
||||
} catch (e) {
|
||||
this.selected = this.model;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (this.multiple && !this.selected.length) {
|
||||
@ -569,6 +589,82 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
setFullOptions() {
|
||||
// Reset full_options
|
||||
this.full_options = [];
|
||||
|
||||
let created_options = (this.dynamicOptions) ? this.dynamicOptions : this.fullOptions;
|
||||
|
||||
if (this.group) {
|
||||
// Option set sort_option data
|
||||
if (!Array.isArray(created_options)) {
|
||||
for (const [index, options] of Object.entries(created_options)) {
|
||||
let values = [];
|
||||
|
||||
for (const [key, value] of Object.entries(options)) {
|
||||
values.push({
|
||||
key: key,
|
||||
value: value,
|
||||
level: 0
|
||||
});
|
||||
}
|
||||
|
||||
this.full_options.push({
|
||||
key: index,
|
||||
value: values
|
||||
});
|
||||
}
|
||||
} else {
|
||||
created_options.forEach(function (option, index) {
|
||||
if (typeof(option) == 'string') {
|
||||
this.full_options.push({
|
||||
index: index,
|
||||
key: index.toString(),
|
||||
value: option,
|
||||
level: 0
|
||||
});
|
||||
} else {
|
||||
this.full_options.push({
|
||||
index: index,
|
||||
key: option.id.toString(),
|
||||
value: (option.title) ? option.title : (option.display_name) ? option.display_name : option.name,
|
||||
level: (option.level) ? option.level : 0
|
||||
});
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
} else {
|
||||
// Option set sort_option data
|
||||
if (!Array.isArray(created_options)) {
|
||||
for (const [key, value] of Object.entries(created_options)) {
|
||||
this.full_options.push({
|
||||
key: key,
|
||||
value: value,
|
||||
level: 0
|
||||
});
|
||||
}
|
||||
} else {
|
||||
created_options.forEach(function (option, index) {
|
||||
if (typeof(option) == 'string') {
|
||||
this.full_options.push({
|
||||
index: index,
|
||||
key: index.toString(),
|
||||
value: option,
|
||||
level: 0
|
||||
});
|
||||
} else {
|
||||
this.full_options.push({
|
||||
index: index,
|
||||
key: option.id.toString(),
|
||||
value: (option.title) ? option.title : (option.display_name) ? option.display_name : option.name,
|
||||
level: (option.level) ? option.level : 0
|
||||
});
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
change() {
|
||||
// This controll added add new changed..
|
||||
if (typeof(this.selected) === 'object' && typeof(this.selected.type) !== 'undefined') {
|
||||
@ -647,6 +743,30 @@ export default {
|
||||
|
||||
visibleChange(event) {
|
||||
this.$emit('visible-change', event);
|
||||
|
||||
this.dynamicPlaceholder = this.placeholder;
|
||||
|
||||
if (event && this.searchText) {
|
||||
this.dynamicPlaceholder = this.searchText;
|
||||
}
|
||||
|
||||
if (this.searchable) {
|
||||
let selected = this.selected;
|
||||
this.sorted_options = [];
|
||||
|
||||
this.setSortedOptions();
|
||||
|
||||
for (const [key, value] of Object.entries(this.full_options)) {
|
||||
if (selected == value.key) {
|
||||
this.sorted_options.push({
|
||||
index: value.index,
|
||||
key: value.key,
|
||||
value: value.value,
|
||||
level: value.level
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
removeTag(event) {
|
||||
@ -670,6 +790,10 @@ export default {
|
||||
document.getElementById('form-select-' + this.name).getElementsByTagName("input")[0].readOnly = false;
|
||||
}
|
||||
|
||||
if (this.searchable) {
|
||||
return this.serchableMethod(query);
|
||||
}
|
||||
|
||||
if (query !== '') {
|
||||
this.loading = true;
|
||||
|
||||
@ -742,6 +866,23 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
serchableMethod(query) {
|
||||
if (query !== '') {
|
||||
this.loading = true;
|
||||
|
||||
setTimeout(() => {
|
||||
this.loading = false;
|
||||
|
||||
this.sorted_options = this.full_options.filter(item => {
|
||||
return item.value.toLowerCase()
|
||||
.indexOf(query.toLowerCase()) > -1;
|
||||
});
|
||||
}, 200);
|
||||
} else {
|
||||
this.setSortedOptions();
|
||||
}
|
||||
},
|
||||
|
||||
async onAddItem() {
|
||||
// Get Select Input value
|
||||
if (this.multiple) {
|
||||
|
@ -29,7 +29,7 @@ const app = new Vue({
|
||||
return {
|
||||
form: new Form('reconciliation'),
|
||||
bulk_action: new BulkAction('reconciliations'),
|
||||
reconcile: true,
|
||||
reconcile: false,
|
||||
difference: null,
|
||||
totals: {
|
||||
closing_balance: 0,
|
||||
@ -48,8 +48,6 @@ const app = new Vue({
|
||||
if (this.form._method == 'PATCH') {
|
||||
this.onCalculate();
|
||||
}
|
||||
|
||||
this.currencyConversion();
|
||||
},
|
||||
|
||||
methods:{
|
||||
@ -57,18 +55,6 @@ const app = new Vue({
|
||||
this.min_due_date = date;
|
||||
},
|
||||
|
||||
currencyConversion() {
|
||||
setTimeout(() => {
|
||||
if (document.querySelectorAll('.js-conversion-input')) {
|
||||
let currency_input = document.querySelectorAll('.js-conversion-input');
|
||||
|
||||
for (let input of currency_input) {
|
||||
input.setAttribute('size', input.value.length);
|
||||
}
|
||||
}
|
||||
}, 250)
|
||||
},
|
||||
|
||||
onReconcilition() {
|
||||
let form = document.getElementById('form-create-reconciliation');
|
||||
|
||||
@ -78,7 +64,7 @@ const app = new Vue({
|
||||
},
|
||||
|
||||
onCalculate() {
|
||||
this.reconcile = true;
|
||||
this.reconcile = false;
|
||||
this.difference = null;
|
||||
|
||||
let transactions = this.form.transactions;
|
||||
@ -120,10 +106,10 @@ const app = new Vue({
|
||||
|
||||
if (difference != 0) {
|
||||
this.difference = 'bg-orange-300';
|
||||
this.reconcile = true;
|
||||
this.reconcile = false;
|
||||
} else {
|
||||
this.difference = 'bg-green-100';
|
||||
this.reconcile = false;
|
||||
this.reconcile = true;
|
||||
}
|
||||
|
||||
this.totals.cleared_amount = parseFloat(cleared_amount);
|
||||
|
39
resources/assets/js/views/common/documents.js
vendored
39
resources/assets/js/views/common/documents.js
vendored
@ -162,10 +162,17 @@ const app = new Vue({
|
||||
sub_total += item.total;
|
||||
grand_total += item.grand_total;
|
||||
|
||||
let item_tax_ids = [];
|
||||
|
||||
item.tax_ids.forEach(function(item_tax, item_tax_index) {
|
||||
item_tax_ids.push(item_tax.id);
|
||||
});
|
||||
|
||||
this.form.items[index].name = item.name;
|
||||
this.form.items[index].description = item.description;
|
||||
this.form.items[index].quantity = item.quantity;
|
||||
this.form.items[index].price = item.price;
|
||||
this.form.items[index].tax_ids = item_tax_ids;
|
||||
this.form.items[index].discount = item.discount;
|
||||
this.form.items[index].discount_type = item.discount_type;
|
||||
this.form.items[index].total = item.total;
|
||||
@ -262,6 +269,7 @@ const app = new Vue({
|
||||
|
||||
if (inclusives.length) {
|
||||
inclusives.forEach(function(inclusive) {
|
||||
item.tax_ids[inclusive.tax_index].name = inclusive.tax_name;
|
||||
item.tax_ids[inclusive.tax_index].price = item.grand_total - (item.grand_total / (1 + inclusive.tax_rate / 100));
|
||||
|
||||
inclusive_tax_total += item.tax_ids[inclusive.tax_index].price;
|
||||
@ -274,6 +282,7 @@ const app = new Vue({
|
||||
|
||||
if (fixed.length) {
|
||||
fixed.forEach(function(fixed) {
|
||||
item.tax_ids[fixed.tax_index].name = fixed.tax_name;
|
||||
item.tax_ids[fixed.tax_index].price = fixed.tax_rate * item.quantity;
|
||||
|
||||
total_tax_amount += item.tax_ids[fixed.tax_index].price;
|
||||
@ -290,6 +299,7 @@ const app = new Vue({
|
||||
|
||||
if (normal.length) {
|
||||
normal.forEach(function(normal) {
|
||||
item.tax_ids[normal.tax_index].name = normal.tax_name;
|
||||
item.tax_ids[normal.tax_index].price = price_for_tax * (normal.tax_rate / 100);
|
||||
|
||||
total_tax_amount += item.tax_ids[normal.tax_index].price;
|
||||
@ -300,6 +310,7 @@ const app = new Vue({
|
||||
|
||||
if (withholding.length) {
|
||||
withholding.forEach(function(withholding) {
|
||||
item.tax_ids[withholding.tax_index].name = withholding.tax_name;
|
||||
item.tax_ids[withholding.tax_index].price = -(price_for_tax * (withholding.tax_rate / 100));
|
||||
|
||||
total_tax_amount += item.tax_ids[withholding.tax_index].price;
|
||||
@ -312,6 +323,7 @@ const app = new Vue({
|
||||
|
||||
if (compounds.length) {
|
||||
compounds.forEach(function(compound) {
|
||||
item.tax_ids[compound.tax_index].name = compound.tax_name;
|
||||
item.tax_ids[compound.tax_index].price = (item.grand_total / 100) * compound.tax_rate;
|
||||
|
||||
totals_taxes = this.calculateTotalsTax(totals_taxes, compound.tax_id, compound.tax_name, item.tax_ids[compound.tax_index].price);
|
||||
@ -448,6 +460,7 @@ const app = new Vue({
|
||||
},
|
||||
|
||||
onSelectedTax(item_index) {
|
||||
|
||||
if (! this.tax_id) {
|
||||
return;
|
||||
}
|
||||
@ -476,6 +489,7 @@ const app = new Vue({
|
||||
}
|
||||
|
||||
this.tax_id = '';
|
||||
this.items[item_index].add_tax = false;
|
||||
|
||||
this.onCalculateTotal();
|
||||
},
|
||||
@ -954,6 +968,7 @@ const app = new Vue({
|
||||
|
||||
form_html.querySelectorAll('[type="submit"]').forEach((submit) => {
|
||||
submit.addEventListener('click', () => {
|
||||
this.minor_form_loading = false;
|
||||
window.onbeforeunload = null;
|
||||
});
|
||||
});
|
||||
@ -968,9 +983,33 @@ const app = new Vue({
|
||||
},
|
||||
|
||||
onSubmitViaSendEmail() {
|
||||
let type_submit_icon = document.querySelector('[type="submit"]').querySelector('i');
|
||||
let type_submit_span = document.querySelector('[type="submit"]').querySelector('span');
|
||||
|
||||
this.form['senddocument'] = true;
|
||||
|
||||
this.minor_form_loading = true;
|
||||
|
||||
if (this.form.loading) {
|
||||
type_submit_icon.classList.add('hidden');
|
||||
type_submit_span.classList.add('opacity-100');
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
if (type_submit_icon && type_submit_span) {
|
||||
type_submit_icon.classList.remove('hidden');
|
||||
type_submit_span.classList.remove('opacity-100');
|
||||
}
|
||||
}, 5000);
|
||||
|
||||
this.onSubmit();
|
||||
|
||||
setTimeout(() => {
|
||||
if (Object.keys(this.form.errors.errors.length > 0)) {
|
||||
this.minor_form_loading = false;
|
||||
return;
|
||||
}
|
||||
}, 200);
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -19,5 +19,7 @@ return [
|
||||
'404' => 'We could not find the page you were looking for.',
|
||||
'500' => 'We will work on fixing that right away.',
|
||||
'record' => 'We could not find the record you were looking for.',
|
||||
'amount' => 'This page contains invalid amounts! Please, contact the system administrator.',
|
||||
],
|
||||
|
||||
];
|
||||
|
@ -79,7 +79,7 @@ return [
|
||||
],
|
||||
|
||||
'sticky' => [
|
||||
'description' => 'You are previewing how your customer will see the web version of your invoice.',
|
||||
'description' => 'You are previewing how your customer will see the web version of your invoice.',
|
||||
],
|
||||
|
||||
];
|
||||
|
@ -41,6 +41,7 @@ return [
|
||||
'reconciled_doc' => 'Warning: You are not allowed to change/delete :type because it has reconciled transactions!',
|
||||
'disable_code' => 'Warning: You are not allowed to disable or change the currency of <b>:name</b> because it has :text related.',
|
||||
'payment_cancel' => 'Warning: You have cancelled your recent :method payment!',
|
||||
'missing_transfer' => 'Warning: The transfer related to this transaction is missing. You should consider deleting this transaction.',
|
||||
],
|
||||
|
||||
];
|
||||
|
@ -13,7 +13,6 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'password' => 'Passwords must be at least six characters and match the confirmation.',
|
||||
'reset' => 'Your password has been reset!',
|
||||
'sent' => 'We have emailed your password reset link!',
|
||||
'throttled' => 'Please wait before retrying.',
|
||||
|
@ -14,6 +14,7 @@ return [
|
||||
*/
|
||||
|
||||
'accepted' => 'The :attribute must be accepted.',
|
||||
'accepted_if' => 'The :attribute must be accepted when :other is :value.',
|
||||
'active_url' => 'The :attribute is not a valid URL.',
|
||||
'after' => 'The :attribute must be a date after :date.',
|
||||
'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
|
||||
@ -24,10 +25,10 @@ return [
|
||||
'before' => 'The :attribute must be a date before :date.',
|
||||
'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
|
||||
'between' => [
|
||||
'numeric' => 'The :attribute must be between :min and :max.',
|
||||
'file' => 'The :attribute must be between :min and :max kilobytes.',
|
||||
'string' => 'The :attribute must be between :min and :max characters.',
|
||||
'array' => 'The :attribute must have between :min and :max items.',
|
||||
'file' => 'The :attribute must be between :min and :max kilobytes.',
|
||||
'numeric' => 'The :attribute must be between :min and :max.',
|
||||
'string' => 'The :attribute must be between :min and :max characters.',
|
||||
],
|
||||
'boolean' => 'The :attribute field must be true or false.',
|
||||
'confirmed' => 'The :attribute confirmation does not match.',
|
||||
@ -35,27 +36,31 @@ return [
|
||||
'date' => 'The :attribute is not a valid date.',
|
||||
'date_equals' => 'The :attribute must be a date equal to :date.',
|
||||
'date_format' => 'The :attribute does not match the format :format.',
|
||||
'declined' => 'The :attribute must be declined.',
|
||||
'declined_if' => 'The :attribute must be declined when :other is :value.',
|
||||
'different' => 'The :attribute and :other must be different.',
|
||||
'digits' => 'The :attribute must be :digits digits.',
|
||||
'digits_between' => 'The :attribute must be between :min and :max digits.',
|
||||
'dimensions' => 'The :attribute has invalid image dimensions.',
|
||||
'distinct' => 'The :attribute field has a duplicate value.',
|
||||
'doesnt_start_with' => 'The :attribute may not start with one of the following: :values.',
|
||||
'email' => 'The :attribute must be a valid email address.',
|
||||
'ends_with' => 'The :attribute must end with one of the following: :values.',
|
||||
'enum' => 'The selected :attribute is invalid.',
|
||||
'exists' => 'The selected :attribute is invalid.',
|
||||
'file' => 'The :attribute must be a file.',
|
||||
'filled' => 'The :attribute field must have a value.',
|
||||
'gt' => [
|
||||
'numeric' => 'The :attribute must be greater than :value.',
|
||||
'file' => 'The :attribute must be greater than :value kilobytes.',
|
||||
'string' => 'The :attribute must be greater than :value characters.',
|
||||
'array' => 'The :attribute must have more than :value items.',
|
||||
'file' => 'The :attribute must be greater than :value kilobytes.',
|
||||
'numeric' => 'The :attribute must be greater than :value.',
|
||||
'string' => 'The :attribute must be greater than :value characters.',
|
||||
],
|
||||
'gte' => [
|
||||
'numeric' => 'The :attribute must be greater than or equal :value.',
|
||||
'file' => 'The :attribute must be greater than or equal :value kilobytes.',
|
||||
'string' => 'The :attribute must be greater than or equal :value characters.',
|
||||
'array' => 'The :attribute must have :value items or more.',
|
||||
'file' => 'The :attribute must be greater than or equal to :value kilobytes.',
|
||||
'numeric' => 'The :attribute must be greater than or equal to :value.',
|
||||
'string' => 'The :attribute must be greater than or equal to :value characters.',
|
||||
],
|
||||
'image' => 'The :attribute must be an image.',
|
||||
'in' => 'The selected :attribute is invalid.',
|
||||
@ -66,61 +71,70 @@ return [
|
||||
'ipv6' => 'The :attribute must be a valid IPv6 address.',
|
||||
'json' => 'The :attribute must be a valid JSON string.',
|
||||
'lt' => [
|
||||
'numeric' => 'The :attribute must be less than :value.',
|
||||
'file' => 'The :attribute must be less than :value kilobytes.',
|
||||
'string' => 'The :attribute must be less than :value characters.',
|
||||
'array' => 'The :attribute must have less than :value items.',
|
||||
'file' => 'The :attribute must be less than :value kilobytes.',
|
||||
'numeric' => 'The :attribute must be less than :value.',
|
||||
'string' => 'The :attribute must be less than :value characters.',
|
||||
],
|
||||
'lte' => [
|
||||
'numeric' => 'The :attribute must be less than or equal :value.',
|
||||
'file' => 'The :attribute must be less than or equal :value kilobytes.',
|
||||
'string' => 'The :attribute must be less than or equal :value characters.',
|
||||
'array' => 'The :attribute must not have more than :value items.',
|
||||
'file' => 'The :attribute must be less than or equal to :value kilobytes.',
|
||||
'numeric' => 'The :attribute must be less than or equal to :value.',
|
||||
'string' => 'The :attribute must be less than or equal to :value characters.',
|
||||
],
|
||||
'mac_address' => 'The :attribute must be a valid MAC address.',
|
||||
'max' => [
|
||||
'numeric' => 'The :attribute must not be greater than :max.',
|
||||
'file' => 'The :attribute must not be greater than :max kilobytes.',
|
||||
'string' => 'The :attribute must not be greater than :max characters.',
|
||||
'array' => 'The :attribute must not have more than :max items.',
|
||||
'file' => 'The :attribute must not be greater than :max kilobytes.',
|
||||
'numeric' => 'The :attribute must not be greater than :max.',
|
||||
'string' => 'The :attribute must not be greater than :max characters.',
|
||||
],
|
||||
'mimes' => 'The :attribute must be a file of type: :values.',
|
||||
'mimetypes' => 'The :attribute must be a file of type: :values.',
|
||||
'min' => [
|
||||
'numeric' => 'The :attribute must be at least :min.',
|
||||
'file' => 'The :attribute must be at least :min kilobytes.',
|
||||
'string' => 'The :attribute must be at least :min characters.',
|
||||
'array' => 'The :attribute must have at least :min items.',
|
||||
'file' => 'The :attribute must be at least :min kilobytes.',
|
||||
'numeric' => 'The :attribute must be at least :min.',
|
||||
'string' => 'The :attribute must be at least :min characters.',
|
||||
],
|
||||
'multiple_of' => 'The :attribute must be a multiple of :value.',
|
||||
'not_in' => 'The selected :attribute is invalid.',
|
||||
'not_regex' => 'The :attribute format is invalid.',
|
||||
'numeric' => 'The :attribute must be a number.',
|
||||
'password' => 'The password is incorrect.',
|
||||
'password' => [
|
||||
'letters' => 'The :attribute must contain at least one letter.',
|
||||
'mixed' => 'The :attribute must contain at least one uppercase and one lowercase letter.',
|
||||
'numbers' => 'The :attribute must contain at least one number.',
|
||||
'symbols' => 'The :attribute must contain at least one symbol.',
|
||||
'uncompromised' => 'The given :attribute has appeared in a data leak. Please choose a different :attribute.',
|
||||
],
|
||||
'present' => 'The :attribute field must be present.',
|
||||
'prohibited' => 'The :attribute field is prohibited.',
|
||||
'prohibited_if' => 'The :attribute field is prohibited when :other is :value.',
|
||||
'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.',
|
||||
'prohibits' => 'The :attribute field prohibits :other from being present.',
|
||||
'regex' => 'The :attribute format is invalid.',
|
||||
'required' => 'The :attribute field is required.',
|
||||
'required_array_keys' => 'The :attribute field must contain entries for: :values.',
|
||||
'required_if' => 'The :attribute field is required when :other is :value.',
|
||||
'required_unless' => 'The :attribute field is required unless :other is in :values.',
|
||||
'required_with' => 'The :attribute field is required when :values is present.',
|
||||
'required_with_all' => 'The :attribute field is required when :values are present.',
|
||||
'required_without' => 'The :attribute field is required when :values is not present.',
|
||||
'required_without_all' => 'The :attribute field is required when none of :values are present.',
|
||||
'prohibited' => 'The :attribute field is prohibited.',
|
||||
'prohibited_if' => 'The :attribute field is prohibited when :other is :value.',
|
||||
'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.',
|
||||
'same' => 'The :attribute and :other must match.',
|
||||
'size' => [
|
||||
'numeric' => 'The :attribute must be :size.',
|
||||
'file' => 'The :attribute must be :size kilobytes.',
|
||||
'string' => 'The :attribute must be :size characters.',
|
||||
'array' => 'The :attribute must contain :size items.',
|
||||
'file' => 'The :attribute must be :size kilobytes.',
|
||||
'numeric' => 'The :attribute must be :size.',
|
||||
'string' => 'The :attribute must be :size characters.',
|
||||
],
|
||||
'starts_with' => 'The :attribute must start with one of the following: :values.',
|
||||
'string' => 'The :attribute must be a string.',
|
||||
'timezone' => 'The :attribute must be a valid zone.',
|
||||
'timezone' => 'The :attribute must be a valid timezone.',
|
||||
'unique' => 'The :attribute has already been taken.',
|
||||
'uploaded' => 'The :attribute failed to upload.',
|
||||
'url' => 'The :attribute format is invalid.',
|
||||
'url' => 'The :attribute must be a valid URL.',
|
||||
'uuid' => 'The :attribute must be a valid UUID.',
|
||||
|
||||
/*
|
||||
|
@ -51,7 +51,10 @@
|
||||
:currency="$currency"
|
||||
/>
|
||||
|
||||
<x-form.group.account form-group-class="col-span-10 lg:col-span-5 xl:col-span-2 account-input" />
|
||||
<x-form.group.account
|
||||
form-group-class="col-span-10 lg:col-span-5 xl:col-span-2 account-input"
|
||||
selected="{{ request('account_id', setting('default.account')) }}"
|
||||
/>
|
||||
|
||||
<div class="flex items-end lg:justify-end xl:justify-start col-span-10 xl:col-span-2">
|
||||
<x-button
|
||||
@ -167,11 +170,11 @@
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<tbody class="float-right">
|
||||
<tr class="border-b">
|
||||
<th class="w-11/12 ltr:pr-6 rtl:pl-6 py-4 ltr:text-left rtl:text-right whitespace-nowrap text-sm font-bold text-black">
|
||||
<th class="w-9/12 ltr:pr-6 rtl:pl-6 py-4 ltr:text-left rtl:text-right whitespace-nowrap text-sm font-bold text-black">
|
||||
{{ trans('reconciliations.opening_balance') }}:
|
||||
</th>
|
||||
|
||||
<td id="closing-balance" class="w-1/12 ltr:text-right rtl:text-left">
|
||||
<td id="closing-balance" class="w-3/12 ltr:text-right rtl:text-left">
|
||||
<span class="w-auto pl-6 text-sm">
|
||||
<x-money :amount="$opening_balance" :currency="$account->currency_code" convert />
|
||||
</span>
|
||||
@ -179,11 +182,11 @@
|
||||
</tr>
|
||||
|
||||
<tr class="border-b">
|
||||
<th class="w-11/12 ltr:pr-6 rtl:pl-6 py-4 ltr:text-left rtl:text-right whitespace-nowrap text-sm font-bold text-black">
|
||||
<th class="w-9/12 ltr:pr-6 rtl:pl-6 py-4 ltr:text-left rtl:text-right whitespace-nowrap text-sm font-bold text-black">
|
||||
{{ trans('reconciliations.closing_balance') }}:
|
||||
</th>
|
||||
|
||||
<td id="closing-balance" class="w-1/12 text-right">
|
||||
<td id="closing-balance" class="w-3/12 text-right">
|
||||
<x-form.input.money
|
||||
name="closing_balance_total"
|
||||
value="0"
|
||||
@ -192,18 +195,18 @@
|
||||
v-model="totals.closing_balance"
|
||||
:currency="$currency"
|
||||
dynamicCurrency="currency"
|
||||
money-class="text-right disabled-money banking-price-text w-auto position-absolute right-4 ltr:pr-0 rtl:pl-0 text-sm js-conversion-input"
|
||||
money-class="text-right disabled-money banking-price-text w-auto position-absolute right-4 ltr:pr-0 rtl:pl-0 text-sm"
|
||||
form-group-class="text-right disabled-money"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="border-b">
|
||||
<th class="w-11/12 ltr:pr-6 rtl:pl-6 py-4 ltr:text-left rtl:text-right whitespace-nowrap text-sm font-bold text-black">
|
||||
<th class="w-9/12 ltr:pr-6 rtl:pl-6 py-4 ltr:text-left rtl:text-right whitespace-nowrap text-sm font-bold text-black">
|
||||
{{ trans('reconciliations.cleared_amount') }}:
|
||||
</th>
|
||||
|
||||
<td id="cleared-amount" class="w-1/12 text-right">
|
||||
<td id="cleared-amount" class="w-3/12 text-right">
|
||||
<x-form.input.money
|
||||
name="cleared_amount_total"
|
||||
value="0"
|
||||
@ -212,20 +215,20 @@
|
||||
v-model="totals.cleared_amount"
|
||||
:currency="$currency"
|
||||
dynamicCurrency="currency"
|
||||
money-class="text-right disabled-money banking-price-text w-auto position-absolute right-4 ltr:pr-0 rtl:pl-0 text-sm js-conversion-input"
|
||||
money-class="text-right disabled-money banking-price-text w-auto position-absolute right-4 ltr:pr-0 rtl:pl-0 text-sm"
|
||||
form-group-class="text-right disabled-money"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="border-b">
|
||||
<th class="w-11/12 ltr:pr-6 rtl:pl-6 py-4 ltr:text-left rtl:text-right whitespace-nowrap text-sm font-bold text-black cursor-pointer">
|
||||
<th class="w-9/12 ltr:pr-6 rtl:pl-6 py-4 ltr:text-left rtl:text-right whitespace-nowrap text-sm font-bold text-black cursor-pointer">
|
||||
<span class="px-2 py-1 rounded-xl" :class="difference">
|
||||
{{ trans('general.difference') }}
|
||||
</span>
|
||||
</th>
|
||||
|
||||
<td id="difference" class="w-1/12 ltr:pl-6 rtl:pr-0 text-right">
|
||||
<td id="difference" class="w-3/12 ltr:pl-6 rtl:pr-0 text-right">
|
||||
<div class="difference-money">
|
||||
<x-form.input.money
|
||||
name="difference_total"
|
||||
@ -235,7 +238,7 @@
|
||||
v-model="totals.difference"
|
||||
:currency="$currency"
|
||||
dynamicCurrency="currency"
|
||||
money-class="text-right disabled-money banking-price-text w-auto position-absolute right-4 ltr:pr-0 rtl:pl-0 text-sm js-conversion-input"
|
||||
money-class="text-right disabled-money banking-price-text w-auto position-absolute right-4 ltr:pr-0 rtl:pl-0 text-sm"
|
||||
form-group-class="text-right disabled-money"
|
||||
/>
|
||||
</div>
|
||||
@ -264,37 +267,38 @@
|
||||
class="flex items-center justify-center bg-transparent hover:bg-gray-200 px-3 py-1.5 text-base rounded-lg disabled:opacity-50"
|
||||
override="class"
|
||||
>
|
||||
<x-button.loading>
|
||||
<x-button.loading action="! reconcile && form.loading">
|
||||
{{ trans('reconciliations.save_draft') }}
|
||||
</x-button.loading>
|
||||
</x-button>
|
||||
|
||||
<div v-if="reconcile">
|
||||
|
||||
<div v-if="! reconcile">
|
||||
<x-tooltip id="tooltip-reconcile" placement="top" message="{{ trans('reconciliations.irreconcilable') }}">
|
||||
<x-button
|
||||
type="button"
|
||||
::disabled="reconcile || form.loading"
|
||||
class="relative flex items-center justify-center px-3 py-1.5 ltr:ml-2 rtl:mr-2 text-white text-base rounded-lg bg-blue-300 hover:bg-blue-500 disabled:bg-blue-100"
|
||||
::disabled="! reconcile"
|
||||
class="relative flex items-center justify-center px-3 py-1.5 ltr:ml-2 rtl:mr-2 text-white text-base rounded-lg bg-blue hover:bg-blue-700 disabled:bg-blue-100"
|
||||
override="class"
|
||||
@click="onReconcileSubmit"
|
||||
data-loading-text="{{ trans('general.loading') }}"
|
||||
>
|
||||
<x-button.loading action="! reconcile">
|
||||
<x-button.loading action="reconcile && form.loading">
|
||||
{{ trans('reconciliations.reconcile') }}
|
||||
</x-button.loading>
|
||||
</x-button>
|
||||
</x-tooltip>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<x-button
|
||||
type="button"
|
||||
::disabled="reconcile || form.loading"
|
||||
class="relative flex items-center justify-center px-3 py-1.5 ltr:ml-2 rtl:mr-2 text-white text-base rounded-lg bg-blue-300 hover:bg-blue-500 disabled:bg-blue-100"
|
||||
::disabled="! reconcile"
|
||||
class="relative flex items-center justify-center px-3 py-1.5 ltr:ml-2 rtl:mr-2 text-white text-base rounded-lg bg-blue hover:bg-blue-700 disabled:bg-blue-100"
|
||||
override="class"
|
||||
@click="onReconcileSubmit"
|
||||
data-loading-text="{{ trans('general.loading') }}"
|
||||
>
|
||||
<x-button.loading action="! reconcile">
|
||||
<x-button.loading action="reconcile && form.loading">
|
||||
{{ trans('reconciliations.reconcile') }}
|
||||
</x-button.loading>
|
||||
</x-button>
|
||||
|
@ -105,11 +105,11 @@
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<tbody class="float-right">
|
||||
<tr class="border-b">
|
||||
<th class="w-11/12 ltr:pr-6 rtl:pl-6 py-4 ltr:text-left rtl:text-right whitespace-nowrap text-sm font-bold text-black">
|
||||
<th class="w-9/12 ltr:pr-6 rtl:pl-6 py-4 ltr:text-left rtl:text-right whitespace-nowrap text-sm font-bold text-black">
|
||||
{{ trans('reconciliations.opening_balance') }}:
|
||||
</th>
|
||||
|
||||
<td id="closing-balance" class="w-1/12 text-right">
|
||||
<td id="closing-balance" class="w-3/12 text-right">
|
||||
<span class="w-auto pl-6 text-sm">
|
||||
<x-money :amount="$opening_balance" :currency="$account->currency_code" convert />
|
||||
</span>
|
||||
@ -117,11 +117,11 @@
|
||||
</tr>
|
||||
|
||||
<tr class="border-b">
|
||||
<th class="w-11/12 ltr:pr-6 rtl:pl-6 py-4 ltr:text-left rtl:text-right whitespace-nowrap text-sm font-bold text-black">
|
||||
<th class="w-9/12 ltr:pr-6 rtl:pl-6 py-4 ltr:text-left rtl:text-right whitespace-nowrap text-sm font-bold text-black">
|
||||
{{ trans('reconciliations.closing_balance') }}:
|
||||
</th>
|
||||
|
||||
<td id="closing-balance" class="w-1/12 text-right">
|
||||
<td id="closing-balance" class="w-3/12 text-right">
|
||||
<x-form.input.money
|
||||
name="closing_balance_total"
|
||||
value="0"
|
||||
@ -130,18 +130,18 @@
|
||||
v-model="totals.closing_balance"
|
||||
:currency="$currency"
|
||||
dynamicCurrency="currency"
|
||||
money-class="text-right disabled-money banking-price-text w-auto position-absolute right-4 ltr:pr-0 rtl:pl-0 text-sm js-conversion-input"
|
||||
money-class="text-right disabled-money banking-price-text w-auto position-absolute right-4 ltr:pr-0 rtl:pl-0 text-sm"
|
||||
form-group-class="text-right disabled-money"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="border-b">
|
||||
<th class="w-11/12 ltr:pr-6 rtl:pl-6 py-4 ltr:text-left rtl:text-right whitespace-nowrap text-sm font-bold text-black">
|
||||
<th class="w-9/12 ltr:pr-6 rtl:pl-6 py-4 ltr:text-left rtl:text-right whitespace-nowrap text-sm font-bold text-black">
|
||||
{{ trans('reconciliations.cleared_amount') }}:
|
||||
</th>
|
||||
|
||||
<td id="cleared-amount" class="w-1/12 text-right">
|
||||
<td id="cleared-amount" class="w-3/12 text-right">
|
||||
<x-form.input.money
|
||||
name="cleared_amount_total"
|
||||
value="0"
|
||||
@ -150,20 +150,20 @@
|
||||
v-model="totals.cleared_amount"
|
||||
:currency="$currency"
|
||||
dynamicCurrency="currency"
|
||||
money-class="text-right disabled-money banking-price-text w-auto position-absolute right-4 ltr:pr-0 rtl:pl-0 text-sm js-conversion-input"
|
||||
money-class="text-right disabled-money banking-price-text w-auto position-absolute right-4 ltr:pr-0 rtl:pl-0 text-sm"
|
||||
form-group-class="text-right disabled-money"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th class="w-11/12 ltr:pr-6 rtl:pl-6 py-4 ltr:text-left rtl:text-right whitespace-nowrap text-sm font-bold text-black cursor-pointer">
|
||||
<th class="w-9/12 ltr:pr-6 rtl:pl-6 py-4 ltr:text-left rtl:text-right whitespace-nowrap text-sm font-bold text-black cursor-pointer">
|
||||
<span class="px-2 py-1 rounded-xl" :class="difference">
|
||||
{{ trans('general.difference') }}
|
||||
</span>
|
||||
</th>
|
||||
|
||||
<td id="difference" class="w-1/12 ltr:pl-6 rtl:pr-0 text-right">
|
||||
<td id="difference" class="w-3/12 ltr:pl-6 rtl:pr-0 text-right">
|
||||
<div class="difference-money">
|
||||
<x-form.input.money
|
||||
name="difference_total"
|
||||
@ -173,7 +173,7 @@
|
||||
v-model="totals.difference"
|
||||
:currency="$currency"
|
||||
dynamicCurrency="currency"
|
||||
money-class="text-right disabled-money banking-price-text w-auto position-absolute right-4 ltr:pr-0 rtl:pl-0 text-sm js-conversion-input"
|
||||
money-class="text-right disabled-money banking-price-text w-auto position-absolute right-4 ltr:pr-0 rtl:pl-0 text-sm"
|
||||
form-group-class="text-right disabled-money"
|
||||
/>
|
||||
</div>
|
||||
@ -203,22 +203,22 @@
|
||||
class="relative flex items-center justify-center bg-transparent hover:bg-gray-200 px-3 py-1.5 text-base rounded-lg disabled:opacity-50"
|
||||
override="class"
|
||||
>
|
||||
<x-button.loading>
|
||||
<x-button.loading action="! reconcile && form.loading">
|
||||
{{ trans('general.save') }}
|
||||
</x-button.loading>
|
||||
</x-button>
|
||||
|
||||
<div v-if="reconcile">
|
||||
<div v-if="! reconcile">
|
||||
<x-tooltip id="tooltip-reconcile" placement="top" message="{{ trans('reconciliations.irreconcilable') }}">
|
||||
<x-button
|
||||
type="button"
|
||||
::disabled="reconcile || form.loading"
|
||||
class="relative flex items-center justify-center px-3 py-1.5 ltr:ml-2 rtl:mr-2 text-white text-base rounded-lg bg-blue-300 hover:bg-blue-500 disabled:bg-blue-100"
|
||||
::disabled="! reconcile"
|
||||
class="relative flex items-center justify-center px-3 py-1.5 ltr:ml-2 rtl:mr-2 text-white text-base rounded-lg bg-blue hover:bg-blue-700 disabled:bg-blue-100"
|
||||
override="class"
|
||||
@click="onReconcileSubmit"
|
||||
data-loading-text="{{ trans('general.loading') }}"
|
||||
>
|
||||
<x-button.loading action="! reconcile">
|
||||
<x-button.loading action="reconcile && form.loading">
|
||||
{{ trans('reconciliations.reconcile') }}
|
||||
</x-button.loading>
|
||||
</x-button>
|
||||
@ -228,13 +228,13 @@
|
||||
<div v-else>
|
||||
<x-button
|
||||
type="button"
|
||||
::disabled="reconcile || form.loading"
|
||||
class="relative flex items-center justify-center px-3 py-1.5 ltr:ml-2 rtl:mr-2 text-white text-base rounded-lg bg-blue-300 hover:bg-blue-500 disabled:bg-blue-100"
|
||||
::disabled="! reconcile"
|
||||
class="relative flex items-center justify-center px-3 py-1.5 ltr:ml-2 rtl:mr-2 text-white text-base rounded-lg bg-blue hover:bg-blue-700 disabled:bg-blue-100"
|
||||
override="class"
|
||||
@click="onReconcileSubmit"
|
||||
data-loading-text="{{ trans('general.loading') }}"
|
||||
>
|
||||
<x-button.loading action="! reconcile">
|
||||
<x-button.loading action="reconcile && form.loading">
|
||||
{{ trans('reconciliations.reconcile') }}
|
||||
</x-button.loading>
|
||||
</x-button>
|
||||
|
@ -6,7 +6,6 @@
|
||||
add-new
|
||||
path="{{ $path }}"
|
||||
|
||||
add-new
|
||||
name="{{ $name }}"
|
||||
label="{!! $label !!}"
|
||||
:options="$contacts"
|
||||
@ -26,7 +25,6 @@
|
||||
add-new
|
||||
path="{{ $path }}"
|
||||
|
||||
add-new
|
||||
name="{{ $name }}"
|
||||
label="{!! $label !!}"
|
||||
:options="$contacts"
|
||||
|
@ -47,6 +47,24 @@
|
||||
:dynamic-options="{{ $attributes['dynamicOptions'] }}"
|
||||
@endif
|
||||
|
||||
@if (! empty($attributes['searchable']))
|
||||
searchable
|
||||
@elseif (! empty($searchable))
|
||||
searchable
|
||||
@endif
|
||||
|
||||
@if (isset($attributes['fullOptions']) || isset($attributes['full-options']))
|
||||
:full-options="{{ json_encode(! empty($attributes['fullOptions']) ? $attributes['fullOptions'] : $attributes['full-options']) }}"
|
||||
@else
|
||||
:full-options="{{ json_encode($fullOptions) }}"
|
||||
@endif
|
||||
|
||||
@if (isset($attributes['searchText']) || isset($attributes['search-text']))
|
||||
search-text="{{ ! empty($attributes['searchText']) ? $attributes['searchText'] : $attributes['search-text'] }}"
|
||||
@else
|
||||
search-text="{{ $searchText }}"
|
||||
@endif
|
||||
|
||||
@if (empty($multiple))
|
||||
@if (isset($selected) || old($name))
|
||||
value="{{ old($name, $selected) }}"
|
||||
@ -107,6 +125,10 @@
|
||||
@change="{{ $attributes['change'] }}($event)"
|
||||
@endif
|
||||
|
||||
@if (! empty($attributes['focus']))
|
||||
@focus="{{ $attributes['focus'] }}"
|
||||
@endif
|
||||
|
||||
@if (! empty($attributes['visible-change']))
|
||||
@visible-change="{{ $attributes['visible-change'] }}"
|
||||
@endif
|
||||
|
@ -47,6 +47,24 @@
|
||||
:dynamic-options="{{ $attributes['dynamicOptions'] }}"
|
||||
@endif
|
||||
|
||||
@if (! empty($attributes['searchable']))
|
||||
searchable
|
||||
@elseif (! empty($searchable))
|
||||
searchable
|
||||
@endif
|
||||
|
||||
@if (isset($attributes['fullOptions']) || isset($attributes['full-options']))
|
||||
:full-options="{{ json_encode(! empty($attributes['fullOptions']) ? $attributes['fullOptions'] : $attributes['full-options']) }}"
|
||||
@else
|
||||
:full-options="{{ json_encode($fullOptions) }}"
|
||||
@endif
|
||||
|
||||
@if (isset($attributes['searchText']) || isset($attributes['search-text']))
|
||||
search-text="{{ ! empty($attributes['searchText']) ? $attributes['searchText'] : $attributes['search-text'] }}"
|
||||
@else
|
||||
search-text="{{ $searchText }}"
|
||||
@endif
|
||||
|
||||
@if (empty($multiple))
|
||||
@if (isset($selected) || old($name))
|
||||
value="{{ old($name, $selected) }}"
|
||||
|
@ -1,10 +1,15 @@
|
||||
@if ($transaction->isTransferTransaction())
|
||||
@php
|
||||
$from_account = '<span class="font-medium">' . $transaction->transfer->expense_account->title . '</span>';
|
||||
$to_account = '<span class="font-medium">' . $transaction->transfer->income_account->title . '</span>';
|
||||
@endphp
|
||||
@php $transfer = $transaction->transfer; @endphp
|
||||
|
||||
<div class="border-b pb-4" x-data="{ transfer : null }">
|
||||
@if ($transfer)
|
||||
@php
|
||||
$from_account = '<span class="font-medium">' . $transfer->expense_account->title . '</span>';
|
||||
$to_account = '<span class="font-medium">' . $transfer->income_account->title . '</span>';
|
||||
$date = '<a href="' . route('transfers.show', $transfer->id) . '" class="text-purple">' . company_date($transaction->paid_at) . '</a>';
|
||||
@endphp
|
||||
@endif
|
||||
|
||||
<div class="border-b pb-4" x-data="{ transfer : 1 }">
|
||||
<button class="relative w-full text-left cursor-pointer group"
|
||||
x-on:click="transfer !== 1 ? transfer = 1 : transfer = null"
|
||||
>
|
||||
@ -12,9 +17,11 @@
|
||||
{{ trans_choice('general.transfers', 1) }}
|
||||
</span>
|
||||
|
||||
<div class="text-black-400 text-sm">
|
||||
{!! trans('transactions.slider.transfer_headline', ['from_account' => $from_account, 'to_account' => $to_account]) !!}
|
||||
</div>
|
||||
@if ($transfer)
|
||||
<div class="text-black-400 text-sm">
|
||||
{!! trans('transactions.slider.transfer_headline', ['from_account' => $from_account, 'to_account' => $to_account]) !!}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<span class="material-icons absolute right-0 top-0 transition-all transform"
|
||||
x-bind:class="transfer === 1 ? 'rotate-180' : ''"
|
||||
@ -25,13 +32,19 @@
|
||||
x-ref="container1"
|
||||
x-bind:class="transfer === 1 ? 'h-auto' : 'scale-y-0 h-0'"
|
||||
>
|
||||
@php
|
||||
$date = '<a href="' . route('transfers.show', $transaction->transfer->id) . '" class="text-purple">' . company_date($transaction->paid_at) . '</a>';
|
||||
@endphp
|
||||
|
||||
<div class="my-2">
|
||||
{!! trans('transactions.slider.transfer_desc', ['date' => $date]) !!}
|
||||
</div>
|
||||
@if ($transfer)
|
||||
<div class="my-2">
|
||||
{!! trans('transactions.slider.transfer_desc', ['date' => $date]) !!}
|
||||
</div>
|
||||
@else
|
||||
<div class="mt-2">
|
||||
<div class="alert alert-notify p-4 text-black font-bold rounded-lg bg-orange-100 text-orange-600">
|
||||
<span class="alert-text">
|
||||
<span>{{ trans('messages.warning.missing_transfer') }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
@ -14,6 +14,12 @@
|
||||
{{ trans('errors.title.403') }}
|
||||
</span>
|
||||
|
||||
@if (! empty($message))
|
||||
<span class="text-lg">
|
||||
{{ $message }}
|
||||
</span>
|
||||
@endif
|
||||
|
||||
@php $landing_page = user() ? user()->getLandingPageOfUser() : route('login'); @endphp
|
||||
<a href="{{ $landing_page }}" class="relative flex items-center justify-center bg-green hover:bg-green-700 text-white px-6 py-1.5 text-base rounded-lg disabled:bg-green-100 mt-3">
|
||||
{{ trans('general.go_to_dashboard') }}
|
||||
|
@ -14,6 +14,12 @@
|
||||
{{ trans('errors.title.404') }}
|
||||
</span>
|
||||
|
||||
@if (! empty($message))
|
||||
<span class="text-lg">
|
||||
{{ $message }}
|
||||
</span>
|
||||
@endif
|
||||
|
||||
@php $landing_page = user() ? user()->getLandingPageOfUser() : route('login'); @endphp
|
||||
<a href="{{ $landing_page }}" class="relative flex items-center justify-center bg-green hover:bg-green-700 text-white px-6 py-1.5 text-base rounded-lg disabled:bg-green-100 mt-3">
|
||||
{{ trans('general.go_to_dashboard') }}
|
||||
|
@ -14,6 +14,12 @@
|
||||
{{ trans('errors.title.500') }}
|
||||
</span>
|
||||
|
||||
@if (! empty($message))
|
||||
<span class="text-lg">
|
||||
{{ $message }}
|
||||
</span>
|
||||
@endif
|
||||
|
||||
@php $landing_page = user() ? user()->getLandingPageOfUser() : route('login'); @endphp
|
||||
<a href="{{ $landing_page }}" class="relative flex items-center justify-center bg-green hover:bg-green-700 text-white px-6 py-1.5 text-base rounded-lg disabled:bg-green-100 mt-3">
|
||||
{{ trans('general.go_to_dashboard') }}
|
||||
|
@ -4,7 +4,9 @@
|
||||
|
||||
<x-form.group.color name="color" label="{{ trans('general.color') }}" form-group-class="col-span-6" />
|
||||
|
||||
<x-form.input.hidden name="type" :value="$type" />
|
||||
<x-form.group.select name="parent_id" label="{{ trans('general.parent') . ' ' . trans_choice('general.categories', 1) }}" :options="$categories" not-required sort-options="false" searchable form-group-class="col-span-6" />
|
||||
|
||||
<x-form.input.hidden name="type" :value="'{{ $type }}'" @change="updateParentCategories" />
|
||||
<x-form.input.hidden name="enabled" value="1" />
|
||||
</div>
|
||||
</x-form>
|
||||
|
@ -14,9 +14,21 @@
|
||||
</x-slot>
|
||||
|
||||
<x-slot name="content">
|
||||
<x-modules.purchased />
|
||||
@if (! empty($purchase) || ! empty($installed))
|
||||
<x-modules.purchased />
|
||||
|
||||
<x-modules.installed />
|
||||
<x-modules.installed />
|
||||
@else
|
||||
<div class="py-6 font-medium">
|
||||
<div class="flex items-center justify-between mb-5 lg:mb-0">
|
||||
<h4 class="py-3 font-medium lg:text-2xl">
|
||||
{{ trans('modules.my_apps') }}
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<x-modules.no-apps />
|
||||
</div>
|
||||
@endif
|
||||
</x-slot>
|
||||
|
||||
<x-script folder="modules" file="apps" />
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
<x-form.group.select name="type" label="{{ trans_choice('general.types', 1) }}" :options="$types" :selected="config('general.types')" change="updateParentCategories" />
|
||||
|
||||
<x-form.group.select name="parent_id" label="{{ trans('general.parent') . ' ' . trans_choice('general.categories', 1) }}" :options="[]" not-required dynamicOptions="categoriesBasedTypes" sort-options="false" disabled="isParentCategoryDisabled" />
|
||||
<x-form.group.select name="parent_id" label="{{ trans('general.parent') . ' ' . trans_choice('general.categories', 1) }}" :options="[]" not-required dynamicOptions="categoriesBasedTypes" sort-options="false" v-disabled="isParentCategoryDisabled" />
|
||||
|
||||
<x-form.input.hidden name="categories" value="{{ json_encode($categories) }}" />
|
||||
</x-slot>
|
||||
|
@ -24,7 +24,7 @@
|
||||
<x-form.group.select name="type" label="{{ trans_choice('general.types', 1) }}" :options="$types" change="updateParentCategories" />
|
||||
@endif
|
||||
|
||||
<x-form.group.select name="parent_id" label="{{ trans('general.parent') . ' ' . trans_choice('general.categories', 1) }}" :options="$categories[$category->type]" not-required dynamicOptions="categoriesBasedTypes" sort-options="false" />
|
||||
<x-form.group.select name="parent_id" label="{{ trans('general.parent') . ' ' . trans_choice('general.categories', 1) }}" :options="$categories[$category->type]" not-required dynamicOptions="categoriesBasedTypes" sort-options="false" v-disabled="isParentCategoryDisabled" />
|
||||
|
||||
<x-form.input.hidden name="categories" value="{{ json_encode($categories) }}" />
|
||||
<x-form.input.hidden name="parent_category_id" :value="$category->parent_id" />
|
||||
|
@ -20,7 +20,7 @@
|
||||
<x-slot name="body">
|
||||
<x-form.group.text name="name" label="{{ trans('general.name') }}" />
|
||||
|
||||
<x-form.group.select name="code" label="{{ trans('currencies.code') }}" :options="$codes" change="onChangeCode" />
|
||||
<x-form.group.select name="code" label="{{ trans('currencies.code') }}" :options="$codes" searchable change="onChangeCode" />
|
||||
|
||||
<x-form.group.text name="rate" label="{{ trans('currencies.rate') }}" @input="onChangeRate" />
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
<x-slot name="body">
|
||||
<x-form.group.text name="name" label="{{ trans('general.name') }}" />
|
||||
|
||||
<x-form.group.select name="code" label="{{ trans('currencies.code') }}" :options="$codes" change="onChangeCode" />
|
||||
<x-form.group.select name="code" label="{{ trans('currencies.code') }}" :options="$codes" searchable change="onChangeCode" />
|
||||
|
||||
<x-form.group.text name="rate" label="{{ trans('currencies.rate') }}" @input="onChangeRate" />
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user