cats_core 1.1.35 → 1.1.36

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: 03dde5a3e8c977259c5f5c64e2c72feb8212babba6ed10e7d02ea85db7e5eac2
4
- data.tar.gz: 970ad6b55fbe1ff4d4c2cc6cecc48585f6d51b5773ba876cce143ad241827f6a
3
+ metadata.gz: 9d66e9f780b4e36013c3eac6a0c319e61270199d621eea8cc1747451eb09e95b
4
+ data.tar.gz: 83c8aee6ba3e4a15d3aa6a0255f0c8a6aead3247fed994e5ced103c91cc1d314
5
5
  SHA512:
6
- metadata.gz: a7e4bd908db5af74c49d9306580fbfb743de780e000ba3c8d3406da35f454cfc74fef146255d1bde7e1677207cc9cb0b5bb75b2c357a2c11e0057de631c56ea1
7
- data.tar.gz: 2d0658c343d3d30b3fc86c11c41fc273c45b00014bda643d0afd21f21a43fcf7803e1b8b6f9de093aee489e76f1b16f3efb8ade979b9c987d923c7c88ea22d24
6
+ metadata.gz: b77f6a0923079b2e847b263602e42fb489245f15442b11ccd0509d4c6b3790b1f3950469557a686d0b4cbeb9f34c9c94dc14c82e853e0d2d064d42c5db3bd4e8
7
+ data.tar.gz: ac19f2ff28600eaa8d580bef4d6ad8fdec01ea0511f163d486d8bc3397e67d95eab82a79c32977b01e88952f789d53198a40c599fc977c14a623f4cf3eb4da12
@@ -31,8 +31,8 @@ module Cats
31
31
  end
32
32
 
33
33
  def approve
34
- dispatch = @service.approve(@dispatch)
35
- render json: { success: true, data: serialize(dispatch) }
34
+ @dispatch.approve
35
+ render json: { success: true, data: serialize(@dispatch) }
36
36
  rescue StandardError => e
37
37
  render json: { success: false, error: e.message }
38
38
  end
@@ -45,8 +45,8 @@ module Cats
45
45
  end
46
46
 
47
47
  def confirm
48
- dispatch = @service.confirm(@dispatch)
49
- render json: { success: true, data: serialize(dispatch) }
48
+ @dispatch.confirm
49
+ render json: { success: true, data: serialize(@dispatch) }
50
50
  rescue StandardError => e
51
51
  render json: { success: false, error: e.message }
52
52
  end
@@ -13,9 +13,15 @@ module Cats
13
13
  validates :commodity_status, :allocation_status, presence: true
14
14
  validates :reference_no, presence: true, uniqueness: true
15
15
  validates :quantity, presence: true, numericality: { greater_than: 0 }
16
- validates :commodity_status, inclusion: { in: Cats::Core::Commodity::COMMODITY_STATUSES }
16
+ validates :commodity_status, inclusion: { in: Commodity::COMMODITY_STATUSES }
17
17
  validates :allocation_status, inclusion: { in: ALLOCATION_STATUSES }
18
- validate :validate_quantity_against_items, :validate_quantity_against_commodity
18
+ validate :validate_quantity_against_items, :validate_quantity_against_commodity,
19
+ :validate_quantity_against_request, :validate_request_status, :validate_commodity_status
20
+
21
+ delegate(:reference_no, to: :rhn_request, prefix: :rhn, allow_nil: true)
22
+ delegate(:batch_no, to: :commodity, prefix: true)
23
+ delegate(:name, to: :source, prefix: true)
24
+ delegate(:location_type, to: :source, prefix: true)
19
25
 
20
26
  def validate_quantity_against_items
21
27
  return unless quantity
@@ -36,10 +42,33 @@ module Cats
36
42
  errors.add(:quantity, "exceeds commodity quantity. Maximum allowed is #{remaining}") if quantity > remaining
37
43
  end
38
44
 
39
- delegate(:reference_no, to: :rhn_request, prefix: :rhn, allow_nil: true)
40
- delegate(:batch_no, to: :commodity, prefix: true)
41
- delegate(:name, to: :source, prefix: true)
42
- delegate(:location_type, to: :source, prefix: true)
45
+ def validate_quantity_against_request
46
+ return unless quantity && rhn_request
47
+
48
+ errors.add(:quantity, 'is not equal to requested quantity.') if quantity != rhn_request.quantity
49
+ end
50
+
51
+ def validate_request_status
52
+ return unless rhn_request
53
+
54
+ errors.add(:rhn_request, 'should be approved first.') if rhn_request.status != RhnRequest::APPROVED
55
+ end
56
+
57
+ def validate_commodity_status
58
+ return unless commodity
59
+
60
+ errors.add(:commodity, 'should be approved first.') unless commodity.approved
61
+ end
62
+
63
+ def approve
64
+ raise(StandardError, 'Allocation already approved.') if allocation_status == Allocation::APPROVED
65
+
66
+ item_quantity = allocation_items.sum(:quantity)
67
+ raise(StandardError, 'Allocation quantity and items quantity do not match.') if quantity != item_quantity
68
+
69
+ self.allocation_status = Allocation::APPROVED
70
+ save!
71
+ end
43
72
  end
44
73
  end
45
74
  end
@@ -7,6 +7,7 @@ module Cats
7
7
  validates :from, :to, presence: true
8
8
  validates :quantity, presence: true, numericality: { greater_than: 0 }
9
9
  validate :validate_source_and_destination, :validate_quantity
10
+ validate :validate_allocation_status, on: %i[create update]
10
11
 
11
12
  def validate_source_and_destination
12
13
  return unless allocation.present? && destination.present?
@@ -24,6 +25,14 @@ module Cats
24
25
  errors.add(:quantity, "exceeds allocated quantity. Maximum allowed is #{remaining}") if quantity > remaining
25
26
  end
26
27
 
28
+ def validate_allocation_status
29
+ return unless allocation
30
+
31
+ return unless allocation.allocation_status == Cats::Core::Allocation::APPROVED
32
+
33
+ errors.add(:allocation, 'is alreay approved. Changes are not allowed at this point.')
34
+ end
35
+
27
36
  delegate(:name, to: :destination, prefix: true)
28
37
  delegate(:reference_no, to: :allocation, prefix: true)
29
38
  delegate(:location_type, to: :destination, prefix: true)
@@ -20,7 +20,7 @@ module Cats
20
20
  validates :reference_no, uniqueness: true
21
21
  validates :quantity, numericality: { greater_than: 0 }
22
22
  validates :commodity_status, inclusion: { in: Cats::Core::Commodity::COMMODITY_STATUSES }
23
- validate :validate_quantity
23
+ validate :validate_quantity, :validate_allocation_status
24
24
 
25
25
  delegate(:name, to: :transporter, prefix: true)
26
26
  delegate(:email, to: :prepared_by, prefix: true)
@@ -34,6 +34,54 @@ module Cats
34
34
  remaining = allocation_item.quantity - dispatched
35
35
  errors.add(:quantity, "exceeds allocated quantity. Maximum allowed is #{remaining}") if quantity > remaining
36
36
  end
37
+
38
+ def validate_allocation_status
39
+ return unless allocation_item
40
+
41
+ status = allocation_item.allocation.allocation_status
42
+ errors.add(:allocation_item, 'should be approved first.') unless status == Allocation::APPROVED
43
+ end
44
+
45
+ def approve
46
+ raise(StandardError, 'Dispatch has to be in draft state.') unless dispatch_status == Dispatch::DRAFT
47
+
48
+ count = DispatchTransaction.where(destination_id: id).count
49
+ raise(StandardError, 'Dispatch has no transactions.') unless count.positive?
50
+
51
+ quantity = DispatchTransaction.where(destination_id: id).sum(:quantity)
52
+ raise(StandardError, 'Transactions quantity is not equal to dispatch quantity.') if self.quantity != quantity
53
+
54
+ self.dispatch_status = Dispatch::APPROVED
55
+ save!
56
+ end
57
+
58
+ def start
59
+ raise(StandardError, 'Dispatch has to be approved first.') unless dispatch_status == Dispatch::APPROVED
60
+
61
+ self.dispatch_status = Dispatch::STARTED
62
+ save!
63
+ transactions = DispatchTransaction.where(destination_id: id)
64
+ transactions.each(&:commit)
65
+ end
66
+
67
+ def confirm
68
+ total = receipts.sum(:quantity)
69
+
70
+ unless total == quantity
71
+ diff = (quantity - total).abs
72
+ raise(
73
+ StandardError,
74
+ "There is an amount of #{diff} in the dispatch which is unaccounted for."
75
+ )
76
+ end
77
+
78
+ Dispatch.transaction do
79
+ self.dispatch_status = Dispatch::RECEIVED
80
+ receipts.each { |r| r.status = Receipt::CONFIRMED }
81
+ save!
82
+ receipts.each(&:save!)
83
+ end
84
+ end
37
85
  end
38
86
  end
39
87
  end
@@ -35,15 +35,9 @@ module Cats
35
35
 
36
36
  received = dispatch.receipts.sum(:quantity)
37
37
  diff = dispatch.quantity - received
38
- if new_record?
39
- return if quantity <= diff
38
+ diff += quantity_was if quantity_was
40
39
 
41
- errors.add(:quantity, "total is higher than dispatch quantity (Max = #{diff}).")
42
- else
43
- return unless diff.negative?
44
-
45
- errors.add(:quantity, "total is higher than dispatch quantity (Max = #{diff.abs}).")
46
- end
40
+ errors.add(:quantity, "total is higher than dispatch quantity (Max = #{diff}).") if quantity > diff
47
41
  end
48
42
  end
49
43
  end
@@ -1,13 +1,35 @@
1
1
  module Cats
2
2
  module Core
3
3
  class RhnRequest < ApplicationRecord
4
+ DRAFT = 'Draft'.freeze
5
+ APPROVED = 'Approved'.freeze
6
+ STATUSES = [DRAFT, APPROVED].freeze
7
+
4
8
  belongs_to :commodity
5
9
 
6
10
  validates :reference_no, :request_date, :quantity, presence: true
7
11
  validates :reference_no, uniqueness: true
8
12
  validates :quantity, numericality: { greater_than: 0 }
13
+ validates :status, presence: true, inclusion: { in: STATUSES }
14
+ validate :validate_commodity_status, :validate_quantity
9
15
 
10
16
  delegate(:batch_no, to: :commodity, prefix: true)
17
+
18
+ def validate_commodity_status
19
+ return unless commodity
20
+
21
+ errors.add(:commodity, 'should be approved first.') unless commodity.approved
22
+ end
23
+
24
+ def validate_quantity
25
+ return unless commodity && quantity
26
+
27
+ requested = RhnRequest.where(commodity: commodity).sum(:quantity)
28
+ remaining = commodity.quantity - requested
29
+
30
+ remaining += quantity_was if quantity_was
31
+ errors.add(:quantity, "exceeds commodity quantity. Maximum allowed is #{remaining}") if quantity > remaining
32
+ end
11
33
  end
12
34
  end
13
35
  end
@@ -2,9 +2,6 @@ module Cats
2
2
  module Core
3
3
  class DispatchService
4
4
  def create_receipt_authorization(reference_no, allocation_item, quantity, remark, user)
5
- status = allocation_item.allocation.allocation_status
6
- raise(StandardError, 'Allocation not approved.') unless status == Cats::Core::Allocation::APPROVED
7
-
8
5
  transporter = Cats::Core::Transporter.find_by(code: 'SUP-TRANS')
9
6
  raise(StandardError, 'Supplier transporter does not exist.') unless transporter
10
7
 
@@ -16,27 +13,30 @@ module Cats
16
13
 
17
14
  raise(StandardError, 'Commodity not found in supplier store.') unless stack
18
15
 
19
- dispatch = Cats::Core::Dispatch.create!(
20
- reference_no: reference_no,
21
- allocation_item: allocation_item,
22
- transporter: transporter,
23
- plate_no: 'Supplier plate no',
24
- driver_name: 'Supplier driver',
25
- driver_phone: 'Supplier driver phone',
26
- quantity: quantity,
27
- remark: remark,
28
- prepared_by: user,
29
- dispatch_status: Cats::Core::Dispatch::DRAFT
30
- )
16
+ dispatch = nil
17
+ ApplicationRecord.transaction do
18
+ dispatch = Cats::Core::Dispatch.create!(
19
+ reference_no: reference_no,
20
+ allocation_item: allocation_item,
21
+ transporter: transporter,
22
+ plate_no: 'Supplier plate no',
23
+ driver_name: 'Supplier driver',
24
+ driver_phone: 'Supplier driver phone',
25
+ quantity: quantity,
26
+ remark: remark,
27
+ prepared_by: user,
28
+ dispatch_status: Cats::Core::Dispatch::DRAFT
29
+ )
31
30
 
32
- # Create a dispatch transaction
33
- Cats::Core::DispatchTransaction.create!(
34
- source: stack,
35
- destination: dispatch,
36
- transaction_date: Date.today,
37
- quantity: quantity,
38
- status: Cats::Core::Transaction::DRAFT
39
- )
31
+ # Create a dispatch transaction
32
+ Cats::Core::DispatchTransaction.create!(
33
+ source: stack,
34
+ destination: dispatch,
35
+ transaction_date: Date.today,
36
+ quantity: quantity,
37
+ status: Cats::Core::Transaction::DRAFT
38
+ )
39
+ end
40
40
  dispatch
41
41
  end
42
42
 
@@ -87,52 +87,12 @@ module Cats
87
87
  dispatches
88
88
  end
89
89
 
90
- def approve(dispatch)
91
- unless dispatch.dispatch_status == Cats::Core::Dispatch::DRAFT
92
- raise(StandardError, 'Dispatch has to be in draft state.')
93
- end
94
-
95
- transactions = Cats::Core::DispatchTransaction.where(destination: dispatch).count
96
- raise(StandardError, 'Dispatch has no transactions.') unless transactions.positive?
97
-
98
- dispatch.dispatch_status = Cats::Core::Dispatch::APPROVED
99
- dispatch.save
100
- dispatch
101
- end
102
-
103
90
  def start(dispatch)
104
- unless dispatch.dispatch_status == Cats::Core::Dispatch::APPROVED
105
- raise(StandardError, 'Dispatch has to be approved first.')
106
- end
107
-
108
- dispatch.dispatch_status = Cats::Core::Dispatch::STARTED
109
- dispatch.save
110
- transactions = Cats::Core::DispatchTransaction.where(destination: dispatch)
111
- transactions.each(&:commit)
91
+ dispatch.start
112
92
  send_notification(dispatch)
113
93
  dispatch
114
94
  end
115
95
 
116
- def confirm(dispatch)
117
- total = dispatch.receipts.sum(:quantity)
118
-
119
- unless total == dispatch.quantity
120
- raise(
121
- StandardError,
122
- "There is an amount of #{dispatch.quantity - total} in the dispatch which is unaccounted for."
123
- )
124
- end
125
-
126
- Cats::Core::Dispatch.transaction do
127
- dispatch.dispatch_status = Cats::Core::Dispatch::RECEIVED
128
- dispatch.receipts.each { |r| r.status = Cats::Core::Receipt::CONFIRMED }
129
- dispatch.save
130
- dispatch.receipts.each(&:save!)
131
- end
132
-
133
- dispatch
134
- end
135
-
136
96
  def send_notification(dispatch)
137
97
  notification_rule = Cats::Core::NotificationRule.find_by(code: 'dispatch')
138
98
  raise(StandardError, 'Notification rule not found for dispatch notification.') unless notification_rule
@@ -0,0 +1,5 @@
1
+ class AddStatusToCatsCoreRhnRequests < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :cats_core_rhn_requests, :status, :string, null: false, default: 'Draft'
4
+ end
5
+ end
@@ -1,5 +1,5 @@
1
1
  module Cats
2
2
  module Core
3
- VERSION = '1.1.35'.freeze
3
+ VERSION = '1.1.36'.freeze
4
4
  end
5
5
  end
@@ -8,6 +8,6 @@ FactoryBot.define do
8
8
  best_use_before { Date.today + 2.month }
9
9
  volume_per_metric_ton { 10 }
10
10
  arrival_status { Cats::Core::Commodity::AT_SOURCE }
11
- approved { false }
11
+ approved { true }
12
12
  end
13
13
  end
@@ -1,7 +1,12 @@
1
1
  FactoryBot.define do
2
2
  factory :dispatch, class: 'Cats::Core::Dispatch' do
3
3
  reference_no { FFaker::Name.name }
4
- allocation_item
4
+ allocation_item do
5
+ allocation = create(:allocation, quantity: 100)
6
+ allocation_item = create(:allocation_item, allocation: allocation, quantity: 100)
7
+ allocation.approve
8
+ allocation_item
9
+ end
5
10
  transporter
6
11
  plate_no { FFaker::Name.name }
7
12
  driver_name { FFaker::Name.name }
@@ -1,6 +1,12 @@
1
1
  FactoryBot.define do
2
2
  factory :receipt, class: 'Cats::Core::Receipt' do
3
- dispatch factory: :dispatch, dispatch_status: Cats::Core::Dispatch::STARTED
3
+ dispatch do
4
+ dispatch = create(:dispatch)
5
+ create(:dispatch_transaction, destination: dispatch, quantity: 50)
6
+ dispatch.approve
7
+ dispatch.start
8
+ dispatch
9
+ end
4
10
  quantity { 50 }
5
11
  commodity_status { Cats::Core::Commodity::GOOD }
6
12
  status { Cats::Core::Receipt::DRAFT }
@@ -5,5 +5,6 @@ FactoryBot.define do
5
5
  quantity { 100 }
6
6
  request_date { Date.today }
7
7
  requested_by { FFaker::Name.name }
8
+ status { Cats::Core::RhnRequest::DRAFT }
8
9
  end
9
10
  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.1.35
4
+ version: 1.1.36
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henock L.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-23 00:00:00.000000000 Z
11
+ date: 2021-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_model_serializers
@@ -345,6 +345,7 @@ files:
345
345
  - db/migrate/20210814160628_create_cats_core_receipt_transactions.rb
346
346
  - db/migrate/20210814175406_create_cats_core_stack_transactions.rb
347
347
  - db/migrate/20211002050739_create_cats_core_notification_rules.rb
348
+ - db/migrate/20211024063240_add_status_to_cats_core_rhn_requests.rb
348
349
  - lib/cats/core.rb
349
350
  - lib/cats/core/engine.rb
350
351
  - lib/cats/core/version.rb