Browse Source

Update 2016-08-02.11.34

Search payments by project name
List On Progress Project by features list
Refactor project work duration to ProjectPresenter class
Project deletation also remove its payments, features and tasks
Show Current Credit on On Progress, Done, and On Hold project status
Add form error notification
Add route name on a task of feature
Add Project status update on project detail page
Add pagination on top of payment and project index page
Fix missing line break on project detail description
pull/1/head
Nafies Luthfi 10 years ago
parent
commit
c2b313780a
  1. 3
      app/Entities/Payments/PaymentsRepository.php
  2. 9
      app/Entities/Projects/FeaturesRepository.php
  3. 12
      app/Entities/Projects/ProjectPresenter.php
  4. 26
      app/Entities/Projects/ProjectsRepository.php
  5. 3
      app/Entities/Reports/ReportsRepository.php
  6. 8
      app/Http/Controllers/Projects/FeaturesController.php
  7. 11
      app/Http/Controllers/Projects/ProjectsController.php
  8. 2
      app/Http/Requests/Request.php
  9. 3
      app/Http/Requests/Tasks/CreateRequest.php
  10. 3
      app/Http/Requests/Tasks/UpdateRequest.php
  11. 3
      app/Http/routes/projects.php
  12. 4
      app/Services/FormField.php
  13. 2
      app/helpers.php
  14. 1
      database/factories/ModelFactory.php
  15. 3
      public/assets/css/app.css
  16. 2
      public/assets/css/app.css.map
  17. 4
      resources/assets/sass/app.scss
  18. 1
      resources/lang/id/task.php
  19. 2
      resources/views/features/add-from-other-project.blade.php
  20. 53
      resources/views/features/partials/feature-tasks-operation.blade.php
  21. 64
      resources/views/features/partials/feature-tasks.blade.php
  22. 5
      resources/views/features/show.blade.php
  23. 63
      resources/views/features/unfinished.blade.php
  24. 5
      resources/views/layouts/partials/sidebar.blade.php
  25. 7
      resources/views/pages/home.blade.php
  26. 3
      resources/views/payments/index.blade.php
  27. 1
      resources/views/projects/create.blade.php
  28. 8
      resources/views/projects/features.blade.php
  29. 19
      resources/views/projects/index.blade.php
  30. 6
      resources/views/projects/partials/project-show.blade.php
  31. 2
      resources/views/projects/payments.blade.php
  32. 16
      resources/views/projects/show.blade.php
  33. 2
      resources/views/reports/current-credits.blade.php
  34. 6
      resources/views/reports/payments/yearly.blade.php
  35. 33
      tests/ManageFeaturesTest.php
  36. 23
      tests/ManagePaymentsTest.php
  37. 71
      tests/ManageProjectsTest.php
  38. 10
      tests/ManageTasksTest.php

3
app/Entities/Payments/PaymentsRepository.php

@ -19,6 +19,9 @@ class PaymentsRepository extends BaseRepository
public function getAll($q) public function getAll($q)
{ {
return $this->model->orderBy('date','desc') return $this->model->orderBy('date','desc')
->whereHas('project', function($query) use ($q) {
$query->where('name', 'like', '%' . $q . '%');
})
->with('customer','project') ->with('customer','project')
->whereOwnerId(auth()->id()) ->whereOwnerId(auth()->id())
->paginate($this->_paginate); ->paginate($this->_paginate);

9
app/Entities/Projects/FeaturesRepository.php

@ -18,6 +18,15 @@ class FeaturesRepository extends BaseRepository
parent::__construct($model); parent::__construct($model);
} }
public function getUnfinishedFeatures()
{
return $this->model->whereHas('tasks', function($query) {
return $query->where('progress','<',100);
})
->with(['tasks','project','worker'])
->get();
}
public function requireProjectById($projectId) public function requireProjectById($projectId)
{ {
return Project::findOrFail($projectId); return Project::findOrFail($projectId);

12
app/Entities/Projects/ProjectPresenter.php

@ -21,4 +21,16 @@ class ProjectPresenter extends Presenter
return getProjectStatusesList($this->entity->status_id); return getProjectStatusesList($this->entity->status_id);
} }
public function workDuration()
{
if (is_null($this->entity->end_date))
return '-';
$workDuration = dateDifference($this->entity->start_date,$this->entity->end_date);
if ((int) $workDuration > 30)
return dateDifference($this->entity->start_date,$this->entity->end_date, '%m Bulan %d Hari');
return $workDuration . ' Hari';
}
} }

26
app/Entities/Projects/ProjectsRepository.php

@ -30,6 +30,7 @@ class ProjectsRepository extends BaseRepository
$query->where('status_id', $statusId); $query->where('status_id', $statusId);
}) })
->withCount('payments') ->withCount('payments')
->with('customer')
->whereOwnerId(auth()->id()) ->whereOwnerId(auth()->id())
->paginate($this->_paginate); ->paginate($this->_paginate);
} }
@ -73,14 +74,37 @@ class ProjectsRepository extends BaseRepository
public function delete($projectId) public function delete($projectId)
{ {
$project = $this->requireById($projectId); $project = $this->requireById($projectId);
DB::beginTransaction();
// Delete project payments
$project->payments()->delete(); $project->payments()->delete();
// Delete features tasks
$featureIds = $project->features->lists('id')->all();
DB::table('tasks')->whereIn('feature_id', $featureIds)->delete();
// Delete features
$project->features()->delete(); $project->features()->delete();
return $project->delete();
// Delete project
$project->delete();
DB::commit();
return 'deleted';
} }
public function getProjectFeatures($projectId) public function getProjectFeatures($projectId)
{ {
return Feature::whereProjectId($projectId)->with('worker','tasks')->get(); return Feature::whereProjectId($projectId)->with('worker','tasks')->get();
} }
public function updateStatus($statusId, $projectId)
{
$project = $this->requireById($projectId);
$project->status_id = $statusId;
$project->save();
// die('hit');
return $project;
}
} }

3
app/Entities/Reports/ReportsRepository.php

@ -52,7 +52,8 @@ class ReportsRepository extends BaseRepository
public function getCurrentCredits() public function getCurrentCredits()
{ {
$projects = Project::whereIn('status_id',[3,6])->with('payments')->get();
// On Progress, Done, On Hold
$projects = Project::whereIn('status_id',[2,3,6])->with('payments','customer')->get();
return $projects->filter(function($project) { return $projects->filter(function($project) {
return $project->cashInTotal() < $project->project_value; return $project->cashInTotal() < $project->project_value;
})->values(); })->values();

8
app/Http/Controllers/Projects/FeaturesController.php

@ -19,6 +19,12 @@ class FeaturesController extends Controller {
$this->repo = $repo; $this->repo = $repo;
} }
public function index()
{
$features = $this->repo->getUnfinishedFeatures();
return view('features.unfinished', compact('features'));
}
public function create($projectId) public function create($projectId)
{ {
$project = $this->repo->requireProjectById($projectId); $project = $this->repo->requireProjectById($projectId);
@ -95,7 +101,7 @@ class FeaturesController extends Controller {
$projectId = $feature->project_id; $projectId = $feature->project_id;
if ($featureId == $req->get('feature_id')) if ($featureId == $req->get('feature_id'))
{ {
// $feature->tasks()->delete();
$feature->tasks()->delete();
$feature->delete(); $feature->delete();
flash()->success(trans('feature.deleted')); flash()->success(trans('feature.deleted'));
} }

11
app/Http/Controllers/Projects/ProjectsController.php

@ -22,7 +22,7 @@ class ProjectsController extends Controller {
public function index(Request $req) public function index(Request $req)
{ {
$status = null; $status = null;
$statusId = $req->get('status', 3);
$statusId = $req->get('status');
if ($statusId) { if ($statusId) {
$status = $this->repo->getStatusName($statusId); $status = $this->repo->getStatusName($statusId);
} }
@ -41,7 +41,7 @@ class ProjectsController extends Controller {
{ {
$project = $this->repo->create($req->except('_token')); $project = $this->repo->create($req->except('_token'));
flash()->success(trans('project.created')); flash()->success(trans('project.created'));
return redirect()->route('projects.index');
return redirect()->route('projects.show', $project->id);
} }
public function show($projectId) public function show($projectId)
@ -98,4 +98,11 @@ class ProjectsController extends Controller {
return view('projects.payments', compact('project')); return view('projects.payments', compact('project'));
} }
public function statusUpdate(Request $req, $projectId)
{
$project = $this->repo->updateStatus($req->get('status_id'), $projectId);
flash()->success(trans('project.updated'));
return redirect()->route('projects.show', $projectId);
}
} }

2
app/Http/Requests/Request.php

@ -13,6 +13,6 @@ abstract class Request extends FormRequest
protected function formatErrors(Validator $validator) protected function formatErrors(Validator $validator)
{ {
flash()->error('Mohon periksa kembali form isian Anda.'); flash()->error('Mohon periksa kembali form isian Anda.');
return $validator->errors()->all();
return $validator->getMessageBag()->toArray();
} }
} }

3
app/Http/Requests/Tasks/CreateRequest.php

@ -28,7 +28,8 @@ class CreateRequest extends Request {
return [ return [
'name' => 'required|max:60', 'name' => 'required|max:60',
'description' => 'max:255', 'description' => 'max:255',
'progress' => 'numeric',
'progress' => 'numeric|max:100',
'route_name' => 'max:255',
]; ];
} }

3
app/Http/Requests/Tasks/UpdateRequest.php

@ -28,7 +28,8 @@ class UpdateRequest extends Request {
return [ return [
'name' => 'required|max:60', 'name' => 'required|max:60',
'description' => 'max:255', 'description' => 'max:255',
'progress' => 'required|numeric|max:100',
'progress' => 'numeric|max:100',
'route_name' => 'max:255',
]; ];
} }

3
app/Http/routes/projects.php

@ -7,6 +7,7 @@ Route::group(['middleware' => ['web','role:admin'], 'namespace' => 'Projects'],
Route::get('projects/{id}/delete', ['as'=>'projects.delete', 'uses'=>'ProjectsController@delete']); Route::get('projects/{id}/delete', ['as'=>'projects.delete', 'uses'=>'ProjectsController@delete']);
Route::get('projects/{id}/features', ['as'=>'projects.features', 'uses'=>'ProjectsController@features']); Route::get('projects/{id}/features', ['as'=>'projects.features', 'uses'=>'ProjectsController@features']);
Route::get('projects/{id}/payments', ['as'=>'projects.payments', 'uses'=>'ProjectsController@payments']); Route::get('projects/{id}/payments', ['as'=>'projects.payments', 'uses'=>'ProjectsController@payments']);
Route::patch('projects/{id}/status-update', ['as'=>'projects.status-update', 'uses'=>'ProjectsController@statusUpdate']);
Route::resource('projects','ProjectsController'); Route::resource('projects','ProjectsController');
/** /**
@ -18,7 +19,7 @@ Route::group(['middleware' => ['web','role:admin'], 'namespace' => 'Projects'],
Route::post('projects/{id}/features', ['as'=>'features.store', 'uses'=>'FeaturesController@store']); Route::post('projects/{id}/features', ['as'=>'features.store', 'uses'=>'FeaturesController@store']);
Route::post('projects/{id}/features/store-from-other-project', ['as'=>'features.store-from-other-project', 'uses'=>'FeaturesController@storeFromOtherProject']); Route::post('projects/{id}/features/store-from-other-project', ['as'=>'features.store-from-other-project', 'uses'=>'FeaturesController@storeFromOtherProject']);
Route::get('features/{id}/delete', ['as'=>'features.delete', 'uses'=>'FeaturesController@delete']); Route::get('features/{id}/delete', ['as'=>'features.delete', 'uses'=>'FeaturesController@delete']);
Route::resource('features','FeaturesController',['except' => ['index','create','store']]);
Route::resource('features','FeaturesController',['except' => ['create','store']]);
/** /**
* Tasks Routes * Tasks Routes

4
app/Services/FormField.php

@ -4,20 +4,20 @@ namespace App\Services;
use Form; use Form;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\MessageBag; use Illuminate\Support\MessageBag;
use Session;
/** /**
* FormField Class (Site FormField Service) * FormField Class (Site FormField Service)
*/ */
class FormField class FormField
{ {
protected $errorBag; protected $errorBag;
protected $options; protected $options;
protected $fieldParams; protected $fieldParams;
public function __construct() public function __construct()
{ {
$this->errorBag = session()->get('errors', new MessageBag);
$this->errorBag = Session::get('errors', new MessageBag);
} }
public function text($name, $options = []) public function text($name, $options = [])

2
app/helpers.php

@ -208,7 +208,7 @@ function getProjectStatusesList($statusId = null) {
return null; return null;
} }
function dateDifference($date1 , $date2 , $differenceFormat = '%m Bulan %d Hari' )
function dateDifference($date1 , $date2 , $differenceFormat = '%a' )
{ {
$datetime1 = date_create($date1); $datetime1 = date_create($date1);
$datetime2 = date_create($date2); $datetime2 = date_create($date2);

1
database/factories/ModelFactory.php

@ -106,5 +106,6 @@ $factory->define(Task::class, function (Faker\Generator $faker) {
'name' => $faker->sentence(3), 'name' => $faker->sentence(3),
'description' => $faker->paragraph, 'description' => $faker->paragraph,
'progress' => rand(40,100), 'progress' => rand(40,100),
'route_name' => implode('.', $faker->words(3))
]; ];
}); });

3
public/assets/css/app.css

@ -7170,6 +7170,9 @@ h1.page-header {
label.control-label { label.control-label {
color: #428bca; } color: #428bca; }
.well .pagination {
margin: -2px 0 0 -2px; }
@media (min-width: 768px) { @media (min-width: 768px) {
#page-wrapper { #page-wrapper {
margin-left: 200px; margin-left: 200px;

2
public/assets/css/app.css.map
File diff suppressed because it is too large
View File

4
resources/assets/sass/app.scss

@ -67,6 +67,10 @@ label.control-label {
color: #428bca; color: #428bca;
} }
.well .pagination {
margin: -2px 0 0 -2px;
}
@media(min-width:768px) { @media(min-width:768px) {
#page-wrapper { #page-wrapper {
margin-left: 200px; margin-left: 200px;

1
resources/lang/id/task.php

@ -18,5 +18,6 @@ return [
'not_found' => 'Task tidak ditemukan', 'not_found' => 'Task tidak ditemukan',
'progress' => 'Progress', 'progress' => 'Progress',
'empty' => 'Belum ada Task', 'empty' => 'Belum ada Task',
'route_name' => 'Route Aplikasi',
'back_to_index' => 'Kembali ke daftar Task', 'back_to_index' => 'Kembali ke daftar Task',
]; ];

2
resources/views/features/add-from-other-project.blade.php

@ -1,6 +1,6 @@
@extends('layouts.app') @extends('layouts.app')
@section('title', trans('feature.add_from_other_project'))
@section('title', trans('feature.add_from_other_project') . ' | ' . $project->name)
@section('content') @section('content')
@include('projects.partials.breadcrumb',['title' => trans('feature.add_from_other_project')]) @include('projects.partials.breadcrumb',['title' => trans('feature.add_from_other_project')])

53
resources/views/features/partials/feature-tasks-operation.blade.php

@ -0,0 +1,53 @@
@if (Request::has('action') == false)
{!! Form::open(['route' => ['tasks.store', $feature->id]])!!}
<div class="panel panel-default">
<div class="panel-heading"><h3 class="panel-title">{{ trans('task.create') }}</h3></div>
<div class="panel-body">
<div class="row">
<div class="col-sm-5">{!! FormField::text('name') !!}</div>
<div class="col-sm-5">{!! FormField::text('route_name') !!}</div>
<div class="col-sm-2">{!! FormField::text('progress', ['addon' => ['after' => '%'],'value' => 0]) !!}</div>
</div>
{!! FormField::text('description') !!}
{!! Form::submit(trans('task.create'), ['class' => 'btn btn-primary']) !!}
{!! Form::close() !!}
</div>
</div>
@endif
@if (Request::get('action') == 'task_edit' && $editableTask)
{!! Form::model($editableTask, ['route' => ['tasks.update', $editableTask->id],'method' =>'patch'])!!}
<div class="panel panel-default">
<div class="panel-heading"><h3 class="panel-title">{{ trans('task.edit') }}</h3></div>
<div class="panel-body">
<div class="row">
<div class="col-sm-5">{!! FormField::text('name') !!}</div>
<div class="col-sm-5">{!! FormField::text('route_name') !!}</div>
<div class="col-sm-2">{!! FormField::text('progress', ['addon' => ['after' => '%']]) !!}</div>
</div>
{!! FormField::text('description') !!}
{!! Form::hidden('feature_id', $editableTask->feature_id) !!}
{!! Form::submit(trans('task.update'), ['class' => 'btn btn-warning']) !!}
{!! link_to_route('features.show', trans('app.cancel'), [$feature->id], ['class' => 'btn btn-default']) !!}
{!! Form::close() !!}
</div>
</div>
@endif
@if (Request::get('action') == 'task_delete' && $editableTask)
<div class="panel panel-default">
<div class="panel-heading"><h3 class="panel-title">{{ trans('task.delete') }}</h3></div>
<div class="panel-body">
{{ trans('app.delete_confirm') }}
{!! link_to_route('features.show', trans('app.cancel'), [$feature->id], ['class' => 'btn btn-default']) !!}
<div class="pull-right">
{!! FormField::delete([
'route'=>['tasks.destroy',$editableTask->id]],
trans('app.delete_confirm_button'),
['class'=>'btn btn-danger'],
[
'task_id' => $editableTask->id,
'feature_id' => $editableTask->feature_id,
]) !!}
</div>
</div>
</div>
@endif

64
resources/views/features/partials/feature-tasks.blade.php

@ -1,65 +1,10 @@
@if (Request::has('action') == false)
{!! Form::open(['route' => ['tasks.store', $feature->id]])!!}
<div class="panel panel-default">
<div class="panel-heading"><h3 class="panel-title">{{ trans('task.create') }}</h3></div>
<div class="panel-body">
<div class="row">
<div class="col-sm-4">{!! FormField::text('name') !!}</div>
<div class="col-sm-6">{!! FormField::text('description') !!}</div>
<div class="col-sm-2">
{!! FormField::text('progress', ['addon' => ['after' => '%'],'value' => 0]) !!}
</div>
</div>
{!! Form::submit(trans('task.create'), ['class' => 'btn btn-primary']) !!}
{!! Form::close() !!}
</div>
</div>
@endif
@if (Request::get('action') == 'task_edit' && $editableTask)
{!! Form::model($editableTask, ['route' => ['tasks.update', $editableTask->id],'method' =>'patch'])!!}
<div class="panel panel-default">
<div class="panel-heading"><h3 class="panel-title">{{ trans('task.edit') }}</h3></div>
<div class="panel-body">
<div class="row">
<div class="col-sm-4">{!! FormField::text('name') !!}</div>
<div class="col-sm-6">{!! FormField::text('description') !!}</div>
<div class="col-sm-2">
{!! FormField::text('progress', ['addon' => ['after' => '%']]) !!}
</div>
</div>
{!! Form::hidden('feature_id', $editableTask->feature_id) !!}
{!! Form::submit(trans('task.update'), ['class' => 'btn btn-warning']) !!}
{!! link_to_route('features.show', trans('app.cancel'), [$feature->id], ['class' => 'btn btn-default']) !!}
{!! Form::close() !!}
</div>
</div>
@endif
@if (Request::get('action') == 'task_delete' && $editableTask)
<div class="panel panel-default">
<div class="panel-heading"><h3 class="panel-title">{{ trans('task.delete') }}</h3></div>
<div class="panel-body">
{{ trans('app.delete_confirm') }}
{!! link_to_route('features.show', trans('app.cancel'), [$feature->id], ['class' => 'btn btn-default']) !!}
<div class="pull-right">
{!! FormField::delete([
'route'=>['tasks.destroy',$editableTask->id]],
trans('app.delete_confirm_button'),
['class'=>'btn btn-danger'],
[
'task_id' => $editableTask->id,
'feature_id' => $editableTask->feature_id,
]) !!}
</div>
</div>
</div>
@endif
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"><h3 class="panel-title">{{ trans('feature.tasks') }}</h3></div> <div class="panel-heading"><h3 class="panel-title">{{ trans('feature.tasks') }}</h3></div>
<table class="table table-condensed"> <table class="table table-condensed">
<thead> <thead>
<th>{{ trans('app.table_no') }}</th> <th>{{ trans('app.table_no') }}</th>
<th>{{ trans('task.name') }}</th> <th>{{ trans('task.name') }}</th>
<th>{{ trans('app.description') }}</th>
<th>{{ trans('task.route_name') }}</th>
<th class="text-center">{{ trans('task.progress') }}</th> <th class="text-center">{{ trans('task.progress') }}</th>
<th>{{ trans('app.action') }}</th> <th>{{ trans('app.action') }}</th>
</thead> </thead>
@ -67,8 +12,11 @@
@forelse($feature->tasks as $key => $task) @forelse($feature->tasks as $key => $task)
<tr> <tr>
<td>{{ 1 + $key }}</td> <td>{{ 1 + $key }}</td>
<td>{{ $task->name }}</td>
<td>{{ $task->description }}</td>
<td>
<div>{{ $task->name }}</div>
<div class="small text-info">{{ $task->description }}</div>
</td>
<td>{{ $task->route_name }}</td>
<td class="text-center">{{ $task->progress }} %</td> <td class="text-center">{{ $task->progress }} %</td>
<td> <td>
{{ link_to_route('features.show', trans('task.edit'), [ {{ link_to_route('features.show', trans('task.edit'), [

5
resources/views/features/show.blade.php

@ -1,6 +1,6 @@
@extends('layouts.app') @extends('layouts.app')
@section('title', trans('feature.show'))
@section('title', trans('feature.show') . ' | ' . $feature->name . ' | ' . $feature->project->name)
@section('content') @section('content')
@include('features.partials.breadcrumb') @include('features.partials.breadcrumb')
@ -17,7 +17,8 @@
@include('features.partials.feature-show') @include('features.partials.feature-show')
</div> </div>
<div class="col-sm-8"> <div class="col-sm-8">
@include('features.partials.feature-tasks')
@include('features.partials.feature-tasks-operation')
</div> </div>
</div> </div>
@include('features.partials.feature-tasks')
@endsection @endsection

63
resources/views/features/unfinished.blade.php

@ -0,0 +1,63 @@
@extends('layouts.app')
@section('title', trans('project.features'))
@section('content')
<h1 class="page-header">
Daftar Fitur on Progress
</h1>
<div class="panel panel-default">
<table class="table table-condensed">
<thead>
<th>{{ trans('app.table_no') }}</th>
<th>{{ trans('project.name') }}</th>
<th>{{ trans('feature.name') }}</th>
<th class="text-center">{{ trans('feature.tasks_count') }}</th>
<th class="text-center">{{ trans('feature.progress') }}</th>
<th class="text-right">{{ trans('feature.price') }}</th>
<th>{{ trans('feature.worker') }}</th>
<th>{{ trans('app.action') }}</th>
</thead>
<tbody>
@forelse($features as $key => $feature)
<tr>
<td>{{ 1 + $key }}</td>
<td>{{ $feature->project->name }}</td>
<td>
{{ $feature->name }}
@if ($feature->tasks->isEmpty() == false)
<ul>
@foreach($feature->tasks as $task)
<li style="cursor:pointer" title="{{ $task->progress }} %">
<i class="fa fa-battery-{{ ceil(4 * $task->progress/100) }}"></i>
{{ $task->name }}
</li>
@endforeach
</ul>
@endif
</td>
<td class="text-center">{{ $feature->tasks_count = $feature->tasks->count() }}</td>
<td class="text-center">{{ formatDecimal($feature->progress = $feature->tasks->avg('progress')) }} %</td>
<td class="text-right">{{ formatRp($feature->price) }}</td>
<td>{{ $feature->worker->name }}</td>
<td>
{!! link_to_route('features.show', trans('app.show'),[$feature->id],['class' => 'btn btn-info btn-xs']) !!}
</td>
</tr>
@empty
<tr><td colspan="7">{{ trans('feature.empty') }}</td></tr>
@endforelse
</tbody>
<tfoot>
<tr>
<th class="text-right" colspan="3">Total</th>
<th class="text-center">{{ $features->sum('tasks_count') }}</th>
<th class="text-center">{{ formatDecimal($features->avg('progress')) }} %</th>
<th class="text-right">{{ formatRp($features->sum('price')) }}</th>
<th colspan="2"></th>
</tr>
</tfoot>
</table>
</div>
@endsection

5
resources/views/layouts/partials/sidebar.blade.php

@ -6,6 +6,7 @@
<ul class="nav" id="side-menu"> <ul class="nav" id="side-menu">
<li>{!! html_link_to_route('home', 'Dashboard', [], ['icon' => 'dashboard']) !!}</li> <li>{!! html_link_to_route('home', 'Dashboard', [], ['icon' => 'dashboard']) !!}</li>
@can('add_project') @can('add_project')
<li>{!! html_link_to_route('features.index', 'On Progress Features', [], ['icon' => 'tasks']) !!}</li>
<li> <li>
<?php $projectsCount = App\Entities\Projects\Project::select(DB::raw('status_id, count(id) as count')) <?php $projectsCount = App\Entities\Projects\Project::select(DB::raw('status_id, count(id) as count'))
->groupBy('status_id') ->groupBy('status_id')
@ -26,6 +27,9 @@
</li> </li>
@endcan @endcan
@can('see_reports') @can('see_reports')
<li>{!! html_link_to_route('reports.payments.yearly', 'Penghasilan', [], ['icon' => 'line-chart']) !!}</li>
<li>{!! html_link_to_route('reports.current-credits', 'Piutang', [], ['icon' => 'money']) !!}</li>
{{--
<li> <li>
{!! html_link_to_route('reports.payments.index', 'Laporan <span class="fa arrow"></span>', [], ['icon' => 'line-chart']) !!} {!! html_link_to_route('reports.payments.index', 'Laporan <span class="fa arrow"></span>', [], ['icon' => 'line-chart']) !!}
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
@ -40,6 +44,7 @@
<li>{!! html_link_to_route('reports.current-credits', 'Piutang') !!}</li> <li>{!! html_link_to_route('reports.current-credits', 'Piutang') !!}</li>
</ul> </ul>
</li> </li>
--}}
@endcan @endcan
@can('manage_subscriptions') @can('manage_subscriptions')
<li>{!! html_link_to_route('subscriptions.index', trans('subscription.subscription'), [], ['icon' => 'retweet']) !!}</li> <li>{!! html_link_to_route('subscriptions.index', trans('subscription.subscription'), [], ['icon' => 'retweet']) !!}</li>

7
resources/views/pages/home.blade.php

@ -3,6 +3,13 @@
@section('content') @section('content')
<h1 class="page-header">Dashboard</h1> <h1 class="page-header">Dashboard</h1>
<div class="well well-sm">
{!! Form::open(['route' => 'projects.index','method'=>'get','class'=>'form-inline']) !!}
{!! Form::text('q', Request::get('q'), ['class'=>'form-control index-search-field','placeholder'=>trans('project.search'),'style' => 'width:350px']) !!}
{!! Form::submit(trans('project.search'), ['class' => 'btn btn-info btn-sm']) !!}
{!! Form::close() !!}
</div>
<div class="row"> <div class="row">
<div class="col-lg-3 col-md-6"> <div class="col-lg-3 col-md-6">
<a href="{{ route('projects.index',['status' => 1]) }}"> <a href="{{ route('projects.index',['status' => 1]) }}">

3
resources/views/payments/index.blade.php

@ -7,7 +7,8 @@
{!! link_to_route('payments.create', trans('payment.create'), [], ['class'=>'btn btn-success pull-right']) !!} {!! link_to_route('payments.create', trans('payment.create'), [], ['class'=>'btn btn-success pull-right']) !!}
{{ trans('payment.payments') }} <small>{{ $payments->total() }} {{ trans('payment.found') }}</small> {{ trans('payment.payments') }} <small>{{ $payments->total() }} {{ trans('payment.found') }}</small>
</h1> </h1>
<div class="well well-sm">
<div class="well well-sm text-right">
<div class="pull-left hidden-xs">{!! str_replace('/?', '?', $payments->appends(Request::except('page'))->render()) !!}</div>
{!! Form::open(['method'=>'get','class'=>'form-inline']) !!} {!! Form::open(['method'=>'get','class'=>'form-inline']) !!}
{!! Form::text('q', Request::get('q'), ['class'=>'form-control index-search-field','placeholder'=>trans('payment.search'),'style' => 'width:350px']) !!} {!! Form::text('q', Request::get('q'), ['class'=>'form-control index-search-field','placeholder'=>trans('payment.search'),'style' => 'width:350px']) !!}
{!! Form::submit(trans('payment.search'), ['class' => 'btn btn-info btn-sm']) !!} {!! Form::submit(trans('payment.search'), ['class' => 'btn btn-info btn-sm']) !!}

1
resources/views/projects/create.blade.php

@ -44,5 +44,4 @@
</div> </div>
{!! Form::close() !!} {!! Form::close() !!}
<?php // echo '<pre>$errors->toArray() : ', print_r($errors->toArray(), true), '</pre>' ?>
@endsection @endsection

8
resources/views/projects/features.blade.php

@ -1,6 +1,6 @@
@extends('layouts.app') @extends('layouts.app')
@section('title', trans('project.features'))
@section('title', trans('project.features') . ' | ' . $project->name)
@section('content') @section('content')
@include('projects.partials.breadcrumb',['title' => trans('project.features')]) @include('projects.partials.breadcrumb',['title' => trans('project.features')])
@ -35,7 +35,10 @@
@if ($feature->tasks->isEmpty() == false) @if ($feature->tasks->isEmpty() == false)
<ul> <ul>
@foreach($feature->tasks as $task) @foreach($feature->tasks as $task)
<li style="cursor:pointer" title="{{ $task->description }}">{{ $task->name }}</li>
<li style="cursor:pointer" title="{{ $task->progress }} %">
<i class="fa fa-battery-{{ ceil(4 * $task->progress/100) }}"></i>
{{ $task->name }}
</li>
@endforeach @endforeach
</ul> </ul>
@endif @endif
@ -45,6 +48,7 @@
<td class="text-right">{{ formatRp($feature->price) }}</td> <td class="text-right">{{ formatRp($feature->price) }}</td>
<td>{{ $feature->worker->name }}</td> <td>{{ $feature->worker->name }}</td>
<td> <td>
{!! link_to_route('features.show', trans('task.create'),[$feature->id],['class' => 'btn btn-default btn-xs']) !!}
{!! link_to_route('features.show', trans('app.show'),[$feature->id],['class' => 'btn btn-info btn-xs']) !!} {!! link_to_route('features.show', trans('app.show'),[$feature->id],['class' => 'btn btn-info btn-xs']) !!}
{!! link_to_route('features.edit', trans('app.edit'),[$feature->id],['class' => 'btn btn-warning btn-xs']) !!} {!! link_to_route('features.edit', trans('app.edit'),[$feature->id],['class' => 'btn btn-warning btn-xs']) !!}
</td> </td>

19
resources/views/projects/index.blade.php

@ -1,13 +1,14 @@
@extends('layouts.app') @extends('layouts.app')
@section('title', trans('project.projects'))
@section('title', 'Daftar ' . $status . ' Project')
@section('content') @section('content')
<h1 class="page-header"> <h1 class="page-header">
{!! link_to_route('projects.create', trans('project.create'), [], ['class'=>'btn btn-success pull-right']) !!} {!! link_to_route('projects.create', trans('project.create'), [], ['class'=>'btn btn-success pull-right']) !!}
Daftar {{ $status }} Project <small>{{ $projects->total() }} {{ trans('project.found') }}</small> Daftar {{ $status }} Project <small>{{ $projects->total() }} {{ trans('project.found') }}</small>
</h1> </h1>
<div class="well well-sm">
<div class="well well-sm text-right">
<div class="pull-left hidden-xs">{!! str_replace('/?', '?', $projects->appends(Request::except('page'))->render()) !!}</div>
{!! Form::open(['method'=>'get','class'=>'form-inline']) !!} {!! Form::open(['method'=>'get','class'=>'form-inline']) !!}
{!! Form::text('q', Request::get('q'), ['class'=>'form-control index-search-field','placeholder'=>trans('project.search'),'style' => 'width:350px']) !!} {!! Form::text('q', Request::get('q'), ['class'=>'form-control index-search-field','placeholder'=>trans('project.search'),'style' => 'width:350px']) !!}
{!! Form::submit(trans('project.search'), ['class' => 'btn btn-info btn-sm']) !!} {!! Form::submit(trans('project.search'), ['class' => 'btn btn-info btn-sm']) !!}
@ -19,11 +20,11 @@
<th>{{ trans('app.table_no') }}</th> <th>{{ trans('app.table_no') }}</th>
<th>{{ trans('project.name') }}</th> <th>{{ trans('project.name') }}</th>
<th class="text-center">{{ trans('project.start_date') }}</th> <th class="text-center">{{ trans('project.start_date') }}</th>
<th class="text-center">{{ trans('project.end_date') }}</th>
<th class="text-center">{{ trans('project.work_duration') }}</th> <th class="text-center">{{ trans('project.work_duration') }}</th>
<th class="text-center">{{ trans('project.payments') }}</th>
<th class="text-right">{{ trans('project.project_value') }}</th>
{{-- <th class="text-center">{{ trans('project.payments') }}</th> --}}
{{-- <th class="text-right">{{ trans('project.project_value') }}</th> --}}
<th class="text-center">{{ trans('app.status') }}</th> <th class="text-center">{{ trans('app.status') }}</th>
<th>{{ trans('project.customer') }}</th>
<th>{{ trans('app.action') }}</th> <th>{{ trans('app.action') }}</th>
</thead> </thead>
<tbody> <tbody>
@ -32,11 +33,11 @@
<td>{{ $projects->firstItem() + $key }}</td> <td>{{ $projects->firstItem() + $key }}</td>
<td>{{ $project->name }}</td> <td>{{ $project->name }}</td>
<td class="text-center">{{ $project->start_date }}</td> <td class="text-center">{{ $project->start_date }}</td>
<td class="text-center">{{ $project->end_date }}</td>
<td class="text-right">{{ dateDifference($project->start_date,$project->end_date) }}</td>
<td class="text-center">{{ $project->payments_count }}</td>
<td class="text-right">{{ formatRp($project->project_value) }}</td>
<td class="text-right">{{ $project->present()->workDuration }}</td>
{{-- <td class="text-center">{{ $project->payments_count }}</td> --}}
{{-- <td class="text-right">{{ formatRp($project->project_value) }}</td> --}}
<td class="text-center">{{ $project->present()->status }}</td> <td class="text-center">{{ $project->present()->status }}</td>
<td>{{ $project->customer->name }}</td>
<td> <td>
{!! link_to_route('projects.show',trans('app.show'),[$project->id],['class'=>'btn btn-info btn-xs']) !!} {!! link_to_route('projects.show',trans('app.show'),[$project->id],['class'=>'btn btn-info btn-xs']) !!}
{!! link_to_route('projects.edit',trans('app.edit'),[$project->id],['class'=>'btn btn-warning btn-xs']) !!} {!! link_to_route('projects.edit',trans('app.edit'),[$project->id],['class'=>'btn btn-warning btn-xs']) !!}

6
resources/views/projects/partials/project-show.blade.php

@ -4,7 +4,7 @@
<table class="table table-condensed"> <table class="table table-condensed">
<tbody> <tbody>
<tr><td>{{ trans('project.name') }}</td><td>{{ $project->name }}</td></tr> <tr><td>{{ trans('project.name') }}</td><td>{{ $project->name }}</td></tr>
<tr><td>{{ trans('project.description') }}</td><td>{{ $project->description }}</td></tr>
<tr><td>{{ trans('project.description') }}</td><td>{!! nl2br($project->description) !!}</td></tr>
<tr><td>{{ trans('project.proposal_date') }}</td><td>{{ dateId($project->proposal_date) }}</td></tr> <tr><td>{{ trans('project.proposal_date') }}</td><td>{{ dateId($project->proposal_date) }}</td></tr>
<tr><td>{{ trans('project.proposal_value') }}</td><td class="text-right">{{ formatRp($project->proposal_value) }}</td></tr> <tr><td>{{ trans('project.proposal_value') }}</td><td class="text-right">{{ formatRp($project->proposal_value) }}</td></tr>
<tr><td>{{ trans('project.project_value') }}</td><td class="text-right">{{ formatRp($project->project_value) }}</td></tr> <tr><td>{{ trans('project.project_value') }}</td><td class="text-right">{{ formatRp($project->project_value) }}</td></tr>
@ -23,8 +23,4 @@
</tbody> </tbody>
</table> </table>
</div> </div>
<div class="panel-footer">
{!! link_to_route('projects.edit', trans('project.edit'), [$project->id], ['class' => 'btn btn-warning']) !!}
{!! link_to_route('projects.index', trans('project.back_to_index'), ['status' => $project->status_id], ['class' => 'btn btn-default']) !!}
</div>
</div> </div>

2
resources/views/projects/payments.blade.php

@ -1,6 +1,6 @@
@extends('layouts.app') @extends('layouts.app')
@section('title', trans('project.payments'))
@section('title', trans('project.payments') . ' | ' . $project->name)
@section('content') @section('content')
@include('projects.partials.breadcrumb',['title' => trans('project.payments')]) @include('projects.partials.breadcrumb',['title' => trans('project.payments')])

16
resources/views/projects/show.blade.php

@ -1,11 +1,17 @@
@extends('layouts.app') @extends('layouts.app')
@section('title', trans('project.show'))
@section('title', trans('project.show') . ' | ' . $project->name)
@section('content') @section('content')
@include('projects.partials.breadcrumb') @include('projects.partials.breadcrumb')
<h1 class="page-header">{{ $project->name }} <small>{{ trans('project.show') }}</small></h1>
<h1 class="page-header">
<div class="pull-right">
{!! link_to_route('projects.edit', trans('project.edit'), [$project->id], ['class' => 'btn btn-warning']) !!}
{!! link_to_route('projects.index', trans('project.back_to_index'), ['status' => $project->status_id], ['class' => 'btn btn-default']) !!}
</div>
{{ $project->name }} <small>{{ trans('project.show') }}</small>
</h1>
@include('projects.partials.nav-tabs') @include('projects.partials.nav-tabs')
@ -13,5 +19,11 @@
<div class="col-md-6"> <div class="col-md-6">
@include('projects.partials.project-show') @include('projects.partials.project-show')
</div> </div>
<div class="col-md-6">
{!! Form::model($project, ['route' => ['projects.status-update', $project->id], 'method' => 'patch','class' => 'well well-sm form-inline']) !!}
{!! FormField::select('status_id', getProjectStatusesList(), ['label' => trans('project.status')]) !!}
{!! Form::submit('Update Project Status', ['class' => 'btn btn-info']) !!}
{!! Form::close() !!}
</div>
</div> </div>
@endsection @endsection

2
resources/views/reports/current-credits.blade.php

@ -21,7 +21,7 @@
@forelse($projects as $key => $project) @forelse($projects as $key => $project)
<tr> <tr>
<td>{{ 1 + $key }}</td> <td>{{ 1 + $key }}</td>
<td>{!! link_to_route('projects.payments',$project->name,[$project->id],['title' => 'Lihat Detail Pembayaran','target' => '_blank']) !!}</td>
<td>{!! link_to_route('projects.payments',$project->name,[$project->id],['title' => 'Lihat Daftar Pembayaran','target' => '_blank']) !!}</td>
<td class="text-right">{{ formatRp($project->project_value) }}</td> <td class="text-right">{{ formatRp($project->project_value) }}</td>
<td class="text-right">{{ formatRp($project->cashInTotal()) }}</td> <td class="text-right">{{ formatRp($project->cashInTotal()) }}</td>
<td class="text-right">{{ formatRp($project->balance = $project->project_value - $project->cashInTotal()) }}</td> <td class="text-right">{{ formatRp($project->balance = $project->project_value - $project->cashInTotal()) }}</td>

6
resources/views/reports/payments/yearly.blade.php

@ -51,7 +51,7 @@
<td class="text-right">{{ formatRp($report->cashin) }}</td> <td class="text-right">{{ formatRp($report->cashin) }}</td>
<td class="text-right">{{ formatRp($report->cashout) }}</td> <td class="text-right">{{ formatRp($report->cashout) }}</td>
<td class="text-right">{{ formatRp(($report->cashin - $report->cashout)) }}</td> <td class="text-right">{{ formatRp(($report->cashin - $report->cashout)) }}</td>
<td class="text-center">{!! link_to_route('reports.payments.monthly','Lihat Bulanan',['month' => monthNumber($report->month), 'year' => $year] , ['class'=>'btn btn-info btn-xs','title'=>'Lihat laporan bulanan ' . monthId($report->month)]) !!}</td>
<td class="text-center">{!! link_to_route('reports.payments.monthly','Lihat Bulanan', ['month' => monthNumber($report->month), 'year' => $year], ['class'=>'btn btn-info btn-xs','title'=>'Lihat laporan bulanan ' . monthId($report->month)]) !!}</td>
</tr> </tr>
<?php <?php
$invoicesCount += $report->count; $invoicesCount += $report->count;
@ -97,7 +97,9 @@
xkey: 'month', xkey: 'month',
ykeys: ['value'], ykeys: ['value'],
labels: ['Profit'], labels: ['Profit'],
parseTime:false
parseTime:false,
goals: [0],
goalLineColors : ['red'],
}); });
})(); })();
</script> </script>

33
tests/ManageFeaturesTest.php

@ -92,6 +92,13 @@ class ManageFeaturesTest extends TestCase
$project = factory(Project::class)->create(['owner_id' => $user->id]); $project = factory(Project::class)->create(['owner_id' => $user->id]);
$feature = factory(Feature::class)->create(['project_id' => $project->id]); $feature = factory(Feature::class)->create(['project_id' => $project->id]);
$tasks = factory(Task::class, 2)->create(['feature_id' => $feature->id]);
$this->seeInDatabase('features', [
'name' => $feature->name,
'price' => $feature->price,
'project_id' => $project->id,
]);
$this->visit('projects/' . $feature->project_id . '/features'); $this->visit('projects/' . $feature->project_id . '/features');
$this->click(trans('app.show')); $this->click(trans('app.show'));
@ -100,6 +107,16 @@ class ManageFeaturesTest extends TestCase
$this->press(trans('app.delete_confirm_button')); $this->press(trans('app.delete_confirm_button'));
$this->seePageIs('projects/' . $project->id . '/features'); $this->seePageIs('projects/' . $project->id . '/features');
$this->see(trans('feature.deleted')); $this->see(trans('feature.deleted'));
$this->notSeeInDatabase('features', [
'name' => $feature->name,
'price' => $feature->price,
'project_id' => $project->id,
]);
$this->notSeeInDatabase('tasks', [
'feature_id' => $feature->id,
]);
} }
/** @test */ /** @test */
@ -206,4 +223,20 @@ class ManageFeaturesTest extends TestCase
// 'worker_id' => $features[1]->worker_id, // 'worker_id' => $features[1]->worker_id,
// ]); // ]);
} }
/** @test */
public function admin_can_see_unfinished_features_list()
{
$user = factory(User::class)->create();
$user->assignRole('admin');
$this->actingAs($user);
// $projects = factory(Project::class, 2)->create(['owner_id' => $user->id]);
// $features = factory(Feature::class, 3)->create(['project_id'=> array_rand($projects->lists('id','id')->all())]);
// $tasks = factory(Task::class, 10)->create(['feature_id'=> array_rand($features->lists('id','id')->all())]);
$this->visit('features');
$this->seePageIs('features');
}
} }

23
tests/ManagePaymentsTest.php

@ -151,11 +151,32 @@ class ManagePaymentsTest extends TestCase
$payments = factory(Payment::class, 5)->create(['owner_id' => $user->id]); $payments = factory(Payment::class, 5)->create(['owner_id' => $user->id]);
$this->assertEquals(5, $payments->count()); $this->assertEquals(5, $payments->count());
$this->visit('/payments');
$this->visit(route('payments.index'));
$this->seePageIs(route('payments.index'));
$this->see($payments[4]->project->name); $this->see($payments[4]->project->name);
$this->see($payments[4]->date); $this->see($payments[4]->date);
$this->see(formatRp($payments[4]->amount)); $this->see(formatRp($payments[4]->amount));
$this->see($payments[4]->description); $this->see($payments[4]->description);
$this->see($payments[4]->customer->name); $this->see($payments[4]->customer->name);
} }
/** @test */
public function admin_can_search_payment_by_customer_name()
{
$user = factory(User::class)->create();
$user->assignRole('admin');
$this->actingAs($user);
$payments = factory(Payment::class, 5)->create(['owner_id' => $user->id]);
$this->assertEquals(5, $payments->count());
$this->visit(route('payments.index'));
$firstName = explode(' ', $payments[0]->project->name)[0];
$this->type($firstName, 'q');
$this->press(trans('payment.search'));
$this->seePageIs(route('payments.index', ['q' => $firstName]));
$this->see($payments[0]->project->name);
}
} }

71
tests/ManageProjectsTest.php

@ -1,6 +1,9 @@
<?php <?php
use App\Entities\Payments\Payment;
use App\Entities\Projects\Feature;
use App\Entities\Projects\Project; use App\Entities\Projects\Project;
use App\Entities\Projects\Task;
use App\Entities\Users\User; use App\Entities\Users\User;
use Illuminate\Foundation\Testing\DatabaseMigrations; use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
@ -19,17 +22,17 @@ class ManageProjectsTest extends TestCase
$users[1]->assignRole('customer'); $users[1]->assignRole('customer');
$this->visit('/projects');
$this->seePageIs('/projects');
$this->visit(route('projects.index'));
$this->seePageIs(route('projects.index'));
$this->click(trans('project.create')); $this->click(trans('project.create'));
$this->seePageIs('/projects/create');
$this->seePageIs(route('projects.create'));
$this->type('Project Baru','name'); $this->type('Project Baru','name');
$this->select($users[1]->id,'customer_id'); $this->select($users[1]->id,'customer_id');
$this->type('2016-04-15','proposal_date'); $this->type('2016-04-15','proposal_date');
$this->type('2000000','proposal_value'); $this->type('2000000','proposal_value');
$this->type('Deskripsi project baru','description'); $this->type('Deskripsi project baru','description');
$this->press(trans('project.create')); $this->press(trans('project.create'));
$this->seePageIs('/projects');
$this->see(trans('project.created')); $this->see(trans('project.created'));
$this->see('Project Baru'); $this->see('Project Baru');
$this->seeInDatabase('projects', ['name' => 'Project Baru', 'proposal_value' => '2000000']); $this->seeInDatabase('projects', ['name' => 'Project Baru', 'proposal_value' => '2000000']);
@ -42,10 +45,10 @@ class ManageProjectsTest extends TestCase
$user->assignRole('admin'); $user->assignRole('admin');
$this->actingAs($user); $this->actingAs($user);
$this->visit('/projects');
$this->seePageIs('/projects');
$this->visit(route('projects.index'));
$this->seePageIs(route('projects.index'));
$this->click(trans('project.create')); $this->click(trans('project.create'));
$this->seePageIs('/projects/create');
$this->seePageIs(route('projects.create'));
// Invalid entry // Invalid entry
$this->type('Project Baru','name'); $this->type('Project Baru','name');
@ -54,13 +57,12 @@ class ManageProjectsTest extends TestCase
$this->type('2000000','proposal_value'); $this->type('2000000','proposal_value');
$this->type('Deskripsi project baru','description'); $this->type('Deskripsi project baru','description');
$this->press(trans('project.create')); $this->press(trans('project.create'));
$this->seePageIs('/projects/create');
$this->seePageIs(route('projects.create'));
$this->notSeeInDatabase('projects', ['name' => 'Project Baru', 'proposal_value' => '2000000']); $this->notSeeInDatabase('projects', ['name' => 'Project Baru', 'proposal_value' => '2000000']);
$this->type('Customer Baru','customer_name'); $this->type('Customer Baru','customer_name');
$this->type('email@customer.baru','customer_email'); $this->type('email@customer.baru','customer_email');
$this->press(trans('project.create')); $this->press(trans('project.create'));
$this->seePageIs('/projects');
$this->see(trans('project.created')); $this->see(trans('project.created'));
$this->see('Project Baru'); $this->see('Project Baru');
$this->seeInDatabase('users', ['name' => 'Customer Baru', 'email' => 'email@customer.baru']); $this->seeInDatabase('users', ['name' => 'Customer Baru', 'email' => 'email@customer.baru']);
@ -76,12 +78,34 @@ class ManageProjectsTest extends TestCase
$this->actingAs($user); $this->actingAs($user);
$project = factory(Project::class)->create(['owner_id' => $user->id]); $project = factory(Project::class)->create(['owner_id' => $user->id]);
$feature = factory(Feature::class)->create(['project_id' => $project->id]);
$task = factory(Task::class)->create(['feature_id' => $feature->id]);
$payment = factory(Payment::class)->create(['project_id' => $project->id]);
$this->visit('/projects?status=' . $project->status_id); $this->visit('/projects?status=' . $project->status_id);
$this->click(trans('app.edit')); $this->click(trans('app.edit'));
$this->click(trans('app.delete')); $this->click(trans('app.delete'));
$this->press(trans('app.delete_confirm_button')); $this->press(trans('app.delete_confirm_button'));
$this->seePageIs('projects'); $this->seePageIs('projects');
$this->see(trans('project.deleted')); $this->see(trans('project.deleted'));
$this->notSeeInDatabase('projects', [
'name' => $project->name,
'proposal_value' => $project->proposal_value,
'owner_id' => $user->id,
]);
$this->notSeeInDatabase('payments', [
'project_id' => $project->id,
]);
$this->notSeeInDatabase('features', [
'project_id' => $project->id,
]);
$this->notSeeInDatabase('tasks', [
'feature_id' => $feature->id,
]);
} }
/** @test */ /** @test */
@ -128,18 +152,39 @@ class ManageProjectsTest extends TestCase
$users[1]->assignRole('customer'); $users[1]->assignRole('customer');
$this->visit('/projects');
$this->seePageIs('/projects');
$this->visit(route('projects.index'));
$this->seePageIs(route('projects.index'));
$this->click(trans('project.create')); $this->click(trans('project.create'));
$this->seePageIs('/projects/create');
$this->seePageIs(route('projects.create'));
$this->type('','name'); $this->type('','name');
$this->select($users[1]->id,'customer_id'); $this->select($users[1]->id,'customer_id');
$this->type('2016-04-15aa','proposal_date'); $this->type('2016-04-15aa','proposal_date');
$this->type('','proposal_value'); $this->type('','proposal_value');
$this->type('Deskripsi project baru','description'); $this->type('Deskripsi project baru','description');
$this->press(trans('project.create')); $this->press(trans('project.create'));
$this->seePageIs('/projects/create');
$this->seePageIs(route('projects.create'));
$this->see('Mohon periksa kembali form isian Anda.'); $this->see('Mohon periksa kembali form isian Anda.');
} }
/** @test */
public function admin_can_update_project_status_on_project_detail_page()
{
$user = factory(User::class)->create();
$user->assignRole('admin');
$this->actingAs($user);
$project = factory(Project::class)->create(['owner_id' => $user->id, 'status_id' => 1]);
$this->visit(route('projects.show', $project->id));
$this->seePageIs(route('projects.show', $project->id));
$this->select(2, 'status_id');
$this->press('Update Project Status');
$this->see(trans('project.updated'));
$this->seePageIs(route('projects.show', $project->id));
$this->seeInDatabase('projects', [
'id' => $project->id,
'status_id' => 2,
]);
}
} }

10
tests/ManageTasksTest.php

@ -29,6 +29,7 @@ class ManageTasksTest extends TestCase
$this->type('Nama Task Baru','name'); $this->type('Nama Task Baru','name');
$this->type('Ipsam magnam laboriosam distinctio officia facere sapiente eius corporis','description'); $this->type('Ipsam magnam laboriosam distinctio officia facere sapiente eius corporis','description');
$this->type(70,'progress'); $this->type(70,'progress');
$this->type('tasks/create','route_name');
$this->press(trans('task.create')); $this->press(trans('task.create'));
$this->seePageIs('features/' . $feature->id); $this->seePageIs('features/' . $feature->id);
@ -36,7 +37,8 @@ class ManageTasksTest extends TestCase
$this->seeInDatabase('tasks', [ $this->seeInDatabase('tasks', [
'name' => 'Nama Task Baru', 'name' => 'Nama Task Baru',
'progress' => 70, 'progress' => 70,
'feature_id' => $feature->id
'feature_id' => $feature->id,
'route_name' => 'tasks/create',
]); ]);
} }
@ -60,6 +62,7 @@ class ManageTasksTest extends TestCase
// Fill Form // Fill Form
$this->type('Nama Task Edit','name'); $this->type('Nama Task Edit','name');
$this->type('tasks/{id}/edit','route_name');
$this->type(77,'progress'); $this->type(77,'progress');
$this->press(trans('task.update')); $this->press(trans('task.update'));
@ -68,7 +71,8 @@ class ManageTasksTest extends TestCase
$this->seeInDatabase('tasks', [ $this->seeInDatabase('tasks', [
'name' => 'Nama Task Edit', 'name' => 'Nama Task Edit',
'progress' => 77, 'progress' => 77,
'feature_id' => $feature->id
'feature_id' => $feature->id,
'route_name' => 'tasks/{id}/edit',
]); ]);
} }
@ -109,8 +113,10 @@ class ManageTasksTest extends TestCase
$this->see($tasks[1]->name); $this->see($tasks[1]->name);
$this->see($tasks[1]->progress); $this->see($tasks[1]->progress);
$this->see($tasks[1]->description); $this->see($tasks[1]->description);
$this->see($tasks[1]->route_name);
$this->see($tasks[4]->name); $this->see($tasks[4]->name);
$this->see($tasks[4]->progress); $this->see($tasks[4]->progress);
$this->see($tasks[4]->description); $this->see($tasks[4]->description);
$this->see($tasks[4]->route_name);
} }
} }
Loading…
Cancel
Save