cats_core 1.4.1 → 1.4.2
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/cats/core/commodities_controller.rb +1 -1
- data/app/controllers/cats/core/commodity_categories_controller.rb +5 -0
- data/app/controllers/cats/core/monthly_plans_controller.rb +3 -5
- data/app/models/cats/core/commodity.rb +0 -21
- data/app/models/cats/core/gift_certificate.rb +5 -2
- data/app/models/cats/core/monthly_plan.rb +24 -2
- data/app/models/cats/core/route.rb +9 -1
- data/app/models/cats/core/stack.rb +31 -4
- data/app/models/cats/core/transport_bid.rb +1 -1
- data/app/models/cats/core/transport_offer.rb +1 -0
- data/app/models/concerns/cats/core/dispatchable.rb +2 -2
- data/app/serializers/cats/core/commodity_serializer.rb +1 -1
- data/app/services/cats/core/stack_service.rb +18 -30
- data/config/routes.rb +1 -0
- data/db/migrate/20210717032602_create_cats_core_gift_certificates.rb +6 -1
- data/db/migrate/20210717033223_create_cats_core_commodities.rb +1 -0
- data/db/migrate/20211215121151_create_cats_core_transport_bids.rb +3 -2
- data/db/migrate/20211229160125_create_cats_core_transport_offers.rb +2 -0
- data/lib/cats/core/version.rb +1 -1
- data/spec/factories/cats/core/commodities.rb +1 -0
- data/spec/factories/cats/core/dispatch_plans.rb +4 -0
- data/spec/factories/cats/core/gift_certificates.rb +2 -0
- data/spec/factories/cats/core/stacking_rules.rb +3 -3
- data/spec/factories/cats/core/transport_bids.rb +3 -2
- metadata +2 -8
- data/app/models/cats/core/allocation.rb +0 -78
- data/app/models/cats/core/allocation_item.rb +0 -42
- data/db/migrate/20210718042823_create_cats_core_allocations.rb +0 -25
- data/db/migrate/20210718043204_create_cats_core_allocation_items.rb +0 -19
- data/spec/factories/cats/core/allocation_items.rb +0 -9
- data/spec/factories/cats/core/allocations.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16cbad0f2d1788e23d39a4b904aac57711bc3d6432b36ea4a96105ee9fccfd94
|
4
|
+
data.tar.gz: d3ff309544e77e52620b48c66f19be7488c7629bcd6a2e7cf45cd084f48ce835
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c38aaf1efefb124e3e2e1d2122d420f5fe152363580931ac0c49065a19392b092cd280e503ce84d674c87709f251d1f780c50674808b83c47c2f7cd3bcf48a89
|
7
|
+
data.tar.gz: d7c641de65a5a30397eecabd9af62c792e50e5540aeafbb1f795a720ce49a4d0747611a01af39ab086b72c6c8cd759deb1561940d1c31f09b2cda51c8c2b6a1d
|
@@ -34,7 +34,7 @@ module Cats
|
|
34
34
|
def model_params
|
35
35
|
params.require(:payload).permit(:batch_no, :description, :unit_of_measure_id, :source_id,
|
36
36
|
:source_type, :quantity, :best_use_before, :volume_per_metric_ton,
|
37
|
-
:arrival_status)
|
37
|
+
:arrival_status, :shipping_reference)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
@@ -9,6 +9,11 @@ module Cats
|
|
9
9
|
render json: { success: true, data: data }
|
10
10
|
end
|
11
11
|
|
12
|
+
def all
|
13
|
+
data = Cats::Core::CommodityCategory.all
|
14
|
+
render json: { success: true, data: data }
|
15
|
+
end
|
16
|
+
|
12
17
|
def root
|
13
18
|
data = Cats::Core::CommodityCategory.roots
|
14
19
|
render json: { success: true, data: serialize(data) }
|
@@ -17,12 +17,10 @@ module Cats
|
|
17
17
|
|
18
18
|
def approve
|
19
19
|
plan = Cats::Core::MonthlyPlan.find(params[:id])
|
20
|
-
|
21
|
-
render json: { success: false, error: 'Empty plan cannot be approved.' }, status: :unprocessable_entity
|
22
|
-
return
|
23
|
-
end
|
24
|
-
plan.update(status: Cats::Core::Plan::APPROVED)
|
20
|
+
plan.approve
|
25
21
|
render json: { success: true, data: serialize(plan) }
|
22
|
+
rescue StandardError => e
|
23
|
+
render json: { success: false, error: e.message }, status: :unprocessable_entity
|
26
24
|
end
|
27
25
|
|
28
26
|
def generate
|
@@ -31,8 +31,6 @@ module Cats
|
|
31
31
|
belongs_to :unit_of_measure
|
32
32
|
belongs_to :source, polymorphic: true
|
33
33
|
|
34
|
-
has_many :allocations
|
35
|
-
|
36
34
|
validates :best_use_before, presence: true
|
37
35
|
validates :batch_no, presence: true, uniqueness: true
|
38
36
|
validates :quantity, presence: true, numericality: { greater_than: 0 }
|
@@ -74,25 +72,6 @@ module Cats
|
|
74
72
|
end
|
75
73
|
result
|
76
74
|
end
|
77
|
-
|
78
|
-
def allocate(ignore_errors: true)
|
79
|
-
statuses = Allocation.where(commodity_id: id).map(&:allocation_status).uniq
|
80
|
-
unless statuses.count == 1 && statuses[0] == APPROVED
|
81
|
-
return if ignore_errors
|
82
|
-
|
83
|
-
raise(StandardError, 'There are allocations in "Draft" state.')
|
84
|
-
end
|
85
|
-
|
86
|
-
quantity = allocations.sum(:quantity)
|
87
|
-
unless quantity == self.quantity
|
88
|
-
return if ignore_errors
|
89
|
-
|
90
|
-
raise(StandardError, 'Total allocations quantity is not the same as commodity quantity.')
|
91
|
-
end
|
92
|
-
|
93
|
-
self.status = ALLOCATED
|
94
|
-
save!
|
95
|
-
end
|
96
75
|
end
|
97
76
|
end
|
98
77
|
end
|
@@ -4,21 +4,24 @@ module Cats
|
|
4
4
|
belongs_to :donation, optional: true
|
5
5
|
belongs_to :commodity_category
|
6
6
|
belongs_to :unit_of_measure
|
7
|
+
belongs_to :currency
|
7
8
|
belongs_to :destination_warehouse, class_name: 'Cats::Core::Location'
|
8
9
|
|
9
10
|
validates :reference_no, presence: true, uniqueness: true
|
10
|
-
validates :gift_date, :quantity, :requested_by, :
|
11
|
+
validates :gift_date, :quantity, :requested_by, :customs_office, presence: true
|
11
12
|
validates :quantity, numericality: { greater_than: 0 }
|
12
13
|
|
13
14
|
delegate(:name, to: :commodity_category, prefix: true)
|
14
15
|
delegate(:name, to: :destination_warehouse, prefix: true)
|
15
16
|
delegate(:abbreviation, to: :unit_of_measure, prefix: true)
|
17
|
+
delegate(:code, to: :currency, prefix: true)
|
16
18
|
|
17
19
|
before_validation :set_commodity_category
|
18
20
|
after_create :update_donation
|
19
21
|
|
20
22
|
def update_donation
|
21
|
-
|
23
|
+
return unless donation
|
24
|
+
|
22
25
|
return if donation.active
|
23
26
|
|
24
27
|
donation.active = true
|
@@ -3,6 +3,13 @@ module Cats
|
|
3
3
|
class MonthlyPlan < ApplicationRecord
|
4
4
|
include Dispatchable
|
5
5
|
|
6
|
+
DRAFT = 'Draft'.freeze
|
7
|
+
APPROVED = 'Approved'.freeze
|
8
|
+
RESERVED = 'Reserved'.freeze
|
9
|
+
NEEDS_APPROVED = 'Needs Approved'.freeze
|
10
|
+
|
11
|
+
STATUSES = [DRAFT, APPROVED, RESERVED, NEEDS_APPROVED].freeze
|
12
|
+
|
6
13
|
belongs_to :plan
|
7
14
|
belongs_to :region, class_name: 'Cats::Core::Location'
|
8
15
|
|
@@ -11,7 +18,7 @@ module Cats
|
|
11
18
|
has_many :monthly_rations
|
12
19
|
|
13
20
|
validates :reference_no, presence: true, uniqueness: true
|
14
|
-
validates :status, presence: true, inclusion: { in:
|
21
|
+
validates :status, presence: true, inclusion: { in: MonthlyPlan::STATUSES }
|
15
22
|
validates :no_of_days, :month, presence: true, numericality: { greater_than: 0 }
|
16
23
|
validate :validate_month, :validate_region
|
17
24
|
|
@@ -26,6 +33,21 @@ module Cats
|
|
26
33
|
nil
|
27
34
|
end
|
28
35
|
|
36
|
+
def approve
|
37
|
+
raise(StandardError, 'Plan is not in draft state.') unless status == DRAFT
|
38
|
+
|
39
|
+
raise(StandardError, 'Empty plan cannot be approved.') if monthly_plan_items.count.zero?
|
40
|
+
|
41
|
+
update!(status: APPROVED)
|
42
|
+
end
|
43
|
+
|
44
|
+
def reserve
|
45
|
+
raise(StandardError, 'Plan is not approved.') unless status == APPROVED
|
46
|
+
|
47
|
+
self.status = RESERVED
|
48
|
+
save!
|
49
|
+
end
|
50
|
+
|
29
51
|
def validate_month
|
30
52
|
return unless month
|
31
53
|
|
@@ -35,7 +57,7 @@ module Cats
|
|
35
57
|
def validate_region
|
36
58
|
return unless region
|
37
59
|
|
38
|
-
errors.add(:region, 'is not valid.') unless region.location_type ==
|
60
|
+
errors.add(:region, 'is not valid.') unless region.location_type == Location::REGION
|
39
61
|
end
|
40
62
|
end
|
41
63
|
end
|
@@ -8,7 +8,7 @@ module Cats
|
|
8
8
|
belongs_to :destination, class_name: 'Cats::Core::Location'
|
9
9
|
|
10
10
|
validates :source_id, uniqueness: { scope: :destination_id }
|
11
|
-
validate :validate_region, :validate_source, :validate_destination
|
11
|
+
validate :validate_region, :validate_source, :validate_destination, :validate_route
|
12
12
|
|
13
13
|
delegate(:name, to: :region, prefix: true)
|
14
14
|
|
@@ -35,6 +35,14 @@ module Cats
|
|
35
35
|
|
36
36
|
errors.add(:destination, 'cannot be a region.') if destination.location_type == Location::REGION
|
37
37
|
end
|
38
|
+
|
39
|
+
def validate_route
|
40
|
+
return unless source
|
41
|
+
|
42
|
+
return unless destination
|
43
|
+
|
44
|
+
errors.add(:base, 'Source and destination cannot be the same') if source == destination
|
45
|
+
end
|
38
46
|
end
|
39
47
|
end
|
40
48
|
end
|
@@ -20,7 +20,8 @@ module Cats
|
|
20
20
|
validates :commodity_status, inclusion: { in: Cats::Core::Commodity::COMMODITY_STATUSES }
|
21
21
|
validates :stack_status, inclusion: { in: STACK_STATUSES }
|
22
22
|
validate :validate_coordinates, :validate_dimensions, :validate_distance_from_wall, :validate_overlap,
|
23
|
-
:validate_space_between_stack,
|
23
|
+
:validate_space_between_stack, :validate_max_height, :validate_max_length, :validate_max_width,
|
24
|
+
:validate_distance_from_ceiling, unless: -> { store && store.code == 'SUP-STORE' }
|
24
25
|
|
25
26
|
delegate :batch_no, to: :commodity, prefix: true
|
26
27
|
|
@@ -48,9 +49,9 @@ module Cats
|
|
48
49
|
space_between_stack: 1,
|
49
50
|
distance_from_gangway: 2,
|
50
51
|
distance_from_ceiling: 1,
|
51
|
-
maximum_height:
|
52
|
-
maximum_length:
|
53
|
-
maximum_width:
|
52
|
+
maximum_height: 7,
|
53
|
+
maximum_length: 12,
|
54
|
+
maximum_width: 12,
|
54
55
|
distance_from_wall: 1
|
55
56
|
)
|
56
57
|
rule
|
@@ -92,6 +93,32 @@ module Cats
|
|
92
93
|
end
|
93
94
|
end
|
94
95
|
|
96
|
+
def validate_max_height
|
97
|
+
return unless height
|
98
|
+
|
99
|
+
errors.add(:height, 'exceeds stacking rule height.') if height > stacking_rules.maximum_height
|
100
|
+
end
|
101
|
+
|
102
|
+
def validate_max_length
|
103
|
+
return unless length
|
104
|
+
|
105
|
+
errors.add(:length, 'exceeds stacking rule length.') if length > stacking_rules.maximum_length
|
106
|
+
end
|
107
|
+
|
108
|
+
def validate_max_width
|
109
|
+
return unless width
|
110
|
+
|
111
|
+
errors.add(:width, 'exceeds stacking rule width.') if width > stacking_rules.maximum_width
|
112
|
+
end
|
113
|
+
|
114
|
+
def validate_distance_from_ceiling
|
115
|
+
return unless height && store
|
116
|
+
|
117
|
+
return unless store.height - height < stacking_rules.distance_from_ceiling
|
118
|
+
|
119
|
+
errors.add(:height, 'of stack is close to the ceiling.')
|
120
|
+
end
|
121
|
+
|
95
122
|
# A method that checks if an overlap exists b/n two stacks.
|
96
123
|
# An overlap b/n stacks does not occur if one of the stacks is completely above the other stack or
|
97
124
|
# if one of the stacks is on the left side of the other stack.
|
@@ -16,7 +16,7 @@ module Cats
|
|
16
16
|
belongs_to :transport_plan
|
17
17
|
|
18
18
|
validates :reference_no, presence: true, uniqueness: true
|
19
|
-
validates :start_date, :end_date, :status, :bid_bond_amount, presence: true
|
19
|
+
validates :start_date, :end_date, :opening_date, :status, :bid_bond_amount, presence: true
|
20
20
|
validates :bid_bond_amount, numericality: { greater_than_or_equal_to: 0 }
|
21
21
|
validates :status, inclusion: { in: STATUSES }
|
22
22
|
validate :validate_start_date_against_end_date
|
@@ -7,6 +7,7 @@ module Cats
|
|
7
7
|
|
8
8
|
validates :offer_date, :bid_bond_amount, presence: true
|
9
9
|
validates :bid_bond_amount, numericality: { greater_than_or_equal_to: 0 }
|
10
|
+
validates :transport_bid_id, uniqueness: { scope: :transporter_id }
|
10
11
|
|
11
12
|
delegate(:name, to: :transporter, prefix: true)
|
12
13
|
delegate(:reference_no, to: :transport_bid, prefix: 'bid')
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# A concern to represent entities that lead to dispatch plan.
|
2
|
-
# All classes including this concern must implement `request_reference()
|
3
|
-
# and `request_quantity()` methods, which will be used to generate
|
2
|
+
# All classes including this concern must implement `request_reference()`,
|
3
|
+
# `reserve()`, and `request_quantity()` methods, which will be used to generate
|
4
4
|
# reference information in dispatch plan serializer.
|
5
5
|
module Cats
|
6
6
|
module Core
|
@@ -3,7 +3,7 @@ module Cats
|
|
3
3
|
class CommoditySerializer < ActiveModel::Serializer
|
4
4
|
attributes :id, :name, :batch_no, :description, :unit_of_measure_id, :unit_of_measure_abbreviation, :source_id,
|
5
5
|
:source_type, :source_reference_no, :quantity, :best_use_before, :volume_per_metric_ton,
|
6
|
-
:arrival_status, :status
|
6
|
+
:arrival_status, :status, :shipping_reference
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
@@ -7,41 +7,29 @@ module Cats
|
|
7
7
|
key_available = details.keys.any? { |key| %w[stores warehouse hub].include?(key) }
|
8
8
|
raise(StandardError, 'User does not have associated location.') unless key_available
|
9
9
|
|
10
|
-
if details['hub']
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
hub = warehouse.parent
|
23
|
-
end
|
24
|
-
allocation_items =
|
25
|
-
Cats::Core::AllocationItem
|
26
|
-
.joins(allocation: :commodity)
|
27
|
-
.where(destination: hub, allocation: { allocation_status: Cats::Core::Allocation::APPROVED })
|
28
|
-
.or(
|
29
|
-
Cats::Core::AllocationItem
|
30
|
-
.joins(allocation: :commodity)
|
31
|
-
.where(destination: warehouse, allocation: { allocation_status: Cats::Core::Allocation::APPROVED })
|
32
|
-
)
|
33
|
-
end
|
10
|
+
hub = if details['hub']
|
11
|
+
Location.find(details['hub'])
|
12
|
+
elsif details['warehouse']
|
13
|
+
Location.find(details['warehouse']).parent
|
14
|
+
else
|
15
|
+
Store.find(details['stores'][0]).warehouse.parent
|
16
|
+
end
|
17
|
+
|
18
|
+
allocation_items =
|
19
|
+
DispatchPlanItem
|
20
|
+
.joins(dispatch_plan: :commodity)
|
21
|
+
.where(destination: hub, dispatch_plan: { status: DispatchPlan::APPROVED })
|
34
22
|
|
35
23
|
allocation_items.map do |item|
|
36
24
|
{
|
37
|
-
reference_no: item.
|
38
|
-
source: item.
|
25
|
+
reference_no: item.dispatch_plan.reference_no,
|
26
|
+
source: item.source.name,
|
39
27
|
destination: item.destination.name,
|
40
28
|
quantity: item.quantity,
|
41
|
-
batch_no: item.
|
42
|
-
commodity_id: item.
|
43
|
-
commodity_name: item.
|
44
|
-
unit: item.
|
29
|
+
batch_no: item.dispatch_plan.commodity.batch_no,
|
30
|
+
commodity_id: item.dispatch_plan.commodity_id,
|
31
|
+
commodity_name: item.dispatch_plan.commodity.name,
|
32
|
+
unit: item.dispatch_plan.commodity.unit_of_measure.abbreviation
|
45
33
|
}
|
46
34
|
end
|
47
35
|
end
|
data/config/routes.rb
CHANGED
@@ -60,6 +60,7 @@ Cats::Core::Engine.routes.draw do
|
|
60
60
|
defaults: { level: Cats::Core::SpaceService::STORE }
|
61
61
|
|
62
62
|
get '/commodity_categories/roots', to: 'commodity_categories#root', as: :commodity_category_roots
|
63
|
+
get '/commodity_categories/all', to: 'commodity_categories#all', as: :commodity_category_all
|
63
64
|
resources :commodity_categories, except: %i[destroy] do
|
64
65
|
member do
|
65
66
|
get 'children'
|
@@ -30,9 +30,14 @@ class CreateCatsCoreGiftCertificates < ActiveRecord::Migration[6.1]
|
|
30
30
|
foreign_key: { to_table: :cats_core_locations }
|
31
31
|
t.float :estimated_price
|
32
32
|
t.float :estimated_tax
|
33
|
+
t.references :currency,
|
34
|
+
null: false,
|
35
|
+
index: { name: 'currency_on_gc_indx' },
|
36
|
+
foreign_key: { to_table: :cats_core_currencies }
|
33
37
|
t.string :registration_no
|
34
38
|
t.string :requested_by, null: false
|
35
|
-
t.string :request_reference
|
39
|
+
t.string :request_reference
|
40
|
+
t.string :customs_office, null: false
|
36
41
|
|
37
42
|
t.timestamps
|
38
43
|
end
|
@@ -13,6 +13,7 @@ class CreateCatsCoreCommodities < ActiveRecord::Migration[6.1]
|
|
13
13
|
t.float :volume_per_metric_ton
|
14
14
|
t.string :arrival_status, null: false, default: 'At Source'
|
15
15
|
t.boolean :approved, null: false, default: false
|
16
|
+
t.string :shipping_reference
|
16
17
|
|
17
18
|
t.timestamps
|
18
19
|
end
|
@@ -3,8 +3,9 @@ class CreateCatsCoreTransportBids < ActiveRecord::Migration[6.1]
|
|
3
3
|
create_table :cats_core_transport_bids do |t|
|
4
4
|
t.string :reference_no, unique: true
|
5
5
|
t.string :description
|
6
|
-
t.
|
7
|
-
t.
|
6
|
+
t.datetime :start_date, null: false
|
7
|
+
t.datetime :end_date, null: false
|
8
|
+
t.datetime :opening_date, null: false
|
8
9
|
t.string :status, null: false, default: 'New'
|
9
10
|
t.float :bid_bond_amount, null: false, default: 0
|
10
11
|
t.references :transport_plan,
|
data/lib/cats/core/version.rb
CHANGED
@@ -15,8 +15,10 @@ FactoryBot.define do
|
|
15
15
|
quantity { 1.5 }
|
16
16
|
estimated_price { 1.5 }
|
17
17
|
estimated_tax { 1.5 }
|
18
|
+
currency
|
18
19
|
registration_no { FFaker::Name.name }
|
19
20
|
requested_by { FFaker::Name.name }
|
20
21
|
request_reference { FFaker::Name.name }
|
22
|
+
customs_office { FFaker::Name.name }
|
21
23
|
end
|
22
24
|
end
|
@@ -3,9 +3,9 @@ FactoryBot.define do
|
|
3
3
|
space_between_stack { 1 }
|
4
4
|
distance_from_gangway { 1.5 }
|
5
5
|
distance_from_ceiling { 1 }
|
6
|
-
maximum_height {
|
7
|
-
maximum_length {
|
8
|
-
maximum_width {
|
6
|
+
maximum_height { 7 }
|
7
|
+
maximum_length { 12 }
|
8
|
+
maximum_width { 12 }
|
9
9
|
distance_from_wall { 1 }
|
10
10
|
end
|
11
11
|
end
|
@@ -2,8 +2,9 @@ FactoryBot.define do
|
|
2
2
|
factory :transport_bid, class: 'Cats::Core::TransportBid' do
|
3
3
|
reference_no { FFaker::Name.name }
|
4
4
|
description { FFaker::Name.name }
|
5
|
-
start_date {
|
6
|
-
end_date {
|
5
|
+
start_date { DateTime.now - 1.week }
|
6
|
+
end_date { DateTime.now }
|
7
|
+
opening_date { DateTime.now + 1.week }
|
7
8
|
bid_bond_amount { 100 }
|
8
9
|
transport_plan
|
9
10
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cats_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henock L.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-04-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_model_serializers
|
@@ -255,8 +255,6 @@ files:
|
|
255
255
|
- app/controllers/cats/core/users_controller.rb
|
256
256
|
- app/controllers/concerns/cats/core/common.rb
|
257
257
|
- app/jobs/cats/core/application_job.rb
|
258
|
-
- app/models/cats/core/allocation.rb
|
259
|
-
- app/models/cats/core/allocation_item.rb
|
260
258
|
- app/models/cats/core/application_module.rb
|
261
259
|
- app/models/cats/core/application_record.rb
|
262
260
|
- app/models/cats/core/commodity.rb
|
@@ -374,8 +372,6 @@ files:
|
|
374
372
|
- db/migrate/20210718040129_create_cats_core_routes.rb
|
375
373
|
- db/migrate/20210718042749_create_cats_core_transporters.rb
|
376
374
|
- db/migrate/20210718042755_create_cats_core_rhn_requests.rb
|
377
|
-
- db/migrate/20210718042823_create_cats_core_allocations.rb
|
378
|
-
- db/migrate/20210718043204_create_cats_core_allocation_items.rb
|
379
375
|
- db/migrate/20210718043328_create_cats_core_dispatch_plans.rb
|
380
376
|
- db/migrate/20210718043401_create_cats_core_dispatch_plan_items.rb
|
381
377
|
- db/migrate/20210718045516_create_cats_core_dispatches.rb
|
@@ -409,8 +405,6 @@ files:
|
|
409
405
|
- lib/cats/core/version.rb
|
410
406
|
- lib/cats_core.rb
|
411
407
|
- lib/tasks/cats_core_tasks.rake
|
412
|
-
- spec/factories/cats/core/allocation_items.rb
|
413
|
-
- spec/factories/cats/core/allocations.rb
|
414
408
|
- spec/factories/cats/core/application_modules.rb
|
415
409
|
- spec/factories/cats/core/commodities.rb
|
416
410
|
- spec/factories/cats/core/commodity_categories.rb
|
@@ -1,78 +0,0 @@
|
|
1
|
-
module Cats
|
2
|
-
module Core
|
3
|
-
class Allocation < ApplicationRecord
|
4
|
-
DRAFT = 'Draft'.freeze
|
5
|
-
APPROVED = 'Approved'.freeze
|
6
|
-
ALLOCATION_STATUSES = [DRAFT, APPROVED].freeze
|
7
|
-
|
8
|
-
belongs_to :rhn_request, optional: true
|
9
|
-
belongs_to :commodity
|
10
|
-
belongs_to :source, class_name: 'Cats::Core::Location'
|
11
|
-
has_many :allocation_items
|
12
|
-
|
13
|
-
validates :commodity_status, :allocation_status, presence: true
|
14
|
-
validates :reference_no, presence: true, uniqueness: true
|
15
|
-
validates :quantity, presence: true, numericality: { greater_than: 0 }
|
16
|
-
validates :commodity_status, inclusion: { in: Commodity::COMMODITY_STATUSES }
|
17
|
-
validates :allocation_status, inclusion: { in: ALLOCATION_STATUSES }
|
18
|
-
validate :validate_quantity_against_items, :validate_quantity_against_commodity,
|
19
|
-
:validate_quantity_against_request, :validate_request_status, :validate_commodity_status
|
20
|
-
|
21
|
-
delegate(:reference_no, to: :rhn_request, prefix: :rhn, allow_nil: true)
|
22
|
-
delegate(:batch_no, to: :commodity, prefix: true)
|
23
|
-
delegate(:name, to: :source, prefix: true)
|
24
|
-
delegate(:location_type, to: :source, prefix: true)
|
25
|
-
|
26
|
-
def validate_quantity_against_items
|
27
|
-
return unless quantity
|
28
|
-
|
29
|
-
return unless quantity_changed?
|
30
|
-
|
31
|
-
allocated = allocation_items.sum(:quantity)
|
32
|
-
errors.add(:quantity, "is below items quantity. Minimum allowed is #{allocated}") if quantity < allocated
|
33
|
-
end
|
34
|
-
|
35
|
-
def validate_quantity_against_commodity
|
36
|
-
return unless quantity && commodity
|
37
|
-
|
38
|
-
allocated = Allocation.where(commodity: commodity).sum(:quantity)
|
39
|
-
remaining = commodity.quantity - allocated
|
40
|
-
|
41
|
-
remaining += quantity_was if quantity_was
|
42
|
-
errors.add(:quantity, "exceeds commodity quantity. Maximum allowed is #{remaining}") if quantity > remaining
|
43
|
-
end
|
44
|
-
|
45
|
-
def validate_quantity_against_request
|
46
|
-
return unless quantity && rhn_request
|
47
|
-
|
48
|
-
errors.add(:quantity, 'is not equal to requested quantity.') if quantity != rhn_request.quantity
|
49
|
-
end
|
50
|
-
|
51
|
-
def validate_request_status
|
52
|
-
return unless rhn_request
|
53
|
-
|
54
|
-
errors.add(:rhn_request, 'should be approved first.') if rhn_request.status != RhnRequest::APPROVED
|
55
|
-
end
|
56
|
-
|
57
|
-
def validate_commodity_status
|
58
|
-
return unless commodity
|
59
|
-
|
60
|
-
errors.add(:commodity, 'should be approved first.') unless commodity.status == Commodity::APPROVED
|
61
|
-
end
|
62
|
-
|
63
|
-
def approve
|
64
|
-
raise(StandardError, 'Allocation already approved.') if allocation_status == Allocation::APPROVED
|
65
|
-
|
66
|
-
item_quantity = allocation_items.sum(:quantity)
|
67
|
-
raise(StandardError, 'Allocation quantity and items quantity do not match.') if quantity != item_quantity
|
68
|
-
|
69
|
-
self.allocation_status = Allocation::APPROVED
|
70
|
-
save!
|
71
|
-
|
72
|
-
# If the commodity is all allocated, then we should
|
73
|
-
# set its status to allocated.
|
74
|
-
commodity.allocate
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
module Cats
|
2
|
-
module Core
|
3
|
-
class AllocationItem < ApplicationRecord
|
4
|
-
belongs_to :allocation
|
5
|
-
belongs_to :destination, class_name: 'Cats::Core::Location'
|
6
|
-
|
7
|
-
validates :from, :to, presence: true
|
8
|
-
validates :quantity, presence: true, numericality: { greater_than: 0 }
|
9
|
-
validate :validate_source_and_destination, :validate_quantity
|
10
|
-
validate :validate_allocation_status, on: %i[create update]
|
11
|
-
|
12
|
-
def validate_source_and_destination
|
13
|
-
return unless allocation.present? && destination.present?
|
14
|
-
|
15
|
-
errors.add(:base, 'source and destination cannot be the same') if allocation.source == destination
|
16
|
-
end
|
17
|
-
|
18
|
-
def validate_quantity
|
19
|
-
return unless quantity && allocation
|
20
|
-
|
21
|
-
return unless quantity_changed?
|
22
|
-
|
23
|
-
allocated = AllocationItem.where(allocation: allocation).sum(:quantity)
|
24
|
-
remaining = allocation.quantity - allocated
|
25
|
-
remaining += quantity_was if quantity_was
|
26
|
-
errors.add(:quantity, "exceeds allocated quantity. Maximum allowed is #{remaining}") if quantity > remaining
|
27
|
-
end
|
28
|
-
|
29
|
-
def validate_allocation_status
|
30
|
-
return unless allocation
|
31
|
-
|
32
|
-
return unless allocation.allocation_status == Cats::Core::Allocation::APPROVED
|
33
|
-
|
34
|
-
errors.add(:allocation, 'is alreay approved. Changes are not allowed at this point.')
|
35
|
-
end
|
36
|
-
|
37
|
-
delegate(:name, to: :destination, prefix: true)
|
38
|
-
delegate(:reference_no, to: :allocation, prefix: true)
|
39
|
-
delegate(:location_type, to: :destination, prefix: true)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
class CreateCatsCoreAllocations < ActiveRecord::Migration[6.1]
|
2
|
-
def change
|
3
|
-
create_table :cats_core_allocations do |t|
|
4
|
-
t.string :reference_no, unique: true
|
5
|
-
t.references :rhn_request,
|
6
|
-
null: true,
|
7
|
-
index: { name: 'rr_on_allocation_indx' },
|
8
|
-
foreign_key: { to_table: :cats_core_rhn_requests }
|
9
|
-
t.references :commodity,
|
10
|
-
null: false,
|
11
|
-
index: { name: 'ca_on_commodity_indx' },
|
12
|
-
foreign_key: { to_table: :cats_core_commodities }
|
13
|
-
t.references :source,
|
14
|
-
null: false,
|
15
|
-
index: { name: 'ca_on_source_indx' },
|
16
|
-
foreign_key: { to_table: :cats_core_locations }
|
17
|
-
t.float :quantity, null: false
|
18
|
-
t.string :commodity_status, null: false, default: 'Good'
|
19
|
-
t.string :allocation_status, null: false, default: 'Draft'
|
20
|
-
t.string :remark
|
21
|
-
|
22
|
-
t.timestamps
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
class CreateCatsCoreAllocationItems < ActiveRecord::Migration[6.1]
|
2
|
-
def change
|
3
|
-
create_table :cats_core_allocation_items do |t|
|
4
|
-
t.references :allocation,
|
5
|
-
null: false,
|
6
|
-
index: { name: 'allocation_on_ai_indx' },
|
7
|
-
foreign_key: { to_table: :cats_core_allocations }
|
8
|
-
t.references :destination,
|
9
|
-
null: false,
|
10
|
-
index: { name: 'destination_on_ai_indx'},
|
11
|
-
foreign_key: { to_table: :cats_core_locations }
|
12
|
-
t.float :quantity, null: false
|
13
|
-
t.date :from, null: false
|
14
|
-
t.date :to, null: false
|
15
|
-
|
16
|
-
t.timestamps
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
FactoryBot.define do
|
2
|
-
factory :allocation, class: 'Cats::Core::Allocation' do
|
3
|
-
reference_no { FFaker::Name.name }
|
4
|
-
rhn_request { nil }
|
5
|
-
commodity do
|
6
|
-
c = create(:commodity)
|
7
|
-
c.approve
|
8
|
-
c
|
9
|
-
end
|
10
|
-
source factory: :location
|
11
|
-
quantity { 50 }
|
12
|
-
commodity_status { Cats::Core::Commodity::GOOD }
|
13
|
-
allocation_status { Cats::Core::Allocation::DRAFT }
|
14
|
-
remark { FFaker::Name.name }
|
15
|
-
end
|
16
|
-
end
|