ecom_core 1.2.31 → 1.2.32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/concerns/ecom/core/filterable.rb +14 -0
- data/app/models/ecom/core/crew.rb +10 -1
- data/app/models/ecom/core/dimension_element.rb +22 -0
- data/app/models/ecom/core/job_card.rb +1 -1
- data/app/models/ecom/core/measurement_unit.rb +55 -0
- data/app/models/ecom/core/overtime_sheet.rb +15 -5
- data/app/models/ecom/core/plan.rb +18 -0
- data/app/models/ecom/core/schedule_setting.rb +8 -6
- data/app/models/ecom/core/takeoff.rb +10 -0
- data/app/models/ecom/core/takeoff_calculator.rb +115 -0
- data/app/models/ecom/core/task.rb +11 -0
- data/app/models/ecom/core/task_resource.rb +2 -0
- data/app/models/ecom/core/task_step.rb +85 -0
- data/app/models/ecom/core/task_step_dependency.rb +10 -0
- data/app/models/ecom/core/task_template.rb +92 -0
- data/app/models/ecom/core/work_order.rb +26 -0
- data/app/models/ecom/core/work_product.rb +1 -0
- data/db/migrate/20191119012027_create_ecom_core_takeoff_calculators.rb +11 -0
- data/db/migrate/20191119012030_create_ecom_core_task_templates.rb +7 -0
- data/db/migrate/20191202235434_create_ecom_core_work_products.rb +0 -1
- data/db/migrate/{20191225100054_create_ecom_core_crews.rb → 20191207103729_create_ecom_core_crews.rb} +3 -3
- data/db/migrate/20191207103730_create_ecom_core_plans.rb +12 -0
- data/db/migrate/20191207103731_create_ecom_core_work_orders.rb +23 -0
- data/db/migrate/20191207103735_create_ecom_core_tasks.rb +9 -1
- data/db/migrate/20200813165553_create_ecom_core_measurement_units.rb +14 -0
- data/db/migrate/20200814043632_create_ecom_core_takeoffs.rb +14 -0
- data/db/migrate/20200820123719_create_ecom_core_task_steps.rb +17 -0
- data/db/migrate/20200821130934_create_ecom_core_task_step_dependencies.rb +16 -0
- data/db/migrate/20200901134912_create_ecom_core_dimension_elements.rb +23 -0
- data/lib/ecom/core/version.rb +1 -1
- data/spec/factories/dimension_elements.rb +8 -0
- data/spec/factories/ecom/core/maintenance_statuses.rb +1 -1
- data/spec/factories/ecom/core/plans.rb +8 -0
- data/spec/factories/ecom/core/takeoff_calculators.rb +18 -0
- data/spec/factories/ecom/core/takeoffs.rb +6 -0
- data/spec/factories/ecom/core/task_step_dependencies.rb +6 -0
- data/spec/factories/ecom/core/task_steps.rb +8 -0
- data/spec/factories/ecom/core/task_templates.rb +6 -0
- data/spec/factories/ecom/core/work_orders.rb +10 -0
- data/spec/factories/ecom/core/work_products.rb +0 -1
- data/spec/factories/measurement_units.rb +10 -0
- metadata +42 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 18c07bbf068fb4b629257c21df23a45979e0d1f505e4002d0477d3a37926549d
|
4
|
+
data.tar.gz: 2c4efc8c1e021bbf12a87805a78722d3d1e093e8a3e53f9a75f7246c665a888d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11bbca4344928bcd49f1256c6566b135467a943458be8744e78d11af0dd1626187a68a93655ee3d875a9938a4f5e87000b8c58fb4a216d0a6da5ff918997059e
|
7
|
+
data.tar.gz: 587ff863a59b121e6184f2db3226b1159c3fbafb536a49d08ec82937bf858a9f307eff4ff4b7eaeb340c850100fd22c4e82e616ec667eaef9b48068abb862f9a
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Ecom
|
2
|
+
module Core
|
3
|
+
module Filterable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def filter(filtering_params)
|
8
|
+
results = where(nil)
|
9
|
+
results.public_send('filter_by_condition', filtering_params) if filtering_params.present?
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -10,9 +10,11 @@ module Ecom
|
|
10
10
|
before_save :set_employment_date,
|
11
11
|
if: proc { |c| c.employment_date.nil? }
|
12
12
|
|
13
|
+
after_save :set_employee_id
|
14
|
+
|
13
15
|
belongs_to :crew_type
|
14
16
|
|
15
|
-
validates :name, :address, :qualification, :employment, :wage, :
|
17
|
+
validates :name, :address, :qualification, :employment, :wage, :guarantor_name, :guarantor_phone, presence: true
|
16
18
|
validates :employment, inclusion: EMPLOYMENT_TYPES
|
17
19
|
|
18
20
|
has_many :project_crews
|
@@ -25,6 +27,13 @@ module Ecom
|
|
25
27
|
def set_employment_date
|
26
28
|
self.employment_date = Date.today
|
27
29
|
end
|
30
|
+
|
31
|
+
def set_employee_id
|
32
|
+
company = Ecom::Core::Company.first
|
33
|
+
date = employment_date.to_s[0..3]
|
34
|
+
company_name = company ? company.name : ''
|
35
|
+
self.employee_id = "#{company_name}/#{employment}/#{date}/#{id}"
|
36
|
+
end
|
28
37
|
end
|
29
38
|
end
|
30
39
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Ecom
|
2
|
+
module Core
|
3
|
+
class DimensionElement < ApplicationRecord
|
4
|
+
LENGTH = 'Length'.freeze
|
5
|
+
WIDTH = 'Width'.freeze
|
6
|
+
HEIGHT = 'Height'.freeze
|
7
|
+
RADIUS = 'Radius'.freeze
|
8
|
+
DIAMETER = 'Diameter'.freeze
|
9
|
+
DIMENSION_ELEMENT_NAMES = %w[LENGTH WIDTH HEIGHT RADIUS DIAMETER].freeze
|
10
|
+
|
11
|
+
validates :work_product_id, :work_product, :measurement_unit_id, :measurement_unit,
|
12
|
+
:amount, :dimension_element_name, presence: true
|
13
|
+
|
14
|
+
validates :dimension_element_name, inclusion: DIMENSION_ELEMENT_NAMES
|
15
|
+
|
16
|
+
validates :amount, numericality: { greater_than: 0 }
|
17
|
+
|
18
|
+
belongs_to :work_product
|
19
|
+
belongs_to :measurement_unit
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,55 @@
|
|
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
|
+
validate :si_unit_system_of_measurement_and_physical_quantity
|
32
|
+
|
33
|
+
def si_unit_with_conversion_factor
|
34
|
+
if is_si_unit && conversion_factor != 1
|
35
|
+
errors.add(:base, 'Conversion factor for an SI unit has to be 1')
|
36
|
+
elsif !is_si_unit && conversion_factor == 1
|
37
|
+
errors.add(:base, 'Only SI units can have a conversion factor 1')
|
38
|
+
end
|
39
|
+
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
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -13,19 +13,29 @@ module Ecom
|
|
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) }
|
16
|
+
# scope :open, ->(id) { where(status: StatusConstants::OPEN, project_id: id) }
|
17
|
+
# scope :submitted, ->(id) { where(status: StatusConstants::SUBMITTED, project_id: id) }
|
18
18
|
|
19
19
|
def self.open_exists?(project_id)
|
20
|
-
OvertimeSheet
|
20
|
+
OvertimeSheet
|
21
|
+
.by_project(project_id)
|
22
|
+
.by_status(StatusConstants::OPEN)
|
23
|
+
.exists?
|
21
24
|
end
|
22
25
|
|
23
26
|
def self.open_for_date_exists?(date, project_id)
|
24
|
-
OvertimeSheet
|
27
|
+
OvertimeSheet
|
28
|
+
.by_project(project_id)
|
29
|
+
.by_status(StatusConstants::OPEN)
|
30
|
+
.by_date(date)
|
31
|
+
.exists?
|
25
32
|
end
|
26
33
|
|
27
34
|
def self.exists_for_date?(date, project_id)
|
28
|
-
OvertimeSheet
|
35
|
+
OvertimeSheet
|
36
|
+
.by_project(project_id)
|
37
|
+
.by_date(date)
|
38
|
+
.exists?
|
29
39
|
end
|
30
40
|
|
31
41
|
# Overtime sheet should be created using the
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Ecom
|
2
|
+
module Core
|
3
|
+
class Plan < ApplicationRecord
|
4
|
+
NEW = 'New'.freeze
|
5
|
+
READY_TO_START = 'Ready to start'.freeze
|
6
|
+
IN_PROGRESS = 'In Progress'.freeze
|
7
|
+
COMPLETED = 'Completed'.freeze
|
8
|
+
|
9
|
+
STATUSES = [NEW, READY_TO_START, IN_PROGRESS, COMPLETED].freeze
|
10
|
+
|
11
|
+
validates :name, :start_date, :end_date, :status, presence: true
|
12
|
+
|
13
|
+
validates :status, presence: true, inclusion: STATUSES
|
14
|
+
|
15
|
+
has_many :tasks
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,9 +1,11 @@
|
|
1
|
-
module Ecom
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
-
|
8
|
+
validates :value, presence: true
|
9
|
+
end
|
8
10
|
end
|
9
11
|
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module Ecom
|
2
|
+
module Core
|
3
|
+
class TakeoffCalculator < ApplicationRecord
|
4
|
+
INPUT_PARAMETERS_SCHEMA = {
|
5
|
+
'type' => 'object',
|
6
|
+
'required' => %w[name label input_type],
|
7
|
+
'additionalProperties' => false,
|
8
|
+
'properties' => {
|
9
|
+
'name' => { 'type' => 'string' },
|
10
|
+
'label' => { 'type' => 'string' },
|
11
|
+
'input_type' => {
|
12
|
+
'type' => 'string',
|
13
|
+
'enum' => %w[string number measurement enum]
|
14
|
+
}
|
15
|
+
},
|
16
|
+
"patternProperties": {
|
17
|
+
"enum_values": {
|
18
|
+
'type' => 'array'
|
19
|
+
},
|
20
|
+
"default_value": {
|
21
|
+
'type' => 'object',
|
22
|
+
'required' => %w[value],
|
23
|
+
'properties' => {
|
24
|
+
'value' => { 'type' => 'string' }
|
25
|
+
},
|
26
|
+
"patternProperties": {
|
27
|
+
"measurement_unit_id": { 'type' => 'integer' }
|
28
|
+
}
|
29
|
+
},
|
30
|
+
"validation": {
|
31
|
+
'type' => 'object',
|
32
|
+
'required' => %w[required],
|
33
|
+
'properties' => {
|
34
|
+
'required' => { 'type' => 'boolean' }
|
35
|
+
},
|
36
|
+
"patternProperties": {
|
37
|
+
"minimum": { 'type' => 'number' },
|
38
|
+
"maximum": { 'type' => 'number' }
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}.freeze
|
43
|
+
|
44
|
+
REBAR_TAKEOFF_CALCULATOR = 'Rebar Takeoff Calculator'.freeze
|
45
|
+
FORMWORK_TAKEOFF_CALCULATOR = 'Formwork Takeoff Calculator'.freeze
|
46
|
+
CONCRETE_POURING_TAKEOFF_CALCULATOR =
|
47
|
+
'Concrete Pouring Takeoff Calculator'.freeze
|
48
|
+
|
49
|
+
TAKEOFF_CALCULATOR_NAMES =
|
50
|
+
[
|
51
|
+
REBAR_TAKEOFF_CALCULATOR,
|
52
|
+
FORMWORK_TAKEOFF_CALCULATOR,
|
53
|
+
CONCRETE_POURING_TAKEOFF_CALCULATOR
|
54
|
+
].freeze
|
55
|
+
|
56
|
+
validates :name, :input_parameters, presence: true
|
57
|
+
validates :name, inclusion: TAKEOFF_CALCULATOR_NAMES
|
58
|
+
|
59
|
+
validates :name, uniqueness: true
|
60
|
+
|
61
|
+
validate :input_parameters_schema
|
62
|
+
validate :measurement_unit_id_in_input_parameters
|
63
|
+
validate :enum_in_input_parameters
|
64
|
+
|
65
|
+
def input_parameters_schema
|
66
|
+
return if input_parameters.nil?
|
67
|
+
|
68
|
+
errors.add(:input_parameters, 'There has to be one or more input parameters') if input_parameters.count.zero?
|
69
|
+
|
70
|
+
validation_errors = JSON::Validator.fully_validate(INPUT_PARAMETERS_SCHEMA,
|
71
|
+
input_parameters, strict: true,
|
72
|
+
list: true, clear_cache: true)
|
73
|
+
|
74
|
+
errors.add(:input_parameters, validation_errors) unless validation_errors.empty?
|
75
|
+
end
|
76
|
+
|
77
|
+
def measurement_unit_id_in_input_parameters
|
78
|
+
return if input_parameters.nil?
|
79
|
+
|
80
|
+
input_parameters.each do |input_parameter|
|
81
|
+
next unless input_parameter['input_type'] == 'measurement' && !input_parameter['default_value'].nil?
|
82
|
+
|
83
|
+
if input_parameter['default_value']['measurement_unit_id'].nil?
|
84
|
+
errors.add(:base, 'measurement_unit_id is required')
|
85
|
+
next
|
86
|
+
end
|
87
|
+
|
88
|
+
measurement_unit_id = input_parameter['default_value']['measurement_unit_id']
|
89
|
+
measurement_unit = Ecom::Core::MeasurementUnit.find_by(id: measurement_unit_id)
|
90
|
+
|
91
|
+
errors.add(:base, "measurement unit with id #{measurement_unit_id} does not exist") if measurement_unit.nil?
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def enum_in_input_parameters
|
96
|
+
return if input_parameters.nil?
|
97
|
+
|
98
|
+
input_parameters.each do |input_parameter|
|
99
|
+
next if input_parameter['input_type'] != 'enum'
|
100
|
+
|
101
|
+
if input_parameter['enum_values'].nil?
|
102
|
+
errors.add(:base, 'enum_values are requiered if the input_type is enum')
|
103
|
+
next
|
104
|
+
end
|
105
|
+
|
106
|
+
next unless !input_parameter['enum_values'].nil? &&
|
107
|
+
input_parameter['enum_values'].class == Array &&
|
108
|
+
input_parameter['enum_values'].count.zero?
|
109
|
+
|
110
|
+
errors.add(:base, 'Provide at least one enum value')
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -8,11 +8,18 @@ module Ecom
|
|
8
8
|
belongs_to :work_product
|
9
9
|
belongs_to :task_template
|
10
10
|
belongs_to :work_package, optional: true
|
11
|
+
belongs_to :work_order, optional: true
|
12
|
+
belongs_to :plan, optional: true
|
11
13
|
belongs_to :performer, class_name: 'Ecom::Core::User', optional: true
|
12
14
|
belongs_to :approver, class_name: 'Ecom::Core::User', optional: true
|
13
15
|
belongs_to :supervisor, class_name: 'Ecom::Core::User', optional: true
|
14
16
|
belongs_to :quality_controller, class_name: 'Ecom::Core::User', optional: true
|
15
17
|
|
18
|
+
has_many :task_steps
|
19
|
+
has_many :task_resources
|
20
|
+
has_one :takeoff
|
21
|
+
|
22
|
+
validates_with DateRangeValidator
|
16
23
|
validates :code, :name, :status, :percent_completed, presence: true
|
17
24
|
validates_numericality_of :percent_completed,
|
18
25
|
only_integer: true,
|
@@ -21,8 +28,12 @@ module Ecom
|
|
21
28
|
|
22
29
|
scope :by_status, ->(status) { where(status: status) }
|
23
30
|
|
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
|
24
33
|
aasm column: 'status' do
|
25
34
|
state :new, initial: true
|
35
|
+
state :planned
|
36
|
+
state :ready_to_start
|
26
37
|
state :in_progress
|
27
38
|
state :submitted
|
28
39
|
state :under_review
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Ecom
|
2
|
+
module Core
|
3
|
+
class TaskStep < ApplicationRecord
|
4
|
+
include Filterable
|
5
|
+
|
6
|
+
before_save :update_task_progress
|
7
|
+
|
8
|
+
scope :filter_by_condition, ->(condition) { where(condition) }
|
9
|
+
|
10
|
+
validates :name, :total_contribution_percentage_to_task, presence: true
|
11
|
+
validates_with DateRangeValidator
|
12
|
+
validate :date_range_validator
|
13
|
+
validates_numericality_of :total_contribution_percentage_to_task,
|
14
|
+
greater_than: 0,
|
15
|
+
less_than_or_equal_to: 100
|
16
|
+
|
17
|
+
validate :task_step_percentage_validator, on: :create
|
18
|
+
|
19
|
+
validate :task_step_in_task_template_inclusion_validator
|
20
|
+
|
21
|
+
belongs_to :task
|
22
|
+
has_many :dependent_task_steps,
|
23
|
+
class_name: 'Ecom::Core::TaskStepDependency', foreign_key: 'dependent_task_step_id'
|
24
|
+
has_many :dependee_task_steps,
|
25
|
+
class_name: 'Ecom::Core::TaskStepDependency', foreign_key: 'dependee_task_step_id'
|
26
|
+
|
27
|
+
def date_range_validator
|
28
|
+
task_ = Ecom::Core::Task.find_by(id: task_id)
|
29
|
+
|
30
|
+
return if task_.nil?
|
31
|
+
|
32
|
+
if !start_date.nil? && start_date < task_.start_date
|
33
|
+
errors.add(:start_date, "The task steps start date can not be before the task's start date")
|
34
|
+
end
|
35
|
+
|
36
|
+
return unless !end_date.nil? && end_date > task_.end_date
|
37
|
+
|
38
|
+
errors.add(:end_date, "The task steps end date can not be after the task's end date")
|
39
|
+
end
|
40
|
+
|
41
|
+
def task_step_percentage_validator
|
42
|
+
return if task_id.nil?
|
43
|
+
|
44
|
+
task = Ecom::Core::Task.find_by(id: task_id)
|
45
|
+
|
46
|
+
return if task.nil?
|
47
|
+
|
48
|
+
total_contribution_of_all_task_steps = task.task_steps.sum(:total_contribution_percentage_to_task)
|
49
|
+
|
50
|
+
max_total_contribution = 100 - total_contribution_of_all_task_steps
|
51
|
+
return unless total_contribution_percentage_to_task > max_total_contribution
|
52
|
+
|
53
|
+
errors
|
54
|
+
.add(:total_contribution_of_all_task_steps,
|
55
|
+
"The maximum that this task step can contribute to the total task is #{max_total_contribution}")
|
56
|
+
end
|
57
|
+
|
58
|
+
def update_task_progress
|
59
|
+
return unless completed_changed? && completed == true
|
60
|
+
|
61
|
+
# update the task progress
|
62
|
+
task = self.task
|
63
|
+
percent_completed = task.percent_completed
|
64
|
+
task.percent_completed = (percent_completed + total_contribution_percentage_to_task).to_i
|
65
|
+
task.save
|
66
|
+
end
|
67
|
+
|
68
|
+
def task_step_in_task_template_inclusion_validator
|
69
|
+
return if task_id.nil?
|
70
|
+
|
71
|
+
task = Ecom::Core::Task.find_by(id: task_id)
|
72
|
+
|
73
|
+
return if task.nil?
|
74
|
+
|
75
|
+
task_template = task.task_template
|
76
|
+
|
77
|
+
return unless task_template.task_steps.nil?
|
78
|
+
|
79
|
+
errors.add(:base,
|
80
|
+
'Task steps are not defined for the given task in the
|
81
|
+
task template, please first define the task steps in the task template.')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Ecom
|
2
|
+
module Core
|
3
|
+
class TaskStepDependency < ApplicationRecord
|
4
|
+
validates :dependent_task_step_id, :dependee_task_step_id, presence: true
|
5
|
+
|
6
|
+
belongs_to :dependent_task_step, class_name: 'Ecom::Core::TaskStep'
|
7
|
+
belongs_to :dependee_task_step, class_name: 'Ecom::Core::TaskStep'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -1,16 +1,58 @@
|
|
1
|
+
require 'json-schema'
|
1
2
|
module Ecom
|
2
3
|
module Core
|
3
4
|
class TaskTemplate < ApplicationRecord
|
5
|
+
TASK_STEP_SCHEMA = {
|
6
|
+
'type' => 'object',
|
7
|
+
'required' => %w[name total_contribution_percentage_to_task],
|
8
|
+
'additionalProperties' => false,
|
9
|
+
'properties' => {
|
10
|
+
'name' => { 'type' => 'string' },
|
11
|
+
'total_contribution_percentage_to_task' => {
|
12
|
+
'type' => 'integer',
|
13
|
+
'minimum' => 1,
|
14
|
+
'maximum' => 100
|
15
|
+
}
|
16
|
+
}
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
# here the json schema has a bug ( including all properties as required)
|
20
|
+
# and because task_step_name is required on a condition ( only if the
|
21
|
+
# milestone is after a task step ), we can solve this with a workaround
|
22
|
+
# by specifying task_step_name in patternProperties.
|
23
|
+
MILESTONE_SCHEMA = {
|
24
|
+
'type' => 'object',
|
25
|
+
'required' => %w[name is_after_task_step],
|
26
|
+
'additionalProperties' => false,
|
27
|
+
'properties' => {
|
28
|
+
'name' => { 'type' => 'string' },
|
29
|
+
'is_after_task_step' => {
|
30
|
+
'type' => 'boolean'
|
31
|
+
}
|
32
|
+
},
|
33
|
+
"patternProperties": {
|
34
|
+
"task_step_name": {
|
35
|
+
'type' => 'string'
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}.freeze
|
39
|
+
|
4
40
|
has_ancestry
|
5
41
|
|
6
42
|
belongs_to :task_template_type
|
7
43
|
has_and_belongs_to_many :work_product_templates, join_table: 'ecom_core_task_templates_work_product_templates'
|
8
44
|
has_and_belongs_to_many :resource_types, join_table: 'ecom_core_task_templates_resource_types'
|
45
|
+
belongs_to :takeoff_calculator, optional: true
|
9
46
|
|
10
47
|
validates :name, :code, presence: true
|
11
48
|
validates :code, uniqueness: true
|
12
49
|
delegate(:name, to: :task_template_type, prefix: true)
|
13
50
|
|
51
|
+
validate :task_steps_schema_validator
|
52
|
+
validate :milestones_schema_validator
|
53
|
+
validate :validate_sum_of_task_step_contribution
|
54
|
+
validate :validate_milestone_task_step_association
|
55
|
+
|
14
56
|
def full_name
|
15
57
|
parent_name = parent&.name
|
16
58
|
return name unless parent_name
|
@@ -29,6 +71,56 @@ module Ecom
|
|
29
71
|
def equipment_types
|
30
72
|
resource_types.where(type: 'Ecom::Core::EquipmentType')
|
31
73
|
end
|
74
|
+
|
75
|
+
def task_steps_schema_validator
|
76
|
+
return if task_steps.nil?
|
77
|
+
|
78
|
+
validation_errors = JSON::Validator.fully_validate(TASK_STEP_SCHEMA,
|
79
|
+
task_steps, strict: true,
|
80
|
+
list: true, clear_cache: true)
|
81
|
+
|
82
|
+
errors.add(:task_steps, validation_errors) unless validation_errors.empty?
|
83
|
+
end
|
84
|
+
|
85
|
+
def milestones_schema_validator
|
86
|
+
return if milestones.nil?
|
87
|
+
|
88
|
+
validation_errors = JSON::Validator.fully_validate(MILESTONE_SCHEMA,
|
89
|
+
milestones, strict: true,
|
90
|
+
list: true, clear_cache: true)
|
91
|
+
|
92
|
+
errors.add(:milestones, validation_errors) unless validation_errors.empty?
|
93
|
+
end
|
94
|
+
|
95
|
+
def validate_sum_of_task_step_contribution
|
96
|
+
return if task_steps.nil?
|
97
|
+
|
98
|
+
filtered_task_steps = task_steps.select { |task_step| task_step['total_contribution_percentage_to_task'] }
|
99
|
+
|
100
|
+
sum_of_task_step_contribution =
|
101
|
+
filtered_task_steps.sum { |task_step| task_step['total_contribution_percentage_to_task'] }
|
102
|
+
|
103
|
+
errors.add(:task_steps, 'Sum of task step contributions has to be 100') if sum_of_task_step_contribution != 100
|
104
|
+
end
|
105
|
+
|
106
|
+
def validate_milestone_task_step_association
|
107
|
+
return if milestones.nil?
|
108
|
+
|
109
|
+
task_step_names = task_steps&.map { |task_step| task_step['name'] }
|
110
|
+
|
111
|
+
milestones_associated_with_task_step = milestones.select { |milestone| milestone['is_after_task_step'] }
|
112
|
+
|
113
|
+
milestones_associated_with_task_step.each do |milestone|
|
114
|
+
if milestone['task_step_name'].nil?
|
115
|
+
errors.add(:milestones, 'if the milestone is after a task step, please specify the task step name')
|
116
|
+
next
|
117
|
+
end
|
118
|
+
|
119
|
+
unless task_step_names.include? milestone['task_step_name']
|
120
|
+
errors.add(:milestone, 'task step for the given milestone does not exist in list of task steps')
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
32
124
|
end
|
33
125
|
end
|
34
126
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Ecom
|
2
|
+
module Core
|
3
|
+
class WorkOrder < ApplicationRecord
|
4
|
+
before_save :add_reference_number
|
5
|
+
|
6
|
+
NEW = 'New'.freeze
|
7
|
+
IN_PROGRESS = 'In Progress'.freeze
|
8
|
+
COMPLETED = 'Completed'.freeze
|
9
|
+
|
10
|
+
STATUSES = [NEW, IN_PROGRESS, COMPLETED].freeze
|
11
|
+
|
12
|
+
validates :name, :assigned_to_id, :generated_by_id, :status,
|
13
|
+
:start_date, :end_date, presence: true
|
14
|
+
|
15
|
+
validates :status, presence: true, inclusion: STATUSES
|
16
|
+
|
17
|
+
belongs_to :assigned_to, class_name: 'Ecom::Core::Crew'
|
18
|
+
belongs_to :generated_by, class_name: 'Ecom::Core::User'
|
19
|
+
has_many :tasks
|
20
|
+
|
21
|
+
def add_reference_number
|
22
|
+
self.reference_number = "WO-#{(Time.now.to_f * 1000).to_i}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -30,6 +30,7 @@ module Ecom
|
|
30
30
|
belongs_to :supervisor, class_name: 'Ecom::Core::User', optional: true
|
31
31
|
belongs_to :quality_controller, class_name: 'Ecom::Core::User', optional: true
|
32
32
|
has_many :tasks
|
33
|
+
has_many :dimension_elements
|
33
34
|
|
34
35
|
validates :name, :design_reference_no, :status, :percent_completed, presence: true
|
35
36
|
validates :design_reference_no, uniqueness: { scope: :project_id }
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class CreateEcomCoreTakeoffCalculators < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :ecom_core_takeoff_calculators do |t|
|
4
|
+
t.string :name, unique: true
|
5
|
+
t.boolean :is_custom_calculator, null: false, default: false
|
6
|
+
t.jsonb :input_parameters
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -8,9 +8,16 @@ class CreateEcomCoreTaskTemplates < ActiveRecord::Migration[6.0]
|
|
8
8
|
null: false,
|
9
9
|
index: { name: 'tt_on_ttt_indx' },
|
10
10
|
foreign_key: { to_table: :ecom_core_task_template_types }
|
11
|
+
t.references :takeoff_calculator,
|
12
|
+
null: true,
|
13
|
+
index: { name: 'tt_on_tc_indx' },
|
14
|
+
foreign_key: { to_table: :ecom_core_takeoff_calculators }
|
11
15
|
t.string :ancestry, index: true
|
12
16
|
t.boolean :has_takeoff_fields, null:false, default: false
|
13
17
|
t.jsonb :fields
|
18
|
+
t.jsonb :takeoff_fields
|
19
|
+
t.jsonb :task_steps
|
20
|
+
t.jsonb :milestones
|
14
21
|
|
15
22
|
t.timestamps
|
16
23
|
end
|
@@ -9,12 +9,12 @@ class CreateEcomCoreCrews < ActiveRecord::Migration[6.0]
|
|
9
9
|
t.string :qualification, null: false
|
10
10
|
t.string :employment, null: false
|
11
11
|
t.float :wage, null: false
|
12
|
-
t.string :wage_in_words
|
12
|
+
t.string :wage_in_words
|
13
13
|
t.date :employment_date
|
14
14
|
t.boolean :sub_contracted, null: false, default: false
|
15
15
|
t.string :photo
|
16
|
-
t.string :guarantor_name
|
17
|
-
t.string :guarantor_phone
|
16
|
+
t.string :guarantor_name, null: false
|
17
|
+
t.string :guarantor_phone, null: false
|
18
18
|
t.boolean :active, null: false, default: true
|
19
19
|
t.references :crew_type,
|
20
20
|
null: false,
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateEcomCorePlans < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :ecom_core_plans do |t|
|
4
|
+
t.string :name, null: false
|
5
|
+
t.date :start_date, null: false
|
6
|
+
t.date :end_date, null: false
|
7
|
+
t.string :status, null: false, default: 'New'
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class CreateEcomCoreWorkOrders < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :ecom_core_work_orders do |t|
|
4
|
+
t.string :name
|
5
|
+
t.string :reference_number
|
6
|
+
t.references :assigned_to,
|
7
|
+
null: false,
|
8
|
+
index: { name: 'wo_on_at_indx' },
|
9
|
+
foreign_key: { to_table: :ecom_core_crews }
|
10
|
+
|
11
|
+
t.references :generated_by,
|
12
|
+
null: false,
|
13
|
+
index: { name: 'wo_on_gb_indx' },
|
14
|
+
foreign_key: { to_table: :ecom_core_users }
|
15
|
+
|
16
|
+
t.date :start_date, null: false
|
17
|
+
t.date :end_date, null: false
|
18
|
+
t.string :status, null: false, default: :new
|
19
|
+
|
20
|
+
t.timestamps
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -12,8 +12,16 @@ class CreateEcomCoreTasks < ActiveRecord::Migration[6.0]
|
|
12
12
|
t.string :remark
|
13
13
|
t.references :work_package,
|
14
14
|
null: true,
|
15
|
-
index: { name: '
|
15
|
+
index: { name: 'tasks_on_work_package_indx' },
|
16
16
|
foreign_key: { to_table: :ecom_core_work_packages }
|
17
|
+
t.references :work_order,
|
18
|
+
null: true,
|
19
|
+
index: { name: 'tasks_on_wo_indx' },
|
20
|
+
foreign_key: { to_table: :ecom_core_work_orders }
|
21
|
+
t.references :plan,
|
22
|
+
null: true,
|
23
|
+
index: { name: 'tasks_on_plan_indx' },
|
24
|
+
foreign_key: { to_table: :ecom_core_plans }
|
17
25
|
t.references :performer,
|
18
26
|
null: true,
|
19
27
|
index: { name: 'tasks_on_performer_indx' },
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateEcomCoreMeasurementUnits < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :ecom_core_measurement_units do |t|
|
4
|
+
t.string :name, null: false
|
5
|
+
t.string :abbrivation, null: false
|
6
|
+
t.string :physical_quantity, null: false
|
7
|
+
t.boolean :is_si_unit, null: false, default: false
|
8
|
+
t.float :conversion_factor, null: false
|
9
|
+
t.string :system_of_measurement, null: false
|
10
|
+
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateEcomCoreTakeoffs < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :ecom_core_takeoffs do |t|
|
4
|
+
t.references :task,
|
5
|
+
null: false,
|
6
|
+
index: { name: 'takeoff_on_task_indx' },
|
7
|
+
foreign_key: { to_table: :ecom_core_tasks }
|
8
|
+
|
9
|
+
t.float :takeoff_quantity, null: false
|
10
|
+
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateEcomCoreTaskSteps < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :ecom_core_task_steps do |t|
|
4
|
+
t.references :task,
|
5
|
+
null: false,
|
6
|
+
index: { name: 'ts_on_task_indx' },
|
7
|
+
foreign_key: { to_table: :ecom_core_tasks }
|
8
|
+
t.string :name, null: false
|
9
|
+
t.date :start_date
|
10
|
+
t.date :end_date
|
11
|
+
t.float :total_contribution_percentage_to_task, null: false
|
12
|
+
t.boolean :completed, null: false, default: false
|
13
|
+
|
14
|
+
t.timestamps
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateEcomCoreTaskStepDependencies < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :ecom_core_task_step_dependencies do |t|
|
4
|
+
t.references :dependent_task_step,
|
5
|
+
null: false,
|
6
|
+
index: { name: 'tsd_on_dts_indx' },
|
7
|
+
foreign_key: { to_table: :ecom_core_task_steps }
|
8
|
+
|
9
|
+
t.references :dependee_task_step,
|
10
|
+
null: false,
|
11
|
+
index: { name: 'tsd_on_dependee_ts_indx' },
|
12
|
+
foreign_key: { to_table: :ecom_core_task_steps }
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class CreateEcomCoreDimensionElements < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :ecom_core_dimension_elements do |t|
|
4
|
+
|
5
|
+
t.references :work_product,
|
6
|
+
null: false,
|
7
|
+
index: { name: 'dimension_on_wp_indx' },
|
8
|
+
foreign_key: { to_table: :ecom_core_work_products }
|
9
|
+
|
10
|
+
t.references :measurement_unit,
|
11
|
+
null: false,
|
12
|
+
index: { name: 'dimension_on_mu_indx' },
|
13
|
+
foreign_key: { to_table: :ecom_core_measurement_units }
|
14
|
+
|
15
|
+
t.string :dimension_element_name, null: false
|
16
|
+
t.float :amount
|
17
|
+
|
18
|
+
t.timestamps
|
19
|
+
end
|
20
|
+
|
21
|
+
add_index :ecom_core_dimension_elements, [:work_product_id, :dimension_element_name], unique: true, name: 'de_on_wp_and_den'
|
22
|
+
end
|
23
|
+
end
|
data/lib/ecom/core/version.rb
CHANGED
@@ -0,0 +1,8 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :dimension_element, class: Ecom::Core::DimensionElement do
|
3
|
+
association :work_product
|
4
|
+
association :measurement_unit
|
5
|
+
amount { 5 }
|
6
|
+
dimension_element_name { Ecom::Core::DimensionElement::DIMENSION_ELEMENT_NAMES.sample }
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :takeoff_calculator, class: Ecom::Core::TakeoffCalculator do
|
3
|
+
name { Ecom::Core::TakeoffCalculator::TAKEOFF_CALCULATOR_NAMES.sample }
|
4
|
+
is_custom_calculator { false }
|
5
|
+
input_parameters do
|
6
|
+
[
|
7
|
+
{
|
8
|
+
name: 'number_of_bar',
|
9
|
+
label: 'Number Of Bar',
|
10
|
+
input_type: 'number',
|
11
|
+
default_value: {
|
12
|
+
value: '1'
|
13
|
+
}
|
14
|
+
}
|
15
|
+
]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :work_order, class: Ecom::Core::WorkOrder do
|
3
|
+
name { FFaker::Name.unique.name }
|
4
|
+
association :assigned_to, factory: :crew
|
5
|
+
association :generated_by, factory: :user
|
6
|
+
start_date { (Time.now + 1.day).to_s }
|
7
|
+
end_date { (Time.now + 1.month).to_s }
|
8
|
+
status { Ecom::Core::WorkOrder::STATUSES.sample }
|
9
|
+
end
|
10
|
+
end
|
@@ -3,7 +3,6 @@ FactoryBot.define do
|
|
3
3
|
name { FFaker::Name.name }
|
4
4
|
description { FFaker::Name.name }
|
5
5
|
design_reference_no { FFaker::Guid.guid }
|
6
|
-
dimension { [{ label: 'Length', name: 'length', value: 12 }] }
|
7
6
|
association :product_group
|
8
7
|
association :work_product_template
|
9
8
|
association :project
|
@@ -0,0 +1,10 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :measurement_unit, class: Ecom::Core::MeasurementUnit do
|
3
|
+
name { 'Meter' }
|
4
|
+
abbrivation { 'm' }
|
5
|
+
physical_quantity { Ecom::Core::MeasurementUnit::LENGTH }
|
6
|
+
is_si_unit { true }
|
7
|
+
conversion_factor { 1 }
|
8
|
+
system_of_measurement { Ecom::Core::MeasurementUnit::METRIC }
|
9
|
+
end
|
10
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ecom_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.32
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henock L.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-09-
|
11
|
+
date: 2020-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aasm
|
@@ -142,6 +142,20 @@ dependencies:
|
|
142
142
|
- - "~>"
|
143
143
|
- !ruby/object:Gem::Version
|
144
144
|
version: 6.0.3
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: json-schema
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
type: :runtime
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
145
159
|
- !ruby/object:Gem::Dependency
|
146
160
|
name: factory_bot_rails
|
147
161
|
requirement: !ruby/object:Gem::Requirement
|
@@ -238,6 +252,7 @@ files:
|
|
238
252
|
- README.md
|
239
253
|
- Rakefile
|
240
254
|
- app/constants/ecom/core/status_constants.rb
|
255
|
+
- app/controllers/concerns/ecom/core/filterable.rb
|
241
256
|
- app/controllers/concerns/ecom/core/lookupable.rb
|
242
257
|
- app/controllers/concerns/ecom/core/resource_typeable.rb
|
243
258
|
- app/controllers/ecom/core/access_controller.rb
|
@@ -269,6 +284,7 @@ files:
|
|
269
284
|
- app/models/ecom/core/crew_type.rb
|
270
285
|
- app/models/ecom/core/currency.rb
|
271
286
|
- app/models/ecom/core/custom_payment_detail.rb
|
287
|
+
- app/models/ecom/core/dimension_element.rb
|
272
288
|
- app/models/ecom/core/equipment.rb
|
273
289
|
- app/models/ecom/core/equipment_category.rb
|
274
290
|
- app/models/ecom/core/equipment_component.rb
|
@@ -286,6 +302,7 @@ files:
|
|
286
302
|
- app/models/ecom/core/maintenance_status.rb
|
287
303
|
- app/models/ecom/core/maintenance_type.rb
|
288
304
|
- app/models/ecom/core/material_type.rb
|
305
|
+
- app/models/ecom/core/measurement_unit.rb
|
289
306
|
- app/models/ecom/core/menu.rb
|
290
307
|
- app/models/ecom/core/overtime_sheet.rb
|
291
308
|
- app/models/ecom/core/overtime_sheet_entry.rb
|
@@ -293,6 +310,7 @@ files:
|
|
293
310
|
- app/models/ecom/core/payment.rb
|
294
311
|
- app/models/ecom/core/payment_detail.rb
|
295
312
|
- app/models/ecom/core/payroll.rb
|
313
|
+
- app/models/ecom/core/plan.rb
|
296
314
|
- app/models/ecom/core/product_group.rb
|
297
315
|
- app/models/ecom/core/product_type.rb
|
298
316
|
- app/models/ecom/core/project.rb
|
@@ -303,12 +321,17 @@ files:
|
|
303
321
|
- app/models/ecom/core/schedule_unit.rb
|
304
322
|
- app/models/ecom/core/stakeholder.rb
|
305
323
|
- app/models/ecom/core/stakeholder_type.rb
|
324
|
+
- app/models/ecom/core/takeoff.rb
|
325
|
+
- app/models/ecom/core/takeoff_calculator.rb
|
306
326
|
- app/models/ecom/core/task.rb
|
307
327
|
- app/models/ecom/core/task_resource.rb
|
328
|
+
- app/models/ecom/core/task_step.rb
|
329
|
+
- app/models/ecom/core/task_step_dependency.rb
|
308
330
|
- app/models/ecom/core/task_template.rb
|
309
331
|
- app/models/ecom/core/task_template_type.rb
|
310
332
|
- app/models/ecom/core/user.rb
|
311
333
|
- app/models/ecom/core/user_role.rb
|
334
|
+
- app/models/ecom/core/work_order.rb
|
312
335
|
- app/models/ecom/core/work_package.rb
|
313
336
|
- app/models/ecom/core/work_product.rb
|
314
337
|
- app/models/ecom/core/work_product_template.rb
|
@@ -328,6 +351,7 @@ files:
|
|
328
351
|
- db/migrate/20190101112620_create_ecom_core_lookups.rb
|
329
352
|
- db/migrate/20190101112625_create_ecom_core_overtime_types.rb
|
330
353
|
- db/migrate/20191119010518_create_ecom_core_task_template_types.rb
|
354
|
+
- db/migrate/20191119012027_create_ecom_core_takeoff_calculators.rb
|
331
355
|
- db/migrate/20191119012030_create_ecom_core_task_templates.rb
|
332
356
|
- db/migrate/20191119013236_create_ecom_core_work_product_templates.rb
|
333
357
|
- db/migrate/20191119144141_create_ecom_core_stakeholder_types.rb
|
@@ -344,9 +368,11 @@ files:
|
|
344
368
|
- db/migrate/20191202221423_create_ecom_core_menus.rb
|
345
369
|
- db/migrate/20191202222210_create_ecom_core_work_packages.rb
|
346
370
|
- db/migrate/20191202235434_create_ecom_core_work_products.rb
|
371
|
+
- db/migrate/20191207103729_create_ecom_core_crews.rb
|
372
|
+
- db/migrate/20191207103730_create_ecom_core_plans.rb
|
373
|
+
- db/migrate/20191207103731_create_ecom_core_work_orders.rb
|
347
374
|
- db/migrate/20191207103735_create_ecom_core_tasks.rb
|
348
375
|
- db/migrate/20191210724614_create_ecom_core_task_resources.rb
|
349
|
-
- db/migrate/20191225100054_create_ecom_core_crews.rb
|
350
376
|
- db/migrate/20191225121850_create_ecom_core_project_crews.rb
|
351
377
|
- db/migrate/20191225140433_create_ecom_core_attendance_sheets.rb
|
352
378
|
- db/migrate/20191225162539_create_ecom_core_attendance_sheet_entries.rb
|
@@ -368,7 +394,12 @@ files:
|
|
368
394
|
- db/migrate/20200602130247_create_ecom_core_requested_items.rb
|
369
395
|
- db/migrate/20200602830603_create_ecom_core_bookings.rb
|
370
396
|
- db/migrate/20200603115317_create_ecom_core_booked_items.rb
|
397
|
+
- db/migrate/20200813165553_create_ecom_core_measurement_units.rb
|
398
|
+
- db/migrate/20200814043632_create_ecom_core_takeoffs.rb
|
399
|
+
- db/migrate/20200820123719_create_ecom_core_task_steps.rb
|
400
|
+
- db/migrate/20200821130934_create_ecom_core_task_step_dependencies.rb
|
371
401
|
- db/migrate/20200901085227_create_ecom_core_crew_contracts.rb
|
402
|
+
- db/migrate/20200901134912_create_ecom_core_dimension_elements.rb
|
372
403
|
- db/migrate/20200919053331_create_ecom_core_maintenance_types.rb
|
373
404
|
- db/migrate/20200919072216_create_ecom_core_schedule_settings.rb
|
374
405
|
- db/migrate/20200919081338_create_ecom_core_maintenance_service_orders.rb
|
@@ -381,6 +412,7 @@ files:
|
|
381
412
|
- lib/ecom/core/version.rb
|
382
413
|
- lib/ecom_core.rb
|
383
414
|
- lib/tasks/ecom_core_tasks.rake
|
415
|
+
- spec/factories/dimension_elements.rb
|
384
416
|
- spec/factories/ecom/core/application_modules.rb
|
385
417
|
- spec/factories/ecom/core/attendance_sheet_entries.rb
|
386
418
|
- spec/factories/ecom/core/attendance_sheets.rb
|
@@ -421,6 +453,7 @@ files:
|
|
421
453
|
- spec/factories/ecom/core/payment_details.rb
|
422
454
|
- spec/factories/ecom/core/payments.rb
|
423
455
|
- spec/factories/ecom/core/payrolls.rb
|
456
|
+
- spec/factories/ecom/core/plans.rb
|
424
457
|
- spec/factories/ecom/core/product_groups.rb
|
425
458
|
- spec/factories/ecom/core/product_types.rb
|
426
459
|
- spec/factories/ecom/core/project_crews.rb
|
@@ -431,15 +464,21 @@ files:
|
|
431
464
|
- spec/factories/ecom/core/schedule_units.rb
|
432
465
|
- spec/factories/ecom/core/stakeholder_types.rb
|
433
466
|
- spec/factories/ecom/core/stakeholders.rb
|
467
|
+
- spec/factories/ecom/core/takeoff_calculators.rb
|
468
|
+
- spec/factories/ecom/core/takeoffs.rb
|
434
469
|
- spec/factories/ecom/core/task_resources.rb
|
470
|
+
- spec/factories/ecom/core/task_step_dependencies.rb
|
471
|
+
- spec/factories/ecom/core/task_steps.rb
|
435
472
|
- spec/factories/ecom/core/task_template_types.rb
|
436
473
|
- spec/factories/ecom/core/task_templates.rb
|
437
474
|
- spec/factories/ecom/core/tasks.rb
|
438
475
|
- spec/factories/ecom/core/user_roles.rb
|
439
476
|
- spec/factories/ecom/core/users.rb
|
477
|
+
- spec/factories/ecom/core/work_orders.rb
|
440
478
|
- spec/factories/ecom/core/work_packages.rb
|
441
479
|
- spec/factories/ecom/core/work_product_templates.rb
|
442
480
|
- spec/factories/ecom/core/work_products.rb
|
481
|
+
- spec/factories/measurement_units.rb
|
443
482
|
homepage: http://www.mks.com.et
|
444
483
|
licenses:
|
445
484
|
- MIT
|