cats_core 1.3.38 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/cats/core/dispatch_plan_items_controller.rb +7 -1
- data/app/controllers/cats/core/dispatch_plans_controller.rb +2 -1
- data/app/controllers/cats/core/dispatch_transactions_controller.rb +20 -0
- data/app/controllers/cats/core/receipts_controller.rb +8 -18
- data/app/controllers/cats/core/stacks_controller.rb +37 -0
- data/app/controllers/cats/core/transporters_controller.rb +5 -0
- data/app/models/cats/core/stack.rb +1 -0
- data/app/notifications/cats/core/allocation_notification.rb +5 -3
- data/app/serializers/cats/core/dispatch_plan_item_serializer.rb +2 -1
- data/app/serializers/cats/core/monthly_plan_serializer.rb +2 -1
- data/app/serializers/cats/core/stack_serializer.rb +8 -0
- data/app/services/cats/core/dispatch_plan_service.rb +44 -2
- data/app/services/cats/core/receipt_service.rb +22 -0
- data/app/services/cats/core/stack_service.rb +59 -0
- data/config/routes.rb +16 -0
- data/lib/cats/core/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b1563c8d3250c1cda415de5081c46f445a82f593c727be676c3f9a7041f28fa7
|
4
|
+
data.tar.gz: b614991a9f6a2a4046c7c4e54af584d59a33478c62b5a0c6dee77ddbbdad2e6b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff00ffac606dfa2136aaaed05a6825238b5ae38f737f4a3790db2b94193f0108b6d394097c0828339af8aab226acf871d65ddefa68c54ad929a47e7069d9d49b
|
7
|
+
data.tar.gz: fd1b163787f8fc21ba49f79929f027143f1a45d74425518536d9adc4369eb33ea6ab9b96a30fb34b7cba6e9f8ba11e2f9f191acd83200debf91589cc9be490e3
|
@@ -8,10 +8,16 @@ module Cats
|
|
8
8
|
render json: { success: true, data: serialize(items) }
|
9
9
|
end
|
10
10
|
|
11
|
+
def filter
|
12
|
+
query = Cats::Core::DispatchPlanItem.ransack(params[:q])
|
13
|
+
render json: { success: true, data: serialize(query.result) }
|
14
|
+
end
|
15
|
+
|
11
16
|
private
|
12
17
|
|
13
18
|
def model_params
|
14
|
-
params.require(:payload).permit(:dispatch_plan_id, :source_id, :destination_id, :quantity, :commodity_status
|
19
|
+
params.require(:payload).permit(:dispatch_plan_id, :source_id, :destination_id, :quantity, :commodity_status,
|
20
|
+
:status)
|
15
21
|
end
|
16
22
|
end
|
17
23
|
end
|
@@ -22,8 +22,9 @@ module Cats
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def approve
|
25
|
+
service = DispatchPlanService.new
|
25
26
|
plan = Cats::Core::DispatchPlan.find(params[:id])
|
26
|
-
plan.approve
|
27
|
+
plan = service.approve(plan)
|
27
28
|
render json: { success: true, data: serialize(plan) }
|
28
29
|
rescue StandardError => e
|
29
30
|
render json: { success: false, error: e.message }
|
@@ -8,6 +8,26 @@ module Cats
|
|
8
8
|
render json: { success: true, data: serialize(transactions) }
|
9
9
|
end
|
10
10
|
|
11
|
+
# This end-point is used to create upstream dispatch transactions.
|
12
|
+
# We need a specific method like this because for upstream the source
|
13
|
+
# stack is a dummy one and we need to use that without waiting for the
|
14
|
+
# user to give us a source.
|
15
|
+
def create_allocation
|
16
|
+
dispatch = Dispatch.find(model_params[:dispatch_id])
|
17
|
+
commodity = dispatch.dispatch_plan_item.dispatch_plan.commodity
|
18
|
+
transaction = DispatchTransaction.new(model_params)
|
19
|
+
|
20
|
+
# Fetch supplier stack by commodity
|
21
|
+
stack = Stack.joins(:store).find_by(commodity: commodity, store: { code: 'SUP-STORE' })
|
22
|
+
transaction.source = stack
|
23
|
+
|
24
|
+
if transaction.save
|
25
|
+
render json: { success: true, data: serialize(transaction) }, status: :created
|
26
|
+
else
|
27
|
+
render json: { success: false, error: transaction.errors.full_messages[0] }, status: :unprocessable_entity
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
11
31
|
private
|
12
32
|
|
13
33
|
def model_params
|
@@ -9,26 +9,16 @@ module Cats
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def create
|
12
|
-
|
13
|
-
receipt =
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
if receipt
|
18
|
-
receipt.quantity += p[:quantity]
|
19
|
-
if receipt.save
|
20
|
-
render json: { success: true, data: serialize(receipt) }
|
21
|
-
else
|
22
|
-
render json: { success: false, error: receipt.errors.full_messages[0] }, status: :unprocessable_entity
|
23
|
-
end
|
12
|
+
service = ReceiptService.new
|
13
|
+
receipt = service.init(model_params)
|
14
|
+
|
15
|
+
if receipt.save
|
16
|
+
render json: { success: true, data: serialize(receipt) }
|
24
17
|
else
|
25
|
-
|
26
|
-
if obj.save
|
27
|
-
render json: { success: true, data: serialize(obj) }, status: :created
|
28
|
-
else
|
29
|
-
render json: { success: false, error: obj.errors.full_messages[0] }, status: :unprocessable_entity
|
30
|
-
end
|
18
|
+
render json: { success: false, error: receipt.errors.full_messages[0] }, status: :unprocessable_entity
|
31
19
|
end
|
20
|
+
rescue StandardError => e
|
21
|
+
render json: { success: false, error: e.message }
|
32
22
|
end
|
33
23
|
|
34
24
|
def start_stacking
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Cats
|
2
|
+
module Core
|
3
|
+
class StacksController < ApplicationController
|
4
|
+
include Common
|
5
|
+
|
6
|
+
def index
|
7
|
+
stacks = Stack.where(store_id: params[:id])
|
8
|
+
render json: { success: true, data: serialize(stacks) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def filter
|
12
|
+
query = Stack.where(store_id: params[:id]).ransack(params[:q])
|
13
|
+
render json: { success: true, data: serialize(query.result) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def commodity_for_location
|
17
|
+
service = StackService.new
|
18
|
+
commodities = service.commodity_for_location(current_user)
|
19
|
+
render json: { success: true, data: serialize(commodities) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def receipt_stacks
|
23
|
+
service = StackService.new
|
24
|
+
receipt = Receipt.find(params[:id])
|
25
|
+
stacks = service.receipt_stacks(receipt)
|
26
|
+
render json: { success: true, data: serialize(stacks) }
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def model_params
|
32
|
+
params.require(:payload).permit(:code, :length, :width, :height, :start_x, :start_y, :commodity_id, :store_id,
|
33
|
+
:commodity_status, :stack_status, :quantity)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -3,6 +3,11 @@ module Cats
|
|
3
3
|
class TransportersController < ApplicationController
|
4
4
|
include Cats::Core::Common
|
5
5
|
|
6
|
+
def filter
|
7
|
+
query = Cats::Core::Transporter.ransack(params[:q])
|
8
|
+
render json: { success: true, data: serialize(query.result) }
|
9
|
+
end
|
10
|
+
|
6
11
|
private
|
7
12
|
|
8
13
|
def model_params
|
@@ -71,6 +71,7 @@ module Cats
|
|
71
71
|
return unless store.present? && length.present? && width.present? && start_x.present? && start_y.present?
|
72
72
|
|
73
73
|
stacks = store.stacks.where(stack_status: [RESERVED, ALLOCATED]).where.not(id: id)
|
74
|
+
|
74
75
|
stacks.each do |s|
|
75
76
|
errors.add(:base, message: "#{code} overlaps with #{s.code}") if overlaps?(self, s)
|
76
77
|
end
|
@@ -12,15 +12,17 @@ module Cats
|
|
12
12
|
|
13
13
|
def message
|
14
14
|
allocation_item = params[:allocation_item]
|
15
|
-
commodity = allocation_item.
|
15
|
+
commodity = allocation_item.dispatch_plan.commodity.name
|
16
|
+
source = allocation_item.source.name
|
17
|
+
destination = allocation_item.destination.name
|
16
18
|
title = "Allocation Notification - #{commodity}"
|
17
19
|
date = Date.today
|
18
20
|
body = <<~BODY
|
19
21
|
Commodity with the following specification has been allocated to you:
|
20
|
-
Batch No. = #{allocation_item.
|
22
|
+
Batch No. = #{allocation_item.dispatch_plan.commodity.batch_no}
|
21
23
|
Commodity = #{commodity}
|
22
24
|
Quantity = #{allocation_item.quantity}
|
23
|
-
The commodity is expected to be delivered from #{
|
25
|
+
The commodity is expected to be delivered from #{source} to #{destination}
|
24
26
|
BODY
|
25
27
|
{ title: title, date: date, body: body }
|
26
28
|
end
|
@@ -2,7 +2,8 @@ module Cats
|
|
2
2
|
module Core
|
3
3
|
class DispatchPlanItemSerializer < ActiveModel::Serializer
|
4
4
|
attributes :id, :dispatch_plan_id, :plan_reference_no, :source_id, :source_name, :destination_id,
|
5
|
-
:destination_name, :quantity, :source_location_type, :destination_location_type, :commodity_status
|
5
|
+
:destination_name, :quantity, :source_location_type, :destination_location_type, :commodity_status,
|
6
|
+
:status
|
6
7
|
end
|
7
8
|
end
|
8
9
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module Cats
|
2
2
|
module Core
|
3
3
|
class MonthlyPlanSerializer < ActiveModel::Serializer
|
4
|
-
attributes :id, :reference_no, :status, :plan_id, :plan_reference_no, :region_id, :region_name, :month,
|
4
|
+
attributes :id, :reference_no, :status, :plan_id, :plan_reference_no, :region_id, :region_name, :month,
|
5
|
+
:no_of_days
|
5
6
|
end
|
6
7
|
end
|
7
8
|
end
|
@@ -4,8 +4,28 @@ module Cats
|
|
4
4
|
def approve(plan)
|
5
5
|
plan.approve
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
if plan.upstream
|
8
|
+
# Create source hub authorizations for each item and
|
9
|
+
# put them in a `Source Authorized` state
|
10
|
+
store = Store.find_by(code: 'SUP-STORE')
|
11
|
+
keeper = User.find_by(first_name: 'SUP-Storekeeper')
|
12
|
+
authorizations = []
|
13
|
+
plan.dispatch_plan_items.each do |item|
|
14
|
+
authorizations << {
|
15
|
+
dispatch_plan_item_id: item.id,
|
16
|
+
store_id: store.id,
|
17
|
+
quantity: item.quantity,
|
18
|
+
authorization_type: HubAuthorization::SOURCE,
|
19
|
+
authorized_by_id: keeper.id,
|
20
|
+
created_at: Date.today,
|
21
|
+
updated_at: Date.today
|
22
|
+
}
|
23
|
+
end
|
24
|
+
HubAuthorization.insert_all(authorizations)
|
25
|
+
plan.dispatch_plan_items.update_all(status: DispatchPlanItem::SOURCE_AUTHORIZED)
|
26
|
+
plan.dispatchable.allocate
|
27
|
+
end
|
28
|
+
send_notification(plan)
|
9
29
|
plan
|
10
30
|
end
|
11
31
|
|
@@ -17,6 +37,28 @@ module Cats
|
|
17
37
|
rescue ActiveRecord::RecordInvalid
|
18
38
|
raise(StandardError, plan.errors.full_messages[0])
|
19
39
|
end
|
40
|
+
|
41
|
+
def send_notification(allocation)
|
42
|
+
notification_rule = Cats::Core::NotificationRule.find_by(code: 'allocation')
|
43
|
+
raise(StandardError, 'Notification rule not found for allocation notification.') unless notification_rule
|
44
|
+
|
45
|
+
users = Cats::Core::User.joins(:roles).where(cats_core_roles: { name: notification_rule.roles })
|
46
|
+
allocation.dispatch_plan_items.each do |item|
|
47
|
+
location_id = item.destination_id
|
48
|
+
|
49
|
+
recipients = users.map do |user|
|
50
|
+
details = user.details
|
51
|
+
if (details.key?('warehouse') && details['warehouse'] == location_id) ||
|
52
|
+
(details.key?('hub') && details['hub'] == location_id)
|
53
|
+
user
|
54
|
+
end
|
55
|
+
end.compact
|
56
|
+
unless recipients.empty?
|
57
|
+
notification = Cats::Core::AllocationNotification.with(allocation_item: item)
|
58
|
+
notification.deliver(recipients)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
20
62
|
end
|
21
63
|
end
|
22
64
|
end
|
@@ -21,6 +21,28 @@ module Cats
|
|
21
21
|
receipt.save!
|
22
22
|
receipt
|
23
23
|
end
|
24
|
+
|
25
|
+
def init(params)
|
26
|
+
receipt = Cats::Core::Receipt.find_by(
|
27
|
+
dispatch_id: params[:dispatch_id],
|
28
|
+
commodity_status: params[:commodity_status]
|
29
|
+
)
|
30
|
+
|
31
|
+
if receipt
|
32
|
+
# We can assume that the plan item is destination authorized.
|
33
|
+
# Therefore no need for checking destination authorization.
|
34
|
+
receipt.quantity += params[:quantity]
|
35
|
+
return receipt
|
36
|
+
end
|
37
|
+
|
38
|
+
# Check if plan item is destination authorized
|
39
|
+
dispatch = Dispatch.find(params[:dispatch_id])
|
40
|
+
status = dispatch.dispatch_plan_item.status
|
41
|
+
statuses = [DispatchPlanItem::DESTINATION_AUTHORIZED, DispatchPlanItem::AUTHORIZED]
|
42
|
+
raise(StandardError, 'Plan item is not destination authorized.') unless statuses.include?(status)
|
43
|
+
|
44
|
+
Receipt.new(params)
|
45
|
+
end
|
24
46
|
end
|
25
47
|
end
|
26
48
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Cats
|
2
|
+
module Core
|
3
|
+
class StackService
|
4
|
+
def commodity_for_location(user)
|
5
|
+
details = user.details
|
6
|
+
|
7
|
+
key_available = details.keys.any? { |key| %w[stores warehouse hub].include?(key) }
|
8
|
+
raise(StandardError, 'User does not have associated location.') unless key_available
|
9
|
+
|
10
|
+
if details['hub']
|
11
|
+
hub = Cats::Core::Location.find(details['hub'])
|
12
|
+
allocation_items =
|
13
|
+
Cats::Core::AllocationItem
|
14
|
+
.joins(allocation: :commodity)
|
15
|
+
.where(destination: hub, allocation: { allocation_status: Cats::Core::Allocation::APPROVED })
|
16
|
+
else
|
17
|
+
if details['stores']
|
18
|
+
warehouse = Cats::Core::Store.find(details['stores'][0]).warehouse
|
19
|
+
hub = warehouse.parent
|
20
|
+
elsif details['warehouse']
|
21
|
+
warehouse = Cats::Core::Location.find(details['warehouse'])
|
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
|
34
|
+
|
35
|
+
allocation_items.map do |item|
|
36
|
+
{
|
37
|
+
reference_no: item.allocation.reference_no,
|
38
|
+
source: item.allocation.source.name,
|
39
|
+
destination: item.destination.name,
|
40
|
+
quantity: item.quantity,
|
41
|
+
batch_no: item.allocation.commodity.batch_no,
|
42
|
+
commodity_id: item.allocation.commodity_id,
|
43
|
+
commodity_name: item.allocation.commodity.name,
|
44
|
+
unit: item.allocation.commodity.unit_of_measure.abbreviation
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def receipt_stacks(receipt)
|
50
|
+
location = receipt.dispatch.dispatch_plan_item.destination
|
51
|
+
warehouses = location.children
|
52
|
+
stores = Cats::Core::Store.where(warehouse: warehouses)
|
53
|
+
|
54
|
+
commodity = receipt.dispatch.dispatch_plan_item.dispatch_plan.commodity
|
55
|
+
Cats::Core::Stack.where(commodity: commodity, store: stores)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/config/routes.rb
CHANGED
@@ -73,6 +73,8 @@ Cats::Core::Engine.routes.draw do
|
|
73
73
|
end
|
74
74
|
resources :currencies, except: %i[destroy]
|
75
75
|
resources :unit_of_measures, except: %i[destroy]
|
76
|
+
|
77
|
+
post '/transporters/filter', controller: :transporters, action: :filter
|
76
78
|
resources :transporters, except: %i[destroy]
|
77
79
|
|
78
80
|
post '/routes/filter', controller: :routes, action: :filter
|
@@ -88,6 +90,7 @@ Cats::Core::Engine.routes.draw do
|
|
88
90
|
|
89
91
|
resources :dispatch_plan_items, except: %i[index destroy]
|
90
92
|
|
93
|
+
post '/dispatch_plan_items/filter', controller: :dispatch_plan_items, action: :filter
|
91
94
|
get '/dispatch_plan_items/:id/dispatches', controller: :dispatches, action: :index, as: :dispatches_plan_item
|
92
95
|
|
93
96
|
get '/dispatches/search', controller: :dispatches, action: :search, as: :search_dispatches
|
@@ -102,6 +105,13 @@ Cats::Core::Engine.routes.draw do
|
|
102
105
|
post 'confirm'
|
103
106
|
end
|
104
107
|
end
|
108
|
+
|
109
|
+
post(
|
110
|
+
'dispatch_transactions/allocation',
|
111
|
+
controller: :dispatch_transactions,
|
112
|
+
action: :create_allocation,
|
113
|
+
as: :allocation_transaction
|
114
|
+
)
|
105
115
|
resources :dispatch_transactions, except: %i[index new edit destroy]
|
106
116
|
resources :receipts, except: %i[index new edit destroy] do
|
107
117
|
member do
|
@@ -122,4 +132,10 @@ Cats::Core::Engine.routes.draw do
|
|
122
132
|
post 'approve'
|
123
133
|
end
|
124
134
|
end
|
135
|
+
|
136
|
+
get '/stores/:id/stacks', controller: :stacks, action: :index, as: :stacks_store
|
137
|
+
post '/stores/:id/stacks', controller: :stacks, action: :filter
|
138
|
+
get '/stacks/commodity_for_location', controller: :stacks, action: :commodity_for_location, as: :commodity_for_location
|
139
|
+
get '/receipts/:id/stacks', controller: :stacks, action: :receipt_stacks, as: :receipt_stacks
|
140
|
+
resources :stacks, only: %i[show index create update]
|
125
141
|
end
|
data/lib/cats/core/version.rb
CHANGED
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
|
+
version: 1.4.0
|
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-03-
|
11
|
+
date: 2022-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_model_serializers
|
@@ -249,6 +249,7 @@ files:
|
|
249
249
|
- app/controllers/cats/core/roles_controller.rb
|
250
250
|
- app/controllers/cats/core/routes_controller.rb
|
251
251
|
- app/controllers/cats/core/spaces_controller.rb
|
252
|
+
- app/controllers/cats/core/stacks_controller.rb
|
252
253
|
- app/controllers/cats/core/transporters_controller.rb
|
253
254
|
- app/controllers/cats/core/unit_of_measures_controller.rb
|
254
255
|
- app/controllers/cats/core/users_controller.rb
|
@@ -331,6 +332,7 @@ files:
|
|
331
332
|
- app/serializers/cats/core/role_menu_serializer.rb
|
332
333
|
- app/serializers/cats/core/role_serializer.rb
|
333
334
|
- app/serializers/cats/core/route_serializer.rb
|
335
|
+
- app/serializers/cats/core/stack_serializer.rb
|
334
336
|
- app/serializers/cats/core/transporter_serializer.rb
|
335
337
|
- app/serializers/cats/core/unit_of_measure_serializer.rb
|
336
338
|
- app/serializers/cats/core/user_serializer.rb
|
@@ -341,6 +343,7 @@ files:
|
|
341
343
|
- app/services/cats/core/notification_service.rb
|
342
344
|
- app/services/cats/core/receipt_service.rb
|
343
345
|
- app/services/cats/core/space_service.rb
|
346
|
+
- app/services/cats/core/stack_service.rb
|
344
347
|
- app/services/cats/core/token_auth_service.rb
|
345
348
|
- config/routes.rb
|
346
349
|
- db/migrate/20210715114238_create_cats_core_application_modules.rb
|