My-Commerce_core 1.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.
- data/LICENSE +26 -0
- data/README.md +15 -0
- data/app/controllers/admin/adjustments_controller.rb +10 -0
- data/app/controllers/admin/base_controller.rb +63 -0
- data/app/controllers/admin/configurations_controller.rb +2 -0
- data/app/controllers/admin/general_settings_controller.rb +22 -0
- data/app/controllers/admin/images_controller.rb +49 -0
- data/app/controllers/admin/inventory_settings_controller.rb +13 -0
- data/app/controllers/admin/inventory_units_controller.rb +2 -0
- data/app/controllers/admin/line_items_controller.rb +60 -0
- data/app/controllers/admin/mail_methods_controller.rb +8 -0
- data/app/controllers/admin/mail_settings_controller.rb +14 -0
- data/app/controllers/admin/option_types_controller.rb +65 -0
- data/app/controllers/admin/orders_controller.rb +136 -0
- data/app/controllers/admin/overview_controller.rb +14 -0
- data/app/controllers/admin/payment_methods_controller.rb +43 -0
- data/app/controllers/admin/payments_controller.rb +107 -0
- data/app/controllers/admin/product_groups_controller.rb +46 -0
- data/app/controllers/admin/product_properties_controller.rb +10 -0
- data/app/controllers/admin/product_scopes_controller.rb +35 -0
- data/app/controllers/admin/products_controller.rb +113 -0
- data/app/controllers/admin/products_controller.rb~ +114 -0
- data/app/controllers/admin/properties_controller.rb +11 -0
- data/app/controllers/admin/prototypes_controller.rb +26 -0
- data/app/controllers/admin/reports_controller.rb +50 -0
- data/app/controllers/admin/resource_controller.rb +232 -0
- data/app/controllers/admin/return_authorizations_controller.rb +17 -0
- data/app/controllers/admin/shipments_controller.rb +117 -0
- data/app/controllers/admin/shipping_categories_controller.rb +2 -0
- data/app/controllers/admin/shipping_methods_controller.rb +14 -0
- data/app/controllers/admin/states_controller.rb +25 -0
- data/app/controllers/admin/tax_categories_controller.rb +2 -0
- data/app/controllers/admin/tax_rates_controller.rb +22 -0
- data/app/controllers/admin/tax_settings_controller.rb +13 -0
- data/app/controllers/admin/taxonomies_controller.rb +20 -0
- data/app/controllers/admin/taxons_controller.rb +161 -0
- data/app/controllers/admin/trackers_controller.rb +2 -0
- data/app/controllers/admin/users_controller.rb +65 -0
- data/app/controllers/admin/variants_controller.rb +51 -0
- data/app/controllers/admin/zones_controller.rb +23 -0
- data/app/controllers/checkout_controller.rb +97 -0
- data/app/controllers/content_controller.rb +21 -0
- data/app/controllers/locale_controller.rb +14 -0
- data/app/controllers/orders_controller.rb +64 -0
- data/app/controllers/products_controller.rb +39 -0
- data/app/controllers/spree/base_controller.rb +4 -0
- data/app/controllers/states_controller.rb +16 -0
- data/app/controllers/taxons_controller.rb +22 -0
- data/app/helpers/account_helper.rb +2 -0
- data/app/helpers/admin/base_helper.rb +194 -0
- data/app/helpers/admin/inventory_settings_helper.rb +5 -0
- data/app/helpers/admin/navigation_helper.rb +162 -0
- data/app/helpers/admin/orders_helper.rb +22 -0
- data/app/helpers/admin/overview_helper.rb +12 -0
- data/app/helpers/admin/payments_helper.rb +7 -0
- data/app/helpers/admin/product_groups_helper.rb +11 -0
- data/app/helpers/admin/product_properties_helper.rb +21 -0
- data/app/helpers/admin/products_helper.rb +11 -0
- data/app/helpers/admin/taxons_helper.rb +18 -0
- data/app/helpers/admin/users_helper.rb +8 -0
- data/app/helpers/admin/zones_helper.rb +11 -0
- data/app/helpers/checkout_helper.rb +31 -0
- data/app/helpers/hook_helper.rb +20 -0
- data/app/helpers/orders_helper.rb +3 -0
- data/app/helpers/products_helper.rb +30 -0
- data/app/helpers/search_helper.rb +10 -0
- data/app/helpers/spree/base_helper.rb +119 -0
- data/app/helpers/taxons_helper.rb +32 -0
- data/app/helpers/trackers_helper.rb +2 -0
- data/app/mailers/order_mailer.rb +19 -0
- data/app/mailers/shipment_mailer.rb +11 -0
- data/app/models/address.rb +115 -0
- data/app/models/adjustment.rb +47 -0
- data/app/models/app_configuration.rb +44 -0
- data/app/models/asset.rb +4 -0
- data/app/models/billing_integration.rb +23 -0
- data/app/models/calculator/flat_percent_item_total.rb +19 -0
- data/app/models/calculator/flat_rate.rb +16 -0
- data/app/models/calculator/flexi_rate.rb +32 -0
- data/app/models/calculator/per_item.rb +16 -0
- data/app/models/calculator/price_bucket.rb +30 -0
- data/app/models/calculator/sales_tax.rb +48 -0
- data/app/models/calculator/vat.rb +63 -0
- data/app/models/calculator.rb +46 -0
- data/app/models/configuration.rb +3 -0
- data/app/models/country.rb +16 -0
- data/app/models/creditcard.rb +267 -0
- data/app/models/gateway/authorize_net.rb +19 -0
- data/app/models/gateway/authorize_net_cim.rb +132 -0
- data/app/models/gateway/beanstream.rb +187 -0
- data/app/models/gateway/bogus.rb +80 -0
- data/app/models/gateway/braintree.rb +88 -0
- data/app/models/gateway/eway.rb +11 -0
- data/app/models/gateway/linkpoint.rb +8 -0
- data/app/models/gateway/pay_pal.rb +11 -0
- data/app/models/gateway/sage_pay.rb +9 -0
- data/app/models/gateway.rb +48 -0
- data/app/models/image.rb +31 -0
- data/app/models/inventory_unit.rb +119 -0
- data/app/models/line_item.rb +95 -0
- data/app/models/log_entry.rb +3 -0
- data/app/models/mail_method.rb +23 -0
- data/app/models/option_type.rb +9 -0
- data/app/models/option_value.rb +5 -0
- data/app/models/order.rb +484 -0
- data/app/models/payment.rb +119 -0
- data/app/models/payment_method/check.rb +27 -0
- data/app/models/payment_method.rb +56 -0
- data/app/models/preference.rb +51 -0
- data/app/models/product.rb +258 -0
- data/app/models/product_group.rb +216 -0
- data/app/models/product_option_type.rb +5 -0
- data/app/models/product_property.rb +15 -0
- data/app/models/product_scope.rb +78 -0
- data/app/models/property.rb +18 -0
- data/app/models/prototype.rb +5 -0
- data/app/models/return_authorization.rb +79 -0
- data/app/models/role.rb +3 -0
- data/app/models/shipment.rb +157 -0
- data/app/models/shipping_category.rb +3 -0
- data/app/models/shipping_method.rb +25 -0
- data/app/models/spree/alert.rb +13 -0
- data/app/models/state.rb +16 -0
- data/app/models/state_event.rb +16 -0
- data/app/models/tax_category.rb +15 -0
- data/app/models/tax_rate.rb +16 -0
- data/app/models/taxon.rb +52 -0
- data/app/models/taxonomy.rb +20 -0
- data/app/models/taxonomy.rb~ +22 -0
- data/app/models/tracker.rb +5 -0
- data/app/models/user.rb +21 -0
- data/app/models/variant.rb +104 -0
- data/app/models/zone.rb +84 -0
- data/app/models/zone_member.rb +10 -0
- data/app/stylesheets/_buttons.less +80 -0
- data/app/stylesheets/_cart.less +24 -0
- data/app/stylesheets/_checkout.less +76 -0
- data/app/stylesheets/_checkout_progress.less +62 -0
- data/app/stylesheets/_colors.less +16 -0
- data/app/stylesheets/_forms.less +50 -0
- data/app/stylesheets/_layout.less +77 -0
- data/app/stylesheets/_messages.less +32 -0
- data/app/stylesheets/_mixins.less +71 -0
- data/app/stylesheets/_navigation.less +130 -0
- data/app/stylesheets/_prices.less +18 -0
- data/app/stylesheets/_product_details.less +56 -0
- data/app/stylesheets/_product_lists.less +66 -0
- data/app/stylesheets/_registration.less +24 -0
- data/app/stylesheets/_reset.less +69 -0
- data/app/stylesheets/_typography.less +158 -0
- data/app/stylesheets/screen.less +13 -0
- data/app/views/admin/adjustments/_adjustments_table.html.erb +24 -0
- data/app/views/admin/adjustments/_form.html.erb +12 -0
- data/app/views/admin/adjustments/edit.html.erb +13 -0
- data/app/views/admin/adjustments/index.html.erb +4 -0
- data/app/views/admin/adjustments/new.html.erb +14 -0
- data/app/views/admin/configurations/index.html.erb +66 -0
- data/app/views/admin/extensions/index.html.erb +23 -0
- data/app/views/admin/general_settings/edit.html.erb +46 -0
- data/app/views/admin/general_settings/show.html.erb +36 -0
- data/app/views/admin/images/_form.html.erb +16 -0
- data/app/views/admin/images/edit.html.erb +19 -0
- data/app/views/admin/images/index.html.erb +69 -0
- data/app/views/admin/images/new.html.erb +22 -0
- data/app/views/admin/images/new.html.erb~ +22 -0
- data/app/views/admin/inventory_settings/edit.html.erb +27 -0
- data/app/views/admin/inventory_settings/show.html.erb +9 -0
- data/app/views/admin/inventory_units/adjust.html.erb +33 -0
- data/app/views/admin/mail_methods/_form.html.erb +96 -0
- data/app/views/admin/mail_methods/edit.html.erb +9 -0
- data/app/views/admin/mail_methods/index.html.erb +41 -0
- data/app/views/admin/mail_methods/new.html.erb +9 -0
- data/app/views/admin/option_types/_available.html.erb +27 -0
- data/app/views/admin/option_types/_form.html.erb +11 -0
- data/app/views/admin/option_types/_option_value_fields.html.erb +5 -0
- data/app/views/admin/option_types/_selected.html.erb +26 -0
- data/app/views/admin/option_types/available.js.erb +2 -0
- data/app/views/admin/option_types/edit.html.erb +32 -0
- data/app/views/admin/option_types/index.html.erb +33 -0
- data/app/views/admin/option_types/new.erb +11 -0
- data/app/views/admin/option_types/select.js.erb +3 -0
- data/app/views/admin/option_types/selected.html.erb +6 -0
- data/app/views/admin/orders/_add_product.html.erb +20 -0
- data/app/views/admin/orders/_form.html.erb +67 -0
- data/app/views/admin/orders/_line_item.html.erb +17 -0
- data/app/views/admin/orders/_user_form.html.erb +42 -0
- data/app/views/admin/orders/edit.html.erb +31 -0
- data/app/views/admin/orders/history.html.erb +29 -0
- data/app/views/admin/orders/index.html.erb +103 -0
- data/app/views/admin/orders/new.html.erb +20 -0
- data/app/views/admin/orders/show.html.erb +28 -0
- data/app/views/admin/orders/user.html.erb +24 -0
- data/app/views/admin/payment_methods/_form.html.erb +50 -0
- data/app/views/admin/payment_methods/edit.html.erb +10 -0
- data/app/views/admin/payment_methods/index.html.erb +49 -0
- data/app/views/admin/payment_methods/new.html.erb +11 -0
- data/app/views/admin/payments/_bill_address_form.html.erb +9 -0
- data/app/views/admin/payments/_form.html.erb +15 -0
- data/app/views/admin/payments/_list.html.erb +22 -0
- data/app/views/admin/payments/_transaction_list.html.erb +24 -0
- data/app/views/admin/payments/credit.html.erb +14 -0
- data/app/views/admin/payments/index.html.erb +22 -0
- data/app/views/admin/payments/new.html.erb +19 -0
- data/app/views/admin/payments/show.html.erb +10 -0
- data/app/views/admin/payments/source_forms/_check.html.erb +0 -0
- data/app/views/admin/payments/source_forms/_gateway.html.erb +43 -0
- data/app/views/admin/payments/source_views/_check.html.erb +0 -0
- data/app/views/admin/payments/source_views/_gateway.html.erb +34 -0
- data/app/views/admin/product_groups/_preview.html.erb +34 -0
- data/app/views/admin/product_groups/_product_scope.html.erb +24 -0
- data/app/views/admin/product_groups/edit.html.erb +56 -0
- data/app/views/admin/product_groups/index.html.erb +37 -0
- data/app/views/admin/product_groups/new.html.erb +12 -0
- data/app/views/admin/product_groups/show.html.erb +32 -0
- data/app/views/admin/product_groups/update.js.erb +8 -0
- data/app/views/admin/product_properties/_product_property_fields.html.erb +11 -0
- data/app/views/admin/product_properties/index.html.erb +55 -0
- data/app/views/admin/product_scopes/_form.html.erb +106 -0
- data/app/views/admin/product_scopes/create.js.erb +3 -0
- data/app/views/admin/product_scopes/destroy.js.erb +3 -0
- data/app/views/admin/product_scopes/new.html.erb +1 -0
- data/app/views/admin/products/_form.html.erb +112 -0
- data/app/views/admin/products/_option_types.html.erb +40 -0
- data/app/views/admin/products/_properties_form.erb +7 -0
- data/app/views/admin/products/edit.html.erb +10 -0
- data/app/views/admin/products/edit.html.erb~ +10 -0
- data/app/views/admin/products/index.html.erb +81 -0
- data/app/views/admin/products/index.html.erb~ +81 -0
- data/app/views/admin/products/new.erb +58 -0
- data/app/views/admin/products/new.erb~ +53 -0
- data/app/views/admin/products/show.html.erb +4 -0
- data/app/views/admin/products/show.html.erb~ +4 -0
- data/app/views/admin/properties/_form.html.erb +12 -0
- data/app/views/admin/properties/edit.html.erb +10 -0
- data/app/views/admin/properties/filtered.html.erb +1 -0
- data/app/views/admin/properties/index.html.erb +40 -0
- data/app/views/admin/properties/new.erb +11 -0
- data/app/views/admin/prototypes/_form.html.erb +44 -0
- data/app/views/admin/prototypes/available.html.erb +22 -0
- data/app/views/admin/prototypes/edit.html.erb +9 -0
- data/app/views/admin/prototypes/index.html.erb +37 -0
- data/app/views/admin/prototypes/new.erb +11 -0
- data/app/views/admin/prototypes/select.js.erb +4 -0
- data/app/views/admin/reports/index.html.erb +19 -0
- data/app/views/admin/reports/sales_total.html.erb +23 -0
- data/app/views/admin/return_authorizations/_form.html.erb +78 -0
- data/app/views/admin/return_authorizations/edit.html.erb +27 -0
- data/app/views/admin/return_authorizations/index.html.erb +45 -0
- data/app/views/admin/return_authorizations/new.html.erb +13 -0
- data/app/views/admin/shared/_additional_field.html.erb +5 -0
- data/app/views/admin/shared/_address.html.erb +5 -0
- data/app/views/admin/shared/_address_form.html.erb +79 -0
- data/app/views/admin/shared/_alert.html.erb +6 -0
- data/app/views/admin/shared/_calculator_fields.html.erb +19 -0
- data/app/views/admin/shared/_configuration_menu.html.erb +22 -0
- data/app/views/admin/shared/_destroy.js.erb +16 -0
- data/app/views/admin/shared/_edit_resource_links.html.erb +4 -0
- data/app/views/admin/shared/_group_from_products_form.html.erb +12 -0
- data/app/views/admin/shared/_new_adjustment_button.html.erb +8 -0
- data/app/views/admin/shared/_new_resource_links.html.erb +4 -0
- data/app/views/admin/shared/_order_details.html.erb +3 -0
- data/app/views/admin/shared/_order_sub_menu.html.erb +0 -0
- data/app/views/admin/shared/_order_tabs.html.erb +64 -0
- data/app/views/admin/shared/_product_sub_menu.html.erb +11 -0
- data/app/views/admin/shared/_product_tabs.html.erb +34 -0
- data/app/views/admin/shared/_report_criteria.html.erb +15 -0
- data/app/views/admin/shared/_show_resource_links.html.erb +5 -0
- data/app/views/admin/shared/_tabs.html.erb +6 -0
- data/app/views/admin/shared/_update_order_state.js +6 -0
- data/app/views/admin/shipments/_form.html.erb +77 -0
- data/app/views/admin/shipments/edit.html.erb +40 -0
- data/app/views/admin/shipments/index.html.erb +47 -0
- data/app/views/admin/shipments/new.html.erb +18 -0
- data/app/views/admin/shipping_categories/_form.html.erb +6 -0
- data/app/views/admin/shipping_categories/edit.html.erb +6 -0
- data/app/views/admin/shipping_categories/index.html.erb +29 -0
- data/app/views/admin/shipping_categories/new.html.erb +8 -0
- data/app/views/admin/shipping_methods/_form.html.erb +26 -0
- data/app/views/admin/shipping_methods/edit.html.erb +16 -0
- data/app/views/admin/shipping_methods/index.html.erb +49 -0
- data/app/views/admin/shipping_methods/new.html.erb +17 -0
- data/app/views/admin/states/_form.html.erb +9 -0
- data/app/views/admin/states/_state_list.html.erb +34 -0
- data/app/views/admin/states/edit.html.erb +10 -0
- data/app/views/admin/states/index.html.erb +16 -0
- data/app/views/admin/states/new.erb +8 -0
- data/app/views/admin/tax_categories/_form.html.erb +12 -0
- data/app/views/admin/tax_categories/edit.html.erb +10 -0
- data/app/views/admin/tax_categories/index.html.erb +44 -0
- data/app/views/admin/tax_categories/new.html.erb +10 -0
- data/app/views/admin/tax_categories/show.html.erb +1 -0
- data/app/views/admin/tax_rates/_form.html.erb +16 -0
- data/app/views/admin/tax_rates/edit.html.erb +6 -0
- data/app/views/admin/tax_rates/index.html.erb +34 -0
- data/app/views/admin/tax_rates/new.html.erb +8 -0
- data/app/views/admin/tax_settings/edit.html.erb +17 -0
- data/app/views/admin/tax_settings/show.html.erb +14 -0
- data/app/views/admin/taxonomies/_form.html.erb +10 -0
- data/app/views/admin/taxonomies/_form.html.erb~ +11 -0
- data/app/views/admin/taxonomies/_js_head.html.erb +9 -0
- data/app/views/admin/taxonomies/_list.html.erb +19 -0
- data/app/views/admin/taxonomies/_list.html.erb~ +20 -0
- data/app/views/admin/taxonomies/_taxon.html.erb +12 -0
- data/app/views/admin/taxonomies/edit.erb +49 -0
- data/app/views/admin/taxonomies/get_children.json.erb +9 -0
- data/app/views/admin/taxonomies/index.html.erb +16 -0
- data/app/views/admin/taxonomies/new.html.erb +12 -0
- data/app/views/admin/taxons/_form.html.erb +23 -0
- data/app/views/admin/taxons/_taxon_table.html.erb +23 -0
- data/app/views/admin/taxons/available.js.erb +33 -0
- data/app/views/admin/taxons/edit.html.erb +11 -0
- data/app/views/admin/taxons/remove.html.erb +1 -0
- data/app/views/admin/taxons/select.js.erb +2 -0
- data/app/views/admin/taxons/selected.html.erb +43 -0
- data/app/views/admin/trackers/_form.html.erb +26 -0
- data/app/views/admin/trackers/edit.html.erb +8 -0
- data/app/views/admin/trackers/index.html.erb +41 -0
- data/app/views/admin/trackers/new.html.erb +9 -0
- data/app/views/admin/users/_form.html.erb +35 -0
- data/app/views/admin/users/edit.html.erb +14 -0
- data/app/views/admin/users/index.html.erb +63 -0
- data/app/views/admin/users/new.html.erb +14 -0
- data/app/views/admin/users/show.html.erb +21 -0
- data/app/views/admin/variants/_form.html.erb +40 -0
- data/app/views/admin/variants/edit.html.erb +13 -0
- data/app/views/admin/variants/index.html.erb +66 -0
- data/app/views/admin/variants/new.erb +11 -0
- data/app/views/admin/zones/_country_member.html.erb +5 -0
- data/app/views/admin/zones/_form.html.erb +29 -0
- data/app/views/admin/zones/_member_type.html.erb +15 -0
- data/app/views/admin/zones/_state_member.html.erb +5 -0
- data/app/views/admin/zones/_zone_member.html.erb +5 -0
- data/app/views/admin/zones/edit.html.erb +10 -0
- data/app/views/admin/zones/index.html.erb +41 -0
- data/app/views/admin/zones/new.html.erb +10 -0
- data/app/views/checkout/_address.html.erb +163 -0
- data/app/views/checkout/_confirm.html.erb +11 -0
- data/app/views/checkout/_delivery.html.erb +25 -0
- data/app/views/checkout/_payment.html.erb +30 -0
- data/app/views/checkout/_summary.html.erb +21 -0
- data/app/views/checkout/edit.html.erb +20 -0
- data/app/views/checkout/payment/_check.html.erb +0 -0
- data/app/views/checkout/payment/_gateway.html.erb +31 -0
- data/app/views/checkout/registration.html.erb +20 -0
- data/app/views/content/cvv.html.erb +13 -0
- data/app/views/layouts/admin.html.erb +75 -0
- data/app/views/layouts/spree_application.html.erb +52 -0
- data/app/views/order_mailer/cancel_email.text.erb +16 -0
- data/app/views/order_mailer/confirm_email.text.erb +19 -0
- data/app/views/orders/_form.html.erb +19 -0
- data/app/views/orders/_line_item.html.erb +41 -0
- data/app/views/orders/edit.html.erb +41 -0
- data/app/views/orders/new.html.erb +9 -0
- data/app/views/orders/show.html.erb +14 -0
- data/app/views/products/_cart_form.html.erb +54 -0
- data/app/views/products/_cart_form.html.erb~ +54 -0
- data/app/views/products/_image.html.erb +5 -0
- data/app/views/products/_image.html.erb~ +5 -0
- data/app/views/products/_properties.html.erb +8 -0
- data/app/views/products/_taxons.html.erb +16 -0
- data/app/views/products/_thumbnails.html.erb +40 -0
- data/app/views/products/index.html.erb +37 -0
- data/app/views/products/show.html.erb +31 -0
- data/app/views/shared/_additional_field.html.erb +7 -0
- data/app/views/shared/_admin_head.html.erb +34 -0
- data/app/views/shared/_basic_layout.html.erb +44 -0
- data/app/views/shared/_edit_resource_links.html.erb +1 -0
- data/app/views/shared/_end_soon.html.erb +43 -0
- data/app/views/shared/_error_messages.html.erb +11 -0
- data/app/views/shared/_filters.html.erb +27 -0
- data/app/views/shared/_footer.html.erb +13 -0
- data/app/views/shared/_google_analytics.html.erb +40 -0
- data/app/views/shared/_head.html.erb +10 -0
- data/app/views/shared/_method_error_message.html.erb +4 -0
- data/app/views/shared/_nav_bar.html.erb +5 -0
- data/app/views/shared/_new_release.html.erb +42 -0
- data/app/views/shared/_new_resource_links.html.erb +1 -0
- data/app/views/shared/_order_details.html.erb +50 -0
- data/app/views/shared/_products.html.erb +42 -0
- data/app/views/shared/_search.html.erb +9 -0
- data/app/views/shared/_show_resource_links.html.erb +3 -0
- data/app/views/shared/_store_menu.html.erb +3 -0
- data/app/views/shared/_taxonomies.html.erb +19 -0
- data/app/views/shared/_test_hook.html.erb +1 -0
- data/app/views/shared/_upcoming_products.html.erb +42 -0
- data/app/views/shipment_mailer/shipped_email.text.erb +15 -0
- data/app/views/states/index.js.erb +1 -0
- data/app/views/taxons/_taxon.html.erb +4 -0
- data/app/views/taxons/show.html.erb +19 -0
- data/config/cucumber.yml +10 -0
- data/config/initializers/form_builder.rb +19 -0
- data/config/initializers/load_unobtrusive_date_picker.rb +8 -0
- data/config/initializers/spree.rb +29 -0
- data/config/initializers/workarounds_for_ruby19.rb +72 -0
- data/config/locales/en.yml +1015 -0
- data/config/routes.rb +207 -0
- data/db/default/countries.yml +1583 -0
- data/db/default/roles.yml +7 -0
- data/db/default/states.yml +256 -0
- data/db/default/zone_members.yml +169 -0
- data/db/default/zones.yml +13 -0
- data/db/migrate/20090823005402_spree_zero_nine_zero.rb +442 -0
- data/db/migrate/20090904192342_create_indexes_for_inventory_units.rb +12 -0
- data/db/migrate/20090923100315_add_count_on_hand_to_variants_and_products.rb +36 -0
- data/db/migrate/20091007134354_change_taxons_to_nested_set.rb +40 -0
- data/db/migrate/20091008091614_move_to_configurable_gateways.rb +55 -0
- data/db/migrate/20091012120519_product_groups_and_scopes.rb +25 -0
- data/db/migrate/20091015110842_add_open_id_authentication_tables.rb +20 -0
- data/db/migrate/20091015153048_add_openid_field_to_users.rb +19 -0
- data/db/migrate/20091016174634_change_preference_value_type.rb +10 -0
- data/db/migrate/20091017175558_create_billing_integrations.rb +16 -0
- data/db/migrate/20091021133257_charge_refactoring.rb +35 -0
- data/db/migrate/20091104151730_add_some_indexes.rb +21 -0
- data/db/migrate/20091126190904_checkout_state_machine.rb +13 -0
- data/db/migrate/20091209153045_state_for_shipments.rb +9 -0
- data/db/migrate/20091209202200_make_state_events_polymorphic.rb +12 -0
- data/db/migrate/20091211203813_ship_address_id_for_checkouts.rb +9 -0
- data/db/migrate/20091212161118_shipping_method_id_for_checkouts.rb +9 -0
- data/db/migrate/20091213222815_creditcard_last_four_digits.rb +19 -0
- data/db/migrate/20091214183826_populate_legacy_shipment_state.rb +19 -0
- data/db/migrate/20100105090147_add_cost_price.rb +9 -0
- data/db/migrate/20100105132138_shipment_id_for_inventory_units.rb +21 -0
- data/db/migrate/20100111205525_cim_fields_for_creditcards.rb +11 -0
- data/db/migrate/20100112151511_create_return_authorizations.rb +16 -0
- data/db/migrate/20100113090919_add_return_authorization_to_inventory_units.rb +9 -0
- data/db/migrate/20100113203104_create_trackers.rb +14 -0
- data/db/migrate/20100121160010_creditcard_id_for_creditcard_txns.rb +9 -0
- data/db/migrate/20100121183934_original_creditcard_txn_id_for_creditcard_txns.rb +9 -0
- data/db/migrate/20100125145351_add_test_mode_to_billing_integration.rb +11 -0
- data/db/migrate/20100126103714_create_products_product_groups.rb +12 -0
- data/db/migrate/20100209025806_create_payment_methods.rb +20 -0
- data/db/migrate/20100209144531_polymorphic_payments.rb +29 -0
- data/db/migrate/20100213103131_change_payments_payment_method_to_belongs_to.rb +11 -0
- data/db/migrate/20100214212536_assign_creditcard_txns_to_payment.rb +16 -0
- data/db/migrate/20100223170312_sti_for_transactions.rb +14 -0
- data/db/migrate/20100223183812_drop_billing_integrations.rb +16 -0
- data/db/migrate/20100224153127_deleted_at_for_payment_methods.rb +13 -0
- data/db/migrate/20100301163454_add_adjustments_index.rb +10 -0
- data/db/migrate/20100306153445_fix_by_popularity.rb +8 -0
- data/db/migrate/20100317120946_add_alt_text_to_images.rb +9 -0
- data/db/migrate/20100427121301_add_display_to_payment_methods.rb +9 -0
- data/db/migrate/20100504142133_add_addresses_checkouts_indexes.rb +16 -0
- data/db/migrate/20100506180619_add_icon_to_taxons.rb +18 -0
- data/db/migrate/20100506185838_add_description_to_taxons.rb +11 -0
- data/db/migrate/20100528155333_index_for_shipments_number.rb +9 -0
- data/db/migrate/20100528185820_add_index_on_users_persistence_token.rb +9 -0
- data/db/migrate/20100605152042_add_default_to_tax_categories.rb +9 -0
- data/db/migrate/20100624110730_add_display_to_shipping_methods.rb +9 -0
- data/db/migrate/20100624123336_rename_payment_method_display.rb +9 -0
- data/db/migrate/20100624175547_rename_preferences_field.rb +8 -0
- data/db/migrate/20100811163637_add_guest_flag.rb +13 -0
- data/db/migrate/20100811205836_drop_order_token.rb +11 -0
- data/db/migrate/20100812162326_payments_state_and_assigned_to_order_only.rb +11 -0
- data/db/migrate/20100813023502_create_address_keys_for_order.rb +15 -0
- data/db/migrate/20100813185745_payment_total_for_orders.rb +9 -0
- data/db/migrate/20100816212146_shipping_method_id_for_orders.rb +9 -0
- data/db/migrate/20100817152723_add_shipment_and_payment_state.rb +15 -0
- data/db/migrate/20100819170125_refactor_adjustments.rb +19 -0
- data/db/migrate/20100820135707_response_code_and_avs_response_for_payments.rb +11 -0
- data/db/migrate/20100901171814_change_guest_flag_to_anonymous.rb +13 -0
- data/db/migrate/20100903203949_email_for_orders.rb +9 -0
- data/db/migrate/20100923162011_create_mail_methods.rb +12 -0
- data/db/migrate/20100929151905_rename_frozen_to_locked.rb +8 -0
- data/db/migrate/20101008190536_move_special_instructions_to_orders.rb +11 -0
- data/db/migrate/20101026184700_create_log_entries.rb +15 -0
- data/db/migrate/20101026184714_migrate_transactions_to_payment_state.rb +94 -0
- data/db/migrate/20101026184746_delete_in_progress_orders.rb +18 -0
- data/db/migrate/20101026184808_migrate_checkout_to_orders.rb +27 -0
- data/db/migrate/20101026184833_migrate_adjustments.rb +9 -0
- data/db/migrate/20101026184855_remove_shipped_state.rb +14 -0
- data/db/migrate/20101026184916_prevent_nil_payment_total.rb +8 -0
- data/db/migrate/20101026184932_prevent_nil_email.rb +9 -0
- data/db/migrate/20101026184959_generate_anonymous_users.rb +14 -0
- data/db/migrate/20101026185022_update_order_state.rb +8 -0
- data/db/migrate/20101026192225_cleanup_legacy_tables.rb +11 -0
- data/db/migrate/20101028151745_remove_number_and_cvv_from_credicard.rb +9 -0
- data/db/migrate/20101103212716_drop_anonymous_field_for_user.rb +8 -0
- data/db/migrate/20101111133551_renamed_rma_cancelled_state.rb +10 -0
- data/db/migrate/20101117031806_fix_problematic_index_names.rb +13 -0
- data/db/migrate/20101223215658_add_position_to_variants.rb +9 -0
- data/db/migrate/20110110130847_add_next_state_to_state_events.rb +9 -0
- data/db/migrate/20110111122537_add_position_to_option_types.rb +9 -0
- data/db/migrate/20110314192118_remove_trailing_slashes_in_taxon_permalinks.rb +17 -0
- data/db/sample/users.rb +61 -0
- data/db/seeds.rb +3 -0
- data/lib/custom_fixtures.rb +7 -0
- data/lib/generators/spree_core/upgrade_generator.rb +23 -0
- data/lib/generators/templates/config/initializers/%file_name%.rb.tt +1 -0
- data/lib/generators/templates/config/locales/%current_locale%.yml.tt +2 -0
- data/lib/generators/templates/config/routes.rb +3 -0
- data/lib/middleware/seo_assist.rb +44 -0
- data/lib/product_filters.rb +179 -0
- data/lib/redirect_legacy_product_url.rb +13 -0
- data/lib/scopes/dynamic.rb +31 -0
- data/lib/scopes/product.rb +266 -0
- data/lib/scopes/variant.rb +18 -0
- data/lib/scopes.rb +69 -0
- data/lib/spree/calculated_adjustments.rb +69 -0
- data/lib/spree/config.rb +33 -0
- data/lib/spree/current_order.rb +30 -0
- data/lib/spree/file_utilz.rb +73 -0
- data/lib/spree/gateway_error.rb +3 -0
- data/lib/spree/mail_interceptor.rb +23 -0
- data/lib/spree/mail_settings.rb +33 -0
- data/lib/spree/preference_access.rb +27 -0
- data/lib/spree/search/base.rb +64 -0
- data/lib/spree_base.rb +116 -0
- data/lib/spree_core/action_callbacks.rb +26 -0
- data/lib/spree_core/authorize_net_cim_hack.rb +871 -0
- data/lib/spree_core/delegate_belongs_to.rb +89 -0
- data/lib/spree_core/enumerable_constants.rb +209 -0
- data/lib/spree_core/ext/active_record.rb +15 -0
- data/lib/spree_core/ext/array.rb +14 -0
- data/lib/spree_core/ext/hash.rb +75 -0
- data/lib/spree_core/ext/string.rb +10 -0
- data/lib/spree_core/preferences/model_hooks.rb +293 -0
- data/lib/spree_core/preferences/preference_definition.rb +53 -0
- data/lib/spree_core/railtie.rb +63 -0
- data/lib/spree_core/spree_custom_responder.rb +29 -0
- data/lib/spree_core/spree_respond_with.rb +57 -0
- data/lib/spree_core/ssl_requirement.rb +104 -0
- data/lib/spree_core/testing_support/factories/address_factory.rb +20 -0
- data/lib/spree_core/testing_support/factories/adjustment_factory.rb +6 -0
- data/lib/spree_core/testing_support/factories/calculator_factory.rb +5 -0
- data/lib/spree_core/testing_support/factories/configuraion_factory.rb +4 -0
- data/lib/spree_core/testing_support/factories/country_factory.rb +7 -0
- data/lib/spree_core/testing_support/factories/creditcard_factory.rb +11 -0
- data/lib/spree_core/testing_support/factories/inventory_unit_factory.rb +7 -0
- data/lib/spree_core/testing_support/factories/line_item_factory.rb +8 -0
- data/lib/spree_core/testing_support/factories/mail_method_factory.rb +4 -0
- data/lib/spree_core/testing_support/factories/options_factory.rb +10 -0
- data/lib/spree_core/testing_support/factories/order_factory.rb +18 -0
- data/lib/spree_core/testing_support/factories/payment_factory.rb +26 -0
- data/lib/spree_core/testing_support/factories/payment_method_factory.rb +17 -0
- data/lib/spree_core/testing_support/factories/product_factory.rb +16 -0
- data/lib/spree_core/testing_support/factories/product_group_factory.rb +3 -0
- data/lib/spree_core/testing_support/factories/product_option_type_factory.rb +4 -0
- data/lib/spree_core/testing_support/factories/product_property_factory.rb +4 -0
- data/lib/spree_core/testing_support/factories/product_scope_factory.rb +6 -0
- data/lib/spree_core/testing_support/factories/property_factory.rb +4 -0
- data/lib/spree_core/testing_support/factories/prototype_factory.rb +4 -0
- data/lib/spree_core/testing_support/factories/return_authorization_factory.rb +8 -0
- data/lib/spree_core/testing_support/factories/role_factory.rb +9 -0
- data/lib/spree_core/testing_support/factories/shipment_factory.rb +9 -0
- data/lib/spree_core/testing_support/factories/shipping_category_factory.rb +5 -0
- data/lib/spree_core/testing_support/factories/shipping_method_factory.rb +11 -0
- data/lib/spree_core/testing_support/factories/state_factory.rb +11 -0
- data/lib/spree_core/testing_support/factories/tax_category_factory.rb +8 -0
- data/lib/spree_core/testing_support/factories/tax_rate_factory.rb +5 -0
- data/lib/spree_core/testing_support/factories/taxon_factory.rb +5 -0
- data/lib/spree_core/testing_support/factories/taxonomy_factory.rb +3 -0
- data/lib/spree_core/testing_support/factories/tracker_factory.rb +5 -0
- data/lib/spree_core/testing_support/factories/user_factory.rb +15 -0
- data/lib/spree_core/testing_support/factories/variant_factory.rb +14 -0
- data/lib/spree_core/testing_support/factories/zone_factory.rb +18 -0
- data/lib/spree_core/testing_support/factories.rb +13 -0
- data/lib/spree_core/theme_support/hook.rb +51 -0
- data/lib/spree_core/theme_support/hook_listener.rb +68 -0
- data/lib/spree_core/theme_support/hook_modifier.rb +35 -0
- data/lib/spree_core/theme_support/more_patches.rb +118 -0
- data/lib/spree_core/theme_support.rb +4 -0
- data/lib/spree_core/version.rb +5 -0
- data/lib/spree_core.rb +94 -0
- data/lib/store_helpers.rb +10 -0
- data/lib/tasks/common.rb +30 -0
- data/lib/tasks/core.rake +105 -0
- data/lib/tasks/install.rake +26 -0
- data/lib/tasks/rake_util.rb +19 -0
- data/lib/tasks/taxon.rake +14 -0
- data/lib/tasks/themes.rake +34 -0
- data/public/images/add-to-cart.png +0 -0
- data/public/images/admin/bg/active-tab.png +0 -0
- data/public/images/admin/bg/admin_tab_back.png +0 -0
- data/public/images/admin/bg/admin_tab_selected_back.png +0 -0
- data/public/images/admin/bg/content-back-blue.png +0 -0
- data/public/images/admin/bg/content-back-green.png +0 -0
- data/public/images/admin/bg/content-back.png +0 -0
- data/public/images/admin/bg/flash-error.png +0 -0
- data/public/images/admin/bg/flash-notice.png +0 -0
- data/public/images/admin/bg/green-stripes.gif +0 -0
- data/public/images/admin/bg/green-stripes.png +0 -0
- data/public/images/admin/bg/grid_header_back.png +0 -0
- data/public/images/admin/bg/grid_header_back_green.png +0 -0
- data/public/images/admin/bg/header-bg.png +0 -0
- data/public/images/admin/bg/header.png +0 -0
- data/public/images/admin/bg/header_bg.jpg +0 -0
- data/public/images/admin/bg/menu-current.png +0 -0
- data/public/images/admin/bg/red-stripes.gif +0 -0
- data/public/images/admin/bg/red-stripes.png +0 -0
- data/public/images/admin/bg/spree_50.png +0 -0
- data/public/images/admin/bg/subnav-divider.png +0 -0
- data/public/images/admin/bg/subnav.png +0 -0
- data/public/images/admin/bg/tab-back.png +0 -0
- data/public/images/admin/buttons/blue/left_01.png +0 -0
- data/public/images/admin/buttons/blue/right_01.png +0 -0
- data/public/images/admin/buttons/drag-handle-green.png +0 -0
- data/public/images/admin/buttons/green/left_01.png +0 -0
- data/public/images/admin/buttons/green/right_01.png +0 -0
- data/public/images/admin/buttons/left_01.png +0 -0
- data/public/images/admin/buttons/left_01_small.png +0 -0
- data/public/images/admin/buttons/orange/left_03.png +0 -0
- data/public/images/admin/buttons/orange/right_03.png +0 -0
- data/public/images/admin/buttons/right_01.png +0 -0
- data/public/images/admin/buttons/right_01_small.png +0 -0
- data/public/images/admin/icons/16x16/1.png +0 -0
- data/public/images/admin/icons/16x16/10.png +0 -0
- data/public/images/admin/icons/16x16/2.png +0 -0
- data/public/images/admin/icons/16x16/3.png +0 -0
- data/public/images/admin/icons/16x16/4.png +0 -0
- data/public/images/admin/icons/16x16/5.png +0 -0
- data/public/images/admin/icons/16x16/6.png +0 -0
- data/public/images/admin/icons/16x16/7.png +0 -0
- data/public/images/admin/icons/16x16/8.png +0 -0
- data/public/images/admin/icons/16x16/9.png +0 -0
- data/public/images/admin/icons/32x32/1.png +0 -0
- data/public/images/admin/icons/32x32/10.png +0 -0
- data/public/images/admin/icons/32x32/11.png +0 -0
- data/public/images/admin/icons/32x32/2.png +0 -0
- data/public/images/admin/icons/32x32/3.png +0 -0
- data/public/images/admin/icons/32x32/4.png +0 -0
- data/public/images/admin/icons/32x32/5.png +0 -0
- data/public/images/admin/icons/32x32/6.png +0 -0
- data/public/images/admin/icons/32x32/7.png +0 -0
- data/public/images/admin/icons/32x32/8.png +0 -0
- data/public/images/admin/icons/32x32/9.png +0 -0
- data/public/images/admin/icons/accept.png +0 -0
- data/public/images/admin/icons/add.gif +0 -0
- data/public/images/admin/icons/add.png +0 -0
- data/public/images/admin/icons/arrow-down.gif +0 -0
- data/public/images/admin/icons/cross.png +0 -0
- data/public/images/admin/icons/delete.gif +0 -0
- data/public/images/admin/icons/delete.png +0 -0
- data/public/images/admin/icons/drag.gif +0 -0
- data/public/images/admin/icons/edit.gif +0 -0
- data/public/images/admin/icons/edit.png +0 -0
- data/public/images/admin/icons/email.png +0 -0
- data/public/images/admin/icons/error.png +0 -0
- data/public/images/admin/icons/exclamation.png +0 -0
- data/public/images/admin/icons/feed.png +0 -0
- data/public/images/admin/icons/pdf.png +0 -0
- data/public/images/admin/icons/reorder.gif +0 -0
- data/public/images/admin/icons/search.gif +0 -0
- data/public/images/admin/icons/send-email.png +0 -0
- data/public/images/admin/icons/stop.png +0 -0
- data/public/images/admin/icons/tick.png +0 -0
- data/public/images/admin/icons/up.gif +0 -0
- data/public/images/admin/icons/xls.png +0 -0
- data/public/images/admin/tabs/off-left.png +0 -0
- data/public/images/admin/tabs/off-right.png +0 -0
- data/public/images/admin/tabs/on-left.png +0 -0
- data/public/images/admin/tabs/on-right.png +0 -0
- data/public/images/ajax_loader.gif +0 -0
- data/public/images/amex_cid.gif +0 -0
- data/public/images/bg-button-hover.png +0 -0
- data/public/images/bg-button-pressed.png +0 -0
- data/public/images/bg-button.gif +0 -0
- data/public/images/bg-button.png +0 -0
- data/public/images/blue/left_01.png +0 -0
- data/public/images/blue/right_01.png +0 -0
- data/public/images/body-back.png +0 -0
- data/public/images/bottom_shine.png +0 -0
- data/public/images/breadcrumb.gif +0 -0
- data/public/images/button-dark-hover.png +0 -0
- data/public/images/button-dark.png +0 -0
- data/public/images/buttons/bg-button-hover.png +0 -0
- data/public/images/buttons/bg-button-pressed.png +0 -0
- data/public/images/buttons/bg-button.gif +0 -0
- data/public/images/buttons/bg-button.png +0 -0
- data/public/images/buttons/blue/left_01.png +0 -0
- data/public/images/buttons/blue/right_01.png +0 -0
- data/public/images/buttons/button-dark-hover.png +0 -0
- data/public/images/buttons/button-dark.png +0 -0
- data/public/images/buttons/drag-handle-green.png +0 -0
- data/public/images/buttons/green/left_01.png +0 -0
- data/public/images/buttons/green/right_01.png +0 -0
- data/public/images/buttons/left_01.png +0 -0
- data/public/images/buttons/left_01_small.png +0 -0
- data/public/images/buttons/orange/left_03.png +0 -0
- data/public/images/buttons/orange/right_03.png +0 -0
- data/public/images/buttons/right_01.png +0 -0
- data/public/images/buttons/right_01_small.png +0 -0
- data/public/images/buttons/sxsw-ribbon-v1.png +0 -0
- data/public/images/buttons/top-shine.png +0 -0
- data/public/images/calendar_date_select/calendar.gif +0 -0
- data/public/images/cart-empty.png +0 -0
- data/public/images/cart-empty_x32.png +0 -0
- data/public/images/cart-full.png +0 -0
- data/public/images/cart-full_x32.png +0 -0
- data/public/images/checkout.png +0 -0
- data/public/images/creditcard.gif +0 -0
- data/public/images/datepicker/backstripes.gif +0 -0
- data/public/images/datepicker/bg_header.jpg +0 -0
- data/public/images/datepicker/bullet1.gif +0 -0
- data/public/images/datepicker/bullet2.gif +0 -0
- data/public/images/datepicker/cal.gif +0 -0
- data/public/images/datepicker/gradient-e5e5e5-ffffff.gif +0 -0
- data/public/images/discover_cid.gif +0 -0
- data/public/images/drag-handle-green.png +0 -0
- data/public/images/favicon.ico +0 -0
- data/public/images/green/left_01.png +0 -0
- data/public/images/green/right_01.png +0 -0
- data/public/images/grid.png +0 -0
- data/public/images/left_01.png +0 -0
- data/public/images/left_01_small.png +0 -0
- data/public/images/master_cid.jpg +0 -0
- data/public/images/menu-current.png +0 -0
- data/public/images/menu-hover.png +0 -0
- data/public/images/noimage/mini.jpg +0 -0
- data/public/images/noimage/product.jpg +0 -0
- data/public/images/noimage/small.jpg +0 -0
- data/public/images/openid-inputicon.gif +0 -0
- data/public/images/orange/left_03.png +0 -0
- data/public/images/orange/right_03.png +0 -0
- data/public/images/progress.gif +0 -0
- data/public/images/reorder.jpg +0 -0
- data/public/images/right_01.png +0 -0
- data/public/images/right_01_small.png +0 -0
- data/public/images/separator.png +0 -0
- data/public/images/shadow-top.png +0 -0
- data/public/images/shadow_top.png +0 -0
- data/public/images/spinner.gif +0 -0
- data/public/images/spree/progress.gif +0 -0
- data/public/images/spree/spinner.gif +0 -0
- data/public/images/spree/spree.jpg +0 -0
- data/public/images/spree.jpg +0 -0
- data/public/images/step-progress/completed-completed.gif +0 -0
- data/public/images/step-progress/completed-current.gif +0 -0
- data/public/images/step-progress/completed-first.gif +0 -0
- data/public/images/step-progress/current-first.gif +0 -0
- data/public/images/step-progress/current-incomplete.gif +0 -0
- data/public/images/step-progress/current-right.gif +0 -0
- data/public/images/step-progress/incomplete-incomplete.gif +0 -0
- data/public/images/step-progress/incomplete-right.gif +0 -0
- data/public/images/steps/1.png +0 -0
- data/public/images/steps/1_small.png +0 -0
- data/public/images/steps/2.png +0 -0
- data/public/images/steps/2_small.png +0 -0
- data/public/images/steps/3.png +0 -0
- data/public/images/steps/3_small.png +0 -0
- data/public/images/steps/4.png +0 -0
- data/public/images/steps/4_small.png +0 -0
- data/public/images/steps/5.png +0 -0
- data/public/images/steps/5_small.png +0 -0
- data/public/images/steps/6.png +0 -0
- data/public/images/steps/6_small.png +0 -0
- data/public/images/sxsw-ribbon-v1.png +0 -0
- data/public/images/tab_bottom.gif +0 -0
- data/public/images/tile-header.png +0 -0
- data/public/images/tile-slider.png +0 -0
- data/public/images/top-shine.png +0 -0
- data/public/images/tree-nav-icons/bullet.gif +0 -0
- data/public/images/tree-nav-icons/minus.gif +0 -0
- data/public/images/tree-nav-icons/plus.gif +0 -0
- data/public/images/tree-nav-icons/treeview-loading.gif +0 -0
- data/public/images/tree-nav-icons/treeview-sprite.gif +0 -0
- data/public/images/update.png +0 -0
- data/public/images/visa_cid.gif +0 -0
- data/public/images/wrapper-back-2.png +0 -0
- data/public/images/wrapper-back.png +0 -0
- data/public/images/yui-menubaritem_submenuindicator.png +0 -0
- data/public/images/yui-menubaritem_submenuindicator_disabled.png +0 -0
- data/public/images/yui-menuitem_checkbox.png +0 -0
- data/public/images/yui-menuitem_checkbox_disabled.png +0 -0
- data/public/images/yui-menuitem_submenuindicator.png +0 -0
- data/public/images/yui-menuitem_submenuindicator_disabled.png +0 -0
- data/public/images/yui-sprite.png +0 -0
- data/public/javascripts/additional-methods.js +236 -0
- data/public/javascripts/admin/address_states.js +25 -0
- data/public/javascripts/admin/checkouts/edit.js +130 -0
- data/public/javascripts/admin/orders/edit.js +23 -0
- data/public/javascripts/admin/orders/edit_form.js +16 -0
- data/public/javascripts/admin/payments/new.js +9 -0
- data/public/javascripts/admin/unobtrusive_handlers.js +43 -0
- data/public/javascripts/admin.js +232 -0
- data/public/javascripts/application.js +12 -0
- data/public/javascripts/calculator.js +15 -0
- data/public/javascripts/checkout.js +75 -0
- data/public/javascripts/datepicker.js +1445 -0
- data/public/javascripts/gateway.js +13 -0
- data/public/javascripts/jquery-1.4.2.min.js +154 -0
- data/public/javascripts/jquery-ui.js +188 -0
- data/public/javascripts/jquery.alerts/images/help.gif +0 -0
- data/public/javascripts/jquery.alerts/images/important.gif +0 -0
- data/public/javascripts/jquery.alerts/images/info.gif +0 -0
- data/public/javascripts/jquery.alerts/images/title.gif +0 -0
- data/public/javascripts/jquery.alerts/jquery.alerts.css +57 -0
- data/public/javascripts/jquery.alerts/jquery.alerts.js +235 -0
- data/public/javascripts/jquery.alerts/jquery.alerts.spree.css +30 -0
- data/public/javascripts/jquery.autocomplete.min.js +13 -0
- data/public/javascripts/jquery.cookie.js +96 -0
- data/public/javascripts/jquery.delayedobserver.js +35 -0
- data/public/javascripts/jquery.suggest.js +276 -0
- data/public/javascripts/jquery.template.js +255 -0
- data/public/javascripts/jquery.tokeninput.js +618 -0
- data/public/javascripts/jquery.validate.min.js +16 -0
- data/public/javascripts/jsTree/jquery.jstree.js +3510 -0
- data/public/javascripts/jsTree/themes/apple/bg.jpg +0 -0
- data/public/javascripts/jsTree/themes/apple/d.png +0 -0
- data/public/javascripts/jsTree/themes/apple/dot_for_ie.gif +0 -0
- data/public/javascripts/jsTree/themes/apple/style.css +60 -0
- data/public/javascripts/jsTree/themes/apple/throbber.gif +0 -0
- data/public/javascripts/lang/af.js +40 -0
- data/public/javascripts/lang/ar.js +50 -0
- data/public/javascripts/lang/de.js +40 -0
- data/public/javascripts/lang/du.js +40 -0
- data/public/javascripts/lang/en.js +42 -0
- data/public/javascripts/lang/es.js +41 -0
- data/public/javascripts/lang/fi.js +40 -0
- data/public/javascripts/lang/fr.js +44 -0
- data/public/javascripts/lang/gr.js +40 -0
- data/public/javascripts/lang/he.js +49 -0
- data/public/javascripts/lang/it.js +13 -0
- data/public/javascripts/lang/nl.js +40 -0
- data/public/javascripts/lang/no.js +40 -0
- data/public/javascripts/lang/pt.js +50 -0
- data/public/javascripts/lang/ro.js +40 -0
- data/public/javascripts/lang/ru.js +40 -0
- data/public/javascripts/lang/sp.js +40 -0
- data/public/javascripts/lang/sv.js +41 -0
- data/public/javascripts/lang/ua.js +40 -0
- data/public/javascripts/localization/messages_cn.js +24 -0
- data/public/javascripts/localization/messages_cs.js +23 -0
- data/public/javascripts/localization/messages_da.js +21 -0
- data/public/javascripts/localization/messages_de.js +21 -0
- data/public/javascripts/localization/messages_es.js +24 -0
- data/public/javascripts/localization/messages_fr.js +23 -0
- data/public/javascripts/localization/messages_hu.js +21 -0
- data/public/javascripts/localization/messages_it.js +26 -0
- data/public/javascripts/localization/messages_kk.js +23 -0
- data/public/javascripts/localization/messages_nl.js +23 -0
- data/public/javascripts/localization/messages_no.js +23 -0
- data/public/javascripts/localization/messages_pl.js +23 -0
- data/public/javascripts/localization/messages_ptbr.js +30 -0
- data/public/javascripts/localization/messages_ro.js +24 -0
- data/public/javascripts/localization/messages_ru.js +23 -0
- data/public/javascripts/localization/messages_se.js +23 -0
- data/public/javascripts/localization/messages_sk.js +21 -0
- data/public/javascripts/localization/messages_tr.js +24 -0
- data/public/javascripts/localization/messages_tw.js +24 -0
- data/public/javascripts/localization/messages_ua.js +24 -0
- data/public/javascripts/nested-attribute.js +26 -0
- data/public/javascripts/open_id.js +15 -0
- data/public/javascripts/product.js +49 -0
- data/public/javascripts/rails.js +127 -0
- data/public/javascripts/taxonomy.js +201 -0
- data/public/javascripts/zone.js +39 -0
- data/public/stylesheets/admin/admin-forms.css +154 -0
- data/public/stylesheets/admin/admin-reset.css +69 -0
- data/public/stylesheets/admin/admin-tables.css +39 -0
- data/public/stylesheets/admin/admin-typography.css +117 -0
- data/public/stylesheets/admin/admin.css +614 -0
- data/public/stylesheets/admin/autocomplete.css +73 -0
- data/public/stylesheets/admin/dashboard.css +143 -0
- data/public/stylesheets/admin/edit_checkouts.css +57 -0
- data/public/stylesheets/admin/grids.css +314 -0
- data/public/stylesheets/admin/reset-fonts-grids-2-6-0.css +7 -0
- data/public/stylesheets/admin/token-input.css +109 -0
- data/public/stylesheets/admin/yui-includes.css +14 -0
- data/public/stylesheets/datepicker.css +263 -0
- data/public/stylesheets/jquery.autocomplete.css +48 -0
- data/public/stylesheets/screen.css +916 -0
- metadata +1071 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# THIS FILE SHOULD BE OVER-RIDDEN IN YOUR SITE EXTENSION!
|
|
2
|
+
# the exact code probably won't be useful, though you're welcome to modify and reuse
|
|
3
|
+
# the current contents are mainly for testing and documentation
|
|
4
|
+
|
|
5
|
+
# set up some basic filters for use with products
|
|
6
|
+
#
|
|
7
|
+
# Each filter has two parts
|
|
8
|
+
# * a parametrized named scope which expects a list of labels
|
|
9
|
+
# * an object which describes/defines the filter
|
|
10
|
+
#
|
|
11
|
+
# The filter description has three components
|
|
12
|
+
# * a name, for displaying on pages
|
|
13
|
+
# * a named scope which will 'execute' the filter
|
|
14
|
+
# * a mapping of presentation labels to the relevant condition (in the context of the named scope)
|
|
15
|
+
# * an optional list of labels and values (for use with object selection - see taxons examples below)
|
|
16
|
+
#
|
|
17
|
+
# The named scopes here have a suffix '_any', following SearchLogic's convention for a
|
|
18
|
+
# scope which returns results which match any of the inputs. This is purely a convention,
|
|
19
|
+
# but might be a useful reminder.
|
|
20
|
+
#
|
|
21
|
+
# When creating a form, the name of the checkbox group for a filter F should be
|
|
22
|
+
# the name of F's scope with [] appended, eg "price_range_any[]", and for
|
|
23
|
+
# each label you should have a checkbox with the label as its value. On submission,
|
|
24
|
+
# Rails will send the action a hash containing (among other things) an array named
|
|
25
|
+
# after the scope whose values are the active labels.
|
|
26
|
+
#
|
|
27
|
+
# SearchLogic will then convert this array to a call to the named scope with the array
|
|
28
|
+
# contents, and the named scope will build a query with the disjunction of the conditions
|
|
29
|
+
# relating to the labels, all relative to the scope's context.
|
|
30
|
+
#
|
|
31
|
+
# The details of how/when filters are used is a detail for specific models (eg products
|
|
32
|
+
# or taxons), eg see the taxon model/controller.
|
|
33
|
+
|
|
34
|
+
# See specific filters below for concrete examples.
|
|
35
|
+
|
|
36
|
+
# This module is included by Taxon. In development mode that inclusion does not
|
|
37
|
+
# happen until Taxon class is loaded. Ensure that Taxon class is loaded before
|
|
38
|
+
# you try something like Product.price_range_any
|
|
39
|
+
module ProductFilters
|
|
40
|
+
|
|
41
|
+
# Example: filtering by price
|
|
42
|
+
# The named scope just maps incoming labels onto their conditions, and builds the conjunction
|
|
43
|
+
# 'price' is in the base scope's context (ie, "select foo from products where ...") so
|
|
44
|
+
# we can access the field right away
|
|
45
|
+
# The filter identifies which scope to use, then sets the conditions for each price range
|
|
46
|
+
#
|
|
47
|
+
# If user checks off three different price ranges then the argument passed to
|
|
48
|
+
# below scope would be something like ["$10 - $15", "$15 - $18", "$18 - $20"]
|
|
49
|
+
#
|
|
50
|
+
Product.scope :price_range_any,
|
|
51
|
+
lambda {|*opts|
|
|
52
|
+
conds = opts.map {|o| ProductFilters.price_filter[:conds][o]}.reject {|c| c.nil?}
|
|
53
|
+
Product.scoped(:joins => :master).conditions_any(conds)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
def ProductFilters.price_filter
|
|
57
|
+
conds = [ [ "Under $10", "price <= 10" ],
|
|
58
|
+
[ "$10 - $15", "price between 10 and 15" ],
|
|
59
|
+
[ "$15 - $18", "price between 15 and 18" ],
|
|
60
|
+
[ "$18 - $20", "price between 18 and 20" ],
|
|
61
|
+
[ "$20 or over", "price >= 20" ] ]
|
|
62
|
+
{ :name => "Price Range",
|
|
63
|
+
:scope => :price_range_any,
|
|
64
|
+
:conds => Hash[*conds.flatten],
|
|
65
|
+
:labels => conds.map {|k,v| [k,k]}
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# Example: filtering by possible brands
|
|
71
|
+
#
|
|
72
|
+
# First, we define the scope. Two interesting points here: (a) we run our conditions
|
|
73
|
+
# in the scope where the info for the 'brand' property has been loaded; and (b)
|
|
74
|
+
# because we may want to filter by other properties too, we give this part of the
|
|
75
|
+
# query a unique name (which must be used in the associated conditions too).
|
|
76
|
+
#
|
|
77
|
+
# Secondly, the filter. Instead of a static list of values, we pull out all existing
|
|
78
|
+
# brands from the db, and then build conditions which test for string equality on
|
|
79
|
+
# the (uniquely named) field "p_brand.value". There's also a test for brand info
|
|
80
|
+
# being blank: note that this relies on with_property doing a left outer join
|
|
81
|
+
# rather than an inner join.
|
|
82
|
+
|
|
83
|
+
if Property.table_exists? && @@brand_property = Property.find_by_name("brand")
|
|
84
|
+
Product.scope :brand_any,
|
|
85
|
+
lambda {|*opts|
|
|
86
|
+
conds = opts.map {|o| ProductFilters.brand_filter[:conds][o]}.reject {|c| c.nil?}
|
|
87
|
+
Product.with_property("brand").conditions_any(conds)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
def ProductFilters.brand_filter
|
|
91
|
+
brands = ProductProperty.where(:property_id => @@brand_property).map(&:value).compact.uniq
|
|
92
|
+
conds = Hash[*brands.map {|b| [b, "product_properties.value = '#{b}'"]}.flatten]
|
|
93
|
+
{ :name => "Brands",
|
|
94
|
+
:scope => :brand_any,
|
|
95
|
+
:conds => conds,
|
|
96
|
+
:labels => (brands.sort).map {|k| [k,k]}
|
|
97
|
+
}
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Example: a parametrized filter
|
|
102
|
+
# The filter above may show brands which aren't applicable to the current taxon,
|
|
103
|
+
# so this one only shows the brands that are relevant to a particular taxon and
|
|
104
|
+
# its descendants.
|
|
105
|
+
#
|
|
106
|
+
# We don't have to give a new scope since the conditions here are a subset of the
|
|
107
|
+
# more general filter, so decoding will still work - as long as the filters on a
|
|
108
|
+
# page all have unique names (ie, you can't use the two brand filters together
|
|
109
|
+
# if they use the same scope). To be safe, the code uses a copy of the scope.
|
|
110
|
+
#
|
|
111
|
+
# HOWEVER: what happens if we want a more precise scope? we can't pass
|
|
112
|
+
# parametrized scope names to SearchLogic, only atomic names, so couldn't ask
|
|
113
|
+
# for taxon T's customized filter to be used. BUT: we can arrange for the form
|
|
114
|
+
# to pass back a hash instead of an array, where the key acts as the (taxon)
|
|
115
|
+
# parameter and value is its label array, and then get a modified named scope
|
|
116
|
+
# to get its conditions from a particular filter.
|
|
117
|
+
#
|
|
118
|
+
# The brand-finding code can be simplified if a few more named scopes were added to
|
|
119
|
+
# the product properties model.
|
|
120
|
+
|
|
121
|
+
if Property.table_exists? && @@brand_property
|
|
122
|
+
Product.scope :selective_brand_any, lambda {|opts| Product.brand_any(opts) }
|
|
123
|
+
|
|
124
|
+
def ProductFilters.selective_brand_filter(taxon = nil)
|
|
125
|
+
if taxon.nil?
|
|
126
|
+
taxon = Taxonomy.first.root
|
|
127
|
+
end
|
|
128
|
+
all_brands = ProductProperty.where(:property_id => @@brand_property).map(&:value).uniq
|
|
129
|
+
scope = ProductProperty.scoped(:conditions => ["property_id = ?", @@brand_property]).
|
|
130
|
+
scoped(:joins => {:product => :taxons},
|
|
131
|
+
:conditions => ["taxons.id in (?)", [taxon] + taxon.descendants])
|
|
132
|
+
brands = scope.map {|p| p.value}
|
|
133
|
+
|
|
134
|
+
{ :name => "Applicable Brands",
|
|
135
|
+
:scope => :selective_brand_any,
|
|
136
|
+
:conds => Hash[*all_brands.map {|m| [m, "p_colour.value like '%#{m}%'"]}.flatten],
|
|
137
|
+
:labels => brands.sort.map {|k| [k,k]}
|
|
138
|
+
}
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
# Provide filtering on the immediate children of a taxon
|
|
144
|
+
#
|
|
145
|
+
# This doesn't fit the pattern of the examples above, so there's a few changes.
|
|
146
|
+
# Firstly, it uses an existing scope which was not built for filtering - and so
|
|
147
|
+
# has no need of a conditions mapping, and secondly, it has a mapping of name
|
|
148
|
+
# to the argument type expected by the other scope.
|
|
149
|
+
#
|
|
150
|
+
# This technique is useful for filtering on objects (by passing ids) or with a
|
|
151
|
+
# scope that can be used directly (eg. testing only ever on a single property).
|
|
152
|
+
#
|
|
153
|
+
# This scope selects products in any of the active taxons or their children.
|
|
154
|
+
#
|
|
155
|
+
def ProductFilters.taxons_below(taxon)
|
|
156
|
+
return ProductFilters.all_taxons if taxon.nil?
|
|
157
|
+
{ :name => "Taxons under " + taxon.name,
|
|
158
|
+
:scope => :taxons_id_in_tree_any,
|
|
159
|
+
:labels => taxon.children.sort_by(&:position).map {|t| [t.name, t.id]},
|
|
160
|
+
:conds => nil
|
|
161
|
+
}
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Filtering by the list of all taxons
|
|
165
|
+
#
|
|
166
|
+
# Similar idea as above, but we don't want the descendants' products, hence
|
|
167
|
+
# it uses one of the auto-generated scopes from SearchLogic.
|
|
168
|
+
#
|
|
169
|
+
# idea: expand the format to allow nesting of labels?
|
|
170
|
+
def ProductFilters.all_taxons
|
|
171
|
+
taxons = Taxonomy.all.map {|t| [t.root] + t.root.descendants }.flatten
|
|
172
|
+
{ :name => "All taxons",
|
|
173
|
+
:scope => :taxons_id_equals_any,
|
|
174
|
+
:labels => taxons.sort_by(&:name).map {|t| [t.name, t.id]},
|
|
175
|
+
:conds => nil # not needed
|
|
176
|
+
}
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# This module is extended by ProductScope
|
|
2
|
+
module Scopes::Dynamic
|
|
3
|
+
module_function
|
|
4
|
+
|
|
5
|
+
# Sample dynamic scope generating from set of products
|
|
6
|
+
# generates 0 or (2..scope_limit) scopes for prices, based
|
|
7
|
+
# on number of products (uses Math.log, to guess number of scopes)
|
|
8
|
+
def price_scopes_for(products, scope_limit=5)
|
|
9
|
+
scopes = []
|
|
10
|
+
|
|
11
|
+
# Price based scopes
|
|
12
|
+
all_prices = products.map(&:price).sort
|
|
13
|
+
|
|
14
|
+
ranges = [Math.log(products.length).floor, scope_limit].max
|
|
15
|
+
|
|
16
|
+
if ranges >= 2
|
|
17
|
+
l = all_prices.length / ranges
|
|
18
|
+
scopes << ProductScope.new({:name => "master_price_lte", :arguments => [all_prices[l]] })
|
|
19
|
+
|
|
20
|
+
(ranges - 2).times do |x|
|
|
21
|
+
scopes << ProductScope.new({:name => "price_between",
|
|
22
|
+
:arguments => [ all_prices[l*(x+1)+1], all_prices[l*(x+2)] ] })
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
scopes << ProductScope.new({:name => "master_price_gte", :arguments => [all_prices[l*(ranges-1)+1]] })
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
scopes
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
module Scopes::Product
|
|
2
|
+
#TODO: change this to array pairs so we preserve order?
|
|
3
|
+
|
|
4
|
+
SCOPES = {
|
|
5
|
+
# Scopes for selecting products based on taxon
|
|
6
|
+
:taxon => {
|
|
7
|
+
:taxons_name_eq => [:taxon_name],
|
|
8
|
+
:in_taxons => [:taxon_names],
|
|
9
|
+
},
|
|
10
|
+
# product selection based on name, or search
|
|
11
|
+
:search => {
|
|
12
|
+
:in_name => [:words],
|
|
13
|
+
:in_name_or_keywords => [:words],
|
|
14
|
+
:in_name_or_description => [:words],
|
|
15
|
+
:with_ids => [:ids]
|
|
16
|
+
},
|
|
17
|
+
# Scopes for selecting products based on option types and properties
|
|
18
|
+
:values => {
|
|
19
|
+
:with => [:value],
|
|
20
|
+
:with_property => [:property],
|
|
21
|
+
:with_property_value => [:property, :value],
|
|
22
|
+
:with_option => [:option],
|
|
23
|
+
:with_option_value => [:option, :value],
|
|
24
|
+
},
|
|
25
|
+
# product selection based upon master price
|
|
26
|
+
:price => {
|
|
27
|
+
:price_between => [:low, :high],
|
|
28
|
+
:master_price_lte => [:amount],
|
|
29
|
+
:master_price_gte => [:amount],
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
ORDERING = [
|
|
34
|
+
:ascend_by_updated_at,
|
|
35
|
+
:descend_by_updated_at,
|
|
36
|
+
:ascend_by_name,
|
|
37
|
+
:descend_by_name,
|
|
38
|
+
:ascend_by_master_price,
|
|
39
|
+
:descend_by_master_price,
|
|
40
|
+
:descend_by_popularity,
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
ORDERING.each do |name|
|
|
44
|
+
next if %w(asecend_by_master_price descend_by_master_price).include?(name.to_s)
|
|
45
|
+
r = name.to_s.match(/(.*)_by_(.*)/)
|
|
46
|
+
|
|
47
|
+
order_text = "products.#{r[2]} "
|
|
48
|
+
order_text << ((r[1] == 'ascend') ? "asc" : "desc")
|
|
49
|
+
|
|
50
|
+
Product.send(:scope, name.to_s, Product.send(:relation).order(order_text) )
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
::Product.scope :ascend_by_master_price, Product.joins(:variants_with_only_master).order('variants.price asc')
|
|
54
|
+
|
|
55
|
+
::Product.scope :descend_by_master_price, Product.joins(:variants_with_only_master).order('variants.price desc')
|
|
56
|
+
|
|
57
|
+
ATTRIBUTE_HELPER_METHODS = {
|
|
58
|
+
:with_ids => :product_picker_field
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
# Ryan Bates - http://railscasts.com/episodes/112
|
|
62
|
+
# general merging of conditions, names following the searchlogic pattern
|
|
63
|
+
::Product.scope :conditions, lambda { |*args| {:conditions => args}}
|
|
64
|
+
|
|
65
|
+
# conditions_all is a more descriptively named enhancement of the above
|
|
66
|
+
::Product.scope :conditions_all, lambda { |*args| {:conditions => [args].flatten}}
|
|
67
|
+
|
|
68
|
+
# forming the disjunction of a list of conditions (as strings)
|
|
69
|
+
::Product.scope :conditions_any, lambda { |*args|
|
|
70
|
+
args = [args].flatten
|
|
71
|
+
raise "non-strings in conditions_any" unless args.all? {|s| s.is_a? String}
|
|
72
|
+
{:conditions => args.map {|c| "(#{c})"}.join(" OR ")}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
::Product.scope :price_between, lambda { |low, high|
|
|
77
|
+
{ :joins => :master, :conditions => ["variants.price BETWEEN ? AND ?", low, high] }
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
::Product.scope :master_price_lte, lambda { |price|
|
|
81
|
+
{ :joins => :master, :conditions => ["variants.price <= ?", price] }
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
::Product.scope :master_price_gte, lambda { |price|
|
|
85
|
+
{ :joins => :master, :conditions => ["variants.price >= ?", price] }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# This scope selects products in taxon AND all its descendants
|
|
90
|
+
# If you need products only within one taxon use
|
|
91
|
+
#
|
|
92
|
+
# Product.taxons_id_eq(x)
|
|
93
|
+
#
|
|
94
|
+
::Product.scope :in_taxon, lambda {|taxon|
|
|
95
|
+
{ :joins => :taxons, :conditions => ["taxons.id IN (?) ", taxon.self_and_descendants.map(&:id)]}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
# This scope selects products in all taxons AND all its descendants
|
|
99
|
+
# If you need products only within one taxon use
|
|
100
|
+
#
|
|
101
|
+
# Product.taxons_id_eq([x,y])
|
|
102
|
+
#
|
|
103
|
+
Product.scope :in_taxons, lambda {|*taxons|
|
|
104
|
+
taxons = get_taxons(taxons)
|
|
105
|
+
taxons.first ? prepare_taxon_conditions(taxons) : {}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
# for quick access to products in a group, WITHOUT using the association mechanism
|
|
109
|
+
Product.scope :in_cached_group, lambda {|product_group|
|
|
110
|
+
{ :joins => "JOIN product_groups_products ON products.id = product_groups_products.product_id",
|
|
111
|
+
:conditions => ["product_groups_products.product_group_id = ?", product_group]
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
# a scope that finds all products having property specified by name, object or id
|
|
117
|
+
Product.scope :with_property, lambda {|property|
|
|
118
|
+
conditions = case property
|
|
119
|
+
when String then ["properties.name = ?", property]
|
|
120
|
+
when Property then ["properties.id = ?", property.id]
|
|
121
|
+
else ["properties.id = ?", property.to_i]
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
{
|
|
125
|
+
:joins => :properties,
|
|
126
|
+
:conditions => conditions
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
# a scope that finds all products having an option_type specified by name, object or id
|
|
131
|
+
Product.scope :with_option, lambda {|option|
|
|
132
|
+
conditions = case option
|
|
133
|
+
when String then ["option_types.name = ?", option]
|
|
134
|
+
when OptionType then ["option_types.id = ?", option.id]
|
|
135
|
+
else ["option_types.id = ?", option.to_i]
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
{
|
|
139
|
+
:joins => :option_types,
|
|
140
|
+
:conditions => conditions
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
# a simple test for product with a certain property-value pairing
|
|
145
|
+
# note that it can test for properties with NULL values, but not for absent values
|
|
146
|
+
Product.scope :with_property_value, lambda { |property, value|
|
|
147
|
+
conditions = case property
|
|
148
|
+
when String then ["properties.name = ?", property]
|
|
149
|
+
when Property then ["properties.id = ?", property.id]
|
|
150
|
+
else ["properties.id = ?", property.to_i]
|
|
151
|
+
end
|
|
152
|
+
conditions = ["product_properties.value = ? AND #{conditions[0]}", value, conditions[1]]
|
|
153
|
+
|
|
154
|
+
{
|
|
155
|
+
:joins => :properties,
|
|
156
|
+
:conditions => conditions
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
# a scope that finds all products having an option value specified by name, object or id
|
|
161
|
+
Product.scope :with_option_value, lambda {|option, value|
|
|
162
|
+
option_type_id = case option
|
|
163
|
+
when String
|
|
164
|
+
option_type = OptionType.find_by_name(option) || option.to_i
|
|
165
|
+
when OptionType
|
|
166
|
+
option.id
|
|
167
|
+
else
|
|
168
|
+
option.to_i
|
|
169
|
+
end
|
|
170
|
+
conditions = [
|
|
171
|
+
"option_values.name = ? AND option_values.option_type_id = ?",
|
|
172
|
+
value, option_type_id
|
|
173
|
+
]
|
|
174
|
+
|
|
175
|
+
{
|
|
176
|
+
:joins => {:variants => :option_values},
|
|
177
|
+
:conditions => conditions
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
# finds product having option value OR product_property
|
|
182
|
+
Product.scope :with, lambda{|value|
|
|
183
|
+
{
|
|
184
|
+
:conditions => ["option_values.name = ? OR product_properties.value = ?", value, value],
|
|
185
|
+
:joins => {:variants => :option_values, :product_properties => []}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
Product.scope :in_name, lambda{|words|
|
|
190
|
+
Product.like_any([:name], prepare_words(words))
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
Product.scope :in_name_or_keywords, lambda{|words|
|
|
194
|
+
Product.like_any([:name, :meta_keywords], prepare_words(words))
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
Product.scope :in_name_or_description, lambda{|words|
|
|
198
|
+
Product.like_any([:name, :description, :meta_description, :meta_keywords], prepare_words(words))
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
Product.scope :with_ids, lambda{|ids|
|
|
202
|
+
ids = ids.split(',') if ids.is_a?(String)
|
|
203
|
+
{ :conditions => {:id => ids} }
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
# Sorts products from most popular (poularity is extracted from how many
|
|
207
|
+
# times use has put product in cart, not completed orders)
|
|
208
|
+
#
|
|
209
|
+
# there is alternative faster and more elegant solution, it has small drawback though,
|
|
210
|
+
# it doesn stack with other scopes :/
|
|
211
|
+
#
|
|
212
|
+
# :joins => "LEFT OUTER JOIN (SELECT line_items.variant_id as vid, COUNT(*) as cnt FROM line_items GROUP BY line_items.variant_id) AS popularity_count ON variants.id = vid",
|
|
213
|
+
# :order => 'COALESCE(cnt, 0) DESC'
|
|
214
|
+
Product.scope :descend_by_popularity,
|
|
215
|
+
{
|
|
216
|
+
:joins => :master,
|
|
217
|
+
:order => <<SQL
|
|
218
|
+
COALESCE((
|
|
219
|
+
SELECT
|
|
220
|
+
COUNT(line_items.id)
|
|
221
|
+
FROM
|
|
222
|
+
line_items
|
|
223
|
+
JOIN
|
|
224
|
+
variants as popular_variants
|
|
225
|
+
ON
|
|
226
|
+
popular_variants.id = line_items.variant_id
|
|
227
|
+
WHERE
|
|
228
|
+
popular_variants.product_id = products.id
|
|
229
|
+
), 0) DESC
|
|
230
|
+
SQL
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
# Produce an array of keywords for use in scopes.
|
|
234
|
+
# Always return array with at least an empty string to avoid SQL errors
|
|
235
|
+
def self.prepare_words(words)
|
|
236
|
+
return [''] if words.blank?
|
|
237
|
+
a = words.split(/[,\s]/).map(&:strip)
|
|
238
|
+
a.any? ? a : ['']
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def self.arguments_for_scope_name(name)
|
|
242
|
+
if group = Scopes::Product::SCOPES.detect{|k,v| v[name.to_sym]}
|
|
243
|
+
group[1][name.to_sym]
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def self.get_taxons(*ids_or_records_or_names)
|
|
248
|
+
ids_or_records_or_names.flatten.map { |t|
|
|
249
|
+
case t
|
|
250
|
+
when Integer then Taxon.find_by_id(t)
|
|
251
|
+
when ActiveRecord::Base then t
|
|
252
|
+
when String
|
|
253
|
+
Taxon.find_by_name(t) ||
|
|
254
|
+
Taxon.find(:first, :conditions => [
|
|
255
|
+
"taxons.permalink LIKE ? OR taxons.permalink = ?", "%/#{t}/", "#{t}/"
|
|
256
|
+
])
|
|
257
|
+
end
|
|
258
|
+
}.compact.uniq
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
# specifically avoid having an order for taxon search (conflicts with main order)
|
|
262
|
+
def self.prepare_taxon_conditions(taxons)
|
|
263
|
+
ids = taxons.map{|taxon| taxon.self_and_descendants.map(&:id)}.flatten.uniq
|
|
264
|
+
{ :joins => :taxons, :conditions => ["taxons.id IN (?)", ids] }
|
|
265
|
+
end
|
|
266
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Scopes::Variant
|
|
2
|
+
|
|
3
|
+
#FIXME WARNING tested only under sqlite and postgresql
|
|
4
|
+
Variant.scope :descend_by_popularity, lambda{
|
|
5
|
+
order('COALESCE((SELECT COUNT(*) FROM line_items GROUP BY line_items.variant_id HAVING line_items.variant_id = variants.id), 0) DESC')
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
# for selecting variants with an option value
|
|
9
|
+
# no option type given since the value implies an option type
|
|
10
|
+
# this scope can be chained repeatedly, since the join name is unique
|
|
11
|
+
Variant.scope :has_option, lambda {|opt|
|
|
12
|
+
tbl = 'o' + Time.now.to_i.to_s + Time.now.usec.to_s
|
|
13
|
+
{ :joins => "inner join option_values_variants as #{tbl} on variants.id = #{tbl}.variant_id",
|
|
14
|
+
:conditions => ["#{tbl}.option_value_id = (?)", opt]
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
end
|
data/lib/scopes.rb
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# This module contains all custom scopes created for selecting products.
|
|
2
|
+
#
|
|
3
|
+
# All usable scopes *should* be included in SCOPES constant, it represents
|
|
4
|
+
# all scopes that are selectable from user interface, extensions can extend
|
|
5
|
+
# and modify it, but should provide corresponding translations.
|
|
6
|
+
#
|
|
7
|
+
# Format of constant is following:
|
|
8
|
+
#
|
|
9
|
+
# {
|
|
10
|
+
# :namespace/grouping => {
|
|
11
|
+
# :name_of_the_scope => [:list, :of, :arguments]
|
|
12
|
+
# }
|
|
13
|
+
# }
|
|
14
|
+
#
|
|
15
|
+
# This values are used in translation file, to describe them in the interface.
|
|
16
|
+
# So for each scope you define here you have to provide following entry in translation file
|
|
17
|
+
# product_scopes:
|
|
18
|
+
# name_of_the_group:
|
|
19
|
+
# name: Translated name of the group
|
|
20
|
+
# description: Longer description of what this scope group does, inluding
|
|
21
|
+
# any possible help user may need
|
|
22
|
+
# scopes:
|
|
23
|
+
# name_of_the_scope:
|
|
24
|
+
# name: Short name of the scope
|
|
25
|
+
# description: What does this scope does exactly
|
|
26
|
+
# arguments:
|
|
27
|
+
# arg1: Description of argument
|
|
28
|
+
# arg2: Description of second Argument
|
|
29
|
+
#
|
|
30
|
+
module Scopes
|
|
31
|
+
module_function
|
|
32
|
+
|
|
33
|
+
def generate_translation(all_scopes)
|
|
34
|
+
result = {"groups" => {}, "scopes" => {}}
|
|
35
|
+
all_scopes.dup.each_pair do |group_name, scopes|
|
|
36
|
+
result["groups"][group_name.to_s] = {
|
|
37
|
+
'name' => group_name.to_s.humanize,
|
|
38
|
+
'description' => "Scopes for selecting products based on #{group_name.to_s}",
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
scopes.each_pair do |scope_name, targs|
|
|
42
|
+
hashed_args = {}
|
|
43
|
+
targs.each{|v| hashed_args[v.to_s] = v.to_s.humanize}
|
|
44
|
+
|
|
45
|
+
result['scopes'][scope_name.to_s] = {
|
|
46
|
+
'name' => scope_name.to_s.humanize,
|
|
47
|
+
'description' => "",
|
|
48
|
+
'args' => hashed_args.dup
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
result
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def generate_translations
|
|
57
|
+
require 'ya2yaml'
|
|
58
|
+
{
|
|
59
|
+
'product_scopes' => generate_translation(Scopes::Product::SCOPES)
|
|
60
|
+
}.ya2yaml
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Rails 3 TODO
|
|
65
|
+
# ActiveRecord::NamedScope::Scope.class_eval do
|
|
66
|
+
# def to_sql
|
|
67
|
+
# construct_finder_sql({})
|
|
68
|
+
# end
|
|
69
|
+
# end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module Spree::CalculatedAdjustments
|
|
2
|
+
module ClassMethods
|
|
3
|
+
def calculated_adjustments(options = {})
|
|
4
|
+
has_one :calculator, :as => :calculable, :dependent => :destroy
|
|
5
|
+
accepts_nested_attributes_for :calculator
|
|
6
|
+
validates :calculator, :presence => true if options[:require]
|
|
7
|
+
|
|
8
|
+
class_attribute :calculators
|
|
9
|
+
self.calculators = Set.new
|
|
10
|
+
# @available_calculators = []
|
|
11
|
+
def register_calculator(calculator)
|
|
12
|
+
self.calculators.add(calculator)
|
|
13
|
+
end
|
|
14
|
+
# def calculators
|
|
15
|
+
# @available_calculators
|
|
16
|
+
# end
|
|
17
|
+
|
|
18
|
+
if options[:default]
|
|
19
|
+
default_calculator_class = options[:default]
|
|
20
|
+
#if default_calculator_class.available?(self.new)
|
|
21
|
+
before_create :default_calculator
|
|
22
|
+
define_method(:default_calculator) do
|
|
23
|
+
self.calculator ||= default_calculator_class.new
|
|
24
|
+
end
|
|
25
|
+
# else
|
|
26
|
+
# raise(ArgumentError, "calculator #{default_calculator_class} can't be used with #{self}")
|
|
27
|
+
# end
|
|
28
|
+
else
|
|
29
|
+
define_method(:default_calculator) do
|
|
30
|
+
nil
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
include InstanceMethods
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
module InstanceMethods
|
|
39
|
+
def calculator_type
|
|
40
|
+
calculator.class.to_s if calculator
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def calculator_type=(calculator_type)
|
|
44
|
+
clazz = calculator_type.constantize if calculator_type
|
|
45
|
+
self.calculator = clazz.new if clazz and not self.calculator.is_a? clazz
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Creates a new adjustment for the target object (which is any class that has_many :adjustments) and
|
|
49
|
+
# sets amount based on the calculator as applied to the calculable argument (Order, LineItems[], Shipment, etc.)
|
|
50
|
+
# By default the adjustment will not be considered mandatory
|
|
51
|
+
def create_adjustment(label, target, calculable, mandatory=false)
|
|
52
|
+
amount = self.calculator.compute(calculable)
|
|
53
|
+
target.adjustments.create(:amount => amount, :source => calculable,
|
|
54
|
+
:originator => self,
|
|
55
|
+
:label => label,
|
|
56
|
+
:mandatory => mandatory)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Updates the amount of the adjustment using our Calculator and calling the +compute+ method with the +calculable+
|
|
60
|
+
# referenced passed to the method.
|
|
61
|
+
def update_adjustment(adjustment, calculable)
|
|
62
|
+
adjustment.update_attribute_without_callbacks(:amount, self.calculator.compute(calculable))
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.included(receiver)
|
|
67
|
+
receiver.extend Spree::CalculatedAdjustments::ClassMethods
|
|
68
|
+
end
|
|
69
|
+
end
|
data/lib/spree/config.rb
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
# Singleton class to access the configuration object (AppConfiguration.first by default) and its preferences.
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# Spree::Config[:foo] # Returns the +foo+ preference
|
|
6
|
+
# Spree::Config[] # Returns a Hash with all the application preferences
|
|
7
|
+
# Spree::Config.instance # Returns the configuration object (AppConfiguration.first)
|
|
8
|
+
# Spree::Config.set(preferences_hash) # Set the application preferences as especified in +preference_hash+
|
|
9
|
+
# Spree::Config.searcher/searcher= # get/set the default product search implementation
|
|
10
|
+
class Config
|
|
11
|
+
include Singleton
|
|
12
|
+
include Spree::PreferenceAccess
|
|
13
|
+
|
|
14
|
+
class << self
|
|
15
|
+
def instance
|
|
16
|
+
return @configuration if @configuration
|
|
17
|
+
return nil unless ActiveRecord::Base.connection.tables.include?('configurations')
|
|
18
|
+
@configuration ||= AppConfiguration.find_or_create_by_name("Default configuration")
|
|
19
|
+
@configuration
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# searcher_class allows spree extension writers to provide their own Search class
|
|
23
|
+
def searcher_class
|
|
24
|
+
@searcher_class ||= Spree::Search::Base
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def searcher_class=(sclass)
|
|
28
|
+
@searcher_class = sclass
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|