erp_orders 4.0.0 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/models/charge_line.rb +31 -13
- data/app/models/charge_type.rb +7 -0
- data/app/models/extensions/party.rb +13 -0
- data/app/models/order_line_item.rb +150 -14
- data/app/models/order_line_item_rel_type.rb +6 -0
- data/app/models/order_line_item_relationship.rb +8 -0
- data/app/models/order_txn.rb +314 -61
- data/app/models/sales_tax_line.rb +15 -0
- data/app/models/sales_tax_policy.rb +7 -0
- data/db/data_migrations/20141214150732_add_order_tracked_statues.rb +25 -0
- data/db/data_migrations/20150309004308_add_base_charge_types.rb +19 -0
- data/db/migrate/20080805000060_base_orders.rb +119 -111
- data/db/migrate/20150309003812_add_charge_type_to_charge_lines.rb +5 -0
- data/db/migrate/20150309004440_create_charge_types.rb +18 -0
- data/db/migrate/20150311160005_add_unit_price_to_order_line_items.rb +5 -0
- data/db/migrate/20150622151009_add_tax_policy.rb +42 -0
- data/db/migrate/20150622170438_update_taxation_for_orders.rb +58 -0
- data/db/migrate/20150624000721_add_internal_identifier_to_charge_type.rb +5 -0
- data/db/migrate/20160310163060_add_created_by_updated_by_to_erp_orders.rb +35 -0
- data/lib/erp_orders.rb +2 -0
- data/lib/erp_orders/engine.rb +0 -4
- data/lib/erp_orders/extensions/active_record/acts_as_order_line_item.rb +2 -1
- data/lib/erp_orders/extensions/active_record/acts_as_order_txn.rb +1 -1
- data/lib/erp_orders/taxation.rb +49 -0
- data/lib/erp_orders/version.rb +1 -1
- metadata +24 -15
- data/app/models/charge_line_payment_txn.rb +0 -7
- data/db/migrate/20130620203217_add_quantity_to_order_line_items.rb +0 -13
- data/db/migrate/20131005232344_update_order_line_pty_role_indexes.erp_orders.rb +0 -19
- data/db/migrate/20131005232611_remove_order_line_specific_rtype.rb +0 -32
- data/db/migrate/20140129200040_add_uom_to_order_line_item.rb +0 -13
- data/db/migrate/20140930152140_add_custom_fields_to_order_txn.rb +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b6867785c98bc211e0349e3c5a3c2d7139277ce
|
4
|
+
data.tar.gz: 10720ff3b69094fe0c7c2873eec1eec70c70dad5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9206b5e1533e05612c2e2fc3b5dd21da40bba895deae4b53ec422eba56815b50ce5484deb3f5cad050d00fb6aecf7f546a7838aaa5d6d3d0ecc22e5152e4e9e7
|
7
|
+
data.tar.gz: 75dcd09070cd56edb15ab308878f818b07681b0c21edc4df9d484c50c6a969b9caa103a6163a8533f9d81872593de9009dac17e7b085a0a55e459fe4b8311b59
|
data/app/models/charge_line.rb
CHANGED
@@ -1,23 +1,41 @@
|
|
1
|
+
# create_table :charge_lines do |t|
|
2
|
+
# t.string :sti_type
|
3
|
+
# t.references :money
|
4
|
+
# t.string :description #could be expanded to include type information, etc.
|
5
|
+
# t.string :external_identifier
|
6
|
+
# t.string :external_id_source
|
7
|
+
#
|
8
|
+
# #polymorphic
|
9
|
+
# t.references :charged_item, :polymorphic => true
|
10
|
+
#
|
11
|
+
# t.timestamps
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# add_index :charge_lines, [:charged_item_id, :charged_item_type], :name => 'charged_item_idx'
|
15
|
+
|
1
16
|
class ChargeLine < ActiveRecord::Base
|
2
17
|
attr_protected :created_at, :updated_at
|
3
18
|
|
19
|
+
tracks_created_by_updated_by
|
20
|
+
|
4
21
|
belongs_to :charged_item, :polymorphic => true
|
5
|
-
belongs_to :money
|
6
|
-
|
7
|
-
has_many :financial_txns, :through => :charge_line_payment_txns, :source => :financial_txn,
|
8
|
-
:conditions => ["charge_line_payment_txns.payment_txn_type = ?", 'FinancialTxn']
|
22
|
+
belongs_to :money, :dependent => :destroy
|
23
|
+
belongs_to :charge_type
|
9
24
|
|
10
|
-
|
11
|
-
|
25
|
+
has_many :sales_tax_lines, as: :taxed_record, dependent: :destroy
|
26
|
+
|
27
|
+
def taxed?
|
28
|
+
self.charge_type.try(:taxable)
|
12
29
|
end
|
13
30
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
31
|
+
# calculates tax and save to sales_tax
|
32
|
+
def calculate_tax(ctx={})
|
33
|
+
taxation = ErpOrders::Taxation.new
|
34
|
+
|
35
|
+
self.sales_tax = taxation.calculate_tax(self,
|
36
|
+
ctx.merge({
|
37
|
+
amount: money.amount
|
38
|
+
}))
|
21
39
|
end
|
22
40
|
|
23
41
|
end
|
@@ -1,3 +1,16 @@
|
|
1
1
|
Party.class_eval do
|
2
2
|
has_many :order_line_item_pty_roles
|
3
|
+
|
4
|
+
def orders(statuses=[])
|
5
|
+
statement = OrderTxn
|
6
|
+
|
7
|
+
unless statuses.empty?
|
8
|
+
statement = statement.with_current_status({'order_statuses' => statuses})
|
9
|
+
end
|
10
|
+
|
11
|
+
statement = statement.joins(:biz_txn_event => :biz_txn_party_roles)
|
12
|
+
.where(:biz_txn_party_roles => {:party_id => self.id})
|
13
|
+
|
14
|
+
statement
|
15
|
+
end
|
3
16
|
end
|
@@ -1,34 +1,170 @@
|
|
1
|
+
# create_table :order_line_items do |t|
|
2
|
+
# t.integer :order_txn_id
|
3
|
+
# t.integer :order_line_item_type_id
|
4
|
+
# t.integer :product_offer_id
|
5
|
+
# t.string :product_offer_description
|
6
|
+
# t.integer :product_instance_id,
|
7
|
+
# t.string :product_instance_description
|
8
|
+
# t.integer :product_type_id
|
9
|
+
# t.string :product_type_description
|
10
|
+
# t.decimal :sold_price, :precision => 8, :scale => 2
|
11
|
+
# t.integer :sold_price_uom
|
12
|
+
# t.integer :sold_amount
|
13
|
+
# t.integer :sold_amount_uom
|
14
|
+
# t.integer :quantity
|
15
|
+
# t.integer :unit_of_measurement_id
|
16
|
+
# t.decimal :unit_price, :precision => 8, :scale => 2
|
17
|
+
# t.boolean :taxable
|
18
|
+
# t.decimal :sales_tax, :precision => 8, :scale => 2
|
19
|
+
#
|
20
|
+
# t.timestamps
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# add_index :order_line_items, :order_txn_id
|
24
|
+
# add_index :order_line_items, :order_line_item_type_id
|
25
|
+
# add_index :order_line_items, :product_instance_id
|
26
|
+
# add_index :order_line_items, :product_type_id
|
27
|
+
# add_index :order_line_items, :product_offer_id
|
28
|
+
|
1
29
|
class OrderLineItem < ActiveRecord::Base
|
2
30
|
attr_protected :created_at, :updated_at
|
3
31
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
32
|
+
tracks_created_by_updated_by
|
33
|
+
|
34
|
+
belongs_to :order_txn, :class_name => 'OrderTxn'
|
35
|
+
belongs_to :order_line_item_type
|
36
|
+
|
37
|
+
has_many :charge_lines, :as => :charged_item, :dependent => :destroy
|
8
38
|
|
9
39
|
belongs_to :product_instance
|
10
40
|
belongs_to :product_type
|
41
|
+
belongs_to :product_offer
|
11
42
|
|
12
43
|
has_many :order_line_item_pty_roles, :dependent => :destroy
|
13
44
|
has_many :role_types, :through => :order_line_item_pty_roles
|
45
|
+
has_many :sales_tax_lines, as: :taxed_record, dependent: :destroy
|
14
46
|
|
15
47
|
## Allow for polymorphic subtypes of this class
|
16
48
|
belongs_to :order_line_record, :polymorphic => true
|
17
49
|
|
18
|
-
|
50
|
+
before_destroy :destroy_order_line_item_relationships
|
51
|
+
|
52
|
+
def taxed?
|
53
|
+
line_item_record.taxable?
|
54
|
+
end
|
55
|
+
|
56
|
+
# helper method to get dba_organization related to this order_line_item
|
57
|
+
def dba_organization
|
58
|
+
order_txn.find_party_by_role('dba_org')
|
59
|
+
end
|
60
|
+
|
61
|
+
def destroy_order_line_item_relationships
|
62
|
+
OrderLineItemRelationship.where("order_line_item_id_from = ? or order_line_item_id_to = ?", self.id, self.id).destroy_all
|
63
|
+
end
|
64
|
+
|
65
|
+
# get the total charges for a order_line_item.
|
66
|
+
# The total will be returned as Money.
|
67
|
+
# There may be multiple Monies assocated with an order, such as points and
|
68
|
+
# dollars. To handle this, the method should return an array of Monies
|
69
|
+
# if a currency is passed in return the amount for only that currency
|
70
|
+
def total_amount(currency=Currency.usd)
|
71
|
+
if currency and currency.is_a?(String)
|
72
|
+
currency = Currency.send(currency)
|
73
|
+
end
|
74
|
+
|
75
|
+
charges = {}
|
76
|
+
|
77
|
+
# get sold price
|
78
|
+
# TODO currency will eventually need to be accounted for here. Solid price should probably be a money record
|
79
|
+
if self.sold_price
|
80
|
+
charges["USD"] ||= {amount: 0}
|
81
|
+
charges["USD"][:amount] += (self.sold_price * (self.quantity || 1))
|
82
|
+
end
|
83
|
+
|
19
84
|
# get all of the charge lines associated with the order_line
|
20
|
-
total_hash = Hash.new
|
21
85
|
charge_lines.each do |charge|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
86
|
+
charge_money = charge.money
|
87
|
+
|
88
|
+
total_by_currency = charges[charge_money.currency.internal_identifier]
|
89
|
+
unless total_by_currency
|
90
|
+
total_by_currency = {
|
91
|
+
amount: 0
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
total_by_currency[:amount] += charge_money.amount unless charge_money.amount.nil?
|
96
|
+
|
97
|
+
charges[charge_money.currency.internal_identifier] = total_by_currency
|
98
|
+
end
|
99
|
+
|
100
|
+
# if currency was based only return that amount
|
101
|
+
# if there is only one currency then return that amount
|
102
|
+
# if there is more than once currency return the hash
|
103
|
+
if currency
|
104
|
+
charges[currency.internal_identifier][:amount].round(2)
|
105
|
+
elsif charges.keys.count == 1
|
106
|
+
charges
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# calculates tax and save to sales_tax
|
111
|
+
def calculate_tax(ctx={})
|
112
|
+
taxation = ErpOrders::Taxation.new
|
113
|
+
tax = 0
|
114
|
+
|
115
|
+
if self.taxed?
|
116
|
+
tax = taxation.calculate_tax(self,
|
117
|
+
ctx.merge({
|
118
|
+
amount: (self.sold_price * (self.quantity || 1))
|
119
|
+
}))
|
120
|
+
end
|
121
|
+
|
122
|
+
# only get charges that are USD currency
|
123
|
+
charge_lines.joins(:money).joins(:charge_type)
|
124
|
+
.where('money.currency_id' => Currency.usd)
|
125
|
+
.where('charge_types.taxable' => true).readonly(false).each do |charge_line|
|
126
|
+
tax += charge_line.calculate_tax(ctx)
|
127
|
+
end
|
128
|
+
|
129
|
+
self.sales_tax = tax
|
130
|
+
self.save
|
131
|
+
|
132
|
+
tax
|
133
|
+
end
|
134
|
+
|
135
|
+
# Alias for to_s
|
136
|
+
def to_label
|
137
|
+
to_s
|
138
|
+
end
|
139
|
+
|
140
|
+
# description of line_item_record
|
141
|
+
def to_s
|
142
|
+
if line_item_record
|
143
|
+
line_item_record.description
|
144
|
+
else
|
145
|
+
nil
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# determine the record this OrderLineItem pertains to
|
150
|
+
# can be a ProductOffer, ProductInstance or ProductType
|
151
|
+
def line_item_record
|
152
|
+
if product_offer
|
153
|
+
product_offer
|
154
|
+
else
|
155
|
+
if product_instance
|
156
|
+
product_instance
|
26
157
|
else
|
27
|
-
|
28
|
-
cur_total.amount += cur_money.amount if !cur_money.amount.nil?
|
158
|
+
product_type
|
29
159
|
end
|
30
|
-
total_hash[cur_money.currency.internal_identifier] = cur_total
|
31
160
|
end
|
32
|
-
return total_hash.values
|
33
161
|
end
|
162
|
+
|
163
|
+
def clone
|
164
|
+
order_line_item_dup = dup
|
165
|
+
order_line_item_dup.order_txn_id = nil
|
166
|
+
|
167
|
+
order_line_item_dup
|
168
|
+
end
|
169
|
+
|
34
170
|
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class OrderLineItemRelationship < ActiveRecord::Base
|
2
|
+
attr_protected :created_at, :updated_at
|
3
|
+
|
4
|
+
belongs_to :order_line_item_from, :class_name => "OrderLineItem", :foreign_key => "order_line_item_id_from"
|
5
|
+
belongs_to :order_line_item_to, :class_name => "OrderLineItem", :foreign_key => "order_line_item_id_to"
|
6
|
+
belongs_to :order_line_item_rel_type
|
7
|
+
|
8
|
+
end
|
data/app/models/order_txn.rb
CHANGED
@@ -1,51 +1,163 @@
|
|
1
|
+
# Table Definition ##########################################
|
2
|
+
# create_table :order_txns do |t|
|
3
|
+
# t.column :description, :string
|
4
|
+
# t.column :order_txn_type_id, :integer
|
5
|
+
#
|
6
|
+
# # Multi-table inheritance info
|
7
|
+
# t.column :order_txn_record_id, :integer
|
8
|
+
# t.column :order_txn_record_type, :string
|
9
|
+
#
|
10
|
+
# # Contact Information
|
11
|
+
# t.column :email, :string
|
12
|
+
# t.column :phone_number, :string
|
13
|
+
#
|
14
|
+
# # Shipping Address
|
15
|
+
# t.column :ship_to_first_name, :string
|
16
|
+
# t.column :ship_to_last_name, :string
|
17
|
+
# t.column :ship_to_address_line_1, :string
|
18
|
+
# t.column :ship_to_address_line_2, :string
|
19
|
+
# t.column :ship_to_city, :string
|
20
|
+
# t.column :ship_to_state, :string
|
21
|
+
# t.column :ship_to_postal_code, :string
|
22
|
+
# t.column :ship_to_country, :string
|
23
|
+
#
|
24
|
+
# # Private parts
|
25
|
+
# t.column :customer_ip, :string
|
26
|
+
# t.column :order_number, :string
|
27
|
+
# t.column :error_message, :string
|
28
|
+
#
|
29
|
+
# t.timestamps
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# add_index :order_txns, :order_txn_type_id
|
33
|
+
# add_index :order_txns, [:order_txn_record_id, :order_txn_record_type], :name => 'order_txn_record_idx'
|
34
|
+
#
|
35
|
+
# add_index :order_txns, :order_txn_type_id
|
36
|
+
# add_index :order_txns, [:order_txn_record_id, :order_txn_record_type], :name => 'order_txn_record_idx'
|
37
|
+
|
1
38
|
class OrderTxn < ActiveRecord::Base
|
2
39
|
attr_protected :created_at, :updated_at
|
3
40
|
|
4
|
-
# serialize custom attributes
|
5
|
-
is_json :custom_fields
|
6
|
-
|
7
41
|
acts_as_biz_txn_event
|
8
42
|
|
9
43
|
belongs_to :order_txn_record, :polymorphic => true
|
10
|
-
has_many
|
11
|
-
has_many
|
44
|
+
has_many :order_line_items, :dependent => :destroy
|
45
|
+
has_many :charge_lines, :as => :charged_item, :dependent => :destroy
|
12
46
|
|
13
47
|
alias :line_items :order_line_items
|
14
|
-
|
48
|
+
|
15
49
|
# validation
|
16
50
|
validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :update, :allow_nil => true
|
51
|
+
validates :order_number, {uniqueness: true, :allow_nil => true}
|
52
|
+
|
53
|
+
class << self
|
54
|
+
#find a order by given biz txn party role iid and party
|
55
|
+
def find_by_party_role(biz_txn_party_role_type_iid, party)
|
56
|
+
BizTxnPartyRole.where('party_id = ? and biz_txn_party_role_type_id = ?', party.id, BizTxnPartyRoleType.find_by_internal_identifier(biz_txn_party_role_type_iid).id).all.collect { |item| item.biz_txn_event.biz_txn_record }
|
57
|
+
end
|
58
|
+
|
59
|
+
def next_order_number
|
60
|
+
max_id = maximum('id')
|
61
|
+
|
62
|
+
current_order = where(OrderTxn.arel_table[:order_number].matches("%#{max_id}%")).first
|
17
63
|
|
18
|
-
|
19
|
-
|
20
|
-
|
64
|
+
if current_order
|
65
|
+
while current_order
|
66
|
+
max_id = max_id + 1
|
67
|
+
current_order = where(OrderTxn.arel_table[:order_number].matches("%#{max_id}%")).first
|
68
|
+
end
|
69
|
+
else
|
70
|
+
if max_id
|
71
|
+
max_id = max_id + 1
|
72
|
+
else
|
73
|
+
max_id = 1
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
"#{max_id}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# helper method to get dba_organization related to this order_txn
|
82
|
+
def dba_organization
|
83
|
+
find_party_by_role('dba_org')
|
21
84
|
end
|
22
85
|
|
23
86
|
# get the total charges for an order.
|
24
87
|
# The total will be returned as Money.
|
25
|
-
# There may be multiple Monies
|
88
|
+
# There may be multiple Monies associated with an order, such as points and
|
26
89
|
# dollars. To handle this, the method should return an array of Monies
|
27
|
-
#
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
90
|
+
# if a currency is passed in return the amount for only that currency
|
91
|
+
def total_amount(currency=Currency.usd)
|
92
|
+
if currency and currency.is_a?(String)
|
93
|
+
currency = Currency.send(currency)
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
charges = {"USD" => {amount: 0}}
|
98
|
+
# get any charges directly on this order_txn or on order_line_items
|
99
|
+
charge_lines.each do |charge|
|
100
|
+
charge_money = charge.money
|
101
|
+
|
102
|
+
total_by_currency = charges[charge_money.currency.internal_identifier]
|
103
|
+
unless total_by_currency
|
104
|
+
total_by_currency = {
|
105
|
+
amount: 0
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
total_by_currency[:amount] += charge_money.amount unless charge_money.amount.nil?
|
110
|
+
|
111
|
+
charges[charge_money.currency.internal_identifier] = total_by_currency
|
112
|
+
end
|
113
|
+
|
114
|
+
# TODO currency will eventually need to be accounted for here.
|
115
|
+
charges["USD"][:amount] += line_items.sum(&:total_amount).round(2)
|
116
|
+
|
117
|
+
# add tax
|
118
|
+
charges["USD"][:amount] += (self.sales_tax.nil? ? 0 : self.sales_tax)
|
119
|
+
|
120
|
+
if charges.empty?
|
121
|
+
0
|
122
|
+
else
|
123
|
+
# if currency was based only return that amount
|
124
|
+
# if there is only one currency then return that amount
|
125
|
+
# if there is more than once currency return the hash
|
126
|
+
if currency
|
127
|
+
charges[currency.internal_identifier][:amount].round(2)
|
38
128
|
else
|
39
|
-
|
40
|
-
cur_total.amount += cur_money.amount if !cur_money.amount.nil?
|
129
|
+
charges
|
41
130
|
end
|
42
|
-
total_hash[cur_money.currency.internal_identifier] = cur_total
|
43
131
|
end
|
44
|
-
return total_hash.values
|
45
132
|
end
|
46
133
|
|
47
|
-
|
48
|
-
|
134
|
+
def sub_total(currency=Currency.usd)
|
135
|
+
line_items.collect { |item| item.total_amount(currency) }.inject(:+)
|
136
|
+
end
|
137
|
+
|
138
|
+
# gets the total amount of payments made against this order via charge line payments
|
139
|
+
def total_payment_amount
|
140
|
+
amount = all_charge_lines.collect(&:total_payments).inject(:+)
|
141
|
+
if amount.nil?
|
142
|
+
0
|
143
|
+
else
|
144
|
+
amount
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
# gets total amount due (total_amount - total_payments)
|
150
|
+
# only returns Currency USD
|
151
|
+
def total_amount_due
|
152
|
+
if total_amount(Currency.usd)
|
153
|
+
total_amount(Currency.usd) - total_payment_amount
|
154
|
+
else
|
155
|
+
0
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# get all charge lines on order and order line items
|
160
|
+
def all_charge_lines
|
49
161
|
all_charges = []
|
50
162
|
all_charges.concat(charge_lines)
|
51
163
|
order_line_items.each do |line_item|
|
@@ -54,32 +166,78 @@ class OrderTxn < ActiveRecord::Base
|
|
54
166
|
all_charges
|
55
167
|
end
|
56
168
|
|
57
|
-
|
58
|
-
|
169
|
+
# get the total quantity of this order
|
170
|
+
def total_quantity
|
171
|
+
order_line_items.pluck(:quantity).inject(:+)
|
172
|
+
end
|
173
|
+
|
174
|
+
# calculates tax for each line item and save to sales_tax
|
175
|
+
def calculate_tax(ctx)
|
176
|
+
tax = 0
|
177
|
+
order_line_items.select { |line_item| line_item.taxed? }.each do |line_item|
|
178
|
+
tax += line_item.calculate_tax(ctx)
|
179
|
+
end
|
180
|
+
|
181
|
+
# only get charges that are USD currency
|
182
|
+
charge_lines.joins(:money)
|
183
|
+
.joins(:charge_type)
|
184
|
+
.where('money.currency_id' => Currency.usd)
|
185
|
+
.where('charge_types.taxable' => true).readonly(false).each do |charge_line|
|
186
|
+
tax += charge_line.calculate_tax(ctx)
|
187
|
+
end
|
188
|
+
|
189
|
+
self.sales_tax = tax
|
190
|
+
self.save
|
191
|
+
|
192
|
+
tax
|
59
193
|
end
|
60
194
|
|
61
195
|
#add product_type or product_instance line item
|
62
196
|
def add_line_item(object, reln_type = nil, to_role = nil, from_role = nil)
|
63
|
-
class_name = object.class.name
|
64
197
|
if object.is_a?(Array)
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
198
|
+
class_name = object.first.class.name
|
199
|
+
else
|
200
|
+
class_name = object.class.name
|
201
|
+
end
|
202
|
+
|
203
|
+
case class_name
|
204
|
+
when 'ProductType'
|
205
|
+
add_product_type_line_item(object, reln_type, to_role, from_role)
|
206
|
+
when 'ProductInstance'
|
207
|
+
add_product_instance_line_item(object, reln_type, to_role, from_role)
|
208
|
+
when 'SimpleProductOffer'
|
209
|
+
add_simple_product_offer_line_item(object)
|
210
|
+
end
|
76
211
|
end
|
77
212
|
|
78
|
-
|
213
|
+
def add_simple_product_offer_line_item(simple_product_offer)
|
79
214
|
|
80
|
-
|
215
|
+
line_item = get_line_item_for_simple_product_offer(simple_product_offer)
|
81
216
|
|
82
|
-
|
217
|
+
product_type = simple_product_offer.product_type
|
218
|
+
|
219
|
+
if line_item
|
220
|
+
ActiveRecord::Base.transaction do
|
221
|
+
line_item.quantity += 1
|
222
|
+
line_item.save
|
223
|
+
end
|
224
|
+
else
|
225
|
+
ActiveRecord::Base.transaction do
|
226
|
+
line_item = OrderLineItem.new
|
227
|
+
line_item.product_type = product_type
|
228
|
+
line_item.product_offer = simple_product_offer.product_offer
|
229
|
+
line_item.sold_price = simple_product_offer.get_current_simple_plan.money_amount
|
230
|
+
line_item.quantity = 1
|
231
|
+
line_item.save
|
232
|
+
line_items << line_item
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
line_item
|
237
|
+
end
|
238
|
+
|
239
|
+
def add_product_type_line_item(product_type, reln_type = nil, to_role = nil, from_role = nil)
|
240
|
+
if (product_type.is_a?(Array))
|
83
241
|
if (product_type.size == 0)
|
84
242
|
return
|
85
243
|
elsif (product_type.size == 1)
|
@@ -107,17 +265,32 @@ class OrderTxn < ActiveRecord::Base
|
|
107
265
|
product_type_for_line_item = product_type
|
108
266
|
end
|
109
267
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
268
|
+
line_item = get_line_item_for_product_type(product_type_for_line_item)
|
269
|
+
|
270
|
+
if line_item
|
271
|
+
ActiveRecord::Base.transaction do
|
272
|
+
line_item.quantity += 1
|
273
|
+
line_item.save
|
274
|
+
end
|
275
|
+
else
|
276
|
+
ActiveRecord::Base.transaction do
|
277
|
+
line_item = OrderLineItem.new
|
278
|
+
line_item.product_type = product_type_for_line_item
|
279
|
+
line_item.sold_price = product_type_for_line_item.get_current_simple_plan.money_amount
|
280
|
+
line_item.quantity = 1
|
281
|
+
line_item.save
|
282
|
+
line_items << line_item
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
line_item
|
287
|
+
end
|
115
288
|
|
116
289
|
def add_product_instance_line_item(product_instance, reln_type = nil, to_role = nil, from_role = nil)
|
117
290
|
|
118
291
|
li = OrderLineItem.new
|
119
292
|
|
120
|
-
if(product_instance.is_a?(Array))
|
293
|
+
if (product_instance.is_a?(Array))
|
121
294
|
if (product_instance.size == 0)
|
122
295
|
return
|
123
296
|
elsif (product_instance.size == 1)
|
@@ -149,13 +322,24 @@ class OrderTxn < ActiveRecord::Base
|
|
149
322
|
li.product_instance = product_instance_for_line_item
|
150
323
|
self.line_items << li
|
151
324
|
li.save
|
152
|
-
|
325
|
+
|
326
|
+
li
|
327
|
+
end
|
328
|
+
|
329
|
+
def get_line_item_for_product_type(product_type)
|
330
|
+
line_items.detect { |oli| oli.product_type == product_type }
|
331
|
+
end
|
332
|
+
|
333
|
+
def get_line_item_for_simple_product_offer(simple_product_offer)
|
334
|
+
line_items.detect { |oli| oli.product_offer.product_offer_record == simple_product_offer }
|
153
335
|
end
|
154
336
|
|
155
337
|
def find_party_by_role(role_type_iid)
|
156
338
|
party = nil
|
157
339
|
|
158
|
-
tpr = self.root_txn.biz_txn_party_roles.
|
340
|
+
tpr = self.root_txn.biz_txn_party_roles.includes(:biz_txn_party_role_type)
|
341
|
+
.where('biz_txn_party_role_types.internal_identifier = ?', role_type_iid).first
|
342
|
+
|
159
343
|
party = tpr.party unless tpr.nil?
|
160
344
|
|
161
345
|
party
|
@@ -172,9 +356,23 @@ class OrderTxn < ActiveRecord::Base
|
|
172
356
|
self.ship_to_city = shipping_address.city
|
173
357
|
self.ship_to_state = shipping_address.state
|
174
358
|
self.ship_to_postal_code = shipping_address.zip
|
175
|
-
#self.ship_to_country_name = shipping_address.country_name
|
176
|
-
|
359
|
+
# self.ship_to_country_name = shipping_address.country_name
|
360
|
+
self.ship_to_country = shipping_address.country
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
# Get shipping info formatted for HTML
|
365
|
+
#
|
366
|
+
def shipping_info
|
367
|
+
info = %(#{ship_to_first_name} #{ship_to_last_name}<br>#{ship_to_address_line_1})
|
368
|
+
|
369
|
+
if ship_to_address_line_2.present?
|
370
|
+
info << "<br>#{ship_to_address_line_2}"
|
177
371
|
end
|
372
|
+
|
373
|
+
info << %(<br>#{ship_to_city} #{ship_to_state} #{ship_to_postal_code}<br>#{ship_to_country})
|
374
|
+
|
375
|
+
info
|
178
376
|
end
|
179
377
|
|
180
378
|
def set_billing_info(party)
|
@@ -191,11 +389,25 @@ class OrderTxn < ActiveRecord::Base
|
|
191
389
|
self.bill_to_city = billing_address.city
|
192
390
|
self.bill_to_state = billing_address.state
|
193
391
|
self.bill_to_postal_code = billing_address.zip
|
194
|
-
#self.bill_to_country_name = billing_address.country_name
|
195
|
-
|
392
|
+
# self.bill_to_country_name = billing_address.country_name
|
393
|
+
self.bill_to_country = billing_address.country
|
196
394
|
end
|
197
395
|
end
|
198
396
|
|
397
|
+
# Get billing info formatted for HTML
|
398
|
+
#
|
399
|
+
def billing_info
|
400
|
+
info = %(#{bill_to_first_name} #{bill_to_last_name}<br>#{bill_to_address_line_1}<br>)
|
401
|
+
|
402
|
+
if bill_to_address_line_2.present?
|
403
|
+
info << "<br>#{bill_to_address_line_2}"
|
404
|
+
end
|
405
|
+
|
406
|
+
info << %(<br>#{bill_to_city} #{bill_to_state} #{bill_to_postal_code}<br>#{bill_to_country})
|
407
|
+
|
408
|
+
info
|
409
|
+
end
|
410
|
+
|
199
411
|
def determine_txn_party_roles
|
200
412
|
#Template Method
|
201
413
|
end
|
@@ -212,8 +424,8 @@ class OrderTxn < ActiveRecord::Base
|
|
212
424
|
#BizTxnEvent Overrides
|
213
425
|
###############################################################################
|
214
426
|
def create_dependent_txns
|
215
|
-
|
216
|
-
|
427
|
+
#Template Method
|
428
|
+
end
|
217
429
|
|
218
430
|
################################################################
|
219
431
|
################################################################
|
@@ -274,9 +486,9 @@ class OrderTxn < ActiveRecord::Base
|
|
274
486
|
unless use_delayed_jobs
|
275
487
|
authorized_txns.each do |financial_txn|
|
276
488
|
result = financial_txn.capture(credit_card, gateway, gateway_options)
|
277
|
-
unless(result[:success])
|
489
|
+
unless (result[:success])
|
278
490
|
all_txns_captured = false
|
279
|
-
gateway_message
|
491
|
+
gateway_message = result[:gateway_message]
|
280
492
|
break
|
281
493
|
end
|
282
494
|
end
|
@@ -312,7 +524,7 @@ class OrderTxn < ActiveRecord::Base
|
|
312
524
|
unless use_delayed_jobs
|
313
525
|
authorized_txns.each do |financial_txn|
|
314
526
|
result = financial_txn.reverse_authorization(credit_card, gateway, gateway_options)
|
315
|
-
unless(result[:success])
|
527
|
+
unless (result[:success])
|
316
528
|
all_txns_rolledback = false
|
317
529
|
end
|
318
530
|
end
|
@@ -379,4 +591,45 @@ class OrderTxn < ActiveRecord::Base
|
|
379
591
|
return result, message, authorized_txns
|
380
592
|
end
|
381
593
|
|
594
|
+
def clone
|
595
|
+
ActiveRecord::Base.transaction do
|
596
|
+
order_txn_dup = dup
|
597
|
+
order_txn_dup.order_txn_record_id = nil
|
598
|
+
order_txn_dup.order_txn_record_type = nil
|
599
|
+
order_txn_dup.order_number = OrderTxn.next_order_number
|
600
|
+
order_txn_dup.error_message = nil
|
601
|
+
order_txn_dup.payment_gateway_txn_id = nil
|
602
|
+
order_txn_dup.credit_card_id = nil
|
603
|
+
order_txn_dup.initialize_biz_txn_event
|
604
|
+
order_txn_dup.biz_txn_event.description = self.biz_txn_event.description
|
605
|
+
|
606
|
+
# add a relationship describing the original and the clone
|
607
|
+
biz_txn_rel_type = BizTxnRelType.find_or_create('cloned_from', 'Cloned From', nil)
|
608
|
+
BizTxnRelationship.create(txn_event_to: self.root_txn,
|
609
|
+
txn_event_from: order_txn_dup.root_txn,
|
610
|
+
biz_txn_rel_type: biz_txn_rel_type)
|
611
|
+
|
612
|
+
|
613
|
+
order_line_item_rel_type = OrderLineItemRelType.find_or_create('cloned_from', 'Cloned From', nil)
|
614
|
+
|
615
|
+
self.order_line_items.each do |order_line_item|
|
616
|
+
order_line_item_clone = order_line_item.clone
|
617
|
+
order_txn_dup.order_line_items << order_line_item_clone
|
618
|
+
|
619
|
+
OrderLineItemRelationship.create(order_line_item_from: order_line_item_clone,
|
620
|
+
order_line_item_to: order_line_item,
|
621
|
+
order_line_item_rel_type: order_line_item_rel_type)
|
622
|
+
|
623
|
+
end
|
624
|
+
order_txn_dup.save!
|
625
|
+
order_txn_dup.current_status = self.current_status
|
626
|
+
|
627
|
+
order_txn_dup
|
628
|
+
end
|
629
|
+
|
630
|
+
end
|
631
|
+
|
632
|
+
def to_label
|
633
|
+
self.order_number
|
634
|
+
end
|
382
635
|
end
|