ecom_core 1.2.27 → 1.2.32

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/ecom/core/filterable.rb +14 -0
  3. data/app/controllers/ecom/core/companies_controller.rb +15 -0
  4. data/app/controllers/ecom/core/project_crews_controller.rb +25 -0
  5. data/app/controllers/ecom/core/projects_controller.rb +32 -0
  6. data/app/models/ecom/core/cost_type.rb +8 -0
  7. data/app/models/ecom/core/crew.rb +13 -1
  8. data/app/models/ecom/core/crew_time.rb +10 -2
  9. data/app/models/ecom/core/dimension_element.rb +22 -0
  10. data/app/models/ecom/core/job_card.rb +16 -0
  11. data/app/models/ecom/core/maintenance_category.rb +6 -0
  12. data/app/models/ecom/core/maintenance_cost.rb +10 -0
  13. data/app/models/ecom/core/maintenance_service_order.rb +19 -0
  14. data/app/models/ecom/core/maintenance_status.rb +6 -0
  15. data/app/models/ecom/core/maintenance_type.rb +9 -0
  16. data/app/models/ecom/core/measurement_unit.rb +55 -0
  17. data/app/models/ecom/core/overtime_sheet.rb +15 -5
  18. data/app/models/ecom/core/plan.rb +18 -0
  19. data/app/models/ecom/core/schedule_setting.rb +11 -0
  20. data/app/models/ecom/core/schedule_unit.rb +6 -0
  21. data/app/models/ecom/core/takeoff.rb +10 -0
  22. data/app/models/ecom/core/takeoff_calculator.rb +115 -0
  23. data/app/models/ecom/core/task.rb +11 -0
  24. data/app/models/ecom/core/task_resource.rb +2 -0
  25. data/app/models/ecom/core/task_step.rb +85 -0
  26. data/app/models/ecom/core/task_step_dependency.rb +10 -0
  27. data/app/models/ecom/core/task_template.rb +92 -0
  28. data/app/models/ecom/core/work_order.rb +26 -0
  29. data/app/models/ecom/core/work_product.rb +1 -0
  30. data/app/services/ecom/core/project_crew_service.rb +39 -0
  31. data/config/routes.rb +5 -0
  32. data/db/migrate/20191119012027_create_ecom_core_takeoff_calculators.rb +11 -0
  33. data/db/migrate/20191119012030_create_ecom_core_task_templates.rb +7 -0
  34. data/db/migrate/20191202235434_create_ecom_core_work_products.rb +0 -1
  35. data/db/migrate/{20191225100054_create_ecom_core_crews.rb → 20191207103729_create_ecom_core_crews.rb} +3 -3
  36. data/db/migrate/20191207103730_create_ecom_core_plans.rb +12 -0
  37. data/db/migrate/20191207103731_create_ecom_core_work_orders.rb +23 -0
  38. data/db/migrate/20191207103735_create_ecom_core_tasks.rb +9 -1
  39. data/db/migrate/20200813165553_create_ecom_core_measurement_units.rb +14 -0
  40. data/db/migrate/20200814043632_create_ecom_core_takeoffs.rb +14 -0
  41. data/db/migrate/20200820123719_create_ecom_core_task_steps.rb +17 -0
  42. data/db/migrate/20200821130934_create_ecom_core_task_step_dependencies.rb +16 -0
  43. data/db/migrate/20200901134912_create_ecom_core_dimension_elements.rb +23 -0
  44. data/db/migrate/20200919053331_create_ecom_core_maintenance_types.rb +14 -0
  45. data/db/migrate/20200919072216_create_ecom_core_schedule_settings.rb +21 -0
  46. data/db/migrate/20200919081338_create_ecom_core_maintenance_service_orders.rb +32 -0
  47. data/db/migrate/20200919085613_create_ecom_core_job_cards.rb +48 -0
  48. data/db/migrate/20200919101941_create_ecom_core_cost_types.rb +10 -0
  49. data/db/migrate/20200919102802_create_ecom_core_maintenance_costs.rb +19 -0
  50. data/db/migrate/20200922044959_add_costs_approved_to_job_card.rb +5 -0
  51. data/lib/ecom/core/version.rb +1 -1
  52. data/spec/factories/dimension_elements.rb +8 -0
  53. data/spec/factories/ecom/core/attendance_sheet_entries.rb +1 -1
  54. data/spec/factories/ecom/core/cost_types.rb +6 -0
  55. data/spec/factories/ecom/core/job_cards.rb +17 -0
  56. data/spec/factories/ecom/core/maintenance_categories.rb +5 -0
  57. data/spec/factories/ecom/core/maintenance_costs.rb +9 -0
  58. data/spec/factories/ecom/core/maintenance_service_orders.rb +16 -0
  59. data/spec/factories/ecom/core/maintenance_statuses.rb +5 -0
  60. data/spec/factories/ecom/core/maintenance_types.rb +7 -0
  61. data/spec/factories/ecom/core/plans.rb +8 -0
  62. data/spec/factories/ecom/core/schedule_settings.rb +8 -0
  63. data/spec/factories/ecom/core/schedule_units.rb +5 -0
  64. data/spec/factories/ecom/core/takeoff_calculators.rb +18 -0
  65. data/spec/factories/ecom/core/takeoffs.rb +6 -0
  66. data/spec/factories/ecom/core/task_step_dependencies.rb +6 -0
  67. data/spec/factories/ecom/core/task_steps.rb +8 -0
  68. data/spec/factories/ecom/core/task_templates.rb +6 -0
  69. data/spec/factories/ecom/core/work_orders.rb +10 -0
  70. data/spec/factories/ecom/core/work_products.rb +0 -1
  71. data/spec/factories/measurement_units.rb +10 -0
  72. metadata +72 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 42f95a3904d7cdfebcafa09111ccfa6739bfda3496f67126e7d2fc43b586000f
4
- data.tar.gz: e9cbda9dfca1b89b7660a50a1550ec0a0218dc2faaef488e179d5c0a5a21eedf
3
+ metadata.gz: 18c07bbf068fb4b629257c21df23a45979e0d1f505e4002d0477d3a37926549d
4
+ data.tar.gz: 2c4efc8c1e021bbf12a87805a78722d3d1e093e8a3e53f9a75f7246c665a888d
5
5
  SHA512:
6
- metadata.gz: 704d938a16a2f48723e94663ba0161ada47c46d4c3cea081e1856d476aaaabb0820d1c0de57422f0787946bcf35a9eaac87973568c2736e3f63b7f03e4f9c77f
7
- data.tar.gz: ceb93623c85ace2292f56142d3982e8be76fff618cdcad2cea79bdfe7c70d35a008e213114a885f16eacbd2de83df995287b94d66face645abb6513feeda0bbc
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
@@ -0,0 +1,15 @@
1
+ module Ecom
2
+ module Core
3
+ class CompaniesController < ApplicationController
4
+ def index
5
+ data = Ecom::Core::Company.all
6
+ render json: data
7
+ end
8
+
9
+ def default_company
10
+ data = Ecom::Core::Company.first
11
+ render json: data
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ module Ecom
2
+ module Core
3
+ class ProjectCrewsController < ApplicationController
4
+ before_action :set_service, only: %i[update]
5
+
6
+ def index
7
+ project = Ecom::Core::Project.find(params[:id])
8
+ serialized = ActiveModelSerializers::SerializableResource.new(project.crews)
9
+ render json: { success: true, data: serialized }
10
+ end
11
+
12
+ def update
13
+ data = @service.update(params)
14
+ serialized = ActiveModelSerializers::SerializableResource.new(data[:data])
15
+ render json: { success: true, data: serialized }
16
+ end
17
+
18
+ private
19
+
20
+ def set_service
21
+ @service = ProjectCrewService.new
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,32 @@
1
+ module Ecom
2
+ module Core
3
+ class ProjectsController < ApplicationController
4
+ before_action :set_project, only: %i[show]
5
+ # GET /projects
6
+ def index
7
+ projects = Ecom::Core::Project.includes(:employer, :contractor, :consultant, :project_manager)
8
+ .where(company_id: params[:id])
9
+ serialized = ActiveModelSerializers::SerializableResource.new(projects)
10
+ render json: { success: true, data: serialized }
11
+ end
12
+
13
+ def show
14
+ render json: @project
15
+ end
16
+
17
+ private
18
+
19
+ def set_project
20
+ @project = Project.find(params[:id])
21
+ end
22
+
23
+ def model_params
24
+ params.require(:project).permit(:name, :description, :location, :objective, :project_scope, :employer_id,
25
+ :contractor_id, :consultant_id, :project_manager_id, :contract_number,
26
+ :company_id, :date_contract_signed, :commencement_date, :completion_date,
27
+ :contract_amount, :advance_payment, :retention, :remark, :task_template_type_id,
28
+ :currency_id)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,8 @@
1
+ module Ecom
2
+ module Core
3
+ class CostType < ApplicationRecord
4
+ validates :name, presence: true, uniqueness: true
5
+ validates :fields, presence: true
6
+ end
7
+ end
8
+ end
@@ -10,11 +10,16 @@ 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, :wage_in_words, presence: true
17
+ validates :name, :address, :qualification, :employment, :wage, :guarantor_name, :guarantor_phone, presence: true
16
18
  validates :employment, inclusion: EMPLOYMENT_TYPES
17
19
 
20
+ has_many :project_crews
21
+ has_many :projects, through: :project_crews
22
+
18
23
  scope :by_active, ->(active) { where(active: active) }
19
24
  scope :by_qualification, ->(qualification) { where(qualification: qualification) }
20
25
  scope :by_sub_contracted, ->(sub_contracted) { where(sub_contracted: sub_contracted) }
@@ -22,6 +27,13 @@ module Ecom
22
27
  def set_employment_date
23
28
  self.employment_date = Date.today
24
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
25
37
  end
26
38
  end
27
39
  end
@@ -12,7 +12,7 @@ module Ecom
12
12
  has_one :revision, class_name: 'Ecom::Core::CrewTime', foreign_key: :revision_to_id
13
13
 
14
14
  validates :checkin_time, presence: true, if: :checkout_time
15
- validate :checkout_is_greater_than_checkin
15
+ validate :time_range_validation, :total_time_validation
16
16
 
17
17
  scope :by_attendance, lambda { |id|
18
18
  joins(:attendance_sheet_entry).where(ecom_core_attendance_sheet_entries: { attendance_sheet_id: id })
@@ -22,12 +22,20 @@ module Ecom
22
22
  before_save :calculate_hours
23
23
  after_save :calculate_total
24
24
 
25
- def checkout_is_greater_than_checkin
25
+ def time_range_validation
26
26
  return unless checkin_time && checkout_time && checkout_time <= checkin_time
27
27
 
28
28
  errors.add(:checkout_time, "can't be less than checkin time.")
29
29
  end
30
30
 
31
+ def total_time_validation
32
+ return if checkout_time.nil? || checkin_time.nil?
33
+
34
+ return unless attendance_sheet_entry.total_hours + compute_hours > 8
35
+
36
+ errors.add(:attendance_sheet_entry, 'has more than 8 hours')
37
+ end
38
+
31
39
  def calculate_hours
32
40
  self.hours = if checkout_time.nil? || checkin_time.nil?
33
41
  0
@@ -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,16 @@
1
+ module Ecom
2
+ module Core
3
+ class JobCard < ApplicationRecord
4
+ belongs_to :maintenance_service_order
5
+ belongs_to :service_provider, class_name: 'Ecom::Core::EquipmentLocation'
6
+ belongs_to :checkout_by, class_name: 'Ecom::Core::User', optional: true
7
+ belongs_to :checkout_to, class_name: 'Ecom::Core::EquipmentLocation', optional: true
8
+ belongs_to :maintenance_status
9
+ belongs_to :checkin_by, class_name: 'Ecom::Core::User', optional: true
10
+ belongs_to :checkin_to, class_name: 'Ecom::Core::EquipmentLocation', optional: true
11
+ belongs_to :prepared_by, class_name: 'Ecom::Core::User'
12
+
13
+ validates :code, presence: true, uniqueness: true
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,6 @@
1
+ module Ecom
2
+ module Core
3
+ class MaintenanceCategory < Lookup
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ module Ecom
2
+ module Core
3
+ class MaintenanceCost < ApplicationRecord
4
+ belongs_to :job_card
5
+ belongs_to :cost_type
6
+
7
+ validates :cost_detail, presence: true
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,19 @@
1
+ module Ecom
2
+ module Core
3
+ class MaintenanceServiceOrder < ApplicationRecord
4
+ NEW = 'New'.freeze
5
+ IN_PROGRESS = 'In Progress'.freeze
6
+ COMPLETED = 'Completed'.freeze
7
+
8
+ STATUSES = [NEW, IN_PROGRESS, COMPLETED].freeze
9
+
10
+ belongs_to :equipment_item
11
+ belongs_to :maintenance_type
12
+ belongs_to :prepared_by, class_name: 'Ecom::Core::User'
13
+ belongs_to :approved_by, class_name: 'Ecom::Core::User'
14
+
15
+ validates :title, :status, :current_reading, presence: true
16
+ validates :status, inclusion: STATUSES
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,6 @@
1
+ module Ecom
2
+ module Core
3
+ class MaintenanceStatus < Lookup
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ module Ecom
2
+ module Core
3
+ class MaintenanceType < ApplicationRecord
4
+ belongs_to :maintenance_category
5
+
6
+ validates :name, presence: true
7
+ end
8
+ end
9
+ 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.open(project_id).exists?
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.open(project_id).where(date: date).exists?
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.by_project(project_id).by_date(date).exists?
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
@@ -0,0 +1,11 @@
1
+ module Ecom
2
+ module Core
3
+ class ScheduleSetting < ApplicationRecord
4
+ belongs_to :equipment
5
+ belongs_to :maintenance_type
6
+ belongs_to :schedule_unit
7
+
8
+ validates :value, presence: true
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ module Ecom
2
+ module Core
3
+ class ScheduleUnit < Lookup
4
+ end
5
+ end
6
+ 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
@@ -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