James Cole 2 years ago
parent
commit
c50b62f4f4
No known key found for this signature in database GPG Key ID: B49A324B7EAD6D80
  1. 12
      .ci/php-cs-fixer/composer.lock
  2. 4
      app/Http/Controllers/Import/ConversionController.php
  3. 4
      app/Services/CSV/Converter/Amount.php
  4. 23
      app/Services/Camt/Conversion/TransactionMapper.php
  5. 186
      config/app.php
  6. 3
      config/auth.php
  7. 64
      phpunit.xml
  8. 2
      tests/Feature/ExampleTest.php
  9. 59
      tests/Unit/Services/CSV/Converter/AmountTest.php

12
.ci/php-cs-fixer/composer.lock

@ -226,16 +226,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.46.0",
"version": "v3.47.1",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "be6831c9af1740470d2a773119b9273f8ac1c3d2"
"reference": "173c60d1eff911c9c54322704623a45561d3241d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/be6831c9af1740470d2a773119b9273f8ac1c3d2",
"reference": "be6831c9af1740470d2a773119b9273f8ac1c3d2",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/173c60d1eff911c9c54322704623a45561d3241d",
"reference": "173c60d1eff911c9c54322704623a45561d3241d",
"shasum": ""
},
"require": {
@ -305,7 +305,7 @@
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.46.0"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.47.1"
},
"funding": [
{
@ -313,7 +313,7 @@
"type": "github"
}
],
"time": "2024-01-03T21:38:46+00:00"
"time": "2024-01-16T18:54:21+00:00"
},
{
"name": "psr/container",

4
app/Http/Controllers/Import/ConversionController.php

@ -108,7 +108,7 @@ class ConversionController extends Controller
}
if ('camt' === $contentType) {
app('log')->debug('Create CAMT routine manager.');
$routine = new CAMTRoutineManager($identifier);
$routine = new CamtRoutineManager($identifier);
}
}
if ('nordigen' === $flow) {
@ -158,7 +158,7 @@ class ConversionController extends Controller
$routine = new CSVRoutineManager($identifier);
}
if ('camt' === $contentType) {
$routine = new CAMTRoutineManager($identifier); // why do we need this one?
$routine = new CamtRoutineManager($identifier); // why do we need this one?
}
}
if ('nordigen' === $flow) {

4
app/Services/CSV/Converter/Amount.php

@ -81,7 +81,9 @@ class Amount implements ConverterInterface
// decimal character still null? Search from the left for '.',',' or ' '.
if (null === $decimal) {
$decimal = $this->findFromLeft($value);
// See issue #8404
// $decimal = $this->findFromLeft($value);
app('log')->debug('Disabled "findFromLeft" because it happens more often that "1.000" is thousand than "1.000" is 1 with three zeroes.');
}
// if decimal is dot, replace all comma's and spaces with nothing

23
app/Services/Camt/Conversion/TransactionMapper.php

@ -499,12 +499,19 @@ class TransactionMapper
break;
case 'amount':
$current['amount'] = null;
// #8367 default amount = 0
$current['amount'] = 0;
app('log')->debug(sprintf('Start with amount at zero ("%s")', $current['amount']));
if ('group' === $groupHandling || 'split' === $groupHandling) {
// if multiple values, use biggest (... at index 0?)
// TODO this will never work because $current['amount'] is NULL the first time and abs() can't handle that.
foreach ($data['data'] as $amount) {
if (abs($current['amount']) < abs($amount) || null === $current['amount']) {
if(null === $amount) {
// #8367 skip null values
continue;
}
if (abs($current['amount']) < abs($amount)) {
app('log')->debug(sprintf('Amount is now "%s" instead of "%s"', $amount, $current['amount']));
$current['amount'] = $amount;
}
}
@ -512,12 +519,22 @@ class TransactionMapper
if ('single' === $groupHandling) {
// if multiple values, use smallest (... at index 1?)
foreach ($data['data'] as $amount) {
// #8367 skip null values
if(null === $amount) {
continue;
}
// check for null first, should prevent null pointers in abs()
if (null === $current['amount'] && null !== $amount && abs($current['amount']) > abs($amount)) {
if (abs($current['amount']) < abs($amount)) {
app('log')->debug(sprintf('Amount is now "%s" instead of "%s"', $amount, $current['amount']));
$current['amount'] = $amount;
}
}
}
if(0 === bccomp('0', (string)$current['amount'])) {
app('log')->debug('Amount is ZERO, zet to NULL');
$current['amount'] = null;
}
app('log')->debug(sprintf('Final amount is "%s"', $amount));
break;

186
config/app.php

@ -22,7 +22,69 @@
declare(strict_types=1);
use App\Providers\AppServiceProvider;
use App\Providers\EventServiceProvider;
use App\Providers\RouteServiceProvider;
use App\Support\Facades\Steam;
use Illuminate\Auth\AuthServiceProvider;
use Illuminate\Auth\Passwords\PasswordResetServiceProvider;
use Illuminate\Broadcasting\BroadcastServiceProvider;
use Illuminate\Bus\BusServiceProvider;
use Illuminate\Cache\CacheServiceProvider;
use Illuminate\Cookie\CookieServiceProvider;
use Illuminate\Database\DatabaseServiceProvider;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Encryption\EncryptionServiceProvider;
use Illuminate\Filesystem\FilesystemServiceProvider;
use Illuminate\Foundation\Providers\ConsoleSupportServiceProvider;
use Illuminate\Foundation\Providers\FoundationServiceProvider;
use Illuminate\Hashing\HashServiceProvider;
use Illuminate\Mail\MailServiceProvider;
use Illuminate\Notifications\NotificationServiceProvider;
use Illuminate\Pagination\PaginationServiceProvider;
use Illuminate\Pipeline\PipelineServiceProvider;
use Illuminate\Queue\QueueServiceProvider;
use Illuminate\Redis\RedisServiceProvider;
use Illuminate\Session\SessionServiceProvider;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Broadcast;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Cookie;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Str;
use Illuminate\Translation\TranslationServiceProvider;
use Illuminate\Validation\ValidationServiceProvider;
use Illuminate\View\ViewServiceProvider;
use TwigBridge\Facade\Twig;
use TwigBridge\ServiceProvider;
return [
/*
@ -159,38 +221,38 @@ return [
'providers' => [
// Laravel Framework Service Providers...
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
Illuminate\Filesystem\FilesystemServiceProvider::class,
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
Illuminate\Hashing\HashServiceProvider::class,
Illuminate\Mail\MailServiceProvider::class,
Illuminate\Notifications\NotificationServiceProvider::class,
Illuminate\Pagination\PaginationServiceProvider::class,
Illuminate\Pipeline\PipelineServiceProvider::class,
Illuminate\Queue\QueueServiceProvider::class,
Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
AuthServiceProvider::class,
BroadcastServiceProvider::class,
BusServiceProvider::class,
CacheServiceProvider::class,
ConsoleSupportServiceProvider::class,
CookieServiceProvider::class,
DatabaseServiceProvider::class,
EncryptionServiceProvider::class,
FilesystemServiceProvider::class,
FoundationServiceProvider::class,
HashServiceProvider::class,
MailServiceProvider::class,
NotificationServiceProvider::class,
PaginationServiceProvider::class,
PipelineServiceProvider::class,
QueueServiceProvider::class,
RedisServiceProvider::class,
PasswordResetServiceProvider::class,
SessionServiceProvider::class,
TranslationServiceProvider::class,
ValidationServiceProvider::class,
ViewServiceProvider::class,
// Package Service Providers...
TwigBridge\ServiceProvider::class,
ServiceProvider::class,
// Application Service Providers...
App\Providers\AppServiceProvider::class,
AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
EventServiceProvider::class,
RouteServiceProvider::class,
],
/*
@ -206,42 +268,42 @@ return [
'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
'Arr' => Illuminate\Support\Arr::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
'Blade' => Illuminate\Support\Facades\Blade::class,
'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
'Bus' => Illuminate\Support\Facades\Bus::class,
'Cache' => Illuminate\Support\Facades\Cache::class,
'Config' => Illuminate\Support\Facades\Config::class,
'Cookie' => Illuminate\Support\Facades\Cookie::class,
'Crypt' => Illuminate\Support\Facades\Crypt::class,
'DB' => Illuminate\Support\Facades\DB::class,
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
'Event' => Illuminate\Support\Facades\Event::class,
'File' => Illuminate\Support\Facades\File::class,
'Gate' => Illuminate\Support\Facades\Gate::class,
'Hash' => Illuminate\Support\Facades\Hash::class,
'Http' => Illuminate\Support\Facades\Http::class,
'Lang' => Illuminate\Support\Facades\Lang::class,
'Log' => Illuminate\Support\Facades\Log::class,
'Mail' => Illuminate\Support\Facades\Mail::class,
'Notification' => Illuminate\Support\Facades\Notification::class,
'Password' => Illuminate\Support\Facades\Password::class,
'Queue' => Illuminate\Support\Facades\Queue::class,
'Redirect' => Illuminate\Support\Facades\Redirect::class,
'Redis' => Illuminate\Support\Facades\Redis::class,
'Request' => Illuminate\Support\Facades\Request::class,
'Response' => Illuminate\Support\Facades\Response::class,
'Route' => Illuminate\Support\Facades\Route::class,
'Schema' => Illuminate\Support\Facades\Schema::class,
'Session' => Illuminate\Support\Facades\Session::class,
'Storage' => Illuminate\Support\Facades\Storage::class,
'Str' => Illuminate\Support\Str::class,
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
'Twig' => TwigBridge\Facade\Twig::class,
'Arr' => Arr::class,
'Artisan' => Artisan::class,
'Auth' => Auth::class,
'Blade' => Blade::class,
'Broadcast' => Broadcast::class,
'Bus' => Bus::class,
'Cache' => Cache::class,
'Config' => Config::class,
'Cookie' => Cookie::class,
'Crypt' => Crypt::class,
'DB' => DB::class,
'Eloquent' => Model::class,
'Event' => Event::class,
'File' => File::class,
'Gate' => Gate::class,
'Hash' => Hash::class,
'Http' => Http::class,
'Lang' => Lang::class,
'Log' => Log::class,
'Mail' => Mail::class,
'Notification' => Notification::class,
'Password' => Password::class,
'Queue' => Queue::class,
'Redirect' => Redirect::class,
'Redis' => Redis::class,
'Request' => Request::class,
'Response' => Response::class,
'Route' => Route::class,
'Schema' => Schema::class,
'Session' => Session::class,
'Storage' => Storage::class,
'Str' => Str::class,
'URL' => URL::class,
'Validator' => Validator::class,
'View' => View::class,
'Twig' => Twig::class,
'Steam' => Steam::class,
],
];

3
config/auth.php

@ -21,6 +21,7 @@
*/
declare(strict_types=1);
use App\User;
return [
/*
@ -96,7 +97,7 @@ return [
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
'model' => User::class,
],
// 'users' => [

64
phpunit.xml

@ -19,41 +19,31 @@
~ 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/>.
-->
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="tests/bootstrap.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./app</directory>
</whitelist>
</filter>
<php>
<server name="APP_ENV" value="testing"/>
<server name="BCRYPT_ROUNDS" value="4"/>
<server name="CACHE_DRIVER" value="array"/>
<server name="MAIL_DRIVER" value="array"/>
<server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/>
<server name="APP_CONFIG_CACHE" value="bootstrap/cache/config.phpunit.php"/>
<server name="APP_SERVICES_CACHE" value="bootstrap/cache/services.phpunit.php"/>
<server name="APP_PACKAGES_CACHE" value="bootstrap/cache/packages.phpunit.php"/>
<server name="APP_ROUTES_CACHE" value="bootstrap/cache/routes.phpunit.php"/>
<server name="APP_EVENTS_CACHE" value="bootstrap/cache/events.phpunit.php"/>
</php>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" bootstrap="tests/bootstrap.php" colors="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false">
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
</testsuites>
<php>
<server name="APP_ENV" value="testing"/>
<server name="BCRYPT_ROUNDS" value="4"/>
<server name="CACHE_DRIVER" value="array"/>
<server name="MAIL_DRIVER" value="array"/>
<server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/>
<server name="APP_CONFIG_CACHE" value="bootstrap/cache/config.phpunit.php"/>
<server name="APP_SERVICES_CACHE" value="bootstrap/cache/services.phpunit.php"/>
<server name="APP_PACKAGES_CACHE" value="bootstrap/cache/packages.phpunit.php"/>
<server name="APP_ROUTES_CACHE" value="bootstrap/cache/routes.phpunit.php"/>
<server name="APP_EVENTS_CACHE" value="bootstrap/cache/events.phpunit.php"/>
</php>
<source>
<include>
<directory suffix=".php">./app</directory>
</include>
</source>
</phpunit>

2
tests/Feature/ExampleTest.php

@ -40,6 +40,6 @@ final class ExampleTest extends TestCase
{
$response = $this->get('/');
$response->assertStatus(200);
$response->assertStatus(302);
}
}

59
tests/Unit/Services/CSV/Converter/AmountTest.php

@ -0,0 +1,59 @@
<?php
/*
* AmountTest.php
* Copyright (c) 2024 james@firefly-iii.org
*
* This file is part of the Firefly III Data Importer
* (https://github.com/firefly-iii/data-importer).
*
* 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/>.
*/
declare(strict_types=1);
namespace Tests\Unit\Services\CSV\Converter;
use App\Services\CSV\Converter\Amount;
use Tests\TestCase;
/**
* @internal
*
* @coversNothing
*/
final class AmountTest extends TestCase
{
/**
* A basic test example.
*/
public function testBasicTest(): void
{
$amount = new Amount();
self::assertSame('0', $amount->convert('0'));
self::assertSame('0.0', $amount->convert('0.0'));
self::assertSame('0.1', $amount->convert('0.1'));
self::assertSame('0.1', $amount->convert(0.1));
self::assertSame('1', $amount->convert(1));
self::assertSame('1', $amount->convert('1'));
self::assertSame('1.0', $amount->convert('1.0'));
self::assertSame('1000.000000000000', $amount->convert('1000,-'));
self::assertSame('1000.00', $amount->convert('1000,00'));
self::assertSame('1000.00', $amount->convert('1.000,00'));
self::assertSame('1000', $amount->convert('1.000,'));
self::assertSame('1000', $amount->convert('1.000'));
self::assertSame('1.00', $amount->convert('1.00'));
}
}
Loading…
Cancel
Save