-
Notifications
You must be signed in to change notification settings - Fork 0
/
sourcedest.rb
executable file
·105 lines (89 loc) · 2.87 KB
/
sourcedest.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/env ruby
#
# Porp - The Prototype Open Retail Platform
#
# Copyright (c) 2010 Phil Stewart
#
# License: MIT (see LICENSE file)
class Stock
=begin
The StockSourceDest class represents movement targets which create or
destroy stock. Class implements a default source/destination issue and receipt
behaviour
=end
class SourceDest < MovementTarget
include Ohm::Locking
attribute :net_stock_qty
attribute :net_stock_value
# Set defaults for attributes if not supplied
def initialize(attrs = {})
super(attrs)
self.net_stock_qty ||= 0
self.net_stock_value ||= 0
end
# Issue stock from this target
def issue(movement)
# Lock while we update the attributes
mutex(0.01) do
self.net_stock_qty = Integer(self.net_stock_qty) - Integer(movement.source_amount.qty)
self.net_stock_value = Rational(self.net_stock_value) - Rational(movement.source_amount.value)
end
self.save
# Return the quantity issued
movement.source_amount.qty
end
# Reverse an issue
def reverse_issue(movement)
# Lock while we update the attributes
mutex(0.01) do
self.net_stock_qty = Integer(self.net_stock_qty) + Integer(movement.source_amount.qty)
self.net_stock_value = Rational(self.net_stock_value) + Rational(movement.source_amount.value)
end
self.save
# Return the quantity issued (negated as we're reversing)
-movement.source_amount.qty
end
# Receive stock to this target
def receive(movement)
# Lock while we update the attributes
# The stock value change is calculated on source qty and source unit
# to ensure conservation of value. The destination unit cost can be
# calculated by dividing out the dest qty
mutex(0.01) do
self.net_stock_qty = Integer(self.net_stock_qty) + Integer(movement.dest_amount.qty)
self.net_stock_value = Rational(self.net_stock_value) + Rational(movement.source_amount.value)
end
self.save
# Return the quantity received
movement.dest_amount.qty
end
end
# Misc target uses the default net quantity and net value scheme. It maintains
# a single instance primarily intended for testing.
class MiscTarget < SourceDest
@@misc_singleton = Hash.new
def self.acquire
@@misc_singleton[self] ||= self.create
end
def self.reinit(*args)
@@misc_singleton[self] = self.create(*args)
end
# Ensure only one instance in the database by overriding id creation and
# only ever allowing the first id
def initialize_id
@id = "1"
end
end
# Null target literally does nothing. Intended for testing only.
class NullTarget < MiscTarget
def issue(movement)
true
end
def reverse_issue(movement)
true
end
def receive(movement)
true
end
end
end