Piggy bank can now have a group.

This commit is contained in:
James Cole
2020-06-07 11:31:01 +02:00
parent 2f63090e7c
commit 16b0307b0a
20 changed files with 439 additions and 105 deletions

View File

@@ -27,6 +27,7 @@ use Carbon\Carbon;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\ObjectGroup;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
@@ -35,6 +36,7 @@ use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
@@ -342,6 +344,34 @@ class AutoCompleteController extends Controller
return response()->json($return);
}
/**
* An auto-complete specifically for expense accounts, used when mass updating mostly.
*
* @param Request $request
*
* @return JsonResponse
*/
public function objectGroups(Request $request): JsonResponse
{
$search = $request->get('search');
/** @var ObjectGroupRepositoryInterface $repository */
$repository = app(ObjectGroupRepositoryInterface::class);
$return = [];
$result = $repository->search((string) $search);
/** @var ObjectGroup $account */
foreach ($result as $objectGroup) {
$return[] = [
'id' => $objectGroup->id,
'title' => $objectGroup->title,
];
}
return response()->json($return);
}
/**
* @return JsonResponse
* @codeCoverageIgnore

View File

@@ -54,6 +54,7 @@ class PiggyBankFormRequest extends Request
'targetamount' => $this->string('targetamount'),
'targetdate' => $this->date('targetdate'),
'notes' => $this->nlString('notes'),
'object_group' => $this->string('object_group'),
];
}

View File

@@ -10,14 +10,27 @@ use Illuminate\Database\Eloquent\Model;
* Class ObjectGroup
*
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\PiggyBank[] $piggyBanks
* @property-read int|null $piggy_banks_count
* @property-read int|null $piggy_banks_count
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup query()
* @mixin \Eloquent
* @property int $id
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $deleted_at
* @property string $title
* @property int $order
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereDeletedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereOrder($value)
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereTitle($value)
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereUpdatedAt($value)
*/
class ObjectGroup extends Model
{
protected $fillable = ['title', 'order'];
/**
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany
*/

View File

@@ -78,9 +78,9 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @property-read int|null $notes_count
* @property-read int|null $piggy_bank_events_count
* @property-read int|null $piggy_bank_repetitions_count
* @property bool $encrypted
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\ObjectGroup[] $objectGroups
* @property-read int|null $object_groups_count
* @property bool $encrypted
*/
class PiggyBank extends Model
{

View File

@@ -37,6 +37,8 @@ use FireflyIII\Helpers\Report\PopupReport;
use FireflyIII\Helpers\Report\PopupReportInterface;
use FireflyIII\Helpers\Report\ReportHelper;
use FireflyIII\Helpers\Report\ReportHelperInterface;
use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepository;
use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface;
use FireflyIII\Repositories\Telemetry\TelemetryRepository;
use FireflyIII\Repositories\Telemetry\TelemetryRepositoryInterface;
use FireflyIII\Repositories\TransactionType\TransactionTypeRepository;
@@ -172,6 +174,7 @@ class FireflyServiceProvider extends ServiceProvider
// other generators
$this->app->bind(UserRepositoryInterface::class, UserRepository::class);
$this->app->bind(TransactionTypeRepositoryInterface::class, TransactionTypeRepository::class);
$this->app->bind(ObjectGroupRepositoryInterface::class,ObjectGroupRepository::class);
$this->app->bind(AttachmentHelperInterface::class, AttachmentHelper::class);
// more generators:

View File

@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace FireflyIII\Repositories\ObjectGroup;
use FireflyIII\Models\ObjectGroup;
/**
* Trait CreatesObjectGroups
*/
trait CreatesObjectGroups
{
/**
* @param string $title
*
* @return null|ObjectGroup
*/
protected function findObjectGroup(string $title): ?ObjectGroup
{
return ObjectGroup::where('title', $title)->first();
}
/**
* @param string $title
*
* @return ObjectGroup|null
*/
protected function findOrCreateObjectGroup(string $title): ?ObjectGroup
{
$group = null;
$maxOrder = $this->getObjectGroupMaxOrder();
if (!$this->hasObjectGroup($title)) {
return ObjectGroup::create(
[
'title' => $title,
'order' => $maxOrder + 1,
]
);
}
return $this->findObjectGroup($title);
}
/**
* @return int
*/
protected function getObjectGroupMaxOrder(): int
{
return ObjectGroup::max('order');
}
/**
* @param string $title
*
* @return bool
*/
protected function hasObjectGroup(string $title): bool
{
return 1 === ObjectGroup::where('title', $title)->count();
}
}

View File

@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
namespace FireflyIII\Repositories\ObjectGroup;
use FireflyIII\Models\ObjectGroup;
use Illuminate\Support\Collection;
/**
* Class ObjectGroupRepository
*/
class ObjectGroupRepository implements ObjectGroupRepositoryInterface
{
/**
* @inheritDoc
*/
public function get(): Collection
{
return ObjectGroup::orderBy('order')->get();
}
/**
* @param string $query
*
* @return Collection
*/
public function search(string $query): Collection
{
$dbQuery = ObjectGroup::orderBy('order');
if ('' !== $query) {
// split query on spaces just in case:
$parts = explode(' ', $query);
foreach ($parts as $part) {
$search = sprintf('%%%s%%', $part);
$dbQuery->where('title', 'LIKE', $search);
}
}
return $dbQuery->get(['object_groups.*']);
}
}

View File

@@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace FireflyIII\Repositories\ObjectGroup;
use Illuminate\Support\Collection;
/**
* Interface ObjectGroupRepositoryInterface
*/
interface ObjectGroupRepositoryInterface
{
/**
* @return Collection
*/
public function get(): Collection;
/**
* @param string $query
*
* @return Collection
*/
public function search(string $query): Collection;
}

View File

@@ -31,6 +31,7 @@ use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\PiggyBankEvent;
use FireflyIII\Models\PiggyBankRepetition;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups;
use Illuminate\Database\QueryException;
use Log;
@@ -39,7 +40,7 @@ use Log;
*/
trait ModifiesPiggyBanks
{
use CreatesObjectGroups;
/**
* @param PiggyBank $piggyBank
* @param string $amount
@@ -274,6 +275,15 @@ trait ModifiesPiggyBanks
$repetition->save();
}
$objectGroupTitle = $data['object_group'] ?? '';
if ('' !== $objectGroupTitle) {
$objectGroup = $this->findOrCreateObjectGroup($objectGroupTitle);
if (null !== $objectGroup) {
$piggyBank->objectGroups()->sync([$objectGroup->id]);
$piggyBank->save();
}
}
return $piggyBank;
}
@@ -313,6 +323,15 @@ trait ModifiesPiggyBanks
$repetition->save();
}
$objectGroupTitle = $data['object_group'] ?? '';
if ('' !== $objectGroupTitle) {
$objectGroup = $this->findOrCreateObjectGroup($objectGroupTitle);
if (null !== $objectGroup) {
$piggyBank->objectGroups()->sync([$objectGroup->id]);
$piggyBank->save();
}
}
return $piggyBank;
}

View File

@@ -265,7 +265,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
*/
public function getPiggyBanks(): Collection
{
return $this->user->piggyBanks()->with(['account'])->orderBy('order', 'ASC')->get();
return $this->user->piggyBanks()->with(['account', 'objectGroups'])->orderBy('order', 'ASC')->get();
}

View File

@@ -25,6 +25,7 @@ namespace FireflyIII\Transformers;
use FireflyIII\Models\Account;
use FireflyIII\Models\ObjectGroup;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
@@ -83,6 +84,17 @@ class PiggyBankTransformer extends AbstractTransformer
$notes = $this->piggyRepos->getNoteText($piggyBank);
$notes = '' === $notes ? null : $notes;
$objectGroupId = null;
$objectGroupOrder = 0;
$objectGroupTitle = null;
/** @var ObjectGroup $objectGroup */
$objectGroup = $piggyBank->objectGroups->first();
if (null !== $objectGroup) {
$objectGroupId = (int) $objectGroup->id;
$objectGroupOrder = (int) $objectGroup->order;
$objectGroupTitle = $objectGroup->title;
}
// get currently saved amount:
$currentAmountStr = $this->piggyRepos->getCurrentAmount($piggyBank);
$currentAmount = round($currentAmountStr, $currency->decimal_places);
@@ -114,9 +126,12 @@ class PiggyBankTransformer extends AbstractTransformer
'save_per_month' => round($this->piggyRepos->getSuggestedMonthlyAmount($piggyBank), $currency->decimal_places),
'start_date' => $startDate,
'target_date' => $targetDate,
'order' => (int)$piggyBank->order,
'order' => (int) $piggyBank->order,
'active' => true,
'notes' => $notes,
'object_group_id' => $objectGroupId,
'object_group_order' => $objectGroupOrder,
'object_group_title' => $objectGroupTitle,
'links' => [
[
'rel' => 'self',

View File

@@ -139,6 +139,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @property bool $blocked
* @property string|null $blocked_code
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Role[] $roles
* @property string|null $provider
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\User whereProvider($value)
*/
class User extends Authenticatable
{