smerp-quotation 0.1.0 → 0.2.0
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/.release_history.yml +4 -0
- data/Gemfile.lock +23 -19
- data/db/migrate/20220901033007_create_quotation_items.rb +3 -0
- data/db/migrate/20220930231854_create_quotation_item_distribution.rb +22 -0
- data/lib/smerp/quotation/ar_model/quotation_item.rb +177 -25
- data/lib/smerp/quotation/ar_model/quotation_item_distribution.rb +31 -0
- data/lib/smerp/quotation/calculators/distribution_calculator.rb +73 -0
- data/lib/smerp/quotation/version.rb +1 -1
- data/schema.rb +16 -2
- data/smerp-quotation.gemspec +1 -0
- metadata +20 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9b31b97876363a1e89cf5bfd87e092f304d3a0d873d222a28ac9669473ed53c9
|
|
4
|
+
data.tar.gz: 758df4aba6b9319126334fd2d8b7af834bd1f582ef77c5bb14ab8180008c5c09
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0a465d9ce3167cb1d782f9fbdf8d277be35fe554238da074c431b2235c7a446522ccec29d4a4afe3d8555c0a22999ad7282e5aefcc969ab7e1900ddb684af6ab
|
|
7
|
+
data.tar.gz: c4b6557dc0e7fe67c3daa382d0a147e968f5b4dab7e5a3a8a9fbaa53dff2bb5e6aeed47a74d5ee15a2db181a8861e4637b64983937a1811f7074135d805bccd4
|
data/Gemfile.lock
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
smerp-quotation (0.
|
|
4
|
+
smerp-quotation (0.2.0)
|
|
5
5
|
acts_as_list
|
|
6
6
|
acts_as_tree
|
|
7
7
|
ca-data_store
|
|
8
8
|
ca-data_store-ar
|
|
9
|
+
smerp-common
|
|
9
10
|
state_machines-activerecord
|
|
10
11
|
teLogger
|
|
11
12
|
toolrack
|
|
@@ -13,25 +14,25 @@ PATH
|
|
|
13
14
|
GEM
|
|
14
15
|
remote: https://rubygems.org/
|
|
15
16
|
specs:
|
|
16
|
-
actionpack (7.0.
|
|
17
|
-
actionview (= 7.0.
|
|
18
|
-
activesupport (= 7.0.
|
|
17
|
+
actionpack (7.0.4)
|
|
18
|
+
actionview (= 7.0.4)
|
|
19
|
+
activesupport (= 7.0.4)
|
|
19
20
|
rack (~> 2.0, >= 2.2.0)
|
|
20
21
|
rack-test (>= 0.6.3)
|
|
21
22
|
rails-dom-testing (~> 2.0)
|
|
22
23
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
|
23
|
-
actionview (7.0.
|
|
24
|
-
activesupport (= 7.0.
|
|
24
|
+
actionview (7.0.4)
|
|
25
|
+
activesupport (= 7.0.4)
|
|
25
26
|
builder (~> 3.1)
|
|
26
27
|
erubi (~> 1.4)
|
|
27
28
|
rails-dom-testing (~> 2.0)
|
|
28
29
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
|
29
|
-
activemodel (7.0.
|
|
30
|
-
activesupport (= 7.0.
|
|
31
|
-
activerecord (7.0.
|
|
32
|
-
activemodel (= 7.0.
|
|
33
|
-
activesupport (= 7.0.
|
|
34
|
-
activesupport (7.0.
|
|
30
|
+
activemodel (7.0.4)
|
|
31
|
+
activesupport (= 7.0.4)
|
|
32
|
+
activerecord (7.0.4)
|
|
33
|
+
activemodel (= 7.0.4)
|
|
34
|
+
activesupport (= 7.0.4)
|
|
35
|
+
activesupport (7.0.4)
|
|
35
36
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
36
37
|
i18n (>= 1.6, < 2)
|
|
37
38
|
minitest (>= 5.1)
|
|
@@ -45,7 +46,7 @@ GEM
|
|
|
45
46
|
ca-data_store (0.1.0)
|
|
46
47
|
teLogger
|
|
47
48
|
toolrack
|
|
48
|
-
ca-data_store-ar (0.1.
|
|
49
|
+
ca-data_store-ar (0.1.1)
|
|
49
50
|
activerecord
|
|
50
51
|
activesupport
|
|
51
52
|
ca-data_store
|
|
@@ -94,9 +95,9 @@ GEM
|
|
|
94
95
|
nokogiri (>= 1.6)
|
|
95
96
|
rails-html-sanitizer (1.4.3)
|
|
96
97
|
loofah (~> 2.3)
|
|
97
|
-
railties (7.0.
|
|
98
|
-
actionpack (= 7.0.
|
|
99
|
-
activesupport (= 7.0.
|
|
98
|
+
railties (7.0.4)
|
|
99
|
+
actionpack (= 7.0.4)
|
|
100
|
+
activesupport (= 7.0.4)
|
|
100
101
|
method_source
|
|
101
102
|
rake (>= 12.2)
|
|
102
103
|
thor (~> 1.0)
|
|
@@ -108,14 +109,17 @@ GEM
|
|
|
108
109
|
rspec-mocks (~> 3.11.0)
|
|
109
110
|
rspec-core (3.11.0)
|
|
110
111
|
rspec-support (~> 3.11.0)
|
|
111
|
-
rspec-expectations (3.11.
|
|
112
|
+
rspec-expectations (3.11.1)
|
|
112
113
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
113
114
|
rspec-support (~> 3.11.0)
|
|
114
115
|
rspec-mocks (3.11.1)
|
|
115
116
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
116
117
|
rspec-support (~> 3.11.0)
|
|
117
|
-
rspec-support (3.11.
|
|
118
|
-
|
|
118
|
+
rspec-support (3.11.1)
|
|
119
|
+
smerp-common (0.1.0)
|
|
120
|
+
teLogger
|
|
121
|
+
toolrack
|
|
122
|
+
sqlite3 (1.5.1-x86_64-linux)
|
|
119
123
|
standalone_migrations (7.1.0)
|
|
120
124
|
activerecord (>= 4.2.7, < 7.1.0, != 5.2.3.rc1, != 5.2.3)
|
|
121
125
|
railties (>= 4.2.7, < 7.1.0, != 5.2.3.rc1, != 5.2.3)
|
|
@@ -44,6 +44,9 @@ class CreateQuotationItems < ActiveRecord::Migration[7.0]
|
|
|
44
44
|
|
|
45
45
|
# value stored for display
|
|
46
46
|
t.decimal :line_total, default: 0.0, precision: 25, scale: 2
|
|
47
|
+
|
|
48
|
+
# total including the distributed items included
|
|
49
|
+
t.decimal :consolidated_line_total, default: 0.0, precision: 25, scale: 2
|
|
47
50
|
|
|
48
51
|
t.decimal :discount, precision: 25, scale: 2, default: 0.0
|
|
49
52
|
# yaml hash structure indicate the discount is
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
class CreateQuotationItemDistribution < ActiveRecord::Migration[7.0]
|
|
3
|
+
def change
|
|
4
|
+
create_table :quotation_item_distributions do |t|
|
|
5
|
+
|
|
6
|
+
t.string :quotation_item_id
|
|
7
|
+
t.string :distributed_quotation_item_id
|
|
8
|
+
t.text :distribution_calculations
|
|
9
|
+
|
|
10
|
+
t.decimal :distributed_line_total, default: 0.0
|
|
11
|
+
|
|
12
|
+
t.decimal :distributed_discount, default: 0.0
|
|
13
|
+
t.decimal :distributed_line_total_after_discount, default: 0.0
|
|
14
|
+
|
|
15
|
+
t.decimal :distributed_tax, default: 0.0
|
|
16
|
+
t.decimal :distributed_line_total_with_tax, default: 0.0
|
|
17
|
+
|
|
18
|
+
t.timestamps
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -22,23 +22,40 @@ module Smerp
|
|
|
22
22
|
# polymorphic on model of products / resources
|
|
23
23
|
# has_many :quotation_items, as: :quotable
|
|
24
24
|
|
|
25
|
+
# sel-reflecting relationship
|
|
26
|
+
# This item splited into how many items?
|
|
27
|
+
has_many :quotation_item_distributions
|
|
28
|
+
has_many :destination_quotation_items, through: :quotation_item_distributions, source: :distributed_quotation_item
|
|
29
|
+
|
|
30
|
+
# This item is included distribution from which item?
|
|
31
|
+
has_many :source_quotation_items_link, class_name: "QuotationItemDistribution", foreign_key: "distributed_quotation_item_id"
|
|
32
|
+
has_many :source_quotation_items, through: :source_quotation_items_link, source: :quotation_item
|
|
33
|
+
|
|
25
34
|
belongs_to :quotation_item_group, optional: true
|
|
26
35
|
|
|
27
36
|
before_save :update_total
|
|
28
37
|
after_save :update_group_total, :update_quotation_total
|
|
29
38
|
|
|
30
39
|
before_destroy :update_total
|
|
31
|
-
after_destroy :update_group_total, :update_quotation_total
|
|
40
|
+
after_destroy :update_group_total, :update_quotation_total, :remove_total_from_destination_quotation_items
|
|
32
41
|
|
|
33
42
|
def update_total
|
|
34
43
|
|
|
35
|
-
if children.length == 0
|
|
44
|
+
if self.children.length == 0
|
|
36
45
|
self.line_total = self.quantity * self.unit_price if self.quantity_changed? or self.unit_price_changed?
|
|
37
46
|
self.line_total_after_discount = self.line_total
|
|
38
47
|
self.line_total_with_tax = self.line_total
|
|
48
|
+
|
|
49
|
+
#teLogger.debug "sync consolidated #{self.inspect} to line_total #{self.line_total.to_i}"
|
|
50
|
+
self.consolidated_line_total = self.line_total if self.new_record?
|
|
51
|
+
#teLogger.debug "sync consolidated #{self.inspect} to line_total #{self.line_total.to_i}"
|
|
52
|
+
|
|
53
|
+
else
|
|
54
|
+
#teLogger.debug "#{self.inspect} has children : #{self.children}"
|
|
39
55
|
end
|
|
40
56
|
|
|
41
57
|
if self.quantity_changed?
|
|
58
|
+
teLogger.debug "Quantity changed"
|
|
42
59
|
# Change unit_price for record that has children
|
|
43
60
|
# since unit_price is 'derived' from children's line_total
|
|
44
61
|
if self.quantity > 0
|
|
@@ -49,6 +66,17 @@ module Smerp
|
|
|
49
66
|
end
|
|
50
67
|
end
|
|
51
68
|
|
|
69
|
+
#teLogger.debug "Before recalculate : #{self.inspect}"
|
|
70
|
+
## Calculate consolidated line total
|
|
71
|
+
# Calculate line total of each item that push to this parent item
|
|
72
|
+
if not self.new_record?
|
|
73
|
+
recalculate_total_from_source_quotation_items
|
|
74
|
+
end
|
|
75
|
+
#teLogger.debug "After recalculate : #{self.inspect}"
|
|
76
|
+
|
|
77
|
+
#
|
|
78
|
+
# Start trigger defined calculators
|
|
79
|
+
#
|
|
52
80
|
res = { local: [], quotation: [] }
|
|
53
81
|
extCals = { local: [], quotation: [] }
|
|
54
82
|
if not_empty?(self.extended_calculators)
|
|
@@ -112,7 +140,9 @@ module Smerp
|
|
|
112
140
|
}
|
|
113
141
|
|
|
114
142
|
self.extended_calculators = YAML.dump(res)
|
|
143
|
+
## Calculator execution completed
|
|
115
144
|
|
|
145
|
+
teLogger.debug "before save done : #{self.inspect}"
|
|
116
146
|
end
|
|
117
147
|
|
|
118
148
|
def update_group_total
|
|
@@ -120,7 +150,7 @@ module Smerp
|
|
|
120
150
|
grp = self.quotation_item_group
|
|
121
151
|
if not grp.nil?
|
|
122
152
|
# update total
|
|
123
|
-
grp.group_total = grp.children.sum(:group_total) + grp.quotation_items.sum(:
|
|
153
|
+
grp.group_total = grp.children.sum(:group_total) + grp.quotation_items.sum(:consolidated_line_total)
|
|
124
154
|
grp.group_discount = grp.children.sum(:group_discount) + grp.quotation_items.sum(:discount)
|
|
125
155
|
grp.group_tax = grp.children.sum(:group_tax) + grp.quotation_items.sum(:tax)
|
|
126
156
|
grp.save
|
|
@@ -143,21 +173,22 @@ module Smerp
|
|
|
143
173
|
if self.parent.quantity > 0
|
|
144
174
|
# for children item that has a parent
|
|
145
175
|
# update parent line_total
|
|
146
|
-
self.parent.
|
|
176
|
+
self.parent.consolidated_line_total = self.parent.children.sum(:consolidated_line_total)
|
|
147
177
|
|
|
148
178
|
# update unit_price since line_total is sum of children's line_total
|
|
149
|
-
self.parent.unit_price = self.parent.
|
|
179
|
+
self.parent.unit_price = self.parent.consolidated_line_total / self.parent.quantity
|
|
150
180
|
|
|
151
181
|
self.parent.discount = self.parent.children.sum(:discount)
|
|
152
182
|
self.parent.line_total_after_discount = self.parent.children.sum(:line_total_after_discount)
|
|
153
183
|
self.parent.tax = self.parent.children.sum(:tax)
|
|
154
184
|
self.parent.line_total_with_tax = self.parent.children.sum(:line_total_with_tax)
|
|
155
185
|
|
|
156
|
-
teLogger.debug "After update from children : #{self.parent.inspect}"
|
|
186
|
+
#teLogger.debug "After update from children : #{self.parent.inspect}"
|
|
157
187
|
|
|
158
188
|
else
|
|
159
189
|
|
|
160
190
|
self.parent.line_total = 0.0
|
|
191
|
+
self.parent.consolidated_line_total = 0.0
|
|
161
192
|
self.parent.unit_price = 0.0
|
|
162
193
|
self.parent.discount = 0.0
|
|
163
194
|
self.parent.line_total_after_discount = 0.0
|
|
@@ -171,15 +202,19 @@ module Smerp
|
|
|
171
202
|
teLogger.debug "Parent #{self.parent.inspect} is NOT children linked. Skipping children update to parent."
|
|
172
203
|
end
|
|
173
204
|
|
|
174
|
-
end
|
|
205
|
+
end # if parent exist
|
|
206
|
+
|
|
207
|
+
# calculate if I'm the source to be embedded into other items
|
|
208
|
+
recalculate_total_to_destination_quotation_items
|
|
175
209
|
|
|
176
|
-
self.quotation.total = self.quotation.quotation_items.where(["parent_id is null"]).sum(:
|
|
210
|
+
self.quotation.total = self.quotation.quotation_items.where(["parent_id is null"]).sum(:consolidated_line_total)
|
|
177
211
|
self.quotation.total_discount = self.quotation.quotation_items.where(["parent_id is null"]).sum(:discount)
|
|
178
212
|
self.quotation.total_after_discount = self.quotation.quotation_items.where(["parent_id is null"]).sum(:line_total_after_discount)
|
|
179
213
|
self.quotation.total_tax = self.quotation.quotation_items.where(["parent_id is null"]).sum(:tax)
|
|
180
214
|
self.quotation.total_with_tax = self.quotation.quotation_items.where(["parent_id is null"]).sum(:line_total_with_tax)
|
|
181
215
|
|
|
182
216
|
self.quotation.save
|
|
217
|
+
|
|
183
218
|
end
|
|
184
219
|
|
|
185
220
|
|
|
@@ -187,6 +222,9 @@ module Smerp
|
|
|
187
222
|
|
|
188
223
|
if self.quantity_changed? or self.unit_price_changed?
|
|
189
224
|
self.line_total = self.quantity * self.unit_price
|
|
225
|
+
# reset consolidated total and calculate again
|
|
226
|
+
self.consolidated_line_total = self.line_total
|
|
227
|
+
calculate_incoming_distribution
|
|
190
228
|
end
|
|
191
229
|
|
|
192
230
|
if self.discount_changed?
|
|
@@ -195,24 +233,121 @@ module Smerp
|
|
|
195
233
|
|
|
196
234
|
end
|
|
197
235
|
|
|
236
|
+
# recalculate becauase destionation line_total changed
|
|
237
|
+
# triggered before_save
|
|
238
|
+
def recalculate_total_from_source_quotation_items
|
|
239
|
+
|
|
240
|
+
#self.reload
|
|
241
|
+
ttl = self.line_total
|
|
242
|
+
self.source_quotation_items_link.each do |iqi|
|
|
243
|
+
|
|
244
|
+
srcItm = iqi.quotation_item
|
|
245
|
+
|
|
246
|
+
next if srcItm.nil?
|
|
247
|
+
|
|
248
|
+
#teLogger.debug "Calculating using source item : #{srcItm.inspect}"
|
|
249
|
+
cal = YAML.load(iqi.distribution_calculations)
|
|
250
|
+
cal.calculate(srcItm)
|
|
251
|
+
|
|
252
|
+
teLogger.debug "Distribution calculation : #{cal.result}"
|
|
253
|
+
|
|
254
|
+
ttl += cal.result[Smerp::Quotation::DistributionCalculator::DistributedAmount]
|
|
255
|
+
|
|
256
|
+
iqi.distribution_calculations = YAML.dump(cal.for_storage)
|
|
257
|
+
iqi.save
|
|
258
|
+
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
self.consolidated_line_total = ttl
|
|
262
|
+
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
# recalculate because the source item line_total changed
|
|
266
|
+
# trigger after_save
|
|
267
|
+
def recalculate_total_to_destination_quotation_items
|
|
268
|
+
|
|
269
|
+
#teLogger.debug "before get in : #{self.inspect}"
|
|
270
|
+
self.quotation_item_distributions.each do |qid|
|
|
271
|
+
|
|
272
|
+
citm = qid.distributed_quotation_item
|
|
273
|
+
|
|
274
|
+
# for some reasons when one of the item is deleted first
|
|
275
|
+
# but the connection is not reloaded.
|
|
276
|
+
# Reload before coming in doesn't really solve the issue
|
|
277
|
+
next if citm.nil?
|
|
278
|
+
|
|
279
|
+
#teLogger.debug "citm : #{citm.inspect}"
|
|
280
|
+
cal = YAML.load(qid.distribution_calculations)
|
|
281
|
+
# get the old figure
|
|
282
|
+
oldRes = cal.result.clone
|
|
283
|
+
teLogger.debug "oldRes : #{oldRes}"
|
|
284
|
+
# calculate base on
|
|
285
|
+
#teLogger.debug "Self is : #{self.inspect}"
|
|
286
|
+
cal.calculate(self)
|
|
287
|
+
newRes = cal.result
|
|
288
|
+
teLogger.debug "newRes : #{newRes}"
|
|
289
|
+
|
|
290
|
+
#teLogger.debug "citm before process : #{citm.consolidated_line_total}"
|
|
291
|
+
citm.consolidated_line_total = (citm.consolidated_line_total - oldRes[Smerp::Quotation::DistributionCalculator::DistributedAmount] + newRes[Smerp::Quotation::DistributionCalculator::DistributedAmount])
|
|
292
|
+
#teLogger.debug "citm after process : #{citm.consolidated_line_total}"
|
|
293
|
+
|
|
294
|
+
qid.distribution_calculations = YAML.dump(cal.for_storage)
|
|
295
|
+
qid.save
|
|
296
|
+
|
|
297
|
+
# trigger other calculations
|
|
298
|
+
citm.save
|
|
299
|
+
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
# item that is being distributed to other
|
|
305
|
+
# quotation items is being destroyed
|
|
306
|
+
# Remove those portion from each and every items
|
|
307
|
+
def remove_total_from_destination_quotation_items
|
|
308
|
+
|
|
309
|
+
self.quotation_item_distributions.each do |qid|
|
|
310
|
+
|
|
311
|
+
citm = qid.distributed_quotation_item
|
|
312
|
+
|
|
313
|
+
next if citm.nil?
|
|
314
|
+
|
|
315
|
+
cal = YAML.load(qid.distribution_calculations)
|
|
316
|
+
extRes = cal.result.clone
|
|
317
|
+
|
|
318
|
+
#teLogger.debug "before citm #{citm.inspect} / #{citm.consolidated_line_total}"
|
|
319
|
+
citm.consolidated_line_total = (citm.consolidated_line_total - extRes[Smerp::Quotation::DistributionCalculator::DistributedAmount])
|
|
320
|
+
#teLogger.debug "after deduction citm #{citm.inspect} / #{citm.consolidated_line_total}"
|
|
321
|
+
|
|
322
|
+
#teLogger.debug "qid : #{qid.inspect}"
|
|
323
|
+
qid.destroy
|
|
324
|
+
|
|
325
|
+
citm.source_quotation_items_link.reload
|
|
326
|
+
|
|
327
|
+
citm.save
|
|
328
|
+
#teLogger.debug "after citm #{citm.inspect} / #{citm.consolidated_line_total}"
|
|
329
|
+
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
def total_distributed
|
|
335
|
+
|
|
336
|
+
ttl = 0.0
|
|
337
|
+
self.quotation_item_distributions.each do |qid|
|
|
338
|
+
cal = YAML.load(qid.distribution_calculations)
|
|
339
|
+
ttl += cal.result[Smerp::Quotation::DistributionCalculator::DistributedAmount]
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
ttl
|
|
343
|
+
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
def balance_after_distribution
|
|
347
|
+
bal = self.line_total - self.total_distributed
|
|
348
|
+
{ balance_amount: bal, balance_percentage: bal.percent_of(self.line_total) }
|
|
349
|
+
end
|
|
198
350
|
|
|
199
|
-
#def children
|
|
200
|
-
# if @_children.nil?
|
|
201
|
-
# @_children = QuotationItem.where(["parent_id = ?",self.id])
|
|
202
|
-
# end
|
|
203
|
-
# @_children
|
|
204
|
-
#end
|
|
205
|
-
|
|
206
|
-
#def parent
|
|
207
|
-
# if self.parent_id.nil?
|
|
208
|
-
# nil
|
|
209
|
-
# else
|
|
210
|
-
# if @_parent.nil?
|
|
211
|
-
# @_parent = QuotationItem.find(self.parent_id)
|
|
212
|
-
# end
|
|
213
|
-
# @_parent
|
|
214
|
-
# end
|
|
215
|
-
#end
|
|
216
351
|
|
|
217
352
|
def break_children_link
|
|
218
353
|
|
|
@@ -410,6 +545,23 @@ module Smerp
|
|
|
410
545
|
end
|
|
411
546
|
|
|
412
547
|
|
|
548
|
+
def distribute_to(distTo, val)
|
|
549
|
+
|
|
550
|
+
dist = QuotationItemDistribution.new
|
|
551
|
+
dist.quotation_item = self
|
|
552
|
+
dist.distributed_quotation_item_id = distTo.quotation_item.id
|
|
553
|
+
cal = Smerp::Quotation::DistributionCalculator.new(val)
|
|
554
|
+
cal.input_field = :consolidated_line_total
|
|
555
|
+
dist.distribution_calculations = YAML.dump(cal.for_storage)
|
|
556
|
+
dist.save
|
|
557
|
+
|
|
558
|
+
# trigger the calculator and distribution calculations
|
|
559
|
+
distTo.save
|
|
560
|
+
distTo.reload
|
|
561
|
+
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
|
|
413
565
|
end
|
|
414
566
|
end
|
|
415
567
|
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
module Smerp
|
|
4
|
+
module Quotation
|
|
5
|
+
module ArModel
|
|
6
|
+
|
|
7
|
+
class QuotationItemDistribution < Ca::DataStore::Ar::Model
|
|
8
|
+
include TR::CondUtils
|
|
9
|
+
|
|
10
|
+
belongs_to :quotation_item
|
|
11
|
+
belongs_to :distributed_quotation_item, class_name: 'QuotationItem'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
#after_save :distribute
|
|
15
|
+
|
|
16
|
+
#def distribute
|
|
17
|
+
|
|
18
|
+
# cal = YAML.load(self.distribution_calculators)
|
|
19
|
+
# cal.calculate(self.quotation_item)
|
|
20
|
+
|
|
21
|
+
# self.distributed_quotation_item.consolidated_line_total += cal.result[Smerp::Quotation::DistributionCalculator::DistributedValue]
|
|
22
|
+
|
|
23
|
+
# self.distributed_quotation_item.save
|
|
24
|
+
|
|
25
|
+
#end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
module Smerp
|
|
5
|
+
module Quotation
|
|
6
|
+
class DistributionCalculator
|
|
7
|
+
include ExtendedCalculator
|
|
8
|
+
include TR::CondUtils
|
|
9
|
+
|
|
10
|
+
include TeLogger::TeLogHelper
|
|
11
|
+
teLogger_tag :distributionCal
|
|
12
|
+
|
|
13
|
+
DistributedAmount = :distributed_amount
|
|
14
|
+
ValueWithDistribution = :value_with_distribution
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def calculate(mdl)
|
|
18
|
+
|
|
19
|
+
srcVal = mdl.send(@input_field)
|
|
20
|
+
if not_empty?(srcVal)
|
|
21
|
+
|
|
22
|
+
srcVal = srcVal.to_f
|
|
23
|
+
|
|
24
|
+
res = { input: @input_field, input_value: srcVal }
|
|
25
|
+
case @params
|
|
26
|
+
when Smerp::Common::FinUtils::Percent
|
|
27
|
+
res[DistributedAmount] = srcVal * @params.rep_value
|
|
28
|
+
when Smerp::Common::FinUtils::RawValue
|
|
29
|
+
res[DistributedAmount] = @params.rep_value
|
|
30
|
+
else
|
|
31
|
+
res[DistributedAmount] = @params.to_f
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
res[ValueWithDistribution] = srcVal + res[DistributedAmount]
|
|
35
|
+
|
|
36
|
+
#if not_empty?(@output_field) and not outMdl.nil?
|
|
37
|
+
|
|
38
|
+
# case @output_field
|
|
39
|
+
# when Array
|
|
40
|
+
# @output_field.each do |of|
|
|
41
|
+
# of.each do |f, v|
|
|
42
|
+
# outMdl.send("#{f}=", res[v])
|
|
43
|
+
# end
|
|
44
|
+
# end
|
|
45
|
+
# when Hash
|
|
46
|
+
# @output_field.each do |f,v|
|
|
47
|
+
# outMdl.send("#{f}=", res[v])
|
|
48
|
+
# end
|
|
49
|
+
# when Symbol
|
|
50
|
+
# outMdl.send("#{@output_field}=", res[DistributedAmount])
|
|
51
|
+
# end
|
|
52
|
+
|
|
53
|
+
# res[:output] = @output_field
|
|
54
|
+
# res[:output_model] = outMdl
|
|
55
|
+
# outMdl.recalculate
|
|
56
|
+
|
|
57
|
+
#end # if @output_field not empty
|
|
58
|
+
|
|
59
|
+
@result = res
|
|
60
|
+
|
|
61
|
+
trigger_listener(:after_calculation, mdl)
|
|
62
|
+
|
|
63
|
+
teLogger.debug "Distribution calculation log : #{res}"
|
|
64
|
+
|
|
65
|
+
@result
|
|
66
|
+
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
data/schema.rb
CHANGED
|
@@ -10,7 +10,20 @@
|
|
|
10
10
|
#
|
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
|
12
12
|
|
|
13
|
-
ActiveRecord::Schema[7.0].define(version:
|
|
13
|
+
ActiveRecord::Schema[7.0].define(version: 2022_09_30_231854) do
|
|
14
|
+
create_table "quotation_item_distributions", force: :cascade do |t|
|
|
15
|
+
t.string "quotation_item_id"
|
|
16
|
+
t.string "distributed_quotation_item_id"
|
|
17
|
+
t.text "distribution_calculations"
|
|
18
|
+
t.decimal "distributed_line_total", default: "0.0"
|
|
19
|
+
t.decimal "distributed_discount", default: "0.0"
|
|
20
|
+
t.decimal "distributed_line_total_after_discount", default: "0.0"
|
|
21
|
+
t.decimal "distributed_tax", default: "0.0"
|
|
22
|
+
t.decimal "distributed_line_total_with_tax", default: "0.0"
|
|
23
|
+
t.datetime "created_at", null: false
|
|
24
|
+
t.datetime "updated_at", null: false
|
|
25
|
+
end
|
|
26
|
+
|
|
14
27
|
create_table "quotation_item_groups", force: :cascade do |t|
|
|
15
28
|
t.string "name"
|
|
16
29
|
t.string "quotation_id"
|
|
@@ -35,10 +48,11 @@ ActiveRecord::Schema[7.0].define(version: 20220922121503548314) do
|
|
|
35
48
|
t.text "notes"
|
|
36
49
|
t.integer "children_link", limit: 1, default: 1
|
|
37
50
|
t.decimal "quantity", default: "0.0"
|
|
38
|
-
t.string "unit", default: "
|
|
51
|
+
t.string "unit", default: "Unit(s)"
|
|
39
52
|
t.decimal "unit_price", precision: 25, scale: 2, default: "0.0"
|
|
40
53
|
t.string "price_currency"
|
|
41
54
|
t.decimal "line_total", precision: 25, scale: 2, default: "0.0"
|
|
55
|
+
t.decimal "consolidated_line_total", precision: 25, scale: 2, default: "0.0"
|
|
42
56
|
t.decimal "discount", precision: 25, scale: 2, default: "0.0"
|
|
43
57
|
t.decimal "line_total_after_discount", precision: 25, scale: 2, default: "0.0"
|
|
44
58
|
t.decimal "tax", default: "0.0"
|
data/smerp-quotation.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: smerp-quotation
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ian
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-10-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: toolrack
|
|
@@ -80,6 +80,20 @@ dependencies:
|
|
|
80
80
|
- - ">="
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: smerp-common
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :runtime
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
83
97
|
- !ruby/object:Gem::Dependency
|
|
84
98
|
name: ca-data_store
|
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -143,6 +157,7 @@ executables: []
|
|
|
143
157
|
extensions: []
|
|
144
158
|
extra_rdoc_files: []
|
|
145
159
|
files:
|
|
160
|
+
- ".release_history.yml"
|
|
146
161
|
- ".rspec"
|
|
147
162
|
- Gemfile
|
|
148
163
|
- Gemfile.lock
|
|
@@ -156,12 +171,15 @@ files:
|
|
|
156
171
|
- db/migrate/20220901033007_create_quotation_items.rb
|
|
157
172
|
- db/migrate/20220918121051_create_quotation_item_groups.rb
|
|
158
173
|
- db/migrate/20220922121503_create_tax_category.rb
|
|
174
|
+
- db/migrate/20220930231854_create_quotation_item_distribution.rb
|
|
159
175
|
- lib/smerp/quotation.rb
|
|
160
176
|
- lib/smerp/quotation/ar_model/quotation.rb
|
|
161
177
|
- lib/smerp/quotation/ar_model/quotation_item.rb
|
|
178
|
+
- lib/smerp/quotation/ar_model/quotation_item_distribution.rb
|
|
162
179
|
- lib/smerp/quotation/ar_model/quotation_item_group.rb
|
|
163
180
|
- lib/smerp/quotation/ar_model/tax_category.rb
|
|
164
181
|
- lib/smerp/quotation/calculators/discount_calculator.rb
|
|
182
|
+
- lib/smerp/quotation/calculators/distribution_calculator.rb
|
|
165
183
|
- lib/smerp/quotation/calculators/round_up_calculator.rb
|
|
166
184
|
- lib/smerp/quotation/calculators/tax_calculator.rb
|
|
167
185
|
- lib/smerp/quotation/extended_calculator.rb
|