Initial commit
This commit is contained in:
commit
dbeaf3973d
|
@ -0,0 +1,6 @@
|
||||||
|
= Jobs
|
||||||
|
|
||||||
|
_Jobs_ is a Redmine plugin allowing the management of jobs—chunks of time sold to clients for budget management.
|
||||||
|
|
||||||
|
- Add jobs with time budgets
|
||||||
|
- Associated time log entries with a given job
|
|
@ -0,0 +1,64 @@
|
||||||
|
class JobsController < ApplicationController
|
||||||
|
before_action :set_project, only: [:index, :new, :show, :edit]
|
||||||
|
before_action :set_job, only: [:show, :edit, :update, :destroy]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@jobs = Job.all
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@job = Job.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @job.update(job_params)
|
||||||
|
redirect_to @job
|
||||||
|
else
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
if @job = Job.create(job_params)
|
||||||
|
redirect_to @job
|
||||||
|
else
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
if @job.destroy
|
||||||
|
redirect_to jobs_path(project_id: @project.id)
|
||||||
|
else
|
||||||
|
render :show
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def job_params
|
||||||
|
params.require(:job).permit(
|
||||||
|
:starts_on,
|
||||||
|
:ends_on,
|
||||||
|
:project_id,
|
||||||
|
:budget,
|
||||||
|
:external_project_id,
|
||||||
|
:name,
|
||||||
|
:description
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_project
|
||||||
|
@project = Project.find(params[:project_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_job
|
||||||
|
@job = Job.find(params[:id])
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,2 @@
|
||||||
|
module JobsHelper
|
||||||
|
end
|
|
@ -0,0 +1,10 @@
|
||||||
|
class Job < ActiveRecord::Base
|
||||||
|
validates :starts_on,
|
||||||
|
:ends_on,
|
||||||
|
:name,
|
||||||
|
presence: true
|
||||||
|
|
||||||
|
def time_logged
|
||||||
|
42
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,40 @@
|
||||||
|
<div class="box tabular">
|
||||||
|
<%= form_with model: @job, id: "job_form" do |f| %>
|
||||||
|
<p>
|
||||||
|
<%= f.label :name %>
|
||||||
|
<%= f.text_field :name %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= f.label :description %>
|
||||||
|
<%= f.text_area :description %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= f.label :starts_on %>
|
||||||
|
<%= f.date_field :starts_on %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= f.label :ends_on %>
|
||||||
|
<%= f.date_field :ends_on %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= f.label :project_id %>
|
||||||
|
<%= f.number_field :project_id %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= f.label :external_project_id %>
|
||||||
|
<%= f.number_field :external_project_id %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= f.label :budget %>
|
||||||
|
<%= f.number_field :budget %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<%= f.submit %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<tr>
|
||||||
|
<td><%= link_to job.name, job_path(job, project_id: job.project_id) %></td>
|
||||||
|
<td><%= job.starts_on %></td>
|
||||||
|
<td><%= job.ends_on %></td>
|
||||||
|
<td><%= job.project_id %></td>
|
||||||
|
<td><%= job.external_project_id %></td>
|
||||||
|
<td><%= job.budget %></td>
|
||||||
|
</tr>
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<% html_title "Edit #{@job.name}" %>
|
||||||
|
<h2>Edit <%= @job.name %></h2>
|
||||||
|
|
||||||
|
<%= render "form" %>
|
||||||
|
|
||||||
|
<%= link_to "Delete job", job_path(@job), data: { confirm: "Are you sure?" }, method: :delete %>
|
|
@ -0,0 +1,26 @@
|
||||||
|
<% html_title "Jobs" %>
|
||||||
|
<div class="contextual">
|
||||||
|
<%= link_to 'Create new job', new_job_path(project_id: @project.id), class: "icon icon-add new-job" %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Jobs</h2>
|
||||||
|
|
||||||
|
<% if @jobs.empty? %>
|
||||||
|
<p>You haven’t created any jobs yet.</p>
|
||||||
|
<% else %>
|
||||||
|
<table class="list">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Starts on</th>
|
||||||
|
<th>Ends on</th>
|
||||||
|
<th>Project</th>
|
||||||
|
<th>External project</th>
|
||||||
|
<th>Budget</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<%= render @jobs %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<% end %>
|
|
@ -0,0 +1,3 @@
|
||||||
|
<h2><%= link_to "Jobs", jobs_path(project_id: @project.id) %> » New</h2>
|
||||||
|
|
||||||
|
<%= render "form" %>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<% html_title @job.name %>
|
||||||
|
<h3><%= link_to @job.name, @job %></h3>
|
||||||
|
<p><%= @job.description %></p>
|
||||||
|
<dl>
|
||||||
|
<dt>Starts on:</dt>
|
||||||
|
<dd><%= @job.starts_on %></dd>
|
||||||
|
<dt>Ends on:</dt>
|
||||||
|
<dd><%= @job.ends_on %></dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<%= link_to 'Edit job', edit_job_path(@job, project_id: @project.id) %>
|
|
@ -0,0 +1,3 @@
|
||||||
|
# English strings go here for Rails i18n
|
||||||
|
en:
|
||||||
|
# my_label: "My label"
|
|
@ -0,0 +1 @@
|
||||||
|
resources :jobs
|
|
@ -0,0 +1,14 @@
|
||||||
|
class CreateJobs < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
create_table :jobs do |t|
|
||||||
|
t.date :starts_on, null: false
|
||||||
|
t.date :ends_on, null: false
|
||||||
|
t.integer :external_project_id
|
||||||
|
t.string :name, null: false
|
||||||
|
t.references :project, foreign_key: true
|
||||||
|
t.string :description
|
||||||
|
t.integer :budget
|
||||||
|
end
|
||||||
|
add_index :jobs, :name, unique: true
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,11 @@
|
||||||
|
Redmine::Plugin.register :jobs do
|
||||||
|
name 'Redmine Jobs plugin'
|
||||||
|
author 'T S Vallender'
|
||||||
|
description 'Manage jobs in Redmine'
|
||||||
|
version '0.0.1'
|
||||||
|
url 'http://tsvallender.co.uk'
|
||||||
|
author_url 'http://tsvallender.co.uk'
|
||||||
|
|
||||||
|
permission :jobs, { jobs: [:index, :show, :new, :create, :edit, :update, :destroy] }, public: true
|
||||||
|
menu :project_menu, :jobs, { controller: 'jobs', action: 'index' }, caption: 'Jobs', after: :issues, param: :project_id
|
||||||
|
end
|
|
@ -0,0 +1,8 @@
|
||||||
|
require_relative '../test_helper'
|
||||||
|
|
||||||
|
class JobsControllerTest < ActionController::TestCase
|
||||||
|
# Replace this with your real tests.
|
||||||
|
def test_truth
|
||||||
|
assert true
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Load the Redmine helper
|
||||||
|
require_relative '../../../test/test_helper'
|
|
@ -0,0 +1,9 @@
|
||||||
|
require_relative '../test_helper'
|
||||||
|
|
||||||
|
class JobTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
|
# Replace this with your real tests.
|
||||||
|
def test_truth
|
||||||
|
assert true
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,33 @@
|
||||||
|
- Add a job model
|
||||||
|
- Start/end date
|
||||||
|
- External project ID (one-to-one relationship)
|
||||||
|
- Name
|
||||||
|
- Client (project ID)
|
||||||
|
- Description
|
||||||
|
- Job ID? (this is in Amigo)
|
||||||
|
- Status (pending acceptance etc.)
|
||||||
|
- Total time (budget per activity type?)
|
||||||
|
- List of associated trackers
|
||||||
|
- Add association between time log entries and jobs
|
||||||
|
- Add UI for jobs
|
||||||
|
- CRUD stuff
|
||||||
|
- Set up default associations
|
||||||
|
|
||||||
|
- Separate plugin:
|
||||||
|
- Whenever time log is updated, fire this at Everhour
|
||||||
|
- Back the other way?
|
||||||
|
|
||||||
|
- What about meetings etc?
|
||||||
|
|
||||||
|
- Examples:
|
||||||
|
- Developer logs time for ticket #123
|
||||||
|
- Doesn't explicitly choose a job
|
||||||
|
- Logged as development time
|
||||||
|
- If ticket is in retainer tracker the time is logged against the retainer job
|
||||||
|
- If ticket is in support tracker the time is logged against the support job
|
||||||
|
- If ticket is anywhere else, it is logged against the active project
|
||||||
|
|
||||||
|
- Product manager logs time for ticket #123
|
||||||
|
- Doesn't explicitly choose a job
|
||||||
|
- Logged as refinement time
|
||||||
|
-
|
Loading…
Reference in New Issue