mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Add default rate / amount for time tracking / tasks #1575
This commit is contained in:
parent
7ef9bc9cd6
commit
697de9b3b2
@ -262,7 +262,7 @@ class TaskController extends BaseController
|
||||
$this->taskRepo->save($ids, ['action' => $action]);
|
||||
return Redirect::to('tasks')->withMessage(trans($action == 'stop' ? 'texts.stopped_task' : 'texts.resumed_task'));
|
||||
} elseif ($action == 'invoice' || $action == 'add_to_invoice') {
|
||||
$tasks = Task::scope($ids)->with('client')->orderBy('project_id', 'id')->get();
|
||||
$tasks = Task::scope($ids)->with('account', 'client', 'project')->orderBy('project_id', 'id')->get();
|
||||
$clientPublicId = false;
|
||||
$data = [];
|
||||
|
||||
@ -294,6 +294,7 @@ class TaskController extends BaseController
|
||||
'publicId' => $task->public_id,
|
||||
'description' => $task->present()->invoiceDescription($account, $showProject),
|
||||
'duration' => $task->getHours(),
|
||||
'cost' => $task->getRate(),
|
||||
];
|
||||
$lastProjectId = $task->project_id;
|
||||
}
|
||||
|
@ -176,6 +176,7 @@ class Account extends Eloquent
|
||||
'credit_number_counter',
|
||||
'credit_number_prefix',
|
||||
'credit_number_pattern',
|
||||
'task_rate',
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -52,6 +52,7 @@ class Client extends EntityModel
|
||||
'invoice_number_counter',
|
||||
'quote_number_counter',
|
||||
'public_notes',
|
||||
'task_rate',
|
||||
];
|
||||
|
||||
|
||||
|
@ -24,6 +24,7 @@ class Project extends EntityModel
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'task_rate',
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -145,6 +145,24 @@ class Task extends EntityModel
|
||||
return self::calcDuration($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getRate()
|
||||
{
|
||||
$value = 0;
|
||||
|
||||
if ($this->project && floatval($this->project->task_rate)) {
|
||||
$value = $this->project->task_rate;
|
||||
} elseif ($this->client && floatval($this->client->task_rate)) {
|
||||
$value = $this->client->task_rate;
|
||||
} else {
|
||||
$value = $this->account->task_rate;
|
||||
}
|
||||
|
||||
return Utils::roundSignificant($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
|
@ -38,6 +38,12 @@ class ProjectDatatable extends EntityDatatable
|
||||
}
|
||||
},
|
||||
],
|
||||
[
|
||||
'task_rate',
|
||||
function ($model) {
|
||||
return floatval($model->task_rate) ? Utils::roundSignificant($model->task_rate) : '';
|
||||
}
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ class ProjectRepository extends BaseRepository
|
||||
'projects.public_id',
|
||||
'projects.user_id',
|
||||
'projects.deleted_at',
|
||||
'projects.task_rate',
|
||||
'projects.is_deleted',
|
||||
DB::raw("COALESCE(NULLIF(clients.name,''), NULLIF(CONCAT(contacts.first_name, ' ', contacts.last_name),''), NULLIF(contacts.email,'')) client_name"),
|
||||
'clients.user_id as client_user_id',
|
||||
|
@ -274,6 +274,7 @@ class AccountTransformer extends EntityTransformer
|
||||
'reset_counter_date' => $account->reset_counter_date,
|
||||
'custom_contact_label1' => $account->custom_contact_label1,
|
||||
'custom_contact_label2' => $account->custom_contact_label2,
|
||||
'task_rate' => (float) $account->task_rate,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ class ClientTransformer extends EntityTransformer
|
||||
* @SWG\Property(property="vat_number", type="string", example="123456")
|
||||
* @SWG\Property(property="id_number", type="string", example="123456")
|
||||
* @SWG\Property(property="language_id", type="integer", example=1)
|
||||
* @SWG\Property(property="task_rate", type="number", format="float", example=10)
|
||||
*/
|
||||
protected $defaultIncludes = [
|
||||
'contacts',
|
||||
@ -135,6 +136,7 @@ class ClientTransformer extends EntityTransformer
|
||||
'custom_value2' => $client->custom_value2,
|
||||
'invoice_number_counter' => (int) $client->invoice_number_counter,
|
||||
'quote_number_counter' => (int) $client->quote_number_counter,
|
||||
'task_rate' => (float) $client->task_rate,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ class ProjectTransformer extends EntityTransformer
|
||||
* @SWG\Property(property="updated_at", type="integer", example=1451160233, readOnly=true)
|
||||
* @SWG\Property(property="archived_at", type="integer", example=1451160233, readOnly=true)
|
||||
* @SWG\Property(property="is_deleted", type="boolean", example=false, readOnly=true)
|
||||
* @SWG\Property(property="task_rate", type="number", format="float", example=10)
|
||||
*/
|
||||
public function transform(Project $project)
|
||||
{
|
||||
@ -26,6 +27,7 @@ class ProjectTransformer extends EntityTransformer
|
||||
'updated_at' => $this->getTimestamp($project->updated_at),
|
||||
'archived_at' => $this->getTimestamp($project->deleted_at),
|
||||
'is_deleted' => (bool) $project->is_deleted,
|
||||
'task_rate' => (float) $project->task_rate,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
47
database/migrations/2017_10_17_083846_add_default_rates.php
Normal file
47
database/migrations/2017_10_17_083846_add_default_rates.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddDefaultRates extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('accounts', function ($table) {
|
||||
$table->decimal('task_rate', 12, 4);
|
||||
});
|
||||
|
||||
Schema::table('clients', function ($table) {
|
||||
$table->decimal('task_rate', 12, 4);
|
||||
});
|
||||
|
||||
Schema::table('projects', function ($table) {
|
||||
$table->decimal('task_rate', 12, 4);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('accounts', function ($table) {
|
||||
$table->dropColumn('task_rate');
|
||||
});
|
||||
|
||||
Schema::table('clients', function ($table) {
|
||||
$table->dropColumn('task_rate');
|
||||
});
|
||||
|
||||
Schema::table('projects', function ($table) {
|
||||
$table->dropColumn('task_rate');
|
||||
});
|
||||
}
|
||||
}
|
@ -2483,6 +2483,9 @@ $LANG = array(
|
||||
'clear' => 'Clear',
|
||||
'warn_payment_gateway' => 'Note: to accept online payments :link to add a payment gateway.',
|
||||
'setup_desktop_app' => 'Setup the desktop app',
|
||||
'task_rate' => 'Task Rate',
|
||||
'task_rate_help' => 'Set the default <b>rate for invoiced tasks</b>.',
|
||||
|
||||
);
|
||||
|
||||
return $LANG;
|
||||
|
@ -19,6 +19,7 @@
|
||||
]) !!}
|
||||
|
||||
{{ Former::populate($account) }}
|
||||
{{ Former::populateField('task_rate', floatval($account->task_rate) ? Utils::roundSignificant($account->task_rate) : '') }}
|
||||
|
||||
@include('accounts.nav', ['selected' => ACCOUNT_COMPANY_DETAILS])
|
||||
|
||||
@ -99,6 +100,11 @@
|
||||
->fromQuery(\App\Models\PaymentTerm::getSelectOptions(), 'name', 'num_days')
|
||||
->help(trans('texts.payment_terms_help') . ' | ' . link_to('/settings/payment_terms', trans('texts.customize_options'))) !!}
|
||||
|
||||
@if ($account->isModuleEnabled(ENTITY_TASK))
|
||||
{!! Former::text('task_rate')
|
||||
->help('task_rate_help')!!}
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
@if ($client)
|
||||
{!! Former::populate($client) !!}
|
||||
{!! Former::populateField('task_rate', floatval($client->task_rate) ? Utils::roundSignificant($client->task_rate) : '') !!}
|
||||
{!! Former::hidden('public_id') !!}
|
||||
@else
|
||||
{!! Former::populateField('invoice_number_counter', 1) !!}
|
||||
@ -155,6 +156,10 @@
|
||||
->fromQuery(\App\Models\PaymentTerm::getSelectOptions(), 'name', 'num_days')
|
||||
->placeholder($account->present()->paymentTerms)
|
||||
->help(trans('texts.payment_terms_help')) !!}
|
||||
@if ($account->isModuleEnabled(ENTITY_TASK))
|
||||
{!! Former::text('task_rate')
|
||||
->help('task_rate_help') !!}
|
||||
@endif
|
||||
{!! Former::select('size_id')->addOption('','')
|
||||
->fromQuery($sizes, 'name', 'id') !!}
|
||||
{!! Former::select('industry_id')->addOption('','')
|
||||
|
@ -111,6 +111,8 @@
|
||||
{{ $client->country->name }}<br/>
|
||||
@endif
|
||||
|
||||
<br/>
|
||||
|
||||
@if ($client->account->custom_client_label1 && $client->custom_value1)
|
||||
{{ $client->account->custom_client_label1 . ': ' . $client->custom_value1 }}<br/>
|
||||
@endif
|
||||
@ -122,6 +124,10 @@
|
||||
<i class="fa fa-phone" style="width: 20px"></i>{{ $client->work_phone }}
|
||||
@endif
|
||||
|
||||
@if (floatval($client->task_rate))
|
||||
<p>{{ trans('texts.task_rate') }}: {{ Utils::roundSignificant($client->task_rate) }}</p>
|
||||
@endif
|
||||
|
||||
@if ($client->public_notes)
|
||||
<p><i>{{ $client->public_notes }}</i></p>
|
||||
@endif
|
||||
|
@ -893,6 +893,7 @@
|
||||
var item = model.invoice().addItem(true);
|
||||
item.notes(task.description);
|
||||
item.qty(task.duration);
|
||||
item.cost(task.cost);
|
||||
item.task_public_id(task.publicId);
|
||||
}
|
||||
model.invoice().has_tasks(true);
|
||||
|
@ -1013,8 +1013,10 @@ ko.bindingHandlers.productTypeahead = {
|
||||
model.notes(datum.notes);
|
||||
}
|
||||
if (datum.cost) {
|
||||
if (! model.cost() || ! model.task_public_id()) {
|
||||
model.cost(roundSignificant(datum.cost, 2));
|
||||
}
|
||||
}
|
||||
if (!model.qty()) {
|
||||
model.qty(1);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
@if ($project)
|
||||
{!! Former::populate($project) !!}
|
||||
{!! Former::populateField('task_rate', floatval($project->task_rate) ? Utils::roundSignificant($project->task_rate) : '') !!}
|
||||
@endif
|
||||
|
||||
<span style="display:none">
|
||||
@ -39,6 +40,8 @@
|
||||
|
||||
{!! Former::text('name') !!}
|
||||
|
||||
{!! Former::text('task_rate')
|
||||
->help('task_rate_help') !!}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user