ecom_core 1.2.31 → 1.2.36

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 +15 -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/dimension_element.rb +22 -0
  12. data/app/models/ecom/core/inspection_checklist.rb +6 -0
  13. data/app/models/ecom/core/job_card.rb +1 -1
  14. data/app/models/ecom/core/lookahead_plan.rb +41 -0
  15. data/app/models/ecom/core/lookahead_plan_history.rb +16 -0
  16. data/app/models/ecom/core/lookahead_plan_review_time.rb +29 -0
  17. data/app/models/ecom/core/lookahead_plan_task_progress.rb +22 -0
  18. data/app/models/ecom/core/material.rb +6 -0
  19. data/app/models/ecom/core/material_identity.rb +21 -0
  20. data/app/models/ecom/core/material_item.rb +18 -0
  21. data/app/models/ecom/core/material_sub_type.rb +20 -0
  22. data/app/models/ecom/core/measurement_unit.rb +45 -0
  23. data/app/models/ecom/core/overtime_sheet.rb +26 -16
  24. data/app/models/ecom/core/payroll.rb +3 -3
  25. data/app/models/ecom/core/project.rb +0 -3
  26. data/app/models/ecom/core/project_template.rb +11 -0
  27. data/app/models/ecom/core/project_work_item_template.rb +9 -0
  28. data/app/models/ecom/core/resource_requisition.rb +21 -0
  29. data/app/models/ecom/core/resource_requisition_item.rb +45 -0
  30. data/app/models/ecom/core/schedule_setting.rb +8 -6
  31. data/app/models/ecom/core/{project_crew.rb → site.rb} +8 -4
  32. data/app/models/ecom/core/site_crew.rb +27 -0
  33. data/app/models/ecom/core/takeoff.rb +10 -0
  34. data/app/models/ecom/core/task.rb +28 -4
  35. data/app/models/ecom/core/task_attachment.rb +11 -0
  36. data/app/models/ecom/core/task_inspection_checklist.rb +18 -0
  37. data/app/models/ecom/core/task_resource.rb +2 -0
  38. data/app/models/ecom/core/task_template.rb +24 -2
  39. data/app/models/ecom/core/task_template_inspection_checklist.rb +8 -0
  40. data/app/models/ecom/core/unit_cost.rb +27 -0
  41. data/app/models/ecom/core/unit_of_measure.rb +8 -0
  42. data/app/models/ecom/core/work_item_resource_requirement_template.rb +18 -0
  43. data/app/models/ecom/core/work_order.rb +26 -0
  44. data/app/models/ecom/core/work_package.rb +3 -0
  45. data/app/models/ecom/core/work_product.rb +3 -18
  46. data/app/models/ecom/core/work_product_template.rb +2 -2
  47. data/app/serializers/ecom/core/unit_cost_serializer.rb +21 -0
  48. data/app/services/ecom/core/crew_contract_transaction_service.rb +89 -0
  49. data/app/services/ecom/core/site_crew_service.rb +44 -0
  50. data/app/uploaders/ecom/core/photo_uploader.rb +13 -2
  51. data/app/uploaders/ecom/core/task_attachment_uploader.rb +11 -0
  52. data/config/initializers/carrierwave.rb +9 -0
  53. data/config/routes.rb +4 -2
  54. data/db/migrate/20191118052213_create_ecom_core_unit_of_measures.rb +11 -0
  55. data/db/migrate/20191119012030_create_ecom_core_task_templates.rb +10 -1
  56. data/db/migrate/20191119013236_create_ecom_core_work_product_templates.rb +0 -15
  57. data/db/migrate/20191119021405_create_ecom_core_project_templates.rb +15 -0
  58. data/db/migrate/20191119034319_create_ecom_core_project_work_item_templates.rb +20 -0
  59. data/db/migrate/20191201145849_create_ecom_core_sites.rb +16 -0
  60. data/db/migrate/20191202222210_create_ecom_core_work_packages.rb +12 -0
  61. data/db/migrate/20191202235434_create_ecom_core_work_products.rb +2 -18
  62. data/db/migrate/{20191225100054_create_ecom_core_crews.rb → 20191207103729_create_ecom_core_crews.rb} +3 -3
  63. data/db/migrate/20191207103730_create_ecom_core_lookahead_plans.rb +19 -0
  64. data/db/migrate/20191207103731_create_ecom_core_work_orders.rb +23 -0
  65. data/db/migrate/20191207103735_create_ecom_core_tasks.rb +20 -7
  66. data/db/migrate/20191225140433_create_ecom_core_attendance_sheets.rb +4 -4
  67. data/db/migrate/20200126081005_create_ecom_core_payrolls.rb +3 -3
  68. data/db/migrate/20200410090701_create_ecom_core_overtime_sheets.rb +4 -4
  69. data/db/migrate/20200616044231_create_ecom_core_material_sub_types.rb +14 -0
  70. data/db/migrate/20200616051902_create_ecom_core_material_identities.rb +17 -0
  71. data/db/migrate/20200618105233_create_ecom_core_material_items.rb +16 -0
  72. data/db/migrate/20200813165553_create_ecom_core_measurement_units.rb +14 -0
  73. data/db/migrate/20200813165555_create_ecom_core_available_unit_of_measurements.rb +16 -0
  74. data/db/migrate/20200814043632_create_ecom_core_takeoffs.rb +14 -0
  75. data/db/migrate/20200901085227_create_ecom_core_crew_contracts.rb +7 -1
  76. data/db/migrate/20200901134912_create_ecom_core_dimension_elements.rb +23 -0
  77. data/db/migrate/20200919085613_create_ecom_core_job_cards.rb +1 -0
  78. data/db/migrate/20201013072924_create_ecom_core_crew_contract_transactions.rb +16 -0
  79. data/db/migrate/20201013090609_create_ecom_core_site_crews.rb.rb +22 -0
  80. data/db/migrate/20201013094100_create_ecom_core_crew_id_cards.rb +16 -0
  81. data/db/migrate/20201113050953_create_ecom_core_task_inspection_checklists.rb +22 -0
  82. data/db/migrate/20201113094302_create_ecom_core_task_template_inspection_checklists.rb +17 -0
  83. data/db/migrate/20201121064916_create_ecom_core_unit_costs.rb +30 -0
  84. data/db/migrate/20201122123227_create_ecom_core_lookahead_plan_backlogs.rb +18 -0
  85. data/db/migrate/20201122170645_create_ecom_core_lookahead_plan_histories.rb +21 -0
  86. data/db/migrate/20201122170724_create_ecom_core_lookahead_plan_task_progresses.rb +21 -0
  87. data/db/migrate/20201123134917_create_ecom_core_task_attachments.rb +15 -0
  88. data/db/migrate/20201124171642_create_ecom_core_lookahead_plan_review_times.rb +17 -0
  89. data/db/migrate/20201125191158_create_ecom_core_work_item_resource_requirement_templates.rb +31 -0
  90. data/db/migrate/20201126191334_create_ecom_core_resource_requisitions.rb +23 -0
  91. data/db/migrate/20201126191349_create_ecom_core_resource_requisition_items.rb +33 -0
  92. data/lib/ecom/core/version.rb +1 -1
  93. data/spec/factories/ecom/core/attendance_sheets.rb +1 -1
  94. data/spec/factories/ecom/core/available_unit_of_measurements.rb +6 -0
  95. data/spec/factories/ecom/core/crew_contract_transactions.rb +8 -0
  96. data/spec/factories/ecom/core/crew_contracts.rb +12 -0
  97. data/spec/factories/ecom/core/crew_id_cards.rb +8 -0
  98. data/spec/factories/ecom/core/dimension_elements.rb +8 -0
  99. data/spec/factories/ecom/core/inspection_checklists.rb +5 -0
  100. data/spec/factories/ecom/core/lookahead_plan_histories.rb +9 -0
  101. data/spec/factories/ecom/core/lookahead_plan_review_times.rb +8 -0
  102. data/spec/factories/ecom/core/lookahead_plan_task_progresses.rb +9 -0
  103. data/spec/factories/ecom/core/lookahead_plans.rb +10 -0
  104. data/spec/factories/ecom/core/maintenance_statuses.rb +1 -1
  105. data/spec/factories/ecom/core/material_identities.rb +6 -0
  106. data/spec/factories/ecom/core/material_items.rb +6 -0
  107. data/spec/factories/ecom/core/material_sub_types.rb +6 -0
  108. data/spec/factories/ecom/core/materials.rb +5 -0
  109. data/spec/factories/ecom/core/measurement_units.rb +16 -0
  110. data/spec/factories/ecom/core/overtime_sheets.rb +1 -1
  111. data/spec/factories/ecom/core/payrolls.rb +1 -1
  112. data/spec/factories/ecom/core/project_templates.rb +8 -0
  113. data/spec/factories/ecom/core/project_work_item_templates.rb +7 -0
  114. data/spec/factories/ecom/core/resource_requisition_items.rb +12 -0
  115. data/spec/factories/ecom/core/resource_requisitions.rb +9 -0
  116. data/spec/factories/ecom/core/site_crews.rb +10 -0
  117. data/spec/factories/ecom/core/sites.rb +8 -0
  118. data/spec/factories/ecom/core/takeoffs.rb +6 -0
  119. data/spec/factories/ecom/core/task_attachments.rb +8 -0
  120. data/spec/factories/ecom/core/task_inspection_checklists.rb +11 -0
  121. data/spec/factories/ecom/core/task_template_inspection_checklists.rb +7 -0
  122. data/spec/factories/ecom/core/task_templates.rb +12 -1
  123. data/spec/factories/ecom/core/tasks.rb +9 -3
  124. data/spec/factories/ecom/core/unit_costs.rb +13 -0
  125. data/spec/factories/ecom/core/unit_of_measures.rb +7 -0
  126. data/spec/factories/ecom/core/work_item_resource_requirement_templates.rb +10 -0
  127. data/spec/factories/ecom/core/work_orders.rb +10 -0
  128. data/spec/factories/ecom/core/work_packages.rb +6 -0
  129. data/spec/factories/ecom/core/work_product_templates.rb +0 -1
  130. data/spec/factories/ecom/core/work_products.rb +1 -8
  131. metadata +155 -9
  132. data/app/services/ecom/core/project_crew_service.rb +0 -39
  133. data/db/migrate/20191225121850_create_ecom_core_project_crews.rb +0 -19
  134. data/db/migrate/20200922044959_add_costs_approved_to_job_card.rb +0 -5
  135. data/spec/factories/ecom/core/project_crews.rb +0 -9
@@ -0,0 +1,22 @@
1
+ module Ecom
2
+ module Core
3
+ class LookaheadPlanTaskProgress < ApplicationRecord
4
+ belongs_to :lookahead_plan
5
+ belongs_to :task
6
+
7
+ validates :lookahead_plan_id, :lookahead_plan, :task_id, :task, :started_on, :ended_on,
8
+ :lookahead_plan_revision_number, presence: true
9
+
10
+ validates_numericality_of :lookahead_plan_revision_number,
11
+ greater_than_or_equal_to: 0
12
+
13
+ validate :date_range_validator
14
+
15
+ def date_range_validator
16
+ return unless started_on && ended_on && started_on > ended_on
17
+
18
+ errors.add(:base, 'Ended on cannot be before started on')
19
+ end
20
+ end
21
+ end
22
+ end
@@ -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
@@ -0,0 +1,45 @@
1
+ module Ecom
2
+ module Core
3
+ class MeasurementUnit < ApplicationRecord
4
+ METRIC = 'Metric'.freeze
5
+ IMPERIAL = 'Imperial'.freeze
6
+ SYSTEM_OF_MEASURMENT = [METRIC, IMPERIAL].freeze
7
+
8
+ # commonly used physical quantities in construction
9
+ LENGTH = 'Length'.freeze
10
+ MASS = 'Mass'.freeze
11
+ TIME = 'Time'.freeze
12
+ CURRENT = 'Current'.freeze
13
+ TEMPRATURE = 'Temprature'.freeze
14
+
15
+ AREA = 'Area'.freeze
16
+ VOLUME = 'Volume'.freeze
17
+ ENERGY = 'Energy'.freeze
18
+ DENSITY = 'DENSITY'.freeze
19
+
20
+ PHYSICAL_QUANTITIES = [LENGTH, MASS, TIME, CURRENT, TEMPRATURE, AREA, VOLUME, ENERGY, DENSITY].freeze
21
+
22
+ validates :name, :abbrivation, :physical_quantity,
23
+ :conversion_factor, :system_of_measurement, presence: true
24
+
25
+ validates :is_si_unit, inclusion: { in: [true, false] }
26
+
27
+ validates :system_of_measurement, inclusion: SYSTEM_OF_MEASURMENT
28
+ validates :physical_quantity, inclusion: PHYSICAL_QUANTITIES
29
+
30
+ validate :si_unit_with_conversion_factor
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'
35
+
36
+ def si_unit_with_conversion_factor
37
+ if is_si_unit && conversion_factor != 1
38
+ errors.add(:base, 'Conversion factor for an SI unit has to be 1')
39
+ elsif !is_si_unit && conversion_factor == 1
40
+ errors.add(:base, 'Only SI units can have a conversion factor 1')
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,31 +1,39 @@
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)
20
- OvertimeSheet.open(project_id).exists?
17
+ def self.open_exists?(site_id)
18
+ OvertimeSheet
19
+ .by_site(site_id)
20
+ .by_status(StatusConstants::OPEN)
21
+ .exists?
21
22
  end
22
23
 
23
- def self.open_for_date_exists?(date, project_id)
24
- OvertimeSheet.open(project_id).where(date: date).exists?
24
+ def self.open_for_date_exists?(date, site_id)
25
+ OvertimeSheet
26
+ .by_site(site_id)
27
+ .by_status(StatusConstants::OPEN)
28
+ .by_date(date)
29
+ .exists?
25
30
  end
26
31
 
27
- def self.exists_for_date?(date, project_id)
28
- OvertimeSheet.by_project(project_id).by_date(date).exists?
32
+ def self.exists_for_date?(date, site_id)
33
+ OvertimeSheet
34
+ .by_site(site_id)
35
+ .by_date(date)
36
+ .exists?
29
37
  end
30
38
 
31
39
  # Overtime sheet should be created using the
@@ -33,16 +41,18 @@ module Ecom
33
41
  # check if there is an open overtime already,
34
42
  # and also that we have only one open overtime
35
43
  # sheet at a time.
36
- def self.create_new(date, project_id)
37
- 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)
38
46
  raise 'There is already an overtime sheet for the selected date.'
39
47
  end
40
48
 
41
- if OvertimeSheet.open_exists?(project_id)
42
- 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."
43
53
  end
44
54
 
45
- 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)
46
56
  end
47
57
 
48
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,11 @@
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
+ end
10
+ end
11
+ 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,9 +1,11 @@
1
- module Ecom::Core
2
- class ScheduleSetting < ApplicationRecord
3
- belongs_to :equipment
4
- belongs_to :maintenance_type
5
- belongs_to :schedule_unit
1
+ module Ecom
2
+ module Core
3
+ class ScheduleSetting < ApplicationRecord
4
+ belongs_to :equipment
5
+ belongs_to :maintenance_type
6
+ belongs_to :schedule_unit
6
7
 
7
- validates :value, presence: true
8
+ validates :value, presence: true
9
+ end
8
10
  end
9
11
  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
@@ -0,0 +1,10 @@
1
+ module Ecom
2
+ module Core
3
+ class Takeoff < ApplicationRecord
4
+ validates :task_id, :takeoff_quantity, :task, presence: true
5
+ validates :takeoff_quantity, numericality: { greater_than: 0 }
6
+
7
+ belongs_to :task
8
+ end
9
+ end
10
+ end
@@ -5,24 +5,48 @@ 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
18
+ belongs_to :work_order, optional: true
11
19
  belongs_to :performer, class_name: 'Ecom::Core::User', optional: true
12
- belongs_to :approver, class_name: 'Ecom::Core::User', optional: true
13
- belongs_to :supervisor, class_name: 'Ecom::Core::User', optional: true
14
- 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
15
24
 
16
- validates :code, :name, :status, :percent_completed, presence: true
25
+ has_many :task_resources
26
+ has_one :takeoff
27
+ has_one :change_order, foreign_key: :change_order_for_id, class_name: 'Ecom::Core::Task'
28
+
29
+ validates_with DateRangeValidator
30
+ validates :code, :name, :status, :inspection_status, :percent_completed, presence: true
17
31
  validates_numericality_of :percent_completed,
18
32
  only_integer: true,
19
33
  greater_than_or_equal_to: 0,
20
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
21
44
 
22
45
  scope :by_status, ->(status) { where(status: status) }
23
46
 
24
47
  aasm column: 'status' do
25
48
  state :new, initial: true
49
+ state :ready_to_start
26
50
  state :in_progress
27
51
  state :submitted
28
52
  state :under_review