erp_work_effort 3.1.1 → 4.0.0

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.
Files changed (132) hide show
  1. checksums.yaml +7 -0
  2. data/app/controllers/erp_work_effort/erp_app/organizer/tasks/base_controller.rb +13 -0
  3. data/app/controllers/erp_work_effort/erp_app/organizer/tasks/work_efforts_controller.rb +128 -0
  4. data/app/models/associated_transportation_route.rb +12 -0
  5. data/app/models/associated_work_effort.rb +12 -0
  6. data/app/models/deliverable.rb +7 -0
  7. data/app/models/deliverable_type.rb +9 -0
  8. data/app/models/extensions/party.rb +0 -2
  9. data/app/models/good_type.rb +11 -0
  10. data/app/models/party_fixed_asset_assignment.rb +12 -0
  11. data/app/models/party_skill.rb +6 -0
  12. data/app/models/requirement.rb +14 -0
  13. data/app/models/requirement_party_role.rb +8 -0
  14. data/app/models/requirement_type.rb +7 -0
  15. data/app/models/skill_type.rb +10 -0
  16. data/app/models/transportation_route.rb +71 -0
  17. data/app/models/transportation_route_segment.rb +9 -0
  18. data/app/models/transportation_route_stop.rb +6 -0
  19. data/app/models/work_effort.rb +82 -92
  20. data/app/models/work_effort_association.rb +16 -0
  21. data/app/models/work_effort_association_type.rb +14 -0
  22. data/app/models/work_effort_deliverable_produced.rb +6 -0
  23. data/app/models/work_effort_fixed_asset_assignment.rb +10 -0
  24. data/app/models/work_effort_fixed_asset_serviced.rb +6 -0
  25. data/app/models/work_effort_fixed_asset_standard.rb +7 -0
  26. data/app/models/work_effort_good_standard.rb +7 -0
  27. data/app/models/work_effort_inventory_assignment.rb +10 -0
  28. data/app/models/work_effort_inventory_produced.rb +7 -0
  29. data/app/models/work_effort_party_assignment.rb +12 -0
  30. data/app/models/work_effort_purpose_type.rb +11 -0
  31. data/app/models/work_effort_skill_standard.rb +7 -0
  32. data/app/models/work_effort_type.rb +9 -0
  33. data/app/models/work_effort_type_association.rb +10 -0
  34. data/app/models/work_order_item.rb +5 -0
  35. data/app/models/work_order_item_fulfillment.rb +11 -0
  36. data/app/models/work_requirement_fulfillment.rb +3 -0
  37. data/config/routes.rb +20 -0
  38. data/db/data_migrations/20131213151309_create_tasks_organizer_application.rb +14 -0
  39. data/db/data_migrations/20131215225329_add_task_work_effort_types.rb +11 -0
  40. data/db/data_migrations/20131215234936_add_task_statuses.rb +21 -0
  41. data/db/migrate/20100220000000_base_work_efforts.rb +506 -103
  42. data/db/migrate/20130829153419_base_routes.rb +93 -0
  43. data/db/migrate/20131213140617_add_work_effort_role_assignments.rb +16 -0
  44. data/db/migrate/20131213144223_add_work_item_to_work_effort.rb +8 -0
  45. data/db/migrate/20140106184615_update_work_effort_item_id_to_int.rb +27 -0
  46. data/lib/erp_work_effort.rb +1 -1
  47. data/lib/erp_work_effort/engine.rb +7 -5
  48. data/lib/erp_work_effort/extensions.rb +2 -4
  49. data/lib/erp_work_effort/extensions/active_record/acts_as_routable.rb +55 -0
  50. data/lib/erp_work_effort/extensions/active_record/acts_as_work_effort.rb +66 -0
  51. data/lib/erp_work_effort/version.rb +7 -3
  52. data/spec/models/deliverable_spec.rb +5 -0
  53. data/spec/models/deliverable_type_spec.rb +5 -0
  54. data/spec/models/facility_spec.rb +8 -0
  55. data/spec/models/facility_type_spec.rb +8 -0
  56. data/spec/models/fixed_asset_party_role_spec.rb +5 -0
  57. data/spec/models/fixed_asset_spec.rb +5 -0
  58. data/spec/models/fixed_asset_type_spec.rb +5 -0
  59. data/spec/models/good_type_spec.rb +5 -0
  60. data/spec/models/party_fixed_asset_assignment_spec.rb +5 -0
  61. data/spec/models/party_skill_spec.rb +5 -0
  62. data/spec/models/requirement_party_role_spec.rb +5 -0
  63. data/spec/models/requirement_spec.rb +5 -0
  64. data/spec/models/requirement_type_spec.rb +5 -0
  65. data/spec/models/skill_type_spec.rb +8 -0
  66. data/spec/models/work_effort_association_spec.rb +5 -0
  67. data/spec/models/work_effort_association_type_spec.rb +5 -0
  68. data/spec/models/work_effort_deliverable_produced_spec.rb +5 -0
  69. data/spec/models/work_effort_fixed_asset_assignment_spec.rb +5 -0
  70. data/spec/models/work_effort_fixed_asset_serviced_spec.rb +5 -0
  71. data/spec/models/work_effort_fixed_asset_standard_spec.rb +5 -0
  72. data/spec/models/work_effort_good_standard_spec.rb +5 -0
  73. data/spec/models/work_effort_inventory_assignment_spec.rb +5 -0
  74. data/spec/models/work_effort_inventory_produced_spec.rb +5 -0
  75. data/spec/models/work_effort_party_assignment_spec.rb +5 -0
  76. data/spec/models/work_effort_purpose_type_spec.rb +5 -0
  77. data/spec/models/work_effort_skill_standard_spec.rb +5 -0
  78. data/spec/models/work_effort_spec.rb +49 -0
  79. data/spec/models/work_effort_type_association_spec.rb +5 -0
  80. data/spec/models/work_effort_type_spec.rb +5 -0
  81. data/spec/models/work_order_item_fulfillment_spec.rb +5 -0
  82. data/spec/models/work_order_item_spec.rb +29 -0
  83. data/spec/models/work_requirement_fulfillment_spec.rb +5 -0
  84. metadata +141 -105
  85. data/app/assets/javascripts/erp_work_effort/application.js +0 -9
  86. data/app/assets/stylesheets/erp_work_effort/application.css +0 -7
  87. data/app/controllers/erp_work_effort/application_controller.rb +0 -4
  88. data/app/helpers/erp_work_effort/application_helper.rb +0 -4
  89. data/app/models/cost.rb +0 -5
  90. data/app/models/project_effort.rb +0 -2
  91. data/app/models/project_requirement.rb +0 -2
  92. data/app/models/support_effort.rb +0 -2
  93. data/app/models/support_requirement.rb +0 -2
  94. data/app/models/work_effort_assignment.rb +0 -12
  95. data/app/models/work_effort_status.rb +0 -6
  96. data/app/models/work_effort_status_type.rb +0 -15
  97. data/app/models/work_requirement.rb +0 -78
  98. data/app/models/work_requirement_work_effort_status_type.rb +0 -6
  99. data/app/views/layouts/erp_work_effort/application.html.erb +0 -14
  100. data/lib/erp_work_effort/extensions/active_record/acts_as_project_effort.rb +0 -66
  101. data/lib/erp_work_effort/extensions/active_record/acts_as_project_requirement.rb +0 -64
  102. data/lib/erp_work_effort/extensions/active_record/acts_as_support_effort.rb +0 -61
  103. data/lib/erp_work_effort/extensions/active_record/acts_as_support_requirement.rb +0 -68
  104. data/spec/dummy/db/data_migrations/20110109173616_create_capability_scope_types.erp_tech_svcs.rb +0 -15
  105. data/spec/dummy/db/data_migrations/20110525001935_add_usd_currency.erp_base_erp_svcs.rb +0 -12
  106. data/spec/dummy/db/data_migrations/20110609150135_add_iso_codes.erp_base_erp_svcs.rb +0 -19
  107. data/spec/dummy/db/data_migrations/20110802200222_schedule_delete_expired_sessions_job.erp_tech_svcs.rb +0 -16
  108. data/spec/dummy/db/data_migrations/20110913145838_setup_compass_ae_instance.erp_base_erp_svcs.rb +0 -12
  109. data/spec/dummy/db/data_migrations/20111111144706_setup_audit_log_types.erp_tech_svcs.rb +0 -22
  110. data/spec/dummy/db/data_migrations/20121116155018_create_group_relationship_and_role_types.erp_tech_svcs.rb +0 -20
  111. data/spec/dummy/db/data_migrations/20121130212146_note_capabilities.erp_tech_svcs.rb +0 -24
  112. data/spec/dummy/db/migrate/20130107204429_base_erp_services.erp_base_erp_svcs.rb +0 -461
  113. data/spec/dummy/db/migrate/20130107204430_base_work_efforts.erp_work_effort.rb +0 -211
  114. data/spec/dummy/db/migrate/20130107204431_base_tech_services.erp_tech_svcs.rb +0 -271
  115. data/spec/dummy/db/migrate/20130107204432_create_has_attribute_tables.erp_tech_svcs.rb +0 -39
  116. data/spec/dummy/db/migrate/20130107204433_create_groups.erp_tech_svcs.rb +0 -19
  117. data/spec/dummy/db/migrate/20130107204434_upgrade_security.erp_tech_svcs.rb +0 -54
  118. data/spec/dummy/db/migrate/20130107204435_upgrade_security2.erp_tech_svcs.rb +0 -270
  119. data/spec/dummy/db/schema.rb +0 -750
  120. data/spec/dummy/db/spec.sqlite3 +0 -0
  121. data/spec/models/cost_spec.rb +0 -11
  122. data/spec/models/project_effort_spec.rb +0 -11
  123. data/spec/models/project_requirement_spec.rb +0 -11
  124. data/spec/models/support_effort_spec.rb +0 -11
  125. data/spec/models/support_requirement_spec.rb +0 -11
  126. data/spec/models/valid_work_assignment_attribute_spec.rb +0 -11
  127. data/spec/models/valid_work_assignment_spec.rb +0 -11
  128. data/spec/models/work_effort_assignment_spec.rb +0 -13
  129. data/spec/models/work_effort_status_spec.rb +0 -11
  130. data/spec/models/work_effort_status_type_spec.rb +0 -11
  131. data/spec/models/work_requirement_spec.rb +0 -11
  132. data/spec/models/work_requirement_work_effort_status_type._spec.rb +0 -11
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ad5d23963efb2e5067ac139ef8d7886811a058d1
4
+ data.tar.gz: 0d51e61b9b9b83fe5d6080a4a543cffa27bc9c8f
5
+ SHA512:
6
+ metadata.gz: 7f7a8b18fa29c8584836be2c62a412575163c2ea82acb3d9c8d5106a507efbe704c32ae7b46968949fbbcd765fc7235ab3f5e08ac41fb8a759655cda9a1ad0e3
7
+ data.tar.gz: d775e88305f33b49f9e54e0520638cf70b6bc408606f89acb994449f0204c55e6eaaf8260c3df506540434270c1bf2e6069e5e0dbc542a54f39fd52958d769f6
@@ -0,0 +1,13 @@
1
+ module ErpApp
2
+ module Organizer
3
+ module Tasks
4
+ class BaseController < ::ErpApp::Organizer::BaseController
5
+
6
+ def menu
7
+ render :json => [{:text => 'Menu Item', :leaf => true, :iconCls => 'icon-note_pinned', :applicationCardId => "tasks_example_panel"}]
8
+ end
9
+
10
+ end #BaseController
11
+ end #Tasks
12
+ end #Organizer
13
+ end #ErpApp
@@ -0,0 +1,128 @@
1
+ module ErpWorkEffort
2
+ module ErpApp
3
+ module Organizer
4
+ module Tasks
5
+ class WorkEffortsController < ::ErpApp::Organizer::BaseController
6
+
7
+ def role_types
8
+ data = RoleType.iid('task_master').self_and_descendants.collect{|item| item.to_hash(:only => [:id, :description])}
9
+
10
+ render :json => {success: true, role_types: data}
11
+ end
12
+
13
+ def work_effort_types
14
+ data = WorkEffortType.all.collect{|item| item.to_hash(:only => [:id, :description])}
15
+
16
+ render :json => {success: true, work_effort_types: data}
17
+ end
18
+
19
+ def task_count
20
+ party = params[:party_id].blank? ? nil : Party.find(params[:party_id])
21
+
22
+ if party
23
+ work_efforts_statement = WorkEffort.work_efforts_for_party(party, 'pending')
24
+ else
25
+ work_efforts_statement = WorkEffort.work_efforts_for_party(current_user.party, 'pending')
26
+ end
27
+
28
+ count = work_efforts_statement.count
29
+
30
+ render :json => {success: true, count: count}
31
+ end
32
+
33
+ def index
34
+ offset = params[:offset] || 0
35
+ limit = params[:limit] || 25
36
+ party = params[:party_id].blank? ? nil : Party.find(params[:party_id])
37
+ all_tasks = params[:all_tasks].blank? ? false : true
38
+
39
+ if all_tasks
40
+ work_efforts_statement = WorkEffort
41
+ elsif party
42
+ work_efforts_statement = WorkEffort.work_efforts_for_party(party)
43
+ else
44
+ work_efforts_statement = WorkEffort.work_efforts_for_party(current_user.party)
45
+ end
46
+
47
+ total = work_efforts_statement.count
48
+ work_efforts = work_efforts_statement.limit(limit).offset(offset)
49
+
50
+ work_efforts.sort!
51
+
52
+ data = work_efforts.sort.collect { |item| item.to_hash(
53
+ :only => [
54
+ :id,
55
+ :description,
56
+ :created_at,
57
+ :current_status,
58
+ ],
59
+ :current_status_description => (TrackedStatusType.find_by_internal_identifier(item.current_status).description),
60
+ :assigned_parties => item.assigned_parties,
61
+ :assigned_roles => item.assigned_roles
62
+ )
63
+ }
64
+
65
+ render :json => {:success => true, :total => total, :work_efforts => data}
66
+ end
67
+
68
+ def create
69
+ result = {}
70
+
71
+ begin
72
+ ActiveRecord::Base.transaction do
73
+ estimated_completion_time = params[:estimated_completion_time].to_i
74
+ description = params[:description].strip
75
+ work_effort_type_id = params[:work_effort_type]
76
+
77
+ work_effort_type = WorkEffortType.find(work_effort_type_id)
78
+
79
+ work_effort = WorkEffort.new
80
+ work_effort.work_effort_type = work_effort_type
81
+ work_effort.description = description
82
+ work_effort.projected_completion_time = estimated_completion_time
83
+ work_effort.save
84
+
85
+ work_effort.current_status = 'pending'
86
+
87
+ unless params[:assignment_type_role].blank?
88
+ role_type = RoleType.find(params[:role_type])
89
+
90
+ work_effort.role_types << role_type
91
+
92
+ end
93
+
94
+ unless params[:assignment_type_party].blank?
95
+ party = Party.find(params[:assigned_party_id])
96
+
97
+ work_effort_party_assignment = WorkEffortPartyAssignment.new
98
+ work_effort_party_assignment.party = party
99
+ work_effort_party_assignment.role_type = RoleType.iid('worker')
100
+
101
+ work_effort.work_effort_party_assignments << work_effort_party_assignment
102
+ end
103
+
104
+ work_effort.save
105
+
106
+ result = {:success => true, :message => "Task Added"}
107
+
108
+ end
109
+ rescue => ex
110
+ Rails.logger.error ex.message
111
+ Rails.logger.error ex.backtrace.join("\n")
112
+ result = {:success => false, :message => "Error adding task"}
113
+ end
114
+
115
+ render :json => result
116
+ end
117
+
118
+ def destroy
119
+ work_effort = WorkEffort.find(params[:id])
120
+
121
+ render :json => {:success => work_effort.destroy}
122
+ end
123
+
124
+ end #WorkEffortsController
125
+ end #Tasks
126
+ end #Organizer
127
+ end #ErpApp
128
+ end #ErpWorkEffort
@@ -0,0 +1,12 @@
1
+ # EXAMPLE USAGE of has_many_polymorphic with AssociatedWorkEffort
2
+ # TransportationRoute.class_eval do
3
+ # has_many_polymorphic :associated_records,
4
+ # :through => :associated_transportation_routes,
5
+ # :models => [:shipment_items, :shipments]
6
+ # end
7
+ class AssociatedTransportationRoute < ActiveRecord::Base
8
+ attr_protected :created_at, :updated_at
9
+
10
+ belongs_to :transportation_route
11
+ belongs_to :associated_record, :polymorphic => true
12
+ end
@@ -0,0 +1,12 @@
1
+ # EXAMPLE USAGE of has_many_polymorphic with AssociatedWorkEffort
2
+ # WorkEffort.class_eval do
3
+ # has_many_polymorphic :associated_records,
4
+ # :through => :associated_work_efforts,
5
+ # :models => [:shipment_items]
6
+ # end
7
+ class AssociatedWorkEffort < ActiveRecord::Base
8
+ attr_protected :created_at, :updated_at
9
+
10
+ belongs_to :work_effort
11
+ belongs_to :associated_record, :polymorphic => true
12
+ end
@@ -0,0 +1,7 @@
1
+ class Deliverable < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
4
+ belongs_to :deliverable_type
5
+ belongs_to :deliverable_record, :polymorphic => true
6
+
7
+ end
@@ -0,0 +1,9 @@
1
+ class DeliverableType < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
4
+ acts_as_nested_set
5
+ include ErpTechSvcs::Utils::DefaultNestedSetMethods
6
+
7
+ has_many :deliverables
8
+
9
+ end
@@ -1,5 +1,3 @@
1
1
  Party.class_eval do
2
2
  has_many :resource_availabilities, :class_name => 'PartyResourceAvailability', :dependent => :destroy
3
- has_many :assigned_to_work_efforts, :as => 'assigned_to', :class_name => 'WorkEffortAssignment', :dependent => :destroy
4
- has_many :assigned_by_work_efforts, :as => 'assigned_by', :class_name => 'WorkEffortAssignment', :dependent => :destroy
5
3
  end
@@ -0,0 +1,11 @@
1
+ ## Types of goods required as a standard for the completion of work efforts. This is different from
2
+ ## inventory_items because it is not for planning. It is only for noting the type of good
3
+ ## that is required to perform the work effort. - See DMRB v1, pp 223-224
4
+
5
+ class GoodType < ActiveRecord::Base
6
+ attr_protected :created_at, :updated_at
7
+
8
+ acts_as_nested_set
9
+ include ErpTechSvcs::Utils::DefaultNestedSetMethods
10
+
11
+ end
@@ -0,0 +1,12 @@
1
+ ## Relationship between Parties and Fixed Assets to see who may been assigned or checked out
2
+ ## an asset.
3
+ ## IMPORTANT NOTE: The base framework does not extend Party or Fixed Asset to automatically show these
4
+ ## relationships. It is considered purpose-specific enough so that Party and Fixed asset can be given
5
+ ## the relationship code on a case-by-case basis.
6
+
7
+ class PartyFixedAssetAssignment < ActiveRecord::Base
8
+ attr_protected :created_at, :updated_at
9
+
10
+ belongs_to :party
11
+ belongs_to :fixed_asset
12
+ end
@@ -0,0 +1,6 @@
1
+ class PartySkill < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
4
+ belongs_to :party
5
+ belongs_to :skill_type
6
+ end
@@ -0,0 +1,14 @@
1
+ class Requirement < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
4
+ has_many :requirement_party_roles, :dependent => :destroy
5
+ has_many :parties, :through => :requirement_party_roles
6
+
7
+ #link to support the relationship between requirements and the work_efforts necessary to fulfill them
8
+ has_many :work_requirement_fulfillments
9
+ has_many :work_efforts, :through => :work_requirement_fulfillments
10
+
11
+ belongs_to :requirement_type
12
+ belongs_to :requirement_record, :polymorphic => true
13
+
14
+ end
@@ -0,0 +1,8 @@
1
+ class RequirementPartyRole < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
4
+ belongs_to :party
5
+ belongs_to :role_type
6
+ belongs_to :requirement
7
+
8
+ end
@@ -0,0 +1,7 @@
1
+ class RequirementType < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
4
+ acts_as_nested_set
5
+ include ErpTechSvcs::Utils::DefaultNestedSetMethods
6
+
7
+ end
@@ -0,0 +1,10 @@
1
+ class SkillType < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
4
+ acts_as_nested_set
5
+ include ErpTechSvcs::Utils::DefaultNestedSetMethods
6
+
7
+ has_many :party_skills
8
+ has_many :parties, :through => :party_skills
9
+
10
+ end
@@ -0,0 +1,71 @@
1
+ class TransportationRoute < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
4
+ #declare array to related models
5
+ attr_accessor :associated_records_array
6
+
7
+ # This class instance variable is needed to hold the models linked within :associated_transportation_routes
8
+ class << self; attr_accessor :associated_models end
9
+ @associated_models = []
10
+
11
+ # Needed for polymorophic relationship with other models
12
+ has_many :associated_transportation_routes, :dependent => :destroy
13
+
14
+ has_many :segments, :class_name => "TransportationRouteSegment", :after_add => :modify_stops, :dependent => :destroy
15
+ has_many :stops, :class_name => "TransportationRouteStop", :dependent => :destroy
16
+
17
+ #before we save this model make sure you save all the relationships.
18
+ before_save do |record|
19
+ record.send("associated_records").each do |reln_record|
20
+ #handle STI get superclass class_name if not sub class of ActiveRecord::Base
21
+ klass_name = (reln_record.class.superclass == ActiveRecord::Base) ? reln_record.class.name : reln_record.class.superclass.name
22
+ conditions = "associated_record_id = #{reln_record.id} and associated_record_type = '#{klass_name}'"
23
+ exisiting_record = record.send("associated_transportation_routes").where(conditions).first
24
+
25
+ if exisiting_record.nil?
26
+ values_hash = {}
27
+ values_hash["#{record.class.name.underscore}_id"] = record.id
28
+ values_hash["associated_record_type"] = klass_name
29
+ values_hash["associated_record_id"] = reln_record.id
30
+
31
+ AssociatedTransportationRoute.create(values_hash)
32
+ end
33
+ end
34
+ end
35
+
36
+ # Gets all associated records (of any class) tied to this route
37
+ def associated_records
38
+ #used the declared instance variable array
39
+ records = self.send("associated_records_array")
40
+ records = records || []
41
+ self.class.associated_models.each do |model|
42
+ records = records | self.send(model.to_s)
43
+ end
44
+
45
+ #set it back to the instance variable
46
+ self.send("associated_records_array=", records)
47
+
48
+ records
49
+ end
50
+
51
+ # Ties a segment's from/to stops to its route, and then forces a reload of the route's stops array from its cached value
52
+ def modify_stops(segment)
53
+ stops = []
54
+ stops << segment.from_stop << segment.to_stop
55
+
56
+ stops.each do |stop|
57
+ unless stop.nil? or stop.route == self
58
+ stop.route = self
59
+ stop.save
60
+ end
61
+ end
62
+
63
+ # Force reload of the stops array since it has changed
64
+ self.stops(true)
65
+ end
66
+
67
+ def test
68
+ puts self.name
69
+ end
70
+
71
+ end
@@ -0,0 +1,9 @@
1
+ class TransportationRouteSegment < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
4
+ belongs_to :route, :class_name => "TransportationRoute", :foreign_key => "transportation_route_id"
5
+
6
+ belongs_to :from_stop, :class_name => "TransportationRouteStop", :foreign_key => "from_transportation_route_stop_id"
7
+ belongs_to :to_stop, :class_name => "TransportationRouteStop", :foreign_key => "to_transportation_route_stop_id"
8
+
9
+ end
@@ -0,0 +1,6 @@
1
+ class TransportationRouteStop < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
4
+ belongs_to :route, :class_name => "TransportationRoute", :foreign_key => "transportation_route_id"
5
+
6
+ end
@@ -3,45 +3,106 @@ class WorkEffort < ActiveRecord::Base
3
3
 
4
4
  acts_as_nested_set
5
5
  include ErpTechSvcs::Utils::DefaultNestedSetMethods
6
+ has_tracked_status
6
7
 
8
+ belongs_to :work_effort_item, :polymorphic => true
9
+
10
+ belongs_to :work_effort_type
11
+ belongs_to :work_effort_purpose_type
12
+
13
+ ## How is this Work Effort related to Work Order Items (order_line_items)
14
+ has_many :work_order_item_fulfillments, :dependent => :destroy
15
+ has_many :order_line_items, :through => :work_order_item_fulfillments
16
+
17
+ ## How is a work effort assigned, it can be assigned to party roles which allow for generic assignment.
18
+ has_and_belongs_to_many :role_types
19
+ alias :role_type_assignments :role_types
20
+
21
+ ## How is this Work Effort related to business parties, requestors, workers, approvers
22
+ has_many :work_effort_party_assignments, :dependent => :destroy
23
+ has_many :parties, :through => :work_effort_party_assignments
24
+
25
+ ## What Inventory Items are used in the execution of this Work Effort
26
+ has_many :work_effort_inventory_assignments, :dependent => :destroy
27
+ has_many :inventory_entries, :through => :work_effort_inventory_assignments
28
+
29
+ ## What Fixed Assets (tools, equipment) are used in the execution of this Work Effort
30
+ has_many :work_effort_fixed_asset_assignments, :dependent => :destroy
31
+ has_many :fixed_assets, :through => :work_effort_fixed_asset_assignments
32
+
33
+ ## Allow for polymorphic subtypes of this class
7
34
  belongs_to :work_effort_record, :polymorphic => true
8
- belongs_to :facility, :polymorphic => true
9
- has_many :work_effort_assignments
10
- has_many :work_effort_statuses
11
35
 
12
- belongs_to :projected_cost, :class_name => 'Cost', :foreign_key => 'projected_cost_id'
13
- belongs_to :actual_cost, :class_name => 'Cost', :foreign_key => 'actual_cost_id'
14
- #has_one :work_effort_deliverable
36
+ belongs_to :projected_cost, :class_name => 'Money', :foreign_key => 'projected_cost_money_id'
37
+ belongs_to :actual_cost, :class_name => 'Money', :foreign_key => 'actual_cost_money_id'
38
+ belongs_to :facility
39
+
40
+ class << self
41
+ def work_efforts_for_party(party, status=nil)
42
+ role_types_tbl = RoleType.arel_table
43
+ parties_tbl = Party.arel_table
44
+
45
+ statement = self
46
+
47
+ # apply status if passed
48
+ statement = statement.with_status(status) if status
49
+
50
+ statement.includes(:role_types)
51
+ .includes(:parties)
52
+ .where(role_types_tbl[:id].in(party.party_roles.collect(&:role_type_id)).or(parties_tbl[:id].eq(party.id)))
53
+ end
54
+ end
55
+
56
+ def <=>(an_other)
57
+ case an_other.current_status
58
+ when 'pending'
59
+ 1
60
+ when 'complete'
61
+ 2
62
+ else
63
+ 3
64
+ end
65
+ end
66
+
67
+ def assigned_parties(role_type='worker')
68
+ self.work_effort_party_assignments.where('role_type_id = ?', RoleType.iid(role_type)).collect do |item|
69
+ item.party.description
70
+ end.join(',')
71
+ end
72
+
73
+ def assigned_roles
74
+ self.role_types.collect(&:description).join(',')
75
+ end
15
76
 
16
- #get current status
17
77
  def status
18
- work_effort_status = self.descendants.flatten!.nil? ? self.get_current_status : self.descendants.flatten!.last.get_current_status
19
- work_effort_status.work_effort_status_type.description
78
+ # get status via has_tracked_status
79
+ current_status
20
80
  end
21
81
 
22
82
  # return true if this effort has been started, false otherwise
23
83
  def started?
24
- get_current_status.nil? ? false : true
84
+ current_status.nil? ? false : true
25
85
  end
26
-
86
+
27
87
  # return true if this effort has been completed, false otherwise
28
88
  def completed?
29
89
  finished_at.nil? ? false : true
30
90
  end
31
-
32
- #start initial work_status
33
- def start(status_type)
91
+
92
+ def finished?
93
+ completed?
94
+ end
95
+
96
+ #start work effort with initial_status (string)
97
+ def start(initial_status='')
34
98
  effort = self
35
99
  unless self.descendants.flatten!.nil?
36
100
  children = self.descendants.flatten
37
101
  effort = children.last
38
102
  end
39
103
 
40
- current_status = effort.get_current_status
41
-
42
104
  if current_status.nil?
43
- work_effort_status = WorkEffortStatus.create(:started_at => DateTime.now, :work_effort_status_type => status_type)
44
- effort.work_effort_statuses << work_effort_status
105
+ effort.current_status = initial_status
45
106
  effort.started_at = DateTime.now
46
107
  effort.save
47
108
  else
@@ -49,88 +110,17 @@ class WorkEffort < ActiveRecord::Base
49
110
  end
50
111
  end
51
112
 
52
- # completes current status if current status is in progress
53
- # start status passed in
54
- # if status passed in is last status, starts parent status if status exists
55
- def send_to_status(status_type, complete_effort=false, complete_status=false)
56
- current_status = get_current_status
57
-
58
- unless current_status.nil?
59
- new_work_effort_status = WorkEffortStatus.new
60
- new_work_effort_status.started_at = DateTime.now
61
- new_work_effort_status.finished_at = new_work_effort_status.started_at if complete_status
62
- new_work_effort_status.work_effort_status_type = status_type
63
- new_work_effort_status.work_effort = self
64
- new_work_effort_status.save
65
- current_status.finished_at = DateTime.now
66
- current_status.save
67
- complete_work_effort if complete_effort
68
- else
69
- raise 'Effort Has Not Started'
70
- end
71
- end
72
-
73
- #completes current status
74
- #start next status if not last status
75
- #starts parent status if parent exists
76
- def send_to_next_status
77
- current_status = get_current_status
78
-
79
- unless current_status.nil?
80
- next_status_type = current_status.work_effort_status_type.next_status_type
81
-
82
- if next_status_type.nil?
83
- complete_work_effort
84
- else
85
- new_work_effort_status = WorkEffortStatus.new
86
- new_work_effort_status.started_at = DateTime.now
87
- new_work_effort_status.work_effort_status_type = next_status_type
88
- new_work_effort_status.work_effort = self
89
- new_work_effort_status.save
90
- end
91
-
92
- current_status.finished_at = DateTime.now
93
- current_status.save
94
- else
95
- raise 'Effort Has Not Started' if current_status.nil?
96
- end
97
- end
98
-
99
- def send_to_previous_status
100
- current_status = get_current_status
101
-
102
- unless current_status.nil?
103
- previous_status_type = current_status.work_effort_status_type.previous_status_type
104
-
105
- if previous_status_type.nil?
106
- raise 'Current status is initial status' if current_status.nil?
107
- else
108
- new_work_effort_status = WorkEffortStatus.new
109
- new_work_effort_status.started_at = DateTime.now
110
- new_work_effort_status.work_effort_status_type = previous_status_type
111
- new_work_effort_status.work_effort = self
112
- new_work_effort_status.save
113
- end
114
-
115
- current_status.finished_at = DateTime.now
116
- current_status.save
117
- else
118
- raise 'Effort Has Not Started' if current_status.nil?
119
- end
113
+ def finish
114
+ complete
120
115
  end
121
116
 
122
- def complete_work_effort
117
+ def complete
123
118
  self.finished_at = Time.now
124
119
  self.actual_completion_time = time_diff_in_minutes(self.finished_at.to_time, self.started_at.to_time)
125
120
  self.save
126
- self.parent.start_effort unless self.parent.nil?
127
121
  end
128
122
 
129
123
  protected
130
- def get_current_status
131
- self.work_effort_statuses.find_by_finished_at(nil)
132
- end
133
-
134
124
  def time_diff_in_minutes (time_one, time_two)
135
125
  (((time_one - time_two).round) / 60)
136
126
  end