mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-11-02 12:15:55 +00:00
Merge branch 'release/4.7.2.2'
This commit is contained in:
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\BillRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Transformers\BillTransformer;
|
||||
@@ -126,10 +127,12 @@ class BillController extends Controller
|
||||
* @param BillRequest $request
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function store(BillRequest $request)
|
||||
{
|
||||
$bill = $this->repository->store($request->getAll());
|
||||
if(null !== $bill) {
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
@@ -137,6 +140,8 @@ class BillController extends Controller
|
||||
$resource = new Item($bill, new BillTransformer($this->parameters), 'bills');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
throw new FireflyException('Could not store new bill.');
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,11 @@ class AccountFactory
|
||||
$databaseData['virtual_balance'] = '0';
|
||||
}
|
||||
|
||||
// fix virtual balance when it's empty
|
||||
if ($databaseData['virtual_balance'] === '') {
|
||||
$databaseData['virtual_balance'] = '0';
|
||||
}
|
||||
|
||||
$newAccount = Account::create($databaseData);
|
||||
$this->updateMetaData($newAccount, $data);
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ class BillController extends Controller
|
||||
$overallAverage = $repository->getOverallAverage($bill);
|
||||
$manager = new Manager();
|
||||
$manager->setSerializer(new DataArraySerializer());
|
||||
$manager->parseIncludes(['attachments']);
|
||||
$manager->parseIncludes(['attachments','notes']);
|
||||
|
||||
// Make a resource out of the data and
|
||||
$parameters = new ParameterBag();
|
||||
@@ -269,6 +269,11 @@ class BillController extends Controller
|
||||
{
|
||||
$billData = $request->getBillData();
|
||||
$bill = $repository->store($billData);
|
||||
if (null === $bill) {
|
||||
$request->session()->flash('error', (string)trans('firefly.bill_store_error'));
|
||||
|
||||
return redirect(route('bills.create'))->withInput();
|
||||
}
|
||||
$request->session()->flash('success', (string)trans('firefly.stored_new_bill', ['name' => $bill->name]));
|
||||
Preferences::mark();
|
||||
|
||||
|
||||
@@ -204,7 +204,7 @@ class PiggyBankController extends Controller
|
||||
foreach ($collection as $piggyBank) {
|
||||
|
||||
$piggyBank->savedSoFar = $piggyRepository->getCurrentAmount($piggyBank);
|
||||
$piggyBank->percentage = 0 !== bccomp('0', $piggyBank->savedSoFar) ? (int)$piggyBank->savedSoFar / $piggyBank->targetamount * 100 : 0;
|
||||
$piggyBank->percentage = (int)(0 !== bccomp('0', $piggyBank->savedSoFar) ? $piggyBank->savedSoFar / $piggyBank->targetamount * 100 : 0);
|
||||
$piggyBank->leftToSave = bcsub($piggyBank->targetamount, (string)$piggyBank->savedSoFar);
|
||||
$piggyBank->percentage = $piggyBank->percentage > 100 ? 100 : $piggyBank->percentage;
|
||||
|
||||
|
||||
@@ -267,8 +267,8 @@ class SplitController extends Controller
|
||||
// take some info from first transaction, that should at least exist.
|
||||
$array[$index] = $row;
|
||||
$array[$index]['currency_id'] = $array[0]['transaction_currency_id'];
|
||||
$array[$index]['currency_code'] = $array[0]['transaction_currency_code'];
|
||||
$array[$index]['currency_symbol'] = $array[0]['transaction_currency_symbol'];
|
||||
$array[$index]['currency_code'] = $array[0]['transaction_currency_code'] ?? '';
|
||||
$array[$index]['currency_symbol'] = $array[0]['transaction_currency_symbol'] ?? '';
|
||||
$array[$index]['foreign_amount'] = round($array[0]['foreign_destination_amount'] ?? '0', 12);
|
||||
$array[$index]['foreign_currency_id'] = $array[0]['foreign_currency_id'];
|
||||
$array[$index]['foreign_currency_code'] = $array[0]['foreign_currency_code'];
|
||||
|
||||
@@ -90,12 +90,12 @@ class SplitJournalFormRequest extends Request
|
||||
'identifier' => $index,
|
||||
'currency_id' => $this->integer('journal_currency_id'),
|
||||
'currency_code' => null,
|
||||
'description' => $transaction['transaction_description'],
|
||||
'description' => $transaction['transaction_description'] ?? '',
|
||||
'amount' => $transaction['amount'],
|
||||
'budget_id' => (int)($transaction['budget_id'] ?? 0.0),
|
||||
'budget_name' => null,
|
||||
'category_id' => null,
|
||||
'category_name' => $transaction['category_name'],
|
||||
'category_name' => $transaction['category_name'] ?? '',
|
||||
];
|
||||
$data['transactions'][] = $set;
|
||||
}
|
||||
|
||||
@@ -56,9 +56,9 @@ class ImportBill
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Bill
|
||||
* @return Bill|null
|
||||
*/
|
||||
public function getBill(): Bill
|
||||
public function getBill(): ?Bill
|
||||
{
|
||||
if (null === $this->bill) {
|
||||
$this->store();
|
||||
@@ -268,9 +268,14 @@ class ImportBill
|
||||
];
|
||||
|
||||
Log::debug('Found no bill so must create one ourselves. Assume default values.', $data);
|
||||
|
||||
$this->bill = $this->repository->store($data);
|
||||
Log::debug(sprintf('Successfully stored new bill #%d: %s', $this->bill->id, $this->bill->name));
|
||||
$result = $this->repository->store($data);
|
||||
if (null !== $result) {
|
||||
$this->bill = $result;
|
||||
Log::debug(sprintf('Successfully stored new bill #%d: %s', $this->bill->id, $this->bill->name));
|
||||
}
|
||||
if (null === $result) {
|
||||
Log::error('Could not store new bill.');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -52,4 +52,12 @@ class Note extends Model
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*/
|
||||
public function setTextAttribute($value)
|
||||
{
|
||||
$this->attributes['text'] = e($value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,14 @@ class Rule extends Model
|
||||
return $this->hasMany('FireflyIII\Models\RuleTrigger');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*/
|
||||
public function setDescriptionAttribute($value)
|
||||
{
|
||||
$this->attributes['description'] = e($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
|
||||
@@ -538,9 +538,9 @@ class BillRepository implements BillRepositoryInterface
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Bill
|
||||
* @return Bill|null
|
||||
*/
|
||||
public function store(array $data): Bill
|
||||
public function store(array $data): ?Bill
|
||||
{
|
||||
/** @var BillFactory $factory */
|
||||
$factory = app(BillFactory::class);
|
||||
|
||||
@@ -183,9 +183,9 @@ interface BillRepositoryInterface
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Bill
|
||||
* @return Bill|null
|
||||
*/
|
||||
public function store(array $data): Bill;
|
||||
public function store(array $data): ?Bill;
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
|
||||
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Services\Internal\File;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use Crypt;
|
||||
|
||||
/**
|
||||
* Class EncryptService
|
||||
|
||||
@@ -70,6 +70,7 @@ class Roles implements ConfigurationInterface
|
||||
$stmt = (new Statement)->limit(1)->offset(0);
|
||||
$records = $stmt->process($reader);
|
||||
$headers = $records->fetchOne(0);
|
||||
Log::debug('Detected file headers:', $headers);
|
||||
}
|
||||
|
||||
// example rows:
|
||||
|
||||
@@ -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.7.2.2] - 2018-04-04
|
||||
### Fixed
|
||||
- Bug in split transaction edit routine
|
||||
- Piggy bank percentage was very specific.
|
||||
- Logging in Slack is easier to config.
|
||||
- [Issue 1312](https://github.com/firefly-iii/firefly-iii/issues/1312) Import broken for ING accounts
|
||||
- [Issue 1313](https://github.com/firefly-iii/firefly-iii/issues/1313) Error when creating new asset account
|
||||
- [Issue 1317](https://github.com/firefly-iii/firefly-iii/issues/1317) Forgot an include :(
|
||||
|
||||
## [4.7.2.1] - 2018-04-02
|
||||
### Fixed
|
||||
- Null pointer exception in transaction overview.
|
||||
|
||||
@@ -86,7 +86,7 @@ return [
|
||||
'is_demo_site' => false,
|
||||
],
|
||||
'encryption' => null === env('USE_ENCRYPTION') || env('USE_ENCRYPTION') === true,
|
||||
'version' => '4.7.2.1',
|
||||
'version' => '4.7.2.2',
|
||||
'api_version' => '0.1',
|
||||
'db_version' => 2,
|
||||
'maxUploadSize' => 15242880,
|
||||
|
||||
@@ -53,7 +53,7 @@ return [
|
||||
'channels' => [
|
||||
'stack' => [
|
||||
'driver' => 'stack',
|
||||
'channels' => ['single'],
|
||||
'channels' => ['daily', 'slack'],
|
||||
],
|
||||
|
||||
'single' => [
|
||||
@@ -78,9 +78,9 @@ return [
|
||||
'slack' => [
|
||||
'driver' => 'slack',
|
||||
'url' => env('LOG_SLACK_WEBHOOK_URL'),
|
||||
'username' => 'Laravel Log',
|
||||
'username' => 'Firefly III Log Robot',
|
||||
'emoji' => ':boom:',
|
||||
'level' => 'critical',
|
||||
'level' => 'error',
|
||||
],
|
||||
|
||||
'syslog' => [
|
||||
|
||||
16
public/js/ff/transactions/split/edit.js
vendored
16
public/js/ff/transactions/split/edit.js
vendored
@@ -43,13 +43,13 @@ $(document).ready(function () {
|
||||
|
||||
$.getJSON('json/categories').done(function (data) {
|
||||
categories = data;
|
||||
$('input[name$="category]"]').typeahead({source: categories, autoSelect: false});
|
||||
$('input[name$="category_name]"]').typeahead({source: categories, autoSelect: false});
|
||||
});
|
||||
|
||||
$.getJSON('json/transaction-journals/' + what).done(function (data) {
|
||||
descriptions = data;
|
||||
$('input[name="journal_description"]').typeahead({source: descriptions, autoSelect: false});
|
||||
$('input[name$="description]"]').typeahead({source: descriptions, autoSelect: false});
|
||||
$('input[name$="transaction_description]"]').typeahead({source: descriptions, autoSelect: false});
|
||||
});
|
||||
|
||||
$.getJSON('json/tags').done(function (data) {
|
||||
@@ -123,10 +123,10 @@ function cloneDivRow() {
|
||||
source.find('input[name$="source_account_name]"]').typeahead({source: srcAccounts, autoSelect: false});
|
||||
}
|
||||
if (categories.length > 0) {
|
||||
source.find('input[name$="category]"]').typeahead({source: categories, autoSelect: false});
|
||||
source.find('input[name$="category_name]"]').typeahead({source: categories, autoSelect: false});
|
||||
}
|
||||
if (descriptions.length > 0) {
|
||||
source.find('input[name$="description]"]').typeahead({source: descriptions, autoSelect: false});
|
||||
source.find('input[name$="transaction_description]"]').typeahead({source: descriptions, autoSelect: false});
|
||||
}
|
||||
|
||||
$('div.split_row_holder').append(source);
|
||||
@@ -180,9 +180,9 @@ function resetDivSplits() {
|
||||
// loop each possible field.
|
||||
|
||||
// ends with ][description]
|
||||
$.each($('input[name$="][description]"]'), function (i, v) {
|
||||
$.each($('input[name$="][transaction_description]"]'), function (i, v) {
|
||||
var input = $(v);
|
||||
input.attr('name', 'transactions[' + i + '][description]');
|
||||
input.attr('name', 'transactions[' + i + '][transaction_description]');
|
||||
});
|
||||
// ends with ][destination_account_name]
|
||||
$.each($('input[name$="][destination_account_name]"]'), function (i, v) {
|
||||
@@ -225,9 +225,9 @@ function resetDivSplits() {
|
||||
});
|
||||
|
||||
// ends with ][category]
|
||||
$.each($('input[name$="][category]"]'), function (i, v) {
|
||||
$.each($('input[name$="][category_name]"]'), function (i, v) {
|
||||
var input = $(v);
|
||||
input.attr('name', 'transactions[' + i + '][category]');
|
||||
input.attr('name', 'transactions[' + i + '][category_name]');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -648,6 +648,7 @@ return [
|
||||
'bill_expected_between' => 'Expected between :start and :end',
|
||||
'bill_will_automatch' => 'Bill will automatically linked to matching transactions',
|
||||
'skips_over' => 'skips over',
|
||||
'bill_store_error' => 'An unexpected error occurred while storing your new bill. Please check the log files',
|
||||
|
||||
// accounts:
|
||||
'details_for_asset' => 'Details for asset account ":name"',
|
||||
|
||||
@@ -84,11 +84,11 @@
|
||||
<h3 class="box-title">{{ 'more'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body no-padding">
|
||||
{% if object.notes|length > 0 %}
|
||||
{% if object.data.notes|length > 0 %}
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td>{{ trans('list.notes') }}</td>
|
||||
<td class="markdown">{{ object.notes.data[0].markdown }}</td>
|
||||
<td class="markdown">{{ object.data.notes|markdown }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
@@ -68,6 +68,40 @@ class AccountFactoryTest extends TestCase
|
||||
$this->assertEquals('defaultAsset', $account->getMeta('accountRole'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test minimal set of data to make factory work (asset account).
|
||||
*
|
||||
* @covers \FireflyIII\Factory\AccountFactory
|
||||
* @covers \FireflyIII\Factory\AccountMetaFactory
|
||||
* @covers \FireflyIII\Services\Internal\Support\AccountServiceTrait
|
||||
*/
|
||||
public function testCreateBasicEmptyVb()
|
||||
{
|
||||
|
||||
$data = [
|
||||
'account_type_id' => null,
|
||||
'accountType' => 'asset',
|
||||
'iban' => null,
|
||||
'name' => 'Basic asset account #' . random_int(1, 1000),
|
||||
'virtualBalance' => '',
|
||||
'active' => true,
|
||||
'accountRole' => 'defaultAsset',
|
||||
];
|
||||
|
||||
/** @var AccountFactory $factory */
|
||||
$factory = app(AccountFactory::class);
|
||||
$factory->setUser($this->user());
|
||||
$account = $factory->create($data);
|
||||
|
||||
// assert stuff about account:
|
||||
$this->assertEquals($account->name, $data['name']);
|
||||
$this->assertEquals(AccountType::ASSET, $account->accountType->type);
|
||||
$this->assertEquals('', $account->iban);
|
||||
$this->assertTrue($account->active);
|
||||
$this->assertEquals('0', $account->virtual_balance);
|
||||
$this->assertEquals('defaultAsset', $account->getMeta('accountRole'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creation of CC asset.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user