cats_core 1.4.12 → 1.4.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/cats/core/{monthly_plans_controller.rb → round_plans_controller.rb} +11 -10
  3. data/app/models/cats/core/beneficiary.rb +15 -0
  4. data/app/models/cats/core/beneficiary_category.rb +11 -0
  5. data/app/models/cats/core/beneficiary_plan_item.rb +12 -0
  6. data/app/models/cats/core/beneficiary_round_plan_item.rb +14 -0
  7. data/app/models/cats/core/plan.rb +5 -2
  8. data/app/models/cats/core/plan_item.rb +10 -3
  9. data/app/models/cats/core/plan_item_detail.rb +4 -4
  10. data/app/models/cats/core/ration.rb +7 -1
  11. data/app/models/cats/core/{monthly_plan.rb → round_plan.rb} +22 -11
  12. data/app/models/cats/core/round_plan_item.rb +25 -0
  13. data/app/models/cats/core/round_plan_item_detail.rb +11 -0
  14. data/app/models/cats/core/round_ration.rb +17 -0
  15. data/app/models/cats/core/transport_order.rb +6 -0
  16. data/app/models/cats/core/transport_order_item.rb +3 -0
  17. data/app/serializers/cats/core/round_plan_serializer.rb +7 -0
  18. data/app/services/cats/core/round_plan_service.rb +108 -0
  19. data/config/routes.rb +5 -5
  20. data/db/migrate/20210717031810_create_cats_core_plans.rb +0 -4
  21. data/db/migrate/20210717032024_create_cats_core_plan_items.rb +13 -2
  22. data/db/migrate/20210717032260_create_cats_core_beneficiary_categories.rb +14 -0
  23. data/db/migrate/{20210717031343_create_cats_core_ration_items.rb → 20210717032270_create_cats_core_rations.rb} +9 -8
  24. data/db/migrate/20210717032290_create_cats_core_beneficiary_plan_items.rb +23 -0
  25. data/db/migrate/20210717032295_create_cats_core_plan_item_details.rb +18 -0
  26. data/db/migrate/{20220107121752_create_cats_core_monthly_plans.rb → 20220107121752_create_cats_core_round_plans.rb} +3 -4
  27. data/db/migrate/20220107122280_create_cats_core_round_rations.rb +26 -0
  28. data/db/migrate/20220107125025_create_cats_core_round_plan_items.rb +33 -0
  29. data/db/migrate/20220107126025_create_cats_core_beneficiary_round_plan_items.rb +24 -0
  30. data/db/migrate/20220107132433_create_cats_core_round_plan_item_details.rb +17 -0
  31. data/db/migrate/20220511082354_create_cats_core_beneficiaries.rb +16 -0
  32. data/lib/cats/core/version.rb +1 -1
  33. data/spec/factories/cats/core/beneficiaries.rb +9 -0
  34. data/spec/factories/cats/core/beneficiary_categories.rb +7 -0
  35. data/spec/factories/cats/core/beneficiary_plan_items.rb +7 -0
  36. data/spec/factories/cats/core/beneficiary_round_plan_items.rb +8 -0
  37. data/spec/factories/cats/core/dispatch_plans.rb +3 -3
  38. data/spec/factories/cats/core/locations.rb +4 -4
  39. data/spec/factories/cats/core/plan_item_details.rb +3 -3
  40. data/spec/factories/cats/core/plan_items.rb +4 -2
  41. data/spec/factories/cats/core/plans.rb +0 -1
  42. data/spec/factories/cats/core/rations.rb +5 -2
  43. data/spec/factories/cats/core/round_plan_item_details.rb +7 -0
  44. data/spec/factories/cats/core/round_plan_items.rb +11 -0
  45. data/spec/factories/cats/core/{monthly_plans.rb → round_plans.rb} +2 -3
  46. data/spec/factories/cats/core/round_rations.rb +10 -0
  47. metadata +31 -22
  48. data/app/models/cats/core/monthly_plan_item.rb +0 -15
  49. data/app/models/cats/core/monthly_plan_item_detail.rb +0 -14
  50. data/app/models/cats/core/monthly_ration.rb +0 -15
  51. data/app/models/cats/core/ration_item.rb +0 -14
  52. data/app/serializers/cats/core/monthly_plan_serializer.rb +0 -8
  53. data/app/services/cats/core/monthly_plan_service.rb +0 -86
  54. data/db/migrate/20210717031216_create_cats_core_rations.rb +0 -14
  55. data/db/migrate/20210717032240_create_cats_core_plan_item_details.rb +0 -18
  56. data/db/migrate/20220107124630_create_cats_core_monthly_rations.rb +0 -22
  57. data/db/migrate/20220107125025_create_cats_core_monthly_plan_items.rb +0 -17
  58. data/db/migrate/20220107132433_create_cats_core_monthly_plan_item_details.rb +0 -17
  59. data/spec/factories/cats/core/monthly_plan_item_details.rb +0 -7
  60. data/spec/factories/cats/core/monthly_plan_items.rb +0 -7
  61. data/spec/factories/cats/core/monthly_rations.rb +0 -9
  62. data/spec/factories/cats/core/ration_items.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3724badb244476dc73d7c35fac9971114160be9781ba3a386f2d35ef70226324
4
- data.tar.gz: 9f29cd5757d75472e03f8baa3bd4421fc78109d50612955ebdd666a354c17ca6
3
+ metadata.gz: 52e2769c0f1f85fdbaa5eafafebec437ce3dede1db72a3781ebd5502a8f521b0
4
+ data.tar.gz: e25329c1ee2367d96fe7ef3282f56a7ed60ff9bef55dd6d31e9ffe06143a4950
5
5
  SHA512:
6
- metadata.gz: e5a859815e6420692ab833b54372ae47c0fbf835b8384c8d18421eadb79125deb3a2c91ae740dfb9abe1817bf7e01e45cc14312e94d95aaadaade3e767a64dfe
7
- data.tar.gz: a85113ab315551f8684accc9d21345b684d9762c73bfc44538bf6d8ac30a4d8e1f2aea24620fc0ebdee000f97de0ae18745b72a28a68cb6f44f6e3b9b184b209
6
+ metadata.gz: 4feab6c3d42233222cdc473353c43a36683a2574d1ebad9d6980b98cf6caa405c8961e6b2e358f916c775d3fc88861b1702dc9381f51c574114afd1f46131023
7
+ data.tar.gz: 5435ee907031fa3421a02c2e22e06cde93fe39ebf9cc81cb76e22c1b0de83a8dda97a7c0b9555a11fab1439407d293f48867f9ecdd2e5532f4e79516929d38ae
@@ -1,23 +1,23 @@
1
1
  module Cats
2
2
  module Core
3
- class MonthlyPlansController < ApplicationController
3
+ class RoundPlansController < ApplicationController
4
4
  include Common
5
5
 
6
- before_action :set_service, only: %i[generate remove_items generate_monthly_needs]
6
+ before_action :set_service, only: %i[generate remove_items generate_round_needs]
7
7
 
8
8
  def index
9
9
  super do
10
- MonthlyPlan.where(plan: params[:id])
10
+ RoundPlan.where(plan: params[:id])
11
11
  end
12
12
  end
13
13
 
14
14
  def filter
15
- query = MonthlyPlan.ransack(params[:q])
15
+ query = RoundPlan.ransack(params[:q])
16
16
  render json: { success: true, data: serialize(query.result) }
17
17
  end
18
18
 
19
19
  def approve
20
- plan = MonthlyPlan.find(params[:id])
20
+ plan = RoundPlan.find(params[:id])
21
21
  plan.approve
22
22
  render json: { success: true, data: serialize(plan) }
23
23
  rescue StandardError => e
@@ -25,12 +25,13 @@ module Cats
25
25
  end
26
26
 
27
27
  def generate
28
- plan = @service.generate_monthly_plan(model_params)
28
+ p = model_params
29
+ plan = @service.generate_round_plan(p[:reference_no], p[:rounds], p[:plan_id], p[:region_id])
29
30
  render json: { success: true, data: serialize(plan) }
30
31
  end
31
32
 
32
- def generate_monthly_needs
33
- plan = @service.generate_monthly_needs(params[:id])
33
+ def generate_round_needs
34
+ plan = @service.generate_round_needs(params[:id])
34
35
  render json: { success: true, data: serialize(plan) }
35
36
  rescue StandardError => e
36
37
  render json: { success: false, error: e.message }
@@ -46,11 +47,11 @@ module Cats
46
47
  private
47
48
 
48
49
  def model_params
49
- params.require(:payload).permit(:reference_no, :status, :plan_id, :region_id, :month, :no_of_days)
50
+ params.require(:payload).permit(:reference_no, :status, :plan_id, :region_id, rounds: [])
50
51
  end
51
52
 
52
53
  def set_service
53
- @service = MonthlyPlanService.new
54
+ @service = RoundPlanService.new
54
55
  end
55
56
 
56
57
  def remove_params
@@ -0,0 +1,15 @@
1
+ module Cats
2
+ module Core
3
+ class Beneficiary < ApplicationRecord
4
+ MALE = 'M'.freeze
5
+ FEMALE = 'F'.freeze
6
+ GENDERS = [MALE, FEMALE].freeze
7
+
8
+ belongs_to :beneficiary_category
9
+
10
+ validates :full_name, :age, :gender, presence: true
11
+ validates :gender, inclusion: { in: GENDERS }
12
+ validates :age, numericality: { greater_than: 0, less_than: 100 }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ module Cats
2
+ module Core
3
+ class BeneficiaryCategory < ApplicationRecord
4
+ belongs_to :plan
5
+ has_many :rations
6
+
7
+ validates :code, :name, presence: true
8
+ validates :code, uniqueness: true
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module Cats
2
+ module Core
3
+ class BeneficiaryPlanItem < ApplicationRecord
4
+ belongs_to :plan_item
5
+ belongs_to :beneficiary_category
6
+ has_many :plan_item_details
7
+
8
+ validates :beneficiaries, presence: true, numericality: { greater_than: 0 }
9
+ validates :plan_item_id, uniqueness: { scope: :beneficiary_category_id }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ module Cats
2
+ module Core
3
+ class BeneficiaryRoundPlanItem < ApplicationRecord
4
+ belongs_to :round_plan_item
5
+ belongs_to :beneficiary_category
6
+ has_many :round_plan_item_details
7
+
8
+ validates :beneficiaries, presence: true, numericality: { greater_than_or_equal_to: 0 }
9
+ validates :round_plan_item_id, uniqueness: { scope: :beneficiary_category_id }
10
+
11
+ delegate(:name, to: :beneficiary_category, prefix: true)
12
+ end
13
+ end
14
+ end
@@ -13,9 +13,12 @@ module Cats
13
13
  SEASONS = [BELG, MEHER, ANNUAL].freeze
14
14
 
15
15
  belongs_to :program
16
- belongs_to :ration, optional: true
16
+ has_many :beneficiary_categories
17
+ has_many :rations, through: :beneficiary_categories
17
18
  has_many :plan_items
18
- has_many :plan_item_details, through: :plan_items
19
+ has_many :round_plans
20
+ has_many :beneficiary_plan_items, through: :plan_items
21
+ has_many :plan_item_details, through: :beneficiary_plan_items
19
22
 
20
23
  validates :reference_no, :year, :status, presence: true
21
24
  validates :total_days, :rounds, presence: true, numericality: { greater_than: 0 }
@@ -2,15 +2,22 @@ module Cats
2
2
  module Core
3
3
  class PlanItem < ApplicationRecord
4
4
  belongs_to :plan
5
+
6
+ belongs_to :region, -> { where(location_type: Cats::Core::Location::REGION) }, class_name: 'Cats::Core::Location'
7
+ belongs_to :zone, -> { where(location_type: Cats::Core::Location::ZONE) }, class_name: 'Cats::Core::Location'
5
8
  belongs_to :woreda, -> { where(location_type: Cats::Core::Location::WOREDA) }, class_name: 'Cats::Core::Location'
9
+ belongs_to :fdp, -> { where(location_type: Cats::Core::Location::FDP) }, class_name: 'Cats::Core::Location'
6
10
  belongs_to :operator
7
11
 
8
- has_many :plan_item_details
12
+ has_many :beneficiary_plan_items
13
+ has_many :plan_item_details, through: :beneficiary_plan_items
9
14
 
10
- validates :beneficiaries, presence: true, numericality: { greater_than: 0 }
11
- validates :plan_id, uniqueness: { scope: :woreda_id }
15
+ validates :plan_id, uniqueness: { scope: :fdp_id }
12
16
 
17
+ delegate(:name, to: :region, prefix: true)
18
+ delegate(:name, to: :zone, prefix: true)
13
19
  delegate(:name, to: :woreda, prefix: true)
20
+ delegate(:name, to: :fdp, prefix: true)
14
21
  delegate(:name, to: :operator, prefix: true)
15
22
  end
16
23
  end
@@ -1,11 +1,11 @@
1
1
  module Cats
2
2
  module Core
3
3
  class PlanItemDetail < ApplicationRecord
4
- belongs_to :plan_item
5
- belongs_to :ration_item
4
+ belongs_to :beneficiary_plan_item
5
+ belongs_to :ration
6
6
 
7
- validates :amount, presence: true, numericality: { greater_than: 0 }
8
- validates :plan_item_id, uniqueness: { scope: :ration_item_id }
7
+ validates :quantity, presence: true, numericality: { greater_than: 0 }
8
+ validates :beneficiary_plan_item_id, uniqueness: { scope: :ration_id }
9
9
  end
10
10
  end
11
11
  end
@@ -1,9 +1,15 @@
1
1
  module Cats
2
2
  module Core
3
3
  class Ration < ApplicationRecord
4
- belongs_to :program
4
+ belongs_to :beneficiary_category
5
+ belongs_to :commodity_category
6
+ belongs_to :unit_of_measure
5
7
 
6
8
  validates :reference_no, presence: true, uniqueness: true
9
+ validates :quantity, :no_of_days, presence: true, numericality: { greater_than: 0 }
10
+
11
+ delegate(:name, to: :commodity_category, prefix: true)
12
+ delegate(:abbreviation, to: :unit_of_measure, prefix: true)
7
13
  end
8
14
  end
9
15
  end
@@ -1,6 +1,6 @@
1
1
  module Cats
2
2
  module Core
3
- class MonthlyPlan < ApplicationRecord
3
+ class RoundPlan < ApplicationRecord
4
4
  include Dispatchable
5
5
 
6
6
  DRAFT = 'Draft'.freeze
@@ -13,14 +13,16 @@ module Cats
13
13
  belongs_to :plan
14
14
  belongs_to :region, class_name: 'Cats::Core::Location'
15
15
 
16
- has_many :monthly_plan_items
17
- has_many :monthly_plan_item_details, through: :monthly_plan_items
18
- has_many :monthly_rations
16
+ has_many :round_plan_items
17
+ has_many :round_rations
18
+ has_many :beneficiary_round_plan_items, through: :round_plan_items
19
+ has_many :round_plan_item_details, through: :beneficiary_round_plan_items
19
20
 
21
+ validates :rounds, presence: true
20
22
  validates :reference_no, presence: true, uniqueness: true
21
- validates :status, presence: true, inclusion: { in: MonthlyPlan::STATUSES }
22
- validates :no_of_days, :month, presence: true, numericality: { greater_than: 0 }
23
- validate :validate_month, :validate_region
23
+ validates :status, presence: true, inclusion: { in: RoundPlan::STATUSES }
24
+ validate :validate_region
25
+ validate :validate_rounds, on: :create
24
26
 
25
27
  delegate(:reference_no, to: :plan, prefix: true)
26
28
  delegate(:name, to: :region, prefix: true)
@@ -36,7 +38,7 @@ module Cats
36
38
  def approve
37
39
  raise(StandardError, 'Plan is not in draft state.') unless status == DRAFT
38
40
 
39
- raise(StandardError, 'Empty plan cannot be approved.') if monthly_plan_items.count.zero?
41
+ raise(StandardError, 'Empty plan cannot be approved.') if round_plan_items.count.zero?
40
42
 
41
43
  update!(status: APPROVED)
42
44
  end
@@ -48,10 +50,19 @@ module Cats
48
50
  save!
49
51
  end
50
52
 
51
- def validate_month
52
- return unless month
53
+ def validate_rounds
54
+ return unless rounds && plan
53
55
 
54
- errors.add(:month, 'cannot be greater than 12.') if month > 12
56
+ errors.add(:rounds, 'cannot be an empty list') if rounds.length.zero?
57
+
58
+ existing_rounds = plan.round_plans.where(region: region).map(&:rounds).sum([])
59
+ rounds.each do |round|
60
+ if round > plan.rounds
61
+ errors.add(:rounds, 'cannot exceed the total number of rounds specified in the plan.')
62
+ break
63
+ end
64
+ end
65
+ errors.add(:rounds, 'cannot be repeated.') unless existing_rounds - rounds == existing_rounds
55
66
  end
56
67
 
57
68
  def validate_region
@@ -0,0 +1,25 @@
1
+ module Cats
2
+ module Core
3
+ class RoundPlanItem < ApplicationRecord
4
+ belongs_to :round_plan
5
+ belongs_to :region, -> { where(location_type: Cats::Core::Location::REGION) }, class_name: 'Cats::Core::Location'
6
+ belongs_to :zone, -> { where(location_type: Cats::Core::Location::ZONE) }, class_name: 'Cats::Core::Location'
7
+ belongs_to :woreda, -> { where(location_type: Cats::Core::Location::WOREDA) }, class_name: 'Cats::Core::Location'
8
+ belongs_to :fdp, -> { where(location_type: Cats::Core::Location::FDP) }, class_name: 'Cats::Core::Location'
9
+ belongs_to :operator
10
+
11
+ has_many :beneficiary_round_plan_items
12
+ has_many :round_plan_item_details, through: :beneficiary_round_plan_items
13
+
14
+ validates :plan_item_id, presence: true
15
+ validates :round_plan_id, uniqueness: { scope: :fdp_id }
16
+
17
+ delegate(:reference_no, to: :round_plan, prefix: true)
18
+ delegate(:name, to: :region, prefix: true)
19
+ delegate(:name, to: :zone, prefix: true)
20
+ delegate(:name, to: :woreda, prefix: true)
21
+ delegate(:name, to: :fdp, prefix: true)
22
+ delegate(:name, to: :operator, prefix: true)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ module Cats
2
+ module Core
3
+ class RoundPlanItemDetail < ApplicationRecord
4
+ belongs_to :beneficiary_round_plan_item
5
+ belongs_to :round_ration
6
+
7
+ validates :quantity, presence: true, numericality: { greater_than: 0 }
8
+ validates :beneficiary_round_plan_item_id, uniqueness: { scope: :round_ration_id }
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module Cats
2
+ module Core
3
+ class RoundRation < ApplicationRecord
4
+ belongs_to :beneficiary_category
5
+ belongs_to :commodity_category
6
+ belongs_to :unit_of_measure
7
+ belongs_to :round_plan
8
+
9
+ validates :quantity, :no_of_days, presence: true, numericality: { greater_than: 0 }
10
+
11
+ delegate(:name, to: :commodity_category, prefix: true)
12
+ delegate(:name, to: :beneficiary_category, prefix: true)
13
+ delegate(:abbreviation, to: :unit_of_measure, prefix: true)
14
+ delegate(:reference_no, to: :round_plan, prefix: true)
15
+ end
16
+ end
17
+ end
@@ -9,10 +9,16 @@ module Cats
9
9
  belongs_to :prepared_by, class_name: 'Cats::Core::User'
10
10
  belongs_to :approved_by, class_name: 'Cats::Core::User', optional: true
11
11
 
12
+ has_many :transport_order_items
13
+
12
14
  validates :status, presence: true, inclusion: { in: STATUSES }
13
15
  validates :order_date, presence: true
14
16
  validate :validate_against_requisition
15
17
 
18
+ delegate(:full_name, to: :prepared_by, prefix: true)
19
+ delegate(:full_name, to: :approved_by, prefix: true, allow_nil: true)
20
+ delegate(:reference_no, to: :transport_requisition, prefix: 'requisition')
21
+
16
22
  def validate_against_requisition
17
23
  return unless transport_requisition
18
24
 
@@ -11,6 +11,9 @@ module Cats
11
11
  validates :transport_requisition_item_id, uniqueness: true
12
12
  validate :validate_requisition
13
13
 
14
+ delegate(:name, to: :transporter, prefix: true)
15
+ delegate(:contract_no, to: :transport_contract, prefix: false)
16
+
14
17
  def validate_requisition
15
18
  return unless transport_requisition_item
16
19
 
@@ -0,0 +1,7 @@
1
+ module Cats
2
+ module Core
3
+ class RoundPlanSerializer < ActiveModel::Serializer
4
+ attributes :id, :reference_no, :status, :plan_id, :plan_reference_no, :region_id, :region_name, :rounds
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,108 @@
1
+ module Cats
2
+ module Core
3
+ class RoundPlanService
4
+ def generate_round_needs(plan_id)
5
+ round_plan = Cats::Core::RoundPlan.find(plan_id)
6
+ raise(StandardError, 'Plan has no rations.') if round_plan.round_rations.count.zero?
7
+
8
+ raise(StandardError, 'Plan has no plan items.') if round_plan.round_plan_items.count.zero?
9
+
10
+ round_plan.round_plan_item_details.delete_all if round_plan.round_plan_item_details.count.positive?
11
+
12
+ details = []
13
+ rations = round_plan.round_rations
14
+ plan = round_plan.plan
15
+ no_of_days = plan.total_days / plan.rounds
16
+ round_plan.beneficiary_round_plan_items.each do |plan_item|
17
+ round_rations = rations.select { |r| r.beneficiary_category_id == plan_item.beneficiary_category_id }
18
+ round_rations.each do |ration|
19
+ details << {
20
+ beneficiary_round_plan_item_id: plan_item.id,
21
+ round_ration_id: ration.id,
22
+ quantity: (
23
+ (no_of_days / ration.no_of_days * ration.quantity) *
24
+ plan_item.beneficiaries *
25
+ round_plan.rounds.count
26
+ )
27
+ }
28
+ end
29
+ end
30
+
31
+ Cats::Core::RoundPlanItemDetail.insert_all!(details)
32
+ round_plan
33
+ end
34
+
35
+ def generate_round_plan(reference_no, rounds, plan_id, region_id)
36
+ round_plan = Cats::Core::RoundPlan.create!(
37
+ plan_id: plan_id,
38
+ reference_no: reference_no,
39
+ region_id: region_id,
40
+ status: Cats::Core::Plan::DRAFT,
41
+ rounds: rounds
42
+ )
43
+ rations = Cats::Core::Ration.joins(:beneficiary_category).where(beneficiary_category: { plan_id: plan_id })
44
+ round_rations = rations.map do |ration|
45
+ {
46
+ beneficiary_category_id: ration.beneficiary_category_id,
47
+ commodity_category_id: ration.commodity_category_id,
48
+ quantity: ration.quantity,
49
+ unit_of_measure_id: ration.unit_of_measure_id,
50
+ round_plan_id: round_plan.id,
51
+ no_of_days: ration.no_of_days,
52
+ created_at: Date.today,
53
+ updated_at: Date.today
54
+ }
55
+ end
56
+ Cats::Core::RoundRation.insert_all!(round_rations)
57
+ plan_items = Cats::Core::PlanItem.where(plan_id: plan_id, region_id: region_id)
58
+ ben_plan_items = Cats::Core::BeneficiaryPlanItem.where(plan_item: plan_items)
59
+ round_plan_items = plan_items.map do |plan_item|
60
+ {
61
+ round_plan_id: round_plan.id,
62
+ region_id: region_id,
63
+ zone_id: plan_item.zone_id,
64
+ woreda_id: plan_item.woreda_id,
65
+ fdp_id: plan_item.fdp_id,
66
+ operator_id: plan_item.operator_id,
67
+ plan_item_id: plan_item.id
68
+ }
69
+ end
70
+ result = Cats::Core::RoundPlanItem.insert_all!(
71
+ round_plan_items,
72
+ returning: %w[id plan_item_id],
73
+ record_timestamps: true
74
+ )
75
+ rows = result.rows
76
+ ben_round_plan_items = ben_plan_items.map do |ben_plan_item|
77
+ item = rows.find { |r| r[1] == ben_plan_item.plan_item_id }
78
+ {
79
+ round_plan_item_id: item[0],
80
+ beneficiary_category_id: ben_plan_item.beneficiary_category_id,
81
+ planned_beneficiaries: ben_plan_item.beneficiaries,
82
+ beneficiaries: ben_plan_item.beneficiaries
83
+ }
84
+ end
85
+ Cats::Core::BeneficiaryRoundPlanItem.insert_all!(ben_round_plan_items, record_timestamps: true)
86
+ round_plan
87
+ end
88
+
89
+ def remove_items(plan_id, ids)
90
+ raise(StandardError, 'No plan items specified.') if ids.count.zero?
91
+
92
+ begin
93
+ plan = Cats::Core::RoundPlan.find(plan_id)
94
+ rescue ActiveRecord::RecordNotFound
95
+ raise(StandardError, 'Round plan not found.') unless plan
96
+ end
97
+
98
+ plans = Cats::Core::RoundPlan.includes(:round_plan_items).where(round_plan_items: { id: ids })
99
+ raise(StandardError, 'Plan items should be from the same plan.') if plans.count > 1
100
+
101
+ raise(StandardError, 'Items are not from the given round plan.') unless plan_id == plans[0].id
102
+
103
+ Cats::Core::RoundPlanItem.delete_by(id: ids)
104
+ plan
105
+ end
106
+ end
107
+ end
108
+ end
data/config/routes.rb CHANGED
@@ -124,13 +124,13 @@ Cats::Core::Engine.routes.draw do
124
124
  end
125
125
  resources :receipt_transactions, except: %i[index new edit destroy]
126
126
  resources :lost_commodities, except: %i[index destroy]
127
- get '/plans/:id/monthly_plans', controller: :monthly_plans, action: :index, as: :monthly_plans_plan
128
- post '/monthly_plans/generate'
129
- post '/monthly_plans/filter'
130
- resources :monthly_plans, except: %i[index destroy] do
127
+ get '/plans/:id/round_plans', controller: :round_plans, action: :index, as: :round_plans_plan
128
+ post '/round_plans/generate'
129
+ post '/round_plans/filter'
130
+ resources :round_plans, except: %i[index destroy] do
131
131
  member do
132
132
  post 'remove_items'
133
- post 'generate_monthly_needs'
133
+ post 'generate_round_needs'
134
134
  post 'approve'
135
135
  end
136
136
  end
@@ -13,10 +13,6 @@ class CreateCatsCorePlans < ActiveRecord::Migration[6.1]
13
13
  null: false,
14
14
  index: { name: 'program_on_plan_indx' },
15
15
  foreign_key: { to_table: :cats_core_programs }
16
- t.references :ration,
17
- null: true,
18
- index: { name: 'ration_on_plan_indx' },
19
- foreign_key: { to_table: :cats_core_rations }
20
16
 
21
17
  t.timestamps
22
18
  end
@@ -5,11 +5,22 @@ class CreateCatsCorePlanItems < ActiveRecord::Migration[6.1]
5
5
  null: false,
6
6
  index: { name: 'plan_on_plan_items_indx' },
7
7
  foreign_key: { to_table: :cats_core_plans }
8
+ t.references :region,
9
+ null: false,
10
+ index: { name: 'region_on_plan_items_indx' },
11
+ foreign_key: { to_table: :cats_core_locations }
12
+ t.references :zone,
13
+ null: false,
14
+ index: { name: 'zone_on_plan_items_indx' },
15
+ foreign_key: { to_table: :cats_core_locations }
8
16
  t.references :woreda,
9
17
  null: false,
10
18
  index: { name: 'woreda_on_plan_items_idnx' },
11
19
  foreign_key: { to_table: :cats_core_locations }
12
- t.integer :beneficiaries, null: false
20
+ t.references :fdp,
21
+ null: false,
22
+ index: { name: 'fdp_on_plan_items_indx' },
23
+ foreign_key: { to_table: :cats_core_locations }
13
24
  t.references :operator,
14
25
  null: false,
15
26
  index: { name: 'operator_on_plan_items_indx' },
@@ -18,6 +29,6 @@ class CreateCatsCorePlanItems < ActiveRecord::Migration[6.1]
18
29
  t.timestamps
19
30
  end
20
31
 
21
- add_index :cats_core_plan_items, [:plan_id, :woreda_id], unique: true
32
+ add_index :cats_core_plan_items, [:plan_id, :fdp_id], unique: true
22
33
  end
23
34
  end
@@ -0,0 +1,14 @@
1
+ class CreateCatsCoreBeneficiaryCategories < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :cats_core_beneficiary_categories do |t|
4
+ t.string :code, unique: true
5
+ t.string :name, null: false
6
+ t.references :plan,
7
+ null: false,
8
+ index: { name: 'plan_on_bc_indx' },
9
+ foreign_key: { to_table: :cats_core_plans }
10
+
11
+ t.timestamps
12
+ end
13
+ end
14
+ end
@@ -1,21 +1,22 @@
1
- class CreateCatsCoreRationItems < ActiveRecord::Migration[6.1]
1
+ class CreateCatsCoreRations < ActiveRecord::Migration[6.1]
2
2
  def change
3
- create_table :cats_core_ration_items do |t|
3
+ create_table :cats_core_rations do |t|
4
+ t.string :reference_no, unique: true
5
+ t.references :beneficiary_category,
6
+ null: false,
7
+ index: { name: 'bc_on_ration_indx' },
8
+ foreign_key: { to_table: :cats_core_beneficiary_categories }
4
9
  t.references :commodity_category,
5
10
  null: false,
6
11
  index: { name: 'cc_on_ration_indx' },
7
12
  foreign_key: { to_table: :cats_core_commodity_categories }
8
- t.references :ration,
9
- null: false,
10
- index: { name: 'ri_on_ration_indx' },
11
- foreign_key: { to_table: :cats_core_rations }
12
13
  t.references :unit_of_measure,
13
14
  null: false,
14
15
  index: { name: 'uom_on_ration_indx' },
15
16
  foreign_key: { to_table: :cats_core_unit_of_measures }
16
- t.float :amount, null: false
17
+ t.float :quantity, null: false
17
18
  t.integer :no_of_days, null: false
18
-
19
+
19
20
  t.timestamps
20
21
  end
21
22
  end
@@ -0,0 +1,23 @@
1
+ class CreateCatsCoreBeneficiaryPlanItems < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :cats_core_beneficiary_plan_items do |t|
4
+ t.references :plan_item,
5
+ null: false,
6
+ index: { name: 'pi_on_bpi_indx' },
7
+ foreign_key: { to_table: :cats_core_plan_items }
8
+ t.references :beneficiary_category,
9
+ null: false,
10
+ index: { name: 'bc_on_bpi_indx' },
11
+ foreign_key: { to_table: :cats_core_beneficiary_categories }
12
+ t.integer :beneficiaries, null: false
13
+
14
+ t.timestamps
15
+ end
16
+ add_index(
17
+ :cats_core_beneficiary_plan_items,
18
+ [:plan_item_id, :beneficiary_category_id],
19
+ unique: true,
20
+ name: 'pii_on_bci_uniq_indx'
21
+ )
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ class CreateCatsCorePlanItemDetails < ActiveRecord::Migration[6.1]
2
+ def change
3
+ create_table :cats_core_plan_item_details do |t|
4
+ t.references :beneficiary_plan_item,
5
+ null: false,
6
+ index: { name: 'bpi_on_pid_indx' },
7
+ foreign_key: { to_table: :cats_core_beneficiary_plan_items }
8
+ t.references :ration,
9
+ null: false,
10
+ index: { name: 'ration_on_pid_indx' },
11
+ foreign_key: { to_table: :cats_core_rations }
12
+ t.float :quantity, null: false
13
+
14
+ t.timestamps
15
+ end
16
+ add_index(:cats_core_plan_item_details, [:beneficiary_plan_item_id, :ration_id], unique: true, name: 'bpii_ri_on_pid_indx')
17
+ end
18
+ end
@@ -1,9 +1,8 @@
1
- class CreateCatsCoreMonthlyPlans < ActiveRecord::Migration[6.1]
1
+ class CreateCatsCoreRoundPlans < ActiveRecord::Migration[6.1]
2
2
  def change
3
- create_table :cats_core_monthly_plans do |t|
3
+ create_table :cats_core_round_plans do |t|
4
4
  t.string :reference_no, unique: true
5
- t.integer :month, null: false
6
- t.integer :no_of_days, null: false
5
+ t.integer :rounds, array: true, default: []
7
6
  t.string :status, null: false, default: 'Draft'
8
7
  t.references :plan,
9
8
  null: false,