artisan-ar-repository 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/artisan-ar-repository/base_repository.rb +35 -0
- data/lib/artisan-ar-repository/change_repository.rb +45 -0
- data/lib/artisan-ar-repository/future_user_repository.rb +34 -0
- data/lib/artisan-ar-repository/iteration_repository.rb +29 -0
- data/lib/artisan-ar-repository/member_repository.rb +12 -0
- data/lib/artisan-ar-repository/models/change.rb +5 -0
- data/lib/artisan-ar-repository/models/day.rb +4 -0
- data/lib/artisan-ar-repository/models/future_user.rb +4 -0
- data/lib/artisan-ar-repository/models/iteration.rb +20 -0
- data/lib/artisan-ar-repository/models/iteration_change.rb +2 -0
- data/lib/artisan-ar-repository/models/member.rb +4 -0
- data/lib/artisan-ar-repository/models/project.rb +20 -0
- data/lib/artisan-ar-repository/models/project_change.rb +2 -0
- data/lib/artisan-ar-repository/models/project_configuration.rb +13 -0
- data/lib/artisan-ar-repository/models/story.rb +61 -0
- data/lib/artisan-ar-repository/models/story_assigned_email.rb +4 -0
- data/lib/artisan-ar-repository/models/story_change.rb +2 -0
- data/lib/artisan-ar-repository/models/story_completed_email.rb +3 -0
- data/lib/artisan-ar-repository/models/user.rb +33 -0
- data/lib/artisan-ar-repository/project_configuration_repository.rb +9 -0
- data/lib/artisan-ar-repository/project_repository.rb +73 -0
- data/lib/artisan-ar-repository/story_repository.rb +66 -0
- data/lib/artisan-ar-repository/user_repository.rb +37 -0
- metadata +25 -2
@@ -0,0 +1,35 @@
|
|
1
|
+
module ArtisanArRepository
|
2
|
+
module BaseRepository
|
3
|
+
def new(attributes = {})
|
4
|
+
model_class.new(attributes)
|
5
|
+
end
|
6
|
+
|
7
|
+
def find(id)
|
8
|
+
model_class.find(id)
|
9
|
+
rescue ActiveRecord::RecordNotFound => e
|
10
|
+
raise Artisan::RecordNotFound.new(e)
|
11
|
+
end
|
12
|
+
|
13
|
+
def save(instance)
|
14
|
+
instance.save
|
15
|
+
end
|
16
|
+
|
17
|
+
def create(attributes = {})
|
18
|
+
model_class.create!(attributes)
|
19
|
+
end
|
20
|
+
|
21
|
+
def destroy_all(*args)
|
22
|
+
model_class.destroy_all(*args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def find_each(&block)
|
26
|
+
model_class.find_each(&block)
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
def model_class
|
32
|
+
raise "implement model_class method on your the repository #{self.class} to return the name of the Active Record Model"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'artisan-ar-repository/base_repository'
|
2
|
+
require 'artisan-ar-repository/models/change'
|
3
|
+
require 'artisan-ar-repository/models/story_change'
|
4
|
+
require 'artisan-ar-repository/models/iteration_change'
|
5
|
+
require 'artisan-ar-repository/models/project_change'
|
6
|
+
|
7
|
+
module ArtisanArRepository
|
8
|
+
class ChangeRepository
|
9
|
+
include BaseRepository
|
10
|
+
|
11
|
+
def model_class
|
12
|
+
::Change
|
13
|
+
end
|
14
|
+
|
15
|
+
def project_change_class
|
16
|
+
::ProjectChange
|
17
|
+
end
|
18
|
+
|
19
|
+
def iteration_change_class
|
20
|
+
::IterationChange
|
21
|
+
end
|
22
|
+
|
23
|
+
def story_change_class
|
24
|
+
::StoryChange
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_project_change(attributes = {})
|
28
|
+
project_change_class.create!(attributes)
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_iteration_change(attributes = {})
|
32
|
+
iteration_change_class.create!(attributes)
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_story_change(attributes = {})
|
36
|
+
story_change_class.create!(attributes)
|
37
|
+
end
|
38
|
+
|
39
|
+
def find_all_by_project_id(id)
|
40
|
+
Change.find_all_by_project_id(id)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'artisan-ar-repository/models/future_user'
|
2
|
+
require 'artisan-ar-repository/base_repository'
|
3
|
+
|
4
|
+
module ArtisanArRepository
|
5
|
+
class FutureUserRepository
|
6
|
+
include BaseRepository
|
7
|
+
|
8
|
+
def model_class
|
9
|
+
::FutureUser
|
10
|
+
end
|
11
|
+
|
12
|
+
def create(attributes = {})
|
13
|
+
begin
|
14
|
+
future_user = model_class.new(attributes)
|
15
|
+
future_user.save!
|
16
|
+
future_user
|
17
|
+
rescue ActiveRecord::RecordInvalid
|
18
|
+
raise Artisan::RecordNotValid.new(future_user)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def find_by_email(email)
|
23
|
+
model_class.find_by_email(email)
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_by_project_id(project_id)
|
27
|
+
model_class.find_by_project_id(project_id)
|
28
|
+
end
|
29
|
+
|
30
|
+
def delete(id)
|
31
|
+
model_class.delete(id)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'artisan-ar-repository/models/iteration'
|
2
|
+
require 'artisan-ar-repository/base_repository'
|
3
|
+
|
4
|
+
module ArtisanArRepository
|
5
|
+
class IterationRepository
|
6
|
+
include BaseRepository
|
7
|
+
|
8
|
+
def model_class
|
9
|
+
::Iteration
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_for_project(project, attrs)
|
13
|
+
model_class.create!(attrs.merge(:project => project))
|
14
|
+
end
|
15
|
+
|
16
|
+
def find_by_number(project, number)
|
17
|
+
project.iterations.find_by_number(number)
|
18
|
+
end
|
19
|
+
|
20
|
+
def by_project(project)
|
21
|
+
project.iterations
|
22
|
+
end
|
23
|
+
|
24
|
+
def by_project_by_finish_date(project)
|
25
|
+
project.iterations.by_finish_date
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'artisan-ar-repository/models/story'
|
3
|
+
require 'artisan-ar-repository/models/day'
|
4
|
+
require 'artisan/stories/story_collection'
|
5
|
+
|
6
|
+
class Iteration < ActiveRecord::Base
|
7
|
+
belongs_to :project
|
8
|
+
has_many :stories
|
9
|
+
has_many :days
|
10
|
+
has_many :users, :through => :days
|
11
|
+
accepts_nested_attributes_for :days
|
12
|
+
|
13
|
+
default_scope :order => "number DESC"
|
14
|
+
|
15
|
+
scope :by_finish_date, order("finish_date DESC")
|
16
|
+
|
17
|
+
def total_billed_points
|
18
|
+
Artisan::Stories::StoryCollection.new(stories).billed_points
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'artisan-ar-repository/models/project_configuration'
|
2
|
+
|
3
|
+
class Project < ActiveRecord::Base
|
4
|
+
|
5
|
+
has_many :stories, :dependent => :destroy
|
6
|
+
has_many :iterations, :dependent => :destroy
|
7
|
+
has_many :members
|
8
|
+
has_many :users, :through => :members, :order => :login
|
9
|
+
|
10
|
+
has_many :pages
|
11
|
+
|
12
|
+
|
13
|
+
has_one :project_configuration, :dependent => :destroy
|
14
|
+
accepts_nested_attributes_for :project_configuration
|
15
|
+
|
16
|
+
scope :unarchived, where('archived = ? OR archived is NULL', false).order("name ASC")
|
17
|
+
scope :archived, where(:archived => true).order("name ASC")
|
18
|
+
scope :order_by_name, order("name ASC")
|
19
|
+
scope :by_date, order("updated_at DESC")
|
20
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class ProjectConfiguration < ActiveRecord::Base
|
2
|
+
belongs_to :project
|
3
|
+
|
4
|
+
serialize :story_completed_email_list, Array
|
5
|
+
serialize :story_assigned_email_list, Array
|
6
|
+
|
7
|
+
STANDARD_DEVIATION = "stddev"
|
8
|
+
WEIGHTED_MEAN = "weighted_mean"
|
9
|
+
|
10
|
+
def estimate_mode
|
11
|
+
read_attribute(:estimate_mode) || STANDARD_DEVIATION
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'artisan/stories/pert_calculator'
|
2
|
+
|
3
|
+
class Story < ActiveRecord::Base
|
4
|
+
belongs_to :project
|
5
|
+
belongs_to :iteration
|
6
|
+
belongs_to :assigned_user, :class_name => "User"
|
7
|
+
belongs_to :creator, :class_name => "User"
|
8
|
+
acts_as_taggable
|
9
|
+
|
10
|
+
default_scope where("deleted = ?", false).order("position ASC")
|
11
|
+
|
12
|
+
scope :completed, where("complete = ?", true).order("position ASC")
|
13
|
+
scope :ready, where("assigned_user_id IS NULL AND (complete = ? OR complete IS NULL)", false).order("position ASC")
|
14
|
+
scope :working, where("assigned_user_id IS NOT NULL AND (complete = ? OR complete IS NULL)", false).order("position ASC")
|
15
|
+
scope :for_user, lambda { |user| where "assigned_user_id = ?", user.id }
|
16
|
+
scope :by_project, lambda { |project| where "project_id = ?", project.id }
|
17
|
+
|
18
|
+
scope :backlog, where(:iteration_id => nil)
|
19
|
+
scope :complete, where(:complete => true)
|
20
|
+
|
21
|
+
def to_param
|
22
|
+
number.to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.by_number_and_project(number, project)
|
26
|
+
find_by_number_and_project_id!(number, project.id)
|
27
|
+
end
|
28
|
+
|
29
|
+
def estimate
|
30
|
+
pert_calculator.estimate
|
31
|
+
end
|
32
|
+
|
33
|
+
def standard_deviation
|
34
|
+
pert_calculator.standard_deviation
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete
|
38
|
+
update_attributes(:deleted => true, :iteration => nil)
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_to_iteration(iteration)
|
42
|
+
update_attribute(:iteration, iteration) unless iteration.complete?
|
43
|
+
end
|
44
|
+
|
45
|
+
def assigned_user_name
|
46
|
+
assigned_user.full_name if assigned_user
|
47
|
+
end
|
48
|
+
|
49
|
+
def assigned_user_email
|
50
|
+
assigned_user.email if assigned_user
|
51
|
+
end
|
52
|
+
|
53
|
+
#TODO - PWP - to remove this dependency we need to remove dependency on super as_json
|
54
|
+
def as_json(options={})
|
55
|
+
return Artisan::Stories::StoryExporter.new(self).as_json(super(options), options)
|
56
|
+
end
|
57
|
+
|
58
|
+
def pert_calculator
|
59
|
+
Artisan::Stories::PertCalculator.new(self, project.project_configuration.estimate_mode)
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'artisan/repository'
|
2
|
+
|
3
|
+
class User < ActiveRecord::Base
|
4
|
+
# Setup accessible (or protected) attributes for your model
|
5
|
+
attr_accessible :login, :project_id, :full_name, :email, :password, :password_confirmation, :remember_me
|
6
|
+
|
7
|
+
has_many :days
|
8
|
+
has_many :iterations, :through => :days
|
9
|
+
has_many :stories
|
10
|
+
|
11
|
+
has_many :projects, :through => :members
|
12
|
+
has_many :members
|
13
|
+
|
14
|
+
validates :full_name, :presence => true
|
15
|
+
validates_length_of :login, :minimum => 3
|
16
|
+
validates_format_of :login, :with => /\A\w[\w\.+\-_@ ]+$/, :message => "should use only letters, numbers, spaces, and .-_@ please."
|
17
|
+
validates_uniqueness_of :login, :case_sensitive => false
|
18
|
+
|
19
|
+
after_create :join_team
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def join_team
|
24
|
+
future_user_repository = Artisan::Repository.future_user
|
25
|
+
future_user = future_user_repository.find_by_email(self.email)
|
26
|
+
if future_user
|
27
|
+
project = Artisan::Repository.project.find(future_user.project_id)
|
28
|
+
team = Team.new(project, self)
|
29
|
+
team.add_team_member(self)
|
30
|
+
future_user_repository.delete(future_user.id)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'artisan-ar-repository/models/project'
|
2
|
+
require 'artisan-ar-repository/base_repository'
|
3
|
+
require 'artisan-ar-repository/models/member'
|
4
|
+
|
5
|
+
module ArtisanArRepository
|
6
|
+
class ProjectRepository
|
7
|
+
include BaseRepository
|
8
|
+
|
9
|
+
def model_class
|
10
|
+
::Project
|
11
|
+
end
|
12
|
+
|
13
|
+
def find_by_api_key(id)
|
14
|
+
model_class.find_by_api_key(id)
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_by_name(id)
|
18
|
+
model_class.find_by_name(id)
|
19
|
+
end
|
20
|
+
|
21
|
+
def order_by_name(*args)
|
22
|
+
model_class.order_by_name(*args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def unarchived(*args)
|
26
|
+
model_class.unarchived(*args)
|
27
|
+
end
|
28
|
+
|
29
|
+
def archived(*args)
|
30
|
+
model_class.archived(*args)
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_iteration(project, iteration)
|
34
|
+
project.iterations << iteration
|
35
|
+
return iteration
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_member(project, user, owner)
|
39
|
+
Artisan::Repository.member.create(:user_id => user.id, :project_id => project.id , :owner => owner)
|
40
|
+
end
|
41
|
+
|
42
|
+
def remove_member(project, user)
|
43
|
+
membership_for(project, user).destroy
|
44
|
+
end
|
45
|
+
|
46
|
+
def is_member?(project, user)
|
47
|
+
return !membership_for(project, user).nil?
|
48
|
+
end
|
49
|
+
|
50
|
+
def is_owner?(project, user)
|
51
|
+
return false if project.nil? || not_a_member_of?(project, user)
|
52
|
+
return membership_for(project, user).owner?
|
53
|
+
end
|
54
|
+
|
55
|
+
def not_a_member_of?(project, user)
|
56
|
+
return membership_for(project, user).nil?
|
57
|
+
end
|
58
|
+
|
59
|
+
def membership_for(project, user)
|
60
|
+
return project.members.find_by_user_id(user.id)
|
61
|
+
end
|
62
|
+
|
63
|
+
def owners(project)
|
64
|
+
project.members.find_all_by_owner(true).collect(&:user)
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_project_configuration(project)
|
68
|
+
project.create_project_configuration
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'artisan-ar-repository/base_repository'
|
2
|
+
require 'artisan-ar-repository/models/story'
|
3
|
+
|
4
|
+
module ArtisanArRepository
|
5
|
+
class StoryRepository
|
6
|
+
include BaseRepository
|
7
|
+
|
8
|
+
def model_class
|
9
|
+
::Story
|
10
|
+
end
|
11
|
+
|
12
|
+
def find(number, project)
|
13
|
+
begin
|
14
|
+
model_class.by_number_and_project(number, project)
|
15
|
+
rescue ActiveRecord::RecordNotFound => e
|
16
|
+
raise Artisan::RecordNotFound.new(e)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def for_user(user)
|
21
|
+
model_class.for_user(user)
|
22
|
+
end
|
23
|
+
|
24
|
+
def by_project(project)
|
25
|
+
model_class.by_project(project)
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_to_iteration(iteration, story)
|
29
|
+
iteration.stories << story
|
30
|
+
end
|
31
|
+
|
32
|
+
def remove_from_iteration(story)
|
33
|
+
story.update_attribute(:iteration_id, nil)
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_for_project(project, attrs = {})
|
37
|
+
project.stories.create!(attrs)
|
38
|
+
end
|
39
|
+
|
40
|
+
def all(iteration)
|
41
|
+
iteration.stories
|
42
|
+
end
|
43
|
+
|
44
|
+
def ready(iteration)
|
45
|
+
iteration.stories.ready
|
46
|
+
end
|
47
|
+
|
48
|
+
def working(iteration)
|
49
|
+
iteration.stories.working
|
50
|
+
end
|
51
|
+
|
52
|
+
def completed(iteration)
|
53
|
+
iteration.stories.completed
|
54
|
+
end
|
55
|
+
|
56
|
+
def delete(story)
|
57
|
+
story.update_attributes(:deleted => true, :iteration => nil)
|
58
|
+
story
|
59
|
+
end
|
60
|
+
|
61
|
+
def backlog(project)
|
62
|
+
project.stories.backlog
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'artisan-ar-repository/models/user'
|
2
|
+
require 'artisan-ar-repository/base_repository'
|
3
|
+
|
4
|
+
module ArtisanArRepository
|
5
|
+
class UserRepository
|
6
|
+
include BaseRepository
|
7
|
+
|
8
|
+
def model_class
|
9
|
+
::User
|
10
|
+
end
|
11
|
+
|
12
|
+
def create(attributes = {})
|
13
|
+
begin
|
14
|
+
user = model_class.new(attributes)
|
15
|
+
user.save!
|
16
|
+
user
|
17
|
+
rescue ActiveRecord::RecordInvalid
|
18
|
+
raise Artisan::RecordNotValid.new(user)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def find_by_login(login)
|
23
|
+
model_class.find_by_login(login)
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_by_email(email)
|
27
|
+
model_class.find_by_email(email)
|
28
|
+
end
|
29
|
+
|
30
|
+
def active_stories_for(user)
|
31
|
+
Artisan::Repository.story.for_user(user).working.reject do |story|
|
32
|
+
story.iteration.nil?
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: artisan-ar-repository
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.4
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- 8th Light Craftsmen
|
@@ -22,6 +22,29 @@ extensions: []
|
|
22
22
|
extra_rdoc_files: []
|
23
23
|
|
24
24
|
files:
|
25
|
+
- lib/artisan-ar-repository/base_repository.rb
|
26
|
+
- lib/artisan-ar-repository/change_repository.rb
|
27
|
+
- lib/artisan-ar-repository/future_user_repository.rb
|
28
|
+
- lib/artisan-ar-repository/iteration_repository.rb
|
29
|
+
- lib/artisan-ar-repository/member_repository.rb
|
30
|
+
- lib/artisan-ar-repository/models/change.rb
|
31
|
+
- lib/artisan-ar-repository/models/day.rb
|
32
|
+
- lib/artisan-ar-repository/models/future_user.rb
|
33
|
+
- lib/artisan-ar-repository/models/iteration.rb
|
34
|
+
- lib/artisan-ar-repository/models/iteration_change.rb
|
35
|
+
- lib/artisan-ar-repository/models/member.rb
|
36
|
+
- lib/artisan-ar-repository/models/project.rb
|
37
|
+
- lib/artisan-ar-repository/models/project_change.rb
|
38
|
+
- lib/artisan-ar-repository/models/project_configuration.rb
|
39
|
+
- lib/artisan-ar-repository/models/story.rb
|
40
|
+
- lib/artisan-ar-repository/models/story_assigned_email.rb
|
41
|
+
- lib/artisan-ar-repository/models/story_change.rb
|
42
|
+
- lib/artisan-ar-repository/models/story_completed_email.rb
|
43
|
+
- lib/artisan-ar-repository/models/user.rb
|
44
|
+
- lib/artisan-ar-repository/project_configuration_repository.rb
|
45
|
+
- lib/artisan-ar-repository/project_repository.rb
|
46
|
+
- lib/artisan-ar-repository/story_repository.rb
|
47
|
+
- lib/artisan-ar-repository/user_repository.rb
|
25
48
|
- spec/artisan_ar_repository_spec.rb
|
26
49
|
- spec/change_repository_spec.rb
|
27
50
|
- spec/future_user_repository_spec.rb
|
@@ -43,7 +66,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
43
66
|
requirements:
|
44
67
|
- - ">="
|
45
68
|
- !ruby/object:Gem::Version
|
46
|
-
hash:
|
69
|
+
hash: -3449863664794801791
|
47
70
|
segments:
|
48
71
|
- 0
|
49
72
|
version: "0"
|