spree_core 3.0.9 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (627) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/{spree.js.coffee.erb → spree.js.coffee} +13 -4
  3. data/app/helpers/spree/base_helper.rb +5 -2
  4. data/app/helpers/spree/products_helper.rb +37 -12
  5. data/app/mailers/spree/base_mailer.rb +11 -2
  6. data/app/mailers/spree/reimbursement_mailer.rb +6 -6
  7. data/app/models/concerns/spree/acts_as_taggable.rb +11 -0
  8. data/app/models/concerns/spree/adjustment_source.rb +3 -10
  9. data/app/models/concerns/spree/default_price.rb +7 -1
  10. data/app/models/concerns/spree/named_type.rb +1 -1
  11. data/app/models/concerns/spree/ransackable_attributes.rb +6 -1
  12. data/app/models/concerns/spree/user_api_authentication.rb +7 -1
  13. data/app/models/concerns/spree/user_methods.rb +57 -0
  14. data/app/models/concerns/spree/user_reporting.rb +2 -2
  15. data/app/models/concerns/spree/vat_price_calculation.rb +47 -0
  16. data/app/models/spree/ability.rb +9 -1
  17. data/app/models/spree/address.rb +75 -45
  18. data/app/models/spree/adjustable/adjuster/base.rb +25 -0
  19. data/app/models/spree/adjustable/adjuster/promotion.rb +41 -0
  20. data/app/models/spree/adjustable/adjuster/tax.rb +26 -0
  21. data/app/models/spree/adjustable/adjustments_updater.rb +22 -45
  22. data/app/models/spree/adjustment.rb +8 -10
  23. data/app/models/spree/app_configuration.rb +14 -8
  24. data/app/models/spree/base.rb +5 -1
  25. data/app/models/spree/calculator/default_tax.rb +2 -10
  26. data/app/models/spree/calculator/free_shipping.rb +6 -5
  27. data/app/models/spree/calculator.rb +1 -6
  28. data/app/models/spree/classification.rb +7 -3
  29. data/app/models/spree/country.rb +15 -3
  30. data/app/models/spree/credit_card.rb +37 -38
  31. data/app/models/spree/customer_return.rb +7 -15
  32. data/app/models/spree/gateway/bogus.rb +12 -12
  33. data/app/models/spree/gateway/bogus_simple.rb +4 -4
  34. data/app/models/spree/gateway.rb +8 -7
  35. data/app/models/spree/image.rb +3 -3
  36. data/app/models/spree/inventory_unit.rb +13 -14
  37. data/app/models/spree/legacy_user.rb +1 -14
  38. data/app/models/spree/line_item.rb +79 -67
  39. data/app/models/spree/log_entry.rb +1 -4
  40. data/app/models/spree/option_type.rb +15 -6
  41. data/app/models/spree/option_type_prototype.rb +9 -0
  42. data/app/models/spree/option_value.rb +11 -3
  43. data/app/models/spree/option_value_variant.rb +6 -0
  44. data/app/models/spree/order/checkout.rb +10 -13
  45. data/app/models/spree/order/currency_updater.rb +1 -1
  46. data/app/models/spree/order/store_credit.rb +96 -0
  47. data/app/models/spree/order.rb +105 -68
  48. data/app/models/spree/order_contents.rb +13 -7
  49. data/app/models/spree/order_inventory.rb +16 -9
  50. data/app/models/spree/order_promotion.rb +6 -0
  51. data/app/models/spree/order_updater.rb +4 -8
  52. data/app/models/spree/payment/gateway_options.rb +8 -4
  53. data/app/models/spree/payment/processing.rb +1 -1
  54. data/app/models/spree/payment.rb +55 -29
  55. data/app/models/spree/payment_method/store_credit.rb +130 -0
  56. data/app/models/spree/payment_method.rb +18 -13
  57. data/app/models/spree/preference.rb +1 -1
  58. data/app/models/spree/preferences/store.rb +2 -2
  59. data/app/models/spree/price.rb +16 -6
  60. data/app/models/spree/product/scopes.rb +22 -13
  61. data/app/models/spree/product.rb +83 -52
  62. data/app/models/spree/product_option_type.rb +7 -2
  63. data/app/models/spree/product_promotion_rule.rb +9 -0
  64. data/app/models/spree/product_property.rb +9 -10
  65. data/app/models/spree/promotion/actions/create_adjustment.rb +1 -1
  66. data/app/models/spree/promotion/actions/create_line_items.rb +21 -3
  67. data/app/models/spree/promotion/rules/country.rb +23 -0
  68. data/app/models/spree/promotion/rules/option_value.rb +13 -10
  69. data/app/models/spree/promotion/rules/product.rb +3 -1
  70. data/app/models/spree/promotion/rules/taxon.rb +3 -2
  71. data/app/models/spree/promotion/rules/user.rb +4 -4
  72. data/app/models/spree/promotion.rb +55 -19
  73. data/app/models/spree/promotion_action.rb +3 -3
  74. data/app/models/spree/promotion_category.rb +1 -1
  75. data/app/models/spree/promotion_handler/cart.rb +3 -17
  76. data/app/models/spree/promotion_handler/coupon.rb +22 -22
  77. data/app/models/spree/promotion_handler/page.rb +2 -2
  78. data/app/models/spree/promotion_rule_taxon.rb +9 -0
  79. data/app/models/spree/promotion_rule_user.rb +9 -0
  80. data/app/models/spree/property.rb +2 -1
  81. data/app/models/spree/property_prototype.rb +9 -0
  82. data/app/models/spree/prototype.rb +8 -3
  83. data/app/models/spree/prototype_taxon.rb +9 -0
  84. data/app/models/spree/refund.rb +10 -7
  85. data/app/models/spree/refund_reason.rb +2 -2
  86. data/app/models/spree/reimbursement.rb +12 -16
  87. data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +23 -6
  88. data/app/models/spree/reimbursement_type/store_credit.rb +28 -0
  89. data/app/models/spree/reimbursement_type.rb +5 -1
  90. data/app/models/spree/return_authorization.rb +8 -13
  91. data/app/models/spree/return_authorization_reason.rb +1 -1
  92. data/app/models/spree/return_item/eligibility_validator/time_since_purchase.rb +1 -1
  93. data/app/models/spree/return_item.rb +14 -13
  94. data/app/models/spree/role.rb +3 -2
  95. data/app/models/spree/role_user.rb +6 -0
  96. data/app/models/spree/shipment.rb +23 -30
  97. data/app/models/spree/shipment_handler.rb +2 -2
  98. data/app/models/spree/shipping_category.rb +6 -3
  99. data/app/models/spree/shipping_method.rb +12 -11
  100. data/app/models/spree/shipping_method_zone.rb +6 -0
  101. data/app/models/spree/shipping_rate.rb +16 -29
  102. data/app/models/spree/state.rb +3 -2
  103. data/app/models/spree/state_change.rb +1 -1
  104. data/app/models/spree/stock/adjuster.rb +9 -2
  105. data/app/models/spree/stock/content_item.rb +10 -12
  106. data/app/models/spree/stock/coordinator.rb +21 -15
  107. data/app/models/spree/stock/estimator.rb +28 -30
  108. data/app/models/spree/stock/inventory_unit_builder.rb +2 -10
  109. data/app/models/spree/stock/package.rb +11 -3
  110. data/app/models/spree/stock/packer.rb +16 -6
  111. data/app/models/spree/stock/prioritizer.rb +25 -15
  112. data/app/models/spree/stock/quantifier.rb +5 -5
  113. data/app/models/spree/stock/splitter/backordered.rb +2 -2
  114. data/app/models/spree/stock/splitter/shipping_category.rb +6 -1
  115. data/app/models/spree/stock_item.rb +15 -18
  116. data/app/models/spree/stock_location.rb +4 -7
  117. data/app/models/spree/stock_movement.rb +16 -9
  118. data/app/models/spree/stock_transfer.rb +11 -12
  119. data/app/models/spree/store.rb +15 -6
  120. data/app/models/spree/store_credit.rb +252 -0
  121. data/app/models/spree/store_credit_category.rb +22 -0
  122. data/app/models/spree/store_credit_event.rb +38 -0
  123. data/app/models/spree/store_credit_type.rb +6 -0
  124. data/app/models/spree/tag.rb +4 -0
  125. data/app/models/spree/tax_category.rb +3 -8
  126. data/app/models/spree/tax_rate.rb +61 -121
  127. data/app/models/spree/taxon.rb +12 -6
  128. data/app/models/spree/tracker.rb +12 -1
  129. data/app/models/spree/validations/db_maximum_length_validator.rb +2 -1
  130. data/app/models/spree/variant.rb +94 -49
  131. data/app/models/spree/zone.rb +23 -19
  132. data/app/models/spree/zone_member.rb +6 -0
  133. data/app/validators/db_maximum_length_validator.rb +11 -0
  134. data/app/views/layouts/spree/base_mailer.html.erb +38 -781
  135. data/app/views/spree/order_mailer/_adjustment.html.erb +8 -0
  136. data/app/views/spree/order_mailer/_subtotal.html.erb +8 -0
  137. data/app/views/spree/order_mailer/_total.html.erb +8 -0
  138. data/app/views/spree/order_mailer/cancel_email.html.erb +13 -28
  139. data/app/views/spree/order_mailer/cancel_email.text.erb +1 -1
  140. data/app/views/spree/order_mailer/confirm_email.html.erb +49 -63
  141. data/app/views/spree/order_mailer/confirm_email.text.erb +1 -1
  142. data/app/views/spree/shared/_base_mailer_header.html.erb +5 -7
  143. data/app/views/spree/shared/_base_mailer_stylesheets.html.erb +777 -0
  144. data/app/views/spree/shared/_error_messages.html.erb +1 -1
  145. data/app/views/spree/shared/_mailer_line_item.html.erb +12 -0
  146. data/app/views/spree/shared/_paths.html.erb +8 -0
  147. data/app/views/spree/shipment_mailer/shipped_email.html.erb +21 -14
  148. data/app/views/spree/shipment_mailer/shipped_email.text.erb +3 -3
  149. data/config/initializers/acts_as_taggable_on.rb +9 -0
  150. data/config/initializers/friendly_id.rb +0 -81
  151. data/config/initializers/user_class_extensions.rb +7 -38
  152. data/config/locales/en.yml +137 -12
  153. data/config/routes.rb +7 -0
  154. data/db/default/spree/countries.rb +5 -1
  155. data/db/default/spree/default_reimbursement_type.rb +1 -1
  156. data/db/default/spree/roles.rb +2 -2
  157. data/db/default/spree/states.rb +1 -1
  158. data/db/default/spree/zones.rb +4 -5
  159. data/db/migrate/20120831092320_spree_one_two.rb +101 -101
  160. data/db/migrate/20120831092359_spree_promo_one_two.rb +14 -14
  161. data/db/migrate/20120905145253_add_tax_rate_label.rb +1 -1
  162. data/db/migrate/20120905151823_add_toggle_tax_rate_display.rb +2 -2
  163. data/db/migrate/20120929093553_remove_unused_preference_columns.rb +4 -4
  164. data/db/migrate/20121009142519_add_lock_version_to_variant.rb +2 -2
  165. data/db/migrate/20121010142909_add_states_required_to_countries.rb +2 -2
  166. data/db/migrate/20121012071449_add_on_demand_to_product_and_variant.rb +3 -3
  167. data/db/migrate/20121017010007_remove_not_null_constraint_from_products_on_hand.rb +5 -5
  168. data/db/migrate/20121031162139_split_prices_from_variants.rb +10 -10
  169. data/db/migrate/20121107003422_remove_not_null_from_spree_prices_amount.rb +3 -3
  170. data/db/migrate/20121107184631_add_currency_to_line_items.rb +1 -1
  171. data/db/migrate/20121107194006_add_currency_to_orders.rb +1 -1
  172. data/db/migrate/20121109173623_add_cost_currency_to_variants.rb +2 -2
  173. data/db/migrate/20121111231553_remove_display_on_from_payment_methods.rb +1 -1
  174. data/db/migrate/20121124203911_add_position_to_taxonomies.rb +2 -2
  175. data/db/migrate/20121126040517_add_last_ip_to_spree_orders.rb +1 -1
  176. data/db/migrate/20121213162028_add_state_to_spree_adjustments.rb +1 -1
  177. data/db/migrate/20130114053446_add_display_on_to_spree_payment_methods.rb +1 -1
  178. data/db/migrate/20130120201805_add_position_to_product_properties.spree.rb +2 -2
  179. data/db/migrate/20130203232234_add_identifier_to_spree_payments.rb +1 -1
  180. data/db/migrate/20130207155350_add_order_id_index_to_payments.rb +1 -1
  181. data/db/migrate/20130208032954_add_primary_to_spree_products_taxons.rb +1 -1
  182. data/db/migrate/20130211190146_create_spree_stock_items.rb +2 -2
  183. data/db/migrate/20130211191120_create_spree_stock_locations.rb +1 -1
  184. data/db/migrate/20130213191427_create_default_stock.rb +1 -2
  185. data/db/migrate/20130222032153_add_order_id_index_to_shipments.rb +1 -1
  186. data/db/migrate/20130226032817_change_meta_description_on_spree_products_to_text.rb +2 -2
  187. data/db/migrate/20130226191231_add_stock_location_id_to_spree_shipments.rb +1 -1
  188. data/db/migrate/20130227143905_add_pending_to_inventory_unit.rb +3 -3
  189. data/db/migrate/20130228164411_remove_on_demand_from_product_and_variant.rb +1 -1
  190. data/db/migrate/20130228210442_create_shipping_method_zone.rb +3 -3
  191. data/db/migrate/20130301162745_remove_shipping_category_id_from_shipping_method.rb +1 -1
  192. data/db/migrate/20130301162924_create_shipping_method_categories.rb +3 -3
  193. data/db/migrate/20130301205200_add_tracking_url_to_spree_shipping_methods.rb +1 -1
  194. data/db/migrate/20130304162240_create_spree_shipping_rates.rb +5 -5
  195. data/db/migrate/20130304192936_remove_category_match_attributes_from_shipping_method.rb +1 -1
  196. data/db/migrate/20130305143310_create_stock_movements.rb +1 -1
  197. data/db/migrate/20130306181701_add_address_fields_to_stock_location.rb +3 -3
  198. data/db/migrate/20130306191917_add_active_field_to_stock_locations.rb +2 -2
  199. data/db/migrate/20130306195650_add_backorderable_to_stock_item.rb +2 -2
  200. data/db/migrate/20130307161754_add_default_quantity_to_stock_movement.rb +2 -2
  201. data/db/migrate/20130318151756_add_source_and_destination_to_stock_movements.rb +1 -1
  202. data/db/migrate/20130319062004_change_orders_total_precision.rb +5 -5
  203. data/db/migrate/20130319063911_change_spree_payments_amount_precision.rb +2 -2
  204. data/db/migrate/20130319064308_change_spree_return_authorization_amount_precision.rb +2 -2
  205. data/db/migrate/20130319082943_change_adjustments_amount_precision.rb +2 -2
  206. data/db/migrate/20130319183250_add_originator_to_stock_movement.rb +1 -1
  207. data/db/migrate/20130319190507_drop_source_and_destination_from_stock_movement.rb +3 -3
  208. data/db/migrate/20130325163316_migrate_inventory_unit_sold_to_on_hand.rb +3 -3
  209. data/db/migrate/20130326175857_add_stock_location_to_rma.rb +1 -1
  210. data/db/migrate/20130328130308_update_shipment_state_for_canceled_orders.rb +1 -1
  211. data/db/migrate/20130328195253_add_seo_metas_to_taxons.rb +1 -1
  212. data/db/migrate/20130329134939_remove_stock_item_and_variant_lock.rb +1 -1
  213. data/db/migrate/20130413230529_add_name_to_spree_credit_cards.rb +1 -1
  214. data/db/migrate/20130414000512_update_name_fields_on_spree_credit_cards.rb +2 -2
  215. data/db/migrate/20130417120034_add_index_to_source_columns_on_adjustments.rb +1 -1
  216. data/db/migrate/20130417120035_update_adjustment_states.rb +3 -3
  217. data/db/migrate/20130417123427_add_shipping_rates_to_shipments.rb +4 -4
  218. data/db/migrate/20130418125341_create_spree_stock_transfers.rb +1 -1
  219. data/db/migrate/20130423110707_drop_products_count_on_hand.rb +1 -1
  220. data/db/migrate/20130423223847_set_default_shipping_rate_cost.rb +1 -1
  221. data/db/migrate/20130509115210_add_number_to_stock_transfer.rb +1 -1
  222. data/db/migrate/20130514151929_add_sku_index_to_spree_variants.rb +1 -1
  223. data/db/migrate/20130515180736_add_backorderable_default_to_spree_stock_location.rb +1 -1
  224. data/db/migrate/20130516151222_add_propage_all_variants_to_spree_stock_location.rb +1 -1
  225. data/db/migrate/20130611054351_rename_shipping_methods_zones_to_spree_shipping_methods_zones.rb +1 -1
  226. data/db/migrate/20130611185927_add_user_id_index_to_spree_orders.rb +1 -1
  227. data/db/migrate/20130618041418_add_updated_at_to_spree_countries.rb +1 -1
  228. data/db/migrate/20130619012236_add_updated_at_to_spree_states.rb +1 -1
  229. data/db/migrate/20130626232741_add_cvv_result_code_and_cvv_result_message_to_spree_payments.rb +1 -1
  230. data/db/migrate/20130628021056_add_unique_index_to_permalink_on_spree_products.rb +2 -2
  231. data/db/migrate/20130628022817_add_unique_index_to_orders_shipments_and_stock_transfers.rb +4 -4
  232. data/db/migrate/20130708052307_add_deleted_at_to_spree_tax_rates.rb +1 -1
  233. data/db/migrate/20130711200933_remove_lock_version_from_inventory_units.rb +1 -1
  234. data/db/migrate/20130718042445_add_cost_price_to_line_item.rb +2 -2
  235. data/db/migrate/20130718233855_set_backorderable_to_default_to_false.rb +3 -3
  236. data/db/migrate/20130725031716_add_created_by_id_to_spree_orders.rb +1 -1
  237. data/db/migrate/20130729214043_index_completed_at_on_spree_orders.rb +1 -1
  238. data/db/migrate/20130802014537_add_tax_category_id_to_spree_line_items.rb +1 -1
  239. data/db/migrate/20130802022321_migrate_tax_categories_to_line_items.rb +1 -1
  240. data/db/migrate/20130806022521_drop_spree_mail_methods.rb +1 -1
  241. data/db/migrate/20130806145853_set_default_stock_location_on_shipments.rb +1 -1
  242. data/db/migrate/20130807024301_upgrade_adjustments.rb +4 -4
  243. data/db/migrate/20130807024302_rename_adjustment_fields.rb +1 -1
  244. data/db/migrate/20130809164245_add_admin_name_column_to_spree_shipping_methods.rb +1 -1
  245. data/db/migrate/20130809164330_add_admin_name_column_to_spree_stock_locations.rb +1 -1
  246. data/db/migrate/20130813004002_add_shipment_total_to_spree_orders.rb +2 -2
  247. data/db/migrate/20130813140619_expand_order_number_size.rb +3 -3
  248. data/db/migrate/20130813232134_rename_activators_to_promotions.rb +1 -1
  249. data/db/migrate/20130815000406_add_adjustment_total_to_line_items.rb +2 -2
  250. data/db/migrate/20130815024413_add_adjustment_total_to_shipments.rb +2 -2
  251. data/db/migrate/20130826062534_add_depth_to_spree_taxons.rb +1 -1
  252. data/db/migrate/20130828234942_add_tax_total_to_line_items_shipments_and_orders.rb +2 -2
  253. data/db/migrate/20130830001033_add_shipping_category_to_shipping_methods_and_products.rb +2 -2
  254. data/db/migrate/20130830001159_migrate_old_shipping_calculators.rb +1 -1
  255. data/db/migrate/20130903183026_add_code_to_spree_promotion_rules.rb +1 -1
  256. data/db/migrate/20130909115621_change_states_required_for_countries.rb +1 -1
  257. data/db/migrate/20130915032339_add_deleted_at_to_spree_stock_items.rb +1 -1
  258. data/db/migrate/20130917024658_remove_promotions_event_name_field.rb +2 -2
  259. data/db/migrate/20130924040529_add_promo_total_to_line_items_and_shipments_and_orders.rb +1 -1
  260. data/db/migrate/20131001013410_remove_unused_credit_card_fields.rb +2 -2
  261. data/db/migrate/20131026154747_add_track_inventory_to_variant.rb +2 -2
  262. data/db/migrate/20131107132123_add_tax_category_to_variants.rb +1 -1
  263. data/db/migrate/20131113035136_add_channel_to_spree_orders.rb +1 -1
  264. data/db/migrate/20131118043959_add_included_to_adjustments.rb +2 -2
  265. data/db/migrate/20131118050234_rename_tax_total_fields.rb +1 -1
  266. data/db/migrate/20131118183431_add_line_item_id_to_spree_inventory_units.rb +1 -1
  267. data/db/migrate/20131120234456_add_updated_at_to_variants.rb +1 -1
  268. data/db/migrate/20131127001002_add_position_to_classifications.rb +1 -1
  269. data/db/migrate/20131211112807_create_spree_orders_promotions.rb +2 -2
  270. data/db/migrate/20131211192741_unique_shipping_method_categories.rb +1 -1
  271. data/db/migrate/20131218054603_add_item_count_to_spree_orders.rb +2 -2
  272. data/db/migrate/20140106065820_remove_value_type_from_spree_preferences.rb +1 -1
  273. data/db/migrate/20140106224208_rename_permalink_to_slug_for_products.rb +1 -1
  274. data/db/migrate/20140120160805_add_index_to_variant_id_and_currency_on_prices.rb +1 -1
  275. data/db/migrate/20140124023232_rename_activator_id_in_rules_and_actions_to_promotion_id.rb +1 -1
  276. data/db/migrate/20140129024326_add_deleted_at_to_spree_prices.rb +1 -1
  277. data/db/migrate/20140203161722_add_approver_id_and_approved_at_to_orders.rb +1 -1
  278. data/db/migrate/20140204115338_add_confirmation_delivered_to_spree_orders.rb +1 -1
  279. data/db/migrate/20140204192230_add_auto_capture_to_payment_methods.rb +1 -1
  280. data/db/migrate/20140205120320_create_spree_payment_capture_events.rb +1 -1
  281. data/db/migrate/20140205144710_add_uncaptured_amount_to_payments.rb +1 -1
  282. data/db/migrate/20140205181631_default_variant_weight_to_zero.rb +1 -1
  283. data/db/migrate/20140207085910_add_tax_category_id_to_shipping_methods.rb +1 -1
  284. data/db/migrate/20140207093021_add_tax_rate_id_to_shipping_rates.rb +1 -1
  285. data/db/migrate/20140211040159_add_pre_tax_amount_to_line_items_and_shipments.rb +1 -1
  286. data/db/migrate/20140213184916_add_more_indexes.rb +1 -1
  287. data/db/migrate/20140219060952_add_considered_risky_to_orders.rb +2 -2
  288. data/db/migrate/20140227112348_add_preference_store_to_everything.rb +1 -1
  289. data/db/migrate/20140307235515_add_user_id_to_spree_credit_cards.rb +1 -1
  290. data/db/migrate/20140309023735_migrate_old_preferences.rb +1 -1
  291. data/db/migrate/20140309024355_create_spree_stores.rb +2 -2
  292. data/db/migrate/20140309033438_create_store_from_preferences.rb +2 -2
  293. data/db/migrate/20140315053743_add_timestamps_to_spree_assets.rb +1 -1
  294. data/db/migrate/20140318191500_create_spree_taxons_promotion_rules.rb +1 -1
  295. data/db/migrate/20140331100557_add_additional_store_fields.rb +1 -1
  296. data/db/migrate/20140410141842_add_many_missing_indexes.rb +1 -1
  297. data/db/migrate/20140410150358_correct_some_polymorphic_index_and_add_more_missing.rb +1 -1
  298. data/db/migrate/20140415041315_add_user_id_created_by_id_index_to_order.rb +1 -1
  299. data/db/migrate/20140508151342_change_spree_price_amount_precision.rb +5 -5
  300. data/db/migrate/20140518174634_add_token_to_spree_orders.rb +1 -1
  301. data/db/migrate/20140530024945_move_order_token_from_tokenized_permission.rb +2 -2
  302. data/db/migrate/20140601011216_set_shipment_total_for_users_upgrading.rb +1 -1
  303. data/db/migrate/20140604135309_drop_credit_card_first_name_and_last_name.rb +1 -1
  304. data/db/migrate/20140609201656_add_deleted_at_to_spree_promotion_actions.rb +1 -1
  305. data/db/migrate/20140616202624_remove_uncaptured_amount_from_spree_payments.rb +1 -1
  306. data/db/migrate/20140625214618_create_spree_refunds.rb +1 -1
  307. data/db/migrate/20140702140656_create_spree_return_authorization_inventory_unit.rb +1 -1
  308. data/db/migrate/20140707125621_rename_return_authorization_inventory_unit_to_return_items.rb +1 -1
  309. data/db/migrate/20140709160534_backfill_line_item_pre_tax_amount.rb +1 -1
  310. data/db/migrate/20140710041921_recreate_spree_return_authorizations.rb +2 -2
  311. data/db/migrate/20140710181204_add_amount_fields_to_return_items.rb +1 -1
  312. data/db/migrate/20140710190048_drop_return_authorization_amount.rb +1 -1
  313. data/db/migrate/20140713140455_create_spree_return_authorization_reasons.rb +1 -1
  314. data/db/migrate/20140713140527_create_spree_refund_reasons.rb +1 -1
  315. data/db/migrate/20140713142214_rename_return_authorization_reason.rb +1 -1
  316. data/db/migrate/20140715182625_create_spree_promotion_categories.rb +1 -1
  317. data/db/migrate/20140716204111_drop_received_at_on_return_items.rb +1 -1
  318. data/db/migrate/20140716212330_add_reception_and_acceptance_status_to_return_items.rb +1 -1
  319. data/db/migrate/20140717155155_create_default_refund_reason.rb +1 -1
  320. data/db/migrate/20140717185932_add_default_to_spree_stock_locations.rb +1 -1
  321. data/db/migrate/20140718133010_create_spree_customer_returns.rb +1 -1
  322. data/db/migrate/20140718133349_add_customer_return_id_to_return_item.rb +1 -1
  323. data/db/migrate/20140718195325_create_friendly_id_slugs.rb +5 -5
  324. data/db/migrate/20140723004419_rename_spree_refund_return_authorization_id.rb +1 -1
  325. data/db/migrate/20140723152808_increase_return_item_pre_tax_amount_precision.rb +1 -1
  326. data/db/migrate/20140723214541_copy_product_slugs_to_slug_history.rb +2 -2
  327. data/db/migrate/20140725131539_create_spree_reimbursements.rb +1 -1
  328. data/db/migrate/20140728225422_add_promotionable_to_spree_products.rb +1 -1
  329. data/db/migrate/20140729133613_add_exchange_inventory_unit_foreign_keys.rb +1 -1
  330. data/db/migrate/20140730155938_add_acceptance_status_errors_to_return_item.rb +1 -1
  331. data/db/migrate/20140731150017_create_spree_reimbursement_types.rb +1 -1
  332. data/db/migrate/20140804185157_add_default_to_shipment_cost.rb +1 -1
  333. data/db/migrate/20140805171035_add_default_to_spree_credit_cards.rb +1 -1
  334. data/db/migrate/20140805171219_make_existing_credit_cards_default.rb +1 -1
  335. data/db/migrate/20140806144901_add_type_to_reimbursement_type.rb +1 -1
  336. data/db/migrate/20140808184039_create_spree_reimbursement_credits.rb +1 -1
  337. data/db/migrate/20140827170513_add_meta_title_to_spree_products.rb +1 -1
  338. data/db/migrate/20140911173301_add_kind_to_zone.rb +1 -1
  339. data/db/migrate/20140924164824_add_code_to_spree_tax_categories.rb +1 -1
  340. data/db/migrate/20140927193717_default_pre_tax_amount_should_be_zero.rb +1 -1
  341. data/db/migrate/20141002191113_add_code_to_spree_shipping_methods.rb +1 -1
  342. data/db/migrate/20141007230328_add_cancel_audit_fields_to_spree_orders.rb +1 -1
  343. data/db/migrate/20141009204607_add_store_id_to_orders.rb +1 -1
  344. data/db/migrate/20141012083513_create_spree_taxons_prototypes.rb +1 -1
  345. data/db/migrate/20141021194502_add_state_lock_version_to_order.rb +1 -1
  346. data/db/migrate/20141023005240_add_counter_cache_from_spree_variants_to_spree_stock_items.rb +2 -7
  347. data/db/migrate/20141101231208_fix_adjustment_order_presence.rb +1 -1
  348. data/db/migrate/20141105213646_update_classifications_positions.rb +1 -1
  349. data/db/migrate/20141120135441_add_guest_token_index_to_spree_orders.rb +1 -1
  350. data/db/migrate/20141215232040_remove_token_permissions_table.rb +1 -1
  351. data/db/migrate/20141215235502_remove_extra_products_slug_index.rb +1 -1
  352. data/db/migrate/20141217215630_update_product_slug_index.rb +1 -1
  353. data/db/migrate/20141218025915_rename_identifier_to_number_for_payment.rb +1 -1
  354. data/db/migrate/20150118210639_create_spree_store_credits.rb +24 -0
  355. data/db/migrate/20150118211500_create_spree_store_credit_categories.rb +8 -0
  356. data/db/migrate/20150118212051_create_spree_store_credit_events.rb +17 -0
  357. data/db/migrate/20150118212101_create_spree_store_credit_types.rb +10 -0
  358. data/db/migrate/20150121022521_remove_environment_from_payment_method.rb +1 -1
  359. data/db/migrate/20150122145607_add_resellable_to_return_items.rb +1 -1
  360. data/db/migrate/20150122202432_add_code_to_spree_promotion_categories.rb +1 -1
  361. data/db/migrate/20150128032538_remove_environment_from_tracker.rb +1 -1
  362. data/db/migrate/20150128060325_remove_spree_configurations.rb +1 -1
  363. data/db/migrate/20150216173445_add_index_to_spree_stock_items_variant_id.rb +1 -1
  364. data/db/migrate/20150309161154_ensure_payments_have_numbers.rb +1 -1
  365. data/db/migrate/20150314013438_add_missing_indexes_on_spree_tables.rb +67 -0
  366. data/db/migrate/20150317174308_remove_duplicated_indexes_from_multi_columns.rb +18 -0
  367. data/db/migrate/20150324104002_remove_user_index_from_spree_state_changes.rb +14 -0
  368. data/db/migrate/20150515211137_fix_adjustment_order_id.rb +1 -1
  369. data/db/migrate/20150522071831_add_position_to_spree_payment_methods.rb +5 -0
  370. data/db/migrate/20150522181728_add_deleted_at_to_friendly_id_slugs.rb +1 -1
  371. data/db/migrate/20150609093816_increase_scale_on_pre_tax_amounts.rb +1 -1
  372. data/db/migrate/20150626181949_add_taxable_adjustment_total_to_line_item.rb +19 -0
  373. data/db/migrate/20150627090949_migrate_payment_methods_display.rb +12 -0
  374. data/db/migrate/20150707204155_enable_acts_as_paranoid_on_calculators.rb +1 -1
  375. data/db/migrate/20150714154102_spree_payment_method_store_credits.rb +12 -0
  376. data/db/migrate/20150726141425_rename_has_and_belongs_to_associations_to_model_names.rb +18 -0
  377. data/db/migrate/20150727191614_spree_store_credit_types.rb +11 -0
  378. data/db/migrate/20150819154308_add_discontinued_to_products_and_variants.rb +68 -0
  379. data/db/migrate/20151220072838_remove_shipping_method_id_from_spree_orders.rb +13 -0
  380. data/db/migrate/20160207191757_add_id_column_to_earlier_habtm_tables.rb +16 -0
  381. data/db/migrate/20160219165458_add_indexes.rb +14 -0
  382. data/db/migrate/20160509064646_remove_counter_cache_from_spree_variants_to_spree_stock_items.rb +10 -0
  383. data/db/migrate/20160511071954_acts_as_taggable_on_spree_migration.rb +40 -0
  384. data/db/migrate/20160511072249_change_collation_for_spree_tag_names.rb +9 -0
  385. data/db/migrate/20160511072335_add_missing_indexes_to_spree_taggings.rb +14 -0
  386. data/db/migrate/20160608090604_add_zipcode_required_to_spree_countries.rb +7 -0
  387. data/db/migrate/20161014145148_add_created_at_to_variant.rb +8 -0
  388. data/db/migrate/20161014152814_add_null_false_to_spree_variants_timestamps.rb +6 -0
  389. data/lib/generators/spree/custom_user/custom_user_generator.rb +1 -1
  390. data/lib/generators/spree/custom_user/templates/authentication_helpers.rb.tt +3 -3
  391. data/lib/generators/spree/custom_user/templates/migration.rb.tt +2 -2
  392. data/lib/generators/spree/dummy/dummy_generator.rb +11 -11
  393. data/lib/generators/spree/dummy/templates/rails/application.rb +1 -1
  394. data/lib/generators/spree/dummy/templates/rails/database.yml +38 -28
  395. data/lib/generators/spree/dummy/templates/rails/test.rb +4 -3
  396. data/lib/generators/spree/install/install_generator.rb +37 -13
  397. data/lib/spree/core/controller_helpers/auth.rb +1 -1
  398. data/lib/spree/core/controller_helpers/common.rb +6 -6
  399. data/lib/spree/core/controller_helpers/order.rb +9 -10
  400. data/lib/spree/core/controller_helpers/respond_with.rb +1 -1
  401. data/lib/spree/core/controller_helpers/search.rb +1 -1
  402. data/lib/spree/core/controller_helpers/store.rb +29 -0
  403. data/lib/spree/core/delegate_belongs_to.rb +4 -4
  404. data/lib/spree/core/engine.rb +39 -20
  405. data/lib/spree/core/environment.rb +1 -1
  406. data/lib/spree/core/importer/order.rb +37 -40
  407. data/lib/spree/core/importer/product.rb +2 -2
  408. data/lib/spree/core/number_generator.rb +52 -0
  409. data/lib/spree/core/product_duplicator.rb +1 -1
  410. data/lib/spree/core/product_filters.rb +2 -2
  411. data/lib/spree/core/search/base.rb +4 -3
  412. data/lib/spree/core/version.rb +1 -1
  413. data/lib/spree/core.rb +16 -0
  414. data/lib/spree/i18n/initializer.rb +1 -1
  415. data/lib/spree/localized_number.rb +3 -1
  416. data/lib/spree/permitted_attributes.rb +6 -3
  417. data/lib/spree/testing_support/caching.rb +3 -3
  418. data/lib/spree/testing_support/common_rake.rb +3 -3
  419. data/lib/spree/testing_support/controller_requests.rb +4 -4
  420. data/lib/spree/testing_support/factories/address_factory.rb +1 -1
  421. data/lib/spree/testing_support/factories/country_factory.rb +2 -2
  422. data/lib/spree/testing_support/factories/line_item_factory.rb +0 -1
  423. data/lib/spree/testing_support/factories/order_factory.rb +3 -2
  424. data/lib/spree/testing_support/factories/payment_factory.rb +5 -0
  425. data/lib/spree/testing_support/factories/payment_method_factory.rb +8 -0
  426. data/lib/spree/testing_support/factories/promotion_rule_factory.rb +5 -0
  427. data/lib/spree/testing_support/factories/refund_factory.rb +9 -1
  428. data/lib/spree/testing_support/factories/return_authorization_factory.rb +2 -0
  429. data/lib/spree/testing_support/factories/state_factory.rb +2 -2
  430. data/lib/spree/testing_support/factories/store_credit_category_factory.rb +9 -0
  431. data/lib/spree/testing_support/factories/store_credit_event_factory.rb +8 -0
  432. data/lib/spree/testing_support/factories/store_credit_factory.rb +17 -0
  433. data/lib/spree/testing_support/factories/store_credit_type_factory.rb +11 -0
  434. data/lib/spree/testing_support/factories/tag_factory.rb +5 -0
  435. data/lib/spree/testing_support/factories/user_factory.rb +1 -1
  436. data/lib/spree/testing_support/factories/zone_member_factory.rb +6 -0
  437. data/lib/spree/testing_support/factories.rb +3 -3
  438. data/lib/spree/testing_support/kernel.rb +18 -0
  439. data/lib/spree/testing_support/microdata.rb +189 -0
  440. data/lib/spree/testing_support/order_walkthrough.rb +4 -4
  441. data/lib/tasks/core.rake +69 -1
  442. data/lib/tasks/exchanges.rake +2 -2
  443. data/spec/fixtures/microdata.html +22 -0
  444. data/spec/fixtures/microdata_itemref.html +15 -0
  445. data/spec/fixtures/microdata_no_itemscope.html +20 -0
  446. data/spec/helpers/base_helper_spec.rb +74 -11
  447. data/spec/helpers/products_helper_spec.rb +80 -15
  448. data/spec/lib/i18n_spec.rb +13 -13
  449. data/spec/lib/search/base_spec.rb +18 -18
  450. data/spec/lib/spree/core/controller_helpers/auth_spec.rb +6 -4
  451. data/spec/lib/spree/core/controller_helpers/order_spec.rb +15 -0
  452. data/spec/lib/spree/core/controller_helpers/store_spec.rb +56 -0
  453. data/spec/lib/spree/core/importer/order_spec.rb +227 -124
  454. data/spec/lib/spree/core/number_generator_spec.rb +175 -0
  455. data/spec/lib/spree/core_spec.rb +23 -0
  456. data/spec/lib/spree/localized_number_spec.rb +11 -1
  457. data/spec/lib/spree/money_spec.rb +6 -6
  458. data/spec/mailers/order_mailer_spec.rb +11 -13
  459. data/spec/mailers/reimbursement_mailer_spec.rb +2 -2
  460. data/spec/mailers/shipment_mailer_spec.rb +26 -8
  461. data/spec/mailers/test_mailer_spec.rb +16 -2
  462. data/spec/models/option_type_prototype_spec.rb +9 -0
  463. data/spec/models/spree/ability_spec.rb +20 -15
  464. data/spec/models/spree/address_spec.rb +144 -33
  465. data/spec/models/spree/adjustable/adjuster/base_spec.rb +10 -0
  466. data/spec/models/spree/adjustable/adjuster/promotion_spec.rb +211 -0
  467. data/spec/models/spree/adjustable/adjuster/tax_spec.rb +86 -0
  468. data/spec/models/spree/adjustable/adjustments_updater_spec.rb +2 -262
  469. data/spec/models/spree/adjustment_spec.rb +28 -2
  470. data/spec/models/spree/app_configuration_spec.rb +6 -3
  471. data/spec/models/spree/asset_spec.rb +9 -6
  472. data/spec/models/spree/calculator/default_tax_spec.rb +39 -14
  473. data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +1 -1
  474. data/spec/models/spree/calculator/flexi_rate_spec.rb +6 -6
  475. data/spec/models/spree/calculator/percent_on_line_item_spec.rb +1 -1
  476. data/spec/models/spree/calculator/price_sack_spec.rb +2 -2
  477. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +4 -8
  478. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +4 -4
  479. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +2 -2
  480. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +6 -6
  481. data/spec/models/spree/calculator/shipping/per_item_spec.rb +2 -2
  482. data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +1 -1
  483. data/spec/models/spree/calculator/tiered_percent_spec.rb +1 -1
  484. data/spec/models/spree/calculator_spec.rb +3 -3
  485. data/spec/models/spree/classification_spec.rb +1 -1
  486. data/spec/models/spree/concerns/user_methods_spec.rb +82 -0
  487. data/spec/models/spree/concerns/vat_price_calculation_spec.rb +66 -0
  488. data/spec/models/spree/country_spec.rb +45 -8
  489. data/spec/models/spree/credit_card_spec.rb +13 -9
  490. data/spec/models/spree/customer_return_spec.rb +4 -26
  491. data/spec/models/spree/exchange_spec.rb +1 -1
  492. data/spec/models/spree/gateway/bogus_simple.rb +1 -1
  493. data/spec/models/spree/gateway/bogus_spec.rb +1 -1
  494. data/spec/models/spree/gateway_spec.rb +8 -1
  495. data/spec/models/spree/image_spec.rb +4 -1
  496. data/spec/models/spree/inventory_unit_spec.rb +35 -21
  497. data/spec/models/spree/line_item_spec.rb +100 -21
  498. data/spec/models/spree/option_type_spec.rb +3 -3
  499. data/spec/models/spree/option_value_spec.rb +8 -3
  500. data/spec/models/spree/order/address_spec.rb +1 -1
  501. data/spec/models/spree/order/adjustments_spec.rb +1 -1
  502. data/spec/models/spree/order/callbacks_spec.rb +3 -3
  503. data/spec/models/spree/order/checkout_spec.rb +99 -93
  504. data/spec/models/spree/order/currency_updater_spec.rb +4 -4
  505. data/spec/models/spree/order/finalizing_spec.rb +5 -8
  506. data/spec/models/spree/order/helpers_spec.rb +1 -1
  507. data/spec/models/spree/order/payment_spec.rb +21 -21
  508. data/spec/models/spree/order/risk_assessment_spec.rb +1 -1
  509. data/spec/models/spree/order/state_machine_spec.rb +4 -8
  510. data/spec/models/spree/order/store_credit_spec.rb +426 -0
  511. data/spec/models/spree/order/tax_spec.rb +13 -13
  512. data/spec/models/spree/order/totals_spec.rb +2 -2
  513. data/spec/models/spree/order/updating_spec.rb +4 -4
  514. data/spec/models/spree/order/validations_spec.rb +2 -2
  515. data/spec/models/spree/order_contents_spec.rb +45 -4
  516. data/spec/models/spree/order_inventory_spec.rb +28 -17
  517. data/spec/models/spree/order_merger_spec.rb +3 -1
  518. data/spec/models/spree/order_spec.rb +188 -96
  519. data/spec/models/spree/order_updater_spec.rb +43 -32
  520. data/spec/models/spree/payment/gateway_options_spec.rb +10 -2
  521. data/spec/models/spree/payment/store_credit_spec.rb +60 -0
  522. data/spec/models/spree/payment_method/store_credit_spec.rb +291 -0
  523. data/spec/models/spree/payment_method_spec.rb +22 -14
  524. data/spec/models/spree/payment_spec.rb +75 -82
  525. data/spec/models/spree/preference_spec.rb +1 -1
  526. data/spec/models/spree/preferences/configuration_spec.rb +2 -2
  527. data/spec/models/spree/preferences/preferable_spec.rb +15 -19
  528. data/spec/models/spree/preferences/scoped_store_spec.rb +1 -1
  529. data/spec/models/spree/preferences/store_spec.rb +3 -3
  530. data/spec/models/spree/price_spec.rb +87 -1
  531. data/spec/models/spree/product/scopes_spec.rb +39 -4
  532. data/spec/models/spree/product_duplicator_spec.rb +2 -2
  533. data/spec/models/spree/product_filter_spec.rb +2 -2
  534. data/spec/models/spree/product_option_type_spec.rb +6 -2
  535. data/spec/models/spree/product_promotion_rule_spec.rb +9 -0
  536. data/spec/models/spree/product_property_spec.rb +16 -1
  537. data/spec/models/spree/product_spec.rb +196 -41
  538. data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +63 -0
  539. data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +6 -6
  540. data/spec/models/spree/promotion/actions/free_shipping_spec.rb +1 -1
  541. data/spec/models/spree/promotion/rules/country_spec.rb +36 -0
  542. data/spec/models/spree/promotion/rules/first_order_spec.rb +11 -11
  543. data/spec/models/spree/promotion/rules/item_total_spec.rb +1 -1
  544. data/spec/models/spree/promotion/rules/one_use_per_user_spec.rb +1 -1
  545. data/spec/models/spree/promotion/rules/product_spec.rb +8 -8
  546. data/spec/models/spree/promotion/rules/taxon_spec.rb +1 -1
  547. data/spec/models/spree/promotion/rules/user_logged_in_spec.rb +3 -3
  548. data/spec/models/spree/promotion/rules/user_spec.rb +15 -7
  549. data/spec/models/spree/promotion_action_spec.rb +2 -2
  550. data/spec/models/spree/promotion_category_spec.rb +1 -1
  551. data/spec/models/spree/promotion_handler/cart_spec.rb +1 -1
  552. data/spec/models/spree/promotion_handler/coupon_spec.rb +28 -28
  553. data/spec/models/spree/promotion_handler/page_spec.rb +6 -6
  554. data/spec/models/spree/promotion_rule_spec.rb +2 -2
  555. data/spec/models/spree/promotion_rule_taxon_spec.rb +9 -0
  556. data/spec/models/spree/promotion_rule_user_spec.rb +9 -0
  557. data/spec/models/spree/promotion_spec.rb +141 -65
  558. data/spec/models/spree/property_prototype_spec.rb +9 -0
  559. data/spec/models/spree/property_spec.rb +1 -1
  560. data/spec/models/spree/prototype_spec.rb +1 -1
  561. data/spec/models/spree/prototype_taxon_spec.rb +9 -0
  562. data/spec/models/spree/refund_reason_spec.rb +20 -0
  563. data/spec/models/spree/refund_spec.rb +1 -1
  564. data/spec/models/spree/reimbursement/credit_spec.rb +1 -1
  565. data/spec/models/spree/reimbursement/reimbursement_type_engine_spec.rb +1 -1
  566. data/spec/models/spree/reimbursement/reimbursement_type_validator_spec.rb +1 -1
  567. data/spec/models/spree/reimbursement_performer_spec.rb +1 -1
  568. data/spec/models/spree/reimbursement_spec.rb +3 -30
  569. data/spec/models/spree/reimbursement_tax_calculator_spec.rb +18 -6
  570. data/spec/models/spree/reimbursement_type/credit_spec.rb +1 -1
  571. data/spec/models/spree/reimbursement_type/exchange_spec.rb +1 -1
  572. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +1 -1
  573. data/spec/models/spree/reimbursement_type/store_credit_spec.rb +101 -0
  574. data/spec/models/spree/return_authorization_reason_spec.rb +7 -0
  575. data/spec/models/spree/return_authorization_spec.rb +3 -23
  576. data/spec/models/spree/return_item/eligibility_validator/default_spec.rb +1 -1
  577. data/spec/models/spree/return_item/eligibility_validator/rma_required_spec.rb +1 -1
  578. data/spec/models/spree/return_item/eligibility_validator/time_since_purchase_spec.rb +1 -1
  579. data/spec/models/spree/return_item/exchange_variant_eligibility/same_option_value_spec.rb +1 -1
  580. data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +1 -1
  581. data/spec/models/spree/return_item_spec.rb +51 -2
  582. data/spec/models/spree/returns_calculator_spec.rb +2 -2
  583. data/spec/models/spree/role_spec.rb +7 -0
  584. data/spec/models/spree/shipment_spec.rb +24 -22
  585. data/spec/models/spree/shipping_calculator_spec.rb +5 -5
  586. data/spec/models/spree/shipping_category_spec.rb +15 -1
  587. data/spec/models/spree/shipping_method_spec.rb +11 -4
  588. data/spec/models/spree/shipping_rate_spec.rb +40 -41
  589. data/spec/models/spree/state_spec.rb +13 -2
  590. data/spec/models/spree/stock/availability_validator_spec.rb +1 -1
  591. data/spec/models/spree/stock/content_item_spec.rb +9 -0
  592. data/spec/models/spree/stock/coordinator_spec.rb +13 -3
  593. data/spec/models/spree/stock/differentiator_spec.rb +1 -1
  594. data/spec/models/spree/stock/estimator_spec.rb +60 -12
  595. data/spec/models/spree/stock/inventory_unit_builder_spec.rb +1 -1
  596. data/spec/models/spree/stock/package_spec.rb +6 -18
  597. data/spec/models/spree/stock/packer_spec.rb +1 -1
  598. data/spec/models/spree/stock/prioritizer_spec.rb +7 -7
  599. data/spec/models/spree/stock/quantifier_spec.rb +61 -32
  600. data/spec/models/spree/stock/splitter/backordered_spec.rb +1 -1
  601. data/spec/models/spree/stock/splitter/base_spec.rb +1 -1
  602. data/spec/models/spree/stock/splitter/shipping_category_spec.rb +3 -3
  603. data/spec/models/spree/stock_item_spec.rb +30 -8
  604. data/spec/models/spree/stock_location_spec.rb +5 -5
  605. data/spec/models/spree/stock_movement_spec.rb +101 -37
  606. data/spec/models/spree/stock_transfer_spec.rb +1 -1
  607. data/spec/models/spree/store_credit_event_spec.rb +101 -0
  608. data/spec/models/spree/store_credit_spec.rb +786 -0
  609. data/spec/models/spree/store_spec.rb +40 -12
  610. data/spec/models/spree/tax_category_spec.rb +7 -2
  611. data/spec/models/spree/tax_rate_spec.rb +288 -109
  612. data/spec/models/spree/taxon_spec.rb +15 -4
  613. data/spec/models/spree/taxonomy_spec.rb +2 -2
  614. data/spec/models/spree/tracker_spec.rb +1 -1
  615. data/spec/models/spree/user_spec.rb +114 -41
  616. data/spec/models/spree/variant_spec.rb +310 -15
  617. data/spec/models/spree/zone_member_spec.rb +38 -0
  618. data/spec/models/spree/zone_spec.rb +38 -10
  619. data/spec/spec_helper.rb +5 -0
  620. data/spec/support/concerns/{adjustment_source_spec.rb → adjustment_source.rb} +0 -0
  621. data/spec/support/concerns/{default_price_spec.rb → default_price.rb} +9 -0
  622. data/spree_core.gemspec +12 -13
  623. data/vendor/assets/javascripts/jquery.payment.js +239 -84
  624. metadata +136 -65
  625. data/CHANGELOG.md +0 -4
  626. data/app/models/concerns/spree/number_generator.rb +0 -39
  627. data/spec/models/spree/validations/db_maximum_length_validator_spec.rb +0 -24
@@ -0,0 +1,38 @@
1
+ module Spree
2
+ class StoreCreditEvent < Spree::Base
3
+ acts_as_paranoid
4
+
5
+ belongs_to :store_credit
6
+ belongs_to :originator, polymorphic: true
7
+
8
+ scope :exposed_events, -> { where.not(action: [Spree::StoreCredit::ELIGIBLE_ACTION, Spree::StoreCredit::AUTHORIZE_ACTION]) }
9
+ scope :reverse_chronological, -> { order(created_at: :desc) }
10
+
11
+ delegate :currency, to: :store_credit
12
+
13
+ def display_amount
14
+ Spree::Money.new(amount, currency: currency)
15
+ end
16
+
17
+ def display_user_total_amount
18
+ Spree::Money.new(user_total_amount, currency: currency)
19
+ end
20
+
21
+ def display_action
22
+ case action
23
+ when Spree::StoreCredit::CAPTURE_ACTION
24
+ Spree.t('store_credit.captured')
25
+ when Spree::StoreCredit::AUTHORIZE_ACTION
26
+ Spree.t('store_credit.authorized')
27
+ when Spree::StoreCredit::ALLOCATION_ACTION
28
+ Spree.t('store_credit.allocated')
29
+ when Spree::StoreCredit::VOID_ACTION, Spree::StoreCredit::CREDIT_ACTION
30
+ Spree.t('store_credit.credit')
31
+ end
32
+ end
33
+
34
+ def order
35
+ Spree::Payment.find_by_response_code(authorization_code).try(:order)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,6 @@
1
+ module Spree
2
+ class StoreCreditType < Spree::Base
3
+ DEFAULT_TYPE_NAME = 'Expiring'.freeze
4
+ has_many :store_credits, class_name: 'Spree::StoreCredit', foreign_key: 'type_id'
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+ module Spree
2
+ class Tag < ActsAsTaggableOn::Tag
3
+ end
4
+ end
@@ -1,7 +1,7 @@
1
1
  module Spree
2
2
  class TaxCategory < Spree::Base
3
3
  acts_as_paranoid
4
- validates :name, presence: true, uniqueness: { scope: :deleted_at, allow_blank: true }
4
+ validates :name, presence: true, uniqueness: { case_sensitive: false, scope: :deleted_at, allow_blank: true }
5
5
 
6
6
  has_many :tax_rates, dependent: :destroy, inverse_of: :tax_category
7
7
 
@@ -10,13 +10,8 @@ module Spree
10
10
  def set_default_category
11
11
  #set existing default tax category to false if this one has been marked as default
12
12
 
13
- if is_default && tax_category = self.class.where(is_default: true).first
14
- unless tax_category == self
15
- tax_category.update_columns(
16
- is_default: false,
17
- updated_at: Time.now,
18
- )
19
- end
13
+ if is_default && tax_category = self.class.where(is_default: true).where.not(id: id).first
14
+ tax_category.update_columns(is_default: false, updated_at: Time.current)
20
15
  end
21
16
  end
22
17
  end
@@ -1,13 +1,3 @@
1
- module Spree
2
- class DefaultTaxZoneValidator < ActiveModel::Validator
3
- def validate(record)
4
- if record.included_in_price
5
- record.errors.add(:included_in_price, Spree.t(:included_price_validation)) unless Zone.default_tax
6
- end
7
- end
8
- end
9
- end
10
-
11
1
  module Spree
12
2
  class TaxRate < Spree::Base
13
3
  acts_as_paranoid
@@ -15,50 +5,32 @@ module Spree
15
5
  include Spree::CalculatedAdjustments
16
6
  include Spree::AdjustmentSource
17
7
 
18
- belongs_to :zone, class_name: "Spree::Zone", inverse_of: :tax_rates
19
- belongs_to :tax_category, class_name: "Spree::TaxCategory", inverse_of: :tax_rates
20
-
21
- validates :amount, presence: true, numericality: true
22
- validates :tax_category_id, presence: true
23
- validates_with DefaultTaxZoneValidator
24
-
25
- scope :by_zone, ->(zone) { where(zone_id: zone) }
8
+ with_options inverse_of: :tax_rates do
9
+ belongs_to :zone, class_name: "Spree::Zone"
10
+ belongs_to :tax_category,
11
+ class_name: "Spree::TaxCategory"
12
+ end
26
13
 
27
- def self.potential_rates_for_zone(zone)
28
- select("spree_tax_rates.*, spree_zones.default_tax").
29
- joins(:zone).
30
- merge(Spree::Zone.potential_matching_zones(zone)).
31
- order("spree_zones.default_tax DESC")
14
+ with_options presence: true do
15
+ validates :amount, numericality: { allow_nil: true }
16
+ validates :tax_category
32
17
  end
33
18
 
34
- # Gets the array of TaxRates appropriate for the specified order
19
+ scope :by_zone, -> (zone) { where(zone_id: zone.id) }
20
+ scope :potential_rates_for_zone,
21
+ -> (zone) do
22
+ where(zone_id: Spree::Zone.potential_matching_zones(zone).pluck(:id))
23
+ end
24
+ scope :for_default_zone,
25
+ -> { potential_rates_for_zone(Spree::Zone.default_tax) }
26
+ scope :for_tax_category,
27
+ -> (category) { where(tax_category_id: category.try(:id)) }
28
+ scope :included_in_price, -> { where(included_in_price: true) }
29
+
30
+ # Gets the array of TaxRates appropriate for the specified tax zone
35
31
  def self.match(order_tax_zone)
36
32
  return [] unless order_tax_zone
37
-
38
- potential_rates = potential_rates_for_zone(order_tax_zone)
39
- rates = potential_rates.includes(zone: { zone_members: :zoneable }).load.select do |rate|
40
- # Why "potentially"?
41
- # Go see the documentation for that method.
42
- rate.potentially_applicable?(order_tax_zone)
43
- end
44
-
45
- # Imagine with me this scenario:
46
- # You are living in Spain and you have a store which ships to France.
47
- # Spain is therefore your default tax rate.
48
- # When you ship to Spain, you want the Spanish rate to apply.
49
- # When you ship to France, you want the French rate to apply.
50
- #
51
- # Normally, Spree would notice that you have two potentially applicable
52
- # tax rates for one particular item.
53
- # When you ship to Spain, only the Spanish one will apply.
54
- # When you ship to France, you'll see a Spanish refund AND a French tax.
55
- # This little bit of code at the end stops the Spanish refund from appearing.
56
- #
57
- # For further discussion, see #4397 and #4327.
58
- rates.delete_if do |rate|
59
- rate.included_in_price? &&
60
- (rates - [rate]).map(&:tax_category).include?(rate.tax_category)
61
- end
33
+ potential_rates_for_zone(order_tax_zone)
62
34
  end
63
35
 
64
36
  # Pre-tax amounts must be stored so that we can calculate
@@ -66,9 +38,9 @@ module Spree
66
38
  # https://github.com/spree/spree/issues/4318#issuecomment-34723428
67
39
  def self.store_pre_tax_amount(item, rates)
68
40
  pre_tax_amount = case item
69
- when Spree::LineItem then item.discounted_amount
70
- when Spree::Shipment then item.discounted_cost
71
- end
41
+ when Spree::LineItem then item.discounted_amount
42
+ when Spree::Shipment then item.discounted_cost
43
+ end
72
44
 
73
45
  included_rates = rates.select(&:included_in_price)
74
46
  if included_rates.any?
@@ -78,99 +50,67 @@ module Spree
78
50
  item.update_column(:pre_tax_amount, pre_tax_amount)
79
51
  end
80
52
 
81
- # This method is best described by the documentation on #potentially_applicable?
53
+ # Deletes all tax adjustments, then applies all applicable rates
54
+ # to relevant items.
82
55
  def self.adjust(order, items)
83
56
  rates = match(order.tax_zone)
84
57
  tax_categories = rates.map(&:tax_category)
85
- relevant_items, non_relevant_items = items.partition { |item| tax_categories.include?(item.tax_category) }
86
- Spree::Adjustment.where(adjustable: relevant_items).tax.destroy_all # using destroy_all to ensure adjustment destroy callback fires.
58
+
59
+ # using destroy_all to ensure adjustment destroy callback fires.
60
+ Spree::Adjustment.where(adjustable: items).tax.destroy_all
61
+
62
+ relevant_items = items.select do |item|
63
+ tax_categories.include?(item.tax_category)
64
+ end
65
+
87
66
  relevant_items.each do |item|
88
- relevant_rates = rates.select { |rate| rate.tax_category == item.tax_category }
67
+ relevant_rates = rates.select do |rate|
68
+ rate.tax_category == item.tax_category
69
+ end
89
70
  store_pre_tax_amount(item, relevant_rates)
90
71
  relevant_rates.each do |rate|
91
72
  rate.adjust(order, item)
92
73
  end
93
74
  end
94
- non_relevant_items.each do |item|
95
- if item.adjustments.tax.present?
96
- item.adjustments.tax.destroy_all # using destroy_all to ensure adjustment destroy callback fires.
97
- item.update_columns pre_tax_amount: 0
98
- end
75
+
76
+ # updates pre_tax for items without any tax rates
77
+ remaining_items = items - relevant_items
78
+ remaining_items.each do |item|
79
+ store_pre_tax_amount(item, [])
99
80
  end
100
81
  end
101
82
 
102
- # Tax rates can *potentially* be applicable to an order.
103
- # We do not know if they are/aren't until we attempt to apply these rates to
104
- # the items contained within the Order itself.
105
- # For instance, if a rate passes the criteria outlined in this method,
106
- # but then has a tax category that doesn't match against any of the line items
107
- # inside of the order, then that tax rate will not be applicable to anything.
108
- # For instance:
109
- #
110
- # Zones:
111
- # - Spain (default tax zone)
112
- # - France
113
- #
114
- # Tax rates: (note: amounts below do not actually reflect real VAT rates)
115
- # 21% inclusive - "Clothing" - Spain
116
- # 18% inclusive - "Clothing" - France
117
- # 10% inclusive - "Food" - Spain
118
- # 8% inclusive - "Food" - France
119
- # 5% inclusive - "Hotels" - Spain
120
- # 2% inclusive - "Hotels" - France
121
- #
122
- # Order has:
123
- # Line Item #1 - Tax Category: Clothing
124
- # Line Item #2 - Tax Category: Food
125
- #
126
- # Tax rates that should be selected:
127
- #
128
- # 21% inclusive - "Clothing" - Spain
129
- # 10% inclusive - "Food" - Spain
130
- #
131
- # If the order's address changes to one in France, then the tax will be recalculated:
132
- #
133
- # 18% inclusive - "Clothing" - France
134
- # 8% inclusive - "Food" - France
135
- #
136
- # Note here that the "Hotels" tax rates will not be used at all.
137
- # This is because there are no items which have the tax category of "Hotels".
138
- #
139
- # Under no circumstances should negative adjustments be applied for the Spanish tax rates.
140
- #
141
- # Those rates should never come into play at all and only the French rates should apply.
142
- def potentially_applicable?(order_tax_zone)
143
- # If the rate's zone matches the order's tax zone, then it's applicable.
144
- self.zone == order_tax_zone ||
145
- # If the rate's zone *contains* the order's tax zone, then it's applicable.
146
- self.zone.contains?(order_tax_zone) ||
147
- # 1) The rate's zone is the default zone, then it's always applicable.
148
- (self.included_in_price? && self.zone.default_tax)
83
+ def self.included_tax_amount_for(options)
84
+ return 0 unless options[:tax_zone] && options[:tax_category]
85
+ potential_rates_for_zone(options[:tax_zone]).
86
+ included_in_price.
87
+ for_tax_category(options[:tax_category]).
88
+ pluck(:amount).sum
149
89
  end
150
90
 
151
91
  def adjust(order, item)
152
- included = included_in_price && default_zone_or_zone_match?(order)
153
- create_adjustment(order, item, included)
92
+ create_adjustment(order, item, included_in_price)
154
93
  end
155
94
 
156
95
  def compute_amount(item)
157
- refund = included_in_price && !default_zone_or_zone_match?(item.order)
158
- compute(item) * (refund ? -1 : 1)
96
+ compute(item)
159
97
  end
160
98
 
161
99
  private
162
100
 
163
- def default_zone_or_zone_match?(order)
164
- Zone.default_tax.try(:contains?, order.tax_zone) || order.tax_zone == zone
101
+ def label
102
+ Spree.t included_in_price? ? :including_tax : :excluding_tax,
103
+ scope: "adjustment_labels.tax_rates",
104
+ name: name.presence || tax_category.name,
105
+ amount: amount_for_label
165
106
  end
166
107
 
167
- def label(adjustment_amount)
168
- label = ""
169
- label << Spree.t(:refund) << ' ' if adjustment_amount < 0
170
- label << (name.present? ? name : tax_category.name) + " "
171
- label << (show_rate_in_label? ? "#{amount * 100}%" : "")
172
- label << " (#{Spree.t(:included_in_price)})" if included_in_price?
173
- label
108
+ def amount_for_label
109
+ return "" unless show_rate_in_label?
110
+ " " + ActiveSupport::NumberHelper::NumberToPercentageConverter.convert(
111
+ amount * 100,
112
+ locale: I18n.locale
113
+ )
174
114
  end
175
115
  end
176
116
  end
@@ -4,7 +4,7 @@ require 'stringex'
4
4
  module Spree
5
5
  class Taxon < Spree::Base
6
6
  extend FriendlyId
7
- friendly_id :permalink, slug_column: :permalink, use: :slugged
7
+ friendly_id :permalink, slug_column: :permalink, use: :history
8
8
  before_create :set_permalink
9
9
 
10
10
  acts_as_nested_set dependent: :destroy
@@ -13,12 +13,18 @@ module Spree
13
13
  has_many :classifications, -> { order(:position) }, dependent: :delete_all, inverse_of: :taxon
14
14
  has_many :products, through: :classifications
15
15
 
16
- has_and_belongs_to_many :prototypes, join_table: :spree_taxons_prototypes
16
+ has_many :prototype_taxons, class_name: 'Spree::PrototypeTaxon', dependent: :destroy
17
+ has_many :prototypes, through: :prototype_taxons, class_name: 'Spree::Prototype'
18
+
19
+ has_many :promotion_rule_taxons, class_name: 'Spree::PromotionRuleTaxon', dependent: :destroy
20
+ has_many :promotion_rules, through: :promotion_rule_taxons, class_name: 'Spree::PromotionRule'
17
21
 
18
22
  validates :name, presence: true
19
- validates :meta_keywords, length: { maximum: 255 }
20
- validates :meta_description, length: { maximum: 255 }
21
- validates :meta_title, length: { maximum: 255 }
23
+ with_options length: { maximum: 255 }, allow_blank: true do
24
+ validates :meta_keywords
25
+ validates :meta_description
26
+ validates :meta_title
27
+ end
22
28
 
23
29
  after_save :touch_ancestors_and_taxonomy
24
30
  after_touch :touch_ancestors_and_taxonomy
@@ -88,7 +94,7 @@ module Spree
88
94
 
89
95
  def touch_ancestors_and_taxonomy
90
96
  # Touches all ancestors at once to avoid recursive taxonomy touch, and reduce queries.
91
- self.class.where(id: ancestors.pluck(:id)).update_all(updated_at: Time.now)
97
+ ancestors.update_all(updated_at: Time.current)
92
98
  # Have taxonomy touch happen in #touch_ancestors_and_taxonomy rather than association option in order for imports to override.
93
99
  taxonomy.try!(:touch)
94
100
  end
@@ -1,8 +1,19 @@
1
1
  module Spree
2
2
  class Tracker < Spree::Base
3
+ after_commit :clear_cache
4
+
5
+ validates :analytics_id, presence: true, uniqueness: { allow_blank: true }
6
+
3
7
  def self.current
4
- tracker = where(active: true).first
8
+ tracker = Rails.cache.fetch("current_tracker") do
9
+ where(active: true).first
10
+ end
5
11
  tracker.analytics_id.present? ? tracker : nil if tracker
6
12
  end
13
+
14
+
15
+ def clear_cache
16
+ Rails.cache.delete("current_tracker")
17
+ end
7
18
  end
8
19
  end
@@ -11,9 +11,10 @@ module Spree
11
11
  end
12
12
 
13
13
  def validate(record)
14
+ warn "`Spree::Validations::DbMaximumLengthValidator` is deprecated. Use `DbMaximumLengthValidator` instead."
14
15
  limit = record.class.columns_hash[@field].limit
15
16
  value = record[@field.to_sym]
16
- if value && limit && value.to_s.length > limit
17
+ if value && limit && value.to_s.length > limit
17
18
  record.errors.add(@field.to_sym, :too_long, count: limit)
18
19
  end
19
20
  end
@@ -12,15 +12,25 @@ module Spree
12
12
  :shipping_category_id, :meta_description, :meta_keywords,
13
13
  :shipping_category
14
14
 
15
- has_many :inventory_units, inverse_of: :variant
16
- has_many :line_items, inverse_of: :variant
15
+ # we need to have this callback before any dependent: :destroy associations
16
+ # https://github.com/rails/rails/issues/3458
17
+ before_destroy :ensure_no_line_items
18
+
19
+ with_options inverse_of: :variant do
20
+ has_many :inventory_units
21
+ has_many :line_items
22
+ has_many :stock_items, dependent: :destroy
23
+ end
24
+
17
25
  has_many :orders, through: :line_items
26
+ with_options through: :stock_items do
27
+ has_many :stock_locations
28
+ has_many :stock_movements
29
+ end
18
30
 
19
- has_many :stock_items, dependent: :destroy, inverse_of: :variant
20
- has_many :stock_locations, through: :stock_items
21
- has_many :stock_movements, through: :stock_items
31
+ has_many :option_value_variants, class_name: 'Spree::OptionValueVariant'
32
+ has_many :option_values, through: :option_value_variants, class_name: 'Spree::OptionValue'
22
33
 
23
- has_and_belongs_to_many :option_values, join_table: :spree_option_values_variants
24
34
  has_many :images, -> { order(:position) }, as: :viewable, dependent: :destroy, class_name: "Spree::Image"
25
35
 
26
36
  has_many :prices,
@@ -32,9 +42,13 @@ module Spree
32
42
 
33
43
  validate :check_price
34
44
 
35
- validates :cost_price, numericality: { greater_than_or_equal_to: 0, allow_nil: true }
36
- validates :price, numericality: { greater_than_or_equal_to: 0, allow_nil: true }
37
- validates_uniqueness_of :sku, allow_blank: true, conditions: -> { where(deleted_at: nil) }
45
+ validates :option_values, presence: true, unless: :is_master?
46
+
47
+ with_options numericality: { greater_than_or_equal_to: 0, allow_nil: true } do
48
+ validates :cost_price
49
+ validates :price
50
+ end
51
+ validates :sku, uniqueness: { conditions: -> { where(deleted_at: nil) } }, allow_blank: true
38
52
 
39
53
  after_create :create_stock_items
40
54
  after_create :set_master_out_of_stock, unless: :is_master?
@@ -43,6 +57,26 @@ module Spree
43
57
 
44
58
  scope :in_stock, -> { joins(:stock_items).where('count_on_hand > ? OR track_inventory = ?', 0, false) }
45
59
 
60
+ scope :not_discontinued, -> do
61
+ where(
62
+ arel_table[:discontinue_on].eq(nil).or(
63
+ arel_table[:discontinue_on].gteq(Time.current)
64
+ )
65
+ )
66
+ end
67
+
68
+ scope :not_deleted, -> { where("#{Variant.quoted_table_name}.deleted_at IS NULL") }
69
+
70
+ scope :for_currency_and_available_price_amount, -> (currency) do
71
+ currency ||= Spree::Config[:currency]
72
+ joins(:prices).where("spree_prices.currency = ?", currency).where("spree_prices.amount IS NOT NULL").distinct
73
+ end
74
+
75
+ scope :active, -> (currency = nil) do
76
+ not_discontinued.not_deleted.
77
+ for_currency_and_available_price_amount(currency)
78
+ end
79
+
46
80
  LOCALIZED_NUMBERS = %w(cost_price weight depth width height)
47
81
 
48
82
  LOCALIZED_NUMBERS.each do |m|
@@ -54,8 +88,8 @@ module Spree
54
88
  self.whitelisted_ransackable_associations = %w[option_values product prices default_price]
55
89
  self.whitelisted_ransackable_attributes = %w[weight sku]
56
90
 
57
- def self.active(currency = nil)
58
- joins(:prices).where(deleted_at: nil).where('spree_prices.currency' => currency || Spree::Config[:currency]).where('spree_prices.amount IS NOT NULL')
91
+ def available?
92
+ !discontinued? && product.available?
59
93
  end
60
94
 
61
95
  def self.having_orders
@@ -75,10 +109,6 @@ module Spree
75
109
  inventory_units.with_state('backordered').size
76
110
  end
77
111
 
78
- def is_backorderable?
79
- Spree::Stock::Quantifier.new(self).backorderable?
80
- end
81
-
82
112
  def options_text
83
113
  values = self.option_values.sort do |a, b|
84
114
  a.option_type.position <=> b.option_type.position
@@ -155,7 +185,7 @@ module Spree
155
185
  end
156
186
 
157
187
  def price_in(currency)
158
- prices.detect { |price| price.currency == currency } || Spree::Price.new(variant_id: id, currency: currency)
188
+ prices.detect { |price| price.currency == currency } || prices.build(currency: currency)
159
189
  end
160
190
 
161
191
  def amount_in(currency)
@@ -202,13 +232,9 @@ module Spree
202
232
  end
203
233
  end
204
234
 
205
- def can_supply?(quantity=1)
206
- Spree::Stock::Quantifier.new(self).can_supply?(quantity)
207
- end
235
+ delegate :total_on_hand, :can_supply?, :backorderable?, to: :quantifier
208
236
 
209
- def total_on_hand
210
- Spree::Stock::Quantifier.new(self).total_on_hand
211
- end
237
+ alias is_backorderable? backorderable?
212
238
 
213
239
  # Shortcut method to determine if inventory tracking is enabled for this variant
214
240
  # This considers both variant tracking flag and site-wide inventory tracking settings
@@ -228,43 +254,62 @@ module Spree
228
254
  (width || 0) + (height || 0) + (depth || 0)
229
255
  end
230
256
 
257
+ def discontinue!
258
+ update_attribute(:discontinue_on, Time.current)
259
+ end
260
+
261
+ def discontinued?
262
+ !!discontinue_on && discontinue_on <= Time.current
263
+ end
264
+
231
265
  private
232
266
 
233
- def set_master_out_of_stock
234
- if product.master && product.master.in_stock?
235
- product.master.stock_items.update_all(:backorderable => false)
236
- product.master.stock_items.each { |item| item.reduce_count_on_hand_to_zero }
237
- end
267
+ def ensure_no_line_items
268
+ if line_items.any?
269
+ errors.add(:base, Spree.t(:cannot_destroy_if_attached_to_line_items))
270
+ throw(:abort)
238
271
  end
272
+ end
239
273
 
240
- # Ensures a new variant takes the product master price when price is not supplied
241
- def check_price
242
- if price.nil? && Spree::Config[:require_master_price]
243
- raise 'No master variant found to infer price' unless (product && product.master)
244
- raise 'Must supply price for variant or master.price for product.' if self == product.master
245
- self.price = product.master.price
246
- end
247
- if currency.nil?
248
- self.currency = Spree::Config[:currency]
249
- end
250
- end
274
+ def quantifier
275
+ Spree::Stock::Quantifier.new(self)
276
+ end
251
277
 
252
- def set_cost_currency
253
- self.cost_currency = Spree::Config[:currency] if cost_currency.nil? || cost_currency.empty?
278
+ def set_master_out_of_stock
279
+ if product.master && product.master.in_stock?
280
+ product.master.stock_items.update_all(backorderable: false)
281
+ product.master.stock_items.each(&:reduce_count_on_hand_to_zero)
254
282
  end
283
+ end
255
284
 
256
- def create_stock_items
257
- StockLocation.where(propagate_all_variants: true).each do |stock_location|
258
- stock_location.propagate_variant(self)
259
- end
285
+ # Ensures a new variant takes the product master price when price is not supplied
286
+ def check_price
287
+ if price.nil? && Spree::Config[:require_master_price]
288
+ raise 'No master variant found to infer price' unless product && product.master
289
+ raise 'Must supply price for variant or master.price for product.' if self == product.master
290
+ self.price = product.master.price
260
291
  end
261
-
262
- def in_stock_cache_key
263
- "variant-#{id}-in_stock"
292
+ if price.present? && currency.nil?
293
+ self.currency = Spree::Config[:currency]
264
294
  end
295
+ end
265
296
 
266
- def clear_in_stock_cache
267
- Rails.cache.delete(in_stock_cache_key)
297
+ def set_cost_currency
298
+ self.cost_currency = Spree::Config[:currency] if cost_currency.blank?
299
+ end
300
+
301
+ def create_stock_items
302
+ StockLocation.where(propagate_all_variants: true).each do |stock_location|
303
+ stock_location.propagate_variant(self)
268
304
  end
305
+ end
306
+
307
+ def in_stock_cache_key
308
+ "variant-#{id}-in_stock"
309
+ end
310
+
311
+ def clear_in_stock_cache
312
+ Rails.cache.delete(in_stock_cache_key)
313
+ end
269
314
  end
270
315
  end