diff --git a/app/Abstracts/View/Components/Transactions/Show.php b/app/Abstracts/View/Components/Transactions/Show.php index 1577e3aa9..629bdd1cf 100644 --- a/app/Abstracts/View/Components/Transactions/Show.php +++ b/app/Abstracts/View/Components/Transactions/Show.php @@ -304,6 +304,9 @@ abstract class Show extends Component /** @var bool */ public $hideRecurringMessage; + /** @var bool */ + public $hideConnectMessage; + /** @var bool */ public $hideCreated; @@ -335,7 +338,7 @@ abstract class Show extends Component string $routeDocumentShow = '', string $routeTransactionShow = '', string $textButtonAddNew = '', bool $hideSchedule = false, bool $hideChildren = false, bool $hideConnect = false, bool $hideTransfer = false, bool $hideAttachment = false, $attachment = [], - array $connectTranslations = [], string $textRecurringType = '', bool $hideRecurringMessage = false, bool $hideCreated = false + array $connectTranslations = [], string $textRecurringType = '', bool $hideRecurringMessage = false, $hideConnectMessage = false, bool $hideCreated = false ) { $this->type = $type; $this->transaction = $transaction; @@ -472,6 +475,7 @@ abstract class Show extends Component // Connect translations $this->connectTranslations = $this->getTranslationsForConnect($type); + $this->hideConnectMessage = $hideConnectMessage; $this->textRecurringType = $this->getTextRecurringType($type, $textRecurringType); $this->hideRecurringMessage = $hideRecurringMessage; diff --git a/app/Http/Controllers/Banking/Transactions.php b/app/Http/Controllers/Banking/Transactions.php index 62241035e..6cac4f5ce 100644 --- a/app/Http/Controllers/Banking/Transactions.php +++ b/app/Http/Controllers/Banking/Transactions.php @@ -39,7 +39,7 @@ class Transactions extends Controller { $this->setActiveTabForTransactions(); - $transactions = Transaction::with('account', 'category', 'contact')->collect(['paid_at'=> 'desc']); + $transactions = Transaction::with('account', 'category', 'contact', 'taxes')->collect(['paid_at'=> 'desc']); $total_transactions = Transaction::count(); @@ -395,7 +395,7 @@ class Transactions extends Controller $translations = collect($this->getTranslationsForConnect($transaction->type)); $data = [ - 'transaction' => $transaction->load(['account', 'category'])->toJson(), + 'transaction' => $transaction->load(['account', 'category', 'taxes'])->toJson(), 'currency' => $transaction->currency->toJson(), 'documents' => $documents, 'translations' => $translations->toJson(), diff --git a/app/Models/Banking/TransactionTax.php b/app/Models/Banking/TransactionTax.php index b50e3a89b..2b4ae76b6 100644 --- a/app/Models/Banking/TransactionTax.php +++ b/app/Models/Banking/TransactionTax.php @@ -5,12 +5,13 @@ namespace App\Models\Banking; use App\Abstracts\Model; use App\Models\Banking\Transaction; use App\Traits\Currencies; +use App\Traits\Transactions; use Bkwld\Cloner\Cloneable; use Illuminate\Database\Eloquent\Builder; class TransactionTax extends Model { - use Cloneable, Currencies; + use Cloneable, Currencies, Transactions; protected $table = 'transaction_taxes'; @@ -31,34 +32,92 @@ class TransactionTax extends Model return $this->belongsTo('App\Models\Banking\Transaction')->withDefault(['name' => trans('general.na')]); } - public function scopeType(Builder $query, string $type) + public function scopeType(Builder $query, $types): Builder { - return $query->where($this->qualifyColumn('type'), '=', $type); + if (empty($types)) { + return $query; + } + + return $query->whereIn($this->qualifyColumn('type'), (array) $types); } public function scopeIncome(Builder $query) { - return $query->where($this->qualifyColumn('type'), '=', Transaction::INCOME_TYPE); + return $query->whereIn($this->qualifyColumn('type'), (array) $this->getIncomeTypes()); + } + + public function scopeIncomeTransfer(Builder $query): Builder + { + return $query->where($this->qualifyColumn('type'), '=', Transaction::INCOME_TRANSFER_TYPE); } public function scopeIncomeRecurring(Builder $query): Builder { return $query->where($this->qualifyColumn('type'), '=', Transaction::INCOME_RECURRING_TYPE) - ->whereHas('document.recurring', function (Builder $query) { - $query->whereNull('deleted_at'); - }); + ->whereHas('transaction.recurring', function (Builder $query) { + $query->whereNull('deleted_at'); + }); } public function scopeExpense(Builder $query) { - return $query->where($this->qualifyColumn('type'), '=', Transaction::EXPENSE_TYPE); + return $query->whereIn($this->qualifyColumn('type'), (array) $this->getExpenseTypes()); + } + + public function scopeExpenseTransfer(Builder $query): Builder + { + return $query->where($this->qualifyColumn('type'), '=', Transaction::EXPENSE_TRANSFER_TYPE); } public function scopeExpenseRecurring(Builder $query): Builder { return $query->where($this->qualifyColumn('type'), '=', Transaction::EXPENSE_RECURRING_TYPE) - ->whereHas('document.recurring', function (Builder $query) { - $query->whereNull('deleted_at'); - }); + ->whereHas('transaction.recurring', function (Builder $query) { + $query->whereNull('deleted_at'); + }); + } + + public function scopeIsTransfer(Builder $query): Builder + { + return $query->where($this->qualifyColumn('type'), 'like', '%-transfer'); + } + + public function scopeIsNotTransfer(Builder $query): Builder + { + return $query->where($this->qualifyColumn('type'), 'not like', '%-transfer'); + } + + public function scopeIsRecurring(Builder $query): Builder + { + return $query->where($this->qualifyColumn('type'), 'like', '%-recurring'); + } + + public function scopeIsNotRecurring(Builder $query): Builder + { + return $query->where($this->qualifyColumn('type'), 'not like', '%-recurring'); + } + + public function scopeIsSplit(Builder $query): Builder + { + return $query->where($this->qualifyColumn('type'), 'like', '%-split'); + } + + public function scopeIsNotSplit(Builder $query): Builder + { + return $query->where($this->qualifyColumn('type'), 'not like', '%-split'); + } + + public function scopeIsDocument(Builder $query): Builder + { + return $query->whereHas('transaction', function ($q) { + $q->whereNotNull('document_id'); + }); + } + + public function scopeIsNotDocument(Builder $query): Builder + { + return $query->whereHas('transaction', function ($q) { + $q->whereNull('document_id'); + }); } } diff --git a/app/Reports/TaxSummary.php b/app/Reports/TaxSummary.php index 62ee34b70..f75951223 100644 --- a/app/Reports/TaxSummary.php +++ b/app/Reports/TaxSummary.php @@ -4,6 +4,7 @@ namespace App\Reports; use App\Abstracts\Report; use App\Models\Banking\Transaction; +use App\Models\Banking\TransactionTax; use App\Models\Document\Document; use App\Models\Setting\Tax; use App\Traits\Currencies; @@ -68,6 +69,14 @@ class TaxSummary extends Report break; } + + // Incomes + $incomes = $this->applyFilters(Transaction::with('taxes')->income()->isNotDocument()->isNotTransfer(), ['date_field' => 'paid_at'])->get(); + $this->setTotals($incomes, 'paid_at'); + + // Expenses + $expenses = $this->applyFilters(Transaction::with('taxes')->expense()->isNotDocument()->isNotTransfer(), ['date_field' => 'paid_at'])->get(); + $this->setTotals($expenses, 'paid_at'); } public function setTotals($items, $date_field, $check_type = false, $table = 'default', $with_tax = true) @@ -78,6 +87,11 @@ class TaxSummary extends Report $type = ($item->type === Document::INVOICE_TYPE || $item->type === 'income') ? 'income' : 'expense'; + if ($item instanceof Transaction && empty($item->document_id)) { + $this->setTransactionTaxTotal($item, $type, $date_field); + continue; + } + $date = $this->getFormattedDate(Date::parse($item->$date_field)); if ($date_field == 'paid_at') { @@ -122,6 +136,36 @@ class TaxSummary extends Report } } + public function setTransactionTaxTotal($item, $type, $date_field) + { + if (empty($item->taxes)) { + return; + } + + $date = $this->getFormattedDate(Date::parse($item->$date_field)); + + foreach ($item->taxes as $tax) { + if ( + !isset($this->row_values[$tax->name][$type][$date]) + || !isset($this->footer_totals[$tax->name][$date]) + ) { + continue; + } + + $amount = $this->convertToDefault($tax->amount, $item->currency_code, $item->currency_rate); + + if ($type == 'income') { + $this->row_values[$tax->name][$type][$date] += $amount; + + $this->footer_totals[$tax->name][$date] += $amount; + } else { + $this->row_values[$tax->name][$type][$date] -= $amount; + + $this->footer_totals[$tax->name][$date] -= $amount; + } + } + } + public function getFields() { return [ diff --git a/app/Traits/Transactions.php b/app/Traits/Transactions.php index c9de6f7d5..c418e8d46 100644 --- a/app/Traits/Transactions.php +++ b/app/Traits/Transactions.php @@ -192,6 +192,7 @@ trait Transactions 'add_an' => trans('general.form.add_an', ['field' => trans_choice('general.' . Str::plural($document_type), 1)]), 'transaction' => trans_choice('general.' . Str::plural($type), 1), 'difference' => trans('general.difference'), + 'connect_tax' => trans('messages.warning.connect_tax', ['type' => $type]), ]; } diff --git a/resources/assets/js/components/AkauntingConnectTransactions.vue b/resources/assets/js/components/AkauntingConnectTransactions.vue index d33cd411b..16231f0af 100644 --- a/resources/assets/js/components/AkauntingConnectTransactions.vue +++ b/resources/assets/js/components/AkauntingConnectTransactions.vue @@ -21,6 +21,11 @@ +
+

+ {{ translations.connect_tax }} +

+
diff --git a/resources/lang/en-GB/messages.php b/resources/lang/en-GB/messages.php index 0e655640b..31334d4a9 100644 --- a/resources/lang/en-GB/messages.php +++ b/resources/lang/en-GB/messages.php @@ -46,6 +46,7 @@ return [ 'disable_code' => 'Warning: You are not allowed to disable or change the currency of :name 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.', + 'connect_tax' => 'Warning: This :type has a tax amount. Taxes added to the :type can not be connected, so the tax will be added to the total and calculated accordingly.', ], ]; diff --git a/resources/lang/en-GB/transactions.php b/resources/lang/en-GB/transactions.php index 96711392f..8bfef6e66 100644 --- a/resources/lang/en-GB/transactions.php +++ b/resources/lang/en-GB/transactions.php @@ -12,6 +12,7 @@ return [ 'recurring_expense' => 'Recurring Expense', 'included_tax' => 'Included tax amount', 'connected' => 'Connected', + 'connect_message' => 'Taxes for this :type were not calculated during the connection process. Taxes can not be connected.', 'form_description' => [ 'general' => 'Here you can enter the general information of transaction such as date, amount, account, description, etc.', diff --git a/resources/views/components/transactions/show/content.blade.php b/resources/views/components/transactions/show/content.blade.php index 68d15a6ce..00ca6de32 100644 --- a/resources/views/components/transactions/show/content.blade.php +++ b/resources/views/components/transactions/show/content.blade.php @@ -28,6 +28,14 @@ @stack('recurring_message_end') + @stack('connect_message_start') + + @if (! $hideConnectMessage && $transaction->isSplitTransaction() && $transaction->taxes->count()) + + @endif + + @stack('connect_message_end') + @stack('row_create_start') @if (! $hideCreated)