mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2026-01-10 12:24:50 +00:00
Piggy bank can now have a group.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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'),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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:
|
||||
|
||||
61
app/Repositories/ObjectGroup/CreatesObjectGroups.php
Normal file
61
app/Repositories/ObjectGroup/CreatesObjectGroups.php
Normal 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();
|
||||
}
|
||||
}
|
||||
44
app/Repositories/ObjectGroup/ObjectGroupRepository.php
Normal file
44
app/Repositories/ObjectGroup/ObjectGroupRepository.php
Normal 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.*']);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user