Class: Cats::Core::DispatchPlanService

Inherits:
Object
  • Object
show all
Defined in:
app/services/cats/core/dispatch_plan_service.rb

Instance Method Summary collapse

Instance Method Details

#approve(plan) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'app/services/cats/core/dispatch_plan_service.rb', line 4

def approve(plan)
  plan.approve

  if plan.upstream
    # Create source hub authorizations for each item and
    # put them in a `Source Authorized` state
    store = Store.find_by(code: "SUP-STORE")
    keeper = User.find_by(first_name: "SUP-Storekeeper")
    authorizations = []
    plan.dispatch_plan_items.each do |item|
      authorizations << {
        dispatch_plan_item_id: item.id,
        store_id: store.id,
        quantity: item.quantity,
        unit_id: item.unit_id,
        authorization_type: HubAuthorization::SOURCE,
        authorized_by_id: keeper.id,
        created_at: Date.today,
        updated_at: Date.today
      }
    end
    HubAuthorization.insert_all(authorizations)
    plan.dispatch_plan_items.update_all(status: DispatchPlanItem::SOURCE_AUTHORIZED)
  end
  send_notification(plan)
  plan
end

#bulk_create(payload, user) ⇒ Object

This method creates dispatch and dispatch plan items once users fill out additional details such as source and destination for generated dispatch plan items.

NOTE: Users still have to go through each plan item and set the

reference_no. If the product team comes up with a reference_no
generation scheme, then we may use that to avoid this.


116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'app/services/cats/core/dispatch_plan_service.rb', line 116

def bulk_create(payload, user)
  plan = Cats::Core::DispatchPlan.new(
    reference_no: payload[:reference_no],
    dispatchable_id: payload[:dispatchable_id],
    dispatchable_type: payload[:dispatchable_type],
    prepared_by: user
  )
  ActiveRecord::Base.transaction do
    plan.save!

    items = payload[:items].each_with_object([]) do |item, res|
      res << {
        reference_no: item[:reference_no],
        source_id: item[:source_id],
        destination_id: item[:destination_id],
        dispatch_plan_id: plan.id,
        quantity: item[:quantity],
        unit_id: item[:unit_id],
        commodity_id: item[:commodity_id],
        commodity_status: item[:commodity_status],
        beneficiaries: item[:beneficiaries],
        status: Cats::Core::DispatchPlanItem::UNAUTHORIZED
      }
    end
    Cats::Core::DispatchPlanItem.insert_all(items, record_timestamps: true)
  end
  plan
end

#create(params, user) ⇒ Object



32
33
34
35
36
37
38
39
40
# File 'app/services/cats/core/dispatch_plan_service.rb', line 32

def create(params, user)
  plan = Cats::Core::DispatchPlan.new(params)
  plan.prepared_by = user
  plan.save!

  plan
rescue ActiveRecord::RecordInvalid
  raise(StandardError, plan.errors.full_messages[0])
end

#generate(id) ⇒ Object

This method generates dispatch plan for a round plan by aggregating the FDP level quantities into woreda level quantity per commodity.

Parameters:

id => The ID of the round plan for which dispatch plan is to be generated


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'app/services/cats/core/dispatch_plan_service.rb', line 70

def generate(id)
  details = RoundPlanItemDetail.joins(
    beneficiary_round_plan_item: {round_plan_item: :round_plan}
  ).where(
    beneficiary_round_plan_item: {cats_core_round_plan_items: {round_plan_id: id}}
  ).includes(
    beneficiary_round_plan_item: {
      round_plan_item: %i[round_plan region zone woreda fdp]
    },
    round_ration: :commodity_category
  )

  items = details.each_with_object([]) do |detail, res|
    res << {
      reference_no: nil,
      region: detail.beneficiary_round_plan_item.round_plan_item.region.name,
      zone: detail.beneficiary_round_plan_item.round_plan_item.zone.name,
      woreda: detail.beneficiary_round_plan_item.round_plan_item.woreda.name,
      fdp: detail.beneficiary_round_plan_item.round_plan_item.fdp.name,
      commodity_category: detail.round_ration.commodity_category.name,
      beneficiaries: detail.beneficiary_round_plan_item.beneficiaries,
      unit_id: detail.unit_id,
      unit: detail.unit.abbreviation,
      quantity: detail.quantity,
      source_id: nil,
      destination_id: detail.beneficiary_round_plan_item.round_plan_item.fdp.id,
      commodity_id: nil,
      commodity_status: Cats::Core::Commodity::GOOD
    }
  end
  {
    reference_no: nil,
    dispatchable_id: id,
    dispatchable_type: "Cats::Core::RoundPlan",
    items: items
  }
end

#send_notification(allocation) ⇒ Object

Raises:

  • (StandardError)


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'app/services/cats/core/dispatch_plan_service.rb', line 42

def send_notification(allocation)
  notification_rule = Cats::Core::NotificationRule.find_by(code: "allocation")
  raise(StandardError, "Notification rule not found for allocation notification.") unless notification_rule

  users = Cats::Core::User.joins(:roles).where(cats_core_roles: {name: notification_rule.roles})
  allocation.dispatch_plan_items.each do |item|
    location_id = item.destination_id

    recipients = users.map do |user|
      details = user.details
      if (details.key?("warehouse") && details["warehouse"] == location_id) ||
         (details.key?("hub") && details["hub"] == location_id)
        user
      end
    end.compact
    unless recipients.empty?
      notification = Cats::Core::AllocationNotification.with(allocation_item: item)
      notification.deliver(recipients)
    end
  end
end