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,56 @@
|
|
|
1
|
+
class PaymentMethod < ActiveRecord::Base
|
|
2
|
+
DISPLAY = [:both, :front_end, :back_end]
|
|
3
|
+
default_scope where(:deleted_at => nil)
|
|
4
|
+
|
|
5
|
+
@provider = nil
|
|
6
|
+
@@providers = Set.new
|
|
7
|
+
def self.register
|
|
8
|
+
@@providers.add(self)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.providers
|
|
12
|
+
@@providers.to_a
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def provider_class
|
|
16
|
+
raise "You must implement provider_class method for this gateway."
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# The class that will process payments for this payment type, used for @payment.source
|
|
20
|
+
# e.g. Creditcard in the case of a the Gateway payment type
|
|
21
|
+
# nil means the payment method doesn't require a source e.g. check
|
|
22
|
+
def payment_source_class
|
|
23
|
+
raise "You must implement payment_source_class method for this gateway."
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.available(display_on='both')
|
|
27
|
+
PaymentMethod.all.select { |p| p.active && (p.display_on == display_on.to_s || p.display_on.blank?) && (p.environment == Rails.env || p.environment.blank?) }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.active?
|
|
31
|
+
self.count(:conditions => {:type => self.to_s, :environment => Rails.env, :active => true}) > 0
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.current
|
|
35
|
+
PaymentMethod.find(:first, :conditions => {:active => true, :environment => Rails.env})
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def method_type
|
|
39
|
+
type.demodulize.downcase
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def destroy
|
|
43
|
+
self.update_attribute(:deleted_at, Time.now.utc)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def self.find_with_destroyed *args
|
|
47
|
+
self.with_exclusive_scope { find(*args) }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def payment_profiles_supported?
|
|
51
|
+
false
|
|
52
|
+
end
|
|
53
|
+
def source_required?
|
|
54
|
+
true
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Represents a preferred value for a particular preference on a model.
|
|
2
|
+
#
|
|
3
|
+
# == Targeted preferences
|
|
4
|
+
#
|
|
5
|
+
# In addition to simple named preferences, preferences can also be targeted for
|
|
6
|
+
# a particular record. For example, a User may have a preferred color for a
|
|
7
|
+
# particular Car. In this case, the +owner+ is the User, the +preference+ is
|
|
8
|
+
# the color, and the +target+ is the Car. This allows preferences to have a sort
|
|
9
|
+
# of context around them.
|
|
10
|
+
class Preference < ActiveRecord::Base
|
|
11
|
+
belongs_to :owner, :polymorphic => true
|
|
12
|
+
belongs_to :group, :polymorphic => true
|
|
13
|
+
|
|
14
|
+
validates :name, :owner_id, :owner_type, :presence => true
|
|
15
|
+
validates :group_type, :presence => true, :if => :group_id?
|
|
16
|
+
|
|
17
|
+
class << self
|
|
18
|
+
# Splits the given group into its corresponding id and type
|
|
19
|
+
def split_group(group = nil)
|
|
20
|
+
if group.is_a?(ActiveRecord::Base)
|
|
21
|
+
group_id, group_type = group.id, group.class.base_class.name.to_s
|
|
22
|
+
else
|
|
23
|
+
group_id, group_type = nil, group
|
|
24
|
+
end
|
|
25
|
+
return group_id, group_type
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# The definition for the attribute
|
|
30
|
+
def definition
|
|
31
|
+
owner.preference_definitions[name] unless owner_type.blank?
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Typecasts the value depending on the preference definition's declared type
|
|
35
|
+
def value
|
|
36
|
+
value = read_attribute(:value)
|
|
37
|
+
value = definition.type_cast(value) if definition
|
|
38
|
+
value
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Only searches for the group record if the group id is specified
|
|
42
|
+
def group_with_optional_lookup
|
|
43
|
+
group_id ? group_without_optional_lookup : group_type
|
|
44
|
+
end
|
|
45
|
+
alias_method_chain :group, :optional_lookup
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# Most of this code is taken from the preferences plugin available
|
|
50
|
+
# at http://github.com/pluginaweek/preferences/tree/master
|
|
51
|
+
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# PRODUCTS
|
|
2
|
+
# Products represent an entity for sale in a store.
|
|
3
|
+
# Products can have variations, called variants
|
|
4
|
+
# Products properties include description, permalink, availability,
|
|
5
|
+
# shipping category, etc. that do not change by variant.
|
|
6
|
+
#
|
|
7
|
+
# MASTER VARIANT
|
|
8
|
+
# Every product has one master variant, which stores master price and sku, size and weight, etc.
|
|
9
|
+
# The master variant does not have option values associated with it.
|
|
10
|
+
# Price, SKU, size, weight, etc. are all delegated to the master variant.
|
|
11
|
+
# Contains on_hand inventory levels only when there are no variants for the product.
|
|
12
|
+
#
|
|
13
|
+
# VARIANTS
|
|
14
|
+
# All variants can access the product properties directly (via reverse delegation).
|
|
15
|
+
# Inventory units are tied to Variant.
|
|
16
|
+
# The master variant can have inventory units, but not option values.
|
|
17
|
+
# All other variants have option values and may have inventory units.
|
|
18
|
+
# Sum of on_hand each variant's inventory level determine "on_hand" level for the product.
|
|
19
|
+
#
|
|
20
|
+
class Product < ActiveRecord::Base
|
|
21
|
+
has_many :product_option_types, :dependent => :destroy
|
|
22
|
+
has_many :option_types, :through => :product_option_types
|
|
23
|
+
has_many :product_properties, :dependent => :destroy
|
|
24
|
+
has_many :properties, :through => :product_properties
|
|
25
|
+
has_many :images, :as => :viewable, :order => :position, :dependent => :destroy
|
|
26
|
+
has_and_belongs_to_many :product_groups
|
|
27
|
+
belongs_to :tax_category
|
|
28
|
+
has_and_belongs_to_many :taxons
|
|
29
|
+
belongs_to :shipping_category
|
|
30
|
+
|
|
31
|
+
has_one :master,
|
|
32
|
+
:class_name => 'Variant',
|
|
33
|
+
:conditions => ["variants.is_master = ? AND variants.deleted_at IS NULL", true]
|
|
34
|
+
|
|
35
|
+
delegate_belongs_to :master, :sku, :price, :weight, :height, :width, :depth, :is_master
|
|
36
|
+
delegate_belongs_to :master, :cost_price if Variant.table_exists? && Variant.column_names.include?("cost_price")
|
|
37
|
+
|
|
38
|
+
after_create :set_master_variant_defaults
|
|
39
|
+
after_create :add_properties_and_option_types_from_prototype
|
|
40
|
+
before_save :recalculate_count_on_hand
|
|
41
|
+
before_update :sanitize_permalink
|
|
42
|
+
after_save :update_memberships if ProductGroup.table_exists?
|
|
43
|
+
after_save :set_master_on_hand_to_zero_when_product_has_variants
|
|
44
|
+
after_save :save_master
|
|
45
|
+
|
|
46
|
+
has_many :variants,
|
|
47
|
+
:conditions => ["variants.is_master = ? AND variants.deleted_at IS NULL", false],
|
|
48
|
+
:order => 'variants.position ASC'
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
has_many :variants_including_master,
|
|
52
|
+
:class_name => 'Variant',
|
|
53
|
+
:conditions => ["variants.deleted_at IS NULL"],
|
|
54
|
+
:dependent => :destroy
|
|
55
|
+
|
|
56
|
+
has_many :variants_with_only_master,
|
|
57
|
+
:class_name => 'Variant',
|
|
58
|
+
:conditions => ["variants.deleted_at IS NULL AND variants.is_master = ?", true],
|
|
59
|
+
:dependent => :destroy
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
validates :name, :price, :permalink,:available_on, :presence => true
|
|
63
|
+
|
|
64
|
+
accepts_nested_attributes_for :product_properties, :allow_destroy => true, :reject_if => lambda { |pp| pp[:property_name].blank? }
|
|
65
|
+
|
|
66
|
+
make_permalink
|
|
67
|
+
|
|
68
|
+
alias :options :product_option_types
|
|
69
|
+
|
|
70
|
+
include ::Scopes::Product
|
|
71
|
+
|
|
72
|
+
#RAILS3 TODO - scopes are duplicated here and in scopres/product.rb - can we DRY it up?
|
|
73
|
+
# default product scope only lists available and non-deleted products
|
|
74
|
+
scope :not_deleted, where("products.deleted_at is NULL")
|
|
75
|
+
|
|
76
|
+
scope :available, lambda { |*on| where("products.available_on <= ?", on.first || Time.zone.now ) }
|
|
77
|
+
|
|
78
|
+
#RAILS 3 TODO - this scope doesn't match the original 2.3.x version, needs attention (but it works)
|
|
79
|
+
scope :active, lambda{ not_deleted.available }
|
|
80
|
+
|
|
81
|
+
scope :on_hand, where("products.count_on_hand > 0")
|
|
82
|
+
|
|
83
|
+
if (ActiveRecord::Base.connection.adapter_name == 'PostgreSQL')
|
|
84
|
+
if ActiveRecord::Base.connection.tables.include?("products")
|
|
85
|
+
scope :group_by_products_id, { :group => "products." + Product.column_names.join(", products.") }
|
|
86
|
+
end
|
|
87
|
+
else
|
|
88
|
+
scope :group_by_products_id, { :group => "products.id" }
|
|
89
|
+
end
|
|
90
|
+
search_methods :group_by_products_id
|
|
91
|
+
|
|
92
|
+
scope :id_equals, lambda { |input_id| where("products.id = ?", input_id) }
|
|
93
|
+
|
|
94
|
+
scope :taxons_name_eq, lambda { |name| joins(:taxons).where("taxons.name = ?", name) }
|
|
95
|
+
|
|
96
|
+
# ----------------------------------------------------------------------------------------------------------
|
|
97
|
+
#
|
|
98
|
+
# The following methods are deprecated and will be removed in a future version of Spree
|
|
99
|
+
#
|
|
100
|
+
# ----------------------------------------------------------------------------------------------------------
|
|
101
|
+
|
|
102
|
+
def master_price
|
|
103
|
+
warn "[DEPRECATION] `Product.master_price` is deprecated. Please use `Product.price` instead. (called from #{caller[0]})"
|
|
104
|
+
self.price
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def master_price=(value)
|
|
108
|
+
warn "[DEPRECATION] `Product.master_price=` is deprecated. Please use `Product.price=` instead. (called from #{caller[0]})"
|
|
109
|
+
self.price = value
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def variants?
|
|
113
|
+
warn "[DEPRECATION] `Product.variants?` is deprecated. Please use `Product.has_variants?` instead. (called from #{caller[0]})"
|
|
114
|
+
self.has_variants?
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def variant
|
|
118
|
+
warn "[DEPRECATION] `Product.variant` is deprecated. Please use `Product.master` instead. (called from #{caller[0]})"
|
|
119
|
+
self.master
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# ----------------------------------------------------------------------------------------------------------
|
|
123
|
+
# end deprecation region
|
|
124
|
+
# ----------------------------------------------------------------------------------------------------------
|
|
125
|
+
|
|
126
|
+
def to_param
|
|
127
|
+
return permalink if permalink.present?
|
|
128
|
+
name.to_url
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# returns true if the product has any variants (the master variant is not a member of the variants array)
|
|
132
|
+
def has_variants?
|
|
133
|
+
!variants.empty?
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# returns the number of inventory units "on_hand" for this product
|
|
137
|
+
def on_hand
|
|
138
|
+
has_variants? ? variants.inject(0){|sum, v| sum + v.on_hand} : master.on_hand
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# adjusts the "on_hand" inventory level for the product up or down to match the given new_level
|
|
142
|
+
def on_hand=(new_level)
|
|
143
|
+
raise "cannot set on_hand of product with variants" if has_variants? && Spree::Config[:track_inventory_levels]
|
|
144
|
+
master.on_hand = new_level
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Returns true if there are inventory units (any variant) with "on_hand" state for this product
|
|
148
|
+
def has_stock?
|
|
149
|
+
master.in_stock? || !!variants.detect{|v| v.in_stock?}
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def tax_category
|
|
153
|
+
if self[:tax_category_id].nil?
|
|
154
|
+
TaxCategory.first(:conditions => {:is_default => true})
|
|
155
|
+
else
|
|
156
|
+
TaxCategory.find(self[:tax_category_id])
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Adding properties and option types on creation based on a chosen prototype
|
|
161
|
+
attr_reader :prototype_id
|
|
162
|
+
def prototype_id=(value)
|
|
163
|
+
@prototype_id = value.to_i
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def add_properties_and_option_types_from_prototype
|
|
167
|
+
if prototype_id && prototype = Prototype.find_by_id(prototype_id)
|
|
168
|
+
prototype.properties.each do |property|
|
|
169
|
+
product_properties.create(:property => property)
|
|
170
|
+
end
|
|
171
|
+
self.option_types = prototype.option_types
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# for adding products which are closely related to existing ones
|
|
176
|
+
# define "duplicate_extra" for site-specific actions, eg for additional fields
|
|
177
|
+
def duplicate
|
|
178
|
+
p = self.clone
|
|
179
|
+
p.name = 'COPY OF ' + self.name
|
|
180
|
+
p.deleted_at = nil
|
|
181
|
+
p.created_at = p.updated_at = nil
|
|
182
|
+
p.taxons = self.taxons
|
|
183
|
+
|
|
184
|
+
p.product_properties = self.product_properties.map {|q| r = q.clone; r.created_at = r.updated_at = nil; r}
|
|
185
|
+
|
|
186
|
+
image_clone = lambda {|i| j = i.clone; j.attachment = i.attachment.clone; j}
|
|
187
|
+
p.images = self.images.map {|i| image_clone.call i}
|
|
188
|
+
|
|
189
|
+
variant = self.master.clone
|
|
190
|
+
variant.sku = 'COPY OF ' + self.master.sku
|
|
191
|
+
variant.deleted_at = nil
|
|
192
|
+
variant.images = self.master.images.map {|i| image_clone.call i}
|
|
193
|
+
p.master = variant
|
|
194
|
+
|
|
195
|
+
if self.has_variants?
|
|
196
|
+
# don't clone the actual variants, just the characterising types
|
|
197
|
+
p.option_types = self.option_types
|
|
198
|
+
else
|
|
199
|
+
end
|
|
200
|
+
# allow site to do some customization
|
|
201
|
+
p.send(:duplicate_extra) if p.respond_to?(:duplicate_extra)
|
|
202
|
+
p.save!
|
|
203
|
+
p
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# use deleted? rather than checking the attribute directly. this
|
|
207
|
+
# allows extensions to override deleted? if they want to provide
|
|
208
|
+
# their own definition.
|
|
209
|
+
def deleted?
|
|
210
|
+
!!deleted_at
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# split variants list into hash which shows mapping of opt value onto matching variants
|
|
214
|
+
# eg categorise_variants_from_option(color) => {"red" -> [...], "blue" -> [...]}
|
|
215
|
+
def categorise_variants_from_option(opt_type)
|
|
216
|
+
return {} unless option_types.include?(opt_type)
|
|
217
|
+
variants.active.group_by {|v| v.option_values.detect {|o| o.option_type == opt_type} }
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def self.like_any(fields, values)
|
|
221
|
+
where_str = fields.map{|field| Array.new(values.size, "products.#{field} #{LIKE} ?").join(' OR ') }.join(' OR ')
|
|
222
|
+
self.where([where_str, values.map{|value| "%#{value}%"} * fields.size].flatten)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
private
|
|
226
|
+
|
|
227
|
+
def sanitize_permalink
|
|
228
|
+
self.permalink = self.permalink.to_url
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def recalculate_count_on_hand
|
|
232
|
+
product_count_on_hand = has_variants? ?
|
|
233
|
+
variants.inject(0) {|acc, v| acc + v.count_on_hand} :
|
|
234
|
+
(master ? master.count_on_hand : 0)
|
|
235
|
+
self.count_on_hand = product_count_on_hand
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# the master on_hand is meaningless once a product has variants as the inventory
|
|
239
|
+
# units are now "contained" within the product variants
|
|
240
|
+
def set_master_on_hand_to_zero_when_product_has_variants
|
|
241
|
+
master.on_hand = 0 if has_variants? && Spree::Config[:track_inventory_levels]
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# ensures the master variant is flagged as such
|
|
245
|
+
def set_master_variant_defaults
|
|
246
|
+
master.is_master = true
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# there's a weird quirk with the delegate stuff that does not automatically save the delegate object
|
|
250
|
+
# when saving so we force a save using a hook.
|
|
251
|
+
def save_master
|
|
252
|
+
master.save if master && (master.changed? || master.new_record?)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def update_memberships
|
|
256
|
+
self.product_groups = ProductGroup.all.select{|pg| pg.include?(self)}
|
|
257
|
+
end
|
|
258
|
+
end
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# *ProductGroups* are used for creating and managing sets of products.
|
|
2
|
+
# Product group can be either anonymous(adhoc) or named.
|
|
3
|
+
#
|
|
4
|
+
# Anonymous Product groups are created by combining product scopes generated from url
|
|
5
|
+
# in 2 formats:
|
|
6
|
+
#
|
|
7
|
+
# /t/*taxons/s/name_of_scope/comma_separated_arguments/name_of_scope_that_doesn_take_any//order
|
|
8
|
+
# */s/name_of_scope/comma_separated_arguments/name_of_scope_that_doesn_take_any//order
|
|
9
|
+
#
|
|
10
|
+
# Named product groups can be created from anonymous ones, lub from another named scope
|
|
11
|
+
# (using ProductGroup.from_url method).
|
|
12
|
+
# Named product groups have pernament urls, that don't change even after changes
|
|
13
|
+
# to scopes are made, and come in two types.
|
|
14
|
+
#
|
|
15
|
+
# /t/*taxons/pg/named_product_group
|
|
16
|
+
# */pg/named_product_group
|
|
17
|
+
#
|
|
18
|
+
# first one is used for combining named scope with taxons, named product group can
|
|
19
|
+
# have #in_taxon or #taxons_name_eq scope defined, result should combine both
|
|
20
|
+
# and return products that exist in both taxons.
|
|
21
|
+
#
|
|
22
|
+
# ProductGroup#dynamic_products returns chain of named scopes generated from order and
|
|
23
|
+
# product scopes. So you can do counting, calculations etc, on resulted set of products,
|
|
24
|
+
# without retriving all records.
|
|
25
|
+
#
|
|
26
|
+
# ProductGroup operates on named scopes defined for product in Scopes::Product,
|
|
27
|
+
# or generated automatically by meta_search
|
|
28
|
+
#
|
|
29
|
+
class ProductGroup < ActiveRecord::Base
|
|
30
|
+
validates :name, :presence => true # TODO ensure that this field is defined as not_null
|
|
31
|
+
validates_associated :product_scopes
|
|
32
|
+
|
|
33
|
+
before_save :set_permalink
|
|
34
|
+
after_save :update_memberships
|
|
35
|
+
|
|
36
|
+
has_and_belongs_to_many :cached_products, :class_name => "Product"
|
|
37
|
+
# name
|
|
38
|
+
has_many :product_scopes
|
|
39
|
+
accepts_nested_attributes_for :product_scopes
|
|
40
|
+
|
|
41
|
+
# Testing utility: creates new *ProductGroup* from search permalink url.
|
|
42
|
+
# Follows conventions for accessing PGs from URLs, as decoded in routes
|
|
43
|
+
def self.from_url(url)
|
|
44
|
+
pg = nil;
|
|
45
|
+
case url
|
|
46
|
+
when /\/t\/(.+?)\/s\/(.+)/ then taxons = $1; attrs = $2;
|
|
47
|
+
when /\/t\/(.+?)\/pg\/(.+)/ then taxons = $1; pg_name = $2;
|
|
48
|
+
when /(.*?)\/s\/(.+)/ then attrs = $2;
|
|
49
|
+
when /(.*?)\/pg\/(.+)/ then pg_name = $2;
|
|
50
|
+
else return(nil)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if pg_name && opg = ProductGroup.find_by_permalink(pg_name)
|
|
54
|
+
pg = new.from_product_group(opg)
|
|
55
|
+
elsif attrs
|
|
56
|
+
attrs = url.split("/")
|
|
57
|
+
pg = new.from_route(attrs)
|
|
58
|
+
end
|
|
59
|
+
taxon = taxons && taxons.split("/").last
|
|
60
|
+
pg.add_scope("in_taxon", taxon) if taxon
|
|
61
|
+
|
|
62
|
+
pg
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def from_product_group(opg)
|
|
66
|
+
self.product_scopes = opg.product_scopes.map{|ps|
|
|
67
|
+
ps = ps.clone;
|
|
68
|
+
ps.product_group_id = nil;
|
|
69
|
+
ps.product_group = self;
|
|
70
|
+
ps
|
|
71
|
+
}
|
|
72
|
+
self
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def from_route(attrs)
|
|
76
|
+
self.order_scope = attrs.pop if attrs.length % 2 == 1
|
|
77
|
+
attrs.each_slice(2) do |scope|
|
|
78
|
+
next unless Product.respond_to?(scope.first)
|
|
79
|
+
add_scope(scope.first, scope.last.split(","))
|
|
80
|
+
end
|
|
81
|
+
self
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def from_search(search_hash)
|
|
85
|
+
search_hash.each_pair do |scope_name, scope_attribute|
|
|
86
|
+
add_scope(scope_name, scope_attribute)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
self
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def add_scope(scope_name, arguments=[])
|
|
93
|
+
if scope_name.to_s !~ /eval|send|system|[^a-z0-9_!?]/
|
|
94
|
+
self.product_scopes << ProductScope.new({
|
|
95
|
+
:name => scope_name.to_s,
|
|
96
|
+
:arguments => [*arguments]
|
|
97
|
+
})
|
|
98
|
+
else
|
|
99
|
+
raise ArgumentError.new("'#{scope_name}` can't be used as scope")
|
|
100
|
+
end
|
|
101
|
+
self
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def apply_on(scopish, use_order = true)
|
|
105
|
+
# There's bug in AR, it doesn't merge :order, instead it takes order
|
|
106
|
+
# from first nested_scope so we have to apply ordering FIRST.
|
|
107
|
+
# see #2253 on rails LH
|
|
108
|
+
base_product_scope = scopish
|
|
109
|
+
if use_order && !self.order_scope.blank? && Product.respond_to?(self.order_scope.intern)
|
|
110
|
+
base_product_scope = base_product_scope.send(self.order_scope)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
return self.product_scopes.reject {|s| s.is_ordering? }.inject(base_product_scope) do |result, scope|
|
|
114
|
+
scope.apply_on(result)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# returns chain of named scopes generated from order scope and product scopes.
|
|
120
|
+
def dynamic_products(use_order = true)
|
|
121
|
+
apply_on(Product.group_by_products_id, use_order)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Does the final ordering if requested
|
|
125
|
+
# TODO: move the order stuff out of the above - is superfluous now
|
|
126
|
+
def products(use_order = true)
|
|
127
|
+
cached_group = Product.in_cached_group(self)
|
|
128
|
+
if cached_group.limit(1).blank?
|
|
129
|
+
dynamic_products(use_order)
|
|
130
|
+
elsif !use_order
|
|
131
|
+
cached_group
|
|
132
|
+
else
|
|
133
|
+
product_scopes.select {|s|
|
|
134
|
+
s.is_ordering?
|
|
135
|
+
}.inject(cached_group) {|res,order|
|
|
136
|
+
order.apply_on(res)
|
|
137
|
+
}
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def include?(product)
|
|
142
|
+
res = apply_on(Product.id_equals(product.id), false)
|
|
143
|
+
res.count > 0
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def scopes_to_hash
|
|
147
|
+
result = {}
|
|
148
|
+
self.product_scopes.each do |scope|
|
|
149
|
+
result[scope.name] = scope.arguments
|
|
150
|
+
end
|
|
151
|
+
result
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# generates ProductGroup url
|
|
155
|
+
def to_url
|
|
156
|
+
if (new_record? || name.blank?)
|
|
157
|
+
result = ""
|
|
158
|
+
result+= self.product_scopes.map{|ps|
|
|
159
|
+
[ps.name, ps.arguments.join(",")]
|
|
160
|
+
}.flatten.join('/')
|
|
161
|
+
result+= self.order_scope if self.order_scope
|
|
162
|
+
|
|
163
|
+
result
|
|
164
|
+
else
|
|
165
|
+
name.to_url
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def set_permalink
|
|
170
|
+
self.permalink = self.name.to_url
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def update_memberships
|
|
174
|
+
# wipe everything directly to avoid expensive in-rails sorting
|
|
175
|
+
ActiveRecord::Base.connection.execute "DELETE FROM product_groups_products WHERE product_group_id = #{self.id}"
|
|
176
|
+
|
|
177
|
+
# and generate the new group entirely in SQL
|
|
178
|
+
ActiveRecord::Base.connection.execute "INSERT INTO product_groups_products #{dynamic_products(false).scoped(:select => "products.id, #{self.id}").to_sql}"
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def generate_preview(size = Spree::Config[:admin_pgroup_preview_size])
|
|
182
|
+
count = self.class.count_by_sql ["SELECT COUNT(*) FROM product_groups_products WHERE product_groups_products.product_group_id = ?", self]
|
|
183
|
+
|
|
184
|
+
return count, products.limit(size)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def to_s
|
|
188
|
+
"<ProductGroup" + (id && "[#{id}]").to_s + ":'#{to_url}'>"
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def to_param
|
|
192
|
+
self.permalink
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def order_scope
|
|
196
|
+
if scope = product_scopes.detect {|s| s.is_ordering?}
|
|
197
|
+
scope.name
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def order_scope=(scope_name)
|
|
202
|
+
if scope = product_scopes.detect {|s| s.is_ordering?}
|
|
203
|
+
scope.update_attribute(:name, scope_name)
|
|
204
|
+
else
|
|
205
|
+
self.product_scopes.build(:name => scope_name, :arguments => [])
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Build a new product group with a scope to filter by specified products
|
|
210
|
+
def self.new_from_products(products, attrs = {})
|
|
211
|
+
pg = new(attrs)
|
|
212
|
+
pg.product_scopes.build(:name => 'with_ids', :arguments => [products.map(&:id).join(',')])
|
|
213
|
+
pg
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class ProductProperty < ActiveRecord::Base
|
|
2
|
+
belongs_to :product
|
|
3
|
+
belongs_to :property
|
|
4
|
+
|
|
5
|
+
validates :property, :presence => true
|
|
6
|
+
|
|
7
|
+
# virtual attributes for use with AJAX completion stuff
|
|
8
|
+
def property_name
|
|
9
|
+
property.name if property
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def property_name=(name)
|
|
13
|
+
self.property = Property.find_by_name(name) unless name.blank?
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# *ProductScope* is model for storing named scopes with their arguments,
|
|
2
|
+
# to be used with ProductGroups.
|
|
3
|
+
#
|
|
4
|
+
# Each product Scope can be applied to Product (or product scope) with #apply_on method
|
|
5
|
+
# which returns new combined named scope
|
|
6
|
+
#
|
|
7
|
+
class ProductScope < ActiveRecord::Base
|
|
8
|
+
# name
|
|
9
|
+
# arguments
|
|
10
|
+
belongs_to :product_group
|
|
11
|
+
serialize :arguments
|
|
12
|
+
|
|
13
|
+
validate :check_validity_of_scope
|
|
14
|
+
|
|
15
|
+
extend ::Scopes::Dynamic
|
|
16
|
+
|
|
17
|
+
# Get all products with this scope
|
|
18
|
+
def products
|
|
19
|
+
if Product.respond_to?(name)
|
|
20
|
+
Product.send(name, *arguments)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Applies product scope on Product model or another named scope
|
|
25
|
+
def apply_on(another_scope)
|
|
26
|
+
array = *self.arguments
|
|
27
|
+
if Product.respond_to?(self.name.intern)
|
|
28
|
+
relation2 = if (array.blank? || array.size < 2)
|
|
29
|
+
Product.send(self.name.intern, array.try(:first))
|
|
30
|
+
else
|
|
31
|
+
Product.send(self.name.intern, *array)
|
|
32
|
+
end
|
|
33
|
+
else
|
|
34
|
+
relation2 = Product.metasearch({self.name.intern => array}).relation
|
|
35
|
+
end
|
|
36
|
+
unless another_scope.class == ActiveRecord::Relation
|
|
37
|
+
another_scope = another_scope.send(:relation)
|
|
38
|
+
end
|
|
39
|
+
another_scope.merge(relation2)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
before_validation(:on => :create) {
|
|
43
|
+
# Add default empty arguments so scope validates and errors aren't caused when previewing it
|
|
44
|
+
if name && args = Scopes::Product.arguments_for_scope_name(name)
|
|
45
|
+
self.arguments ||= ['']*args.length
|
|
46
|
+
end
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# checks validity of the named scope (if its safe and can be applied on Product)
|
|
50
|
+
def check_validity_of_scope
|
|
51
|
+
errors.add(:name, "is not a valid scope name") unless Product.respond_to?(self.name.intern)
|
|
52
|
+
apply_on(Product).limit(0) != nil
|
|
53
|
+
rescue Exception => e
|
|
54
|
+
unless Rails.env.production?
|
|
55
|
+
|
|
56
|
+
puts "name: #{self.name}"
|
|
57
|
+
puts "arguments: #{self.arguments.inspect}"
|
|
58
|
+
puts e.message
|
|
59
|
+
puts e.backtrace
|
|
60
|
+
end
|
|
61
|
+
errors.add(:arguments, "are incorrect")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# test ordering scope by looking for name pattern or missed arguments
|
|
65
|
+
def is_ordering?
|
|
66
|
+
name =~ /^(ascend_by|descend_by)/ || arguments.blank?
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def to_sentence
|
|
70
|
+
result = I18n.t(:sentence, :scope => [:product_scopes, :scopes, self.name], :default => "")
|
|
71
|
+
result = I18n.t(:name, :scope => [:product_scopes, :scopes, self.name]) if result.blank?
|
|
72
|
+
result % [*self.arguments]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def to_s
|
|
76
|
+
to_sentence
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class Property < ActiveRecord::Base
|
|
2
|
+
has_and_belongs_to_many :prototypes
|
|
3
|
+
|
|
4
|
+
has_many :product_properties, :dependent => :destroy
|
|
5
|
+
has_many :products, :through => :product_properties
|
|
6
|
+
|
|
7
|
+
validates :name, :presentation, :presence => true
|
|
8
|
+
|
|
9
|
+
scope :sorted, lambda { order(:name) }
|
|
10
|
+
|
|
11
|
+
def self.find_all_by_prototype(prototype)
|
|
12
|
+
id = prototype
|
|
13
|
+
if prototype.class == Prototype
|
|
14
|
+
id = prototype.id
|
|
15
|
+
end
|
|
16
|
+
joins('left join properties_prototypes on property_id = properties.id').where('prototype_id = ?', id)
|
|
17
|
+
end
|
|
18
|
+
end
|