ecom_core 1.2.32 → 1.3.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 (135) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/ecom/core/{project_crews_controller.rb → site_crews_controller.rb} +5 -4
  3. data/app/controllers/ecom/core/unit_costs_controller.rb +29 -0
  4. data/app/models/ecom/core/attendance_sheet.rb +19 -19
  5. data/app/models/ecom/core/available_unit_of_measurement.rb +10 -0
  6. data/app/models/ecom/core/crew.rb +6 -3
  7. data/app/models/ecom/core/crew_contract.rb +41 -1
  8. data/app/models/ecom/core/crew_contract_transaction.rb +29 -0
  9. data/app/models/ecom/core/crew_id_card.rb +36 -0
  10. data/app/models/ecom/core/crew_time.rb +1 -1
  11. data/app/models/ecom/core/inspection_checklist.rb +6 -0
  12. data/app/models/ecom/core/lookahead_plan.rb +41 -0
  13. data/app/models/ecom/core/lookahead_plan_history.rb +16 -0
  14. data/app/models/ecom/core/lookahead_plan_review_time.rb +29 -0
  15. data/app/models/ecom/core/lookahead_plan_task_progress.rb +22 -0
  16. data/app/models/ecom/core/material.rb +6 -0
  17. data/app/models/ecom/core/material_identity.rb +21 -0
  18. data/app/models/ecom/core/material_item.rb +18 -0
  19. data/app/models/ecom/core/material_sub_type.rb +20 -0
  20. data/app/models/ecom/core/measurement_unit.rb +4 -14
  21. data/app/models/ecom/core/overtime_sheet.rb +16 -16
  22. data/app/models/ecom/core/payroll.rb +3 -3
  23. data/app/models/ecom/core/project.rb +0 -3
  24. data/app/models/ecom/core/project_template.rb +13 -0
  25. data/app/models/ecom/core/project_work_item_template.rb +9 -0
  26. data/app/models/ecom/core/resource_requisition.rb +21 -0
  27. data/app/models/ecom/core/resource_requisition_item.rb +45 -0
  28. data/app/models/ecom/core/{project_crew.rb → site.rb} +8 -4
  29. data/app/models/ecom/core/site_crew.rb +27 -0
  30. data/app/models/ecom/core/stakeholder.rb +1 -1
  31. data/app/models/ecom/core/task.rb +22 -9
  32. data/app/models/ecom/core/task_attachment.rb +11 -0
  33. data/app/models/ecom/core/task_inspection_checklist.rb +18 -0
  34. data/app/models/ecom/core/task_template.rb +20 -90
  35. data/app/models/ecom/core/task_template_inspection_checklist.rb +8 -0
  36. data/app/models/ecom/core/unit_cost.rb +27 -0
  37. data/app/models/ecom/core/unit_of_measure.rb +8 -0
  38. data/app/models/ecom/core/work_item_resource_requirement_template.rb +18 -0
  39. data/app/models/ecom/core/work_package.rb +3 -0
  40. data/app/models/ecom/core/work_product.rb +2 -18
  41. data/app/models/ecom/core/work_product_template.rb +2 -2
  42. data/app/serializers/ecom/core/unit_cost_serializer.rb +21 -0
  43. data/app/services/ecom/core/crew_contract_transaction_service.rb +89 -0
  44. data/app/services/ecom/core/site_crew_service.rb +44 -0
  45. data/app/uploaders/ecom/core/photo_uploader.rb +13 -2
  46. data/app/uploaders/ecom/core/task_attachment_uploader.rb +11 -0
  47. data/config/initializers/carrierwave.rb +9 -0
  48. data/config/routes.rb +4 -2
  49. data/db/migrate/20191118052213_create_ecom_core_unit_of_measures.rb +11 -0
  50. data/db/migrate/20191119012030_create_ecom_core_task_templates.rb +10 -8
  51. data/db/migrate/20191119013236_create_ecom_core_work_product_templates.rb +0 -15
  52. data/db/migrate/20191119021405_create_ecom_core_project_templates.rb +15 -0
  53. data/db/migrate/20191119034319_create_ecom_core_project_work_item_templates.rb +20 -0
  54. data/db/migrate/20191201145849_create_ecom_core_sites.rb +16 -0
  55. data/db/migrate/20191202222210_create_ecom_core_work_packages.rb +12 -0
  56. data/db/migrate/20191202235434_create_ecom_core_work_products.rb +2 -17
  57. data/db/migrate/20191207103730_create_ecom_core_lookahead_plans.rb +19 -0
  58. data/db/migrate/20191207103735_create_ecom_core_tasks.rb +15 -10
  59. data/db/migrate/20191225140433_create_ecom_core_attendance_sheets.rb +4 -4
  60. data/db/migrate/20200126081005_create_ecom_core_payrolls.rb +3 -3
  61. data/db/migrate/20200410090701_create_ecom_core_overtime_sheets.rb +4 -4
  62. data/db/migrate/20200616044231_create_ecom_core_material_sub_types.rb +14 -0
  63. data/db/migrate/20200616051902_create_ecom_core_material_identities.rb +17 -0
  64. data/db/migrate/20200618105233_create_ecom_core_material_items.rb +16 -0
  65. data/db/migrate/20200813165555_create_ecom_core_available_unit_of_measurements.rb +16 -0
  66. data/db/migrate/20200901085227_create_ecom_core_crew_contracts.rb +7 -1
  67. data/db/migrate/20200919085613_create_ecom_core_job_cards.rb +1 -0
  68. data/db/migrate/20201013072924_create_ecom_core_crew_contract_transactions.rb +16 -0
  69. data/db/migrate/20201013090609_create_ecom_core_site_crews.rb.rb +22 -0
  70. data/db/migrate/20201013094100_create_ecom_core_crew_id_cards.rb +16 -0
  71. data/db/migrate/20201113050953_create_ecom_core_task_inspection_checklists.rb +22 -0
  72. data/db/migrate/20201113094302_create_ecom_core_task_template_inspection_checklists.rb +17 -0
  73. data/db/migrate/20201121064916_create_ecom_core_unit_costs.rb +30 -0
  74. data/db/migrate/20201122123227_create_ecom_core_lookahead_plan_backlogs.rb +18 -0
  75. data/db/migrate/20201122170645_create_ecom_core_lookahead_plan_histories.rb +21 -0
  76. data/db/migrate/20201122170724_create_ecom_core_lookahead_plan_task_progresses.rb +21 -0
  77. data/db/migrate/20201123134917_create_ecom_core_task_attachments.rb +15 -0
  78. data/db/migrate/20201124171642_create_ecom_core_lookahead_plan_review_times.rb +17 -0
  79. data/db/migrate/20201125191158_create_ecom_core_work_item_resource_requirement_templates.rb +31 -0
  80. data/db/migrate/20201126191334_create_ecom_core_resource_requisitions.rb +23 -0
  81. data/db/migrate/20201126191349_create_ecom_core_resource_requisition_items.rb +33 -0
  82. data/lib/ecom/core/version.rb +1 -1
  83. data/spec/factories/ecom/core/attendance_sheets.rb +1 -1
  84. data/spec/factories/ecom/core/available_unit_of_measurements.rb +6 -0
  85. data/spec/factories/ecom/core/crew_contract_transactions.rb +8 -0
  86. data/spec/factories/ecom/core/crew_contracts.rb +12 -0
  87. data/spec/factories/ecom/core/crew_id_cards.rb +8 -0
  88. data/spec/factories/{dimension_elements.rb → ecom/core/dimension_elements.rb} +0 -0
  89. data/spec/factories/ecom/core/inspection_checklists.rb +5 -0
  90. data/spec/factories/ecom/core/lookahead_plan_histories.rb +9 -0
  91. data/spec/factories/ecom/core/lookahead_plan_review_times.rb +8 -0
  92. data/spec/factories/ecom/core/lookahead_plan_task_progresses.rb +9 -0
  93. data/spec/factories/ecom/core/lookahead_plans.rb +10 -0
  94. data/spec/factories/ecom/core/material_identities.rb +6 -0
  95. data/spec/factories/ecom/core/material_items.rb +6 -0
  96. data/spec/factories/ecom/core/material_sub_types.rb +6 -0
  97. data/spec/factories/ecom/core/materials.rb +5 -0
  98. data/spec/factories/{measurement_units.rb → ecom/core/measurement_units.rb} +6 -0
  99. data/spec/factories/ecom/core/overtime_sheets.rb +1 -1
  100. data/spec/factories/ecom/core/payrolls.rb +1 -1
  101. data/spec/factories/ecom/core/project_templates.rb +8 -0
  102. data/spec/factories/ecom/core/project_work_item_templates.rb +7 -0
  103. data/spec/factories/ecom/core/resource_requisition_items.rb +12 -0
  104. data/spec/factories/ecom/core/resource_requisitions.rb +9 -0
  105. data/spec/factories/ecom/core/site_crews.rb +10 -0
  106. data/spec/factories/ecom/core/sites.rb +8 -0
  107. data/spec/factories/ecom/core/task_attachments.rb +8 -0
  108. data/spec/factories/ecom/core/task_inspection_checklists.rb +11 -0
  109. data/spec/factories/ecom/core/task_template_inspection_checklists.rb +7 -0
  110. data/spec/factories/ecom/core/task_templates.rb +11 -6
  111. data/spec/factories/ecom/core/tasks.rb +9 -3
  112. data/spec/factories/ecom/core/unit_costs.rb +13 -0
  113. data/spec/factories/ecom/core/unit_of_measures.rb +7 -0
  114. data/spec/factories/ecom/core/work_item_resource_requirement_templates.rb +10 -0
  115. data/spec/factories/ecom/core/work_packages.rb +6 -0
  116. data/spec/factories/ecom/core/work_product_templates.rb +0 -1
  117. data/spec/factories/ecom/core/work_products.rb +1 -7
  118. metadata +130 -23
  119. data/app/controllers/concerns/ecom/core/filterable.rb +0 -14
  120. data/app/models/ecom/core/plan.rb +0 -18
  121. data/app/models/ecom/core/takeoff_calculator.rb +0 -115
  122. data/app/models/ecom/core/task_step.rb +0 -85
  123. data/app/models/ecom/core/task_step_dependency.rb +0 -10
  124. data/app/services/ecom/core/project_crew_service.rb +0 -39
  125. data/db/migrate/20191119012027_create_ecom_core_takeoff_calculators.rb +0 -11
  126. data/db/migrate/20191207103730_create_ecom_core_plans.rb +0 -12
  127. data/db/migrate/20191225121850_create_ecom_core_project_crews.rb +0 -19
  128. data/db/migrate/20200820123719_create_ecom_core_task_steps.rb +0 -17
  129. data/db/migrate/20200821130934_create_ecom_core_task_step_dependencies.rb +0 -16
  130. data/db/migrate/20200922044959_add_costs_approved_to_job_card.rb +0 -5
  131. data/spec/factories/ecom/core/plans.rb +0 -8
  132. data/spec/factories/ecom/core/project_crews.rb +0 -9
  133. data/spec/factories/ecom/core/takeoff_calculators.rb +0 -18
  134. data/spec/factories/ecom/core/task_step_dependencies.rb +0 -6
  135. data/spec/factories/ecom/core/task_steps.rb +0 -8
@@ -0,0 +1,6 @@
1
+ module Ecom
2
+ module Core
3
+ class Material < Lookup
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,21 @@
1
+ module Ecom
2
+ module Core
3
+ class MaterialIdentity < ApplicationRecord
4
+ belongs_to :material_type
5
+ belongs_to :material_sub_type, optional: true
6
+
7
+ validates :material_type_id, :material_type, presence: true
8
+ validate :material_category_hierarchy_validator
9
+
10
+ def material_category_hierarchy_validator
11
+ return if material_type_id.nil? || material_sub_type_id.nil?
12
+
13
+ material_sub_type = MaterialSubType.find_by(id: material_sub_type_id)
14
+
15
+ return unless material_sub_type.material_type_id != material_type_id
16
+
17
+ errors.add(:material_type, 'The given material_sub_type does not belong to the given material_type')
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ module Ecom
2
+ module Core
3
+ class MaterialItem < ApplicationRecord
4
+ before_save :assign_serial_number
5
+
6
+ belongs_to :material_identity
7
+
8
+ validates :serial_number, presence: true, uniqueness: true
9
+ validates :material_identity_id, :material_identity, presence: true
10
+ validates :serial_number, format: { with: /^SN_\d+$/, message: 'Invalid serial number format', multiline: true }
11
+ validates :price, numericality: { greater_than: 0 }, allow_nil: true
12
+
13
+ def assign_serial_number
14
+ self.serial_number = "SN_#{(Time.now.to_f * 1000).to_i}"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ module Ecom
2
+ module Core
3
+ class MaterialSubType < ApplicationRecord
4
+ after_save :create_material_identity
5
+
6
+ belongs_to :material_type
7
+ has_many :material_identity
8
+
9
+ validates :name, presence: true, uniqueness: { case_sensitive: false, scope: :material_type_id }
10
+ validates :material_type_id, :material_type, presence: true
11
+
12
+ def create_material_identity
13
+ Ecom::Core::MaterialIdentity.create(
14
+ material_type_id: material_type_id,
15
+ material_sub_type_id: id
16
+ )
17
+ end
18
+ end
19
+ end
20
+ end
@@ -28,7 +28,10 @@ module Ecom
28
28
  validates :physical_quantity, inclusion: PHYSICAL_QUANTITIES
29
29
 
30
30
  validate :si_unit_with_conversion_factor
31
- validate :si_unit_system_of_measurement_and_physical_quantity
31
+ validates_uniqueness_of :is_si_unit, scope: %i[physical_quantity system_of_measurement],
32
+ if: -> { is_si_unit == true },
33
+ message: 'There exist an si unit of measurement for the '\
34
+ 'given physical quantity and system of measurement'
32
35
 
33
36
  def si_unit_with_conversion_factor
34
37
  if is_si_unit && conversion_factor != 1
@@ -37,19 +40,6 @@ module Ecom
37
40
  errors.add(:base, 'Only SI units can have a conversion factor 1')
38
41
  end
39
42
  end
40
-
41
- # scope si unit with system of measurement and physical quantity
42
- def si_unit_system_of_measurement_and_physical_quantity
43
- return if system_of_measurement.nil? || physical_quantity.nil?
44
-
45
- existing_record = MeasurementUnit
46
- .where(system_of_measurement: system_of_measurement,
47
- physical_quantity: physical_quantity, is_si_unit: true).first
48
- return unless (new_record? && existing_record.present?) || (persisted? && existing_record != self)
49
-
50
- errors.add(:is_si_unit,
51
- 'There exist an si unit of measurement for the given physical quantity and system of measurement')
52
- end
53
43
  end
54
44
  end
55
45
  end
@@ -1,39 +1,37 @@
1
1
  module Ecom
2
2
  module Core
3
3
  class OvertimeSheet < ApplicationRecord
4
- validates :date, :opened_at, presence: true, uniqueness: { scope: :project_id }
4
+ validates :date, :opened_at, presence: true, uniqueness: { scope: :site_id }
5
5
  validates :status, inclusion: StatusConstants::STATUSES
6
6
 
7
- belongs_to :project
7
+ belongs_to :site
8
8
 
9
9
  has_many :overtime_sheet_entries
10
10
  has_many :crew_overtimes, through: :overtime_sheet_entries
11
11
 
12
- scope :by_project, ->(id) { where(project_id: id) }
12
+ scope :by_site, ->(id) { where(site_id: id) }
13
13
  scope :by_date, ->(date) { where(date: date) }
14
14
  scope :by_status, ->(status) { where(status: status) }
15
15
  scope :by_date_between, ->(from, to) { where('date BETWEEN ? AND ?', from, to) }
16
- # scope :open, ->(id) { where(status: StatusConstants::OPEN, project_id: id) }
17
- # scope :submitted, ->(id) { where(status: StatusConstants::SUBMITTED, project_id: id) }
18
16
 
19
- def self.open_exists?(project_id)
17
+ def self.open_exists?(site_id)
20
18
  OvertimeSheet
21
- .by_project(project_id)
19
+ .by_site(site_id)
22
20
  .by_status(StatusConstants::OPEN)
23
21
  .exists?
24
22
  end
25
23
 
26
- def self.open_for_date_exists?(date, project_id)
24
+ def self.open_for_date_exists?(date, site_id)
27
25
  OvertimeSheet
28
- .by_project(project_id)
26
+ .by_site(site_id)
29
27
  .by_status(StatusConstants::OPEN)
30
28
  .by_date(date)
31
29
  .exists?
32
30
  end
33
31
 
34
- def self.exists_for_date?(date, project_id)
32
+ def self.exists_for_date?(date, site_id)
35
33
  OvertimeSheet
36
- .by_project(project_id)
34
+ .by_site(site_id)
37
35
  .by_date(date)
38
36
  .exists?
39
37
  end
@@ -43,16 +41,18 @@ module Ecom
43
41
  # check if there is an open overtime already,
44
42
  # and also that we have only one open overtime
45
43
  # sheet at a time.
46
- def self.create_new(date, project_id)
47
- if OvertimeSheet.exists_for_date?(date, project_id)
44
+ def self.create_new(date, site_id)
45
+ if OvertimeSheet.exists_for_date?(date, site_id)
48
46
  raise 'There is already an overtime sheet for the selected date.'
49
47
  end
50
48
 
51
- if OvertimeSheet.open_exists?(project_id)
52
- raise 'There is already an open overtime sheet. It has to be submitted before creating a new one.'
49
+ if OvertimeSheet.open_exists?(site_id)
50
+ open_overtime_sheet = OvertimeSheet.find_by(status: 'Open')
51
+ raise "There is already an open overtime sheet for #{open_overtime_sheet.date}.
52
+ It has to be submitted before creating a new one."
53
53
  end
54
54
 
55
- OvertimeSheet.create(date: date, opened_at: Time.now, status: StatusConstants::OPEN, project_id: project_id)
55
+ OvertimeSheet.create(date: date, opened_at: Time.now, status: StatusConstants::OPEN, site_id: site_id)
56
56
  end
57
57
 
58
58
  def submit
@@ -4,9 +4,9 @@ module Ecom
4
4
  validates :month, :year, presence: true
5
5
 
6
6
  has_many :payments, class_name: 'Ecom::Core::Payment'
7
- belongs_to :project
7
+ belongs_to :site
8
8
 
9
- scope :by_project, ->(id) { where(project_id: id) }
9
+ scope :by_site, ->(id) { where(site_id: id) }
10
10
  scope :by_month, ->(month) { where(month: month) }
11
11
  scope :by_year, ->(year) { where(year: year) }
12
12
 
@@ -17,7 +17,7 @@ module Ecom
17
17
  m = 1
18
18
  y += 1
19
19
  end
20
- Payroll.create(month: m, year: y, project_id: project_id)
20
+ Payroll.create(month: m, year: y, site_id: site_id)
21
21
  end
22
22
  end
23
23
  end
@@ -9,9 +9,6 @@ module Ecom
9
9
  belongs_to :currency
10
10
  belongs_to :company
11
11
 
12
- has_many :project_crews
13
- has_many :crews, through: :project_crews
14
-
15
12
  validates :name, :location, :contract_number, :date_contract_signed, :commencement_date, :completion_date,
16
13
  :contract_amount, :advance_payment, :retention, presence: true
17
14
  end
@@ -0,0 +1,13 @@
1
+ module Ecom
2
+ module Core
3
+ class ProjectTemplate < ApplicationRecord
4
+ belongs_to :task_template_type
5
+ has_many :project_work_item_templates
6
+
7
+ validates :code, :name, presence: true
8
+ validates_uniqueness_of :code
9
+
10
+ delegate(:name, to: :task_template_type, prefix: true)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ module Ecom
2
+ module Core
3
+ class ProjectWorkItemTemplate < ApplicationRecord
4
+ belongs_to :task_template
5
+ belongs_to :work_product_template
6
+ belongs_to :project_template
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ module Ecom
2
+ module Core
3
+ class ResourceRequisition < ApplicationRecord
4
+ DRAFT = 'Draft'.freeze
5
+ SUBMITTED = 'Submitted'.freeze
6
+ APPROVED = 'Approved'.freeze
7
+ REJECTED = 'Rejected'.freeze
8
+
9
+ STATUSES = [DRAFT, SUBMITTED, APPROVED, REJECTED].freeze
10
+
11
+ belongs_to :lookahead_plan
12
+ belongs_to :reviewed_by, class_name: 'Ecom::Core::User', optional: true
13
+ belongs_to :approved_by, class_name: 'Ecom::Core::User', optional: true
14
+ has_many :resource_requisition_items
15
+
16
+ validates :delivery_point, presence: true
17
+
18
+ validates :status, presence: true, inclusion: STATUSES
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,45 @@
1
+ module Ecom
2
+ module Core
3
+ class ResourceRequisitionItem < ApplicationRecord
4
+ PENDING = 'Pending'.freeze
5
+ APPROVED = 'Approved'.freeze
6
+ REJECTED = 'Rejected'.freeze
7
+
8
+ STATUSES = [PENDING, APPROVED, REJECTED].freeze
9
+
10
+ belongs_to :resource_requisition
11
+ belongs_to :resource_type
12
+ belongs_to :requested_quantity_measurement_unit, class_name: 'Ecom::Core::MeasurementUnit'
13
+ belongs_to :awaiting_quantity_measurement_unit, class_name: 'Ecom::Core::MeasurementUnit'
14
+
15
+ validates :due_date, presence: true
16
+
17
+ validates :requested_quantity, presence: true, numericality: { greater_than: 0 }
18
+ validates :awaiting_quantity, presence: true, numericality: { greater_than: 0 }
19
+
20
+ validates :status, presence: true, inclusion: STATUSES
21
+
22
+ validate :quantity_validator
23
+
24
+ def quantity_validator
25
+ if requested_quantity.nil? || awaiting_quantity.nil? ||
26
+ requested_quantity_measurement_unit_id.nil? ||
27
+ awaiting_quantity_measurement_unit_id.nil?
28
+ return
29
+ end
30
+
31
+ requested_quantity_measurement_unit =
32
+ Ecom::Core::MeasurementUnit.find_by(id: requested_quantity_measurement_unit_id)
33
+ awaiting_quantity_measurement_unit =
34
+ Ecom::Core::MeasurementUnit.find_by(id: awaiting_quantity_measurement_unit_id)
35
+
36
+ requested_quantity_in_si_unit = requested_quantity / requested_quantity_measurement_unit.conversion_factor
37
+ awaiting_quantity_in_si_unit = awaiting_quantity / awaiting_quantity_measurement_unit.conversion_factor
38
+
39
+ return unless awaiting_quantity_in_si_unit > requested_quantity_in_si_unit
40
+
41
+ errors.add(:awaiting_quantity, 'awaiting quantity can not be greater than requested quantity')
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,15 +1,19 @@
1
1
  module Ecom
2
2
  module Core
3
- class ProjectCrew < ApplicationRecord
3
+ class Site < ApplicationRecord
4
4
  ACTIVE = 'Active'.freeze
5
5
  INACTIVE = 'Inactive'.freeze
6
+
6
7
  STATUSES = [ACTIVE, INACTIVE].freeze
7
8
 
8
- belongs_to :project
9
- belongs_to :crew
9
+ validates :name, :project_id, :project, :address, :status, presence: true
10
10
 
11
- validates :start_date, :status, presence: true
12
11
  validates :status, inclusion: STATUSES
12
+
13
+ belongs_to :project
14
+
15
+ has_many :site_crews
16
+ has_many :crews, through: :site_crews
13
17
  end
14
18
  end
15
19
  end
@@ -0,0 +1,27 @@
1
+ module Ecom
2
+ module Core
3
+ class SiteCrew < ApplicationRecord
4
+ TEMPORARY_SITE_CREW = 'Temporary site crew'.freeze
5
+ PERMANENT_SITE_CREW = 'Permanent site crew'.freeze
6
+
7
+ SITE_CREW_TYPES = [TEMPORARY_SITE_CREW, PERMANENT_SITE_CREW].freeze
8
+
9
+ ACTIVE = 'Active'.freeze
10
+ INACTIVE = 'Inactive'.freeze
11
+ STATUSES = [ACTIVE, INACTIVE].freeze
12
+
13
+ validates :crew_id, :crew, :site_id, :site, :start_date, :site_crew_type, :status, presence: true
14
+
15
+ validates_uniqueness_of :site_id,
16
+ scope: :crew_id,
17
+ if: -> { status == 'Active' },
18
+ message: 'There can only be one record with status `Active` for a given site and crew'
19
+
20
+ validates :site_crew_type, inclusion: SITE_CREW_TYPES
21
+ validates :status, inclusion: STATUSES
22
+
23
+ belongs_to :crew
24
+ belongs_to :site
25
+ end
26
+ end
27
+ end
@@ -5,7 +5,7 @@ module Ecom
5
5
 
6
6
  validates :name, presence: true, uniqueness: true
7
7
 
8
- delegate :name, to: :stakeholder_type, prefix: true
8
+ delegate(:name, to: :stakeholder_type, prefix: true)
9
9
  end
10
10
  end
11
11
  end
@@ -5,34 +5,47 @@ module Ecom
5
5
 
6
6
  has_ancestry
7
7
 
8
+ NOT_INSPECTED = 'Not Inspected'.freeze
9
+ IN_PROGRESS = 'In Progress'.freeze
10
+ PASS = 'Pass'.freeze
11
+ FAIL = 'Fail'.freeze
12
+
13
+ INSPECTION_STATUSES = [NOT_INSPECTED, IN_PROGRESS, PASS, FAIL].freeze
14
+
8
15
  belongs_to :work_product
9
16
  belongs_to :task_template
10
17
  belongs_to :work_package, optional: true
11
18
  belongs_to :work_order, optional: true
12
- belongs_to :plan, optional: true
13
19
  belongs_to :performer, class_name: 'Ecom::Core::User', optional: true
14
- belongs_to :approver, class_name: 'Ecom::Core::User', optional: true
15
- belongs_to :supervisor, class_name: 'Ecom::Core::User', optional: true
16
- belongs_to :quality_controller, class_name: 'Ecom::Core::User', optional: true
20
+ belongs_to :client_consultant, class_name: 'Ecom::Core::User', optional: true
21
+ belongs_to :foreman, class_name: 'Ecom::Core::User', optional: true
22
+ belongs_to :inspector, class_name: 'Ecom::Core::User', optional: true
23
+ belongs_to :change_order_for, class_name: 'Ecom::Core::User', optional: true
17
24
 
18
- has_many :task_steps
19
25
  has_many :task_resources
20
26
  has_one :takeoff
27
+ has_one :change_order, foreign_key: :change_order_for_id, class_name: 'Ecom::Core::Task'
21
28
 
22
29
  validates_with DateRangeValidator
23
- validates :code, :name, :status, :percent_completed, presence: true
30
+ validates :code, :name, :status, :inspection_status, :percent_completed, presence: true
24
31
  validates_numericality_of :percent_completed,
25
32
  only_integer: true,
26
33
  greater_than_or_equal_to: 0,
27
34
  less_than_or_equal_to: 100
35
+ validates :percentage_contribution,
36
+ numericality: {
37
+ greater_than_or_equal_to: 0,
38
+ less_than_or_equal_to: 100,
39
+ only_integer: true
40
+ },
41
+ allow_nil: true
42
+
43
+ validates_inclusion_of :inspection_status, in: INSPECTION_STATUSES
28
44
 
29
45
  scope :by_status, ->(status) { where(status: status) }
30
46
 
31
- # State: planned -> The task has be planned for execution
32
- # State: ready_to_start -> All resources for the task has been set and is ready to start
33
47
  aasm column: 'status' do
34
48
  state :new, initial: true
35
- state :planned
36
49
  state :ready_to_start
37
50
  state :in_progress
38
51
  state :submitted
@@ -0,0 +1,11 @@
1
+ module Ecom
2
+ module Core
3
+ class TaskAttachment < ApplicationRecord
4
+ mount_base64_uploader :file, TaskAttachmentUploader
5
+
6
+ belongs_to :task
7
+
8
+ validates :title, presence: true
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+ module Ecom
2
+ module Core
3
+ class TaskInspectionChecklist < ApplicationRecord
4
+ NOT_INSPECTED = 'Not Inspected'.freeze
5
+ IN_PROGRESS = 'In Progress'.freeze
6
+ PASS = 'Pass'.freeze
7
+ FAIL = 'Fail'.freeze
8
+
9
+ INSPECTION_STATUSES = [NOT_INSPECTED, IN_PROGRESS, PASS, FAIL].freeze
10
+
11
+ belongs_to :inspected_by, class_name: 'Ecom::Core::User'
12
+ belongs_to :task
13
+
14
+ validates :name, :status, presence: true
15
+ validates :status, inclusion: INSPECTION_STATUSES
16
+ end
17
+ end
18
+ end