erp_commerce 3.0.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.
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>