mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Merge branch 'release/4.8.1.7'
This commit is contained in:
commit
64a2f22b13
@ -1,7 +1,7 @@
|
||||
sudo: required
|
||||
language: bash
|
||||
env:
|
||||
- VERSION=4.8.1.6
|
||||
- VERSION=4.8.1.7
|
||||
|
||||
dist: xenial
|
||||
|
||||
|
116
app/Api/V1/Controllers/Search/TransferController.php
Normal file
116
app/Api/V1/Controllers/Search/TransferController.php
Normal file
@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/**
|
||||
* TransferController.php
|
||||
* Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers\Search;
|
||||
|
||||
|
||||
use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Api\V1\Requests\Search\TransferRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Support\Search\TransferSearch;
|
||||
use FireflyIII\Transformers\TransactionGroupTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
|
||||
/**
|
||||
* Class TransferController
|
||||
*/
|
||||
class TransferController extends Controller
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse|Response
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function search(TransferRequest $request)
|
||||
{
|
||||
// configure transfer search to search for a > b
|
||||
$search = app(TransferSearch::class);
|
||||
$search->setSource($request->get('source'));
|
||||
$search->setDestination($request->get('destination'));
|
||||
$search->setAmount($request->get('amount'));
|
||||
$search->setDescription($request->get('description'));
|
||||
$search->setDate($request->get('date'));
|
||||
|
||||
$left = $search->search();
|
||||
|
||||
// configure transfer search to search for b > a
|
||||
$search->setSource($request->get('destination'));
|
||||
$search->setDestination($request->get('source'));
|
||||
$search->setAmount($request->get('amount'));
|
||||
$search->setDescription($request->get('description'));
|
||||
$search->setDate($request->get('date'));
|
||||
|
||||
$right = $search->search();
|
||||
|
||||
// add parameters to URL:
|
||||
$this->parameters->set('source', $request->get('source'));
|
||||
$this->parameters->set('destination', $request->get('destination'));
|
||||
$this->parameters->set('amount', $request->get('amount'));
|
||||
$this->parameters->set('description', $request->get('description'));
|
||||
$this->parameters->set('date', $request->get('date'));
|
||||
|
||||
// get all journal ID's.
|
||||
$total = $left->merge($right)->unique('id')->pluck('id')->toArray();
|
||||
if (0 === count($total)) {
|
||||
// forces search to be empty.
|
||||
$total = [-1];
|
||||
}
|
||||
|
||||
// collector to return results.
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
$manager = $this->getManager();
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
// use new group collector:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector
|
||||
->setUser($admin)
|
||||
// all info needed for the API:
|
||||
->withAPIInformation()
|
||||
// set page size:
|
||||
->setLimit($pageSize)
|
||||
// set page to retrieve
|
||||
->setPage(1)
|
||||
->setJournalIds($total);
|
||||
|
||||
$paginator = $collector->getPaginatedGroups();
|
||||
$paginator->setPath(route('api.v1.search.transfers') . $this->buildParams());
|
||||
$transactions = $paginator->getCollection();
|
||||
|
||||
/** @var TransactionGroupTransformer $transformer */
|
||||
$transformer = app(TransactionGroupTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new FractalCollection($transactions, $transformer, 'transactions');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ use FireflyIII\Api\V1\Requests\TransactionStoreRequest;
|
||||
use FireflyIII\Api\V1\Requests\TransactionUpdateRequest;
|
||||
use FireflyIII\Events\StoredTransactionGroup;
|
||||
use FireflyIII\Events\UpdatedTransactionGroup;
|
||||
use FireflyIII\Exceptions\DuplicateTransactionException;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
@ -279,7 +280,20 @@ class TransactionController extends Controller
|
||||
Log::channel('audit')
|
||||
->info('Store new transaction over API.', $data);
|
||||
|
||||
try {
|
||||
$transactionGroup = $this->groupRepository->store($data);
|
||||
} catch (DuplicateTransactionException $e) {
|
||||
// return bad validation message.
|
||||
// TODO use Laravel's internal validation thing to do this.
|
||||
$response = [
|
||||
'message' => 'The given data was invalid.',
|
||||
'errors' => [
|
||||
'transactions.0.description' => [$e->getMessage()],
|
||||
],
|
||||
];
|
||||
|
||||
return response()->json($response, 422);
|
||||
}
|
||||
|
||||
event(new StoredTransactionGroup($transactionGroup));
|
||||
|
||||
|
58
app/Api/V1/Requests/Search/TransferRequest.php
Normal file
58
app/Api/V1/Requests/Search/TransferRequest.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* TransferRequest.php
|
||||
* Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests\Search;
|
||||
|
||||
|
||||
use FireflyIII\Api\V1\Requests\Request;
|
||||
use FireflyIII\Rules\IsTransferAccount;
|
||||
|
||||
/**
|
||||
* Class TransferRequest
|
||||
*/
|
||||
class TransferRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'source' => ['required', new IsTransferAccount],
|
||||
'destination' => ['required', new IsTransferAccount],
|
||||
'amount' => 'required|numeric|more:0',
|
||||
'description' => 'required|min:1',
|
||||
'date' => 'required|date',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -59,6 +59,7 @@ class TransactionStoreRequest extends Request
|
||||
{
|
||||
$data = [
|
||||
'group_title' => $this->string('group_title'),
|
||||
'error_if_duplicate_hash' => $this->boolean('error_if_duplicate_hash'),
|
||||
'transactions' => $this->getTransactionData(),
|
||||
];
|
||||
|
||||
@ -75,6 +76,7 @@ class TransactionStoreRequest extends Request
|
||||
$rules = [
|
||||
// basic fields for group:
|
||||
'group_title' => 'between:1,1000|nullable',
|
||||
'error_if_duplicate_hash' => [new IsBoolean],
|
||||
|
||||
// transaction rules (in array for splits):
|
||||
'transactions.*.type' => 'required|in:withdrawal,deposit,transfer,opening-balance,reconciliation',
|
||||
|
31
app/Exceptions/DuplicateTransactionException.php
Normal file
31
app/Exceptions/DuplicateTransactionException.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* DuplicateTransactionException.php
|
||||
* Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Exceptions;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class DuplicateTransactionException
|
||||
*/
|
||||
class DuplicateTransactionException extends Exception
|
||||
{
|
||||
|
||||
}
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Factory;
|
||||
|
||||
use FireflyIII\Exceptions\DuplicateTransactionException;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\User;
|
||||
|
||||
@ -52,10 +53,13 @@ class TransactionGroupFactory
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionGroup
|
||||
* @throws DuplicateTransactionException
|
||||
*/
|
||||
public function create(array $data): TransactionGroup
|
||||
{
|
||||
$this->journalFactory->setUser($this->user);
|
||||
$this->journalFactory->setErrorOnHash($data['error_if_duplicate_hash']);
|
||||
|
||||
$collection = $this->journalFactory->create($data);
|
||||
$title = $data['group_title'] ?? null;
|
||||
$title = '' === $title ? null : $title;
|
||||
|
@ -26,10 +26,12 @@ namespace FireflyIII\Factory;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use FireflyIII\Exceptions\DuplicateTransactionException;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionJournalMeta;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
@ -72,6 +74,8 @@ class TransactionJournalFactory
|
||||
private $typeRepository;
|
||||
/** @var User The user */
|
||||
private $user;
|
||||
/** @var bool */
|
||||
private $errorOnHash;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@ -81,6 +85,7 @@ class TransactionJournalFactory
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->errorOnHash = false;
|
||||
$this->fields = [
|
||||
// sepa
|
||||
'sepa_cc', 'sepa_ct_op', 'sepa_ct_id',
|
||||
@ -119,6 +124,7 @@ class TransactionJournalFactory
|
||||
* @param array $data
|
||||
*
|
||||
* @return Collection
|
||||
* @throws DuplicateTransactionException
|
||||
*/
|
||||
public function create(array $data): Collection
|
||||
{
|
||||
@ -193,11 +199,15 @@ class TransactionJournalFactory
|
||||
* @param NullArrayObject $row
|
||||
*
|
||||
* @return TransactionJournal|null
|
||||
* @throws Exception
|
||||
* @throws DuplicateTransactionException
|
||||
*/
|
||||
private function createJournal(NullArrayObject $row): ?TransactionJournal
|
||||
{
|
||||
$row['import_hash_v2'] = $this->hashArray($row);
|
||||
|
||||
$this->errorIfDuplicate($row['import_hash_v2']);
|
||||
|
||||
/** Some basic fields */
|
||||
$type = $this->typeRepository->findTransactionType(null, $row['type']);
|
||||
$carbon = $row['date'] ?? new Carbon;
|
||||
@ -376,6 +386,30 @@ class TransactionJournalFactory
|
||||
return $journal;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this transaction already exists, throw an error.
|
||||
*
|
||||
* @param string $hash
|
||||
*
|
||||
* @throws DuplicateTransactionException
|
||||
*/
|
||||
private function errorIfDuplicate(string $hash): void
|
||||
{
|
||||
if (false === $this->errorOnHash) {
|
||||
return;
|
||||
}
|
||||
$result = null;
|
||||
if ($this->errorOnHash) {
|
||||
/** @var TransactionJournalMeta $result */
|
||||
$result = TransactionJournalMeta::where('data', json_encode($hash, JSON_THROW_ON_ERROR))
|
||||
->with(['transactionJournal', 'transactionJournal.transactionGroup'])
|
||||
->first();
|
||||
}
|
||||
if (null !== $result) {
|
||||
throw new DuplicateTransactionException(sprintf('Duplicate of transaction #%d.', $result->transactionJournal->transaction_group_id));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency|null $currency
|
||||
* @param Account $account
|
||||
@ -485,4 +519,14 @@ class TransactionJournalFactory
|
||||
throw new FireflyException(sprintf('Destination: %s', $this->accountValidator->destError)); // @codeCoverageIgnore
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $errorOnHash
|
||||
*/
|
||||
public function setErrorOnHash(bool $errorOnHash): void
|
||||
{
|
||||
$this->errorOnHash = $errorOnHash;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ class CreateController extends Controller
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
$previousUri = $this->rememberPreviousUri('transactions.create.uri');
|
||||
$parts = parse_url($previousUri);
|
||||
$previousUri = sprintf('%s://%s/%s', $parts['scheme'], $parts['host'], $parts['path']);
|
||||
$previousUri = sprintf('%s://%s/%s', $parts['scheme'], $parts['host'] ?? '', $parts['path'] ?? '');
|
||||
|
||||
session()->put('preFilled', $preFilled);
|
||||
|
||||
|
@ -83,7 +83,7 @@ class EditController extends Controller
|
||||
$cash = $repository->getCashAccount();
|
||||
$previousUri = $this->rememberPreviousUri('transactions.edit.uri');
|
||||
$parts = parse_url($previousUri);
|
||||
$previousUri = sprintf('%s://%s/%s', $parts['scheme'], $parts['host'], $parts['path']);
|
||||
$previousUri = sprintf('%s://%s/%s', $parts['scheme'], $parts['host'], $parts['path'] ?? '');
|
||||
|
||||
|
||||
return view('transactions.edit', compact('cash', 'transactionGroup', 'allowedOpposingTypes', 'accountToTypes', 'defaultCurrency', 'previousUri'));
|
||||
|
@ -27,6 +27,7 @@ namespace FireflyIII\Repositories\TransactionGroup;
|
||||
use Carbon\Carbon;
|
||||
use DB;
|
||||
use Exception;
|
||||
use FireflyIII\Exceptions\DuplicateTransactionException;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Factory\TransactionGroupFactory;
|
||||
use FireflyIII\Models\AccountMeta;
|
||||
@ -314,6 +315,7 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionGroup
|
||||
* @throws DuplicateTransactionException
|
||||
*/
|
||||
public function store(array $data): TransactionGroup
|
||||
{
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\TransactionGroup;
|
||||
|
||||
use FireflyIII\Exceptions\DuplicateTransactionException;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\Support\NullArrayObject;
|
||||
use FireflyIII\User;
|
||||
@ -125,6 +126,7 @@ interface TransactionGroupRepositoryInterface
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionGroup
|
||||
* @throws DuplicateTransactionException
|
||||
*/
|
||||
public function store(array $data): TransactionGroup;
|
||||
|
||||
|
73
app/Rules/IsTransferAccount.php
Normal file
73
app/Rules/IsTransferAccount.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* IsTransferAccount.php
|
||||
* Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Rules;
|
||||
|
||||
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Validation\AccountValidator;
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class IsTransferAccount
|
||||
*/
|
||||
class IsTransferAccount implements Rule
|
||||
{
|
||||
/**
|
||||
* Get the validation error message.
|
||||
*
|
||||
* @return string|array
|
||||
*/
|
||||
public function message(): string
|
||||
{
|
||||
return (string)trans('validation.not_transfer_account');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the validation rule passes.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function passes($attribute, $value): bool
|
||||
{
|
||||
Log::debug(sprintf('Now in %s(%s)', __METHOD__, $value));
|
||||
/** @var AccountValidator $validator */
|
||||
$validator = app(AccountValidator::class);
|
||||
$validator->setTransactionType(TransactionType::TRANSFER);
|
||||
$validator->setUser(auth()->user());
|
||||
|
||||
$validAccount = $validator->validateSource(null, (string)$value);
|
||||
if (true === $validAccount) {
|
||||
Log::debug('Found account based on name. Return true.');
|
||||
|
||||
// found by name, use repos to return.
|
||||
return true;
|
||||
}
|
||||
$validAccount = $validator->validateSource((int)$value, null);
|
||||
Log::debug(sprintf('Search by id (%d), result is %s.', (int)$value, var_export($validAccount, true)));
|
||||
|
||||
return !(false === $validAccount);
|
||||
}
|
||||
}
|
@ -22,7 +22,16 @@
|
||||
namespace FireflyIII\Support\Search;
|
||||
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface GenericSearchInterface
|
||||
*/
|
||||
interface GenericSearchInterface
|
||||
{
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function search(): Collection;
|
||||
|
||||
}
|
147
app/Support/Search/TransferSearch.php
Normal file
147
app/Support/Search/TransferSearch.php
Normal file
@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/**
|
||||
* TransferSearch.php
|
||||
* Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Support\Search;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Illuminate\Support\Collection;
|
||||
use InvalidArgumentException;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class TransferSearch
|
||||
*/
|
||||
class TransferSearch implements GenericSearchInterface
|
||||
{
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $accountRepository;
|
||||
/** @var string */
|
||||
private $amount;
|
||||
/** @var Carbon */
|
||||
private $date;
|
||||
/** @var string */
|
||||
private $description;
|
||||
/** @var Account */
|
||||
private $destination;
|
||||
/** @var Account */
|
||||
private $source;
|
||||
/** @var array */
|
||||
private $types;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||
$this->types = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function search(): Collection
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$query = $user->transactionJournals()
|
||||
->leftJoin(
|
||||
'transactions as source', static function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 'source.transaction_journal_id');
|
||||
$join->where('source.amount', '<', '0');
|
||||
}
|
||||
)
|
||||
->leftJoin(
|
||||
'transactions as destination', static function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 'destination.transaction_journal_id');
|
||||
$join->where('destination.amount', '>', '0');
|
||||
}
|
||||
)
|
||||
->where('source.account_id', $this->source->id)
|
||||
->where('destination.account_id', $this->destination->id)
|
||||
->where('transaction_journals.description', $this->description)
|
||||
->where('destination.amount', $this->amount)
|
||||
->where('transaction_journals.date', $this->date->format('Y-m-d 00:00:00'))
|
||||
;
|
||||
|
||||
return $query->get(['transaction_journals.id', 'transaction_journals.transaction_group_id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $amount
|
||||
*/
|
||||
public function setAmount(string $amount): void
|
||||
{
|
||||
$this->amount = $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
*/
|
||||
public function setDate(string $date): void
|
||||
{
|
||||
try {
|
||||
$carbon = Carbon::createFromFormat('Y-m-d', $date);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
Log::error($e->getMessage());
|
||||
$carbon = Carbon::now();
|
||||
}
|
||||
$this->date = $carbon;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $description
|
||||
*/
|
||||
public function setDescription(string $description): void
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $destination
|
||||
*/
|
||||
public function setDestination(string $destination): void
|
||||
{
|
||||
if (is_numeric($destination)) {
|
||||
$this->destination = $this->accountRepository->findNull((int)$destination);
|
||||
}
|
||||
if (null === $this->destination) {
|
||||
$this->destination = $this->accountRepository->findByName($destination, $this->types);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $source
|
||||
*/
|
||||
public function setSource(string $source): void
|
||||
{
|
||||
if (is_numeric($source)) {
|
||||
$this->source = $this->accountRepository->findNull((int)$source);
|
||||
}
|
||||
if (null === $this->source) {
|
||||
$this->source = $this->accountRepository->findByName($source, $this->types);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,15 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [4.8.1.7 (API 0.10.5)] - 2019-10-26
|
||||
|
||||
### Fixed
|
||||
- Error when creating transactions from the index of Firefly III.
|
||||
|
||||
### API
|
||||
- Firefly III can filter duplicate transactions.
|
||||
- New endpoint that can search for specific transfers.
|
||||
|
||||
## [4.8.1.6 (API 0.10.4)] - 2019-10-25
|
||||
|
||||
### Fixed
|
||||
|
12
composer.lock
generated
12
composer.lock
generated
@ -3213,16 +3213,16 @@
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "1.1.0",
|
||||
"version": "1.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/log.git",
|
||||
"reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd"
|
||||
"reference": "bf73deb2b3b896a9d9c75f3f0d88185d2faa27e2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
|
||||
"reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/bf73deb2b3b896a9d9c75f3f0d88185d2faa27e2",
|
||||
"reference": "bf73deb2b3b896a9d9c75f3f0d88185d2faa27e2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3231,7 +3231,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
"dev-master": "1.1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -3256,7 +3256,7 @@
|
||||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2018-11-20T15:27:04+00:00"
|
||||
"time": "2019-10-25T08:06:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/simple-cache",
|
||||
|
@ -125,8 +125,8 @@ return [
|
||||
'is_demo_site' => false,
|
||||
],
|
||||
'encryption' => null === env('USE_ENCRYPTION') || env('USE_ENCRYPTION') === true,
|
||||
'version' => '4.8.1.6',
|
||||
'api_version' => '0.10.4',
|
||||
'version' => '4.8.1.7',
|
||||
'api_version' => '0.10.5',
|
||||
'db_version' => 11,
|
||||
'maxUploadSize' => 15242880,
|
||||
'send_error_message' => env('SEND_ERROR_MESSAGE', true),
|
||||
|
9
resources/lang/.gitignore
vendored
Normal file
9
resources/lang/.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
ca_ES
|
||||
da_DK
|
||||
he_IL
|
||||
ja_JP
|
||||
pt_PT
|
||||
sl_SI
|
||||
uk_UA
|
||||
sv_SE
|
||||
sr_CS
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => 'Potřebujete alespoň jedno opakování.',
|
||||
'require_repeat_until' => 'Require either a number of repetitions, or an end date (repeat_until). Not both.',
|
||||
'require_currency_info' => 'Obsah tohoto pole je neplatný bez informace o měně.',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => 'The content of this field is invalid without foreign amount information.',
|
||||
'equal_description' => 'Popis transakce nesmí být stejný jako globální popis.',
|
||||
'file_invalid_mime' => 'Soubor ":name" je typu ":mime", který není schválen pro nahrání.',
|
||||
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => 'Mindestens eine Wiederholung erforderlich.',
|
||||
'require_repeat_until' => 'Erfordert entweder eine Anzahl von Wiederholungen oder ein Enddatum (repeat_until). Nicht beides.',
|
||||
'require_currency_info' => 'Der Inhalt dieses Feldes ist ohne Währungsinformationen ungültig.',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => 'Der Inhalt dieses Feldes ist ohne Fremdbetragsangaben ungültig.',
|
||||
'equal_description' => 'Die Transaktionsbeschreibung darf nicht der globalen Beschreibung entsprechen.',
|
||||
'file_invalid_mime' => 'Die Datei „:name” ist vom Typ „:mime”, welcher nicht zum Hochladen zugelassen ist.',
|
||||
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => 'Απαιτείται τουλάχιστον μία επανάληψη.',
|
||||
'require_repeat_until' => 'Απαιτείται είτε ένας αριθμός επαναλήψεων, ή μία ημερομηνία λήξης (repeat_until). Όχι και τα δύο.',
|
||||
'require_currency_info' => 'Το περιεχόμενο αυτού του πεδίου δεν είναι έγκυρη χωρίς νομισματικές πληροφορίες.',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => 'Το περιεχόμενο αυτού του πεδίου δεν είναι έγκυρο χωρίς πληροφορίες ετερόχθονος ποσού.',
|
||||
'equal_description' => 'Η περιγραφή της συναλλαγής δεν πρέπει να ισούται με καθολική περιγραφή.',
|
||||
'file_invalid_mime' => 'Το αρχείο ":name" είναι τύπου ":mime" που δεν είναι αποδεκτός ως νέας μεταφόρτωσης.',
|
||||
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => 'Need at least one repetition.',
|
||||
'require_repeat_until' => 'Require either a number of repetitions, or an end date (repeat_until). Not both.',
|
||||
'require_currency_info' => 'The content of this field is invalid without currency information.',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => 'The content of this field is invalid without foreign amount information.',
|
||||
'equal_description' => 'Transaction description should not equal global description.',
|
||||
'file_invalid_mime' => 'File ":name" is of type ":mime" which is not accepted as a new upload.',
|
||||
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => 'Se necesita al menos una repetición.',
|
||||
'require_repeat_until' => 'Se precisa un número de repeticiones o una fecha de finalización (repeat_until). No ambas.',
|
||||
'require_currency_info' => 'El contenido de este campo no es válido sin la información montearia.',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => 'El contenido de este campo no es válido sin información de cantidad extranjera.',
|
||||
'equal_description' => 'La descripción de la transacción no debería ser igual a la descripción global.',
|
||||
'file_invalid_mime' => 'El archivo ":name" es de tipo ":mime", el cual no se acepta.',
|
||||
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => 'Besoin d\'au moins une répétition.',
|
||||
'require_repeat_until' => 'Besoin d’un certain nombre de répétitions ou d\'une date de fin (repeat_until). Pas les deux.',
|
||||
'require_currency_info' => 'Le contenu de ce champ n\'est pas valide sans informations sur la devise.',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => 'Le contenu de ce champ est invalide sans informations sur le montant étranger.',
|
||||
'equal_description' => 'La description de la transaction ne doit pas être identique à la description globale.',
|
||||
'file_invalid_mime' => 'Le fichier ":name" est du type ":mime" ce qui n\'est pas accepté pour un nouvel envoi.',
|
||||
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => 'Legalább egy ismétlés szükséges.',
|
||||
'require_repeat_until' => 'Legalább egy ismétlésszám vagy egy végdátum (repeat_until) kötelező. Csak az egyik.',
|
||||
'require_currency_info' => 'Ennek a mezőnek a tartalma érvénytelen pénznem információ nélkül.',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => 'The content of this field is invalid without foreign amount information.',
|
||||
'equal_description' => 'A tranzakció leírása nem egyezhet meg a globális leírással.',
|
||||
'file_invalid_mime' => '":name" fájl ":mime" típusú ami nem lehet új feltöltés.',
|
||||
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => 'Minimal harus ada satu pengulangan.',
|
||||
'require_repeat_until' => 'Dibutuhkan hanya sebuah angka pengulangan, atau tanggal akhir (repeat_until). Bukan keduanya.',
|
||||
'require_currency_info' => 'Isi dalam bidang ini tidak valid jika tidak disertai informasi mata uang.',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => 'The content of this field is invalid without foreign amount information.',
|
||||
'equal_description' => 'Deskripsi transaksi harus berbeda dari deskripsi umum.',
|
||||
'file_invalid_mime' => 'File ":name" adalah tipe ":mime" yang tidak diterima sebagai upload baru.',
|
||||
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => 'È necessaria almeno una ripetizione.',
|
||||
'require_repeat_until' => 'Richiede un numero di ripetizioni o una data di fine (ripeti fino al), non entrambi.',
|
||||
'require_currency_info' => 'Il contenuto di questo campo non è valido senza informazioni sulla valuta.',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => 'Il contenuto di questo campo non è valido senza le informazioni sull\'importo estero.',
|
||||
'equal_description' => 'La descrizione della transazione non deve essere uguale alla descrizione globale.',
|
||||
'file_invalid_mime' => 'Il file ":name" è di tipo ":mime" che non è accettato come nuovo caricamento.',
|
||||
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => 'Trenger minst en gjentagelse.',
|
||||
'require_repeat_until' => 'Krever enten et antall repetisjoner eller en slutt dato (gjentas til). Ikke begge.',
|
||||
'require_currency_info' => 'Innholdet i dette feltet er ugyldig uten valutainformasjon.',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => 'The content of this field is invalid without foreign amount information.',
|
||||
'equal_description' => 'Transaksjonsbeskrivelsen bør ikke være lik global beskrivelse.',
|
||||
'file_invalid_mime' => 'Kan ikke akseptere fil ":name" av typen ":mime" for opplasting.',
|
||||
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => 'Er is op zijn minst één herhaling nodig.',
|
||||
'require_repeat_until' => 'Je moet een aantal herhalingen opgeven, of een einddatum (repeat_until). Niet beide.',
|
||||
'require_currency_info' => 'De inhoud van dit veld is ongeldig zonder valutagegevens.',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => 'De inhoud van dit veld is ongeldig zonder bedrag in vreemde valuta.',
|
||||
'equal_description' => 'Transactiebeschrijving mag niet gelijk zijn aan globale beschrijving.',
|
||||
'file_invalid_mime' => 'Bestand ":name" is van het type ":mime", en die kan je niet uploaden.',
|
||||
|
@ -258,7 +258,7 @@ return [
|
||||
'search_modifier_created_on' => 'Transakcja stworzona :value',
|
||||
'search_modifier_updated_on' => 'Transakcja zaktualizowana :value',
|
||||
'modifiers_applies_are' => 'Zastosowano także poniższe modyfikatory:',
|
||||
'general_search_error' => 'An error occurred while searching. Please check the log files for more information.',
|
||||
'general_search_error' => 'Wystąpił błąd podczas wyszukiwania. Aby uzyskać więcej informacji proszę sprawdzić logi aplikacji.',
|
||||
'search_box' => 'Szukaj',
|
||||
'search_box_intro' => 'Witamy w funkcji wyszukiwania Firefly III. Wpisz zapytanie w polu. Upewnij się, że sprawdziłeś plik pomocy, ponieważ wyszukiwanie jest dość zaawansowane.',
|
||||
'search_error' => 'Błąd podczas wyszukiwania',
|
||||
@ -666,7 +666,7 @@ return [
|
||||
'cannot_disable_currency_budget_limits' => 'Cannot disable :name because it is used in budget limits.',
|
||||
'cannot_disable_currency_current_default' => 'Cannot disable :name because it is the current default currency.',
|
||||
'cannot_disable_currency_system_fallback' => 'Cannot disable :name because it is the system default currency.',
|
||||
'disable_EUR_side_effects' => 'The Euro is the system\'s emergency fallback currency. Disabling it may have unintended side-effects and may void your warranty.',
|
||||
'disable_EUR_side_effects' => 'Euro jest awaryjną walutą w systemie. Deaktywacja może mieć nieprzewidziane skutki i może spowodować wygaśnięcie gwarancji.',
|
||||
'deleted_currency' => 'Waluta :name została usunięta',
|
||||
'created_currency' => 'Waluta :name została utworzona',
|
||||
'could_not_store_currency' => 'Nie można zapisać nowej waluty.',
|
||||
@ -688,8 +688,8 @@ return [
|
||||
'options' => 'Opcje',
|
||||
|
||||
// budgets:
|
||||
'total_available_budget' => 'Total available budget (between :start and :end)',
|
||||
'total_available_budget_in_currency' => 'Total available budget in :currency',
|
||||
'total_available_budget' => 'Dostępny budżet (pomiędzy :start i :end)',
|
||||
'total_available_budget_in_currency' => 'Dostępny budżet w :currency',
|
||||
'see_below' => 'zobacz poniżej',
|
||||
'create_new_budget' => 'Utwórz nowy budżet',
|
||||
'store_new_budget' => 'Zapisz nowy budżet',
|
||||
@ -791,7 +791,7 @@ return [
|
||||
'asset_accounts' => 'Konta aktywów',
|
||||
'asset_accounts_inactive' => 'Asset accounts (inactive)',
|
||||
'expense_accounts' => 'Konta wydatków',
|
||||
'expense_accounts_inactive' => 'Expense accounts (inactive)',
|
||||
'expense_accounts_inactive' => 'Konto wydatków (nieaktywne)',
|
||||
'revenue_accounts' => 'Konta przychodów',
|
||||
'cash_accounts' => 'Konta gotówkowe',
|
||||
'Cash account' => 'Konto gotówkowe',
|
||||
@ -1490,7 +1490,7 @@ return [
|
||||
'box_spent_in_currency' => 'Wydano (:currency)',
|
||||
'box_earned_in_currency' => 'Zarobiono (:currency)',
|
||||
'box_budgeted_in_currency' => 'Zabudżetowano (:currency)',
|
||||
'box_sum_in_currency' => 'Sum (:currency)',
|
||||
'box_sum_in_currency' => 'Suma (:currency)',
|
||||
'box_bill_paid_in_currency' => 'Zapłacone rachunki (:currency)',
|
||||
'box_bill_unpaid_in_currency' => 'Niezapłacone rachunki (:currency)',
|
||||
'box_left_to_spend_in_currency' => 'Możliwe do wydania (:currency)',
|
||||
|
@ -255,7 +255,7 @@ return [
|
||||
|
||||
'withdrawal_destination_id' => 'Konto docelowe',
|
||||
'deposit_source_id' => 'Konto źródłowe',
|
||||
'expected_on' => 'Expected on',
|
||||
'paid' => 'Paid',
|
||||
'expected_on' => 'Oczekiwany',
|
||||
'paid' => 'Zapłacone',
|
||||
|
||||
];
|
||||
|
@ -38,11 +38,11 @@ return [
|
||||
'active' => 'Jest aktywny?',
|
||||
'percentage' => 'pct.',
|
||||
'next_due' => 'Next due',
|
||||
'transaction_type' => 'Type',
|
||||
'transaction_type' => 'Typ',
|
||||
'lastActivity' => 'Ostatnia aktywność',
|
||||
'balanceDiff' => 'Różnica sald',
|
||||
'matchesOn' => 'Dopasowanie',
|
||||
'other_meta_data' => 'Other meta data',
|
||||
'other_meta_data' => 'Inne dane meta',
|
||||
'account_type' => 'Typ konta',
|
||||
'created_at' => 'Utworzono',
|
||||
'account' => 'Konto',
|
||||
@ -109,14 +109,14 @@ return [
|
||||
'account_on_spectre' => 'Konto (Spectre)',
|
||||
'account_on_ynab' => 'Konto (YNAB)',
|
||||
'do_import' => 'Importuj z tego konta',
|
||||
'sepa_ct_id' => 'SEPA End to End Identifier',
|
||||
'sepa_ct_op' => 'SEPA Opposing Account Identifier',
|
||||
'sepa_db' => 'SEPA Mandate Identifier',
|
||||
'sepa_country' => 'SEPA Country',
|
||||
'sepa_cc' => 'SEPA Clearing Code',
|
||||
'sepa_ct_id' => 'Identyfikator end-to-end SEPA',
|
||||
'sepa_ct_op' => 'Identyfikator przeciwnego konta SEPA',
|
||||
'sepa_db' => 'Identyfikator mandatu SEPA',
|
||||
'sepa_country' => 'Kraj SEPA',
|
||||
'sepa_cc' => 'Kod rozliczeniowy SEPA',
|
||||
'sepa_ep' => 'SEPA External Purpose',
|
||||
'sepa_ci' => 'SEPA Creditor Identifier',
|
||||
'sepa_batch_id' => 'SEPA Batch ID',
|
||||
'sepa_batch_id' => 'ID paczki SEPA',
|
||||
'external_id' => 'Zewnętrzne ID',
|
||||
'account_at_bunq' => 'Konto bunq',
|
||||
'file_name' => 'Nazwa pliku',
|
||||
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => 'Wymaga co najmniej jednego powtórzenia.',
|
||||
'require_repeat_until' => 'Wymagana jest liczba powtórzeń lub data zakończenia (repeat_until), ale nie obie jednocześnie.',
|
||||
'require_currency_info' => 'Treść tego pola jest nieprawidłowa bez informacji o walucie.',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => 'Treść tego pola jest nieprawidłowa bez informacji o obcej kwocie.',
|
||||
'equal_description' => 'Opis transakcji nie powinien być równy globalnemu opisowi.',
|
||||
'file_invalid_mime' => 'Plik ":name" jest typu ":mime", który nie jest akceptowany jako nowy plik do przekazania.',
|
||||
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => 'Precisa de ao menos uma repetição.',
|
||||
'require_repeat_until' => 'É necessário ou um número de repetições ou uma data de término (repetir até). Não ambos.',
|
||||
'require_currency_info' => 'O conteúdo deste campo é inválido sem informações de moeda.',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => 'O conteúdo deste campo é inválido sem a informação de moeda estrangeira.',
|
||||
'equal_description' => 'A descrição da transação não pode ser igual à descrição global.',
|
||||
'file_invalid_mime' => 'Arquivo ":name" é do tipo ":mime" que não é aceito como um novo upload.',
|
||||
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => 'Aveți nevoie de cel puțin o repetare.',
|
||||
'require_repeat_until' => 'Solicitați fie un număr de repetări, fie o dată de încheiere (repeat_until). Nu amândouă.',
|
||||
'require_currency_info' => 'Conținutul acestui câmp este nevalid fără informații despre monedă.',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => 'The content of this field is invalid without foreign amount information.',
|
||||
'equal_description' => 'Descrierea tranzacției nu trebuie să fie egală cu descrierea globală.',
|
||||
'file_invalid_mime' => 'Fișierul ":name" este de tip ":mime" și nu este acceptat ca o încărcare nouă.',
|
||||
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => 'Необходима как минимум одна транзакция.',
|
||||
'require_repeat_until' => 'Требуется либо несколько повторений, либо конечная дата (repeat_until). Но не оба параметра разом.',
|
||||
'require_currency_info' => 'Содержимое этого поля недействительно без информации о валюте.',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => 'Содержимое этого поля недействительно без информации о валюте.',
|
||||
'equal_description' => 'Описание транзакции не должно совпадать с глобальным описанием.',
|
||||
'file_invalid_mime' => 'Файл ":name" имеет тип ":mime". Загрузка файлов такого типа невозможна.',
|
||||
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => 'En az bir tekrarı gerekir.',
|
||||
'require_repeat_until' => 'Require either a number of repetitions, or an end date (repeat_until). Not both.',
|
||||
'require_currency_info' => 'Bu alanın içeriği para birimi bilgileri geçersiz.',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => 'The content of this field is invalid without foreign amount information.',
|
||||
'equal_description' => 'İşlem açıklaması genel açıklama eşit değildir.',
|
||||
'file_invalid_mime' => '":name" dosyası ":mime" türünde olup yeni bir yükleme olarak kabul edilemez.',
|
||||
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => '至少需要一次重复。',
|
||||
'require_repeat_until' => '仅需重复次数或结束日期 (repeat_until) 即可,不需两者均备。',
|
||||
'require_currency_info' => '无货币资讯,此栏位内容无效。',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => 'The content of this field is invalid without foreign amount information.',
|
||||
'equal_description' => '交易描述不应等同全域描述。',
|
||||
'file_invalid_mime' => '档案 ":name" 的类型为 ":mime",系不被允许上载的类型。',
|
||||
|
@ -45,6 +45,7 @@ return [
|
||||
'at_least_one_repetition' => '至少需要一次重複。',
|
||||
'require_repeat_until' => '要嘛重複次數,要嘛結束日期 (repeat_until),須二擇其一。',
|
||||
'require_currency_info' => '此欄位內容須要貨幣資訊。',
|
||||
'not_transfer_account' => 'This account is not an account that can be used for transfers.',
|
||||
'require_currency_amount' => '此欄位內容須要外幣資訊。',
|
||||
'equal_description' => '交易描述不應等同全域描述。',
|
||||
'file_invalid_mime' => '檔案 ":name" 類型為 ":mime",不允許上載。',
|
||||
|
@ -342,6 +342,7 @@ Route::group(
|
||||
// Attachment API routes:
|
||||
Route::get('transactions', ['uses' => 'TransactionController@search', 'as' => 'transactions']);
|
||||
Route::get('accounts', ['uses' => 'AccountController@search', 'as' => 'accounts']);
|
||||
Route::get('transfers', ['uses' => 'TransferController@search', 'as' => 'transfers']);
|
||||
}
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user