cats_core 1.4.23 → 1.4.26

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: 3c58aa13420d9d6df2e5954237e8d8fbfef4db3d620636a49bba9ba2c6d30eb2
4
- data.tar.gz: 6ff8e9bc22538cef900ed1e4ef1d80620699f5b94df2bbf8771f37cf4b0367b1
3
+ metadata.gz: 67116f414334d42cf370f7a2ec48cf137bd1ac0c8d1345e0ce5c99f8fc87c57c
4
+ data.tar.gz: 0fc96065462743887b84a6bc750f97d52bd1f047a32c71fa1b70bb3eda9148cb
5
5
  SHA512:
6
- metadata.gz: caf7a1b4209a0405e22dbf86736424ce82f577ded281348911faed27a1cbc9e232c35eea14cdb768d2655aaa8dcce9fda5362ac3c60ec088b13522a191eeabbc
7
- data.tar.gz: 2992ab176cd20d2e82a56ac9fc178d5aa06cc8870aa67c5c545f42804c9d31dc082203ef5cdebae968b69aee147689056d06401cffe35f4d566d0c5026bf470c
6
+ metadata.gz: 148225081058c17d1435f7888da4076ecfacb458a37154e64fd5eabe1fb3470cc3ff4fcafa696db893eb3d3a70ad90920cb25b408723fd4140b3a6e1f70d02ea
7
+ data.tar.gz: a7ee6bc61afe79bfbb22d65a02852ea00a0872971c023fd0783f30de6f33b59eb47a4807887b239aa8e54996eca58924fdae8321c73c1af2db078e193f39067d
@@ -10,8 +10,8 @@ module Cats
10
10
  end
11
11
 
12
12
  def confirm
13
- service = AuthorizationService.new
14
- authorization = service.confirm(params[:id])
13
+ authorization = DispatchAuthorization.find(params[:id])
14
+ authorization = authorization.confirm
15
15
  render json: { success: true, data: serialize(authorization) }
16
16
  rescue StandardError => e
17
17
  render json: { success: false, error: e.message }
@@ -2,8 +2,8 @@ module Cats
2
2
  module Core
3
3
  class DispatchesController < ApplicationController
4
4
  include Common
5
-
6
- before_action :set_service, only: %i[create_receipt_authorization approve start search confirm]
5
+ skip_before_action :authenticate, only: %i[start_with_pin]
6
+ before_action :set_service, only: %i[create_receipt_authorization approve start start_with_pin search confirm]
7
7
 
8
8
  def index
9
9
  super do
@@ -35,6 +35,13 @@ module Cats
35
35
  render json: { success: false, error: e.message }
36
36
  end
37
37
 
38
+ def start_with_pin
39
+ dispatch = @service.start_with_pin(params[:id], start_with_pin_params[:pin])
40
+ render json: { success: true, data: serialize(dispatch) }
41
+ rescue StandardError => e
42
+ render json: { success: false, error: e.message }
43
+ end
44
+
38
45
  def confirm
39
46
  dispatch = set_object
40
47
  dispatch.confirm
@@ -68,6 +75,10 @@ module Cats
68
75
  params.require(:payload).permit(:reference_no, :dispatch_plan_item_id, :transporter_id, :plate_no, :unit_id,
69
76
  :driver_name, :driver_phone, :remark)
70
77
  end
78
+
79
+ def start_with_pin_params
80
+ params.require(:payload).permit(:pin)
81
+ end
71
82
  end
72
83
  end
73
84
  end
@@ -17,6 +17,23 @@ module Cats
17
17
  render json: { success: false, error: e.message }
18
18
  end
19
19
 
20
+ def stack
21
+ service = AuthorizationService.new
22
+ authorization = ReceiptAuthorization.find(params[:id])
23
+ authorization = service.stack(authorization.id)
24
+ render json: { success: true, data: serialize(authorization) }
25
+ rescue StandardError => e
26
+ render json: { success: false, error: e.message }
27
+ end
28
+
29
+ def storekeeper_authorizations
30
+ storekeeper = User.find(params[:id])
31
+ status = params[:status]
32
+ stores = storekeeper.stores
33
+ authorizations = ReceiptAuthorization.where(store: stores, status: status)
34
+ render json: { success: true, data: serialize(authorizations) }
35
+ end
36
+
20
37
  private
21
38
 
22
39
  def model_params
@@ -46,11 +46,19 @@ module Cats
46
46
 
47
47
  def confirm
48
48
  if instance_of?(DispatchAuthorization)
49
- raise(StandardError, 'Authorization does not have transactions.') if transactions.blank?
50
-
51
- transactions.each(&:commit)
52
- # count = transactions.where(status: Transaction::DRAFT).count
53
- # raise(StandardError, 'There are uncommitted transactions.') if count.positive?
49
+ ActiveRecord::Base.transaction do
50
+ raise(StandardError, 'Authorization does not have transactions.') if transactions.blank?
51
+
52
+ transactions.each(&:commit)
53
+ self.status = CONFIRMED
54
+ save!
55
+ if dispatch.all_authorizations_confirmed?
56
+ dispatch.generate_pin
57
+ dispatch.quantity = dispatch.dispatch_transactions.sum(:quantity)
58
+ dispatch.dispatch_status = Dispatch::READY_TO_START
59
+ dispatch.save!
60
+ end
61
+ end
54
62
  elsif instance_of?(ReceiptAuthorization)
55
63
  raise(StandardError, 'Authorization does not have receipts.') unless receipts.count.positive?
56
64
 
@@ -60,8 +68,16 @@ module Cats
60
68
  raise(StandardError, "A quantity of #{diff} is unaccounted for.") unless diff.zero?
61
69
 
62
70
  self.received_quantity = total_received
71
+ self.status = CONFIRMED
72
+ save!
73
+ generate_pin
63
74
  end
64
- self.status = CONFIRMED
75
+ self
76
+ end
77
+
78
+ def generate_pin
79
+ pin = SecureRandom.hex(10)
80
+ self.auth_details = { pin: pin, active: true, expires_at: DateTime.now + 1.hour }
65
81
  save!
66
82
  end
67
83
 
@@ -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, ARRIVED, UNLOADED, RECEIVED].freeze
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, ARRIVED, UNLOADED]
92
+ dispatch_status: [APPROVED, STARTED]
82
93
  )
83
94
  dispatches.map do |dispatch|
84
95
  {
@@ -92,6 +103,12 @@ module Cats
92
103
  }
93
104
  end
94
105
  end
106
+
107
+ def generate_pin
108
+ pin = SecureRandom.hex(10)
109
+ self.auth_details = { pin: pin, active: true, expires_at: DateTime.now + 1.hour }
110
+ save!
111
+ end
95
112
  end
96
113
  end
97
114
  end
@@ -2,7 +2,7 @@ module Cats
2
2
  module Core
3
3
  class DispatchAuthorizationSerializer < ActiveModel::Serializer
4
4
  attributes :id, :dispatch_id, :dispatch_reference_no, :store_id, :store_name, :quantity, :authorized_by_id,
5
- :authorizer_full_name, :dispatch_status, :plate_no, :driver_name
5
+ :authorizer_full_name, :dispatch_status, :plate_no, :driver_name, :status
6
6
  end
7
7
  end
8
8
  end
@@ -3,7 +3,7 @@ module Cats
3
3
  class DispatchSerializer < ActiveModel::Serializer
4
4
  attributes :id, :reference_no, :dispatch_plan_item_id, :transporter_id, :transporter_name, :plate_no,
5
5
  :driver_name, :driver_phone, :quantity, :remark, :prepared_by_id, :prepared_by_email,
6
- :dispatch_status, :destination
6
+ :dispatch_status, :destination, :auth_details
7
7
 
8
8
  def destination
9
9
  object.dispatch_plan_item.destination.name
@@ -2,7 +2,7 @@ module Cats
2
2
  module Core
3
3
  class ReceiptAuthorizationSerializer < ActiveModel::Serializer
4
4
  attributes :id, :dispatch_id, :dispatch_reference_no, :store_id, :store_name, :quantity, :received_quantity,
5
- :remark, :status, :authorized_by_id, :authorizer_full_name
5
+ :remark, :status, :authorized_by_id, :authorizer_full_name, :auth_details
6
6
  end
7
7
  end
8
8
  end
@@ -1,23 +1,45 @@
1
1
  module Cats
2
2
  module Core
3
3
  class AuthorizationService
4
- # A method to confirm a dispatch authorization. This method
5
- # also checks if all authorizations under a dispatch are confirmed
6
- # and if so it sets the dispatch status to READY_TO_START.
7
- def confirm(id)
8
- authorization = DispatchAuthorization.find(id)
9
-
10
- ActiveRecord::Base.transaction do
11
- authorization.confirm
12
-
13
- # Check if all authorizations under the dispatch are confirmed.
14
- dispatch = authorization.dispatch
15
- if dispatch.all_authorizations_confirmed?
16
- dispatch.quantity = dispatch.dispatch_transactions.sum(:quantity)
17
- dispatch.dispatch_status = Dispatch::READY_TO_START
18
- dispatch.save!
19
- end
4
+ def driver_confirm(authorization_id, pin)
5
+ authorization = ReceiptAuthorization.find(authorization_id)
6
+ if authorization.status == Authorization::AUTHORIZED
7
+ raise(StandardError, 'Authorization not confirmed by storekeeper.')
20
8
  end
9
+
10
+ raise(StandardError, 'No pin has been generated for receipt.') if authorization.auth_details.nil?
11
+
12
+ raise(StandardError, 'Incorrect pin.') unless pin == authorization.auth_details['pin']
13
+
14
+ raise(StandardError, 'Pin is not active.') unless authorization.auth_details['active']
15
+
16
+ if DateTime.now > authorization.auth_details['expires_at']
17
+ authorization.auth_details[:active] = false
18
+ authorization.save!
19
+ raise(StandardError, 'Pin has expired.')
20
+ end
21
+
22
+ authorization.driver_confirmed = true
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
21
43
  authorization
22
44
  end
23
45
  end
@@ -37,6 +37,28 @@ module Cats
37
37
  dispatch
38
38
  end
39
39
 
40
+ def start_with_pin(dispatch_id, pin)
41
+ dispatch = Dispatch.find(dispatch_id)
42
+ raise(StandardError, 'Dispatch is already started.') if dispatch.dispatch_status == Dispatch::STARTED
43
+
44
+ raise(StandardError, 'No pin has been generated for dispatch.') if dispatch.auth_details.nil?
45
+
46
+ raise(StandardError, 'Incorrect pin.') unless pin == dispatch.auth_details['pin']
47
+
48
+ raise(StandardError, 'Pin is not active.') unless dispatch.auth_details['active']
49
+
50
+ if DateTime.now > dispatch.auth_details['expires_at']
51
+ dispatch.auth_details[:active] = false
52
+ dispatch.save!
53
+ raise(StandardError, 'Pin has expired.')
54
+ end
55
+ dispatch.start
56
+ send_notification(dispatch)
57
+ dispatch.auth_details = nil
58
+ dispatch.save!
59
+ dispatch
60
+ end
61
+
40
62
  def send_notification(dispatch)
41
63
  notification_rule = Cats::Core::NotificationRule.find_by(code: 'dispatch')
42
64
  raise(StandardError, 'Notification rule not found for dispatch notification.') unless notification_rule
@@ -34,13 +34,10 @@ module Cats
34
34
  end
35
35
  end
36
36
 
37
- def receipt_stacks(receipt)
38
- location = receipt.dispatch.dispatch_plan_item.destination
39
- warehouses = location.children
40
- stores = Store.where(warehouse: warehouses)
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
@@ -107,6 +107,7 @@ Cats::Core::Engine.routes.draw do
107
107
  post 'approve'
108
108
  post 'start'
109
109
  post 'confirm'
110
+ post 'start_with_pin'
110
111
  end
111
112
  end
112
113
 
@@ -118,10 +119,16 @@ Cats::Core::Engine.routes.draw do
118
119
  end
119
120
 
120
121
  get(
121
- '/storekeeper/:id/authorizations',
122
+ '/storekeeper/:id/dispatch_authorizations',
122
123
  controller: :dispatch_authorizations,
123
124
  action: :storekeeper_authorizations,
124
- as: :storekeeper_authorizations
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
125
132
  )
126
133
  resources :receipt_authorizations, except: %i[index destroy] do
127
134
  member do
@@ -129,6 +136,7 @@ Cats::Core::Engine.routes.draw do
129
136
  get 'lost', controller: :lost_commodities, action: :index
130
137
  get 'receipts', controller: :receipts, action: :index
131
138
  post 'confirm', controller: :receipt_authorizations, action: :confirm
139
+ post 'stack'
132
140
  end
133
141
  end
134
142
 
@@ -25,6 +25,7 @@ class CreateCatsCoreDispatches < ActiveRecord::Migration[6.1]
25
25
  index: { name: 'pb_on_dispatches_indx' },
26
26
  foreign_key: { to_table: :cats_core_users }
27
27
  t.string :dispatch_status, null: false
28
+ t.jsonb :auth_details
28
29
 
29
30
  t.timestamps
30
31
  end
@@ -13,6 +13,8 @@ class CreateCatsCoreReceiptAuthorizations < ActiveRecord::Migration[6.1]
13
13
  t.float :received_quantity, null: false, default: 0
14
14
  t.string :status, null: false, default: 'Authorized'
15
15
  t.string :remark
16
+ t.jsonb :auth_details
17
+ t.boolean :driver_confirmed, null: false, default: false
16
18
  t.references :authorized_by,
17
19
  null: false,
18
20
  index: { name: 'ab_on_receipt_authorizations_indx' },
@@ -1,5 +1,5 @@
1
1
  module Cats
2
2
  module Core
3
- VERSION = '1.4.23'.freeze
3
+ VERSION = '1.4.26'.freeze
4
4
  end
5
5
  end
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.23
4
+ version: 1.4.26
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-28 00:00:00.000000000 Z
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