ecom_core 1.2.30 → 1.2.35
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/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 +14 -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 +11 -3
- data/app/models/ecom/core/dimension_element.rb +22 -0
- data/app/models/ecom/core/inspection_checklist.rb +6 -0
- data/app/models/ecom/core/job_card.rb +1 -1
- 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 +55 -0
- data/app/models/ecom/core/overtime_sheet.rb +26 -16
- data/app/models/ecom/core/payroll.rb +3 -3
- data/app/models/ecom/core/plan.rb +18 -0
- data/app/models/ecom/core/project.rb +0 -3
- data/app/models/ecom/core/project_template.rb +11 -0
- data/app/models/ecom/core/project_work_item_template.rb +9 -0
- data/app/models/ecom/core/schedule_setting.rb +8 -6
- 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/takeoff.rb +10 -0
- data/app/models/ecom/core/task.rb +32 -4
- data/app/models/ecom/core/task_inspection_checklist.rb +18 -0
- data/app/models/ecom/core/task_resource.rb +2 -0
- data/app/models/ecom/core/task_template.rb +22 -2
- data/app/models/ecom/core/task_template_inspection_checklist.rb +8 -0
- data/app/models/ecom/core/work_order.rb +26 -0
- data/app/models/ecom/core/work_package.rb +3 -0
- data/app/models/ecom/core/work_product.rb +3 -18
- data/app/models/ecom/core/work_product_template.rb +2 -2
- 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 +8 -1
- data/config/routes.rb +2 -2
- data/db/migrate/20191119012030_create_ecom_core_task_templates.rb +6 -1
- 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 -18
- 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 +23 -7
- 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/20200813165553_create_ecom_core_measurement_units.rb +14 -0
- data/db/migrate/20200813165555_create_ecom_core_available_unit_of_measurements.rb +16 -0
- data/db/migrate/20200814043632_create_ecom_core_takeoffs.rb +14 -0
- data/db/migrate/20200901085227_create_ecom_core_crew_contracts.rb +7 -1
- data/db/migrate/20200901134912_create_ecom_core_dimension_elements.rb +23 -0
- 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/lib/ecom/core/version.rb +1 -1
- data/spec/factories/ecom/core/attendance_sheet_entries.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/ecom/core/dimension_elements.rb +8 -0
- data/spec/factories/ecom/core/inspection_checklists.rb +5 -0
- data/spec/factories/ecom/core/maintenance_statuses.rb +1 -1
- 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/ecom/core/measurement_units.rb +16 -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/plans.rb +8 -0
- 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/site_crews.rb +10 -0
- data/spec/factories/ecom/core/sites.rb +8 -0
- data/spec/factories/ecom/core/takeoffs.rb +6 -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 -1
- data/spec/factories/ecom/core/tasks.rb +8 -3
- data/spec/factories/ecom/core/work_orders.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 -8
- metadata +75 -9
- data/app/services/ecom/core/project_crew_service.rb +0 -39
- data/db/migrate/20191225121850_create_ecom_core_project_crews.rb +0 -19
- data/db/migrate/20200922044959_add_costs_approved_to_job_card.rb +0 -5
- 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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b43b8dd7f97b9f42d8291e7de02613863b54d79062ab12079792eaabfcdcc78a
|
|
4
|
+
data.tar.gz: 35e01c0eecc8d2ee6d11599f834cd2cb5dbfcdb18a90884bf88401fe18359b8e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '0428fe3fac34831c9ab94b28f4a7819dee36fd608f0d2534249b06278918e8e87313b417279a25328061500833dcf2e281fb43ef8add4b463e824bdac61c3958'
|
|
7
|
+
data.tar.gz: 673cf08cc11e5f3ddc8d8ddef5f3da3adb17292032b8e306deacf4bc326080a5da3ea8c666d71b8014a4b91e690a1267c4f18d920cf45133f864910ccac2d7aa
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
module Ecom
|
|
2
2
|
module Core
|
|
3
|
-
class
|
|
3
|
+
class SiteCrewsController < ApplicationController
|
|
4
4
|
before_action :set_service, only: %i[update]
|
|
5
5
|
|
|
6
6
|
def index
|
|
7
|
-
|
|
8
|
-
|
|
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 =
|
|
22
|
+
@service = SiteCrewService.new
|
|
22
23
|
end
|
|
23
24
|
end
|
|
24
25
|
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: :
|
|
4
|
+
validates :date, 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 :attendance_sheet_entries
|
|
10
10
|
has_many :crew_times, through: :attendance_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
16
|
|
|
17
|
-
def self.open_for_date(date,
|
|
18
|
-
AttendanceSheet.find_by(status: StatusConstants::OPEN, date: date,
|
|
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?(
|
|
21
|
+
def self.open_exists?(site_id)
|
|
22
22
|
AttendanceSheet
|
|
23
|
-
.
|
|
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?(
|
|
28
|
+
def self.exists_for_today?(site_id)
|
|
29
29
|
AttendanceSheet
|
|
30
|
-
.
|
|
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?(
|
|
35
|
+
def self.open_exists_for_today?(site_id)
|
|
36
36
|
AttendanceSheet
|
|
37
|
-
.
|
|
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(
|
|
49
|
-
raise 'Attendance sheet already created for the day.' if AttendanceSheet.exists_for_today?(
|
|
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?(
|
|
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
|
-
|
|
56
|
+
site_id: site_id)
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
def self.submit_current(
|
|
60
|
-
sheet = AttendanceSheet.find_by(date: Date.today, status: StatusConstants::OPEN,
|
|
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,
|
|
75
|
-
sheet = AttendanceSheet.open_for_date(date,
|
|
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,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, :
|
|
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 :
|
|
19
|
-
has_many :
|
|
20
|
+
has_many :site_crews
|
|
21
|
+
has_many :sites, through: :site_crews
|
|
22
|
+
has_many :crew_id_cards
|
|
20
23
|
|
|
21
24
|
scope :by_active, ->(active) { where(active: active) }
|
|
22
25
|
scope :by_qualification, ->(qualification) { where(qualification: qualification) }
|
|
@@ -25,6 +28,14 @@ module Ecom
|
|
|
25
28
|
def set_employment_date
|
|
26
29
|
self.employment_date = Date.today
|
|
27
30
|
end
|
|
31
|
+
|
|
32
|
+
def set_employee_id
|
|
33
|
+
company = Ecom::Core::Company.first
|
|
34
|
+
date = employment_date.to_s[0..3]
|
|
35
|
+
company_name = company ? company.name : ''
|
|
36
|
+
employee_id = "#{company_name}/#{employment}/#{date}/#{id}"
|
|
37
|
+
update_column(:employee_id, employee_id)
|
|
38
|
+
end
|
|
28
39
|
end
|
|
29
40
|
end
|
|
30
41
|
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,
|
|
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
|
+
conditions: -> { where(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
|
|
@@ -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 :
|
|
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 })
|
|
@@ -20,14 +20,22 @@ 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
|
-
def
|
|
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,21 @@
|
|
|
1
|
+
module Ecom
|
|
2
|
+
module Core
|
|
3
|
+
class MaterialIdentity < ApplicationRecord
|
|
4
|
+
belongs_to :material_type
|
|
5
|
+
belongs_to :material_sub_type, optional: true
|
|
6
|
+
|
|
7
|
+
validates :material_type_id, :material_type, presence: true
|
|
8
|
+
validate :material_category_hierarchy_validator
|
|
9
|
+
|
|
10
|
+
def material_category_hierarchy_validator
|
|
11
|
+
return if material_type_id.nil? || material_sub_type_id.nil?
|
|
12
|
+
|
|
13
|
+
material_sub_type = MaterialSubType.find_by(id: material_sub_type_id)
|
|
14
|
+
|
|
15
|
+
return unless material_sub_type.material_type_id != material_type_id
|
|
16
|
+
|
|
17
|
+
errors.add(:material_type, 'The given material_sub_type does not belong to the given material_type')
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Ecom
|
|
2
|
+
module Core
|
|
3
|
+
class MaterialItem < ApplicationRecord
|
|
4
|
+
before_save :assign_serial_number
|
|
5
|
+
|
|
6
|
+
belongs_to :material_identity
|
|
7
|
+
|
|
8
|
+
validates :serial_number, presence: true, uniqueness: true
|
|
9
|
+
validates :material_identity_id, :material_identity, presence: true
|
|
10
|
+
validates :serial_number, format: { with: /^SN_\d+$/, message: 'Invalid serial number format', multiline: true }
|
|
11
|
+
validates :price, numericality: { greater_than: 0 }, allow_nil: true
|
|
12
|
+
|
|
13
|
+
def assign_serial_number
|
|
14
|
+
self.serial_number = "SN_#{(Time.now.to_f * 1000).to_i}"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Ecom
|
|
2
|
+
module Core
|
|
3
|
+
class MaterialSubType < ApplicationRecord
|
|
4
|
+
after_save :create_material_identity
|
|
5
|
+
|
|
6
|
+
belongs_to :material_type
|
|
7
|
+
has_many :material_identity
|
|
8
|
+
|
|
9
|
+
validates :name, presence: true, uniqueness: { case_sensitive: false, scope: :material_type_id }
|
|
10
|
+
validates :material_type_id, :material_type, presence: true
|
|
11
|
+
|
|
12
|
+
def create_material_identity
|
|
13
|
+
Ecom::Core::MaterialIdentity.create(
|
|
14
|
+
material_type_id: material_type_id,
|
|
15
|
+
material_sub_type_id: id
|
|
16
|
+
)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,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
|