Browse Source

Add project collectible earnings

Collectible earnings calculated based on
a project feature price * avg of tasks progress
pull/1/head
Nafies Luthfi 8 years ago
parent
commit
aa8b0430eb
  1. 17
      app/Entities/Projects/Project.php
  2. 2
      app/Providers/AppServiceProvider.php
  3. 78
      app/helpers.php
  4. 3
      database/factories/ModelFactory.php
  5. 17
      resources/views/projects/partials/project-stats.blade.php
  6. 29
      tests/Unit/Models/ProjectTest.php
  7. 2
      tests/Unit/Models/UserTest.php

17
app/Entities/Projects/Project.php

@ -11,7 +11,8 @@ use App\Entities\Users\User;
use Illuminate\Database\Eloquent\Model;
use Laracasts\Presenter\PresentableTrait;
class Project extends Model {
class Project extends Model
{
use PresentableTrait;
@ -98,4 +99,18 @@ class Project extends Model {
return $this->morphMany(File::class, 'fileable');
}
public function getCollectibeEarnings()
{
// Collectible earnings is total of (price * avg task progress of each feature)
$collectibeEarnings = 0;
$this->load('features.tasks');
foreach ($this->features as $feature) {
$progress = $feature->tasks->avg('progress');
$collectibeEarnings += ($progress / 100) * $feature->price;
}
return $collectibeEarnings;
}
}

2
app/Providers/AppServiceProvider.php

@ -2,8 +2,6 @@
namespace App\Providers;
use App\Entities\Projects\Project;
use DB;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider

78
app/helpers.php

@ -13,8 +13,9 @@ function formatNo($number)
function formatRp($number)
{
if ($number == 0) {return '-';}
if ($number < 0)
if ($number < 0) {
return '- Rp. ' . formatNo(abs($number));
}
return 'Rp. ' . formatNo($number);
}
@ -37,17 +38,17 @@ function delete_button($form_params = [], $button_label = 'Delete', $button_opti
$form_params['class'] = isset($form_params['class']) ? $form_params['class'] : 'del-form';
$form_params['style'] = isset($form_params['style']) ? $form_params['style'] : 'display:inline';
if (! isset($button_options['class']))
if (!isset($button_options['class'])) {
$button_options['class'] = 'pull-right';
}
if (! isset($button_options['title']))
if (!isset($button_options['title'])) {
$button_options['title'] = 'Delete this record';
}
$htmlForm = Form::open($form_params);
if (!empty($hiddenFields))
{
foreach ($hiddenFields as $k => $v)
{
if (!empty($hiddenFields)) {
foreach ($hiddenFields as $k => $v) {
$htmlForm .= Form::hidden($k, $v);
}
}
@ -59,8 +60,9 @@ function delete_button($form_params = [], $button_label = 'Delete', $button_opti
function formatDate($date)
{
if (!$date || $date == '0000-00-00')
if (!$date || $date == '0000-00-00') {
return null;
}
$explodedDate = explode('-', $date);
@ -73,9 +75,11 @@ function formatDate($date)
throw new App\Exceptions\InvalidDateException('Kesalahan format tanggal');
}
function dateId($date) {
if (is_null($date) || $date == '0000-00-00')
function dateId($date)
{
if (is_null($date) || $date == '0000-00-00') {
return '-';
}
$explodedDate = explode('-', $date);
@ -87,13 +91,16 @@ function dateId($date) {
throw new App\Exceptions\InvalidDateException('Kesalahan format tanggal');
}
function monthNumber($number) {
function monthNumber($number)
{
return str_pad($number, 2, "0", STR_PAD_LEFT);
}
function monthId($monthNumber) {
if (is_null($monthNumber))
function monthId($monthNumber)
{
if (is_null($monthNumber)) {
return $monthNumber;
}
$months = getMonths();
$monthNumber = monthNumber($monthNumber);
@ -141,7 +148,9 @@ function getDays()
function getDay($dayIndex = null)
{
$days = getDays();
if (!is_null($dayIndex) && in_array($dayIndex, range(1, 7))) return $days[$dayIndex];
if (!is_null($dayIndex) && in_array($dayIndex, range(1, 7))) {
return $days[$dayIndex];
}
return '-';
}
@ -153,28 +162,17 @@ function sanitizeNumber($number)
function formatSizeUnits($bytes)
{
if ($bytes >= 1073741824)
{
if ($bytes >= 1073741824) {
$bytes = number_format($bytes / 1073741824, 2) . ' GB';
}
elseif ($bytes >= 1048576)
{
} elseif ($bytes >= 1048576) {
$bytes = number_format($bytes / 1048576, 2) . ' MB';
}
elseif ($bytes >= 1024)
{
} elseif ($bytes >= 1024) {
$bytes = number_format($bytes / 1024, 2) . ' KB';
}
elseif ($bytes > 1)
{
} elseif ($bytes > 1) {
$bytes = $bytes . ' bytes';
}
elseif ($bytes == 1)
{
} elseif ($bytes == 1) {
$bytes = $bytes . ' byte';
}
else
{
} else {
$bytes = '0 bytes';
}
@ -188,18 +186,22 @@ function formatSizeUnits($bytes)
* @param array $parameters URL Parameter
* @param array $attributes The anchor tag atributes
*/
function html_link_to_route($name, $title = null, $parameters = [], $attributes = []) {
if (array_key_exists('icon', $attributes))
function html_link_to_route($name, $title = null, $parameters = [], $attributes = [])
{
if (array_key_exists('icon', $attributes)) {
$title = '<i class="fa fa-' . $attributes['icon'] . '"></i> ' . $title;
}
return app('html')->decode(link_to_route($name, $title, $parameters, $attributes));
}
function getProjectStatusesList($statusId = null) {
function getProjectStatusesList($statusId = null)
{
$statuses = [1 => 'Planned', 'On Progress', 'Done', 'Closed', 'Canceled', 'On Hold'];
if (is_null($statusId))
if (is_null($statusId)) {
return $statuses;
}
if (array_key_exists($statusId, $statuses)) {
return $statuses[$statusId];
@ -222,11 +224,13 @@ function paymentTypes($paymentTypeId = null)
{
$paymentTypes = [1 => 'Project', 'Add Feature', 'Maintenance'];
if (is_null($paymentTypeId))
if (is_null($paymentTypeId)) {
return $paymentTypes;
}
if (array_key_exists($paymentTypeId, $paymentTypes))
if (array_key_exists($paymentTypeId, $paymentTypes)) {
return $paymentTypes[$paymentTypeId];
}
return null;
}

3
database/factories/ModelFactory.php

@ -7,7 +7,6 @@ use App\Entities\Projects\Project;
use App\Entities\Projects\Task;
use App\Entities\Subscriptions\Subscription;
use App\Entities\Users\Event;
use App\Entities\Users\Role;
use App\Entities\Users\User;
$factory->define(User::class, function (Faker\Generator $faker) {
@ -102,7 +101,7 @@ $factory->define(Feature::class, function (Faker\Generator $faker) {
'worker_id' => function () {
return factory(User::class)->create()->id;
},
'type_id' => rand(1,2),
'type_id' => 1, // Main feature
'position' => rand(1, 10),
];
});

17
resources/views/projects/partials/project-stats.blade.php

@ -15,7 +15,7 @@
</a>
</div>
<div class="col-lg-6 col-md-12">
<a href="{{ route('projects.features',[$project->id]) }}" title="Progress Berdasarkan Index Bobot Biaya Fitur">
<a href="{{ route('projects.features',[$project->id]) }}" title="Total Fitur dan Task">
<div class="panel panel-default">
<div class="panel-heading">
<div class="row">
@ -29,5 +29,20 @@
</div>
</a>
</div>
<div class="col-lg-6 col-md-12">
<a href="{{ route('projects.features',[$project->id]) }}" title="Collectible Earnings">
<div class="panel panel-success">
<div class="panel-heading">
<div class="row">
<div class="col-xs-12 text-right">
<i class="fa fa-money fa-2x pull-left"></i>
<div class="lead">Collectibe Earnings</div>
<div class="lead" style="font-size: 30px;">{{ formatRp($project->getCollectibeEarnings()) }}</div>
</div>
</div>
</div>
</div>
</a>
</div>
<div class="clearfix"></div>
</div>

29
tests/Unit/Models/ProjectTest.php

@ -138,4 +138,33 @@ class ProjectTest extends TestCase
$project = factory(Project::class)->make();
$this->assertEquals(link_to_route('projects.show', $project->name, [$project->id]), $project->nameLink());
}
/** @test */
public function a_project_has_collectible_earnings_method()
{
// Collectible earnings is total of (price * avg task progress of each feature)
$project = factory(Project::class)->create();
$collectibeEarnings = 0;
$feature = factory(Feature::class)->create(['project_id' => $project->id, 'type_id' => 1, 'price' => 2000]);
factory(Task::class)->create(['feature_id' => $feature->id, 'progress' => 20]);
$collectibeEarnings += (2000 * (20 / 100)); // feature price * avg task progress
$feature = factory(Feature::class)->create(['project_id' => $project->id, 'type_id' => 1, 'price' => 3000]);
factory(Task::class)->create(['feature_id' => $feature->id, 'progress' => 30]);
$collectibeEarnings += (3000 * (30 / 100));
$feature = factory(Feature::class)->create(['project_id' => $project->id, 'type_id' => 1, 'price' => 1500]);
factory(Task::class)->create(['feature_id' => $feature->id, 'progress' => 100]);
$collectibeEarnings += (1500 * (100 / 100));
$feature = factory(Feature::class)->create(['project_id' => $project->id, 'type_id' => 1, 'price' => 1500]);
factory(Task::class)->create(['feature_id' => $feature->id, 'progress' => 100]);
$collectibeEarnings += (1500 * (100 / 100));
// $collectibeEarnings = 400 + 900 + 1500 + 1500;
$this->assertEquals($collectibeEarnings, $project->getCollectibeEarnings());
}
}

2
tests/Unit/Models/UserTest.php

@ -13,7 +13,7 @@ class UserTest extends TestCase
$user = factory(User::class)->create();
$this->assertEquals(link_to_route('users.show', $user->name, [$user->id], [
'target' => '_blank'
'target' => '_blank',
]), $user->nameLink());
}

Loading…
Cancel
Save