Skip to content

[Jociel Souza] Created project to test coderockr #57

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

[*.{yml,yaml}]
indent_size = 2
19 changes: 19 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
APP_NAME=Lumen
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
APP_TIMEZONE=UTC

LOG_CHANNEL=stack
LOG_SLACK_WEBHOOK_URL=

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

CACHE_DRIVER=file
QUEUE_CONNECTION=sync
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/vendor
/.idea
Homestead.json
Homestead.yaml
.env
.phpunit.result.cache
/public/docs
/.scribe
1 change: 1 addition & 0 deletions .php-cs-fixer.cache

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions .styleci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
php:
preset: laravel
disabled:
- unused_use
js: true
css: true
133 changes: 67 additions & 66 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,88 +1,89 @@
# Back End Test Project <img src="https://coderockr.com/assets/images/coderockr.svg" align="right" height="50px" />
# Coderock test

You should see this challenge as an opportunity to create an application following modern development best practices (given the stack of your choice), but also feel free to use your own architecture preferences (coding standards, code organization, third-party libraries, etc). It’s perfectly fine to use vanilla code or any framework or libraries.
###

## Scope
## prerequisites
To run the project it is necessary to have already installed PHP, Composer and SQLite database,
check on the projects page how to install each one

In this challenge you should build an API for an application that stores and manages investments, it should have the following features:
* [SQLite](https://sqlite.org/index.html)
* [PHP](https://www.php.net/manual/pt_BR/install.php)
* [Composer](https://getcomposer.org)

1. __Creation__ of an investment with an owner, a creation date and an amount.
1. The creation date of an investment can be today or a date in the past.
2. An investment should not be or become negative.
2. __View__ of an investment with its initial amount and expected balance.
1. Expected balance should be the sum of the invested amount and the [gains][].
2. If an investment was already withdrawn then the balance must reflect the gains of that investment
3. __Withdrawal__ of a investment.
1. The withdraw will always be the sum of the initial amount and its gains,
partial withdrawn is not supported.
2. Withdrawals can happen in the past or today, but can't happen before the investment creation or the future.
3. [Taxes][taxes] need to be applied to the withdrawals before showing the final value.
4. __List__ of a person's investments
1. This list should have pagination.

__NOTE:__ the implementation of an interface will not be evaluated.
### Versions used
* SQLite 3.40
* PHP 8.0

### Gain Calculation
<br>

The investment will pay 0.52% every month in the same day of the investment creation.
## Dependencies and Framework
For this test I used the Lumen framework in version 10.x.
I also used the Moneyphp library that implements the 'Money pattern'
as described in [Fowler2002](https://www.moneyphp.org/en/stable/#fowler2002),
this library provides tools to easily store and use monetary values.
Another library I used was Carbon PHP, also with the intention of facilitating operations with dates.
And I used Scribe lib for generate API documentation.
* [Carbon](https://carbon.nesbot.com/docs/)
* [MoneyPHP](www.moneyphp.org/en/stable/)
* [Scribe](https://scribe.knuckles.wtf/)

Given that the gain is paid every month, it should be treated as [compound gain][], which means that every new period (month) the amount gained will become part of the investment balance for the next payment.
[Test Description](https://github.com/Coderockr/backend-test)
I used the MVC-like estructure from lumen framework and create Service and Repository layers,
I used casts for monetary and dates fields in models, also to fields values for type, origin and
investment status witch coming from an enums object.
A job was created to run a function daily to apply a rate to investments that have been one month
since the last application on the current date.

### Taxation

When money is withdrawn, tax is triggered. Taxes apply only to the profit/gain portion of the money withdrawn. For example, if the initial investment was 1000.00, the current balance is 1200.00, then the taxes will be applied to the 200.00.
## Installation

The tax percentage changes according to the age of the investment:
* If it is less than one year old, the percentage will be 22.5% (tax = 45.00).
* If it is between one and two years old, the percentage will be 18.5% (tax = 37.00).
* If older than two years, the percentage will be 15% (tax = 30.00).
First we must clone the GitHub repository
```sh
git clone https://github.com/Jciel/backend-test.git
```

## Requirements
1. Create project using any technology of your preference. It’s perfectly OK to use vanilla code or any framework or libraries;
2. Although you can use as many dependencies as you want, you should manage them wisely;
3. It is not necessary to send the notification emails, however, the code required for that would be welcome;
4. The API must be documented in some way.
<br>
<br>

## Deliverables
The project source code and dependencies should be made available in GitHub. Here are the steps you should follow:
1. Fork this repository to your GitHub account (create an account if you don't have one, you will need it working with us).
2. Create a "development" branch and commit the code to it. Do not push the code to the main branch.
3. Include a README file that describes:
- Special build instructions, if any
- List of third-party libraries used and short description of why/how they were used
- A link to the API documentation.
4. Once the work is complete, create a pull request from "development" into "main" and send us the link.
5. Avoid using huge commits hiding your progress. Feel free to work on a branch and use `git rebase` to adjust your commits before submitting the final version.
After the clone of the project, we can enter the project directory and install
the application's dependencies
```sh
cd backend-test

## Coding Standards
When working on the project be as clean and consistent as possible.
composer install
```
## Migrations

## Project Deadline
Ideally you'd finish the test project in 5 days. It shouldn't take you longer than a entire week.
To run the migrations that will create the database structure, run the command
```sh
php artisan php artisan migrate
```

## Quality Assurance
Use the following checklist to ensure high quality of the project.
## Seed
To run the seeds to populate the database we can run the command
```sh
php artisan db:seed
```

### General
- First of all, the application should run without errors.
- Are all requirements set above met?
- Is coding style consistent?
- The API is well documented?
- The API has unit tests?
<br>

## Submission
1. A link to the Github repository.
2. Briefly describe how you decided on the tools that you used.
After installing the dependencies, we can upload the project running locally with the command
```sh
php artisan serve
```

## Have Fun Coding 🤘
- This challenge description is intentionally vague in some aspects, but if you need assistance feel free to ask for help.
- If any of the seems out of your current level, you may skip it, but remember to tell us about it in the pull request.
<br>

## Credits
## API documentation

This coding challenge was inspired on [kinvoapp/kinvo-back-end-test](https://github.com/kinvoapp/kinvo-back-end-test/blob/2f17d713de739e309d17a1a74a82c3fd0e66d128/README.md)
To create the API documentation we need to run the command

[gains]: #gain-calculation
[taxes]: #taxation
[interest]: #interest-calculation
[compound gain]: https://www.investopedia.com/terms/g/gain.asp
```
php artisan scribe:generate
```

After that the documentation will be available at the local address
```
http://127.0.0.1:8000/docs
```
25 changes: 25 additions & 0 deletions app/Casts/Carbon.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

class Carbon implements CastsAttributes
{
protected $create_date;

public function __construct($date)
{
$this->create_date = $date;
}

public function get($model, $key, $value, $attributes)
{
return new \Carbon\Carbon(new \DateTime($attributes[$this->create_date]));
}

public function set($model, $key, $value, $attributes)
{
return $value;
}
}
25 changes: 25 additions & 0 deletions app/Casts/InvestmentStatus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

class InvestmentStatus implements CastsAttributes
{
protected $value;

public function __construct($value)
{
$this->value = $value;
}

public function get($model, $key, $value, $attributes)
{
return \App\Service\Enums\InvestmentStatus::from($value);
}

public function set($model, $key, $value, $attributes)
{
return $value;
}
}
34 changes: 34 additions & 0 deletions app/Casts/Money.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Money\Currency;

class Money implements CastsAttributes
{
protected $amount;
protected $currency;

public function __construct($amount, $currency)
{
$this->amount = $amount;
$this->currency = $currency;
}

public function get($model, string $key, $value, array $attributes)
{
return new \Money\Money(
$attributes[$this->amount],
new Currency($attributes[$this->currency])
);
}

public function set($model, string $key, $value, array $attributes)
{
return [
$this->amount => (int) $value->getAmount(),
$this->currency => (string) $value->getCurrency()
];
}
}
25 changes: 25 additions & 0 deletions app/Casts/OriginTransaction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

class OriginTransaction implements CastsAttributes
{
protected $value;

public function __construct($value)
{
$this->value = $value;
}

public function get($model, $key, $value, $attributes)
{
return \App\Service\Enums\OriginTransaction::from($value);
}

public function set($model, $key, $value, $attributes)
{
return $value;
}
}
25 changes: 25 additions & 0 deletions app/Casts/TypeTransaction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

class TypeTransaction implements CastsAttributes
{
protected $value;

public function __construct($value)
{
$this->value = $value;
}

public function get($model, $key, $value, $attributes)
{
return \App\Service\Enums\TypeTransaction::from($value);
}

public function set($model, $key, $value, $attributes)
{
return $value;
}
}
Empty file added app/Console/Commands/.gitkeep
Empty file.
34 changes: 34 additions & 0 deletions app/Console/Kernel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace App\Console;

use App\Jobs\ApplyRateInvestment;
use App\Service\InvestmentsService;
use Illuminate\Console\Scheduling\Schedule;
use Laravel\Lumen\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
\Knuckles\Scribe\Commands\GenerateDocumentation::class,
\Knuckles\Scribe\Commands\MakeStrategy::class,
\Knuckles\Scribe\Commands\Upgrade::class
];

/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->job(new ApplyRateInvestment($this->app->make(InvestmentsService::class)))->daily();
// $schedule->call()->daily();
}
}
10 changes: 10 additions & 0 deletions app/Events/Event.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace App\Events;

use Illuminate\Queue\SerializesModels;

abstract class Event
{
use SerializesModels;
}
Loading