comee_core 0.1.45 → 0.1.46

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 75ec5f13994e93da5d3763590ea59e605abcea49c688f4c904af3be6f7f7387a
4
- data.tar.gz: ec537070f9cf37ebd7e261abfb49f8c4c847e6ae4ea91604554de2d51c5cce17
3
+ metadata.gz: b627b9c57084edd4b480f661502a765f0988cfca86b25c42691b19d650d5dc5b
4
+ data.tar.gz: 9f3f4164affa01dc56b3d2f13b8ec9ac2efca5e0a99d58d935bc33360baacfa5
5
5
  SHA512:
6
- metadata.gz: 873f33e015d319b8194a8d22f16629140dbf604d2f481a078aa38ec5a7f6099f206e35036b9f2c5ef83764d6f0bbb8b2f52f0d0cd84375fc2b234e2ac1af65f6
7
- data.tar.gz: 8ccf84bde86a909f24505431d980b3f4c5532d0d2eb0850685069611199f1aca0aa44e015d659df13606f2b2e16848573ce4f95a56f1bc83fd2ade6717be1643
6
+ metadata.gz: 43c210add4f2c3d2f87535b251ba52e22d0b477439dde17116b95e2c5f12133e800c09cd628967497b5d42a20970ffc753ebb0826ff6361838d15406df601e82
7
+ data.tar.gz: d1a70bed42a7c03cf4473cda58ad8776566c696713ded246742e044ce8b2aeb27f76b37d7a23e509628bcb9b4d0e522bcc5828d18ad4ad1e22c32148fe40af13
@@ -20,7 +20,7 @@ module Comee
20
20
  private
21
21
 
22
22
  def model_params
23
- params.required(:payload).permit(:code, :name, :description, :parent_id, :thumbnail_image, images: [])
23
+ params.required(:payload).permit(:code, :name, :description, :parent_id, :thumbnail_image, :preferred_units, images: [])
24
24
  end
25
25
  end
26
26
  end
@@ -9,6 +9,12 @@ module Comee
9
9
  end
10
10
  end
11
11
 
12
+ def suggest_values
13
+ service = CustomerOrderService.new
14
+ result = service.suggest_values(params[:id], params[:unit_id])
15
+ render json: {success: true, data: result}
16
+ end
17
+
12
18
  def destroy
13
19
  Comee::Core::SalesOrderItem.destroy(params[:id])
14
20
  render json: {success: true}
@@ -0,0 +1,19 @@
1
+ module Comee
2
+ module Core
3
+ class UnitConversionsController < ApplicationController
4
+ include Common
5
+
6
+ def index
7
+ super do
8
+ Comee::Core::UnitConversion.includes(:from, :to).all
9
+ end
10
+ end
11
+
12
+ private
13
+
14
+ def model_params
15
+ params.require(:payload).permit(:from_id, :to_id, :factor)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -25,6 +25,10 @@ module Comee
25
25
  def images_url
26
26
  images.attached? ? images.map { |image| Rails.application.routes.url_helpers.rails_blob_url(image, only_path: false) } : []
27
27
  end
28
+
29
+ def default_unit
30
+ preferred_units.find { |unit| unit["default"] }
31
+ end
28
32
  end
29
33
  end
30
34
  end
@@ -0,0 +1,10 @@
1
+ module Comee
2
+ module Core
3
+ class UnitConversion < ApplicationRecord
4
+ belongs_to :from, class_name: "Comee::Core::Unit"
5
+ belongs_to :to, class_name: "Comee::Core::Unit"
6
+
7
+ validates :factor, presence: true, numericality: {greater_than: 0}
8
+ end
9
+ end
10
+ end
@@ -1,7 +1,7 @@
1
1
  module Comee
2
2
  module Core
3
3
  class ProductSerializer < ActiveModel::Serializer
4
- attributes :id, :code, :name, :description, :thumbnail_image_url, :images_url
4
+ attributes :id, :code, :name, :description, :thumbnail_image_url, :images_url, :preferred_units
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,9 @@
1
+ module Comee
2
+ module Core
3
+ class UnitConversionSerializer < ActiveModel::Serializer
4
+ attributes :id, :factor
5
+ belongs_to :from
6
+ belongs_to :to
7
+ end
8
+ end
9
+ end
@@ -1,6 +1,76 @@
1
1
  module Comee
2
2
  module Core
3
3
  class CustomerOrderService
4
+ ##
5
+ # This method converts a price value per a unit of measure to a price value per another
6
+ # unit of measure.
7
+ #
8
+ # @param price [Numeric] the price value
9
+ # @param unit [Numeric] the unit id of measure for the price
10
+ # @param new_unit [Numeric] the new unit id of measure
11
+ #
12
+ # @return [Numeric] the converted price for the new unit
13
+ #
14
+ def convert_price(price, unit_id, new_unit_id)
15
+ return price if unit_id == new_unit_id
16
+
17
+ conversions = UnitConversion.where("from_id = ? AND to_id = ?", unit_id, new_unit_id)
18
+ .or(UnitConversion.where("from_id = ? AND to_id = ?", new_unit_id, unit_id))
19
+ unless conversions.count.positive?
20
+ units = Unit.where(id: [unit_id, new_unit_id]).select(:code)
21
+ raise(StandardError, "There is no conversion factor between #{units[0].code} and #{units[1].code}.")
22
+ end
23
+
24
+ conversion = conversions.first
25
+ return (price / conversion.factor).round(2) if unit_id == conversion.from_id && new_unit_id == conversion.to_id
26
+
27
+ (price * conversion.factor).round(2)
28
+ end
29
+
30
+ ##
31
+ # This method converts a price value per a unit of measure to a price value per another
32
+ # unit of measure.
33
+ #
34
+ # @param quantity [Numeric] the price value
35
+ # @param unit_id [Numeric] the unit id of measure for the price
36
+ # @param new_unit_id [Numeric] the new unit id of measure
37
+ #
38
+ # @return [Numeric] the converted price for the new unit
39
+ #
40
+ def convert_quantity(quantity, unit_id, new_unit_id)
41
+ return quantity if unit_id == new_unit_id
42
+
43
+ conversions = UnitConversion.where("from_id = ? AND to_id = ?", unit_id, new_unit_id)
44
+ .or(UnitConversion.where("from_id = ? AND to_id = ?", new_unit_id, unit_id))
45
+
46
+ unless conversions.count.positive?
47
+ units = Unit.where(id: [unit_id, new_unit_id]).select(:code)
48
+ raise(StandardError, "There is no conversion factor between #{units[0].code} and #{units[1].code}.")
49
+ end
50
+
51
+ conversion = conversions.first
52
+ return (quantity * conversion.factor).round if unit_id == conversion.from_id && new_unit_id == conversion.to_id
53
+
54
+ (quantity / conversion.factor).round
55
+ end
56
+
57
+ def suggest_values(item_id, new_unit_id)
58
+ item = CustomerOrderItem.includes(:customer_order).find_by(id: item_id)
59
+ raise(StandardError, "Order item with id `#{item_id}` not found.") unless item
60
+
61
+ quantity = convert_quantity(item.quantity, item.unit_id, new_unit_id)
62
+ client_price = ClientPrice.find_by(product_id: item.product_id, client_id: item.customer_order.client_id)
63
+ if client_price
64
+ price = convert_price(client_price.price, client_price.unit_id, new_unit_id)
65
+ else
66
+ master_price = MasterPrice.find_by(product_id: item.product_id, primary: true)
67
+ raise(StandardError, "No price entry could be found for product `#{item.product.code}`.") unless master_price
68
+
69
+ price = convert_price(master_price.selling_price, master_price.unit_id, new_unit_id)
70
+ end
71
+ {quantity: quantity, price: price}
72
+ end
73
+
4
74
  def submit(id)
5
75
  order = CustomerOrder.find_by(id: id)
6
76
  raise(StandardError, "Customer order with id `#{id}` not found.") unless order
@@ -51,16 +121,31 @@ module Comee
51
121
  customer_order: order,
52
122
  status: SalesOrder.statuses[:draft]
53
123
  )
54
- items = order.customer_order_items.each_with_object([]) do |item, res|
124
+ order_items = order.customer_order_items.includes(:product, :unit)
125
+ prices = ClientPrice.where(client: order.client, product_id: order_items.map(&:product_id))
126
+ items = order_items.each_with_object([]) do |item, res|
55
127
  next if item.canceled?
56
128
 
129
+ default_unit = item.product.default_unit
130
+ unit_id = default_unit ? default_unit["id"] : item.unit_id
131
+ quantity = convert_quantity(item.quantity, item.unit_id, unit_id)
132
+ client_price = prices.find { |price| price.product_id == item.product_id }
133
+ if client_price
134
+ price = convert_price(client_price.price, client_price.unit_id, unit_id)
135
+ else
136
+ master_price = MasterPrice.find_by(product: item.product, primary: true)
137
+ raise(StandardError, "No price entry could be found for product `#{item.product.code}`.") unless master_price
138
+
139
+ price = convert_price(master_price.selling_price, master_price.unit_id, unit_id)
140
+ end
141
+
57
142
  res << {
58
143
  sales_order_id: sales_order.id,
59
144
  customer_order_item_id: item.id,
60
145
  product_id: item.product_id,
61
- unit_id: item.unit_id,
62
- quantity: item.quantity,
63
- price: item.price,
146
+ unit_id: unit_id,
147
+ quantity: quantity,
148
+ price: price,
64
149
  delivery_date: item.delivery_date
65
150
  }
66
151
  end
data/config/routes.rb CHANGED
@@ -45,6 +45,7 @@ Comee::Core::Engine.routes.draw do
45
45
  end
46
46
  resources :currencies
47
47
  resources :units
48
+ resources :unit_conversions
48
49
  resources :users
49
50
  post "/purchase_orders/filter", controller: :purchase_orders, action: :filter
50
51
  resources :purchase_orders
@@ -66,7 +67,11 @@ Comee::Core::Engine.routes.draw do
66
67
  post "submit"
67
68
  end
68
69
  end
69
- resources :sales_order_items, except: [:index]
70
+ resources :sales_order_items, except: [:index] do
71
+ member do
72
+ get "suggest", controller: :sales_order_items, action: :suggest_values
73
+ end
74
+ end
70
75
  post "/sales_orders/filter", controller: :sales_orders, action: :filter
71
76
  resources :sales_orders do
72
77
  collection do
@@ -6,6 +6,7 @@ class CreateComeeCoreProducts < ActiveRecord::Migration[7.0]
6
6
  t.string :description
7
7
  t.boolean :leaf, null: false, default: true
8
8
  t.string :ancestry
9
+ t.jsonb :preferred_units, null: false, default: []
9
10
 
10
11
  t.timestamps
11
12
  end
@@ -0,0 +1,19 @@
1
+ class CreateComeeCoreUnitConversions < ActiveRecord::Migration[7.1]
2
+ def change
3
+ create_table :comee_core_unit_conversions do |t|
4
+ t.references :from,
5
+ null: false,
6
+ index: {name: "from_on_uc_indx"},
7
+ foreign_key: {to_table: :comee_core_units}
8
+ t.references :to,
9
+ null: false,
10
+ index: {name: "to_on_uc_indx"},
11
+ foreign_key: {to_table: :comee_core_units}
12
+ t.float :factor, null: false
13
+
14
+ t.timestamps
15
+ end
16
+
17
+ add_index(:comee_core_unit_conversions, %i[from_id to_id], unique: true)
18
+ end
19
+ end
@@ -1,5 +1,5 @@
1
1
  module Comee
2
2
  module Core
3
- VERSION = "0.1.45".freeze
3
+ VERSION = "0.1.46".freeze
4
4
  end
5
5
  end
@@ -8,5 +8,6 @@ FactoryBot.define do
8
8
  description { Faker::Lorem.sentence }
9
9
  leaf { true }
10
10
  ancestry { root.id.to_s }
11
+ preferred_units { [] }
11
12
  end
12
13
  end
@@ -0,0 +1,7 @@
1
+ FactoryBot.define do
2
+ factory :unit_conversion, class: "Comee::Core::UnitConversion" do
3
+ from factory: :unit
4
+ to factory: :unit
5
+ factor { 1 }
6
+ end
7
+ 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.45
4
+ version: 0.1.46
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-12-05 00:00:00.000000000 Z
11
+ date: 2023-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_model_serializers
@@ -298,6 +298,7 @@ files:
298
298
  - app/controllers/comee/core/sales_order_items_controller.rb
299
299
  - app/controllers/comee/core/sales_orders_controller.rb
300
300
  - app/controllers/comee/core/suppliers_controller.rb
301
+ - app/controllers/comee/core/unit_conversions_controller.rb
301
302
  - app/controllers/comee/core/units_controller.rb
302
303
  - app/controllers/comee/core/users_controller.rb
303
304
  - app/controllers/concerns/comee/core/common.rb
@@ -336,6 +337,7 @@ files:
336
337
  - app/models/comee/core/sales_order_item.rb
337
338
  - app/models/comee/core/supplier.rb
338
339
  - app/models/comee/core/unit.rb
340
+ - app/models/comee/core/unit_conversion.rb
339
341
  - app/models/comee/core/user.rb
340
342
  - app/models/comee/core/warehouse_shipment.rb
341
343
  - app/models/comee/core/warehouse_shipment_item.rb
@@ -357,6 +359,7 @@ files:
357
359
  - app/serializers/comee/core/sales_order_item_serializer.rb
358
360
  - app/serializers/comee/core/sales_order_serializer.rb
359
361
  - app/serializers/comee/core/supplier_serializer.rb
362
+ - app/serializers/comee/core/unit_conversion_serializer.rb
360
363
  - app/serializers/comee/core/unit_serializer.rb
361
364
  - app/serializers/comee/core/user_serializer.rb
362
365
  - app/services/comee/core/customer_order_service.rb
@@ -404,6 +407,7 @@ files:
404
407
  - db/migrate/20231125115522_create_comee_core_customs_details.rb
405
408
  - db/migrate/20231125122723_create_comee_core_purchase_orders.rb
406
409
  - db/migrate/20231126082907_create_comee_core_purchase_order_items.rb
410
+ - db/migrate/20231206082503_create_comee_core_unit_conversions.rb
407
411
  - lib/comee/core.rb
408
412
  - lib/comee/core/engine.rb
409
413
  - lib/comee/core/version.rb
@@ -437,6 +441,7 @@ files:
437
441
  - spec/factories/comee/core/sales_order_items.rb
438
442
  - spec/factories/comee/core/sales_orders.rb
439
443
  - spec/factories/comee/core/suppliers.rb
444
+ - spec/factories/comee/core/unit_conversions.rb
440
445
  - spec/factories/comee/core/units.rb
441
446
  - spec/factories/comee/core/users.rb
442
447
  - spec/factories/comee/core/warehouse_shipment_items.rb