cats_core 1.4.42 → 1.4.43

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 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