artisan-ar-repository 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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"