diff --git a/app/Repositories/Tag/TagRepository.php b/app/Repositories/Tag/TagRepository.php index 6a3323f074..ee6e89be17 100644 --- a/app/Repositories/Tag/TagRepository.php +++ b/app/Repositories/Tag/TagRepository.php @@ -198,17 +198,11 @@ class TagRepository implements TagRepositoryInterface /* * If any transaction is a deposit, cannot become a balancing act. */ - $count = 0; foreach ($tag->transactionjournals as $journal) { if ($journal->transactionType->type == 'Deposit') { - $count++; + return false; } } - if ($count > 0) { - return false; - } - - return true; } @@ -294,7 +288,6 @@ class TagRepository implements TagRepositoryInterface // tag is attached just like that: if ($withdrawals < 1 && $deposits < 1) { $journal->tags()->save($tag); - return true; } @@ -308,7 +301,8 @@ class TagRepository implements TagRepositoryInterface return $this->matchAll($journal, $tag); } - return false; + // this statement is unreachable. + return false; // @codeCoverageIgnore } diff --git a/tests/repositories/TagRepositoryTest.php b/tests/repositories/TagRepositoryTest.php index a8b6697b58..7bfd0744dc 100644 --- a/tests/repositories/TagRepositoryTest.php +++ b/tests/repositories/TagRepositoryTest.php @@ -365,6 +365,45 @@ class TagRepositoryTest extends TestCase } + /** + * An advance payment accepts only one withdrawal, not two, even not + * if the accounts are the same + * + * @covers FireflyIII\Repositories\Tag\TagRepository::connect + * @covers FireflyIII\Repositories\Tag\TagRepository::connectAdvancePayment + * @covers FireflyIII\Repositories\Tag\TagRepository::matchAll + */ + public function testConnectPaymentTwoWithdrawalsSameAccounts() + { + $withdrawal = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + FactoryMuffin::create('FireflyIII\Models\TransactionType'); + FactoryMuffin::create('FireflyIII\Models\TransactionType'); + + $journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $otherJournal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + + $journal->transaction_type_id = $withdrawal->id; + $otherJournal->transaction_type_id = $withdrawal->id; + + // match up accounts: + $otherJournal->transactions[0]->account_id = $journal->transactions[0]->account_id; + $otherJournal->transactions[1]->account_id = $journal->transactions[1]->account_id; + $otherJournal->transactions[0]->save(); + $otherJournal->transactions[1]->save(); + + + $tag->tagMode = 'advancePayment'; + + $tag->save(); + $journal->save(); + $otherJournal->save(); + $otherJournal->tags()->save($tag); + + $result = $this->object->connect($journal, $tag); + $this->assertFalse($result); + } + /** * @covers FireflyIII\Repositories\Tag\TagRepository::coveredByBalancingActs */ @@ -485,6 +524,171 @@ class TagRepositoryTest extends TestCase $this->assertEquals($data['tag'], $tag->tag); } + /** + * By default, any tag can become an advancePayment + * + * @covers FireflyIII\Repositories\Tag\TagRepository::tagAllowAdvance + */ + public function testTagAllowAdvance() + { + // create a tag + $user = FactoryMuffin::create('FireflyIII\User'); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + $tag->tagMode = 'nothing'; + $tag->user_id = $user->id; + $tag->save(); + + $result = $this->object->tagAllowAdvance($tag); + $this->assertTrue($result); + } + + /** + * If the tag has one transfer, it can NOT become an advance payment. + * + * @covers FireflyIII\Repositories\Tag\TagRepository::tagAllowAdvance + */ + public function testTagAllowAdvanceWithTransfer() + { + // create a tag + $user = FactoryMuffin::create('FireflyIII\User'); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + FactoryMuffin::create('FireflyIII\Models\TransactionType'); // withdrawal + FactoryMuffin::create('FireflyIII\Models\TransactionType'); // deposit + $transfer = FactoryMuffin::create('FireflyIII\Models\TransactionType'); // transfer + $tag->tagMode = 'nothing'; + $tag->user_id = $user->id; + $tag->save(); + + // create withdrawal: + $journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $journal->transaction_type_id = $transfer->id; + $journal->save(); + $journal->tags()->save($tag); + + $result = $this->object->tagAllowAdvance($tag); + $this->assertFalse($result); + } + + /** + * If the tag has one withdrawal, it can still become an advance payment. + * + * @covers FireflyIII\Repositories\Tag\TagRepository::tagAllowAdvance + */ + public function testTagAllowAdvanceWithWithdrawal() + { + // create a tag + $user = FactoryMuffin::create('FireflyIII\User'); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + $tag->tagMode = 'nothing'; + $tag->user_id = $user->id; + $tag->save(); + + // create withdrawal: + $journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $journal->tags()->save($tag); + + $result = $this->object->tagAllowAdvance($tag); + $this->assertTrue($result); + } + + /** + * If the tag has two withdrawals, it CANNOT become an advance payment. + * + * @covers FireflyIII\Repositories\Tag\TagRepository::tagAllowAdvance + */ + public function testTagAllowAdvanceWithWithdrawals() + { + // create a tag + $user = FactoryMuffin::create('FireflyIII\User'); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + $withdrawal = FactoryMuffin::create('FireflyIII\Models\TransactionType'); + $tag->tagMode = 'nothing'; + $tag->user_id = $user->id; + $tag->save(); + + // create withdrawals + for ($i = 0; $i < 2; $i++) { + $journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $journal->transaction_type_id = $withdrawal->id; + $journal->save(); + $journal->tags()->save($tag); + } + + $result = $this->object->tagAllowAdvance($tag); + $this->assertFalse($result); + } + + /** + * By default, an empty tag can become a balancing act. + * + * @covers FireflyIII\Repositories\Tag\TagRepository::tagAllowBalancing + */ + public function testTagAllowBalancing() + { + // create a tag + $user = FactoryMuffin::create('FireflyIII\User'); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + $tag->tagMode = 'nothing'; + $tag->user_id = $user->id; + $tag->save(); + + $result = $this->object->tagAllowBalancing($tag); + $this->assertTrue($result); + } + + /** + * When the tag has one deposit, it can NOT become a balancing act. + * + * @covers FireflyIII\Repositories\Tag\TagRepository::tagAllowBalancing + */ + public function testTagAllowBalancingDeposit() + { + + // create a tag + FactoryMuffin::create('FireflyIII\Models\TransactionType'); // withdrawal + $deposit = FactoryMuffin::create('FireflyIII\Models\TransactionType'); // deposit + $user = FactoryMuffin::create('FireflyIII\User'); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + $tag->tagMode = 'nothing'; + $tag->user_id = $user->id; + $tag->save(); + + // create three journals and connect them: + for ($i = 0; $i < 1; $i++) { + $journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $journal->transaction_type_id = $deposit->id; + $journal->save(); + $journal->tags()->save($tag); + } + + $result = $this->object->tagAllowBalancing($tag); + $this->assertFalse($result); + } + + /** + * When the tag has more than 2 transactions connected to it, it cannot become abalancing act. + * + * @covers FireflyIII\Repositories\Tag\TagRepository::tagAllowBalancing + */ + public function testTagAllowBalancingManyJournals() + { + // create a tag + $user = FactoryMuffin::create('FireflyIII\User'); + $tag = FactoryMuffin::create('FireflyIII\Models\Tag'); + $tag->tagMode = 'nothing'; + $tag->user_id = $user->id; + $tag->save(); + + // create three journals and connect them: + for ($i = 0; $i < 3; $i++) { + $journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal'); + $journal->tags()->save($tag); + } + + $result = $this->object->tagAllowBalancing($tag); + $this->assertFalse($result); + } + /** * @covers FireflyIII\Repositories\Tag\TagRepository::update */