cats_core 1.4.42 → 1.4.43

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b075feb71a427f4901c4fb32fe34f8b2ad2dfb902a3386b9c92b10fd6e809762
4
- data.tar.gz: 283f7c441c7d3920fbe5a7ce4253d41d24fccbaa9432d634f7004abe2cfa531f
3
+ metadata.gz: c6e5cfab401c5346af868d378d9a068b2cef5a154e803d5fd940f2d9bebdd8ff
4
+ data.tar.gz: de1ea59da4f3e9a283685e84813e2285202d707d9d5bac98d26abc4d87820ac5
5
5
  SHA512:
6
- metadata.gz: 8975cb79857ea468f7c13b638ff8668849b3d0021d59df037f1d88ceb508090481fe10da028a5b5a54ee23117c270c1b67e1d8b9149bc9eeec421015ea92eda9
7
- data.tar.gz: 54936908e0394ead9f8f8ffd887949f1f6afbd1fcb63d7cdf90b5d9d0f32dcd6a0b5f73009d326c03550b5ce43bce7d8bbf758e8a2a735b23c6b653302b48eba
6
+ metadata.gz: 1d1ad46c73a7f35f1916fd9328dbef03cfeb3b6736566eac0c44ef2372bcea6dc6b804e313396c8ed7abe05a17ff2ae2f865a6b091337cbbab0e53f075938ac1
7
+ data.tar.gz: f9f9633161e3578d49ea763e6254cd18706ce7fb0abaf3673d8321e21399a16f4cc3aac607106117901eee84a15fd44e95ed8faffa56454786d51575d926f5c3
@@ -0,0 +1,49 @@
1
+ module Cats
2
+ module Core
3
+ class RoundBeneficiariesController < ApplicationController
4
+ include Common
5
+
6
+ def index
7
+ beneficiaries = RoundBeneficiary.joins(:round_plan_item)
8
+ .where(round_plan_item: { round_plan_id: params[:id] })
9
+ .includes(:beneficiary, :commodity_category, :unit)
10
+ render json: { success: true, data: serialize(beneficiaries) }
11
+ end
12
+
13
+ def generate
14
+ service = BeneficiaryService.new
15
+ result = service.generate_distribution_list(params[:id])
16
+ render json: { success: result }
17
+ rescue StandardError => e
18
+ render json: { success: false, error: e.message }
19
+ end
20
+
21
+ def filter
22
+ query = RoundBeneficiary.includes(:beneficiary, :commodity_category, :unit).ransack(params[:q])
23
+ render json: { success: true, data: serialize(query.result) }
24
+ end
25
+
26
+ def remove_beneficiaries
27
+ service = BeneficiaryService.new
28
+ result = service.remove_items(params[:id], common_params[:ids])
29
+ render json: { success: result }
30
+ rescue StandardError => e
31
+ render json: { success: false, error: e.message }
32
+ end
33
+
34
+ def confirm_receipt
35
+ service = BeneficiaryService.new
36
+ result = service.confirm_receipt(params[:id], common_params[:ids])
37
+ render json: { success: result }
38
+ rescue StandardError => e
39
+ render json: { success: false, error: e.message }
40
+ end
41
+
42
+ private
43
+
44
+ def common_params
45
+ params.permit(ids: [])
46
+ end
47
+ end
48
+ end
49
+ end
@@ -6,12 +6,21 @@ module Cats
6
6
  GENDERS = [MALE, FEMALE].freeze
7
7
 
8
8
  belongs_to :beneficiary_category
9
+ belongs_to :fdp, class_name: 'Location'
9
10
 
10
11
  validates :full_name, :age, :gender, presence: true
11
12
  validates :gender, inclusion: { in: GENDERS }
12
13
  validates :age, numericality: { greater_than: 0, less_than: 100 }
14
+ validate :validate_fdp
13
15
 
14
16
  delegate(:name, to: :beneficiary_category, prefix: true)
17
+ delegate(:name, to: :fdp, prefix: true)
18
+
19
+ def validate_fdp
20
+ return unless fdp
21
+
22
+ errors.add(:fdp, 'should be a valid distribution point.') unless fdp.location_type == Location::FDP
23
+ end
15
24
  end
16
25
  end
17
26
  end
@@ -27,6 +27,10 @@ module Cats
27
27
  validates :season, presence: true, inclusion: { in: SEASONS }
28
28
  validates :reference_no, uniqueness: true
29
29
  validates :status, inclusion: { in: STATUSES }
30
+
31
+ def no_of_round_days
32
+ total_days / rounds
33
+ end
30
34
  end
31
35
  end
32
36
  end
@@ -0,0 +1,16 @@
1
+ module Cats
2
+ module Core
3
+ class RoundBeneficiary < ApplicationRecord
4
+ belongs_to :beneficiary
5
+ belongs_to :round_plan_item
6
+ belongs_to :commodity_category
7
+ belongs_to :unit, class_name: 'UnitOfMeasure'
8
+
9
+ validates :quantity, presence: true, numericality: { greater_than: 0 }
10
+
11
+ delegate(:full_name, to: :beneficiary, prefix: true)
12
+ delegate(:name, to: :commodity_category, prefix: true)
13
+ delegate(:abbreviation, to: :unit, prefix: true)
14
+ end
15
+ end
16
+ end
@@ -14,6 +14,7 @@ module Cats
14
14
  has_many :round_rations
15
15
  has_many :beneficiary_round_plan_items, through: :round_plan_items
16
16
  has_many :round_plan_item_details, through: :beneficiary_round_plan_items
17
+ has_many :round_beneficiaries, through: :round_plan_items
17
18
 
18
19
  validates :rounds, presence: true
19
20
  validates :reference_no, presence: true, uniqueness: true
@@ -10,6 +10,7 @@ module Cats
10
10
 
11
11
  has_many :beneficiary_round_plan_items
12
12
  has_many :round_plan_item_details, through: :beneficiary_round_plan_items
13
+ has_many :round_beneficiaries
13
14
 
14
15
  validates :plan_item_id, presence: true
15
16
  validates :round_plan_id, uniqueness: { scope: :fdp_id }
@@ -0,0 +1,8 @@
1
+ module Cats
2
+ module Core
3
+ class RoundBeneficiarySerializer < ActiveModel::Serializer
4
+ attributes :id, :beneficiary_id, :beneficiary_full_name, :round_plan_item_id, :commodity_category_id,
5
+ :commodity_category_name, :quantity, :unit_id, :unit_abbreviation, :received
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,87 @@
1
+ module Cats
2
+ module Core
3
+ class BeneficiaryService
4
+ def clear_distribution_list(id)
5
+ round_plan = RoundPlan.find(id)
6
+ raise(StandardError, 'Round plan is not in draft state.') unless round_plan.status == RoundPlan::DRAFT
7
+
8
+ RoundBeneficiary.joins(:round_plan_item).where(round_plan_item: { round_plan_id: id }).delete_all
9
+ end
10
+
11
+ def generate_distribution_list(id)
12
+ clear_distribution_list(id)
13
+ round_plan = RoundPlan.find(id)
14
+ plan_days = round_plan.plan.no_of_round_days
15
+ rounds = round_plan.rounds.count
16
+ beneficiaries = Beneficiary.joins(:beneficiary_category).where(
17
+ beneficiary_category: { plan_id: round_plan.plan_id }
18
+ ).group_by(&:fdp_id)
19
+ beneficiaries.each_key do |key|
20
+ beneficiaries[key] = beneficiaries[key].group_by(&:beneficiary_category_id)
21
+ end
22
+ rations = round_plan.round_rations
23
+
24
+ round_beneficiaries = []
25
+ round_plan.round_plan_items.each do |rpi|
26
+ fdp_beneficiaries = beneficiaries[rpi.fdp_id]
27
+ fdp_beneficiaries.each_key do |key|
28
+ category_rations = rations.select { |r| r.beneficiary_category_id == key }
29
+ category_rations.each do |ration|
30
+ fdp_beneficiaries[key].each do |beneficiary|
31
+ round_beneficiaries << {
32
+ beneficiary_id: beneficiary.id,
33
+ round_plan_item_id: rpi.id,
34
+ commodity_category_id: ration.commodity_category_id,
35
+ quantity: plan_days / ration.no_of_days * ration.quantity * rounds,
36
+ unit_id: ration.unit_of_measure_id,
37
+ received: false
38
+ }
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ RoundBeneficiary.insert_all!(round_beneficiaries, record_timestamps: true)
45
+ true
46
+ end
47
+
48
+ def remove_items(plan_id, ids)
49
+ raise(StandardError, 'No beneficiaries specified.') if ids.count.zero?
50
+
51
+ begin
52
+ plan = RoundPlan.find(plan_id)
53
+ rescue ActiveRecord::RecordNotFound
54
+ raise(StandardError, 'Round plan not found.') unless plan
55
+ end
56
+
57
+ beneficiaries = RoundBeneficiary.joins(:round_plan_item)
58
+ .where(round_plan_item: { round_plan_id: plan_id })
59
+ to_delete = RoundBeneficiary.where(id: ids)
60
+ diff = to_delete - beneficiaries
61
+ raise(StandardError, 'Round plan beneficiaries should be from the same plan.') if diff.count.positive?
62
+
63
+ to_delete.delete_all
64
+ true
65
+ end
66
+
67
+ def confirm_receipt(plan_id, ids)
68
+ raise(StandardError, 'No beneficiaries specified.') if ids.count.zero?
69
+
70
+ begin
71
+ plan = RoundPlan.find(plan_id)
72
+ rescue ActiveRecord::RecordNotFound
73
+ raise(StandardError, 'Round plan not found.') unless plan
74
+ end
75
+
76
+ beneficiaries = RoundBeneficiary.joins(:round_plan_item)
77
+ .where(round_plan_item: { round_plan_id: plan_id })
78
+ to_confirm = RoundBeneficiary.where(id: ids)
79
+ diff = to_confirm - beneficiaries
80
+ raise(StandardError, 'Round plan beneficiaries should be from the same plan.') if diff.count.positive?
81
+
82
+ to_confirm.update_all(received: true)
83
+ true
84
+ end
85
+ end
86
+ end
87
+ end
data/config/routes.rb CHANGED
@@ -171,14 +171,21 @@ Cats::Core::Engine.routes.draw do
171
171
  resources :receipt_transactions, except: %i[index new edit destroy]
172
172
  resources :lost_commodities, except: %i[index destroy]
173
173
  get '/plans/:id/round_plans', controller: :round_plans, action: :index, as: :round_plans_plan
174
+
175
+ post '/round_beneficiaries/filter'
176
+ resources :round_beneficiaries, only: %i[show]
174
177
  post '/round_plans/generate'
175
178
  post '/round_plans/filter'
176
179
  resources :round_plans, except: %i[index destroy] do
177
180
  member do
178
181
  post 'generate_dispatch_plan', controller: :dispatch_plans, action: :generate
179
182
  post 'remove_items'
183
+ post 'remove_beneficiaries', controller: :round_beneficiaries, action: :remove_beneficiaries
184
+ post 'confirm_receipt', controller: :round_beneficiaries, action: :confirm_receipt
180
185
  post 'generate_round_needs'
181
186
  post 'approve'
187
+ post 'generate_distribution_list', controller: :round_beneficiaries, action: :generate
188
+ get 'beneficiaries', controller: :round_beneficiaries, action: :index
182
189
  end
183
190
  end
184
191
 
@@ -9,6 +9,10 @@ class CreateCatsCoreBeneficiaries < ActiveRecord::Migration[7.0]
9
9
  null: false,
10
10
  index: { name: 'bc_on_beneficiaries_indx' },
11
11
  foreign_key: { to_table: :cats_core_beneficiary_categories }
12
+ t.references :fdp,
13
+ null: false,
14
+ index: { name: 'fdp_on_beneficiaries_indx' },
15
+ foreign_key: { to_table: :cats_core_locations }
12
16
 
13
17
  t.timestamps
14
18
  end
@@ -0,0 +1,26 @@
1
+ class CreateCatsCoreRoundBeneficiaries < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :cats_core_round_beneficiaries do |t|
4
+ t.references :beneficiary,
5
+ null: false,
6
+ index: { name: 'beneficiary_on_rb_indx' },
7
+ foreign_key: { to_table: :cats_core_beneficiaries }
8
+ t.references :round_plan_item,
9
+ null: false,
10
+ index: { name: 'rpi_on_rb_indx' },
11
+ foreign_key: { to_table: :cats_core_round_plan_items }
12
+ t.references :commodity_category,
13
+ null: false,
14
+ index: { name: 'cc_on_rb_indx' },
15
+ foreign_key: { to_table: :cats_core_commodity_categories }
16
+ t.float :quantity, null: false
17
+ t.references :unit,
18
+ null: false,
19
+ index: { name: 'unit_on_rb_indx' },
20
+ foreign_key: { to_table: :cats_core_unit_of_measures }
21
+ t.boolean :received, null: false, default: false
22
+
23
+ t.timestamps
24
+ end
25
+ end
26
+ end
@@ -1,5 +1,5 @@
1
1
  module Cats
2
2
  module Core
3
- VERSION = '1.4.42'.freeze
3
+ VERSION = '1.4.43'.freeze
4
4
  end
5
5
  end
@@ -5,5 +5,6 @@ FactoryBot.define do
5
5
  gender { 'M' }
6
6
  phone { '0911121212' }
7
7
  beneficiary_category
8
+ fdp factory: :fdp
8
9
  end
9
10
  end
@@ -0,0 +1,10 @@
1
+ FactoryBot.define do
2
+ factory :round_beneficiary, class: 'Cats::Core::RoundBeneficiary' do
3
+ beneficiary
4
+ round_plan_item
5
+ commodity_category
6
+ quantity { 150 }
7
+ unit factory: :unit_of_measure
8
+ received { false }
9
+ end
10
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cats_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.42
4
+ version: 1.4.43
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henock L.
@@ -252,6 +252,7 @@ files:
252
252
  - app/controllers/cats/core/receipt_transactions_controller.rb
253
253
  - app/controllers/cats/core/receipts_controller.rb
254
254
  - app/controllers/cats/core/roles_controller.rb
255
+ - app/controllers/cats/core/round_beneficiaries_controller.rb
255
256
  - app/controllers/cats/core/round_plans_controller.rb
256
257
  - app/controllers/cats/core/routes_controller.rb
257
258
  - app/controllers/cats/core/spaces_controller.rb
@@ -310,6 +311,7 @@ files:
310
311
  - app/models/cats/core/rhn_request.rb
311
312
  - app/models/cats/core/role.rb
312
313
  - app/models/cats/core/role_menu.rb
314
+ - app/models/cats/core/round_beneficiary.rb
313
315
  - app/models/cats/core/round_plan.rb
314
316
  - app/models/cats/core/round_plan_item.rb
315
317
  - app/models/cats/core/round_plan_item_detail.rb
@@ -361,6 +363,7 @@ files:
361
363
  - app/serializers/cats/core/receipt_transaction_serializer.rb
362
364
  - app/serializers/cats/core/role_menu_serializer.rb
363
365
  - app/serializers/cats/core/role_serializer.rb
366
+ - app/serializers/cats/core/round_beneficiary_serializer.rb
364
367
  - app/serializers/cats/core/round_plan_serializer.rb
365
368
  - app/serializers/cats/core/route_serializer.rb
366
369
  - app/serializers/cats/core/stack_serializer.rb
@@ -371,6 +374,7 @@ files:
371
374
  - app/serializers/cats/core/unit_of_measure_serializer.rb
372
375
  - app/serializers/cats/core/user_serializer.rb
373
376
  - app/services/cats/core/authorization_service.rb
377
+ - app/services/cats/core/beneficiary_service.rb
374
378
  - app/services/cats/core/dispatch_plan_service.rb
375
379
  - app/services/cats/core/dispatch_service.rb
376
380
  - app/services/cats/core/menu_service.rb
@@ -451,6 +455,7 @@ files:
451
455
  - db/migrate/20220511082354_create_cats_core_beneficiaries.rb
452
456
  - db/migrate/20220626063501_create_cats_core_loans.rb
453
457
  - db/migrate/20220626063757_create_cats_core_swaps.rb
458
+ - db/migrate/20220626132050_create_cats_core_round_beneficiaries.rb
454
459
  - lib/cats/core.rb
455
460
  - lib/cats/core/engine.rb
456
461
  - lib/cats/core/version.rb
@@ -498,6 +503,7 @@ files:
498
503
  - spec/factories/cats/core/rhn_requests.rb
499
504
  - spec/factories/cats/core/role_menus.rb
500
505
  - spec/factories/cats/core/roles.rb
506
+ - spec/factories/cats/core/round_beneficiaries.rb
501
507
  - spec/factories/cats/core/round_plan_item_details.rb
502
508
  - spec/factories/cats/core/round_plan_items.rb
503
509
  - spec/factories/cats/core/round_plans.rb