mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2026-01-06 06:01:21 +00:00
All kinds of new stuff: finished most of the importing routines, extended the database (single table inheritance) and expanded some other stuff.
This commit is contained in:
78
app/lib/Firefly/Database/SingleTableInheritanceEntity.php
Normal file
78
app/lib/Firefly/Database/SingleTableInheritanceEntity.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace Firefly\Database;
|
||||
|
||||
|
||||
abstract class SingleTableInheritanceEntity extends \Elegant
|
||||
{
|
||||
/**
|
||||
* The field that stores the subclass
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $subclassField = null;
|
||||
/**
|
||||
* must be overridden and set to true in subclasses
|
||||
* @var bool
|
||||
*/
|
||||
protected $isSubclass = false;
|
||||
|
||||
public function newFromBuilder($attributes = array())
|
||||
{
|
||||
$instance = $this->mapData((array)$attributes)->newInstance(array(), true);
|
||||
$instance->setRawAttributes((array)$attributes, true);
|
||||
return $instance;
|
||||
}
|
||||
|
||||
// if no subclass is defined, function as normal
|
||||
|
||||
public function mapData(array $attributes)
|
||||
{
|
||||
if (!$this->subclassField) {
|
||||
return $this->newInstance();
|
||||
}
|
||||
|
||||
return new $attributes[$this->subclassField];
|
||||
}
|
||||
|
||||
// instead of using $this->newInstance(), call
|
||||
// newInstance() on the object from mapData
|
||||
|
||||
public function newQuery($excludeDeleted = true)
|
||||
{
|
||||
// If using Laravel 4.0.x then use the following commented version of this command
|
||||
// $builder = new Builder($this->newBaseQueryBuilder());
|
||||
// newEloquentBuilder() was added in 4.1
|
||||
$builder = $this->newEloquentBuilder($this->newBaseQueryBuilder());
|
||||
|
||||
// Once we have the query builders, we will set the model instances so the
|
||||
// builder can easily access any information it may need from the model
|
||||
// while it is constructing and executing various queries against it.
|
||||
$builder->setModel($this)->with($this->with);
|
||||
|
||||
if ($excludeDeleted && $this->softDelete) {
|
||||
$builder->whereNull($this->getQualifiedDeletedAtColumn());
|
||||
}
|
||||
|
||||
if ($this->subclassField && $this->isSubclass()) {
|
||||
$builder->where($this->subclassField, '=', get_class($this));
|
||||
}
|
||||
|
||||
return $builder;
|
||||
}
|
||||
|
||||
public function isSubclass()
|
||||
{
|
||||
return $this->isSubclass;
|
||||
}
|
||||
|
||||
// ensure that the subclass field is assigned on save
|
||||
|
||||
public function save(array $options = array())
|
||||
{
|
||||
if ($this->subclassField) {
|
||||
$this->attributes[$this->subclassField] = get_class($this);
|
||||
}
|
||||
return parent::save($options);
|
||||
}
|
||||
}
|
||||
@@ -49,9 +49,18 @@ class MigrationHelper implements MigrationHelperInterface
|
||||
\DB::beginTransaction();
|
||||
|
||||
try {
|
||||
// create cash account:
|
||||
$this->_createCashAccount();
|
||||
|
||||
$this->_importAccounts();
|
||||
$this->_importComponents();
|
||||
$this->_importPiggybanks();
|
||||
//$this->_importPiggybanks();
|
||||
|
||||
// create transactions:
|
||||
$this->_importTransactions();
|
||||
|
||||
// create transfers:
|
||||
$this->_importTransfers();
|
||||
|
||||
|
||||
} catch (\Firefly\Exception\FireflyException $e) {
|
||||
@@ -66,6 +75,15 @@ class MigrationHelper implements MigrationHelperInterface
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function _createCashAccount()
|
||||
{
|
||||
$cashAT = \AccountType::where('description', 'Cash account')->first();
|
||||
/** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */
|
||||
$accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
$cash = $accounts->store(['name' => 'Cash account', 'account_type' => $cashAT, 'active' => false]);
|
||||
$this->map['cash'] = $cash;
|
||||
}
|
||||
|
||||
protected function _importAccounts()
|
||||
{
|
||||
|
||||
@@ -83,7 +101,7 @@ class MigrationHelper implements MigrationHelperInterface
|
||||
floatval($entry->openingbalance)
|
||||
);
|
||||
}
|
||||
$this->map['accounts'][$entry->id] = $account->id;
|
||||
$this->map['accounts'][$entry->id] = $account;
|
||||
\Log::info('Imported account "' . $entry->name . '" with balance ' . $entry->openingbalance);
|
||||
}
|
||||
}
|
||||
@@ -91,38 +109,25 @@ class MigrationHelper implements MigrationHelperInterface
|
||||
protected function _importComponents()
|
||||
{
|
||||
$beneficiaryAT = \AccountType::where('description', 'Beneficiary account')->first();
|
||||
$budgetType = \ComponentType::where('type', 'budget')->first();
|
||||
$categoryType = \ComponentType::where('type', 'category')->first();
|
||||
foreach ($this->JSON->components as $entry) {
|
||||
switch ($entry->type->type) {
|
||||
case 'beneficiary':
|
||||
$beneficiary = $this->_importBeneficiary($entry, $beneficiaryAT);
|
||||
$this->map['accounts'][$entry->id] = $beneficiary->id;
|
||||
$this->map['accounts'][$entry->id] = $beneficiary;
|
||||
break;
|
||||
case 'category':
|
||||
$component = $this->_importComponent($entry, $categoryType);
|
||||
$this->map['components'][$entry->id] = $component->id;
|
||||
$component = $this->_importCategory($entry);
|
||||
$this->map['categories'][$entry->id] = $component;
|
||||
break;
|
||||
case 'budget':
|
||||
$component = $this->_importComponent($entry, $budgetType);
|
||||
$this->map['components'][$entry->id] = $component->id;
|
||||
$component = $this->_importBudget($entry);
|
||||
$this->map['budgets'][$entry->id] = $component;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected function _importPiggybanks() {
|
||||
|
||||
/** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */
|
||||
$accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
|
||||
// get type for piggy:
|
||||
$piggyAT = \AccountType::where('description', 'Piggy bank')->first();
|
||||
foreach($this->JSON->piggybanks as $piggyBank) {
|
||||
}
|
||||
}
|
||||
|
||||
protected function _importBeneficiary($component, \AccountType $beneficiaryAT)
|
||||
{
|
||||
/** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */
|
||||
@@ -135,10 +140,98 @@ class MigrationHelper implements MigrationHelperInterface
|
||||
);
|
||||
}
|
||||
|
||||
protected function _importComponent($component, \ComponentType $type)
|
||||
protected function _importCategory($component)
|
||||
{
|
||||
/** @var \Firefly\Storage\Component\ComponentRepositoryInterface $components */
|
||||
$components = \App::make('Firefly\Storage\Component\ComponentRepositoryInterface');
|
||||
return $components->store(['name' => $component->name, 'component_type' => $type]);
|
||||
return $components->store(['name' => $component->name, 'class' => 'Category']);
|
||||
}
|
||||
|
||||
protected function _importBudget($component)
|
||||
{
|
||||
/** @var \Firefly\Storage\Component\ComponentRepositoryInterface $components */
|
||||
$components = \App::make('Firefly\Storage\Component\ComponentRepositoryInterface');
|
||||
return $components->store(['name' => $component->name, 'class' => 'Budget']);
|
||||
}
|
||||
|
||||
protected function _importTransactions()
|
||||
{
|
||||
|
||||
/** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface $journals */
|
||||
$journals = \App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface');
|
||||
|
||||
// loop component_transaction to find beneficiaries, categories and budgets:
|
||||
$beneficiaries = [];
|
||||
$categories = [];
|
||||
$budgets = [];
|
||||
foreach ($this->JSON->component_transaction as $entry) {
|
||||
// beneficiaries
|
||||
if (isset($this->map['accounts'][$entry->component_id])) {
|
||||
$beneficiaries[$entry->transaction_id] = $this->map['accounts'][$entry->component_id];
|
||||
}
|
||||
|
||||
// categories
|
||||
if (isset($this->map['categories'][$entry->component_id])) {
|
||||
$categories[$entry->transaction_id] = $this->map['categories'][$entry->component_id];
|
||||
}
|
||||
|
||||
// budgets:
|
||||
if (isset($this->map['budgets'][$entry->component_id])) {
|
||||
$budgets[$entry->transaction_id] = $this->map['budgets'][$entry->component_id];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->JSON->transactions as $entry) {
|
||||
$id = $entry->id;
|
||||
|
||||
// to properly save the amount, do it times -1:
|
||||
$amount = $entry->amount * -1;
|
||||
|
||||
/** @var \Account $fromAccount */
|
||||
$fromAccount = isset($this->map['accounts'][$entry->account_id])
|
||||
? $this->map['accounts'][$entry->account_id] : false;
|
||||
|
||||
/** @var \Account $toAccount */
|
||||
$toAccount = isset($beneficiaries[$entry->id]) ? $beneficiaries[$entry->id] : $this->map['cash'];
|
||||
|
||||
$date = new \Carbon\Carbon($entry->date);
|
||||
$journal = $journals->createSimpleJournal($fromAccount, $toAccount, $entry->description, $amount, $date);
|
||||
|
||||
// save budgets and categories, on the journal
|
||||
if(isset($budgets[$entry->id])) {
|
||||
$budget = $budgets[$entry->id];
|
||||
$journal->budgets()->save($budget);
|
||||
}
|
||||
if(isset($categories[$entry->id])) {
|
||||
$category = $categories[$entry->id];
|
||||
$journal->categories()->save($category);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected function _importTransfers()
|
||||
{
|
||||
/** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface $journals */
|
||||
$journals = \App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface');
|
||||
|
||||
foreach ($this->JSON->transfers as $entry) {
|
||||
$id = $entry->id;
|
||||
|
||||
// to properly save the amount, do it times 1 (?):
|
||||
$amount = $entry->amount * -1;
|
||||
|
||||
/** @var \Account $fromAccount */
|
||||
$fromAccount = isset($this->map['accounts'][$entry->accountfrom_id])
|
||||
? $this->map['accounts'][$entry->accountto_id] : false;
|
||||
|
||||
/** @var \Account $toAccount */
|
||||
$toAccount = isset($this->map['accounts'][$entry->accountto_id])
|
||||
? $this->map['accounts'][$entry->accountfrom_id] : false;
|
||||
|
||||
$date = new \Carbon\Carbon($entry->date);
|
||||
$journals->createSimpleJournal($fromAccount, $toAccount, $entry->description, $amount, $date);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,8 @@ interface AccountRepositoryInterface
|
||||
|
||||
public function count();
|
||||
|
||||
public function get();
|
||||
|
||||
public function store($data);
|
||||
public function storeWithInitialBalance($data,\Carbon\Carbon $date, $amount = 0);
|
||||
|
||||
|
||||
@@ -13,6 +13,10 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
{
|
||||
}
|
||||
|
||||
public function get() {
|
||||
return \Auth::user()->accounts()->get();
|
||||
}
|
||||
|
||||
public function count()
|
||||
{
|
||||
return \Auth::user()->accounts()->count();
|
||||
|
||||
@@ -20,18 +20,26 @@ class EloquentComponentRepository implements ComponentRepositoryInterface
|
||||
|
||||
public function store($data)
|
||||
{
|
||||
if (!isset($data['component_type'])) {
|
||||
throw new \Firefly\Exception\FireflyException('No component type present.');
|
||||
if (!isset($data['class'])) {
|
||||
throw new \Firefly\Exception\FireflyException('No class type present.');
|
||||
}
|
||||
switch ($data['class']) {
|
||||
case 'Budget':
|
||||
$component = new \Budget;
|
||||
break;
|
||||
case 'Category':
|
||||
$component = new \Category;
|
||||
break;
|
||||
|
||||
}
|
||||
$component = new \Component;
|
||||
$component->componentType()->associate($data['component_type']);
|
||||
$component->name = $data['name'];
|
||||
$component->user()->associate(\Auth::user());
|
||||
try {
|
||||
$component->save();
|
||||
} catch (\Illuminate\Database\QueryException $e) {
|
||||
\Log::error('DB ERROR: ' . $e->getMessage());
|
||||
throw new \Firefly\Exception\FireflyException('Could not save component ' . $data['name']);
|
||||
throw new \Firefly\Exception\FireflyException('Could not save component ' . $data['name'] . ' of type'
|
||||
. $data['class']);
|
||||
}
|
||||
|
||||
return $component;
|
||||
|
||||
@@ -15,7 +15,7 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
public function createSimpleJournal(\Account $from, \Account $to, $description, $amount, \Carbon\Carbon $date)
|
||||
{
|
||||
|
||||
|
||||
\Log::debug('Creating tranaction "'.$description.'".');
|
||||
/*
|
||||
* We're building this thinking the money goes from A to B.
|
||||
* If the amount is negative however, the money still goes
|
||||
@@ -67,6 +67,10 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
$journalType = \TransactionType::where('type', 'Deposit')->first();
|
||||
break;
|
||||
}
|
||||
|
||||
// some debug information:
|
||||
\Log::debug($journalType->type.': AccountFrom "'.$from->name.'" will gain/lose '.$amountFrom.' and AccountTo "'.$to->name.'" will gain/lose '.$amountTo);
|
||||
|
||||
if (is_null($journalType)) {
|
||||
\Log::error('Could not figure out transacion type!');
|
||||
throw new \Firefly\Exception\FireflyException('Could not figure out transaction type.');
|
||||
@@ -122,10 +126,6 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
|
||||
$journal->completed = true;
|
||||
$journal->save();
|
||||
return;
|
||||
|
||||
|
||||
echo 'saved!';
|
||||
|
||||
return $journal;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user