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.
@@ -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,12 @@
1
+ require 'artisan-ar-repository/models/member'
2
+ require 'artisan-ar-repository/base_repository'
3
+
4
+ module ArtisanArRepository
5
+ class MemberRepository
6
+ include BaseRepository
7
+
8
+ def model_class
9
+ ::Member
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ require 'artisan/repository'
2
+
3
+ class Change < ActiveRecord::Base
4
+ default_scope :order => "created_at DESC"
5
+ end
@@ -0,0 +1,4 @@
1
+ class Day < ActiveRecord::Base
2
+ belongs_to :user
3
+ belongs_to :iteration
4
+ end
@@ -0,0 +1,4 @@
1
+ class FutureUser < ActiveRecord::Base
2
+ validates_uniqueness_of :email, :message => "This email has already been taken"
3
+ belongs_to :project
4
+ end
@@ -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,2 @@
1
+ class IterationChange < Change
2
+ end
@@ -0,0 +1,4 @@
1
+ class Member < ActiveRecord::Base
2
+ belongs_to :user
3
+ belongs_to :project
4
+ 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,2 @@
1
+ class ProjectChange < Change
2
+ 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,4 @@
1
+ class StoryAssignedEmail < ActiveRecord::Base
2
+ belongs_to :project_configuration
3
+ end
4
+
@@ -0,0 +1,2 @@
1
+ class StoryChange < Change
2
+ end
@@ -0,0 +1,3 @@
1
+ class StoryCompletedEmail < ActiveRecord::Base
2
+ belongs_to :project_configuration
3
+ 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,9 @@
1
+ require 'artisan-ar-repository/models/project_configuration'
2
+
3
+ module ArtisanArRepository
4
+ class ProjectConfigurationRepository
5
+ def model_class
6
+ ::ProjectConfiguration
7
+ end
8
+ end
9
+ 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.3
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: 2972723930978108558
69
+ hash: -3449863664794801791
47
70
  segments:
48
71
  - 0
49
72
  version: "0"