comee_core 0.1.31 → 0.1.32
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/comee/core/client_prices_controller.rb +2 -1
- data/app/models/comee/core/client_price.rb +12 -14
- data/app/models/comee/core/master_price.rb +51 -17
- data/app/models/comee/core/price.rb +38 -0
- data/app/serializers/comee/core/client_price_serializer.rb +4 -1
- data/app/utils/comee/core/period.rb +18 -0
- data/db/migrate/20230813235946_create_comee_core_master_prices.rb +11 -8
- data/db/migrate/20230814151601_create_comee_core_client_prices.rb +4 -0
- data/lib/comee/core/version.rb +1 -1
- data/spec/factories/comee/core/client_prices.rb +1 -0
- data/spec/factories/comee/core/master_prices.rb +14 -6
- data/spec/factories/comee/core/products.rb +1 -1
- data/spec/factories/comee/core/suppliers.rb +1 -1
- data/spec/factories/comee/core/units.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a9b8f42b3900f864a1225399177186948e42ae9e67c48fe9b3248eb45675ad71
|
4
|
+
data.tar.gz: c487c5e62ef7c83ba1442773f7a19dae1a32fb40fe966e41bcce7b21c7eb80ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a7079cd5b10f8b9cf68fd7ba3c764f875fd09fc827b1f67b006f91dc52b78bee029616a335664becb6f30c1b9305cf9660fafcf5e3dc493b59175f666034b539
|
7
|
+
data.tar.gz: 48ab1f0e3bb54c08830e73f3ce76e472f85afe5f2683d967b8c726197083b7c9a3856faedcdca5ed65edf9fa98dade94b5e78ee355e003811b1062bac5f736c4
|
@@ -18,7 +18,8 @@ module Comee
|
|
18
18
|
private
|
19
19
|
|
20
20
|
def model_params
|
21
|
-
params.require(:payload).permit(:valid_from, :valid_to, :price, :status, :product_id, :discount, :client_id, :previous_price
|
21
|
+
params.require(:payload).permit(:valid_from, :valid_to, :price, :status, :product_id, :discount, :client_id, :previous_price,
|
22
|
+
:unit_id)
|
22
23
|
end
|
23
24
|
end
|
24
25
|
end
|
@@ -1,30 +1,28 @@
|
|
1
1
|
module Comee
|
2
2
|
module Core
|
3
|
-
class ClientPrice <
|
4
|
-
enum :status, {old: 0, current: 1, future: 2}
|
5
|
-
belongs_to :product
|
3
|
+
class ClientPrice < Price
|
6
4
|
belongs_to :client
|
7
5
|
belongs_to :previous_price, class_name: "Comee::Core::ClientPrice", optional: true
|
8
6
|
|
9
|
-
validates :
|
7
|
+
validates :price, presence: true
|
10
8
|
validates :price, numericality: {greater_than: 0}
|
11
9
|
validates :discount, presence: true, numericality: {greater_than_or_equal_to: 0, less_than_or_equal_to: 100}
|
12
10
|
validates :product_id, uniqueness: {scope: %i[client_id previous_price_id]}
|
13
|
-
validate :validate_price_validity_dates
|
14
|
-
|
15
|
-
def validate_price_validity_dates
|
16
|
-
return unless valid_from && valid_to
|
17
|
-
|
18
|
-
period = Period.new(valid_from, valid_to)
|
19
|
-
errors.add(:base, "Price validity date range is not correct.") unless period.valid?
|
20
|
-
end
|
21
11
|
|
22
12
|
def self.ransackable_attributes(_auth_object = nil)
|
23
|
-
%w[
|
13
|
+
%w[
|
14
|
+
valid_from
|
15
|
+
valid_to
|
16
|
+
price
|
17
|
+
status
|
18
|
+
product_id
|
19
|
+
client_id
|
20
|
+
previous_price_id
|
21
|
+
]
|
24
22
|
end
|
25
23
|
|
26
24
|
def self.ransackable_associations(_auth_object = nil)
|
27
|
-
[]
|
25
|
+
%w[product client]
|
28
26
|
end
|
29
27
|
end
|
30
28
|
end
|
@@ -1,38 +1,72 @@
|
|
1
1
|
module Comee
|
2
2
|
module Core
|
3
|
-
class MasterPrice <
|
4
|
-
enum :status, {old: 0, current: 1, future: 2}
|
3
|
+
class MasterPrice < Price
|
5
4
|
belongs_to :supplier
|
6
|
-
belongs_to :product
|
7
5
|
belongs_to :previous_price, class_name: "Comee::Core::MasterPrice", optional: true
|
8
6
|
|
9
|
-
validates :purchase_price, :
|
7
|
+
validates :purchase_price, :selling_price, presence: true
|
10
8
|
validates :margin, presence: true, numericality: {greater_than_or_equal_to: 0, less_than_or_equal_to: 100}
|
11
9
|
validates :product_id, uniqueness: {scope: %i[supplier_id previous_price_id]}
|
12
|
-
validate :validate_primary_price
|
10
|
+
validate :validate_primary_price
|
11
|
+
|
12
|
+
scope :unapplied, -> { where(propagated_to_client: false).current_primary }
|
13
13
|
|
14
14
|
def validate_primary_price
|
15
15
|
return unless product && primary
|
16
16
|
|
17
|
-
count = MasterPrice.where(product: product, primary: true, status:
|
17
|
+
count = MasterPrice.where(product: product, primary: true, status: Price.statuses[:current]).count
|
18
18
|
return unless count.positive? && primary && MasterPrice.statuses[status] == MasterPrice.statuses[:current]
|
19
19
|
|
20
|
-
errors.add(:base,
|
21
|
-
"There is already a primary supplier for item '#{product.code}'")
|
20
|
+
errors.add(:base, "There is already a primary price entry for item '#{product.code}'")
|
22
21
|
end
|
23
22
|
|
24
|
-
def
|
25
|
-
|
23
|
+
# def update_price(new_price, from, to, margin = nil)
|
24
|
+
# raise(StandardError, "Future prices cannot be updated.") if Price.statuses[status] == Price.statuses[:future]
|
26
25
|
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
# margin ||= self.margin
|
27
|
+
# raise(StandardError, "No changes detected. Update failed!") if purchase_price == new_price && self.margin == margin
|
28
|
+
|
29
|
+
# period = Period.new(from, to)
|
30
|
+
# raise(StandardError, "Validity date range is not correct.") unless period.valid?
|
31
|
+
|
32
|
+
# old_period = Period.new(valid_from, valid_to)
|
33
|
+
# new_period = Period.compute_next_valid_period(old_period, period)
|
34
|
+
# raise(StandardError, "No valid validity period could be computed for the given validity date range.") unless new_period
|
30
35
|
|
31
|
-
|
32
|
-
|
36
|
+
# price = dup
|
37
|
+
# price.assign_attributes(
|
38
|
+
# purchase_price: new_price,
|
39
|
+
# valid_from: new_period.start,
|
40
|
+
# valid_to: new_period.finish,
|
41
|
+
# margin: margin,
|
42
|
+
# previous_price: self,
|
43
|
+
# selling_price: (new_price * (1 + margin / 100.0)).round(2)
|
44
|
+
# )
|
45
|
+
|
46
|
+
# ActiveRecord::Base.transaction do
|
47
|
+
# price.previous_price.save!
|
48
|
+
# price.save!
|
49
|
+
# end
|
50
|
+
# price
|
51
|
+
# rescue StandardError
|
52
|
+
# raise
|
53
|
+
# end
|
54
|
+
|
55
|
+
def self.ransackable_attributes(_auth_object = nil)
|
56
|
+
%w[
|
57
|
+
valid_from
|
58
|
+
valid_to
|
59
|
+
purchase_price
|
60
|
+
selling_price
|
61
|
+
status
|
62
|
+
product_id
|
63
|
+
supplier_id
|
64
|
+
previous_price_id
|
65
|
+
]
|
66
|
+
end
|
33
67
|
|
34
|
-
|
35
|
-
|
68
|
+
def self.ransackable_associations(_auth_object = nil)
|
69
|
+
%w[product supplier]
|
36
70
|
end
|
37
71
|
end
|
38
72
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Comee
|
2
|
+
module Core
|
3
|
+
class Price < ApplicationRecord
|
4
|
+
self.abstract_class = true
|
5
|
+
before_save :compute_status
|
6
|
+
|
7
|
+
enum :status, {old: 0, current: 1, future: 2}
|
8
|
+
|
9
|
+
scope :current, -> { where(status: Price.statuses[:current]) }
|
10
|
+
scope :future, -> { where(status: Price.statuses[:future]) }
|
11
|
+
scope :current_primary, -> { where(primary: true).current }
|
12
|
+
|
13
|
+
belongs_to :product
|
14
|
+
belongs_to :unit
|
15
|
+
|
16
|
+
validates :valid_from, :valid_to, presence: true
|
17
|
+
validate :validate_price_validity_dates
|
18
|
+
|
19
|
+
def validate_price_validity_dates
|
20
|
+
return unless valid_from && valid_to
|
21
|
+
|
22
|
+
period = Period.new(valid_from, valid_to)
|
23
|
+
errors.add(:base, "Price validity date range is not correct.") unless period.valid?
|
24
|
+
end
|
25
|
+
|
26
|
+
def compute_status
|
27
|
+
period = Period.new(valid_from, valid_to)
|
28
|
+
if period.old?
|
29
|
+
self.status = Price.statuses[:old]
|
30
|
+
elsif period.current?
|
31
|
+
self.status = Price.statuses[:current]
|
32
|
+
elsif period.future?
|
33
|
+
self.status = Price.statuses[:future]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,7 +1,10 @@
|
|
1
1
|
module Comee
|
2
2
|
module Core
|
3
3
|
class ClientPriceSerializer < ActiveModel::Serializer
|
4
|
-
attributes :id, :valid_from, :valid_to, :price, :status, :
|
4
|
+
attributes :id, :valid_from, :valid_to, :price, :status, :previous_price
|
5
|
+
belongs_to :product
|
6
|
+
belongs_to :client
|
7
|
+
belongs_to :unit
|
5
8
|
end
|
6
9
|
end
|
7
10
|
end
|
@@ -24,6 +24,24 @@ module Comee
|
|
24
24
|
finish > start
|
25
25
|
end
|
26
26
|
|
27
|
+
def current?
|
28
|
+
raise(StandardError, "Period must be valid.") unless valid?
|
29
|
+
|
30
|
+
start <= Date.current && finish > Date.current
|
31
|
+
end
|
32
|
+
|
33
|
+
def old?
|
34
|
+
raise(StandardError, "Period must be valid.") unless valid?
|
35
|
+
|
36
|
+
finish < Date.current
|
37
|
+
end
|
38
|
+
|
39
|
+
def future?
|
40
|
+
raise(StandardError, "Period must be valid.") unless valid?
|
41
|
+
|
42
|
+
start > Date.current
|
43
|
+
end
|
44
|
+
|
27
45
|
def contains?(period)
|
28
46
|
return true if start <= period.start && finish >= period.finish
|
29
47
|
|
@@ -3,29 +3,32 @@ class CreateComeeCoreMasterPrices < ActiveRecord::Migration[7.0]
|
|
3
3
|
create_table :comee_core_master_prices do |t|
|
4
4
|
t.float :purchase_price, null: false
|
5
5
|
t.float :selling_price, null: false
|
6
|
-
t.date :
|
7
|
-
t.date :
|
8
|
-
t.date :sp_valid_from, null: false
|
6
|
+
t.date :valid_from, null: false
|
7
|
+
t.date :valid_to, null: false
|
9
8
|
t.float :status, null: false, default: 0
|
10
|
-
t.
|
11
|
-
t.boolean :active, null: false
|
12
|
-
t.boolean :primary, null: false
|
9
|
+
t.boolean :primary, null: false, default: false
|
13
10
|
t.integer :margin, null: false
|
14
11
|
t.references :product,
|
15
12
|
null: false,
|
16
|
-
index: {name: "
|
13
|
+
index: {name: "product_on_ccmp_indx"},
|
17
14
|
foreign_key: {to_table: :comee_core_products}
|
18
15
|
t.references :supplier,
|
19
16
|
null: false,
|
20
|
-
index: {name: "
|
17
|
+
index: {name: "supplier_on_ccmp_indx"},
|
21
18
|
foreign_key: {to_table: :comee_core_suppliers}
|
19
|
+
t.references :unit,
|
20
|
+
null: false,
|
21
|
+
index: {name: "unit_on_ccmp_indx"},
|
22
|
+
foreign_key: {to_table: :comee_core_units}
|
22
23
|
t.references :previous_price,
|
23
24
|
null: true,
|
24
25
|
index: {name: "previous_price_on_ccsp_indx"},
|
25
26
|
foreign_key: {to_table: :comee_core_master_prices}
|
27
|
+
t.boolean :propagated_to_client, null: false, default: false
|
26
28
|
|
27
29
|
t.timestamps
|
28
30
|
end
|
31
|
+
|
29
32
|
add_index :comee_core_master_prices,
|
30
33
|
%i[product_id supplier_id previous_price_id],
|
31
34
|
unique: true,
|
@@ -14,6 +14,10 @@ class CreateComeeCoreClientPrices < ActiveRecord::Migration[7.0]
|
|
14
14
|
null: false,
|
15
15
|
index: {name: "client_on_cccp_indx"},
|
16
16
|
foreign_key: {to_table: :comee_core_clients}
|
17
|
+
t.references :unit,
|
18
|
+
null: false,
|
19
|
+
index: {name: "unit_on_cccp_indx"},
|
20
|
+
foreign_key: {to_table: :comee_core_units}
|
17
21
|
t.references :previous_price,
|
18
22
|
null: true,
|
19
23
|
index: {name: "previous_price_on_cccp_indx"},
|
data/lib/comee/core/version.rb
CHANGED
@@ -2,16 +2,24 @@ FactoryBot.define do
|
|
2
2
|
factory :master_price, class: "Comee::Core::MasterPrice" do
|
3
3
|
purchase_price { 100.0 }
|
4
4
|
selling_price { 90.0 }
|
5
|
-
|
6
|
-
|
7
|
-
sp_valid_from { Date.current.advance(months: -1) }
|
8
|
-
sp_valid_to { Date.current.advance(months: 1) }
|
9
|
-
active { true }
|
5
|
+
valid_from { Date.current.advance(months: -1) }
|
6
|
+
valid_to { Date.current.advance(months: 1) }
|
10
7
|
primary { false }
|
11
8
|
margin { 10.0 }
|
12
9
|
product
|
13
10
|
supplier
|
11
|
+
unit
|
14
12
|
previous_price { nil }
|
15
|
-
|
13
|
+
propagated_to_client { false }
|
14
|
+
|
15
|
+
trait :old do
|
16
|
+
valid_from { Date.current.advance(months: -2) }
|
17
|
+
valid_to { Date.current.advance(months: -1) }
|
18
|
+
end
|
19
|
+
|
20
|
+
trait :future do
|
21
|
+
valid_from { Date.current.advance(months: 1) }
|
22
|
+
valid_to { Date.current.advance(months: 2) }
|
23
|
+
end
|
16
24
|
end
|
17
25
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
FactoryBot.define do
|
2
2
|
factory :product, class: "Comee::Core::Product" do
|
3
|
-
code { Faker::Alphanumeric.alpha(number: 6) }
|
3
|
+
sequence(:code) { |n| "#{Faker::Alphanumeric.unique.alpha(number: 6)}-#{n}" }
|
4
4
|
name { Faker::Name.name }
|
5
5
|
description { Faker::Lorem.sentence }
|
6
6
|
metadata { {} }
|
@@ -1,6 +1,6 @@
|
|
1
1
|
FactoryBot.define do
|
2
2
|
factory :supplier, class: "Comee::Core::Supplier" do
|
3
|
-
code { Faker::Alphanumeric.alpha(number: 8) }
|
3
|
+
sequence(:code) { |n| "#{Faker::Alphanumeric.alpha(number: 8)}-#{n}" }
|
4
4
|
name { Faker::Name.name }
|
5
5
|
address { Faker::Address.full_address }
|
6
6
|
locale { "en" }
|
@@ -1,6 +1,6 @@
|
|
1
1
|
FactoryBot.define do
|
2
2
|
factory :unit, class: "Comee::Core::Unit" do
|
3
|
-
code { Faker::Alphanumeric.alpha(number: 2) }
|
3
|
+
sequence(:code) { |n| "#{Faker::Alphanumeric.alpha(number: 2)}-#{n}" }
|
4
4
|
name { Faker::Name.name }
|
5
5
|
unit_type { Comee::Core::Unit.unit_types[:weight] }
|
6
6
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: comee_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.32
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henock L.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-11-
|
11
|
+
date: 2023-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_model_serializers
|
@@ -276,6 +276,7 @@ files:
|
|
276
276
|
- app/models/comee/core/master_price.rb
|
277
277
|
- app/models/comee/core/notification.rb
|
278
278
|
- app/models/comee/core/order_source.rb
|
279
|
+
- app/models/comee/core/price.rb
|
279
280
|
- app/models/comee/core/product.rb
|
280
281
|
- app/models/comee/core/product_lookup.rb
|
281
282
|
- app/models/comee/core/product_type.rb
|