cats_core 1.4.25 → 1.4.28
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/receipt_authorizations_controller.rb +31 -0
- data/app/controllers/cats/core/round_plans_controller.rb +2 -3
- data/app/controllers/cats/core/stacks_controller.rb +2 -2
- data/app/models/cats/core/beneficiary_plan_item.rb +21 -0
- data/app/models/cats/core/beneficiary_round_plan_item.rb +1 -0
- data/app/models/cats/core/dispatch.rb +15 -4
- data/app/services/cats/core/authorization_service.rb +20 -0
- data/app/services/cats/core/round_plan_service.rb +37 -1
- data/app/services/cats/core/stack_service.rb +4 -7
- data/config/routes.rb +12 -3
- data/db/migrate/20210717032290_create_cats_core_beneficiary_plan_items.rb +3 -0
- data/db/migrate/20220107126025_create_cats_core_beneficiary_round_plan_items.rb +1 -0
- data/lib/cats/core/version.rb +1 -1
- data/spec/factories/cats/core/beneficiary_plan_items.rb +2 -0
- data/spec/factories/cats/core/beneficiary_round_plan_items.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2cbd9de4f75e95103bf09a853e5d0098e925f6d63c058567657dca04c8e915e
|
4
|
+
data.tar.gz: 39dc39668040493ad924ae291ea3f13b34b3644f113558274bbe8f15564d9f1b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dca66c438930ac24dc216e3ef8f162bae9d0ef54442efaeb2139953379366e9fd93a3fd13ed08cc396f19b6383007f0cee5433ef69cdc863e39a96da92969f8c
|
7
|
+
data.tar.gz: 22e99525720f4e34f0bae5fec105ebfaa80f28c73ce0b60c7323536e167bf54ef735969cafcd602124cfa148983207c9364707f62a4d74835d0fad597f85c793
|
@@ -3,6 +3,8 @@ module Cats
|
|
3
3
|
class ReceiptAuthorizationsController < ApplicationController
|
4
4
|
include Common
|
5
5
|
|
6
|
+
skip_before_action :authenticate, only: %i[driver_confirm]
|
7
|
+
|
6
8
|
def index
|
7
9
|
super do
|
8
10
|
ReceiptAuthorization.where(dispatch_id: params[:id])
|
@@ -17,11 +19,40 @@ module Cats
|
|
17
19
|
render json: { success: false, error: e.message }
|
18
20
|
end
|
19
21
|
|
22
|
+
def driver_confirm
|
23
|
+
service = AuthorizationService.new
|
24
|
+
authorization = service.driver_confirm(params[:id], driver_confirm_params[:pin])
|
25
|
+
render json: { success: true, data: serialize(authorization) }
|
26
|
+
rescue StandardError => e
|
27
|
+
render json: { success: false, error: e.message }
|
28
|
+
end
|
29
|
+
|
30
|
+
def stack
|
31
|
+
service = AuthorizationService.new
|
32
|
+
authorization = ReceiptAuthorization.find(params[:id])
|
33
|
+
authorization = service.stack(authorization.id)
|
34
|
+
render json: { success: true, data: serialize(authorization) }
|
35
|
+
rescue StandardError => e
|
36
|
+
render json: { success: false, error: e.message }
|
37
|
+
end
|
38
|
+
|
39
|
+
def storekeeper_authorizations
|
40
|
+
storekeeper = User.find(params[:id])
|
41
|
+
status = params[:status]
|
42
|
+
stores = storekeeper.stores
|
43
|
+
authorizations = ReceiptAuthorization.where(store: stores, status: status)
|
44
|
+
render json: { success: true, data: serialize(authorizations) }
|
45
|
+
end
|
46
|
+
|
20
47
|
private
|
21
48
|
|
22
49
|
def model_params
|
23
50
|
params.require(:payload).permit(:dispatch_id, :store_id, :quantity, :remark, :status, :authorized_by_id)
|
24
51
|
end
|
52
|
+
|
53
|
+
def driver_confirm_params
|
54
|
+
params.require(:payload).permit(:pin)
|
55
|
+
end
|
25
56
|
end
|
26
57
|
end
|
27
58
|
end
|
@@ -3,7 +3,7 @@ module Cats
|
|
3
3
|
class RoundPlansController < ApplicationController
|
4
4
|
include Common
|
5
5
|
|
6
|
-
before_action :set_service, only: %i[generate remove_items generate_round_needs]
|
6
|
+
before_action :set_service, only: %i[approve generate remove_items generate_round_needs]
|
7
7
|
|
8
8
|
def index
|
9
9
|
super do
|
@@ -17,8 +17,7 @@ module Cats
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def approve
|
20
|
-
plan =
|
21
|
-
plan.approve
|
20
|
+
plan = @service.approve(params[:id])
|
22
21
|
render json: { success: true, data: serialize(plan) }
|
23
22
|
rescue StandardError => e
|
24
23
|
render json: { success: false, error: e.message }, status: :unprocessable_entity
|
@@ -29,8 +29,8 @@ module Cats
|
|
29
29
|
|
30
30
|
def receipt_stacks
|
31
31
|
service = StackService.new
|
32
|
-
|
33
|
-
stacks = service.receipt_stacks(
|
32
|
+
authorization = ReceiptAuthorization.find(params[:id])
|
33
|
+
stacks = service.receipt_stacks(authorization.id)
|
34
34
|
render json: { success: true, data: serialize(stacks) }
|
35
35
|
end
|
36
36
|
|
@@ -8,7 +8,28 @@ module Cats
|
|
8
8
|
validates :beneficiaries, presence: true, numericality: { greater_than: 0 }
|
9
9
|
validates :plan_item_id, uniqueness: { scope: :beneficiary_category_id }
|
10
10
|
|
11
|
+
validates :rounds, presence: true, numericality: { greater_than: 0 }, if: :psnp?
|
12
|
+
validates :rounds_served, presence: true, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true, if: :psnp?
|
13
|
+
validates :rounds, :rounds_served, absence: true, unless: :psnp?
|
14
|
+
validate :validate_rounds
|
15
|
+
|
11
16
|
delegate(:name, to: :beneficiary_category, prefix: true)
|
17
|
+
|
18
|
+
def psnp?
|
19
|
+
return false unless plan_item
|
20
|
+
|
21
|
+
plan_item.plan.program.code == 'PSNP'
|
22
|
+
end
|
23
|
+
|
24
|
+
def validate_rounds
|
25
|
+
return unless rounds && rounds_served
|
26
|
+
|
27
|
+
errors.add(:rounds, 'should not be set for non PSNP plans.') unless psnp?
|
28
|
+
|
29
|
+
errors.add(:rounds_served, 'should not be set for non PSNP plans.') unless psnp?
|
30
|
+
|
31
|
+
errors.add(:rounds, 'cannot be lower than rounds served.') if rounds < rounds_served
|
32
|
+
end
|
12
33
|
end
|
13
34
|
end
|
14
35
|
end
|
@@ -7,6 +7,7 @@ module Cats
|
|
7
7
|
|
8
8
|
validates :beneficiaries, presence: true, numericality: { greater_than_or_equal_to: 0 }
|
9
9
|
validates :round_plan_item_id, uniqueness: { scope: :beneficiary_category_id }
|
10
|
+
validates :beneficiary_plan_item_id, presence: true
|
10
11
|
|
11
12
|
delegate(:name, to: :beneficiary_category, prefix: true)
|
12
13
|
end
|
@@ -5,11 +5,10 @@ module Cats
|
|
5
5
|
APPROVED = 'Approved'.freeze
|
6
6
|
READY_TO_START = 'Ready to Start'.freeze
|
7
7
|
STARTED = 'Started'.freeze
|
8
|
-
ARRIVED = 'Arrived'.freeze
|
9
|
-
UNLOADED = 'Unloaded'.freeze
|
10
8
|
RECEIVED = 'Received'.freeze
|
9
|
+
STACKED = 'Stacked'.freeze
|
11
10
|
|
12
|
-
DISPATCH_STATUSES = [DRAFT, APPROVED, READY_TO_START, STARTED,
|
11
|
+
DISPATCH_STATUSES = [DRAFT, APPROVED, READY_TO_START, STARTED, RECEIVED, STACKED].freeze
|
13
12
|
|
14
13
|
belongs_to :prepared_by, class_name: 'Cats::Core::User'
|
15
14
|
belongs_to :transporter
|
@@ -73,12 +72,24 @@ module Cats
|
|
73
72
|
save!
|
74
73
|
end
|
75
74
|
|
75
|
+
def receive
|
76
|
+
raise(StandardError, 'Dispatch is not started.') unless dispatch_status == Dispatch::STARTED
|
77
|
+
|
78
|
+
self.dispatch_status = RECEIVED
|
79
|
+
save!
|
80
|
+
end
|
81
|
+
|
82
|
+
def stack
|
83
|
+
self.dispatch_status = STACKED
|
84
|
+
save!
|
85
|
+
end
|
86
|
+
|
76
87
|
def self.search_commodity(batch_no)
|
77
88
|
commodity = Commodity.find_by(batch_no: batch_no)
|
78
89
|
dispatches = Dispatch.includes(:dispatch_transactions)
|
79
90
|
.joins(:transporter)
|
80
91
|
.where(
|
81
|
-
dispatch_status: [APPROVED, STARTED
|
92
|
+
dispatch_status: [APPROVED, STARTED]
|
82
93
|
)
|
83
94
|
dispatches.map do |dispatch|
|
84
95
|
{
|
@@ -18,8 +18,28 @@ module Cats
|
|
18
18
|
authorization.save!
|
19
19
|
raise(StandardError, 'Pin has expired.')
|
20
20
|
end
|
21
|
+
|
21
22
|
authorization.driver_confirmed = true
|
22
23
|
authorization.save!
|
24
|
+
statuses = authorization.dispatch.receipt_authorizations.map(&:driver_confirmed).uniq
|
25
|
+
authorization.dispatch.receive if statuses.length == 1 && statuses[0]
|
26
|
+
|
27
|
+
authorization
|
28
|
+
end
|
29
|
+
|
30
|
+
def stack(authorization_id)
|
31
|
+
authorization = ReceiptAuthorization.find(authorization_id)
|
32
|
+
unless authorization.dispatch.dispatch_status == Dispatch::RECEIVED
|
33
|
+
raise(StandardError, 'Dispatch is not received.')
|
34
|
+
end
|
35
|
+
|
36
|
+
total = authorization.transactions.sum(:quantity)
|
37
|
+
if total != authorization.received_quantity
|
38
|
+
raise(StandardError, 'Received quantity is not the same as quantity to be stacked.')
|
39
|
+
end
|
40
|
+
|
41
|
+
authorization.transactions.each(&:commit)
|
42
|
+
authorization.dispatch.stack
|
23
43
|
authorization
|
24
44
|
end
|
25
45
|
end
|
@@ -79,7 +79,8 @@ module Cats
|
|
79
79
|
round_plan_item_id: item[0],
|
80
80
|
beneficiary_category_id: ben_plan_item.beneficiary_category_id,
|
81
81
|
planned_beneficiaries: ben_plan_item.beneficiaries,
|
82
|
-
beneficiaries: ben_plan_item.beneficiaries
|
82
|
+
beneficiaries: ben_plan_item.beneficiaries,
|
83
|
+
beneficiary_plan_item_id: ben_plan_item.id
|
83
84
|
}
|
84
85
|
end
|
85
86
|
Cats::Core::BeneficiaryRoundPlanItem.insert_all!(ben_round_plan_items, record_timestamps: true)
|
@@ -103,6 +104,41 @@ module Cats
|
|
103
104
|
Cats::Core::RoundPlanItem.delete_by(id: ids)
|
104
105
|
plan
|
105
106
|
end
|
107
|
+
|
108
|
+
def approve(plan_id)
|
109
|
+
plan = RoundPlan.find(plan_id)
|
110
|
+
if plan.plan.program.code == 'PSNP'
|
111
|
+
rounds = plan.rounds.count
|
112
|
+
item_ids = plan.beneficiary_round_plan_items.pluck('beneficiary_plan_item_id').flatten
|
113
|
+
plan_items = BeneficiaryPlanItem.where(id: item_ids)
|
114
|
+
invalid = plan_items.select { |pi| pi.rounds - (pi.rounds_served || 0) < rounds }
|
115
|
+
error = 'There are plan items whose served rounds may exceed the allowed number of rounds.'
|
116
|
+
raise(StandardError, error) if invalid.count.positive?
|
117
|
+
|
118
|
+
items = plan_items.each_with_object([]) do |plan_item, res|
|
119
|
+
rounds_served = plan_item.rounds_served || 0
|
120
|
+
res << "(#{plan_item.id}, #{rounds + rounds_served})"
|
121
|
+
end
|
122
|
+
values = items.join(',')
|
123
|
+
sql = <<-SQL
|
124
|
+
UPDATE cats_core_beneficiary_plan_items AS bpi
|
125
|
+
SET
|
126
|
+
rounds_served = l.rounds_served
|
127
|
+
FROM (
|
128
|
+
VALUES
|
129
|
+
#{values}
|
130
|
+
) AS l(id, rounds_served)
|
131
|
+
WHERE l.id = bpi.id
|
132
|
+
SQL
|
133
|
+
ActiveRecord::Base.transaction do
|
134
|
+
ActiveRecord::Base.connection.execute(sql)
|
135
|
+
plan.approve
|
136
|
+
end
|
137
|
+
else
|
138
|
+
plan.approve
|
139
|
+
end
|
140
|
+
plan
|
141
|
+
end
|
106
142
|
end
|
107
143
|
end
|
108
144
|
end
|
@@ -34,13 +34,10 @@ module Cats
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
def receipt_stacks(
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
commodity = receipt.dispatch.dispatch_plan_item.commodity
|
43
|
-
Stack.where(commodity: commodity, store: stores)
|
37
|
+
def receipt_stacks(authorization_id)
|
38
|
+
authorization = ReceiptAuthorization.find(authorization_id)
|
39
|
+
commodity = authorization.dispatch.dispatch_plan_item.commodity
|
40
|
+
Stack.where(commodity: commodity, store_id: authorization.store_id)
|
44
41
|
end
|
45
42
|
|
46
43
|
def dispatch_stacks(dispatch)
|
data/config/routes.rb
CHANGED
@@ -119,17 +119,26 @@ Cats::Core::Engine.routes.draw do
|
|
119
119
|
end
|
120
120
|
|
121
121
|
get(
|
122
|
-
'/storekeeper/:id/
|
122
|
+
'/storekeeper/:id/dispatch_authorizations',
|
123
123
|
controller: :dispatch_authorizations,
|
124
124
|
action: :storekeeper_authorizations,
|
125
|
-
as: :
|
125
|
+
as: :storekeeper_dispatch_authorizations
|
126
|
+
)
|
127
|
+
get(
|
128
|
+
'/storekeeper/:id/receipt_authorizations',
|
129
|
+
controller: :receipt_authorizations,
|
130
|
+
action: :storekeeper_authorizations,
|
131
|
+
as: :storekeeper_receipt_authorizations
|
126
132
|
)
|
127
133
|
resources :receipt_authorizations, except: %i[index destroy] do
|
128
134
|
member do
|
129
135
|
get 'transactions', controller: :receipt_transactions, action: :index
|
130
136
|
get 'lost', controller: :lost_commodities, action: :index
|
131
137
|
get 'receipts', controller: :receipts, action: :index
|
132
|
-
|
138
|
+
get 'stacks', controller: :stacks, action: :receipt_stacks
|
139
|
+
post 'confirm'
|
140
|
+
post 'driver_confirm'
|
141
|
+
post 'stack'
|
133
142
|
end
|
134
143
|
end
|
135
144
|
|
@@ -11,6 +11,9 @@ class CreateCatsCoreBeneficiaryPlanItems < ActiveRecord::Migration[7.0]
|
|
11
11
|
foreign_key: { to_table: :cats_core_beneficiary_categories }
|
12
12
|
t.integer :beneficiaries, null: false
|
13
13
|
|
14
|
+
t.integer :rounds
|
15
|
+
t.integer :rounds_served
|
16
|
+
|
14
17
|
t.timestamps
|
15
18
|
end
|
16
19
|
add_index(
|
@@ -11,6 +11,7 @@ class CreateCatsCoreBeneficiaryRoundPlanItems < ActiveRecord::Migration[7.0]
|
|
11
11
|
foreign_key: { to_table: :cats_core_beneficiary_categories }
|
12
12
|
t.integer :planned_beneficiaries, null: false
|
13
13
|
t.integer :beneficiaries, null: false
|
14
|
+
t.integer :beneficiary_plan_item_id, null: false
|
14
15
|
|
15
16
|
t.timestamps
|
16
17
|
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.
|
4
|
+
version: 1.4.28
|
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-05-
|
11
|
+
date: 2022-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_model_serializers
|