cats_core 1.3.35 → 1.3.38
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 +4 -4
- data/app/controllers/cats/core/commodities_controller.rb +41 -0
- data/app/controllers/cats/core/dispatch_transactions_controller.rb +2 -2
- data/app/controllers/cats/core/dispatches_controller.rb +0 -8
- data/app/controllers/cats/core/lost_commodities_controller.rb +16 -0
- data/app/controllers/cats/core/monthly_plans_controller.rb +62 -0
- data/app/controllers/cats/core/receipt_transactions_controller.rb +3 -3
- data/app/models/cats/core/dispatch.rb +16 -10
- data/app/models/cats/core/dispatch_transaction.rb +3 -2
- data/app/models/cats/core/lost_commodity.rb +10 -0
- data/app/models/cats/core/receipt.rb +2 -2
- data/app/models/cats/core/receipt_transaction.rb +19 -1
- data/app/models/cats/core/stack_transaction.rb +11 -0
- data/app/models/cats/core/transaction.rb +14 -9
- data/app/serializers/cats/core/commodity_category_serializer.rb +5 -1
- data/app/serializers/cats/core/dispatch_transaction_serializer.rb +1 -1
- data/app/serializers/cats/core/lost_commodity_serializer.rb +7 -0
- data/app/serializers/cats/core/monthly_plan_serializer.rb +7 -0
- data/app/serializers/cats/core/receipt_transaction_serializer.rb +3 -3
- data/app/services/cats/core/dispatch_service.rb +17 -80
- data/app/services/cats/core/monthly_plan_service.rb +86 -0
- data/app/services/cats/core/receipt_service.rb +1 -1
- data/config/routes.rb +18 -4
- data/db/migrate/20210718045516_create_cats_core_dispatches.rb +1 -1
- data/db/migrate/20210718202957_create_cats_core_dispatch_transactions.rb +1 -1
- data/db/migrate/20210728041505_create_cats_core_lost_commodities.rb +15 -0
- data/db/migrate/20210814160628_create_cats_core_receipt_transactions.rb +1 -1
- data/lib/cats/core/version.rb +1 -1
- data/spec/factories/cats/core/dispatch_transactions.rb +10 -2
- data/spec/factories/cats/core/dispatches.rb +9 -1
- data/spec/factories/cats/core/lost_commodities.rb +8 -0
- data/spec/factories/cats/core/receipt_transactions.rb +23 -3
- data/spec/factories/cats/core/receipts.rb +1 -2
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef9922d4ff8da58afc9045f7390132b817ce7610941fda378ed3adc061dcb68b
|
4
|
+
data.tar.gz: 2a2005f25ab47f22fd012ab301b5317d41b97ff159f8421826bacf7a4dcab5b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b32b1b7c224845b8c48281da4815d5f4125c87cf954b427ba06ead6c3dbc3c01afbc112552950ef016693d05a7daa565086d54000dd8d496c6526ce7f307b4a5
|
7
|
+
data.tar.gz: cfb9210cd040ca426977ed23c74a3f039ad01fd0d8b36b1e2e9f58c751ffd2b9df2695ac63755ffb7016e44d5c2cdbfc5c5c7939ba136930f2a7734618974ef3
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Cats
|
2
|
+
module Core
|
3
|
+
class CommoditiesController < ApplicationController
|
4
|
+
include Common
|
5
|
+
|
6
|
+
def approve
|
7
|
+
commodity = Cats::Core::Commodity.find(params[:id])
|
8
|
+
result = commodity.approve
|
9
|
+
render json: { success: result, data: serialize(commodity) }
|
10
|
+
rescue StandardError => e
|
11
|
+
render json: { success: false, error: e.message }
|
12
|
+
end
|
13
|
+
|
14
|
+
def update
|
15
|
+
if @obj.status == Cats::Core::Commodity::APPROVED
|
16
|
+
render json: { success: false, error: 'An approved record cannot be edited.' }
|
17
|
+
return
|
18
|
+
end
|
19
|
+
|
20
|
+
if @obj.update(model_params)
|
21
|
+
render json: { success: true, data: serialize(@obj) }
|
22
|
+
else
|
23
|
+
render json: { success: false, error: @obj.errors.full_messages[0] }, status: :unprocessable_entity
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def filter
|
28
|
+
query = Cats::Core::Commodity.ransack(params[:q])
|
29
|
+
render json: { success: true, data: serialize(query.result) }
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def model_params
|
35
|
+
params.require(:payload).permit(:batch_no, :description, :unit_of_measure_id, :source_id,
|
36
|
+
:source_type, :quantity, :best_use_before, :volume_per_metric_ton,
|
37
|
+
:arrival_status)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -4,14 +4,14 @@ module Cats
|
|
4
4
|
include Common
|
5
5
|
|
6
6
|
def index
|
7
|
-
transactions = Cats::Core::DispatchTransaction.where(
|
7
|
+
transactions = Cats::Core::DispatchTransaction.where(dispatch_id: params[:id])
|
8
8
|
render json: { success: true, data: serialize(transactions) }
|
9
9
|
end
|
10
10
|
|
11
11
|
private
|
12
12
|
|
13
13
|
def model_params
|
14
|
-
params.require(:payload).permit(:source_id, :
|
14
|
+
params.require(:payload).permit(:source_id, :dispatch_id, :transaction_date, :quantity)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -22,14 +22,6 @@ module Cats
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
def create_receipt_authorization
|
26
|
-
item = Cats::Core::DispatchPlanItem.find(params[:id])
|
27
|
-
dispatch = @service.create_receipt_authorization(
|
28
|
-
params[:reference_no], item, params[:quantity], params[:remark], current_user
|
29
|
-
)
|
30
|
-
render json: { success: true, data: serialize(dispatch) }
|
31
|
-
end
|
32
|
-
|
33
25
|
def approve
|
34
26
|
@dispatch.approve
|
35
27
|
render json: { success: true, data: serialize(@dispatch) }
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Cats
|
2
|
+
module Core
|
3
|
+
class LostCommoditiesController < ApplicationController
|
4
|
+
include Common
|
5
|
+
|
6
|
+
def index
|
7
|
+
data = LostCommodity.where(dispatch_id: params[:id])
|
8
|
+
render json: { success: true, data: serialize(data) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def model_params
|
12
|
+
params.require(:payload).permit(:dispatch_id, :quantity, :commodity_status, :remark)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Cats
|
2
|
+
module Core
|
3
|
+
class MonthlyPlansController < ApplicationController
|
4
|
+
include Common
|
5
|
+
|
6
|
+
before_action :set_service, only: %i[generate remove_items generate_monthly_needs]
|
7
|
+
|
8
|
+
def index
|
9
|
+
plans = Cats::Core::MonthlyPlan.where(plan: params[:id])
|
10
|
+
render json: { success: true, data: serialize(plans) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def filter
|
14
|
+
query = Cats::Core::MonthlyPlan.ransack(params[:q])
|
15
|
+
render json: { success: true, data: serialize(query.result) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def approve
|
19
|
+
plan = Cats::Core::MonthlyPlan.find(params[:id])
|
20
|
+
if plan.monthly_plan_items.count.zero?
|
21
|
+
render json: { success: false, error: 'Empty plan cannot be approved.' }, status: :unprocessable_entity
|
22
|
+
return
|
23
|
+
end
|
24
|
+
plan.update(status: Cats::Core::Plan::APPROVED)
|
25
|
+
render json: { success: true, data: serialize(plan) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def generate
|
29
|
+
plan = @service.generate_monthly_plan(model_params)
|
30
|
+
render json: { success: true, data: serialize(plan) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def generate_monthly_needs
|
34
|
+
plan = @service.generate_monthly_needs(params[:id])
|
35
|
+
render json: { success: true, data: serialize(plan) }
|
36
|
+
rescue StandardError => e
|
37
|
+
render json: { success: false, error: e.message }
|
38
|
+
end
|
39
|
+
|
40
|
+
def remove_items
|
41
|
+
plan = @service.remove_items(params[:id], remove_params)
|
42
|
+
render json: { success: true, data: serialize(plan) }
|
43
|
+
rescue StandardError => e
|
44
|
+
render json: { success: false, error: e.message }
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def model_params
|
50
|
+
params.require(:payload).permit(:reference_no, :status, :plan_id, :region_id, :month, :no_of_days)
|
51
|
+
end
|
52
|
+
|
53
|
+
def set_service
|
54
|
+
@service = MonthlyPlanService.new
|
55
|
+
end
|
56
|
+
|
57
|
+
def remove_params
|
58
|
+
params.permit(ids: [])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -4,7 +4,7 @@ module Cats
|
|
4
4
|
include Common
|
5
5
|
|
6
6
|
def index
|
7
|
-
transactions = Cats::Core::ReceiptTransaction.where(
|
7
|
+
transactions = Cats::Core::ReceiptTransaction.where(receipt_id: params[:id])
|
8
8
|
render json: { success: true, data: serialize(transactions) }
|
9
9
|
end
|
10
10
|
|
@@ -13,7 +13,7 @@ module Cats
|
|
13
13
|
|
14
14
|
# Look for a transaction with the same destination as incoming
|
15
15
|
transaction = Cats::Core::ReceiptTransaction.find_by(
|
16
|
-
|
16
|
+
receipt_id: p[:receipt_id],
|
17
17
|
destination_id: p[:destination_id]
|
18
18
|
)
|
19
19
|
if transaction
|
@@ -32,7 +32,7 @@ module Cats
|
|
32
32
|
private
|
33
33
|
|
34
34
|
def model_params
|
35
|
-
params.require(:payload).permit(:
|
35
|
+
params.require(:payload).permit(:receipt_id, :destination_id, :transaction_date, :quantity)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -14,17 +14,23 @@ module Cats
|
|
14
14
|
belongs_to :transporter
|
15
15
|
belongs_to :dispatch_plan_item
|
16
16
|
has_many :receipts
|
17
|
+
has_many :dispatch_transactions
|
18
|
+
has_many :lost_commodities
|
17
19
|
|
18
20
|
validates :reference_no, :plate_no, :driver_name, :driver_phone, :quantity, :commodity_status, presence: true
|
19
21
|
validates :dispatch_status, presence: true, inclusion: { in: DISPATCH_STATUSES }
|
20
22
|
validates :reference_no, uniqueness: true
|
21
|
-
validates :quantity, numericality: {
|
23
|
+
validates :quantity, numericality: { greater_than_or_equal_to: 0 }
|
22
24
|
validates :commodity_status, inclusion: { in: Cats::Core::Commodity::COMMODITY_STATUSES }
|
23
25
|
validate :validate_quantity, :validate_dispatch_plan_status
|
24
26
|
|
25
27
|
delegate(:name, to: :transporter, prefix: true)
|
26
28
|
delegate(:email, to: :prepared_by, prefix: true)
|
27
29
|
|
30
|
+
def total_quantity
|
31
|
+
dispatch_transactions.sum(:quantity)
|
32
|
+
end
|
33
|
+
|
28
34
|
def validate_quantity
|
29
35
|
return unless quantity && dispatch_plan_item
|
30
36
|
|
@@ -46,14 +52,16 @@ module Cats
|
|
46
52
|
def approve
|
47
53
|
raise(StandardError, 'Dispatch has to be in draft state.') unless dispatch_status == Dispatch::DRAFT
|
48
54
|
|
49
|
-
|
50
|
-
raise(StandardError, 'Dispatch has no transactions.') unless count.positive?
|
55
|
+
# Check if dispatch has transactions
|
56
|
+
raise(StandardError, 'Dispatch has no transactions.') unless dispatch_transactions.count.positive?
|
51
57
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
58
|
+
Dispatch.transaction do
|
59
|
+
# Commit transactions
|
60
|
+
dispatch_transactions.each(&:commit)
|
61
|
+
self.quantity = total_quantity
|
62
|
+
self.dispatch_status = Dispatch::APPROVED
|
63
|
+
save!
|
64
|
+
end
|
57
65
|
end
|
58
66
|
|
59
67
|
def start
|
@@ -61,8 +69,6 @@ module Cats
|
|
61
69
|
|
62
70
|
self.dispatch_status = Dispatch::STARTED
|
63
71
|
save!
|
64
|
-
transactions = DispatchTransaction.where(destination_id: id)
|
65
|
-
transactions.each(&:commit)
|
66
72
|
end
|
67
73
|
|
68
74
|
def confirm
|
@@ -2,15 +2,16 @@ module Cats
|
|
2
2
|
module Core
|
3
3
|
class DispatchTransaction < Transaction
|
4
4
|
belongs_to :source, class_name: 'Cats::Core::Stack'
|
5
|
-
belongs_to :
|
5
|
+
belongs_to :dispatch
|
6
6
|
|
7
7
|
delegate(:code, to: :source, prefix: true)
|
8
|
-
delegate(:reference_no, to: :
|
8
|
+
delegate(:reference_no, to: :dispatch, prefix: true)
|
9
9
|
|
10
10
|
def commit
|
11
11
|
Transaction.transaction do
|
12
12
|
source.quantity -= quantity
|
13
13
|
source.save!
|
14
|
+
|
14
15
|
self.status = COMMITTED
|
15
16
|
save!
|
16
17
|
end
|
@@ -10,7 +10,7 @@ module Cats
|
|
10
10
|
|
11
11
|
belongs_to :dispatch
|
12
12
|
belongs_to :prepared_by, class_name: 'Cats::Core::User'
|
13
|
-
has_many :receipt_transactions
|
13
|
+
has_many :receipt_transactions
|
14
14
|
|
15
15
|
validates :quantity, :commodity_status, :status, presence: true
|
16
16
|
validates :quantity, numericality: { greater_than: 0 }
|
@@ -33,7 +33,7 @@ module Cats
|
|
33
33
|
def validate_total_quantity
|
34
34
|
return unless dispatch && quantity
|
35
35
|
|
36
|
-
received = dispatch.receipts.sum(:quantity)
|
36
|
+
received = dispatch.receipts.sum(:quantity) + dispatch.lost_commodities.sum(:quantity)
|
37
37
|
diff = dispatch.quantity - received
|
38
38
|
diff += quantity_was if quantity_was
|
39
39
|
|
@@ -1,11 +1,29 @@
|
|
1
1
|
module Cats
|
2
2
|
module Core
|
3
3
|
class ReceiptTransaction < Transaction
|
4
|
-
belongs_to :
|
4
|
+
belongs_to :receipt
|
5
5
|
belongs_to :destination, class_name: 'Cats::Core::Stack'
|
6
6
|
|
7
7
|
delegate(:code, to: :destination, prefix: true)
|
8
8
|
|
9
|
+
def validate_quantity
|
10
|
+
return unless quantity.present? && destination.present? && receipt.present?
|
11
|
+
|
12
|
+
authorized = receipt.dispatch.dispatch_plan_item.hub_authorizations.where(
|
13
|
+
store: destination.store
|
14
|
+
).sum(:quantity)
|
15
|
+
received = self.class.joins(:destination).where(
|
16
|
+
destination: { store_id: destination.store_id }
|
17
|
+
).sum(:quantity)
|
18
|
+
|
19
|
+
received -= quantity_was if quantity_was
|
20
|
+
|
21
|
+
# Get quantity in hub authorization for source
|
22
|
+
available = authorized - received
|
23
|
+
|
24
|
+
errors.add(:quantity, "exceeds authorized quantity (Max = #{available}).") if quantity > available
|
25
|
+
end
|
26
|
+
|
9
27
|
def commit
|
10
28
|
ReceiptTransaction.transaction do
|
11
29
|
destination.quantity += quantity
|
@@ -3,6 +3,17 @@ module Cats
|
|
3
3
|
class StackTransaction < Transaction
|
4
4
|
belongs_to :source, class_name: 'Cats::Core::Stack'
|
5
5
|
belongs_to :destination, class_name: 'Cats::Core::Stack'
|
6
|
+
|
7
|
+
def validate_quantity
|
8
|
+
return unless quantity.present? && source.present?
|
9
|
+
|
10
|
+
dispatched = StackTransaction.where(source: source, status: DRAFT).sum(:quantity)
|
11
|
+
|
12
|
+
available = source.quantity - dispatched
|
13
|
+
available += quantity_was if quantity_was
|
14
|
+
|
15
|
+
errors.add(:quantity, "total is higher than source quantity (Max = #{available}).") if quantity > available
|
16
|
+
end
|
6
17
|
end
|
7
18
|
end
|
8
19
|
end
|
@@ -15,14 +15,19 @@ module Cats
|
|
15
15
|
validate :validate_quantity, unless: :skip_quantity_validation
|
16
16
|
|
17
17
|
def validate_quantity
|
18
|
-
return unless quantity.present? && source.present?
|
18
|
+
return unless quantity.present? && source.present? && dispatch.present?
|
19
19
|
|
20
|
-
dispatched = self.class.
|
20
|
+
dispatched = self.class.joins(:source, :dispatch).where(
|
21
|
+
source: { store_id: source.store_id },
|
22
|
+
dispatch: { dispatch_plan_item_id: dispatch.dispatch_plan_item_id }
|
23
|
+
).sum(:quantity)
|
24
|
+
dispatched -= quantity_was if quantity_was
|
21
25
|
|
22
|
-
|
23
|
-
|
26
|
+
# Get quantity in hub authorization for source
|
27
|
+
authorized = dispatch.dispatch_plan_item.hub_authorizations.where(store_id: source.store_id).sum(:quantity)
|
28
|
+
available = authorized - dispatched
|
24
29
|
|
25
|
-
errors.add(:quantity, "
|
30
|
+
errors.add(:quantity, "exceeds authorized quantity (Max = #{available}).") if quantity > available
|
26
31
|
end
|
27
32
|
|
28
33
|
def commit
|
@@ -33,12 +38,12 @@ module Cats
|
|
33
38
|
# Quantity validation should be skipped if we are commiting transactions.
|
34
39
|
(
|
35
40
|
instance_of?(Cats::Core::DispatchTransaction) &&
|
36
|
-
|
37
|
-
|
41
|
+
dispatch &&
|
42
|
+
status == COMMITTED
|
38
43
|
) || (
|
39
44
|
instance_of?(Cats::Core::ReceiptTransaction) &&
|
40
|
-
|
41
|
-
|
45
|
+
receipt &&
|
46
|
+
receipt.status == Cats::Core::Receipt::STACKING
|
42
47
|
)
|
43
48
|
end
|
44
49
|
|
@@ -1,7 +1,11 @@
|
|
1
1
|
module Cats
|
2
2
|
module Core
|
3
3
|
class CommodityCategorySerializer < ActiveModel::Serializer
|
4
|
-
attributes :id, :code, :name, :description, :parent_id
|
4
|
+
attributes :id, :code, :name, :description, :parent_id, :leaf
|
5
|
+
|
6
|
+
def leaf
|
7
|
+
!object.has_children?
|
8
|
+
end
|
5
9
|
end
|
6
10
|
end
|
7
11
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Cats
|
2
2
|
module Core
|
3
3
|
class DispatchTransactionSerializer < ActiveModel::Serializer
|
4
|
-
attributes :id, :source_id, :source_code, :
|
4
|
+
attributes :id, :source_id, :source_code, :dispatch_id, :dispatch_reference_no, :quantity,
|
5
5
|
:transaction_date, :status
|
6
6
|
end
|
7
7
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module Cats
|
2
2
|
module Core
|
3
3
|
class ReceiptTransactionSerializer < ActiveModel::Serializer
|
4
|
-
attributes :id, :
|
5
|
-
:status
|
4
|
+
attributes :id, :receipt_id, :dispatch_reference, :destination_id, :destination_code, :quantity,
|
5
|
+
:transaction_date, :status
|
6
6
|
|
7
7
|
def dispatch_reference
|
8
|
-
object.
|
8
|
+
object.receipt.dispatch.reference_no
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -1,47 +1,6 @@
|
|
1
1
|
module Cats
|
2
2
|
module Core
|
3
3
|
class DispatchService
|
4
|
-
def create_receipt_authorization(reference_no, plan_item, quantity, remark, user)
|
5
|
-
raise(StandardError, 'Dispatch plan is not an upstream plan.') unless plan_item.dispatch_plan.upstream?
|
6
|
-
|
7
|
-
transporter = Cats::Core::Transporter.find_by(code: 'SUP-TRANS')
|
8
|
-
raise(StandardError, 'Supplier transporter does not exist.') unless transporter
|
9
|
-
|
10
|
-
store = Cats::Core::Store.find_by(code: 'SUP-STORE')
|
11
|
-
raise(StandardError, 'Supplier store does not exist.') unless store
|
12
|
-
|
13
|
-
commodity = plan_item.dispatch_plan.commodity
|
14
|
-
stack = store.stacks.find_by(commodity: commodity)
|
15
|
-
|
16
|
-
raise(StandardError, 'Commodity not found in supplier store.') unless stack
|
17
|
-
|
18
|
-
dispatch = nil
|
19
|
-
ApplicationRecord.transaction do
|
20
|
-
dispatch = Cats::Core::Dispatch.create!(
|
21
|
-
reference_no: reference_no,
|
22
|
-
dispatch_plan_item: plan_item,
|
23
|
-
transporter: transporter,
|
24
|
-
plate_no: 'Supplier plate no',
|
25
|
-
driver_name: 'Supplier driver',
|
26
|
-
driver_phone: 'Supplier driver phone',
|
27
|
-
quantity: quantity,
|
28
|
-
remark: remark,
|
29
|
-
prepared_by: user,
|
30
|
-
dispatch_status: Cats::Core::Dispatch::DRAFT
|
31
|
-
)
|
32
|
-
|
33
|
-
# Create a dispatch transaction
|
34
|
-
Cats::Core::DispatchTransaction.create!(
|
35
|
-
source: stack,
|
36
|
-
destination: dispatch,
|
37
|
-
transaction_date: Date.today,
|
38
|
-
quantity: quantity,
|
39
|
-
status: Cats::Core::Transaction::DRAFT
|
40
|
-
)
|
41
|
-
end
|
42
|
-
dispatch
|
43
|
-
end
|
44
|
-
|
45
4
|
def search(user, status)
|
46
5
|
details = user.details
|
47
6
|
|
@@ -49,44 +8,20 @@ module Cats
|
|
49
8
|
raise(StandardError, 'User does not have associated location.')
|
50
9
|
end
|
51
10
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
)
|
67
|
-
elsif details['warehouse']
|
68
|
-
warehouse = Cats::Core::Location.find(details['warehouse'])
|
69
|
-
hub = warehouse.parent
|
70
|
-
dispatches = Cats::Core::Dispatch.joins(:dispatch_plan_item)
|
71
|
-
.where(
|
72
|
-
dispatch_plan_item: { destination: hub },
|
73
|
-
dispatch_status: status
|
74
|
-
).or(
|
75
|
-
Cats::Core::Dispatch.joins(:dispatch_plan_item)
|
76
|
-
.where(
|
77
|
-
dispatch_plan_item: { destination: warehouse },
|
78
|
-
dispatch_status: status
|
79
|
-
)
|
80
|
-
)
|
81
|
-
elsif details['hub']
|
82
|
-
hub = Cats::Core::Location.find(details['hub'])
|
83
|
-
dispatches = Cats::Core::Dispatch.joins(:dispatch_plan_item)
|
84
|
-
.where(
|
85
|
-
dispatch_plan_item: { destination: hub },
|
86
|
-
dispatch_status: status
|
87
|
-
)
|
88
|
-
end
|
89
|
-
dispatches
|
11
|
+
# Get user's hub
|
12
|
+
hub = if details['stores']
|
13
|
+
Cats::Core::Store.find(details['stores'][0]).warehouse.parent
|
14
|
+
elsif details['warehouse']
|
15
|
+
Cats::Core::Location.find(details['warehouse']).parent
|
16
|
+
else
|
17
|
+
Cats::Core::Location.find(details['hub'])
|
18
|
+
end
|
19
|
+
|
20
|
+
Cats::Core::Dispatch.joins(:dispatch_plan_item)
|
21
|
+
.where(
|
22
|
+
dispatch_plan_item: { destination: hub },
|
23
|
+
dispatch_status: status
|
24
|
+
)
|
90
25
|
end
|
91
26
|
|
92
27
|
def start(dispatch)
|
@@ -101,9 +36,11 @@ module Cats
|
|
101
36
|
|
102
37
|
users = Cats::Core::User.joins(:roles).where(cats_core_roles: { name: notification_rule.roles })
|
103
38
|
location_id = dispatch.dispatch_plan_item.destination_id
|
39
|
+
hub = Cats::Core::Location.find(location_id)
|
104
40
|
recipients = users.map do |user|
|
105
41
|
details = user.details
|
106
|
-
|
42
|
+
|
43
|
+
if (details.key?('warehouse') && hub.child_ids.include?(details['warehouse'])) ||
|
107
44
|
(details.key?('hub') && details['hub'] == location_id)
|
108
45
|
user
|
109
46
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Cats
|
2
|
+
module Core
|
3
|
+
class MonthlyPlanService
|
4
|
+
def generate_monthly_needs(plan_id)
|
5
|
+
plan = Cats::Core::MonthlyPlan.find(plan_id)
|
6
|
+
raise(StandardError, 'Plan has no rations.') if plan.monthly_rations.count.zero?
|
7
|
+
|
8
|
+
raise(StandardError, 'Plan has no plan items.') if plan.monthly_plan_items.count.zero?
|
9
|
+
|
10
|
+
plan.monthly_plan_item_details.delete_all if plan.monthly_plan_item_details.count.positive?
|
11
|
+
|
12
|
+
details = []
|
13
|
+
plan.monthly_plan_items.each do |plan_item|
|
14
|
+
plan.monthly_rations.each do |ration|
|
15
|
+
details << {
|
16
|
+
monthly_plan_item_id: plan_item.id,
|
17
|
+
monthly_ration_id: ration.id,
|
18
|
+
amount: (plan.no_of_days / ration.no_of_days * ration.amount) * plan_item.beneficiaries,
|
19
|
+
created_at: Date.today,
|
20
|
+
updated_at: Date.today
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
Cats::Core::MonthlyPlanItemDetail.insert_all!(details)
|
26
|
+
plan
|
27
|
+
end
|
28
|
+
|
29
|
+
def generate_monthly_plan(params)
|
30
|
+
region = Cats::Core::Location.find(params[:region_id])
|
31
|
+
plan = Cats::Core::Plan.includes(plan_items: :plan_item_details).find(params[:plan_id])
|
32
|
+
rations = Cats::Core::RationItem.where(ration_id: plan.ration_id)
|
33
|
+
monthly_plan = Cats::Core::MonthlyPlan.create!(
|
34
|
+
plan_id: plan.id,
|
35
|
+
reference_no: params[:reference_no],
|
36
|
+
region_id: params[:region_id],
|
37
|
+
status: Cats::Core::Plan::DRAFT,
|
38
|
+
month: params[:month],
|
39
|
+
no_of_days: params[:no_of_days]
|
40
|
+
)
|
41
|
+
ration_items = rations.map do |ration|
|
42
|
+
{
|
43
|
+
commodity_category_id: ration.commodity_category_id,
|
44
|
+
amount: ration.amount,
|
45
|
+
unit_of_measure_id: ration.unit_of_measure_id,
|
46
|
+
no_of_days: ration.no_of_days,
|
47
|
+
monthly_plan_id: monthly_plan.id,
|
48
|
+
created_at: Date.today,
|
49
|
+
updated_at: Date.today
|
50
|
+
}
|
51
|
+
end
|
52
|
+
Cats::Core::MonthlyRation.insert_all!(ration_items)
|
53
|
+
|
54
|
+
plan_items = plan.plan_items.where(woreda_id: region.descendant_ids).map do |plan_item|
|
55
|
+
{
|
56
|
+
monthly_plan_id: monthly_plan.id,
|
57
|
+
beneficiaries: plan_item.beneficiaries,
|
58
|
+
plan_item_id: plan_item.id,
|
59
|
+
created_at: Date.today,
|
60
|
+
updated_at: Date.today
|
61
|
+
}
|
62
|
+
end
|
63
|
+
Cats::Core::MonthlyPlanItem.insert_all!(plan_items)
|
64
|
+
monthly_plan
|
65
|
+
end
|
66
|
+
|
67
|
+
def remove_items(plan_id, ids)
|
68
|
+
raise(StandardError, 'No plan items specified.') if ids.count.zero?
|
69
|
+
|
70
|
+
begin
|
71
|
+
plan = Cats::Core::MonthlyPlan.find(plan_id)
|
72
|
+
rescue ActiveRecord::RecordNotFound
|
73
|
+
raise(StandardError, 'Monthly plan not found.') unless plan
|
74
|
+
end
|
75
|
+
|
76
|
+
plans = Cats::Core::MonthlyPlan.includes(:monthly_plan_items).where(monthly_plan_items: { id: ids })
|
77
|
+
raise(StandardError, 'Plan items should be from the same plan.') if plans.count > 1
|
78
|
+
|
79
|
+
raise(StandardError, 'Items are not from the given monthly plan.') unless plan_id == plans[0].id
|
80
|
+
|
81
|
+
Cats::Core::MonthlyPlanItem.delete_by(id: ids)
|
82
|
+
plan
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -16,9 +16,9 @@ module Cats
|
|
16
16
|
raise(StandardError, 'Receipt should be in stacking state.')
|
17
17
|
end
|
18
18
|
|
19
|
+
receipt.receipt_transactions.each(&:commit)
|
19
20
|
receipt.status = Cats::Core::Receipt::STACKED
|
20
21
|
receipt.save!
|
21
|
-
receipt.receipt_transactions.each(&:commit)
|
22
22
|
receipt
|
23
23
|
end
|
24
24
|
end
|
data/config/routes.rb
CHANGED
@@ -65,6 +65,12 @@ Cats::Core::Engine.routes.draw do
|
|
65
65
|
get 'children'
|
66
66
|
end
|
67
67
|
end
|
68
|
+
post '/commodities/filter', controller: :commodities, action: :filter
|
69
|
+
resources :commodities, except: %i[destroy] do
|
70
|
+
member do
|
71
|
+
post 'approve'
|
72
|
+
end
|
73
|
+
end
|
68
74
|
resources :currencies, except: %i[destroy]
|
69
75
|
resources :unit_of_measures, except: %i[destroy]
|
70
76
|
resources :transporters, except: %i[destroy]
|
@@ -83,16 +89,13 @@ Cats::Core::Engine.routes.draw do
|
|
83
89
|
resources :dispatch_plan_items, except: %i[index destroy]
|
84
90
|
|
85
91
|
get '/dispatch_plan_items/:id/dispatches', controller: :dispatches, action: :index, as: :dispatches_plan_item
|
86
|
-
post '/dispatch_plan_items/:id/receipt_authorizaton',
|
87
|
-
controller: :dispatches,
|
88
|
-
action: :create_receipt_authorization,
|
89
|
-
as: :receipt_authorization_plan_item
|
90
92
|
|
91
93
|
get '/dispatches/search', controller: :dispatches, action: :search, as: :search_dispatches
|
92
94
|
resources :dispatches, except: %i[index destroy] do
|
93
95
|
member do
|
94
96
|
get 'transactions', controller: :dispatch_transactions, action: :index
|
95
97
|
get 'receipts', controller: :receipts, action: :index
|
98
|
+
get 'lost', controller: :lost_commodities, action: :index
|
96
99
|
get 'commodity'
|
97
100
|
post 'approve'
|
98
101
|
post 'start'
|
@@ -108,4 +111,15 @@ Cats::Core::Engine.routes.draw do
|
|
108
111
|
end
|
109
112
|
end
|
110
113
|
resources :receipt_transactions, except: %i[index new edit destroy]
|
114
|
+
resources :lost_commodities, except: %i[index destroy]
|
115
|
+
get '/plans/:id/monthly_plans', controller: :monthly_plans, action: :index, as: :monthly_plans_plan
|
116
|
+
post '/monthly_plans/generate'
|
117
|
+
post '/monthly_plans/filter'
|
118
|
+
resources :monthly_plans, except: %i[index destroy] do
|
119
|
+
member do
|
120
|
+
post 'remove_items'
|
121
|
+
post 'generate_monthly_needs'
|
122
|
+
post 'approve'
|
123
|
+
end
|
124
|
+
end
|
111
125
|
end
|
@@ -13,7 +13,7 @@ class CreateCatsCoreDispatches < ActiveRecord::Migration[6.1]
|
|
13
13
|
t.string :plate_no, null: false
|
14
14
|
t.string :driver_name, null: false
|
15
15
|
t.string :driver_phone, null: false
|
16
|
-
t.float :quantity, null: false
|
16
|
+
t.float :quantity, null: false, default: 0
|
17
17
|
t.string :commodity_status, null: false, default: 'Good'
|
18
18
|
t.string :remark
|
19
19
|
t.references :prepared_by,
|
@@ -5,7 +5,7 @@ class CreateCatsCoreDispatchTransactions < ActiveRecord::Migration[6.1]
|
|
5
5
|
null: false,
|
6
6
|
index: { name: 'stack_on_dt_indx' },
|
7
7
|
foreign_key: { to_table: :cats_core_stacks }
|
8
|
-
t.references :
|
8
|
+
t.references :dispatch,
|
9
9
|
null: false,
|
10
10
|
index: { name: 'dispatch_on_dt_indx' },
|
11
11
|
foreign_key: { to_table: :cats_core_dispatches }
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateCatsCoreLostCommodities < ActiveRecord::Migration[7.0]
|
2
|
+
def change
|
3
|
+
create_table :cats_core_lost_commodities do |t|
|
4
|
+
t.references :dispatch,
|
5
|
+
null: false,
|
6
|
+
index: { name: 'lc_on_dispatch_indx' },
|
7
|
+
foreign_key: { to_table: :cats_core_dispatches }
|
8
|
+
t.float :quantity, null: false
|
9
|
+
t.string :commodity_status, null: false
|
10
|
+
t.string :remark
|
11
|
+
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class CreateCatsCoreReceiptTransactions < ActiveRecord::Migration[6.1]
|
2
2
|
def change
|
3
3
|
create_table :cats_core_receipt_transactions do |t|
|
4
|
-
t.references :
|
4
|
+
t.references :receipt,
|
5
5
|
null: false,
|
6
6
|
index: { name: 'receipt_on_rt_indx' },
|
7
7
|
foreign_key: { to_table: :cats_core_receipts }
|
data/lib/cats/core/version.rb
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
FactoryBot.define do
|
2
2
|
factory :dispatch_transaction, class: 'Cats::Core::DispatchTransaction' do
|
3
|
-
|
4
|
-
|
3
|
+
transient do
|
4
|
+
stack { create(:stack) }
|
5
|
+
end
|
6
|
+
source { stack }
|
7
|
+
dispatch do
|
8
|
+
plan_item = create(:dispatch_plan_item, quantity: 100)
|
9
|
+
plan_item.dispatch_plan.approve
|
10
|
+
create(:hub_authorization, dispatch_plan_item: plan_item, quantity: 100, store: stack.store)
|
11
|
+
create(:dispatch, dispatch_plan_item: plan_item, transaction?: false)
|
12
|
+
end
|
5
13
|
transaction_date { Date.today }
|
6
14
|
quantity { 10 }
|
7
15
|
status { Cats::Core::Transaction::DRAFT }
|
@@ -1,18 +1,26 @@
|
|
1
1
|
FactoryBot.define do
|
2
2
|
factory :dispatch, class: 'Cats::Core::Dispatch' do
|
3
|
+
transient do
|
4
|
+
stack { create(:stack, quantity: 100) }
|
5
|
+
transaction? { true }
|
6
|
+
end
|
3
7
|
reference_no { FFaker::Name.name }
|
4
8
|
dispatch_plan_item do
|
5
9
|
plan_item = create(:dispatch_plan_item, quantity: 100)
|
6
10
|
plan_item.dispatch_plan.approve
|
11
|
+
create(:hub_authorization, dispatch_plan_item: plan_item, quantity: 100, store: stack.store)
|
7
12
|
plan_item
|
8
13
|
end
|
9
14
|
transporter
|
10
15
|
plate_no { FFaker::Name.name }
|
11
16
|
driver_name { FFaker::Name.name }
|
12
17
|
driver_phone { FFaker::Name.name }
|
13
|
-
quantity { 50 }
|
14
18
|
remark { FFaker::Name.name }
|
15
19
|
prepared_by factory: :user
|
16
20
|
dispatch_status { Cats::Core::Dispatch::DRAFT }
|
21
|
+
|
22
|
+
after :create do |dispatch, options|
|
23
|
+
create(:dispatch_transaction, dispatch: dispatch, source: options.stack, quantity: 100) if options.transaction?
|
24
|
+
end
|
17
25
|
end
|
18
26
|
end
|
@@ -1,9 +1,29 @@
|
|
1
1
|
FactoryBot.define do
|
2
2
|
factory :receipt_transaction, class: 'Cats::Core::ReceiptTransaction' do
|
3
|
-
|
4
|
-
|
3
|
+
transient do
|
4
|
+
dispatch { create(:dispatch) }
|
5
|
+
end
|
6
|
+
transient do
|
7
|
+
stack { create(:stack) }
|
8
|
+
end
|
9
|
+
|
10
|
+
destination { stack }
|
11
|
+
receipt do
|
12
|
+
dispatch.approve
|
13
|
+
dispatch.start
|
14
|
+
receipt = create(:receipt, dispatch: dispatch)
|
15
|
+
dispatch.confirm
|
16
|
+
create(
|
17
|
+
:hub_authorization,
|
18
|
+
authorization_type: Cats::Core::HubAuthorization::DESTINATION,
|
19
|
+
dispatch_plan_item: dispatch.dispatch_plan_item,
|
20
|
+
store: stack.store,
|
21
|
+
quantity: 100
|
22
|
+
)
|
23
|
+
receipt
|
24
|
+
end
|
5
25
|
transaction_date { Date.today }
|
6
|
-
quantity {
|
26
|
+
quantity { 100 }
|
7
27
|
status { Cats::Core::Transaction::DRAFT }
|
8
28
|
end
|
9
29
|
end
|
@@ -2,12 +2,11 @@ FactoryBot.define do
|
|
2
2
|
factory :receipt, class: 'Cats::Core::Receipt' do
|
3
3
|
dispatch do
|
4
4
|
dispatch = create(:dispatch)
|
5
|
-
create(:dispatch_transaction, destination: dispatch, quantity: 50)
|
6
5
|
dispatch.approve
|
7
6
|
dispatch.start
|
8
7
|
dispatch
|
9
8
|
end
|
10
|
-
quantity {
|
9
|
+
quantity { 100 }
|
11
10
|
commodity_status { Cats::Core::Commodity::GOOD }
|
12
11
|
status { Cats::Core::Receipt::DRAFT }
|
13
12
|
remark { FFaker::Name.name }
|
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.3.
|
4
|
+
version: 1.3.38
|
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-
|
11
|
+
date: 2022-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_model_serializers
|
@@ -232,6 +232,7 @@ files:
|
|
232
232
|
- Rakefile
|
233
233
|
- app/controllers/cats/core/access_controller.rb
|
234
234
|
- app/controllers/cats/core/application_controller.rb
|
235
|
+
- app/controllers/cats/core/commodities_controller.rb
|
235
236
|
- app/controllers/cats/core/commodity_categories_controller.rb
|
236
237
|
- app/controllers/cats/core/currencies_controller.rb
|
237
238
|
- app/controllers/cats/core/dispatch_plan_items_controller.rb
|
@@ -239,7 +240,9 @@ files:
|
|
239
240
|
- app/controllers/cats/core/dispatch_transactions_controller.rb
|
240
241
|
- app/controllers/cats/core/dispatches_controller.rb
|
241
242
|
- app/controllers/cats/core/locations_controller.rb
|
243
|
+
- app/controllers/cats/core/lost_commodities_controller.rb
|
242
244
|
- app/controllers/cats/core/menus_controller.rb
|
245
|
+
- app/controllers/cats/core/monthly_plans_controller.rb
|
243
246
|
- app/controllers/cats/core/notifications_controller.rb
|
244
247
|
- app/controllers/cats/core/receipt_transactions_controller.rb
|
245
248
|
- app/controllers/cats/core/receipts_controller.rb
|
@@ -269,6 +272,7 @@ files:
|
|
269
272
|
- app/models/cats/core/gift_certificate.rb
|
270
273
|
- app/models/cats/core/hub_authorization.rb
|
271
274
|
- app/models/cats/core/location.rb
|
275
|
+
- app/models/cats/core/lost_commodity.rb
|
272
276
|
- app/models/cats/core/menu.rb
|
273
277
|
- app/models/cats/core/menu_item.rb
|
274
278
|
- app/models/cats/core/monthly_plan.rb
|
@@ -320,6 +324,8 @@ files:
|
|
320
324
|
- app/serializers/cats/core/dispatch_serializer.rb
|
321
325
|
- app/serializers/cats/core/dispatch_transaction_serializer.rb
|
322
326
|
- app/serializers/cats/core/location_serializer.rb
|
327
|
+
- app/serializers/cats/core/lost_commodity_serializer.rb
|
328
|
+
- app/serializers/cats/core/monthly_plan_serializer.rb
|
323
329
|
- app/serializers/cats/core/receipt_serializer.rb
|
324
330
|
- app/serializers/cats/core/receipt_transaction_serializer.rb
|
325
331
|
- app/serializers/cats/core/role_menu_serializer.rb
|
@@ -331,6 +337,7 @@ files:
|
|
331
337
|
- app/services/cats/core/dispatch_plan_service.rb
|
332
338
|
- app/services/cats/core/dispatch_service.rb
|
333
339
|
- app/services/cats/core/menu_service.rb
|
340
|
+
- app/services/cats/core/monthly_plan_service.rb
|
334
341
|
- app/services/cats/core/notification_service.rb
|
335
342
|
- app/services/cats/core/receipt_service.rb
|
336
343
|
- app/services/cats/core/space_service.rb
|
@@ -373,6 +380,7 @@ files:
|
|
373
380
|
- db/migrate/20210719133710_create_cats_core_stacking_rules.rb
|
374
381
|
- db/migrate/20210724074657_create_cats_core_notifications.rb
|
375
382
|
- db/migrate/20210727074646_create_cats_core_receipts.rb
|
383
|
+
- db/migrate/20210728041505_create_cats_core_lost_commodities.rb
|
376
384
|
- db/migrate/20210814160628_create_cats_core_receipt_transactions.rb
|
377
385
|
- db/migrate/20210814175406_create_cats_core_stack_transactions.rb
|
378
386
|
- db/migrate/20211002050739_create_cats_core_notification_rules.rb
|
@@ -415,6 +423,7 @@ files:
|
|
415
423
|
- spec/factories/cats/core/gift_certificates.rb
|
416
424
|
- spec/factories/cats/core/hub_authorizations.rb
|
417
425
|
- spec/factories/cats/core/locations.rb
|
426
|
+
- spec/factories/cats/core/lost_commodities.rb
|
418
427
|
- spec/factories/cats/core/menu_items.rb
|
419
428
|
- spec/factories/cats/core/menus.rb
|
420
429
|
- spec/factories/cats/core/monthly_plan_item_details.rb
|