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.
- checksums.yaml +4 -4
- data/app/controllers/ecom/core/{project_crews_controller.rb → site_crews_controller.rb} +5 -4
- data/app/controllers/ecom/core/unit_costs_controller.rb +29 -0
- data/app/models/ecom/core/attendance_sheet.rb +19 -19
- data/app/models/ecom/core/available_unit_of_measurement.rb +10 -0
- data/app/models/ecom/core/crew.rb +6 -3
- data/app/models/ecom/core/crew_contract.rb +41 -1
- data/app/models/ecom/core/crew_contract_transaction.rb +29 -0
- data/app/models/ecom/core/crew_id_card.rb +36 -0
- data/app/models/ecom/core/crew_time.rb +1 -1
- data/app/models/ecom/core/inspection_checklist.rb +6 -0
- data/app/models/ecom/core/lookahead_plan.rb +41 -0
- data/app/models/ecom/core/lookahead_plan_history.rb +16 -0
- data/app/models/ecom/core/lookahead_plan_review_time.rb +29 -0
- data/app/models/ecom/core/lookahead_plan_task_progress.rb +22 -0
- data/app/models/ecom/core/material.rb +6 -0
- data/app/models/ecom/core/material_identity.rb +21 -0
- data/app/models/ecom/core/material_item.rb +18 -0
- data/app/models/ecom/core/material_sub_type.rb +20 -0
- data/app/models/ecom/core/measurement_unit.rb +4 -14
- data/app/models/ecom/core/overtime_sheet.rb +16 -16
- data/app/models/ecom/core/payroll.rb +3 -3
- data/app/models/ecom/core/project.rb +0 -3
- data/app/models/ecom/core/project_template.rb +13 -0
- data/app/models/ecom/core/project_work_item_template.rb +9 -0
- data/app/models/ecom/core/resource_requisition.rb +21 -0
- data/app/models/ecom/core/resource_requisition_item.rb +45 -0
- data/app/models/ecom/core/{project_crew.rb → site.rb} +8 -4
- data/app/models/ecom/core/site_crew.rb +27 -0
- data/app/models/ecom/core/stakeholder.rb +1 -1
- data/app/models/ecom/core/task.rb +22 -9
- data/app/models/ecom/core/task_attachment.rb +11 -0
- data/app/models/ecom/core/task_inspection_checklist.rb +18 -0
- data/app/models/ecom/core/task_template.rb +20 -90
- data/app/models/ecom/core/task_template_inspection_checklist.rb +8 -0
- data/app/models/ecom/core/unit_cost.rb +27 -0
- data/app/models/ecom/core/unit_of_measure.rb +8 -0
- data/app/models/ecom/core/work_item_resource_requirement_template.rb +18 -0
- data/app/models/ecom/core/work_package.rb +3 -0
- data/app/models/ecom/core/work_product.rb +2 -18
- data/app/models/ecom/core/work_product_template.rb +2 -2
- data/app/serializers/ecom/core/unit_cost_serializer.rb +21 -0
- data/app/services/ecom/core/crew_contract_transaction_service.rb +89 -0
- data/app/services/ecom/core/site_crew_service.rb +44 -0
- data/app/uploaders/ecom/core/photo_uploader.rb +13 -2
- data/app/uploaders/ecom/core/task_attachment_uploader.rb +11 -0
- data/config/initializers/carrierwave.rb +9 -0
- data/config/routes.rb +4 -2
- data/db/migrate/20191118052213_create_ecom_core_unit_of_measures.rb +11 -0
- data/db/migrate/20191119012030_create_ecom_core_task_templates.rb +10 -8
- data/db/migrate/20191119013236_create_ecom_core_work_product_templates.rb +0 -15
- data/db/migrate/20191119021405_create_ecom_core_project_templates.rb +15 -0
- data/db/migrate/20191119034319_create_ecom_core_project_work_item_templates.rb +20 -0
- data/db/migrate/20191201145849_create_ecom_core_sites.rb +16 -0
- data/db/migrate/20191202222210_create_ecom_core_work_packages.rb +12 -0
- data/db/migrate/20191202235434_create_ecom_core_work_products.rb +2 -17
- data/db/migrate/20191207103730_create_ecom_core_lookahead_plans.rb +19 -0
- data/db/migrate/20191207103735_create_ecom_core_tasks.rb +15 -10
- data/db/migrate/20191225140433_create_ecom_core_attendance_sheets.rb +4 -4
- data/db/migrate/20200126081005_create_ecom_core_payrolls.rb +3 -3
- data/db/migrate/20200410090701_create_ecom_core_overtime_sheets.rb +4 -4
- data/db/migrate/20200616044231_create_ecom_core_material_sub_types.rb +14 -0
- data/db/migrate/20200616051902_create_ecom_core_material_identities.rb +17 -0
- data/db/migrate/20200618105233_create_ecom_core_material_items.rb +16 -0
- data/db/migrate/20200813165555_create_ecom_core_available_unit_of_measurements.rb +16 -0
- data/db/migrate/20200901085227_create_ecom_core_crew_contracts.rb +7 -1
- data/db/migrate/20200919085613_create_ecom_core_job_cards.rb +1 -0
- data/db/migrate/20201013072924_create_ecom_core_crew_contract_transactions.rb +16 -0
- data/db/migrate/20201013090609_create_ecom_core_site_crews.rb.rb +22 -0
- data/db/migrate/20201013094100_create_ecom_core_crew_id_cards.rb +16 -0
- data/db/migrate/20201113050953_create_ecom_core_task_inspection_checklists.rb +22 -0
- data/db/migrate/20201113094302_create_ecom_core_task_template_inspection_checklists.rb +17 -0
- data/db/migrate/20201121064916_create_ecom_core_unit_costs.rb +30 -0
- data/db/migrate/20201122123227_create_ecom_core_lookahead_plan_backlogs.rb +18 -0
- data/db/migrate/20201122170645_create_ecom_core_lookahead_plan_histories.rb +21 -0
- data/db/migrate/20201122170724_create_ecom_core_lookahead_plan_task_progresses.rb +21 -0
- data/db/migrate/20201123134917_create_ecom_core_task_attachments.rb +15 -0
- data/db/migrate/20201124171642_create_ecom_core_lookahead_plan_review_times.rb +17 -0
- data/db/migrate/20201125191158_create_ecom_core_work_item_resource_requirement_templates.rb +31 -0
- data/db/migrate/20201126191334_create_ecom_core_resource_requisitions.rb +23 -0
- data/db/migrate/20201126191349_create_ecom_core_resource_requisition_items.rb +33 -0
- data/lib/ecom/core/version.rb +1 -1
- data/spec/factories/ecom/core/attendance_sheets.rb +1 -1
- data/spec/factories/ecom/core/available_unit_of_measurements.rb +6 -0
- data/spec/factories/ecom/core/crew_contract_transactions.rb +8 -0
- data/spec/factories/ecom/core/crew_contracts.rb +12 -0
- data/spec/factories/ecom/core/crew_id_cards.rb +8 -0
- data/spec/factories/{dimension_elements.rb → ecom/core/dimension_elements.rb} +0 -0
- data/spec/factories/ecom/core/inspection_checklists.rb +5 -0
- data/spec/factories/ecom/core/lookahead_plan_histories.rb +9 -0
- data/spec/factories/ecom/core/lookahead_plan_review_times.rb +8 -0
- data/spec/factories/ecom/core/lookahead_plan_task_progresses.rb +9 -0
- data/spec/factories/ecom/core/lookahead_plans.rb +10 -0
- data/spec/factories/ecom/core/material_identities.rb +6 -0
- data/spec/factories/ecom/core/material_items.rb +6 -0
- data/spec/factories/ecom/core/material_sub_types.rb +6 -0
- data/spec/factories/ecom/core/materials.rb +5 -0
- data/spec/factories/{measurement_units.rb → ecom/core/measurement_units.rb} +6 -0
- data/spec/factories/ecom/core/overtime_sheets.rb +1 -1
- data/spec/factories/ecom/core/payrolls.rb +1 -1
- data/spec/factories/ecom/core/project_templates.rb +8 -0
- data/spec/factories/ecom/core/project_work_item_templates.rb +7 -0
- data/spec/factories/ecom/core/resource_requisition_items.rb +12 -0
- data/spec/factories/ecom/core/resource_requisitions.rb +9 -0
- data/spec/factories/ecom/core/site_crews.rb +10 -0
- data/spec/factories/ecom/core/sites.rb +8 -0
- data/spec/factories/ecom/core/task_attachments.rb +8 -0
- data/spec/factories/ecom/core/task_inspection_checklists.rb +11 -0
- data/spec/factories/ecom/core/task_template_inspection_checklists.rb +7 -0
- data/spec/factories/ecom/core/task_templates.rb +11 -6
- data/spec/factories/ecom/core/tasks.rb +9 -3
- data/spec/factories/ecom/core/unit_costs.rb +13 -0
- data/spec/factories/ecom/core/unit_of_measures.rb +7 -0
- data/spec/factories/ecom/core/work_item_resource_requirement_templates.rb +10 -0
- data/spec/factories/ecom/core/work_packages.rb +6 -0
- data/spec/factories/ecom/core/work_product_templates.rb +0 -1
- data/spec/factories/ecom/core/work_products.rb +1 -7
- metadata +130 -23
- data/app/controllers/concerns/ecom/core/filterable.rb +0 -14
- data/app/models/ecom/core/plan.rb +0 -18
- data/app/models/ecom/core/takeoff_calculator.rb +0 -115
- data/app/models/ecom/core/task_step.rb +0 -85
- data/app/models/ecom/core/task_step_dependency.rb +0 -10
- data/app/services/ecom/core/project_crew_service.rb +0 -39
- data/db/migrate/20191119012027_create_ecom_core_takeoff_calculators.rb +0 -11
- data/db/migrate/20191207103730_create_ecom_core_plans.rb +0 -12
- data/db/migrate/20191225121850_create_ecom_core_project_crews.rb +0 -19
- data/db/migrate/20200820123719_create_ecom_core_task_steps.rb +0 -17
- data/db/migrate/20200821130934_create_ecom_core_task_step_dependencies.rb +0 -16
- data/db/migrate/20200922044959_add_costs_approved_to_job_card.rb +0 -5
- data/spec/factories/ecom/core/plans.rb +0 -8
- data/spec/factories/ecom/core/project_crews.rb +0 -9
- data/spec/factories/ecom/core/takeoff_calculators.rb +0 -18
- data/spec/factories/ecom/core/task_step_dependencies.rb +0 -6
- data/spec/factories/ecom/core/task_steps.rb +0 -8
|
@@ -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
|
-
|
|
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: :
|
|
4
|
+
validates :date, :opened_at, presence: true, uniqueness: { scope: :site_id }
|
|
5
5
|
validates :status, inclusion: StatusConstants::STATUSES
|
|
6
6
|
|
|
7
|
-
belongs_to :
|
|
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 :
|
|
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?(
|
|
17
|
+
def self.open_exists?(site_id)
|
|
20
18
|
OvertimeSheet
|
|
21
|
-
.
|
|
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,
|
|
24
|
+
def self.open_for_date_exists?(date, site_id)
|
|
27
25
|
OvertimeSheet
|
|
28
|
-
.
|
|
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,
|
|
32
|
+
def self.exists_for_date?(date, site_id)
|
|
35
33
|
OvertimeSheet
|
|
36
|
-
.
|
|
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,
|
|
47
|
-
if OvertimeSheet.exists_for_date?(date,
|
|
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?(
|
|
52
|
-
|
|
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,
|
|
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 :
|
|
7
|
+
belongs_to :site
|
|
8
8
|
|
|
9
|
-
scope :
|
|
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,
|
|
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,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
|
|
3
|
+
class Site < ApplicationRecord
|
|
4
4
|
ACTIVE = 'Active'.freeze
|
|
5
5
|
INACTIVE = 'Inactive'.freeze
|
|
6
|
+
|
|
6
7
|
STATUSES = [ACTIVE, INACTIVE].freeze
|
|
7
8
|
|
|
8
|
-
|
|
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,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 :
|
|
15
|
-
belongs_to :
|
|
16
|
-
belongs_to :
|
|
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,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
|