solidus_core 1.2.3 → 1.3.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (573) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Rakefile +1 -1
  4. data/app/assets/javascripts/spree.js.coffee.erb +1 -1
  5. data/app/helpers/spree/base_helper.rb +21 -43
  6. data/app/helpers/spree/orders_helper.rb +0 -1
  7. data/app/helpers/spree/products_helper.rb +10 -12
  8. data/app/helpers/spree/taxons_helper.rb +4 -4
  9. data/app/mailers/spree/base_mailer.rb +1 -3
  10. data/app/mailers/spree/carton_mailer.rb +2 -2
  11. data/app/mailers/spree/order_mailer.rb +2 -2
  12. data/app/models/concerns/spree/adjustment_source.rb +12 -16
  13. data/app/models/concerns/spree/calculated_adjustments.rb +17 -14
  14. data/app/models/concerns/spree/default_price.rb +10 -26
  15. data/app/models/concerns/spree/display_money.rb +1 -1
  16. data/app/models/concerns/spree/ordered_property_value_list.rb +10 -12
  17. data/app/models/concerns/spree/ransackable_attributes.rb +6 -5
  18. data/app/models/concerns/spree/user_address_book.rb +87 -81
  19. data/app/models/concerns/spree/user_methods.rb +2 -2
  20. data/app/models/concerns/spree/user_payment_source.rb +12 -8
  21. data/app/models/spree/ability.rb +2 -2
  22. data/app/models/spree/address.rb +37 -38
  23. data/app/models/spree/adjustment.rb +2 -6
  24. data/app/models/spree/app_configuration.rb +60 -5
  25. data/app/models/spree/base.rb +1 -1
  26. data/app/models/spree/calculator/default_tax.rb +28 -24
  27. data/app/models/spree/calculator/flat_percent_item_total.rb +1 -1
  28. data/app/models/spree/calculator/flat_rate.rb +2 -2
  29. data/app/models/spree/calculator/flexi_rate.rb +4 -4
  30. data/app/models/spree/calculator/percent_per_item.rb +8 -9
  31. data/app/models/spree/calculator/price_sack.rb +3 -3
  32. data/app/models/spree/calculator/returns/default_refund_amount.rb +11 -12
  33. data/app/models/spree/calculator/shipping/flat_percent_item_total.rb +1 -1
  34. data/app/models/spree/calculator/shipping/flat_rate.rb +2 -2
  35. data/app/models/spree/calculator/shipping/flexi_rate.rb +3 -3
  36. data/app/models/spree/calculator/shipping/per_item.rb +1 -1
  37. data/app/models/spree/calculator/shipping/price_sack.rb +3 -3
  38. data/app/models/spree/calculator/tiered_flat_rate.rb +2 -1
  39. data/app/models/spree/calculator/tiered_percent.rb +2 -1
  40. data/app/models/spree/calculator.rb +3 -3
  41. data/app/models/spree/carton.rb +2 -2
  42. data/app/models/spree/country.rb +7 -4
  43. data/app/models/spree/credit_card.rb +26 -22
  44. data/app/models/spree/customer_return.rb +8 -7
  45. data/app/models/spree/exchange.rb +1 -9
  46. data/app/models/spree/gateway/bogus.rb +31 -31
  47. data/app/models/spree/gateway/bogus_simple.rb +6 -8
  48. data/app/models/spree/gateway.rb +9 -15
  49. data/app/models/spree/image.rb +3 -3
  50. data/app/models/spree/inventory_unit.rb +23 -23
  51. data/app/models/spree/item_adjustments.rb +3 -2
  52. data/app/models/spree/legacy_user.rb +1 -5
  53. data/app/models/spree/line_item.rb +95 -84
  54. data/app/models/spree/option_type.rb +1 -1
  55. data/app/models/spree/option_value.rb +3 -1
  56. data/app/models/spree/order/checkout.rb +45 -44
  57. data/app/models/spree/order/payments.rb +42 -45
  58. data/app/models/spree/order.rb +70 -75
  59. data/app/models/spree/order_cancellations.rb +4 -4
  60. data/app/models/spree/order_capturing.rb +3 -2
  61. data/app/models/spree/order_contents.rb +61 -59
  62. data/app/models/spree/order_inventory.rb +59 -54
  63. data/app/models/spree/order_mutex.rb +0 -1
  64. data/app/models/spree/order_shipping.rb +8 -9
  65. data/app/models/spree/order_stock_location.rb +3 -3
  66. data/app/models/spree/order_update_attributes.rb +0 -2
  67. data/app/models/spree/order_updater.rb +11 -24
  68. data/app/models/spree/payment/processing.rb +26 -37
  69. data/app/models/spree/payment.rb +68 -71
  70. data/app/models/spree/payment_method/check.rb +2 -2
  71. data/app/models/spree/payment_method/store_credit.rb +6 -7
  72. data/app/models/spree/payment_method.rb +11 -8
  73. data/app/models/spree/preferences/configuration.rb +2 -2
  74. data/app/models/spree/preferences/preferable.rb +1 -1
  75. data/app/models/spree/preferences/preferable_class_methods.rb +1 -1
  76. data/app/models/spree/preferences/scoped_store.rb +6 -5
  77. data/app/models/spree/preferences/static_model_preferences.rb +1 -1
  78. data/app/models/spree/preferences/statically_configurable.rb +2 -2
  79. data/app/models/spree/preferences/store.rb +2 -6
  80. data/app/models/spree/price.rb +17 -19
  81. data/app/models/spree/product/scopes.rb +18 -17
  82. data/app/models/spree/product.rb +28 -11
  83. data/app/models/spree/product_property.rb +2 -0
  84. data/app/models/spree/product_scope/scopes.rb +22 -22
  85. data/app/models/spree/promotion/actions/create_adjustment.rb +3 -4
  86. data/app/models/spree/promotion/actions/create_item_adjustments.rb +8 -8
  87. data/app/models/spree/promotion/actions/create_quantity_adjustments.rb +3 -3
  88. data/app/models/spree/promotion/actions/free_shipping.rb +4 -4
  89. data/app/models/spree/promotion/rules/first_order.rb +7 -6
  90. data/app/models/spree/promotion/rules/first_repeat_purchase_since.rb +2 -3
  91. data/app/models/spree/promotion/rules/item_total.rb +5 -2
  92. data/app/models/spree/promotion/rules/nth_order.rb +3 -4
  93. data/app/models/spree/promotion/rules/one_use_per_user.rb +1 -2
  94. data/app/models/spree/promotion/rules/option_value.rb +1 -2
  95. data/app/models/spree/promotion/rules/product.rb +4 -4
  96. data/app/models/spree/promotion/rules/taxon.rb +5 -5
  97. data/app/models/spree/promotion/rules/user.rb +1 -1
  98. data/app/models/spree/promotion/rules/user_logged_in.rb +1 -1
  99. data/app/models/spree/promotion.rb +8 -8
  100. data/app/models/spree/promotion_action.rb +1 -1
  101. data/app/models/spree/promotion_builder.rb +2 -2
  102. data/app/models/spree/promotion_chooser.rb +1 -0
  103. data/app/models/spree/promotion_code/code_builder.rb +3 -3
  104. data/app/models/spree/promotion_handler/cart.rb +17 -16
  105. data/app/models/spree/promotion_handler/coupon.rb +10 -14
  106. data/app/models/spree/promotion_handler/page.rb +4 -4
  107. data/app/models/spree/promotion_rule.rb +4 -3
  108. data/app/models/spree/prototype.rb +0 -1
  109. data/app/models/spree/refund.rb +3 -3
  110. data/app/models/spree/reimbursement/reimbursement_type_engine.rb +1 -3
  111. data/app/models/spree/reimbursement.rb +3 -5
  112. data/app/models/spree/reimbursement_performer.rb +0 -5
  113. data/app/models/spree/reimbursement_tax_calculator.rb +2 -7
  114. data/app/models/spree/reimbursement_type/credit.rb +1 -1
  115. data/app/models/spree/reimbursement_type/original_payment.rb +1 -1
  116. data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +3 -3
  117. data/app/models/spree/reimbursement_type/store_credit.rb +1 -1
  118. data/app/models/spree/reimbursement_type.rb +1 -1
  119. data/app/models/spree/return_authorization.rb +38 -37
  120. data/app/models/spree/return_item/eligibility_validator/default.rb +4 -4
  121. data/app/models/spree/return_item/eligibility_validator/no_reimbursements.rb +0 -1
  122. data/app/models/spree/return_item/eligibility_validator/rma_required.rb +0 -1
  123. data/app/models/spree/return_item.rb +24 -23
  124. data/app/models/spree/returns_calculator.rb +1 -2
  125. data/app/models/spree/shipment.rb +80 -74
  126. data/app/models/spree/shipping_calculator.rb +4 -5
  127. data/app/models/spree/shipping_manifest.rb +3 -4
  128. data/app/models/spree/shipping_method.rb +54 -23
  129. data/app/models/spree/shipping_method_stock_location.rb +4 -0
  130. data/app/models/spree/shipping_rate.rb +24 -29
  131. data/app/models/spree/shipping_rate_tax.rb +41 -0
  132. data/app/models/spree/state.rb +1 -1
  133. data/app/models/spree/state_change.rb +1 -1
  134. data/app/models/spree/stock/availability_validator.rb +2 -2
  135. data/app/models/spree/stock/coordinator.rb +12 -13
  136. data/app/models/spree/stock/differentiator.rb +1 -0
  137. data/app/models/spree/stock/estimator.rb +18 -25
  138. data/app/models/spree/stock/inventory_unit_builder.rb +1 -1
  139. data/app/models/spree/stock/package.rb +19 -9
  140. data/app/models/spree/stock/packer.rb +2 -3
  141. data/app/models/spree/stock/prioritizer.rb +3 -2
  142. data/app/models/spree/stock/quantifier.rb +2 -3
  143. data/app/models/spree/stock/shipping_rate_selector.rb +0 -1
  144. data/app/models/spree/stock/shipping_rate_sorter.rb +0 -1
  145. data/app/models/spree/stock/splitter/backordered.rb +0 -2
  146. data/app/models/spree/stock/splitter/base.rb +3 -2
  147. data/app/models/spree/stock/splitter/shipping_category.rb +2 -1
  148. data/app/models/spree/stock/splitter/weight.rb +2 -2
  149. data/app/models/spree/stock_item.rb +36 -37
  150. data/app/models/spree/stock_location.rb +17 -13
  151. data/app/models/spree/stock_movement.rb +1 -3
  152. data/app/models/spree/stock_transfer.rb +8 -8
  153. data/app/models/spree/store.rb +6 -0
  154. data/app/models/spree/store_credit.rb +24 -24
  155. data/app/models/spree/store_credit_category.rb +1 -2
  156. data/app/models/spree/tax/item_adjuster.rb +37 -0
  157. data/app/models/spree/tax/order_adjuster.rb +38 -0
  158. data/app/models/spree/tax/shipping_rate_taxer.rb +31 -0
  159. data/app/models/spree/tax/tax_helpers.rb +49 -0
  160. data/app/models/spree/tax/tax_location.rb +33 -0
  161. data/app/models/spree/tax_category.rb +1 -1
  162. data/app/models/spree/tax_rate.rb +46 -111
  163. data/app/models/spree/taxon.rb +36 -12
  164. data/app/models/spree/taxonomy.rb +10 -10
  165. data/app/models/spree/validations/db_maximum_length_validator.rb +0 -1
  166. data/app/models/spree/variant/pricer.rb +19 -0
  167. data/app/models/spree/variant/pricing_options.rb +31 -0
  168. data/app/models/spree/variant/scopes.rb +9 -9
  169. data/app/models/spree/variant.rb +95 -89
  170. data/app/models/spree/variant_property_rule.rb +1 -1
  171. data/app/models/spree/variant_property_rule_value.rb +2 -0
  172. data/app/models/spree/zone.rb +60 -24
  173. data/config/initializers/friendly_id.rb +1 -1
  174. data/config/locales/en.yml +337 -51
  175. data/config/routes.rb +1 -1
  176. data/db/default/spree/countries.rb +9 -15
  177. data/db/default/spree/roles.rb +1 -2
  178. data/db/default/spree/states.rb +7 -11
  179. data/db/default/spree/store_credit.rb +2 -2
  180. data/db/default/spree/stores.rb +2 -1
  181. data/db/migrate/20120831092320_spree_one_two.rb +100 -101
  182. data/db/migrate/20120831092359_spree_promo_one_two.rb +12 -12
  183. data/db/migrate/20120905151823_add_toggle_tax_rate_display.rb +1 -1
  184. data/db/migrate/20121009142519_add_lock_version_to_variant.rb +1 -1
  185. data/db/migrate/20121010142909_add_states_required_to_countries.rb +1 -1
  186. data/db/migrate/20121012071449_add_on_demand_to_product_and_variant.rb +2 -2
  187. data/db/migrate/20121017010007_remove_not_null_constraint_from_products_on_hand.rb +4 -4
  188. data/db/migrate/20121031162139_split_prices_from_variants.rb +8 -8
  189. data/db/migrate/20121107003422_remove_not_null_from_spree_prices_amount.rb +2 -2
  190. data/db/migrate/20121109173623_add_cost_currency_to_variants.rb +1 -1
  191. data/db/migrate/20121124203911_add_position_to_taxonomies.rb +1 -1
  192. data/db/migrate/20130120201805_add_position_to_product_properties.spree.rb +1 -2
  193. data/db/migrate/20130211190146_create_spree_stock_items.rb +1 -1
  194. data/db/migrate/20130213191427_create_default_stock.rb +12 -21
  195. data/db/migrate/20130226032817_change_meta_description_on_spree_products_to_text.rb +1 -1
  196. data/db/migrate/20130227143905_add_pending_to_inventory_unit.rb +2 -2
  197. data/db/migrate/20130228210442_create_shipping_method_zone.rb +1 -1
  198. data/db/migrate/20130301162924_create_shipping_method_categories.rb +2 -2
  199. data/db/migrate/20130304162240_create_spree_shipping_rates.rb +4 -4
  200. data/db/migrate/20130306181701_add_address_fields_to_stock_location.rb +2 -3
  201. data/db/migrate/20130306191917_add_active_field_to_stock_locations.rb +1 -1
  202. data/db/migrate/20130306195650_add_backorderable_to_stock_item.rb +1 -1
  203. data/db/migrate/20130307161754_add_default_quantity_to_stock_movement.rb +1 -1
  204. data/db/migrate/20130319062004_change_orders_total_precision.rb +4 -4
  205. data/db/migrate/20130319063911_change_spree_payments_amount_precision.rb +1 -3
  206. data/db/migrate/20130319064308_change_spree_return_authorization_amount_precision.rb +2 -4
  207. data/db/migrate/20130319082943_change_adjustments_amount_precision.rb +1 -3
  208. data/db/migrate/20130319190507_drop_source_and_destination_from_stock_movement.rb +2 -2
  209. data/db/migrate/20130325163316_migrate_inventory_unit_sold_to_on_hand.rb +2 -2
  210. data/db/migrate/20130417120035_update_adjustment_states.rb +2 -2
  211. data/db/migrate/20130417123427_add_shipping_rates_to_shipments.rb +3 -3
  212. data/db/migrate/20130628021056_add_unique_index_to_permalink_on_spree_products.rb +1 -1
  213. data/db/migrate/20130628022817_add_unique_index_to_orders_shipments_and_stock_transfers.rb +3 -3
  214. data/db/migrate/20130718042445_add_cost_price_to_line_item.rb +1 -1
  215. data/db/migrate/20130718233855_set_backorderable_to_default_to_false.rb +2 -2
  216. data/db/migrate/20130807024301_upgrade_adjustments.rb +3 -3
  217. data/db/migrate/20130813004002_add_shipment_total_to_spree_orders.rb +1 -1
  218. data/db/migrate/20130813140619_expand_order_number_size.rb +2 -2
  219. data/db/migrate/20130815000406_add_adjustment_total_to_line_items.rb +1 -1
  220. data/db/migrate/20130815024413_add_adjustment_total_to_shipments.rb +1 -1
  221. data/db/migrate/20130826062534_add_depth_to_spree_taxons.rb +1 -1
  222. data/db/migrate/20130830001033_add_shipping_category_to_shipping_methods_and_products.rb +1 -1
  223. data/db/migrate/20130830001159_migrate_old_shipping_calculators.rb +1 -1
  224. data/db/migrate/20131001013410_remove_unused_credit_card_fields.rb +1 -0
  225. data/db/migrate/20131026154747_add_track_inventory_to_variant.rb +1 -1
  226. data/db/migrate/20131118043959_add_included_to_adjustments.rb +1 -1
  227. data/db/migrate/20131118183431_add_line_item_id_to_spree_inventory_units.rb +0 -1
  228. data/db/migrate/20131211112807_create_spree_orders_promotions.rb +1 -1
  229. data/db/migrate/20131218054603_add_item_count_to_spree_orders.rb +1 -1
  230. data/db/migrate/20140106065820_remove_value_type_from_spree_preferences.rb +1 -0
  231. data/db/migrate/20140219060952_add_considered_risky_to_orders.rb +1 -1
  232. data/db/migrate/20140309023735_migrate_old_preferences.rb +4 -3
  233. data/db/migrate/20140309033438_create_store_from_preferences.rb +2 -2
  234. data/db/migrate/20140410141842_add_many_missing_indexes.rb +13 -15
  235. data/db/migrate/20140410150358_correct_some_polymorphic_index_and_add_more_missing.rb +38 -40
  236. data/db/migrate/20140508151342_change_spree_price_amount_precision.rb +4 -4
  237. data/db/migrate/20140530024945_move_order_token_from_tokenized_permission.rb +1 -1
  238. data/db/migrate/20140710041921_recreate_spree_return_authorizations.rb +0 -1
  239. data/db/migrate/20140718195325_create_friendly_id_slugs.rb +4 -4
  240. data/db/migrate/20140723214541_copy_product_slugs_to_slug_history.rb +4 -6
  241. data/db/migrate/20140805171219_make_existing_credit_cards_default.rb +1 -0
  242. data/db/migrate/20141217215630_update_product_slug_index.rb +2 -4
  243. data/db/migrate/20150112194216_add_position_to_stock_location.rb +2 -2
  244. data/db/migrate/20150225205344_move_promotion_code_to_promotion_code_value.rb +0 -1
  245. data/db/migrate/20150313201503_copy_shipped_shipments_to_cartons.rb +0 -1
  246. data/db/migrate/20150506181611_create_spree_store_credit_payment_method.rb +3 -3
  247. data/db/migrate/20150515211137_fix_adjustment_order_id.rb +0 -1
  248. data/db/migrate/20150612205731_remove_spree_configurations.rb +2 -2
  249. data/db/migrate/20150619160613_create_adjustment_reason.rb +1 -1
  250. data/db/migrate/20150723224133_remove_unnecessary_indexes.rb +10 -2
  251. data/db/migrate/20150731201146_add_spree_user_addresses.rb +0 -1
  252. data/db/migrate/20150811211025_add_finalized_to_spree_adjustments.rb +1 -1
  253. data/db/migrate/20151001121454_create_spree_shipping_method_stock_locations.rb +13 -0
  254. data/db/migrate/20151002023248_add_foreign_key_to_shipping_method_stock_location.rb +6 -0
  255. data/db/migrate/20151026093607_change_return_item_pre_tax_amount_to_amount.rb +29 -0
  256. data/db/migrate/20160111091912_add_column_available_to_all_on_spree_shipping_method.rb +5 -0
  257. data/db/migrate/20160116133604_add_position_to_spree_payment_methods.rb +5 -0
  258. data/db/migrate/20160122182105_add_carrier_and_service_level_to_spree_shipping_methods.rb +6 -0
  259. data/db/migrate/20160224201413_create_spree_shipping_rate_taxes.rb +11 -0
  260. data/db/migrate/20160229133259_add_cart_tax_country_iso_to_spree_store.rb +5 -0
  261. data/db/migrate/20160301103333_remove_pre_tax_amount_on_line_item_and_shipment.rb +6 -0
  262. data/db/migrate/20160308000300_disallow_adjustment_finalized_nulls.rb +19 -0
  263. data/db/migrate/20160318145302_add_timestamps_to_prices.rb +5 -0
  264. data/db/migrate/20160330204846_add_missing_timestamp_columns.rb +20 -0
  265. data/lib/generators/spree/custom_user/custom_user_generator.rb +3 -8
  266. data/lib/generators/spree/dummy/dummy_generator.rb +17 -19
  267. data/lib/generators/spree/install/install_generator.rb +15 -15
  268. data/lib/generators/spree/install/templates/config/initializers/spree.rb +1 -0
  269. data/lib/spree/core/controller_helpers/auth.rb +2 -4
  270. data/lib/spree/core/controller_helpers/common.rb +42 -43
  271. data/lib/spree/core/controller_helpers/order.rb +5 -9
  272. data/lib/spree/core/controller_helpers/payment_parameters.rb +4 -5
  273. data/lib/spree/core/controller_helpers/pricing.rb +27 -0
  274. data/lib/spree/core/controller_helpers/respond_with.rb +4 -4
  275. data/lib/spree/core/controller_helpers/search.rb +2 -2
  276. data/lib/spree/core/controller_helpers/store.rb +3 -3
  277. data/lib/spree/core/controller_helpers/strong_parameters.rb +4 -4
  278. data/lib/spree/core/current_store.rb +1 -1
  279. data/lib/spree/core/delegate_belongs_to.rb +19 -21
  280. data/lib/spree/core/engine.rb +12 -8
  281. data/lib/spree/core/environment/calculators.rb +0 -1
  282. data/lib/spree/core/environment_extension.rb +4 -4
  283. data/lib/spree/core/importer/order.rb +17 -22
  284. data/lib/spree/core/importer/product.rb +10 -9
  285. data/lib/spree/core/permalinks.rb +16 -16
  286. data/lib/spree/core/product_duplicator.rb +2 -3
  287. data/lib/spree/core/product_filters.rb +15 -16
  288. data/lib/spree/core/role_configuration.rb +2 -2
  289. data/lib/spree/core/search/base.rb +71 -57
  290. data/lib/spree/core/search/variant.rb +2 -4
  291. data/lib/spree/core/unreturned_item_charger.rb +1 -2
  292. data/lib/spree/core/validators/email.rb +2 -2
  293. data/lib/spree/core/version.rb +1 -1
  294. data/lib/spree/core.rb +2 -4
  295. data/lib/spree/i18n.rb +1 -1
  296. data/lib/spree/localized_number.rb +3 -1
  297. data/lib/spree/migrations.rb +27 -26
  298. data/lib/spree/money.rb +19 -4
  299. data/lib/spree/permission_sets/base.rb +1 -1
  300. data/lib/spree/permitted_attributes.rb +7 -7
  301. data/lib/spree/responder.rb +4 -5
  302. data/lib/spree/testing_support/authorization_helpers.rb +1 -1
  303. data/lib/spree/testing_support/caching.rb +8 -8
  304. data/lib/spree/testing_support/capybara_ext.rb +11 -13
  305. data/lib/spree/testing_support/common_rake.rb +4 -4
  306. data/lib/spree/testing_support/controller_requests.rb +1 -1
  307. data/lib/spree/testing_support/extension_rake.rb +1 -2
  308. data/lib/spree/testing_support/factories/address_factory.rb +14 -3
  309. data/lib/spree/testing_support/factories/adjustment_reason_factory.rb +1 -1
  310. data/lib/spree/testing_support/factories/carton_factory.rb +2 -2
  311. data/lib/spree/testing_support/factories/credit_card_factory.rb +4 -0
  312. data/lib/spree/testing_support/factories/customer_return_factory.rb +4 -6
  313. data/lib/spree/testing_support/factories/line_item_factory.rb +1 -1
  314. data/lib/spree/testing_support/factories/order_factory.rb +10 -11
  315. data/lib/spree/testing_support/factories/payment_factory.rb +5 -0
  316. data/lib/spree/testing_support/factories/promotion_category_factory.rb +0 -1
  317. data/lib/spree/testing_support/factories/promotion_factory.rb +0 -1
  318. data/lib/spree/testing_support/factories/refund_factory.rb +1 -1
  319. data/lib/spree/testing_support/factories/reimbursement_factory.rb +1 -1
  320. data/lib/spree/testing_support/factories/return_item_factory.rb +1 -1
  321. data/lib/spree/testing_support/factories/shipping_method_factory.rb +5 -2
  322. data/lib/spree/testing_support/factories/state_factory.rb +17 -7
  323. data/lib/spree/testing_support/factories/stock_location_factory.rb +4 -4
  324. data/lib/spree/testing_support/factories/stock_transfer_factory.rb +1 -1
  325. data/lib/spree/testing_support/factories/store_credit_category_factory.rb +0 -1
  326. data/lib/spree/testing_support/factories/store_credit_type_factory.rb +0 -2
  327. data/lib/spree/testing_support/factories/tax_category_factory.rb +2 -2
  328. data/lib/spree/testing_support/factories/user_factory.rb +1 -1
  329. data/lib/spree/testing_support/factories/variant_factory.rb +1 -2
  330. data/lib/spree/testing_support/factories/zone_factory.rb +2 -1
  331. data/lib/spree/testing_support/i18n.rb +4 -5
  332. data/lib/spree/testing_support/order_walkthrough.rb +8 -9
  333. data/lib/spree/testing_support/preferences.rb +1 -1
  334. data/lib/spree/testing_support/sequences.rb +5 -4
  335. data/lib/tasks/core.rake +15 -19
  336. data/lib/tasks/email.rake +3 -3
  337. data/lib/tasks/exchanges.rake +12 -14
  338. data/lib/tasks/migrations/assure_store_on_orders.rake +38 -0
  339. data/lib/tasks/migrations/copy_order_bill_address_to_credit_card.rake +2 -2
  340. data/lib/tasks/migrations/copy_shipped_shipments_to_cartons.rake +1 -11
  341. data/lib/tasks/migrations/migrate_shipping_rate_taxes.rake +17 -0
  342. data/lib/tasks/migrations/migrate_user_addresses.rake +1 -1
  343. data/lib/tasks/order_capturing.rake +1 -1
  344. data/lib/tasks/upgrade.rake +11 -0
  345. data/script/rails +0 -1
  346. data/solidus_core.gemspec +6 -8
  347. data/spec/helpers/base_helper_spec.rb +15 -18
  348. data/spec/helpers/order_helper_spec.rb +2 -2
  349. data/spec/helpers/products_helper_spec.rb +43 -51
  350. data/spec/helpers/taxons_helper_spec.rb +1 -1
  351. data/spec/lib/i18n_spec.rb +11 -11
  352. data/spec/lib/search/base_spec.rb +12 -14
  353. data/spec/lib/search/variant_spec.rb +1 -0
  354. data/spec/lib/spree/core/controller_helpers/order_spec.rb +1 -7
  355. data/spec/lib/spree/core/controller_helpers/payment_parameters_spec.rb +26 -28
  356. data/spec/lib/spree/core/controller_helpers/pricing_spec.rb +63 -0
  357. data/spec/lib/spree/core/controller_helpers/search_spec.rb +4 -2
  358. data/spec/lib/spree/core/delegate_belongs_to_spec.rb +1 -1
  359. data/spec/lib/spree/core/importer/order_spec.rb +95 -90
  360. data/spec/lib/spree/core/role_configuration_spec.rb +16 -16
  361. data/spec/lib/spree/core/testing_support/factories/address_factory_spec.rb +35 -0
  362. data/spec/lib/spree/core/testing_support/factories/customer_return_factory_spec.rb +10 -1
  363. data/spec/lib/spree/core/testing_support/factories/order_factory_spec.rb +0 -1
  364. data/spec/lib/spree/core/testing_support/factories/shipping_method_factory_spec.rb +6 -1
  365. data/spec/lib/spree/core/testing_support/factories/state_factory_spec.rb +37 -1
  366. data/spec/lib/spree/core/testing_support/factories/stock_package_factory_spec.rb +2 -2
  367. data/spec/lib/spree/core/testing_support/factories/stock_packer_factory_spec.rb +1 -1
  368. data/spec/lib/spree/core/testing_support/factories/store_credit_event_factory_spec.rb +1 -2
  369. data/spec/lib/spree/core/testing_support/preferences_spec.rb +26 -0
  370. data/spec/lib/spree/core/unreturned_item_charger_spec.rb +7 -9
  371. data/spec/lib/spree/core/validators/email_spec.rb +8 -6
  372. data/spec/lib/spree/localized_number_spec.rb +1 -3
  373. data/spec/lib/spree/migrations_spec.rb +2 -2
  374. data/spec/lib/spree/money_spec.rb +75 -6
  375. data/spec/lib/tasks/exchanges_spec.rb +2 -12
  376. data/spec/lib/tasks/migrations/copy_shipped_shipments_to_cartons_spec.rb +0 -1
  377. data/spec/lib/tasks/order_capturing_spec.rb +1 -1
  378. data/spec/mailers/carton_mailer_spec.rb +3 -3
  379. data/spec/mailers/order_mailer_spec.rb +9 -11
  380. data/spec/mailers/reimbursement_mailer_spec.rb +2 -2
  381. data/spec/mailers/test_mailer_spec.rb +1 -1
  382. data/spec/models/spree/ability_spec.rb +4 -7
  383. data/spec/models/spree/address_spec.rb +32 -35
  384. data/spec/models/spree/adjustment_reason_spec.rb +0 -2
  385. data/spec/models/spree/adjustment_spec.rb +2 -2
  386. data/spec/models/spree/app_configuration_spec.rb +33 -3
  387. data/spec/models/spree/asset_spec.rb +1 -2
  388. data/spec/models/spree/calculator/default_tax_spec.rb +141 -52
  389. data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +1 -1
  390. data/spec/models/spree/calculator/flexi_rate_spec.rb +6 -6
  391. data/spec/models/spree/calculator/percent_on_line_item_spec.rb +1 -1
  392. data/spec/models/spree/calculator/price_sack_spec.rb +2 -2
  393. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +9 -11
  394. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +4 -4
  395. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +2 -2
  396. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +6 -7
  397. data/spec/models/spree/calculator/shipping/per_item_spec.rb +2 -2
  398. data/spec/models/spree/calculator/shipping/price_sack_spec.rb +2 -2
  399. data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +1 -2
  400. data/spec/models/spree/calculator/tiered_percent_spec.rb +1 -1
  401. data/spec/models/spree/calculator_spec.rb +3 -8
  402. data/spec/models/spree/carton_spec.rb +1 -1
  403. data/spec/models/spree/classification_spec.rb +1 -1
  404. data/spec/models/spree/concerns/display_money_spec.rb +0 -1
  405. data/spec/models/spree/concerns/ordered_property_value_list_spec.rb +26 -1
  406. data/spec/models/spree/concerns/user_address_book_spec.rb +19 -12
  407. data/spec/models/spree/concerns/user_methods_spec.rb +1 -1
  408. data/spec/models/spree/country_spec.rb +52 -0
  409. data/spec/models/spree/credit_card_spec.rb +17 -12
  410. data/spec/models/spree/customer_return_spec.rb +27 -23
  411. data/spec/models/spree/exchange_spec.rb +2 -7
  412. data/spec/models/spree/gateway/bogus_simple.rb +2 -4
  413. data/spec/models/spree/gateway/bogus_spec.rb +4 -2
  414. data/spec/models/spree/gateway_spec.rb +8 -3
  415. data/spec/models/spree/inventory_unit_spec.rb +13 -14
  416. data/spec/models/spree/item_adjustments_spec.rb +36 -40
  417. data/spec/models/spree/line_item_spec.rb +92 -48
  418. data/spec/models/spree/option_type_spec.rb +1 -1
  419. data/spec/models/spree/option_value_spec.rb +1 -1
  420. data/spec/models/spree/order/address_spec.rb +1 -1
  421. data/spec/models/spree/order/callbacks_spec.rb +3 -3
  422. data/spec/models/spree/order/checkout_spec.rb +55 -48
  423. data/spec/models/spree/order/finalizing_spec.rb +8 -9
  424. data/spec/models/spree/order/payment_spec.rb +20 -20
  425. data/spec/models/spree/order/risk_assessment_spec.rb +1 -1
  426. data/spec/models/spree/order/state_machine_spec.rb +40 -131
  427. data/spec/models/spree/order/tax_spec.rb +11 -12
  428. data/spec/models/spree/order/totals_spec.rb +3 -3
  429. data/spec/models/spree/order/updating_spec.rb +2 -2
  430. data/spec/models/spree/order/validations_spec.rb +2 -2
  431. data/spec/models/spree/order_cancellations_spec.rb +1 -1
  432. data/spec/models/spree/order_capturing_spec.rb +1 -1
  433. data/spec/models/spree/order_contents_spec.rb +10 -11
  434. data/spec/models/spree/order_inventory_spec.rb +11 -11
  435. data/spec/models/spree/order_merger_spec.rb +1 -0
  436. data/spec/models/spree/order_shipping_spec.rb +8 -10
  437. data/spec/models/spree/order_spec.rb +137 -124
  438. data/spec/models/spree/order_stock_location_spec.rb +2 -2
  439. data/spec/models/spree/order_update_attributes_spec.rb +6 -10
  440. data/spec/models/spree/order_updater_spec.rb +4 -8
  441. data/spec/models/spree/payment_create_spec.rb +11 -12
  442. data/spec/models/spree/payment_method/store_credit_spec.rb +10 -6
  443. data/spec/models/spree/payment_method_spec.rb +4 -5
  444. data/spec/models/spree/payment_spec.rb +61 -69
  445. data/spec/models/spree/permission_sets/base_spec.rb +1 -1
  446. data/spec/models/spree/permission_sets/configuration_display.rb +0 -1
  447. data/spec/models/spree/permission_sets/configuration_management_spec.rb +0 -1
  448. data/spec/models/spree/permission_sets/dashboard_display_spec.rb +0 -1
  449. data/spec/models/spree/permission_sets/order_display_spec.rb +0 -1
  450. data/spec/models/spree/permission_sets/order_management_spec.rb +0 -1
  451. data/spec/models/spree/permission_sets/product_display_spec.rb +0 -1
  452. data/spec/models/spree/permission_sets/product_management_spec.rb +0 -1
  453. data/spec/models/spree/permission_sets/promotion_display_spec.rb +0 -1
  454. data/spec/models/spree/permission_sets/promotion_management_spec.rb +0 -1
  455. data/spec/models/spree/permission_sets/report_display_spec.rb +0 -1
  456. data/spec/models/spree/permission_sets/restricted_stock_display_spec.rb +0 -1
  457. data/spec/models/spree/permission_sets/restricted_stock_management_spec.rb +0 -1
  458. data/spec/models/spree/permission_sets/restricted_stock_transfer_display_spec.rb +0 -1
  459. data/spec/models/spree/permission_sets/restricted_stock_transfer_management_spec.rb +6 -6
  460. data/spec/models/spree/permission_sets/stock_display_spec.rb +0 -1
  461. data/spec/models/spree/permission_sets/stock_management_spec.rb +0 -1
  462. data/spec/models/spree/permission_sets/stock_transfer_display_spec.rb +0 -1
  463. data/spec/models/spree/permission_sets/stock_transfer_management_spec.rb +0 -2
  464. data/spec/models/spree/permission_sets/user_display_spec.rb +0 -1
  465. data/spec/models/spree/permission_sets/user_management_spec.rb +0 -1
  466. data/spec/models/spree/preference_spec.rb +1 -4
  467. data/spec/models/spree/preferences/configuration_spec.rb +2 -7
  468. data/spec/models/spree/preferences/preferable_spec.rb +13 -24
  469. data/spec/models/spree/preferences/scoped_store_spec.rb +1 -1
  470. data/spec/models/spree/preferences/static_model_preferences_spec.rb +5 -6
  471. data/spec/models/spree/preferences/statically_configurable_spec.rb +2 -6
  472. data/spec/models/spree/preferences/store_spec.rb +2 -3
  473. data/spec/models/spree/price_spec.rb +6 -6
  474. data/spec/models/spree/product/scopes_spec.rb +20 -20
  475. data/spec/models/spree/product_duplicator_spec.rb +16 -29
  476. data/spec/models/spree/product_filter_spec.rb +2 -2
  477. data/spec/models/spree/product_spec.rb +53 -20
  478. data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +10 -12
  479. data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +4 -4
  480. data/spec/models/spree/promotion/actions/create_quantity_adjustments_spec.rb +9 -9
  481. data/spec/models/spree/promotion/actions/free_shipping_spec.rb +1 -1
  482. data/spec/models/spree/promotion/rules/first_order_spec.rb +10 -10
  483. data/spec/models/spree/promotion/rules/item_total_spec.rb +63 -19
  484. data/spec/models/spree/promotion/rules/one_use_per_user_spec.rb +1 -1
  485. data/spec/models/spree/promotion/rules/product_spec.rb +8 -8
  486. data/spec/models/spree/promotion/rules/taxon_spec.rb +4 -4
  487. data/spec/models/spree/promotion/rules/user_logged_in_spec.rb +3 -4
  488. data/spec/models/spree/promotion/rules/user_spec.rb +7 -7
  489. data/spec/models/spree/promotion_builder_spec.rb +10 -8
  490. data/spec/models/spree/promotion_category_spec.rb +1 -1
  491. data/spec/models/spree/promotion_code/code_builder_spec.rb +1 -3
  492. data/spec/models/spree/promotion_code_spec.rb +8 -7
  493. data/spec/models/spree/promotion_handler/cart_spec.rb +1 -1
  494. data/spec/models/spree/promotion_handler/coupon_spec.rb +28 -28
  495. data/spec/models/spree/promotion_handler/page_spec.rb +6 -7
  496. data/spec/models/spree/promotion_rule_spec.rb +1 -2
  497. data/spec/models/spree/promotion_spec.rb +25 -21
  498. data/spec/models/spree/refund_spec.rb +8 -11
  499. data/spec/models/spree/reimbursement/credit_spec.rb +2 -2
  500. data/spec/models/spree/reimbursement/reimbursement_type_engine_spec.rb +6 -4
  501. data/spec/models/spree/reimbursement/reimbursement_type_validator_spec.rb +1 -1
  502. data/spec/models/spree/reimbursement_performer_spec.rb +2 -2
  503. data/spec/models/spree/reimbursement_spec.rb +9 -11
  504. data/spec/models/spree/reimbursement_tax_calculator_spec.rb +4 -5
  505. data/spec/models/spree/reimbursement_type/credit_spec.rb +2 -2
  506. data/spec/models/spree/reimbursement_type/exchange_spec.rb +2 -3
  507. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +4 -4
  508. data/spec/models/spree/reimbursement_type/store_credit_spec.rb +1 -1
  509. data/spec/models/spree/return_authorization_spec.rb +18 -21
  510. data/spec/models/spree/return_item/eligibility_validator/default_spec.rb +7 -7
  511. data/spec/models/spree/return_item/eligibility_validator/inventory_shipped_spec.rb +0 -1
  512. data/spec/models/spree/return_item/eligibility_validator/no_reimbursements_spec.rb +0 -1
  513. data/spec/models/spree/return_item/eligibility_validator/rma_required_spec.rb +1 -1
  514. data/spec/models/spree/return_item/eligibility_validator/time_since_purchase_spec.rb +1 -1
  515. data/spec/models/spree/return_item/exchange_variant_eligibility/same_option_value_spec.rb +1 -2
  516. data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +3 -5
  517. data/spec/models/spree/return_item_spec.rb +29 -31
  518. data/spec/models/spree/returns_calculator_spec.rb +1 -1
  519. data/spec/models/spree/shipment_spec.rb +59 -43
  520. data/spec/models/spree/shipping_calculator_spec.rb +3 -3
  521. data/spec/models/spree/shipping_manifest_spec.rb +8 -7
  522. data/spec/models/spree/shipping_method_spec.rb +149 -24
  523. data/spec/models/spree/shipping_rate_spec.rb +116 -76
  524. data/spec/models/spree/shipping_rate_tax_spec.rb +83 -0
  525. data/spec/models/spree/state_spec.rb +2 -2
  526. data/spec/models/spree/stock/availability_validator_spec.rb +4 -4
  527. data/spec/models/spree/stock/coordinator_spec.rb +33 -49
  528. data/spec/models/spree/stock/differentiator_spec.rb +1 -1
  529. data/spec/models/spree/stock/estimator_spec.rb +83 -54
  530. data/spec/models/spree/stock/inventory_unit_builder_spec.rb +1 -3
  531. data/spec/models/spree/stock/package_spec.rb +27 -10
  532. data/spec/models/spree/stock/packer_spec.rb +4 -4
  533. data/spec/models/spree/stock/prioritizer_spec.rb +1 -1
  534. data/spec/models/spree/stock/quantifier_spec.rb +2 -6
  535. data/spec/models/spree/stock/splitter/backordered_spec.rb +1 -1
  536. data/spec/models/spree/stock/splitter/base_spec.rb +1 -2
  537. data/spec/models/spree/stock/splitter/shipping_category_spec.rb +1 -3
  538. data/spec/models/spree/stock/splitter/weight_spec.rb +3 -3
  539. data/spec/models/spree/stock_item_spec.rb +16 -16
  540. data/spec/models/spree/stock_location_spec.rb +6 -8
  541. data/spec/models/spree/stock_movement_spec.rb +1 -1
  542. data/spec/models/spree/stock_transfer_spec.rb +1 -3
  543. data/spec/models/spree/store_credit_category_spec.rb +1 -1
  544. data/spec/models/spree/store_credit_event_spec.rb +3 -5
  545. data/spec/models/spree/store_credit_spec.rb +24 -23
  546. data/spec/models/spree/store_spec.rb +21 -2
  547. data/spec/models/spree/tax/item_adjuster_spec.rb +74 -0
  548. data/spec/models/spree/tax/order_adjuster_spec.rb +49 -0
  549. data/spec/models/spree/tax/shipping_rate_taxer_spec.rb +50 -0
  550. data/spec/models/spree/tax/tax_location_spec.rb +68 -0
  551. data/spec/models/spree/tax/taxation_integration_spec.rb +787 -0
  552. data/spec/models/spree/tax_category_spec.rb +2 -2
  553. data/spec/models/spree/tax_rate_spec.rb +185 -536
  554. data/spec/models/spree/taxon_spec.rb +69 -5
  555. data/spec/models/spree/taxonomy_spec.rb +2 -3
  556. data/spec/models/spree/tracker_spec.rb +1 -1
  557. data/spec/models/spree/transfer_item_spec.rb +1 -1
  558. data/spec/models/spree/unit_cancel_spec.rb +9 -14
  559. data/spec/models/spree/user_spec.rb +19 -24
  560. data/spec/models/spree/validations/db_maximum_length_validator_spec.rb +1 -1
  561. data/spec/models/spree/variant/pricer_spec.rb +48 -0
  562. data/spec/models/spree/variant/pricing_options_spec.rb +106 -0
  563. data/spec/models/spree/variant/scopes_spec.rb +31 -8
  564. data/spec/models/spree/variant_property_rule_spec.rb +1 -1
  565. data/spec/models/spree/variant_spec.rb +166 -52
  566. data/spec/models/spree/zone_spec.rb +135 -10
  567. data/spec/support/big_decimal.rb +1 -1
  568. data/spec/support/concerns/working_factories.rb +2 -2
  569. data/spec/support/dummy_ability.rb +0 -1
  570. metadata +55 -44
  571. data/lib/generators/spree/dummy/templates/initializers/devise.rb +0 -3
  572. data/lib/spree/migration_helpers.rb +0 -19
  573. data/vendor/assets/stylesheets/skeleton.css +0 -242
@@ -3,7 +3,6 @@ module Spree
3
3
  ##
4
4
  # Validates a field based on the maximum length of the underlying DB field, if there is one.
5
5
  class DbMaximumLengthValidator < ActiveModel::Validator
6
-
7
6
  def initialize(options)
8
7
  super
9
8
  @field = options[:field].to_s
@@ -0,0 +1,19 @@
1
+ module Spree
2
+ class Variant
3
+ class Pricer
4
+ def self.pricing_options_class
5
+ Spree::Variant::PricingOptions
6
+ end
7
+
8
+ attr_reader :variant
9
+
10
+ def initialize(variant)
11
+ @variant = variant
12
+ end
13
+
14
+ def price_for(price_options)
15
+ variant.prices.currently_valid.find_by(price_options.desired_attributes).try!(:money)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,31 @@
1
+ module Spree
2
+ class Variant
3
+ class PricingOptions
4
+ def self.default_price_attributes
5
+ { currency: Spree::Config.currency }
6
+ end
7
+
8
+ def self.from_line_item(line_item)
9
+ new(currency: line_item.order.try(:currency) || line_item.currency || Spree::Config.currency )
10
+ end
11
+
12
+ def self.from_price(price)
13
+ new(currency: price.currency)
14
+ end
15
+
16
+ attr_reader :desired_attributes
17
+
18
+ def initialize(desired_attributes = {})
19
+ @desired_attributes = self.class.default_price_attributes.merge(desired_attributes)
20
+ end
21
+
22
+ def currency
23
+ desired_attributes[:currency]
24
+ end
25
+
26
+ def cache_key
27
+ desired_attributes.values.map(&:to_s).join("/")
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,6 +1,6 @@
1
1
  module Spree
2
2
  class Variant < Spree::Base
3
- #FIXME WARNING tested only under sqlite and postgresql
3
+ # FIXME: WARNING tested only under sqlite and postgresql
4
4
  scope :descend_by_popularity, -> {
5
5
  order("COALESCE((SELECT COUNT(*) FROM #{LineItem.quoted_table_name} GROUP BY #{LineItem.quoted_table_name}.variant_id HAVING #{LineItem.quoted_table_name}.variant_id = #{Variant.quoted_table_name}.id), 0) DESC")
6
6
  }
@@ -15,18 +15,18 @@ module Spree
15
15
  option_types = OptionType.table_name
16
16
 
17
17
  option_type_conditions = case option_type
18
- when OptionType then { "#{option_types}.name" => option_type.name }
19
- when String then { "#{option_types}.name" => option_type }
20
- else { "#{option_types}.id" => option_type }
18
+ when OptionType then { "#{option_types}.name" => option_type.name }
19
+ when String then { "#{option_types}.name" => option_type }
20
+ else { "#{option_types}.id" => option_type }
21
21
  end
22
22
 
23
- relation = joins(:option_values => :option_type).where(option_type_conditions)
23
+ relation = joins(option_values: :option_type).where(option_type_conditions)
24
24
 
25
- option_values_conditions = option_values.each do |option_value|
25
+ option_values.each do |option_value|
26
26
  option_value_conditions = case option_value
27
- when OptionValue then { "#{OptionValue.table_name}.name" => option_value.name }
28
- when String then { "#{OptionValue.table_name}.name" => option_value }
29
- else { "#{OptionValue.table_name}.id" => option_value }
27
+ when OptionValue then { "#{OptionValue.table_name}.name" => option_value.name }
28
+ when String then { "#{OptionValue.table_name}.name" => option_value }
29
+ else { "#{OptionValue.table_name}.id" => option_value }
30
30
  end
31
31
  relation = relation.where(option_value_conditions)
32
32
  end
@@ -15,6 +15,7 @@ module Spree
15
15
  # inventory level determine "on_hand" level for the product.
16
16
  class Variant < Spree::Base
17
17
  acts_as_paranoid
18
+ acts_as_list scope: :product
18
19
 
19
20
  include Spree::DefaultPrice
20
21
 
@@ -24,6 +25,7 @@ module Spree
24
25
  delegate :name, :description, :slug, :available_on, :shipping_category_id,
25
26
  :meta_description, :meta_keywords, :shipping_category,
26
27
  to: :product
28
+ delegate :tax_category, to: :product, prefix: true
27
29
 
28
30
  has_many :inventory_units, inverse_of: :variant
29
31
  has_many :line_items, inverse_of: :variant
@@ -33,7 +35,7 @@ module Spree
33
35
  has_many :stock_locations, through: :stock_items
34
36
  has_many :stock_movements, through: :stock_items
35
37
 
36
- has_many :option_values_variants, dependent: :destroy
38
+ has_many :option_values_variants
37
39
  has_many :option_values, through: :option_values_variants
38
40
 
39
41
  has_many :images, -> { order(:position) }, as: :viewable, dependent: :destroy, class_name: "Spree::Image"
@@ -57,6 +59,8 @@ module Spree
57
59
 
58
60
  after_touch :clear_in_stock_cache
59
61
 
62
+ after_real_destroy :destroy_option_values_variants
63
+
60
64
  # Returns variants that are in stock. When stock locations are provided as
61
65
  # a parameter, the scope is limited to variants that are in stock in the
62
66
  # provided stock locations.
@@ -64,6 +68,7 @@ module Spree
64
68
  # @param stock_locations [Array<Spree::StockLocation>] the stock locations to check
65
69
  # @return [ActiveRecord::Relation]
66
70
  def self.in_stock(stock_locations = nil)
71
+ return all unless Spree::Config.track_inventory_levels
67
72
  in_stock_variants = joins(:stock_items).where(Spree::StockItem.arel_table[:count_on_hand].gt(0).or(arel_table[:track_inventory].eq(false)))
68
73
  if stock_locations.present?
69
74
  in_stock_variants = in_stock_variants.where(spree_stock_items: { stock_location_id: stock_locations.map(&:id) })
@@ -83,13 +88,21 @@ module Spree
83
88
  joins(:prices).where(deleted_at: nil).where('spree_prices.currency' => currency || Spree::Config[:currency]).where('spree_prices.amount IS NOT NULL')
84
89
  end
85
90
 
91
+ # Returns variants that have a price for the given pricing options
92
+ #
93
+ # @param pricing_options A Pricing Options object as defined on the pricer class
94
+ # @return [ActiveRecord::Relation]
95
+ def self.with_prices(pricing_options = Spree::Config.default_pricing_options)
96
+ joins(:prices).merge(Spree::Price.currently_valid.where(pricing_options.desired_attributes))
97
+ end
98
+
86
99
  # @return [Spree::TaxCategory] the variant's tax category
100
+ #
101
+ # This returns the product's tax category if the tax category ID on the variant is nil. It looks
102
+ # like an association, but really is an override.
103
+ #
87
104
  def tax_category
88
- if self[:tax_category_id].nil?
89
- product.tax_category
90
- else
91
- TaxCategory.find(self[:tax_category_id])
92
- end
105
+ super || product_tax_category
93
106
  end
94
107
 
95
108
  # Sets the cost_price for the variant.
@@ -124,7 +137,7 @@ module Spree
124
137
  #
125
138
  # @return [String] a sentence-ified string of option values.
126
139
  def options_text
127
- values = self.option_values.includes(:option_type).sort_by do |option_value|
140
+ values = option_values.includes(:option_type).sort_by do |option_value|
128
141
  option_value.option_type.position
129
142
  end
130
143
 
@@ -173,22 +186,22 @@ module Spree
173
186
  # @param opt_value [String] the value to set to the option
174
187
  def set_option_value(opt_name, opt_value)
175
188
  # no option values on master
176
- return if self.is_master
189
+ return if is_master
177
190
 
178
191
  option_type = Spree::OptionType.where(name: opt_name).first_or_initialize do |o|
179
192
  o.presentation = opt_name
180
193
  o.save!
181
194
  end
182
195
 
183
- current_value = self.option_values.detect { |o| o.option_type.name == opt_name }
196
+ current_value = option_values.detect { |o| o.option_type.name == opt_name }
184
197
 
185
- unless current_value.nil?
198
+ if current_value
186
199
  return if current_value.name == opt_value
187
- self.option_values.delete(current_value)
200
+ option_values.delete(current_value)
188
201
  else
189
202
  # then we have to check to make sure that the product has the option type
190
- unless self.product.option_types.include? option_type
191
- self.product.option_types << option_type
203
+ unless product.option_types.include? option_type
204
+ product.option_types << option_type
192
205
  end
193
206
  end
194
207
 
@@ -197,8 +210,8 @@ module Spree
197
210
  o.save!
198
211
  end
199
212
 
200
- self.option_values << option_value
201
- self.save
213
+ option_values << option_value
214
+ save
202
215
  end
203
216
 
204
217
  # Fetches the option value for the given option name.
@@ -206,7 +219,35 @@ module Spree
206
219
  # @param opt_name [String] the name of the option whose value you want
207
220
  # @return [String] the option value
208
221
  def option_value(opt_name)
209
- self.option_values.detect { |o| o.option_type.name == opt_name }.try(:presentation)
222
+ option_values.detect { |o| o.option_type.name == opt_name }.try(:presentation)
223
+ end
224
+
225
+ # Returns an instance of the globally configured variant pricer class for this variant.
226
+ # It's cached so we don't create too many objects.
227
+ #
228
+ # @return [Spree::Variant::Pricer] The default pricer class
229
+ def pricer
230
+ @pricer ||= Spree::Config.variant_pricer_class.new(self)
231
+ end
232
+
233
+ # Chooses an appropriate price for the given pricing options
234
+ #
235
+ # @see Spree::Variant::Pricer#price_for
236
+ # @param [Spree::Config.pricing_options_class] An instance of pricing options
237
+ # @return [Spree::Money] The chosen price as a Money object
238
+ delegate :price_for, to: :pricer
239
+
240
+ # Returns the difference in price from the master variant
241
+ def price_difference_from_master(pricing_options = Spree::Config.default_pricing_options)
242
+ master_price = product.master.price_for(pricing_options)
243
+ variant_price = price_for(pricing_options)
244
+ return unless master_price && variant_price
245
+ variant_price - master_price
246
+ end
247
+
248
+ def price_same_as_master?(pricing_options = Spree::Config.default_pricing_options)
249
+ diff = price_difference_from_master(pricing_options)
250
+ diff && diff.zero?
210
251
  end
211
252
 
212
253
  # Converts the variant's price to the given currency.
@@ -214,7 +255,7 @@ module Spree
214
255
  # @param currency [String] the desired currency
215
256
  # @return [Spree::Price] the price in the desired currency
216
257
  def price_in(currency)
217
- prices.detect{ |price| price.currency == currency && price.is_default } || Spree::Price.new(variant_id: self.id, currency: currency)
258
+ prices.currently_valid.find_by(currency: currency)
218
259
  end
219
260
 
220
261
  # Fetches the price amount in the specified currency.
@@ -225,42 +266,6 @@ module Spree
225
266
  price_in(currency).try(:amount)
226
267
  end
227
268
 
228
- # Calculates the sum of the specified price modifiers in the specified
229
- # currency.
230
- #
231
- # @param currency [String] (see #price)
232
- # @param options (see #price_modifier_amount)
233
- # @return (see #price_modifier_amount)
234
- def price_modifier_amount_in(currency, options = {})
235
- return 0 unless options.present?
236
-
237
- options.keys.map { |key|
238
- m = "#{key}_price_modifier_amount_in".to_sym
239
- if self.respond_to? m
240
- self.send(m, currency, options[key])
241
- else
242
- 0
243
- end
244
- }.sum
245
- end
246
-
247
- # Calculates the sum of the specified price modifiers.
248
- #
249
- # @param options [Hash] for specifying keys, eg: `{keys: ['key_1', 'key_2']}`
250
- # @return [Fixnum] the sum
251
- def price_modifier_amount(options = {})
252
- return 0 unless options.present?
253
-
254
- options.keys.map { |key|
255
- m = "#{options[key]}_price_modifier_amount".to_sym
256
- if self.respond_to? m
257
- self.send(m, options[key])
258
- else
259
- 0
260
- end
261
- }.sum
262
- end
263
-
264
269
  # Generates a friendly name and sku string.
265
270
  #
266
271
  # @return [String]
@@ -284,7 +289,7 @@ module Spree
284
289
 
285
290
  # @param quantity [Fixnum] how many are desired
286
291
  # @return [Boolean] true if the desired quantity can be supplied
287
- def can_supply?(quantity=1)
292
+ def can_supply?(quantity = 1)
288
293
  Spree::Stock::Quantifier.new(self).can_supply?(quantity)
289
294
  end
290
295
 
@@ -301,7 +306,7 @@ module Spree
301
306
  #
302
307
  # @return [Boolean] true if inventory tracking is enabled
303
308
  def should_track_inventory?
304
- self.track_inventory? && Spree::Config.track_inventory_levels
309
+ track_inventory? && Spree::Config.track_inventory_levels
305
310
  end
306
311
 
307
312
  # Image that can be used for the variant.
@@ -321,56 +326,57 @@ module Spree
321
326
  #
322
327
  # @return [Array<Spree::VariantPropertyRuleValue>] variant_properties
323
328
  def variant_properties
324
- self.product.variant_property_rules.map do |rule|
329
+ product.variant_property_rules.map do |rule|
325
330
  rule.values if rule.applies_to_variant?(self)
326
331
  end.flatten.compact
327
332
  end
328
333
 
329
334
  private
330
335
 
331
- def set_master_out_of_stock
332
- if product.master && product.master.in_stock?
333
- product.master.stock_items.update_all(:backorderable => false)
334
- product.master.stock_items.each { |item| item.reduce_count_on_hand_to_zero }
335
- end
336
+ def set_master_out_of_stock
337
+ if product.master && product.master.in_stock?
338
+ product.master.stock_items.update_all(backorderable: false)
339
+ product.master.stock_items.each(&:reduce_count_on_hand_to_zero)
336
340
  end
341
+ end
337
342
 
338
- # Ensures a new variant takes the product master price when price is not supplied
339
- def check_price
340
- if price.nil? && Spree::Config[:require_master_price]
341
- if is_master?
342
- errors.add :price, 'Must supply price for variant or master.price for product.'
343
- else
344
- raise 'No master variant found to infer price' unless (product && product.master)
345
- self.price = product.master.price
346
- end
347
- end
348
- if currency.nil?
349
- self.currency = Spree::Config[:currency]
343
+ # Ensures a new variant takes the product master price when price is not supplied
344
+ def check_price
345
+ if price.nil? && Spree::Config[:require_master_price]
346
+ if is_master?
347
+ errors.add :price, 'Must supply price for variant or master.price for product.'
348
+ else
349
+ raise 'No master variant found to infer price' unless product && product.master
350
+ self.price = product.master.price
350
351
  end
351
352
  end
353
+ end
352
354
 
353
- def set_cost_currency
354
- self.cost_currency = Spree::Config[:currency] if cost_currency.blank?
355
- end
355
+ def set_cost_currency
356
+ self.cost_currency = Spree::Config[:currency] if cost_currency.blank?
357
+ end
356
358
 
357
- def create_stock_items
358
- StockLocation.where(propagate_all_variants: true).each do |stock_location|
359
- stock_location.propagate_variant(self)
360
- end
359
+ def create_stock_items
360
+ StockLocation.where(propagate_all_variants: true).each do |stock_location|
361
+ stock_location.propagate_variant(self)
361
362
  end
363
+ end
362
364
 
363
- def set_position
364
- self.update_column(:position, product.variants.maximum(:position).to_i + 1)
365
- end
365
+ def set_position
366
+ update_column(:position, product.variants.maximum(:position).to_i + 1)
367
+ end
366
368
 
367
- def in_stock_cache_key
368
- "variant-#{id}-in_stock"
369
- end
369
+ def in_stock_cache_key
370
+ "variant-#{id}-in_stock"
371
+ end
370
372
 
371
- def clear_in_stock_cache
372
- Rails.cache.delete(in_stock_cache_key)
373
- end
373
+ def clear_in_stock_cache
374
+ Rails.cache.delete(in_stock_cache_key)
375
+ end
376
+
377
+ def destroy_option_values_variants
378
+ option_values_variants.destroy_all
379
+ end
374
380
  end
375
381
  end
376
382
 
@@ -36,7 +36,7 @@ module Spree
36
36
  # @param variant [Spree::Variant] variant to check
37
37
  # @return [Boolean]
38
38
  def applies_to_variant?(variant)
39
- (self.option_value_ids & variant.option_value_ids).present?
39
+ (option_value_ids & variant.option_value_ids).present?
40
40
  end
41
41
  end
42
42
  end
@@ -2,6 +2,8 @@ module Spree
2
2
  class VariantPropertyRuleValue < Spree::Base
3
3
  include Spree::OrderedPropertyValueList
4
4
 
5
+ acts_as_list scope: :variant_property_rule
6
+
5
7
  belongs_to :property
6
8
  belongs_to :variant_property_rule, touch: true
7
9
  end
@@ -15,6 +15,27 @@ module Spree
15
15
  after_save :remove_defunct_members
16
16
  after_save :remove_previous_default
17
17
 
18
+ scope :with_member_ids, ->(state_ids, country_ids) do
19
+ return none if !state_ids.present? && !country_ids.present?
20
+
21
+ spree_zone_members_table = Spree::ZoneMember.arel_table
22
+ matching_state =
23
+ spree_zone_members_table[:zoneable_type].eq("Spree::State").
24
+ and(spree_zone_members_table[:zoneable_id].in(state_ids))
25
+ matching_country =
26
+ spree_zone_members_table[:zoneable_type].eq("Spree::Country").
27
+ and(spree_zone_members_table[:zoneable_id].in(country_ids))
28
+ joins(:zone_members).where(matching_state.or(matching_country)).distinct
29
+ end
30
+
31
+ scope :for_address, ->(address) do
32
+ if address
33
+ with_member_ids(address.state_id, address.country_id)
34
+ else
35
+ none
36
+ end
37
+ end
38
+
18
39
  alias :members :zone_members
19
40
  accepts_nested_attributes_for :zone_members, allow_destroy: true, reject_if: proc { |a| a['zoneable_id'].blank? }
20
41
 
@@ -24,13 +45,14 @@ module Spree
24
45
  where(default_tax: true).first
25
46
  end
26
47
 
27
- # Returns the matching zone with the highest priority zone type (State, Country, Zone.)
28
- # Returns nil in the case of no matches.
48
+ # Returns the most specific matching zone for an address. Specific means:
49
+ # A State zone wins over a country zone, and a zone with few members wins
50
+ # over one with many members. If there is no match, returns nil.
29
51
  def self.match(address)
30
- return unless address and matches = self.includes(:zone_members).
31
- order(:zone_members_count, :created_at, :id).
32
- where("(spree_zone_members.zoneable_type = 'Spree::Country' AND spree_zone_members.zoneable_id = ?) OR (spree_zone_members.zoneable_type = 'Spree::State' AND spree_zone_members.zoneable_id = ?)", address.country_id, address.state_id).
33
- references(:zones)
52
+ return unless address && (matches =
53
+ with_member_ids(address.state_id, address.country_id).
54
+ order(:zone_members_count, :created_at, :id).
55
+ references(:zones))
34
56
 
35
57
  ['state', 'country'].each do |zone_kind|
36
58
  if match = matches.detect { |zone| zone_kind == zone.kind }
@@ -40,6 +62,21 @@ module Spree
40
62
  matches.first
41
63
  end
42
64
 
65
+ # Returns all zones that contain any of the zone members of the zone passed
66
+ # in. This also includes any country zones that contain the state of the
67
+ # current zone, if it's a state zone. If the passed-in zone has members, it
68
+ # will also be in the result set.
69
+ def self.with_shared_members(zone)
70
+ return none unless zone
71
+
72
+ states_and_state_country_ids = zone.states.pluck(:id, :country_id).to_a
73
+ state_ids = states_and_state_country_ids.map(&:first)
74
+ state_country_ids = states_and_state_country_ids.map(&:second)
75
+ country_ids = zone.countries.pluck(:id).to_a
76
+
77
+ with_member_ids(state_ids, country_ids + state_country_ids).distinct
78
+ end
79
+
43
80
  def kind
44
81
  if members.any? && !members.any? { |member| member.try(:zoneable_type).nil? }
45
82
  members.last.zoneable_type.demodulize.underscore
@@ -116,33 +153,32 @@ module Spree
116
153
  return false if zone_members.empty? || target.zone_members.empty?
117
154
 
118
155
  if kind == target.kind
119
- return false if (target.zoneables.collect(&:id) - zoneables.collect(&:id)).present?
156
+ (target.zoneables.collect(&:id) - zoneables.collect(&:id)).empty?
120
157
  else
121
- return false if (target.zoneables.collect(&:country).collect(&:id) - zoneables.collect(&:id)).present?
158
+ (target.zoneables.collect(&:country).collect(&:id) - zoneables.collect(&:id)).empty?
122
159
  end
123
- true
124
160
  end
125
161
 
126
162
  private
127
163
 
128
- def remove_defunct_members
129
- if zone_members.any?
130
- zone_members.where('zoneable_id IS NULL OR zoneable_type != ?', "Spree::#{kind.classify}").destroy_all
131
- end
164
+ def remove_defunct_members
165
+ if zone_members.any?
166
+ zone_members.where('zoneable_id IS NULL OR zoneable_type != ?', "Spree::#{kind.classify}").destroy_all
132
167
  end
168
+ end
133
169
 
134
- def remove_previous_default
135
- Spree::Zone.where('id != ?', self.id).update_all(default_tax: false) if default_tax
136
- end
170
+ def remove_previous_default
171
+ Spree::Zone.where('id != ?', id).update_all(default_tax: false) if default_tax
172
+ end
137
173
 
138
- def set_zone_members(ids, type)
139
- zone_members.destroy_all
140
- ids.reject{ |id| id.blank? }.map do |id|
141
- member = ZoneMember.new
142
- member.zoneable_type = type
143
- member.zoneable_id = id
144
- members << member
145
- end
174
+ def set_zone_members(ids, type)
175
+ zone_members.destroy_all
176
+ ids.reject(&:blank?).map do |id|
177
+ member = ZoneMember.new
178
+ member.zoneable_type = type
179
+ member.zoneable_id = id
180
+ members << member
146
181
  end
182
+ end
147
183
  end
148
184
  end
@@ -17,7 +17,7 @@ FriendlyId.defaults do |config|
17
17
  config.use :reserved
18
18
 
19
19
  config.reserved_words = %w(new edit index session login logout users admin
20
- stylesheets assets javascripts images)
20
+ stylesheets assets javascripts images)
21
21
 
22
22
  # ## Friendly Finders
23
23
  #