Merge branch 'akaunting:master' into master
This commit is contained in:
commit
f19e107f76
@ -12,6 +12,7 @@ use App\Http\Requests\Common\Import as ImportRequest;
|
||||
use App\Imports\Banking\Transactions as Import;
|
||||
use App\Jobs\Banking\CreateTransaction;
|
||||
use App\Jobs\Banking\DeleteTransaction;
|
||||
use App\Jobs\Banking\DuplicateTransaction;
|
||||
use App\Jobs\Banking\MatchBankingDocumentTransaction;
|
||||
use App\Jobs\Banking\SplitTransaction;
|
||||
use App\Jobs\Banking\UpdateTransaction;
|
||||
@ -139,7 +140,7 @@ class Transactions extends Controller
|
||||
*/
|
||||
public function duplicate(Transaction $transaction)
|
||||
{
|
||||
$clone = $transaction->duplicate();
|
||||
$clone = $this->dispatch(new DuplicateTransaction($transaction));
|
||||
|
||||
$message = trans('messages.success.duplicated', ['type' => trans_choice('general.transactions', 1)]);
|
||||
|
||||
|
@ -28,6 +28,8 @@ class Neww extends Component
|
||||
|
||||
foreach($menu->getItems() as $item) {
|
||||
if ($this->availableInSearch($item)) {
|
||||
$this->neww[] = $item;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,8 @@ class Settings extends Component
|
||||
}
|
||||
|
||||
if ($this->availableInSearch($item)) {
|
||||
$this->settings[] = $item;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
30
app/Jobs/Banking/DuplicateTransaction.php
Normal file
30
app/Jobs/Banking/DuplicateTransaction.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Banking;
|
||||
|
||||
use App\Abstracts\Job;
|
||||
use App\Events\Banking\TransactionCreated;
|
||||
use App\Models\Banking\Transaction;
|
||||
|
||||
class DuplicateTransaction extends Job
|
||||
{
|
||||
protected $clone;
|
||||
|
||||
public function __construct(Transaction $model)
|
||||
{
|
||||
$this->model = $model;
|
||||
|
||||
parent::__construct($model);
|
||||
}
|
||||
|
||||
public function handle(): Transaction
|
||||
{
|
||||
\DB::transaction(function () {
|
||||
$this->clone = $this->model->duplicate();
|
||||
});
|
||||
|
||||
event(new TransactionCreated($this->clone, request()));
|
||||
|
||||
return $this->clone;
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ class Account extends Model
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $appends = ['balance'];
|
||||
protected $appends = ['balance', 'title'];
|
||||
|
||||
/**
|
||||
* Attributes that should be mass-assignable.
|
||||
@ -89,6 +89,20 @@ class Account extends Model
|
||||
->select(['accounts.*', 'accounts.opening_balance as balance']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name with currency.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitleAttribute()
|
||||
{
|
||||
if ($this->currency->symbol) {
|
||||
return $this->name . ' (' . $this->currency->symbol . ')';
|
||||
}
|
||||
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current balance.
|
||||
*
|
||||
|
@ -54,7 +54,7 @@ class Transfer extends Model
|
||||
|
||||
public function expense_transaction()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Banking\Transaction', 'expense_transaction_id');
|
||||
return $this->belongsTo('App\Models\Banking\Transaction', 'expense_transaction_id')->withDefault(['name' => trans('general.na')]);
|
||||
}
|
||||
|
||||
public function expense_account()
|
||||
@ -70,7 +70,7 @@ class Transfer extends Model
|
||||
|
||||
public function income_transaction()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Banking\Transaction', 'income_transaction_id');
|
||||
return $this->belongsTo('App\Models\Banking\Transaction', 'income_transaction_id')->withDefault(['name' => trans('general.na')]);
|
||||
}
|
||||
|
||||
public function income_account()
|
||||
|
@ -13,6 +13,22 @@ class Account extends Form
|
||||
|
||||
public $accounts;
|
||||
|
||||
/** @var bool */
|
||||
public $hideCurrency;
|
||||
|
||||
/** @var string */
|
||||
public $formGroupClass;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(bool $hideCurrency = false, string $formGroupClass = 'sm:col-span-3') {
|
||||
$this->hideCurrency = $hideCurrency;
|
||||
$this->formGroupClass = $formGroupClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
@ -26,7 +42,7 @@ class Account extends Form
|
||||
|
||||
$this->path = route('modals.accounts.create');
|
||||
|
||||
$this->accounts = Model::enabled()->orderBy('name')->pluck('name', 'id');
|
||||
$this->accounts = $this->getAccounts();
|
||||
|
||||
if (empty($this->selected) && empty($this->getParentData('model'))) {
|
||||
$this->selected = setting('default.account');
|
||||
@ -34,4 +50,13 @@ class Account extends Form
|
||||
|
||||
return view('components.form.group.account');
|
||||
}
|
||||
|
||||
protected function getAccounts()
|
||||
{
|
||||
if ($this->hideCurrency) {
|
||||
return Model::enabled()->orderBy('name')->pluck('name', 'id');
|
||||
}
|
||||
|
||||
return Model::enabled()->orderBy('name')->get()->pluck('title', 'id');
|
||||
}
|
||||
}
|
||||
|
@ -532,8 +532,7 @@ export default {
|
||||
})
|
||||
.catch(error => {
|
||||
this.form.loading = false;
|
||||
|
||||
console.log(error);
|
||||
this.form.errors.record(error.response.data.errors);
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -585,7 +585,7 @@ const app = new Vue({
|
||||
|
||||
this.component = Vue.component('add-new-component', (resolve, reject) => {
|
||||
resolve({
|
||||
template: '<div id="dynamic-payment-component"><akaunting-modal-add-new modal-dialog-class="max-w-screen-md" :show="payment.modal" @submit="onSubmit" @cancel="onCancel" :buttons="payment.buttons" :title="payment.title" :is_component=true :message="payment.html"></akaunting-modal-add-new></div>',
|
||||
template: '<div id="dynamic-payment-component"><akaunting-modal-add-new modal-dialog-class="max-w-md" :show="payment.modal" @submit="onSubmit" @cancel="onCancel" :buttons="payment.buttons" :title="payment.title" :is_component=true :message="payment.html"></akaunting-modal-add-new></div>',
|
||||
|
||||
mixins: [
|
||||
Global
|
||||
|
@ -224,6 +224,7 @@ return [
|
||||
'copied' => 'Copied',
|
||||
'preview_mode' => 'Preview Mode',
|
||||
'go_back' => 'Go back to :type',
|
||||
'validation_error' => 'Validation error',
|
||||
|
||||
'card' => [
|
||||
'cards' => 'Card|Cards',
|
||||
|
@ -1,15 +1,23 @@
|
||||
<div wire:click.stop id="menu-neww">
|
||||
<div wire:click.stop id="menu-neww" class="relative">
|
||||
<input type="text" name="neww_keyword" wire:model.debounce.500ms="keyword" placeholder="{{ trans('general.search_placeholder') }}" class="border-t-0 border-l-0 border-r-0 border-b border-gray-300 bg-transparent text-gray-500 text-sm mb-3 focus:outline-none focus:ring-transparent focus:border-purple placeholder-light-gray js-search-action">
|
||||
|
||||
{!! menu('neww') !!}
|
||||
</div>
|
||||
@if ($keyword)
|
||||
<button type="button" class="absolute ltr:right-2 rtl:left-2 top-2 clear" wire:click="resetKeyword">
|
||||
<span class="material-icons text-sm">close</span>
|
||||
</button>
|
||||
@endif
|
||||
|
||||
@push('scripts_end')
|
||||
<script type="text/javascript">
|
||||
window.addEventListener('click', function() {
|
||||
if (Livewire.components.getComponentsByName('menu.neww')[0].data.neww.length > 0) {
|
||||
Livewire.emit('resetKeyword');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@if ($neww)
|
||||
{!! menu('neww') !!}
|
||||
@else
|
||||
<ul class="flex flex-col justify-center">
|
||||
<li class="text-sm mb-5">
|
||||
<div class="flex items-start">
|
||||
<p class="text-black">
|
||||
{{ trans('notifications.empty') }}
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@endif
|
||||
</div>
|
||||
|
@ -1,6 +1,12 @@
|
||||
<div wire:click.stop id="menu-notifications">
|
||||
<div wire:click.stop id="menu-notifications" class="relative">
|
||||
<input type="text" name="notification_keyword" wire:model.debounce.500ms="keyword" placeholder="{{ trans('general.search_placeholder') }}" class="border-t-0 border-l-0 border-r-0 border-b border-gray-300 bg-transparent text-gray-500 text-sm mb-3 focus:outline-none focus:ring-transparent focus:border-purple placeholder-light-gray js-search-action">
|
||||
|
||||
@if ($keyword)
|
||||
<button type="button" class="absolute ltr:right-2 rtl:left-2 top-2 clear" wire:click="resetKeyword">
|
||||
<span class="material-icons text-sm">close</span>
|
||||
</button>
|
||||
@endif
|
||||
|
||||
@if ($notifications)
|
||||
<div class="flex justify-end mt-1">
|
||||
<x-tooltip id="notification-all" placement="right" message="Mark as All Read">
|
||||
@ -53,12 +59,6 @@
|
||||
|
||||
@push('scripts_end')
|
||||
<script type="text/javascript">
|
||||
window.addEventListener('click', function() {
|
||||
if (Livewire.components.getComponentsByName('menu.notifications')[0].data.notifications.length > 0) {
|
||||
Livewire.emit('resetKeyword');
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('mark-read', event => {
|
||||
if (event.detail.type == 'notifications') {
|
||||
$.notify(event.detail.message, {
|
||||
|
@ -1,7 +1,25 @@
|
||||
<div wire:click.stop id="menu-settings">
|
||||
<div wire:click.stop id="menu-settings" class="relative">
|
||||
<input type="text" name="settings_keyword" wire:model.debounce.500ms="keyword" placeholder="{{ trans('general.search_placeholder') }}" class="border-t-0 border-l-0 border-r-0 border-b border-gray-300 bg-transparent text-gray-500 text-sm mb-3 focus:outline-none focus:ring-transparent focus:border-purple placeholder-light-gray js-search-action">
|
||||
|
||||
{!! menu('settings') !!}
|
||||
@if ($keyword)
|
||||
<button type="button" class="absolute ltr:right-2 rtl:left-2 top-2 clear" wire:click="resetKeyword">
|
||||
<span class="material-icons text-sm">close</span>
|
||||
</button>
|
||||
@endif
|
||||
|
||||
@if ($settings)
|
||||
{!! menu('settings') !!}
|
||||
@else
|
||||
<ul class="flex flex-col justify-center">
|
||||
<li class="text-sm mb-5">
|
||||
<div class="flex items-start">
|
||||
<p class="text-black">
|
||||
{{ trans('notifications.empty') }}
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@push('scripts_start')
|
||||
@ -9,13 +27,3 @@
|
||||
var is_settings_menu = {{ $active_menu }};
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
@push('scripts_end')
|
||||
<script type="text/javascript">
|
||||
window.addEventListener('click', function() {
|
||||
if (Livewire.components.getComponentsByName('menu.settings')[0].data.settings.length > 0) {
|
||||
Livewire.emit('resetKeyword');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
@ -1,27 +1,70 @@
|
||||
<x-form id="form-transaction" :route="$route" :model="!empty($transaction) ? $transaction : false">
|
||||
<base-alert type="warning" v-if="typeof form.response !== 'undefined' && form.response.error" v-html="form.response.message"></base-alert>
|
||||
<div class="rounded-xl px-5 py-3 mb-5 bg-red-100" v-if="typeof form.response !== 'undefined' && form.response.error">
|
||||
<p class="text-sm mb-0 text-red-600" v-html="form.response.message"></p>
|
||||
</div>
|
||||
|
||||
<div class="grid sm:grid-cols-6 gap-x-8 gap-y-6 my-3.5">
|
||||
<x-form.group.date name="paid_at" label="{{ trans('general.date') }}" icon="calendar_today" value="{{ Date::now()->toDateString() }}" show-date-format="{{ company_date_format() }}" date-format="Y-m-d" autocomplete="off" />
|
||||
<div x-data="{ active: 'general' }">
|
||||
<div>
|
||||
<div>
|
||||
<ul class="grid grid-cols-6">
|
||||
<li class="relative px-8 text-sm text-black text-center pb-2 cursor-pointer transition-all border-b tabs-link col-span-3"
|
||||
id="tab-general"
|
||||
data-id="tab-general"
|
||||
data-tabs="general"
|
||||
x-on:click="active = 'general'"
|
||||
x-bind:class="active != 'general' ? '' : 'active-tabs text-purple border-purple transition-all after:absolute after:w-full after:h-0.5 after:left-0 after:right-0 after:bottom-0 after:bg-purple after:rounded-tl-md after:rounded-tr-md'"
|
||||
>
|
||||
{{ trans('general.general') }}
|
||||
|
||||
<x-form.group.money name="amount" label="{{ trans('general.amount') }}" value="{{ $document->grand_total }}" autofocus="autofocus" :currency="$currency" dynamicCurrency="currency" />
|
||||
<span class="invalid-feedback block text-xs text-red whitespace-normal" v-if="form.errors.has('paid_at')||form.errors.has('amount')||form.errors.has('payment_method')||form.errors.has('account_id')">
|
||||
{{ trans('general.validation_error') }}
|
||||
</span>
|
||||
</li>
|
||||
|
||||
<x-form.group.account change="onChangePaymentAccount" />
|
||||
<li class="relative px-8 text-sm text-black text-center pb-2 cursor-pointer transition-all border-b tabs-link col-span-3"
|
||||
id="tab-other"
|
||||
data-id="tab-other"
|
||||
data-tabs="other"
|
||||
x-on:click="active = 'other'"
|
||||
x-bind:class="active != 'other' ? '' : 'active-tabs text-purple border-purple transition-all after:absolute after:w-full after:h-0.5 after:left-0 after:right-0 after:bottom-0 after:bg-purple after:rounded-tl-md after:rounded-tr-md'"
|
||||
>
|
||||
{{ trans_choice('general.others', 1) }}
|
||||
|
||||
<x-form.group.text name="currency" label="{{ trans_choice('general.currencies', 1) }}" value="{{ $document->currency->name }}" not-required disabled />
|
||||
<span class="invalid-feedback block text-xs text-red whitespace-normal" v-if="form.errors.has('number')||form.errors.has('description')||form.errors.has('recurring')">
|
||||
{{ trans('general.validation_error') }}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<x-form.group.textarea name="description" label="{{ trans('general.description') }}" rows="3" not-required />
|
||||
<div id="tab-general" data-tabs-content="general" x-show="active === 'general'">
|
||||
<div class="grid sm:grid-cols-6 gap-x-8 gap-y-6 my-3.5">
|
||||
<x-form.group.date name="paid_at" label="{{ trans('general.date') }}" icon="calendar_today" value="{{ Date::now()->toDateString() }}" show-date-format="{{ company_date_format() }}" date-format="Y-m-d" autocomplete="off" form-group-class="col-span-6" />
|
||||
|
||||
<x-form.group.payment-method />
|
||||
<x-form.group.money name="amount" label="{{ trans('general.amount') }}" value="{{ $document->grand_total }}" autofocus="autofocus" :currency="$currency" dynamicCurrency="currency" form-group-class="col-span-6" />
|
||||
|
||||
<x-form.group.text name="reference" label="{{ trans('general.reference') }}" not-required />
|
||||
<x-form.group.payment-method form-group-class="col-span-6"/>
|
||||
|
||||
<x-form.input.hidden name="document_id" :value="$document->id" />
|
||||
<x-form.input.hidden name="category_id" :value="$document->category->id" />
|
||||
<x-form.input.hidden name="amount" :value="$document->grand_total" />
|
||||
<x-form.input.hidden name="currency_code" :value="$document->currency_code" />
|
||||
<x-form.input.hidden name="currency_rate" :value="$document->currency_rate" />
|
||||
<x-form.input.hidden name="number" :value="$number" />
|
||||
<x-form.input.hidden name="type" :value="config('type.document.' . $document->type . '.transaction_type')" />
|
||||
<x-form.group.account change="onChangePaymentAccount" form-group-class="col-span-6" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="tab-other" data-tabs-content="other" x-show="active === 'other'">
|
||||
<div class="grid sm:grid-cols-6 gap-x-8 gap-y-6 my-3.5">
|
||||
<x-form.group.textarea name="description" label="{{ trans('general.description') }}" rows="3" not-required form-group-class="col-span-6" />
|
||||
|
||||
<x-form.group.text name="number" label="{{ trans_choice('general.numbers', 1) }}" value="{{ $number }}" form-group-class="col-span-6" />
|
||||
|
||||
<x-form.group.text name="reference" label="{{ trans('general.reference') }}" not-required form-group-class="col-span-6" />
|
||||
|
||||
<x-form.input.hidden name="document_id" :value="$document->id" />
|
||||
<x-form.input.hidden name="category_id" :value="$document->category->id" />
|
||||
<x-form.input.hidden name="amount" :value="$document->grand_total" />
|
||||
<x-form.input.hidden name="currency_code" :value="$document->currency_code" />
|
||||
<x-form.input.hidden name="currency_rate" :value="$document->currency_rate" />
|
||||
<x-form.input.hidden name="type" :value="config('type.document.' . $document->type . '.transaction_type')" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-form>
|
||||
|
Loading…
x
Reference in New Issue
Block a user