ecom_core 1.2.31 → 1.2.36

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e0b7beafc5d7b2e1a7385f1a01db93b9d3279c41434a3e104a76e58aa0b48ac
4
- data.tar.gz: 766cbcb8b998e4725c1afe43f0c28a2a3901d8ce2e9a84fd308c5c88623ef392
3
+ metadata.gz: 2f37ff631e9f8965a0935b6ccd8ca9d28ee8e18c5a81eb9898941bb571a853e2
4
+ data.tar.gz: 3d7b428a2722a3b2fc1207ea648d6b8032d63b5402af7d8a9ce2297a3acf4230
5
5
  SHA512:
6
- metadata.gz: 6590ea1a50bdc293aa807ed135287cb6c89ecdd83e902898801f758d1d187b5003b31c77117f7d02ab8367e13b06bac4fb0054726c9e1934e8aa4279d6a36f43
7
- data.tar.gz: ead89e3cd5136806c9e1ea45fb91c46249604aad30ab6040f902b119307f34c0a34940c491866d04ff8eab5a99b33350dcdbc9a7399a8ce73155ff086d43c802
6
+ metadata.gz: 06030361db29cd37a37f43f8f16fb51c9b460c5c6be78e94e2ef21a75f2d23e0bacc3561c52dd732d4d1b8b16ddcac8d39baa83c3ef37fc5ca25a08e347d9557
7
+ data.tar.gz: 5f4f94583ae5519a0bdc78a4a5183595aa0df0901f0f4e339d5e797756c8b3b40254d89aeb6a30f36d52f7bf197b8961d085d08b97b6515e4de41ddc1bbd5c97
@@ -1,11 +1,12 @@
1
1
  module Ecom
2
2
  module Core
3
- class ProjectCrewsController < ApplicationController
3
+ class SiteCrewsController < ApplicationController
4
4
  before_action :set_service, only: %i[update]
5
5
 
6
6
  def index
7
- project = Ecom::Core::Project.find(params[:id])
8
- serialized = ActiveModelSerializers::SerializableResource.new(project.crews)
7
+ crew_ids = Ecom::Core::SiteCrew.where(site_id: params[:id], status: 'Active').select(:crew_id)
8
+ crews = Ecom::Core::Crew.where(id: crew_ids)
9
+ serialized = ActiveModelSerializers::SerializableResource.new(crews)
9
10
  render json: { success: true, data: serialized }
10
11
  end
11
12
 
@@ -18,7 +19,7 @@ module Ecom
18
19
  private
19
20
 
20
21
  def set_service
21
- @service = ProjectCrewService.new
22
+ @service = SiteCrewService.new
22
23
  end
23
24
  end
24
25
  end
@@ -0,0 +1,29 @@
1
+ module Ecom
2
+ module Core
3
+ class UnitCostsController < ApplicationController
4
+ before_action :set_service, only: %i[update]
5
+
6
+ def index
7
+ unit_costs = UnitCost.where(active: true)
8
+ serialized = ActiveModelSerializers::SerializableResource.new(unit_costs)
9
+ render json: { success: true, data: serialized }
10
+ end
11
+
12
+ def create
13
+ unit_cost = UnitCost.new(unit_cost_params)
14
+ if unit_cost.save
15
+ render json: unit_cost, status: :created
16
+ else
17
+ render json: { success: false, errors: unit_cost.errors }, status: :unprocessable_entity
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def unit_cost_params
24
+ params.require(:unit_cost).permit(:resource_type_id, :quantity, :measurement_unit_id,
25
+ :price, :currency_id, :utilization_factor, :effective_date, :set_by_id)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,40 +1,40 @@
1
1
  module Ecom
2
2
  module Core
3
3
  class AttendanceSheet < ApplicationRecord
4
- validates :date, presence: true, uniqueness: { scope: :project_id }
4
+ validates :date, 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 :attendance_sheet_entries
10
10
  has_many :crew_times, through: :attendance_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
16
 
17
- def self.open_for_date(date, project_id)
18
- AttendanceSheet.find_by(status: StatusConstants::OPEN, date: date, project_id: project_id)
17
+ def self.open_for_date(date, site_id)
18
+ AttendanceSheet.find_by(status: StatusConstants::OPEN, date: date, site_id: site_id)
19
19
  end
20
20
 
21
- def self.open_exists?(project_id)
21
+ def self.open_exists?(site_id)
22
22
  AttendanceSheet
23
- .by_project(project_id)
23
+ .by_site(site_id)
24
24
  .by_status(StatusConstants::OPEN)
25
25
  .exists?
26
26
  end
27
27
 
28
- def self.exists_for_today?(project_id)
28
+ def self.exists_for_today?(site_id)
29
29
  AttendanceSheet
30
- .by_project(project_id)
30
+ .by_site(site_id)
31
31
  .by_date(Date.today)
32
32
  .exists?
33
33
  end
34
34
 
35
- def self.open_exists_for_today?(project_id)
35
+ def self.open_exists_for_today?(site_id)
36
36
  AttendanceSheet
37
- .by_project(project_id)
37
+ .by_site(site_id)
38
38
  .by_date(Date.today)
39
39
  .by_status(StatusConstants::OPEN)
40
40
  .exists?
@@ -45,19 +45,19 @@ module Ecom
45
45
  # check if there is an open attendance already,
46
46
  # and also that we have only one attendace sheet
47
47
  # per day.
48
- def self.create_current(project_id)
49
- raise 'Attendance sheet already created for the day.' if AttendanceSheet.exists_for_today?(project_id)
48
+ def self.create_current(site_id)
49
+ raise 'Attendance sheet already created for the day.' if AttendanceSheet.exists_for_today?(site_id)
50
50
 
51
- if AttendanceSheet.open_exists?(project_id)
51
+ if AttendanceSheet.open_exists?(site_id)
52
52
  raise 'There is an open attendance sheet which needs to be submitted before creating a new one.'
53
53
  end
54
54
 
55
55
  AttendanceSheet.create(date: Date.today, opened_at: Time.now, status: StatusConstants::OPEN,
56
- project_id: project_id)
56
+ site_id: site_id)
57
57
  end
58
58
 
59
- def self.submit_current(project_id)
60
- sheet = AttendanceSheet.find_by(date: Date.today, status: StatusConstants::OPEN, project_id: project_id)
59
+ def self.submit_current(site_id)
60
+ sheet = AttendanceSheet.find_by(date: Date.today, status: StatusConstants::OPEN, site_id: site_id)
61
61
 
62
62
  raise 'There is no open attendance sheet to submit.' if sheet.nil?
63
63
 
@@ -71,8 +71,8 @@ module Ecom
71
71
  # to submit the attendance sheet after the date has
72
72
  # passed. Normally, timekeepers need to open and close
73
73
  # an attendance sheet of a date on the specific date.
74
- def self.submit(date, project_id)
75
- sheet = AttendanceSheet.open_for_date(date, project_id)
74
+ def self.submit(date, site_id)
75
+ sheet = AttendanceSheet.open_for_date(date, site_id)
76
76
  raise 'There is no open attendance sheet to submit for the selected day.' unless sheet
77
77
 
78
78
  sheet.submitted_at = DateTime.now
@@ -0,0 +1,10 @@
1
+ module Ecom
2
+ module Core
3
+ class AvailableUnitOfMeasurement < ApplicationRecord
4
+ validates :material_type_id, :material_type, :measurement_unit_id, :measurement_unit, presence: true
5
+
6
+ belongs_to :material_type
7
+ belongs_to :measurement_unit
8
+ end
9
+ end
10
+ end
@@ -10,13 +10,17 @@ 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
 
18
- has_many :project_crews
19
- has_many :projects, through: :project_crews
20
+ has_many :site_crews
21
+ has_many :sites, through: :site_crews
22
+ has_many :crew_id_cards
23
+ has_many :crew_contracts
20
24
 
21
25
  scope :by_active, ->(active) { where(active: active) }
22
26
  scope :by_qualification, ->(qualification) { where(qualification: qualification) }
@@ -25,6 +29,14 @@ module Ecom
25
29
  def set_employment_date
26
30
  self.employment_date = Date.today
27
31
  end
32
+
33
+ def set_employee_id
34
+ company = Ecom::Core::Company.first
35
+ date = employment_date.to_s[0..3]
36
+ company_name = company ? company.name : ''
37
+ employee_id = "#{company_name}/#{employment}/#{date}/#{id}"
38
+ update_column(:employee_id, employee_id)
39
+ end
28
40
  end
29
41
  end
30
42
  end
@@ -1,17 +1,57 @@
1
1
  module Ecom
2
2
  module Core
3
3
  class CrewContract < ApplicationRecord
4
+ include AASM
5
+
4
6
  belongs_to :crew
7
+ belongs_to :crew_type
5
8
 
6
- validates :contract_no, :from, :to, :place_of_work, :probation_period, :contract_type, presence: true
9
+ validates :status, :contract_no, :from, :to, :place_of_work, :probation_period,
10
+ :contract_type, :wage, :wage_in_words, :crew_type_id, :crew_type, presence: true
7
11
  validates :contract_no, uniqueness: true
8
12
  validate :validate_date_range
9
13
 
14
+ validates :wage, presence: true, numericality: { greater_than: 0 }
15
+
16
+ validates_uniqueness_of :crew_id,
17
+ if: -> { status == 'in_effect' },
18
+ message: 'There can only be one contract' \
19
+ ' with status `In effect` for a given crew at a time'
20
+
10
21
  def validate_date_range
11
22
  return unless from && to
12
23
 
13
24
  errors.add(:to, 'cannot be before from date.') if from >= to
14
25
  end
26
+
27
+ aasm column: 'status' do
28
+ state :draft, initial: true
29
+ state :submitted_for_approval
30
+ state :approved
31
+ state :rejected
32
+ state :in_effect
33
+ state :void
34
+
35
+ event :submit_for_approval do
36
+ transitions from: :draft, to: :submitted_for_approval, guard: -> { status == 'draft' }
37
+ end
38
+
39
+ event :approve do
40
+ transitions from: :submitted_for_approval, to: :approved, guard: -> { status == 'submitted_for_approval' }
41
+ end
42
+
43
+ event :reject do
44
+ transitions from: :submitted_for_approval, to: :rejected, guard: -> { status == 'submitted_for_approval' }
45
+ end
46
+
47
+ event :commence do
48
+ transitions from: :approved, to: :in_effect, guard: -> { status == 'approved' }
49
+ end
50
+
51
+ event :terminate do
52
+ transitions from: :in_effect, to: :void, guard: -> { status == 'in_effect' }
53
+ end
54
+ end
15
55
  end
16
56
  end
17
57
  end
@@ -0,0 +1,29 @@
1
+ module Ecom
2
+ module Core
3
+ class CrewContractTransaction < ApplicationRecord
4
+ PENDING = 'Pending'.freeze
5
+ EXECUTED = 'Executed'.freeze
6
+
7
+ STATUSES = [PENDING, EXECUTED].freeze
8
+
9
+ TXN_UPDATE_CREW_TYPE = 'TXN_UPDATE_CREW_TYPE'.freeze
10
+ TXN_UPDATE_WAGE = 'TXN_UPDATE_WAGE'.freeze
11
+ TXN_UPDATE_VALIDITY = 'TXN_UPDATE_VALIDITY'.freeze
12
+ TXN_UPDATE_PLACE_OF_WORK = 'TXN_UPDATE_PLACE_OF_WORK'.freeze
13
+ TXN_TERMINATE_CONTRACT = 'TXN_TERMINATE_CONTRACT'.freeze
14
+
15
+ TRANSACTION_TYPES = [TXN_UPDATE_CREW_TYPE,
16
+ TXN_UPDATE_WAGE, TXN_UPDATE_VALIDITY,
17
+ TXN_UPDATE_PLACE_OF_WORK,
18
+ TXN_TERMINATE_CONTRACT].freeze
19
+
20
+ validates :status, :transaction_type, :crew_contract_id,
21
+ :crew_contract, :effective_date, presence: true
22
+
23
+ validates :status, inclusion: STATUSES
24
+ validates :transaction_type, inclusion: TRANSACTION_TYPES
25
+
26
+ belongs_to :crew_contract
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,36 @@
1
+ module Ecom
2
+ module Core
3
+ class CrewIdCard < ApplicationRecord
4
+ before_save :invalidate_other_ids
5
+
6
+ VALID = 'Valid'.freeze
7
+ INVALID = 'Invalid'.freeze
8
+
9
+ STATUSES = [VALID, INVALID].freeze
10
+
11
+ validates :crew_id, :crew, :issued_on, :valid_until,
12
+ :status, presence: true
13
+
14
+ validates :status, inclusion: STATUSES
15
+ validate :valid_until_validator
16
+
17
+ belongs_to :crew
18
+
19
+ def valid_until_validator
20
+ return unless valid_until && issued_on
21
+
22
+ errors.add(:valid_until, 'cannot be before issue date.') if issued_on >= valid_until
23
+ end
24
+
25
+ def invalidate_other_ids
26
+ return if crew_id.nil?
27
+
28
+ return if status_changed?(from: 'Valid', to: 'Invalid')
29
+
30
+ Ecom::Core::CrewIdCard
31
+ .where(crew_id: crew_id, status: 'Valid')
32
+ .update(status: 'Invalid')
33
+ end
34
+ end
35
+ end
36
+ end
@@ -20,7 +20,7 @@ module Ecom
20
20
  scope :revised, ->(revised) { where(revised: revised) }
21
21
 
22
22
  before_save :calculate_hours
23
- after_save :calculate_total
23
+ after_save :compute_total_for_entry # :calculate_total
24
24
 
25
25
  def time_range_validation
26
26
  return unless checkin_time && checkout_time && checkout_time <= checkin_time
@@ -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,6 @@
1
+ module Ecom
2
+ module Core
3
+ class InspectionChecklist < Lookup
4
+ end
5
+ end
6
+ end
@@ -13,4 +13,4 @@ module Ecom
13
13
  validates :code, presence: true, uniqueness: true
14
14
  end
15
15
  end
16
- end
16
+ end
@@ -0,0 +1,41 @@
1
+ module Ecom
2
+ module Core
3
+ class LookaheadPlan < ApplicationRecord
4
+ include AASM
5
+
6
+ belongs_to :prepared_by, class_name: 'Ecom::Core::User'
7
+ has_many :lookahead_plan_review_times
8
+ has_many :lookahead_plan_histories
9
+ has_and_belongs_to_many :tasks, join_table: 'ecom_core_lookahead_plan_backlogs'
10
+
11
+ validates :name, :start_date, :end_date, :status,
12
+ :prepared_by_id, :prepared_by, presence: true
13
+
14
+ validates :revision_number, numericality: { greater_than_or_equal_to: 0 }
15
+ validates :lead_time, presence: true, numericality: { greater_than_or_equal_to: 1 }
16
+
17
+ aasm column: 'status' do
18
+ state :new, initial: true
19
+ state :in_progress
20
+ state :in_review
21
+ state :completed
22
+
23
+ event :start do
24
+ transitions from: :new, to: :in_progress, guard: -> { status == 'new' }
25
+ end
26
+
27
+ event :review do
28
+ transitions from: :in_progress, to: :in_review, guard: -> { status == 'in_progress' }
29
+ end
30
+
31
+ event :continue do
32
+ transitions from: :in_review, to: :in_progress, guard: -> { status == 'in_review' }
33
+ end
34
+
35
+ event :complete do
36
+ transitions from: :in_review, to: :completed, guard: -> { status == 'in_review' }
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,16 @@
1
+ module Ecom
2
+ module Core
3
+ class LookaheadPlanHistory < ApplicationRecord
4
+ belongs_to :lookahead_plan
5
+ belongs_to :task
6
+
7
+ validates_with DateRangeValidator
8
+
9
+ validates :lookahead_plan_id, :lookahead_plan, :task_id, :task, :start_date, :end_date,
10
+ :lookahead_plan_revision_number, presence: true
11
+
12
+ validates_numericality_of :lookahead_plan_revision_number,
13
+ greater_than_or_equal_to: 0
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ module Ecom
2
+ module Core
3
+ class LookaheadPlanReviewTime < ApplicationRecord
4
+ include AASM
5
+
6
+ belongs_to :lookahead_plan
7
+
8
+ validates :lookahead_plan_id, :lookahead_plan,
9
+ :lookahead_plan_revision_number, :review_time, :status, presence: true
10
+
11
+ validates_numericality_of :lookahead_plan_revision_number,
12
+ greater_than_or_equal_to: 0
13
+
14
+ aasm column: 'status' do
15
+ state :awaiting, initial: true
16
+ state :attended
17
+ state :cancelled
18
+
19
+ event :attend do
20
+ transitions from: :awaiting, to: :attended, guard: -> { status == 'awaiting' }
21
+ end
22
+
23
+ event :cancel do
24
+ transitions from: :awaiting, to: :cancelled, guard: -> { status == 'awaiting' }
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end