erp_commerce 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/GPL-3-LICENSE +674 -0
  2. data/README.rdoc +2 -0
  3. data/Rakefile +32 -0
  4. data/app/assets/javascripts/erp_commerce/application.js +9 -0
  5. data/app/assets/stylesheets/erp_commerce/application.css +7 -0
  6. data/app/controllers/erp_commerce/application_controller.rb +4 -0
  7. data/app/helpers/erp_commerce/application_helper.rb +4 -0
  8. data/app/models/credit_card.rb +54 -0
  9. data/app/models/credit_card_account.rb +4 -0
  10. data/app/models/credit_card_account_party_role.rb +8 -0
  11. data/app/models/credit_card_account_purpose.rb +6 -0
  12. data/app/models/credit_card_token.rb +12 -0
  13. data/app/models/extensions/charge_line.rb +3 -0
  14. data/app/models/extensions/currency.rb +3 -0
  15. data/app/models/extensions/financial_txn.rb +3 -0
  16. data/app/models/extensions/order_txn.rb +3 -0
  17. data/app/models/extensions/party.rb +21 -0
  18. data/app/models/extensions/product_instance.rb +5 -0
  19. data/app/models/extensions/product_type.rb +3 -0
  20. data/app/models/fee.rb +7 -0
  21. data/app/models/fee_type.rb +4 -0
  22. data/app/models/payment.rb +38 -0
  23. data/app/models/payment_gateway.rb +4 -0
  24. data/app/models/payment_gateway_action.rb +2 -0
  25. data/app/models/price.rb +25 -0
  26. data/app/models/price_component.rb +8 -0
  27. data/app/models/price_component_type.rb +3 -0
  28. data/app/models/pricing_plan.rb +37 -0
  29. data/app/models/pricing_plan_assignment.rb +6 -0
  30. data/app/models/pricing_plan_component.rb +36 -0
  31. data/app/models/valid_price_plan_component.rb +8 -0
  32. data/app/views/layouts/erp_commerce/application.html.erb +14 -0
  33. data/app/widgets/orders/base.rb +40 -0
  34. data/app/widgets/orders/javascript/orders.js +11 -0
  35. data/app/widgets/orders/views/index.html.erb +63 -0
  36. data/app/widgets/product_catalog/base.rb +56 -0
  37. data/app/widgets/product_catalog/javascript/product_catalog.js +62 -0
  38. data/app/widgets/product_catalog/views/add_to_cart.html.erb +10 -0
  39. data/app/widgets/product_catalog/views/index.html.erb +69 -0
  40. data/app/widgets/product_catalog/views/show.html.erb +23 -0
  41. data/app/widgets/shopping_cart/base.rb +178 -0
  42. data/app/widgets/shopping_cart/javascript/shopping_cart.js +107 -0
  43. data/app/widgets/shopping_cart/views/cart_items.html.erb +83 -0
  44. data/app/widgets/shopping_cart/views/confirmation.html.erb +10 -0
  45. data/app/widgets/shopping_cart/views/demographics.html.erb +142 -0
  46. data/app/widgets/shopping_cart/views/login.html.erb +1 -0
  47. data/app/widgets/shopping_cart/views/payment.html.erb +81 -0
  48. data/app/widgets/shopping_cart/views/price_summary.html.erb +4 -0
  49. data/config/routes.rb +2 -0
  50. data/db/data_migrations/20101011152441_payment_gateway_actions.rb +27 -0
  51. data/db/migrate/20100823174238_erp_commerce_base.rb +174 -0
  52. data/db/migrate/20100913154134_setup_payments.rb +57 -0
  53. data/db/migrate/20101103132342_pricing_migrations.rb +169 -0
  54. data/db/migrate/20110921150854_create_fees.rb +50 -0
  55. data/lib/erp_commerce/active_merchant_wrappers/brain_tree_gateway_wrapper.rb +66 -0
  56. data/lib/erp_commerce/active_merchant_wrappers/credit_card_validation.rb +34 -0
  57. data/lib/erp_commerce/active_merchant_wrappers.rb +2 -0
  58. data/lib/erp_commerce/engine.rb +15 -0
  59. data/lib/erp_commerce/extensions/active_record/acts_as_fee.rb +64 -0
  60. data/lib/erp_commerce/extensions/active_record/acts_as_priceable.rb +57 -0
  61. data/lib/erp_commerce/extensions.rb +2 -0
  62. data/lib/erp_commerce/order_helper.rb +254 -0
  63. data/lib/erp_commerce/version.rb +3 -0
  64. data/lib/erp_commerce.rb +8 -0
  65. data/lib/tasks/erp_commerce_tasks.rake +4 -0
  66. data/spec/dummy/Rakefile +7 -0
  67. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  68. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  69. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  70. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  71. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  72. data/spec/dummy/config/application.rb +49 -0
  73. data/spec/dummy/config/boot.rb +10 -0
  74. data/spec/dummy/config/database.yml +8 -0
  75. data/spec/dummy/config/environment.rb +5 -0
  76. data/spec/dummy/config/environments/spec.rb +27 -0
  77. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  78. data/spec/dummy/config/initializers/inflections.rb +10 -0
  79. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  80. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  81. data/spec/dummy/config/initializers/session_store.rb +8 -0
  82. data/spec/dummy/config/initializers/wrap_parameters.rb +12 -0
  83. data/spec/dummy/config/locales/en.yml +5 -0
  84. data/spec/dummy/config/routes.rb +3 -0
  85. data/spec/dummy/config.ru +4 -0
  86. data/spec/dummy/public/404.html +26 -0
  87. data/spec/dummy/public/422.html +26 -0
  88. data/spec/dummy/public/500.html +26 -0
  89. data/spec/dummy/public/favicon.ico +0 -0
  90. data/spec/dummy/script/rails +6 -0
  91. data/spec/models/credit_card_account_party_role_spec.rb +11 -0
  92. data/spec/models/credit_card_account_purpose_spec.rb +11 -0
  93. data/spec/models/credit_card_account_spec.rb +11 -0
  94. data/spec/models/credit_card_spec.rb +11 -0
  95. data/spec/models/fee_spec.rb +11 -0
  96. data/spec/models/fee_type_spec.rb +11 -0
  97. data/spec/models/payment_gateway_action_spec.rb +11 -0
  98. data/spec/models/payment_gateway_spec.rb +11 -0
  99. data/spec/models/payment_spec.rb +11 -0
  100. data/spec/models/price_component_spec.rb +11 -0
  101. data/spec/models/price_component_type_spec.rb +11 -0
  102. data/spec/models/price_spec.rb +11 -0
  103. data/spec/models/pricing_plan_assignment_spec.rb +11 -0
  104. data/spec/models/pricing_plan_component_spec.rb +11 -0
  105. data/spec/models/pricing_plan_spec.rb +11 -0
  106. data/spec/models/valid_price_plan_component_spec.rb +11 -0
  107. data/spec/spec_helper.rb +60 -0
  108. metadata +285 -0
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'ErpCommerce'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+ Bundler::GemHelper.install_tasks
27
+
28
+ require "rspec/core/rake_task"
29
+ RSpec::Core::RakeTask.new(:spec)
30
+ task :default => :spec
31
+
32
+
@@ -0,0 +1,9 @@
1
+ // This is a manifest file that'll be compiled into including all the files listed below.
2
+ // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
3
+ // be included in the compiled file accessible from http://example.com/assets/application.js
4
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
+ // the compiled file.
6
+ //
7
+ //= require jquery
8
+ //= require jquery_ujs
9
+ //= require_tree .
@@ -0,0 +1,7 @@
1
+ /*
2
+ * This is a manifest file that'll automatically include all the stylesheets available in this directory
3
+ * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
4
+ * the top of the compiled file, but it's generally better to create a new file per style scope.
5
+ *= require_self
6
+ *= require_tree .
7
+ */
@@ -0,0 +1,4 @@
1
+ module ErpCommerce
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ErpCommerce
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,54 @@
1
+ class CreditCard < ActiveRecord::Base
2
+
3
+ require 'attr_encrypted'
4
+
5
+ belongs_to :postal_address
6
+ has_many :payments
7
+ belongs_to :credit_card_account_party_role
8
+
9
+ #the function EncryptionKey.get_key is meant to be overridden to provide a means for implementations to specify their
10
+ #own encryption schemes and locations. It will default to a simple string for development and testing
11
+ attr_encrypted :private_card_number, :key => EncryptionKey.get_key, :marshall => true, :attribute => :crypted_private_card_number
12
+
13
+ # These methods are exposed for the purposes of displaying a version of the card number
14
+ # string containing the last four digits of the card number. The idea is to make it
15
+ # painfully obvious when any coder is using the private_card_number, which should
16
+ # be used only in limited circumstances.
17
+
18
+ def card_number
19
+ if self.private_card_number
20
+ n = self.private_card_number
21
+ 'xxxx-xxxx-xxxx-' + n[n.length-4..n.length]
22
+ else
23
+ ''
24
+ end
25
+ end
26
+
27
+ # Note that the setter method allows the same variable to be set, and delegates through
28
+ # the encryption process
29
+
30
+ def card_number=(num)
31
+ self.private_card_number=num
32
+ end
33
+
34
+ def to_label
35
+ "#{card_type}: #{card_number}"
36
+ end
37
+
38
+ def to_s
39
+ "#{card_type}: #{card_number}"
40
+ end
41
+
42
+ def cardholder
43
+ return self.credit_card_account_party_role.party
44
+ end
45
+
46
+ def before_create
47
+ token = CreditCardToken.new
48
+ self.credit_card_token = token.cc_token.strip
49
+ end
50
+
51
+ end
52
+
53
+
54
+
@@ -0,0 +1,4 @@
1
+ class CreditCardAccount < ActiveRecord::Base
2
+ acts_as_biz_txn_account
3
+ belongs_to :credit_card_account_purpose
4
+ end
@@ -0,0 +1,8 @@
1
+ class CreditCardAccountPartyRole < ActiveRecord::Base
2
+
3
+ belongs_to :credit_card_account, :class_name => "CreditCardAccount"
4
+ belongs_to :role_type
5
+ belongs_to :party
6
+ has_one :credit_card, :class_name => "CreditCard", :dependent => :destroy
7
+
8
+ end
@@ -0,0 +1,6 @@
1
+ class CreditCardAccountPurpose < ActiveRecord::Base
2
+ acts_as_nested_set
3
+ include ErpTechSvcs::Utils::DefaultNestedSetMethods
4
+
5
+ has_many :credit_card_accounts
6
+ end
@@ -0,0 +1,12 @@
1
+ require 'uuid'
2
+
3
+ class CreditCardToken
4
+ @cc_token
5
+
6
+ def initialize
7
+ uuid = UUID.new
8
+ @cc_token = uuid.generate(:compact).upcase
9
+ end
10
+
11
+ attr_accessor :cc_token
12
+ end
@@ -0,0 +1,3 @@
1
+ ChargeLine.class_eval do
2
+ has_one :price_component, :as => :priced_component
3
+ end
@@ -0,0 +1,3 @@
1
+ Currency.class_eval do
2
+ has_many :pricing_plans
3
+ end
@@ -0,0 +1,3 @@
1
+ FinancialTxn.class_eval do
2
+ has_many :payments
3
+ end
@@ -0,0 +1,3 @@
1
+ OrderTxn.class_eval do
2
+ acts_as_priceable
3
+ end
@@ -0,0 +1,21 @@
1
+ Party.class_eval do
2
+
3
+ #credit cards
4
+ has_many :credit_card_account_party_roles
5
+
6
+ # return primary credit card
7
+ def primary_credit_card
8
+ return get_credit_card('primary')
9
+ end
10
+
11
+ # return credit card by credit card account purpose using internal identifier
12
+ def get_credit_card(internal_identifier)
13
+ self.credit_card_account_party_roles.each do |ccapr|
14
+ if ccapr.credit_card_account.credit_card_account_purpose.internal_identifier.eql?(internal_identifier)
15
+ return ccapr.credit_card
16
+ end
17
+ end
18
+ return nil
19
+ end
20
+
21
+ end
@@ -0,0 +1,5 @@
1
+ ProductInstance.class_eval do
2
+
3
+ acts_as_priceable
4
+
5
+ end
@@ -0,0 +1,3 @@
1
+ ProductType.class_eval do
2
+ acts_as_priceable
3
+ end
data/app/models/fee.rb ADDED
@@ -0,0 +1,7 @@
1
+ class Fee < ActiveRecord::Base
2
+
3
+ belongs_to :fee_record, :polymorphic => true
4
+ belongs_to :money
5
+ belongs_to :fee_type
6
+
7
+ end
@@ -0,0 +1,4 @@
1
+ class FeeType < ActiveRecord::Base
2
+ acts_as_nested_set
3
+ include ErpTechSvcs::Utils::DefaultNestedSetMethods
4
+ end
@@ -0,0 +1,38 @@
1
+ class Payment < ActiveRecord::Base
2
+ include AASM
3
+
4
+ belongs_to :financial_txn
5
+ has_many :payment_gateways
6
+
7
+ aasm_column :current_state
8
+
9
+ aasm_initial_state :pending
10
+
11
+ aasm_state :pending
12
+ aasm_state :declined
13
+ aasm_state :authorized
14
+ aasm_state :captured
15
+ aasm_state :authorization_reversed
16
+
17
+ aasm_event :authorize do
18
+ transitions :to => :authorized, :from => [:pending]
19
+ end
20
+
21
+ aasm_event :purchase do
22
+ transitions :to => :captured, :from => [:authorized, :pending]
23
+ end
24
+
25
+ aasm_event :decline do
26
+ transitions :to => :declined, :from => [:pending]
27
+ end
28
+
29
+ aasm_event :capture do
30
+ transitions :to => :captured, :from => [:authorized]
31
+ end
32
+
33
+ aasm_event :reverse_authorization do
34
+ transitions :to => :authorization_reversed, :from => [:authorized]
35
+ end
36
+
37
+
38
+ end
@@ -0,0 +1,4 @@
1
+ class PaymentGateway < ActiveRecord::Base
2
+ belongs_to :payment_gateway_action
3
+ belongs_to :payment
4
+ end
@@ -0,0 +1,2 @@
1
+ class PaymentGatewayAction < ActiveRecord::Base
2
+ end
@@ -0,0 +1,25 @@
1
+ class Price < ActiveRecord::Base
2
+
3
+ belongs_to :pricing_plan
4
+ belongs_to :priced_item, :polymorphic => true
5
+ has_many :price_components, :dependent => :destroy
6
+ belongs_to :money
7
+
8
+ alias :components :price_components
9
+
10
+ def get_price_components_by_type(type_iid)
11
+ self.price_components.select{|pc| pc.pricing_plan_component.price_component_type.internal_identifier == type_iid}
12
+ end
13
+
14
+ def get_total_by_type(type_iid)
15
+ total = 0
16
+
17
+ components = self.price_components.select{|pc| pc.pricing_plan_component.price_component_type.internal_identifier == type_iid}
18
+ components.each do |component|
19
+ total = total + component.money.amount
20
+ end
21
+
22
+ total
23
+ end
24
+
25
+ end
@@ -0,0 +1,8 @@
1
+ class PriceComponent < ActiveRecord::Base
2
+
3
+ belongs_to :priced_component, :polymorphic => true
4
+ belongs_to :pricing_plan_component
5
+ belongs_to :price
6
+ belongs_to :money
7
+
8
+ end
@@ -0,0 +1,3 @@
1
+ class PriceComponentType < ActiveRecord::Base
2
+ has_many :pricing_plan_components
3
+ end
@@ -0,0 +1,37 @@
1
+ class PricingPlan < ActiveRecord::Base
2
+
3
+ has_many :valid_price_plan_components
4
+ has_many :pricing_plan_components, :through => :valid_price_plan_components
5
+ belongs_to :currency
6
+
7
+ alias :components :pricing_plan_components
8
+
9
+ def get_price( rule_ctx = nil )
10
+
11
+ price = Price.new
12
+ price.pricing_plan = self
13
+
14
+ #first check if this is a simple amount if so get the amount.
15
+ if self.is_simple_amount
16
+ price.money = Money.new(:amount => self.money_amount, :currency => self.currency)
17
+
18
+ #second check if a pricing calculation exists if so use it.
19
+ elsif !self.pricing_calculation.nil?
20
+ rule_ctx[:pricing_plan] = self
21
+ rule_ctx[:price] = price
22
+ eval(self.pricing_calculation)
23
+
24
+ #finanlly if this is not a simple amount and has no pricing calcuation use the price components associated to this plan
25
+ else
26
+ self.pricing_plan_components.each do |pricing_plan_component|
27
+ price_component = pricing_plan_component.get_price_component(rule_ctx)
28
+ price.components << price_component
29
+ end
30
+ end
31
+
32
+ price.description = self.description
33
+
34
+ price
35
+ end
36
+
37
+ end
@@ -0,0 +1,6 @@
1
+ class PricingPlanAssignment < ActiveRecord::Base
2
+
3
+ belongs_to :pricing_plan
4
+ belongs_to :priceable_item, :polymorphic => true
5
+
6
+ end
@@ -0,0 +1,36 @@
1
+ class PricingPlanComponent < ActiveRecord::Base
2
+
3
+ #these relationships essentially mean that pricing plan components can
4
+ #be shared across pricing plan. This is accomplished by using a cross-reference
5
+ #table called 'valid_price_plan_components'
6
+ has_many :valid_price_plan_components
7
+ has_many :pricing_plans, :through => :valid_price_plan_components
8
+ belongs_to :price_component_type
9
+ belongs_to :currency
10
+
11
+ def get_price_component( rule_ctx = nil )
12
+
13
+ #this will be relaced by an execution of the stored 'matching_rule' and 'pricing_calculation'
14
+ #although it might make sense to have an 'is_simple' flag and corresponding value so the price
15
+ #component can simply create one price component with one float value without invoking a rules
16
+ #engine or the interpreter
17
+
18
+ if self.is_simple_amount
19
+ component_amount = self.money_amount
20
+ else
21
+ component_amount = eval(self.pricing_calculation)
22
+ end
23
+
24
+ money = Money.new(:description => self.description, :amount => component_amount, :currency => self.currency)
25
+
26
+ price_component = PriceComponent.new(
27
+ :money => money,
28
+ :pricing_plan_component => self,
29
+ :description => self.description
30
+ )
31
+
32
+ price_component
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,8 @@
1
+ class ValidPricePlanComponent < ActiveRecord::Base
2
+
3
+ #cross-reference table that allows the association of pricing plan components
4
+ #to multiple pricing plans
5
+ belongs_to :pricing_plan
6
+ belongs_to :pricing_plan_component
7
+
8
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>ErpCommerce</title>
5
+ <%= stylesheet_link_tag "erp_commerce/application" %>
6
+ <%= javascript_include_tag "erp_commerce/application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,40 @@
1
+ module Widgets
2
+ module Orders
3
+ class Base < ErpApp::Widgets::Base
4
+ def index
5
+ @orders = OrderTxn.find_by_party_role('buyer', current_user.party)
6
+ @orders = @orders.select{|order| order.status != "Initialized"}
7
+ render
8
+ end
9
+
10
+ #should not be modified
11
+ #modify at your own risk
12
+ def locate
13
+ File.dirname(__FILE__)
14
+ end
15
+
16
+ class << self
17
+ def title
18
+ "Orders"
19
+ end
20
+
21
+ def views_location
22
+ File.join(File.dirname(__FILE__),"/views")
23
+ end
24
+
25
+ def widget_name
26
+ File.basename(File.dirname(__FILE__))
27
+ end
28
+
29
+ def base_layout
30
+ begin
31
+ file = File.join(File.dirname(__FILE__),"/views/layouts/base.html.erb")
32
+ IO.read(file)
33
+ rescue
34
+ return nil
35
+ end
36
+ end
37
+ end
38
+ end#Base
39
+ end#Orders
40
+ end#Widgets
@@ -0,0 +1,11 @@
1
+ Compass.ErpApp.Widgets.Orders = {
2
+ add:function(){
3
+ Ext.getCmp('knitkitCenterRegion').addContentToActiveCodeMirror("<%= render_widget :orders %>");
4
+ }
5
+ }
6
+
7
+ Compass.ErpApp.Widgets.AvailableWidgets.push({
8
+ name:'Orders',
9
+ iconUrl:'/images/icons/package/package_48x48.png',
10
+ onClick:Compass.ErpApp.Widgets.Orders.add
11
+ });
@@ -0,0 +1,63 @@
1
+ <style type="text/css">
2
+ #products-view {
3
+ font-family:'Lucida Grande','Lucida Sans Unicode',sans-serif;
4
+ text-align:center;
5
+ font-size:14px;
6
+ width:100%;
7
+ border-collapse: collapse;
8
+ border: 2px solid #CCCCCC;
9
+ }
10
+
11
+ #products-view a {
12
+ text-decoration:none;
13
+ }
14
+
15
+ #products-view img {
16
+ height:60px;
17
+ width:65px;
18
+ padding-right:15px;
19
+ }
20
+
21
+ #products-view div
22
+ {
23
+ float:left;
24
+ text-align:left;
25
+ }
26
+
27
+ #products-view th {
28
+ padding: 0 0.5em;
29
+ height:30px;
30
+ text-align:center;
31
+ background:url("/images/knitkit/footer.png") repeat-x scroll 0 0 #29425E;
32
+ }
33
+
34
+ .highlight:hover
35
+ {
36
+ background-color:#FFFFEE;
37
+ }
38
+
39
+ #products-view td+td {
40
+ border-left: 1px solid #CCC;
41
+ text-align: center;
42
+ }
43
+ </style>
44
+ <table id="products-view">
45
+ <thead>
46
+ <tr>
47
+ <th>Order Number</th>
48
+ <th>Order At</th>
49
+ <th>Status</th>
50
+ <th>Amount</th>
51
+ </tr>
52
+ </thead>
53
+ <tbody>
54
+ <% @orders.each do |order| %>
55
+ <tr>
56
+ <td><%=order.order_number%></td>
57
+ <td><%=order.created_at.to_time.strftime("%m/%d/%Y %I:%M%p")%></td>
58
+ <td><%=order.status%></td>
59
+ <td><%=number_to_currency(order.get_total_charges.sum{|money| money.amount})%></td>
60
+ </tr>
61
+ <% end %>
62
+ </tbody>
63
+ </table>
@@ -0,0 +1,56 @@
1
+ module Widgets
2
+ module ProductCatalog
3
+ class Base < ErpApp::Widgets::Base
4
+ def index
5
+ render
6
+ end
7
+
8
+ def back_to_catalog
9
+ render :update => {:id => "#{@uuid}_result", :view => 'index'}
10
+ end
11
+
12
+ def show
13
+ @product_type = ProductType.find(params[:id])
14
+ render :update => {:id => "#{@uuid}_result", :view => 'show'}
15
+ end
16
+
17
+ def add_to_cart
18
+ @product_type = ProductType.find(params[:id])
19
+ @cart_items_url = params[:cart_items_url]
20
+ ErpCommerce::OrderHelper.new(self).add_to_cart(@product_type)
21
+
22
+ render :update => {:id => "#{@uuid}_result", :view => 'add_to_cart'}
23
+ end
24
+
25
+ #should not be modified
26
+ #modify at your own risk
27
+ def locate
28
+ File.dirname(__FILE__)
29
+ end
30
+
31
+ class << self
32
+ def title
33
+ "Product Catalog"
34
+ end
35
+
36
+ def views_location
37
+ File.join(File.dirname(__FILE__),"/views")
38
+ end
39
+
40
+ def widget_name
41
+ File.basename(File.dirname(__FILE__))
42
+ end
43
+
44
+ def base_layout
45
+ begin
46
+ file = File.join(File.dirname(__FILE__),"/views/layouts/base.html.erb")
47
+ IO.read(file)
48
+ rescue
49
+ return nil
50
+ end
51
+ end
52
+ end
53
+ end#Base
54
+ end#ProductCatalog
55
+ end#Widgets
56
+
@@ -0,0 +1,62 @@
1
+ Compass.ErpApp.Widgets.ProductCatalog = {
2
+ add:function(){
3
+ var addProductCatalogWidgetWindow = Ext.create("Ext.window.Window",{
4
+ layout:'fit',
5
+ width:300,
6
+ title:'Add Product Catalog Widget',
7
+ height:100,
8
+ buttonAlign:'center',
9
+ items: Ext.create("Ext.form.Panel",{
10
+ labelWidth: 100,
11
+ frame:false,
12
+ bodyStyle:'padding:5px 5px 0',
13
+ defaults: {
14
+ width: 225
15
+ },
16
+ items: [
17
+ {
18
+ xtype:'textfield',
19
+ fieldLabel:'Cart Items Url',
20
+ name:'cartItemsUrl',
21
+ hidden:false,
22
+ value:'/cart-items'
23
+ }
24
+ ]
25
+ }),
26
+ buttons: [{
27
+ text:'Submit',
28
+ handler:function(button){
29
+ var window = button.findParentByType('window');
30
+ var formPanel = window.query('form')[0];
31
+ var basicForm = formPanel.getForm();
32
+ var cartItemsUrl = basicForm.findField('cartItemsUrl').getValue();
33
+ var data = {
34
+ cartItemsUrl:cartItemsUrl
35
+ };
36
+
37
+ var tpl = new Ext.XTemplate("<%= render_widget :product_catalog,\n",
38
+ " :action => :index,\n",
39
+ " :params => {:cart_items_url => '{cartItemsUrl}'} %>");
40
+
41
+ //add rendered template to center region editor
42
+ Ext.getCmp('knitkitCenterRegion').addContentToActiveCodeMirror(tpl.apply(data));
43
+ addProductCatalogWidgetWindow.close();
44
+ }
45
+ },
46
+ {
47
+ text: 'Close',
48
+ handler: function(){
49
+ addProductCatalogWidgetWindow.close();
50
+ }
51
+ }]
52
+
53
+ });
54
+ addProductCatalogWidgetWindow.show();
55
+ }
56
+ }
57
+
58
+ Compass.ErpApp.Widgets.AvailableWidgets.push({
59
+ name:'Product Catalog',
60
+ iconUrl:'/images/icons/product/product_48x48.png',
61
+ onClick:Compass.ErpApp.Widgets.ProductCatalog.add
62
+ });
@@ -0,0 +1,10 @@
1
+ <%= @product_type.description %>
2
+ <br/>
3
+ <p><%= raw @product_type.find_description_by_iid('long_description').description %></p>
4
+ <br/>
5
+ Added to cart
6
+ <br/>
7
+ <%=link_to_remote 'Continue Shopping', build_widget_url(:index)%> | <a href="<%=@cart_items_url%>">Go to Cart</a>
8
+ <script type="text/javascript">
9
+ Compass.ErpApp.Widgets.refreshWidget('shopping_cart', 'price_summary');
10
+ </script>