cats_core 1.1.38 → 1.2.1

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: 05d36c2ff3f71d11f2d601ae469f69b4db03ae956e98e5ea6e7fc11e230ca918
4
- data.tar.gz: feb9cd6e23c14759ab5c7a423af1669d7d017de9eefa8e8cf602ca36b94ff0e7
3
+ metadata.gz: bdb1adee3b96e70550ebe13e6e0c8a5fb25003bf9f3e6921547ecc597aa12a53
4
+ data.tar.gz: c358a310a99dfff0bf57002f81ea5e4dfccbc6937ed064908a5693d234c77568
5
5
  SHA512:
6
- metadata.gz: d52633ea04e36f159602d53ec10d8e6664921238328e80bd85b6587dbbc5ecc1aade3f64a0cb7d8ae0ced07b9b4657f27be83d66906be5c79b1f66fce51ce359
7
- data.tar.gz: 833963237bc5fa5c84da07a7f2e691f47ac379df36ef0df434f4de308205109bc3dcc40b77a1da2433f260f3b6a104486eca9c01888364d7d73ff9a8d0afaa41
6
+ metadata.gz: afc8027a1addee047913baa073b8ac5cdac7a5e8d42b7c1a81f303e7d8b28c51948a478f02b240760513787d28a0f583e800e2f65a8abc7a6e0e64103661a1fb
7
+ data.tar.gz: 0bfb44fbd9f541ea33738cd1a4f5150040cc9d69d2c3afd40ea5b198cc19b3b8361851bcfb5e6ed412cc0afe74e67d372fcf2a914163fdf672dbea96f60b7dfb
@@ -20,7 +20,7 @@ module Cats
20
20
  jwt = Cats::Core::TokenAuthService.issue(payload)
21
21
  render json: { token: jwt, user: payload }
22
22
  else
23
- render json: { error: 'Invalid username or password.' }, status: 400
23
+ render json: { error: 'Invalid password.' }, status: 400
24
24
  end
25
25
  else
26
26
  render json: { error: 'User does not exist.' }, status: 400
@@ -1,43 +1,10 @@
1
1
  module Cats
2
2
  module Core
3
3
  class CurrenciesController < ApplicationController
4
- before_action :set_currency, only: %i[show update]
5
-
6
- def index
7
- data = ActiveModelSerializers::SerializableResource.new(Cats::Core::Currency.all)
8
- render json: { success: true, data: data }
9
- end
10
-
11
- def show
12
- data = ActiveModelSerializers::SerializableResource.new(@currency)
13
- render json: { success: true, data: data }
14
- end
15
-
16
- def create
17
- obj = Cats::Core::Currency.new(model_params)
18
- if obj.save
19
- data = ActiveModelSerializers::SerializableResource.new(obj)
20
- render json: { success: true, data: data }, status: :created
21
- else
22
- render json: { success: false, error: obj.errors.full_messages[0] }, status: :unprocessable_entity
23
- end
24
- end
25
-
26
- def update
27
- if @currency.update(model_params)
28
- data = ActiveModelSerializers::SerializableResource.new(@currency)
29
- render json: { success: true, data: data }
30
- else
31
- render json: { success: false, error: @currency.errors.full_messages[0] }, status: :unprocessable_entity
32
- end
33
- end
4
+ include Common
34
5
 
35
6
  private
36
7
 
37
- def set_currency
38
- @currency = Cats::Core::Currency.find(params[:id])
39
- end
40
-
41
8
  def model_params
42
9
  params.require(:payload).permit(:code, :name)
43
10
  end
@@ -57,7 +57,7 @@ module Cats
57
57
  def validate_commodity_status
58
58
  return unless commodity
59
59
 
60
- errors.add(:commodity, 'should be approved first.') unless commodity.approved
60
+ errors.add(:commodity, 'should be approved first.') unless commodity.status == Commodity::APPROVED
61
61
  end
62
62
 
63
63
  def approve
@@ -68,6 +68,10 @@ module Cats
68
68
 
69
69
  self.allocation_status = Allocation::APPROVED
70
70
  save!
71
+
72
+ # If the commodity is all allocated, then we should
73
+ # set its status to allocated.
74
+ commodity.allocate
71
75
  end
72
76
  end
73
77
  end
@@ -1,7 +1,11 @@
1
1
  module Cats
2
2
  module Core
3
3
  class Commodity < ApplicationRecord
4
- after_initialize :set_approved
4
+ # Statuses
5
+ DRAFT = 'Draft'.freeze
6
+ APPROVED = 'Approved'.freeze
7
+ ALLOCATED = 'Allocated'.freeze
8
+ STATUSES = [DRAFT, APPROVED, ALLOCATED].freeze
5
9
 
6
10
  # Commodity statuses
7
11
  GOOD = 'Good'.freeze
@@ -17,23 +21,67 @@ module Cats
17
21
  belongs_to :unit_of_measure
18
22
  belongs_to :source, polymorphic: true
19
23
 
24
+ has_many :allocations
25
+
20
26
  validates :best_use_before, presence: true
21
27
  validates :batch_no, presence: true, uniqueness: true
22
28
  validates :quantity, presence: true, numericality: { greater_than: 0 }
23
29
  validates :volume_per_metric_ton, numericality: { greater_than: 0, allow_nil: true }
24
30
  validates :arrival_status, presence: true, inclusion: { in: ARRIVAL_STATUSES }
31
+ validates :status, presence: true, inclusion: { in: STATUSES }
25
32
 
26
33
  delegate(:abbreviation, to: :unit_of_measure, prefix: true)
27
34
  delegate(:reference_no, to: :source, prefix: true)
28
35
 
29
- def set_approved
30
- return unless new_record?
36
+ def name
37
+ source.commodity_category.name
38
+ end
39
+
40
+ def approve
41
+ raise(StandardError, 'Commodity already approved.') if status == APPROVED
42
+
43
+ result = false
44
+ Cats::Core::Commodity.transaction do
45
+ self.status = APPROVED
46
+ save!
47
+ store = Cats::Core::Store.find_by(code: 'SUP-STORE')
48
+ raise(StandardError, 'Supplier store does not exist.') unless store
31
49
 
32
- self.approved = false
50
+ stack = Cats::Core::Stack.create!(
51
+ code: batch_no,
52
+ store: store,
53
+ commodity: self,
54
+ quantity: quantity,
55
+ commodity_status: GOOD,
56
+ stack_status: Stack::ALLOCATED,
57
+ length: 100,
58
+ width: 100,
59
+ height: 10,
60
+ start_x: 1,
61
+ start_y: 1
62
+ )
63
+ result = stack.id.positive?
64
+ end
65
+ result
33
66
  end
34
67
 
35
- def name
36
- source.commodity_category.name
68
+ def allocate(ignore_errors: true)
69
+ statuses = Allocation.where(commodity_id: id).map(&:allocation_status).uniq
70
+ unless statuses.count == 1 && statuses[0] == APPROVED
71
+ return if ignore_errors
72
+
73
+ raise(StandardError, 'There are allocations in "Draft" state.')
74
+ end
75
+
76
+ quantity = allocations.sum(:quantity)
77
+ unless quantity == self.quantity
78
+ return if ignore_errors
79
+
80
+ raise(StandardError, 'Total allocations quantity is not the same as commodity quantity.')
81
+ end
82
+
83
+ self.status = ALLOCATED
84
+ save!
37
85
  end
38
86
  end
39
87
  end
@@ -6,6 +6,15 @@ module Cats
6
6
 
7
7
  delegate(:code, to: :source, prefix: true)
8
8
  delegate(:reference_no, to: :destination, prefix: true)
9
+
10
+ def commit
11
+ Transaction.transaction do
12
+ source.quantity -= quantity
13
+ source.save!
14
+ self.status = COMMITTED
15
+ save!
16
+ end
17
+ end
9
18
  end
10
19
  end
11
20
  end
@@ -10,7 +10,7 @@ module Cats
10
10
  ReceiptTransaction.transaction do
11
11
  destination.quantity += quantity
12
12
  destination.stack_status = Cats::Core::Stack::ALLOCATED
13
- destination.save
13
+ destination.save!
14
14
  self.status = COMMITTED
15
15
  save!
16
16
  end
@@ -18,7 +18,7 @@ module Cats
18
18
  def validate_commodity_status
19
19
  return unless commodity
20
20
 
21
- errors.add(:commodity, 'should be approved first.') unless commodity.approved
21
+ errors.add(:commodity, 'should be approved first.') unless commodity.status == Commodity::APPROVED
22
22
  end
23
23
 
24
24
  def validate_quantity
@@ -22,6 +22,8 @@ module Cats
22
22
  validate :validate_coordinates, :validate_dimensions, :validate_distance_from_wall, :validate_overlap,
23
23
  :validate_space_between_stack, unless: -> { store && store.code == 'SUP-STORE' }
24
24
 
25
+ delegate :batch_no, to: :commodity, prefix: true
26
+
25
27
  after_save :update_store_space
26
28
 
27
29
  def validate_coordinates
@@ -58,8 +60,8 @@ module Cats
58
60
  return unless store.present? && length.present? && width.present? && start_x.present? && start_y.present?
59
61
 
60
62
  rule = stacking_rules
61
- if start_x < rule.distance_from_wall || store.length - (start_y + length) < rule.distance_from_wall ||
62
- store.width - (start_x + width) < rule.distance_from_wall || start_y < rule.distance_from_wall
63
+ if start_x < rule.distance_from_wall || store.length - (start_x + length) < rule.distance_from_wall ||
64
+ store.width - (start_y + width) < rule.distance_from_wall || start_y < rule.distance_from_wall
63
65
  errors.add(:base,
64
66
  message: "The stack must be placed #{rule.distance_from_wall} meter away from a store wall")
65
67
  end
@@ -17,23 +17,16 @@ module Cats
17
17
  def validate_quantity
18
18
  return unless quantity.present? && source.present?
19
19
 
20
- total = self.class.where(source: source).sum(:quantity)
20
+ dispatched = self.class.where(source: source, status: DRAFT).sum(:quantity)
21
21
 
22
- total -= quantity_was if id
22
+ available = source.quantity - dispatched
23
+ available += quantity_was if quantity_was
23
24
 
24
- diff = source.quantity - total
25
- errors.add(:quantity, "total is higher than source quantity (Max = #{diff}).") if quantity > diff
25
+ errors.add(:quantity, "total is higher than source quantity (Max = #{available}).") if quantity > available
26
26
  end
27
27
 
28
28
  def commit
29
- Transaction.transaction do
30
- source.quantity -= quantity
31
- destination.quantity += quantity
32
- source.save
33
- destination.save
34
- self.status = COMMITTED
35
- save!
36
- end
29
+ raise(NotImplementedError, 'Method should be implemented in child classes.')
37
30
  end
38
31
 
39
32
  def skip_quantity_validation
@@ -3,7 +3,7 @@ module Cats
3
3
  class CommoditySerializer < ActiveModel::Serializer
4
4
  attributes :id, :name, :batch_no, :description, :unit_of_measure_id, :unit_of_measure_abbreviation, :source_id,
5
5
  :source_type, :source_reference_no, :quantity, :best_use_before, :volume_per_metric_ton,
6
- :arrival_status, :approved
6
+ :arrival_status, :status
7
7
  end
8
8
  end
9
9
  end
@@ -17,6 +17,7 @@ module Cats
17
17
  end
18
18
 
19
19
  receipt.status = Cats::Core::Receipt::STACKED
20
+ receipt.save!
20
21
  receipt.receipt_transactions.each(&:commit)
21
22
  receipt
22
23
  end
@@ -0,0 +1,6 @@
1
+ class AddStatusToCatsCoreCommodities < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :cats_core_commodities, :status, :string, null: false, default: 'Draft'
4
+ remove_column :cats_core_commodities, :approved, :boolean
5
+ end
6
+ end
@@ -1,5 +1,5 @@
1
1
  module Cats
2
2
  module Core
3
- VERSION = '1.1.38'.freeze
3
+ VERSION = '1.2.1'.freeze
4
4
  end
5
5
  end
@@ -2,7 +2,11 @@ FactoryBot.define do
2
2
  factory :allocation, class: 'Cats::Core::Allocation' do
3
3
  reference_no { FFaker::Name.name }
4
4
  rhn_request { nil }
5
- commodity
5
+ commodity do
6
+ c = create(:commodity)
7
+ c.approve
8
+ c
9
+ end
6
10
  source factory: :location
7
11
  quantity { 50 }
8
12
  commodity_status { Cats::Core::Commodity::GOOD }
@@ -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 { true }
11
+ status { Cats::Core::Commodity::DRAFT }
12
12
  end
13
13
  end
@@ -1,7 +1,11 @@
1
1
  FactoryBot.define do
2
2
  factory :rhn_request, class: 'Cats::Core::RhnRequest' do
3
3
  reference_no { FFaker::Name.name }
4
- commodity
4
+ commodity do
5
+ c = create(:commodity)
6
+ c.approve
7
+ c
8
+ end
5
9
  quantity { 100 }
6
10
  request_date { Date.today }
7
11
  requested_by { 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.1.38
4
+ version: 1.2.1
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-25 00:00:00.000000000 Z
11
+ date: 2021-11-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_model_serializers
@@ -346,6 +346,7 @@ files:
346
346
  - db/migrate/20210814175406_create_cats_core_stack_transactions.rb
347
347
  - db/migrate/20211002050739_create_cats_core_notification_rules.rb
348
348
  - db/migrate/20211024063240_add_status_to_cats_core_rhn_requests.rb
349
+ - db/migrate/20211030133752_add_status_to_cats_core_commodities.rb
349
350
  - lib/cats/core.rb
350
351
  - lib/cats/core/engine.rb
351
352
  - lib/cats/core/version.rb