rfcommerce_core 0.0.3

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 (863) hide show
  1. data/Gemfile +34 -0
  2. data/LICENSE +26 -0
  3. data/README.md +15 -0
  4. data/app/controllers/admin/adjustments_controller.rb +10 -0
  5. data/app/controllers/admin/base_controller.rb +63 -0
  6. data/app/controllers/admin/configurations_controller.rb +2 -0
  7. data/app/controllers/admin/general_settings_controller.rb +22 -0
  8. data/app/controllers/admin/images_controller.rb +49 -0
  9. data/app/controllers/admin/inventory_settings_controller.rb +13 -0
  10. data/app/controllers/admin/inventory_units_controller.rb +2 -0
  11. data/app/controllers/admin/line_items_controller.rb +60 -0
  12. data/app/controllers/admin/mail_methods_controller.rb +8 -0
  13. data/app/controllers/admin/mail_settings_controller.rb +14 -0
  14. data/app/controllers/admin/option_types_controller.rb +65 -0
  15. data/app/controllers/admin/orders_controller.rb +136 -0
  16. data/app/controllers/admin/overview_controller.rb +14 -0
  17. data/app/controllers/admin/payment_methods_controller.rb +43 -0
  18. data/app/controllers/admin/payments_controller.rb +107 -0
  19. data/app/controllers/admin/product_groups_controller.rb +46 -0
  20. data/app/controllers/admin/product_properties_controller.rb +10 -0
  21. data/app/controllers/admin/product_scopes_controller.rb +35 -0
  22. data/app/controllers/admin/products_controller.rb +113 -0
  23. data/app/controllers/admin/products_controller.rb~ +114 -0
  24. data/app/controllers/admin/properties_controller.rb +11 -0
  25. data/app/controllers/admin/prototypes_controller.rb +26 -0
  26. data/app/controllers/admin/reports_controller.rb +50 -0
  27. data/app/controllers/admin/resource_controller.rb +232 -0
  28. data/app/controllers/admin/return_authorizations_controller.rb +17 -0
  29. data/app/controllers/admin/shipments_controller.rb +117 -0
  30. data/app/controllers/admin/shipping_categories_controller.rb +2 -0
  31. data/app/controllers/admin/shipping_methods_controller.rb +14 -0
  32. data/app/controllers/admin/states_controller.rb +25 -0
  33. data/app/controllers/admin/tax_categories_controller.rb +2 -0
  34. data/app/controllers/admin/tax_rates_controller.rb +22 -0
  35. data/app/controllers/admin/tax_settings_controller.rb +13 -0
  36. data/app/controllers/admin/taxonomies_controller.rb +20 -0
  37. data/app/controllers/admin/taxons_controller.rb +161 -0
  38. data/app/controllers/admin/trackers_controller.rb +2 -0
  39. data/app/controllers/admin/users_controller.rb +65 -0
  40. data/app/controllers/admin/variants_controller.rb +51 -0
  41. data/app/controllers/admin/zones_controller.rb +23 -0
  42. data/app/controllers/checkout_controller.rb +97 -0
  43. data/app/controllers/content_controller.rb +21 -0
  44. data/app/controllers/locale_controller.rb +14 -0
  45. data/app/controllers/orders_controller.rb +64 -0
  46. data/app/controllers/products_controller.rb +39 -0
  47. data/app/controllers/spree/base_controller.rb +4 -0
  48. data/app/controllers/states_controller.rb +16 -0
  49. data/app/controllers/taxons_controller.rb +22 -0
  50. data/app/helpers/account_helper.rb +2 -0
  51. data/app/helpers/admin/base_helper.rb +194 -0
  52. data/app/helpers/admin/inventory_settings_helper.rb +5 -0
  53. data/app/helpers/admin/navigation_helper.rb +162 -0
  54. data/app/helpers/admin/orders_helper.rb +22 -0
  55. data/app/helpers/admin/overview_helper.rb +12 -0
  56. data/app/helpers/admin/payments_helper.rb +7 -0
  57. data/app/helpers/admin/product_groups_helper.rb +11 -0
  58. data/app/helpers/admin/product_properties_helper.rb +21 -0
  59. data/app/helpers/admin/products_helper.rb +11 -0
  60. data/app/helpers/admin/taxons_helper.rb +18 -0
  61. data/app/helpers/admin/users_helper.rb +8 -0
  62. data/app/helpers/admin/zones_helper.rb +11 -0
  63. data/app/helpers/checkout_helper.rb +31 -0
  64. data/app/helpers/hook_helper.rb +20 -0
  65. data/app/helpers/orders_helper.rb +3 -0
  66. data/app/helpers/products_helper.rb +30 -0
  67. data/app/helpers/search_helper.rb +10 -0
  68. data/app/helpers/spree/base_helper.rb +119 -0
  69. data/app/helpers/taxons_helper.rb +32 -0
  70. data/app/helpers/trackers_helper.rb +2 -0
  71. data/app/mailers/order_mailer.rb +19 -0
  72. data/app/mailers/shipment_mailer.rb +11 -0
  73. data/app/models/address.rb +115 -0
  74. data/app/models/adjustment.rb +47 -0
  75. data/app/models/app_configuration.rb +44 -0
  76. data/app/models/asset.rb +4 -0
  77. data/app/models/billing_integration.rb +23 -0
  78. data/app/models/calculator.rb +46 -0
  79. data/app/models/calculator/flat_percent_item_total.rb +19 -0
  80. data/app/models/calculator/flat_rate.rb +16 -0
  81. data/app/models/calculator/flexi_rate.rb +32 -0
  82. data/app/models/calculator/per_item.rb +16 -0
  83. data/app/models/calculator/price_bucket.rb +30 -0
  84. data/app/models/calculator/sales_tax.rb +48 -0
  85. data/app/models/calculator/vat.rb +63 -0
  86. data/app/models/configuration.rb +3 -0
  87. data/app/models/country.rb +16 -0
  88. data/app/models/creditcard.rb +267 -0
  89. data/app/models/gateway.rb +48 -0
  90. data/app/models/gateway/authorize_net.rb +19 -0
  91. data/app/models/gateway/authorize_net_cim.rb +132 -0
  92. data/app/models/gateway/beanstream.rb +187 -0
  93. data/app/models/gateway/bogus.rb +80 -0
  94. data/app/models/gateway/braintree.rb +88 -0
  95. data/app/models/gateway/eway.rb +11 -0
  96. data/app/models/gateway/linkpoint.rb +8 -0
  97. data/app/models/gateway/pay_pal.rb +11 -0
  98. data/app/models/gateway/sage_pay.rb +9 -0
  99. data/app/models/image.rb +31 -0
  100. data/app/models/inventory_unit.rb +119 -0
  101. data/app/models/line_item.rb +95 -0
  102. data/app/models/log_entry.rb +3 -0
  103. data/app/models/mail_method.rb +23 -0
  104. data/app/models/option_type.rb +9 -0
  105. data/app/models/option_value.rb +5 -0
  106. data/app/models/order.rb +484 -0
  107. data/app/models/payment.rb +119 -0
  108. data/app/models/payment_method.rb +56 -0
  109. data/app/models/payment_method/check.rb +27 -0
  110. data/app/models/preference.rb +51 -0
  111. data/app/models/product.rb +258 -0
  112. data/app/models/product_group.rb +216 -0
  113. data/app/models/product_option_type.rb +5 -0
  114. data/app/models/product_property.rb +15 -0
  115. data/app/models/product_scope.rb +78 -0
  116. data/app/models/property.rb +18 -0
  117. data/app/models/prototype.rb +5 -0
  118. data/app/models/return_authorization.rb +79 -0
  119. data/app/models/role.rb +3 -0
  120. data/app/models/shipment.rb +157 -0
  121. data/app/models/shipping_category.rb +3 -0
  122. data/app/models/shipping_method.rb +25 -0
  123. data/app/models/spree/alert.rb +13 -0
  124. data/app/models/state.rb +16 -0
  125. data/app/models/state_event.rb +16 -0
  126. data/app/models/tax_category.rb +15 -0
  127. data/app/models/tax_rate.rb +16 -0
  128. data/app/models/taxon.rb +52 -0
  129. data/app/models/taxonomy.rb +20 -0
  130. data/app/models/taxonomy.rb~ +22 -0
  131. data/app/models/tracker.rb +5 -0
  132. data/app/models/user.rb +21 -0
  133. data/app/models/variant.rb +104 -0
  134. data/app/models/zone.rb +84 -0
  135. data/app/models/zone_member.rb +10 -0
  136. data/app/stylesheets/_buttons.less +80 -0
  137. data/app/stylesheets/_cart.less +24 -0
  138. data/app/stylesheets/_checkout.less +76 -0
  139. data/app/stylesheets/_checkout_progress.less +62 -0
  140. data/app/stylesheets/_colors.less +16 -0
  141. data/app/stylesheets/_forms.less +50 -0
  142. data/app/stylesheets/_layout.less +77 -0
  143. data/app/stylesheets/_messages.less +32 -0
  144. data/app/stylesheets/_mixins.less +71 -0
  145. data/app/stylesheets/_navigation.less +130 -0
  146. data/app/stylesheets/_prices.less +18 -0
  147. data/app/stylesheets/_product_details.less +56 -0
  148. data/app/stylesheets/_product_lists.less +66 -0
  149. data/app/stylesheets/_registration.less +24 -0
  150. data/app/stylesheets/_reset.less +69 -0
  151. data/app/stylesheets/_typography.less +158 -0
  152. data/app/stylesheets/screen.less +13 -0
  153. data/app/views/admin/adjustments/_adjustments_table.html.erb +24 -0
  154. data/app/views/admin/adjustments/_form.html.erb +12 -0
  155. data/app/views/admin/adjustments/edit.html.erb +13 -0
  156. data/app/views/admin/adjustments/index.html.erb +4 -0
  157. data/app/views/admin/adjustments/new.html.erb +14 -0
  158. data/app/views/admin/configurations/index.html.erb +66 -0
  159. data/app/views/admin/extensions/index.html.erb +23 -0
  160. data/app/views/admin/general_settings/edit.html.erb +46 -0
  161. data/app/views/admin/general_settings/show.html.erb +36 -0
  162. data/app/views/admin/images/_form.html.erb +16 -0
  163. data/app/views/admin/images/edit.html.erb +19 -0
  164. data/app/views/admin/images/index.html.erb +69 -0
  165. data/app/views/admin/images/new.html.erb +22 -0
  166. data/app/views/admin/images/new.html.erb~ +22 -0
  167. data/app/views/admin/inventory_settings/edit.html.erb +27 -0
  168. data/app/views/admin/inventory_settings/show.html.erb +9 -0
  169. data/app/views/admin/inventory_units/adjust.html.erb +33 -0
  170. data/app/views/admin/mail_methods/_form.html.erb +96 -0
  171. data/app/views/admin/mail_methods/edit.html.erb +9 -0
  172. data/app/views/admin/mail_methods/index.html.erb +41 -0
  173. data/app/views/admin/mail_methods/new.html.erb +9 -0
  174. data/app/views/admin/option_types/_available.html.erb +27 -0
  175. data/app/views/admin/option_types/_form.html.erb +11 -0
  176. data/app/views/admin/option_types/_option_value_fields.html.erb +5 -0
  177. data/app/views/admin/option_types/_selected.html.erb +26 -0
  178. data/app/views/admin/option_types/available.js.erb +2 -0
  179. data/app/views/admin/option_types/edit.html.erb +32 -0
  180. data/app/views/admin/option_types/index.html.erb +33 -0
  181. data/app/views/admin/option_types/new.erb +11 -0
  182. data/app/views/admin/option_types/select.js.erb +3 -0
  183. data/app/views/admin/option_types/selected.html.erb +6 -0
  184. data/app/views/admin/orders/_add_product.html.erb +20 -0
  185. data/app/views/admin/orders/_form.html.erb +67 -0
  186. data/app/views/admin/orders/_line_item.html.erb +17 -0
  187. data/app/views/admin/orders/_user_form.html.erb +42 -0
  188. data/app/views/admin/orders/edit.html.erb +31 -0
  189. data/app/views/admin/orders/history.html.erb +29 -0
  190. data/app/views/admin/orders/index.html.erb +103 -0
  191. data/app/views/admin/orders/new.html.erb +20 -0
  192. data/app/views/admin/orders/show.html.erb +28 -0
  193. data/app/views/admin/orders/user.html.erb +24 -0
  194. data/app/views/admin/payment_methods/_form.html.erb +50 -0
  195. data/app/views/admin/payment_methods/edit.html.erb +10 -0
  196. data/app/views/admin/payment_methods/index.html.erb +49 -0
  197. data/app/views/admin/payment_methods/new.html.erb +11 -0
  198. data/app/views/admin/payments/_bill_address_form.html.erb +9 -0
  199. data/app/views/admin/payments/_form.html.erb +15 -0
  200. data/app/views/admin/payments/_list.html.erb +22 -0
  201. data/app/views/admin/payments/_transaction_list.html.erb +24 -0
  202. data/app/views/admin/payments/credit.html.erb +14 -0
  203. data/app/views/admin/payments/index.html.erb +22 -0
  204. data/app/views/admin/payments/new.html.erb +19 -0
  205. data/app/views/admin/payments/show.html.erb +10 -0
  206. data/app/views/admin/payments/source_forms/_check.html.erb +0 -0
  207. data/app/views/admin/payments/source_forms/_gateway.html.erb +43 -0
  208. data/app/views/admin/payments/source_views/_check.html.erb +0 -0
  209. data/app/views/admin/payments/source_views/_gateway.html.erb +34 -0
  210. data/app/views/admin/product_groups/_preview.html.erb +34 -0
  211. data/app/views/admin/product_groups/_product_scope.html.erb +24 -0
  212. data/app/views/admin/product_groups/edit.html.erb +56 -0
  213. data/app/views/admin/product_groups/index.html.erb +37 -0
  214. data/app/views/admin/product_groups/new.html.erb +12 -0
  215. data/app/views/admin/product_groups/show.html.erb +32 -0
  216. data/app/views/admin/product_groups/update.js.erb +8 -0
  217. data/app/views/admin/product_properties/_product_property_fields.html.erb +11 -0
  218. data/app/views/admin/product_properties/index.html.erb +55 -0
  219. data/app/views/admin/product_scopes/_form.html.erb +106 -0
  220. data/app/views/admin/product_scopes/create.js.erb +3 -0
  221. data/app/views/admin/product_scopes/destroy.js.erb +3 -0
  222. data/app/views/admin/product_scopes/new.html.erb +1 -0
  223. data/app/views/admin/products/_form.html.erb +112 -0
  224. data/app/views/admin/products/_option_types.html.erb +40 -0
  225. data/app/views/admin/products/_properties_form.erb +7 -0
  226. data/app/views/admin/products/edit.html.erb +10 -0
  227. data/app/views/admin/products/edit.html.erb~ +10 -0
  228. data/app/views/admin/products/index.html.erb +81 -0
  229. data/app/views/admin/products/index.html.erb~ +81 -0
  230. data/app/views/admin/products/new.erb +58 -0
  231. data/app/views/admin/products/new.erb~ +53 -0
  232. data/app/views/admin/products/show.html.erb +4 -0
  233. data/app/views/admin/products/show.html.erb~ +4 -0
  234. data/app/views/admin/properties/_form.html.erb +12 -0
  235. data/app/views/admin/properties/edit.html.erb +10 -0
  236. data/app/views/admin/properties/filtered.html.erb +1 -0
  237. data/app/views/admin/properties/index.html.erb +40 -0
  238. data/app/views/admin/properties/new.erb +11 -0
  239. data/app/views/admin/prototypes/_form.html.erb +44 -0
  240. data/app/views/admin/prototypes/available.html.erb +22 -0
  241. data/app/views/admin/prototypes/edit.html.erb +9 -0
  242. data/app/views/admin/prototypes/index.html.erb +37 -0
  243. data/app/views/admin/prototypes/new.erb +11 -0
  244. data/app/views/admin/prototypes/select.js.erb +4 -0
  245. data/app/views/admin/reports/index.html.erb +19 -0
  246. data/app/views/admin/reports/sales_total.html.erb +23 -0
  247. data/app/views/admin/return_authorizations/_form.html.erb +78 -0
  248. data/app/views/admin/return_authorizations/edit.html.erb +27 -0
  249. data/app/views/admin/return_authorizations/index.html.erb +45 -0
  250. data/app/views/admin/return_authorizations/new.html.erb +13 -0
  251. data/app/views/admin/shared/_additional_field.html.erb +5 -0
  252. data/app/views/admin/shared/_address.html.erb +5 -0
  253. data/app/views/admin/shared/_address_form.html.erb +79 -0
  254. data/app/views/admin/shared/_alert.html.erb +6 -0
  255. data/app/views/admin/shared/_calculator_fields.html.erb +19 -0
  256. data/app/views/admin/shared/_configuration_menu.html.erb +22 -0
  257. data/app/views/admin/shared/_destroy.js.erb +16 -0
  258. data/app/views/admin/shared/_edit_resource_links.html.erb +4 -0
  259. data/app/views/admin/shared/_group_from_products_form.html.erb +12 -0
  260. data/app/views/admin/shared/_new_adjustment_button.html.erb +8 -0
  261. data/app/views/admin/shared/_new_resource_links.html.erb +4 -0
  262. data/app/views/admin/shared/_order_details.html.erb +3 -0
  263. data/app/views/admin/shared/_order_sub_menu.html.erb +0 -0
  264. data/app/views/admin/shared/_order_tabs.html.erb +64 -0
  265. data/app/views/admin/shared/_product_sub_menu.html.erb +11 -0
  266. data/app/views/admin/shared/_product_tabs.html.erb +34 -0
  267. data/app/views/admin/shared/_report_criteria.html.erb +15 -0
  268. data/app/views/admin/shared/_show_resource_links.html.erb +5 -0
  269. data/app/views/admin/shared/_tabs.html.erb +6 -0
  270. data/app/views/admin/shared/_update_order_state.js +6 -0
  271. data/app/views/admin/shipments/_form.html.erb +77 -0
  272. data/app/views/admin/shipments/edit.html.erb +40 -0
  273. data/app/views/admin/shipments/index.html.erb +47 -0
  274. data/app/views/admin/shipments/new.html.erb +18 -0
  275. data/app/views/admin/shipping_categories/_form.html.erb +6 -0
  276. data/app/views/admin/shipping_categories/edit.html.erb +6 -0
  277. data/app/views/admin/shipping_categories/index.html.erb +29 -0
  278. data/app/views/admin/shipping_categories/new.html.erb +8 -0
  279. data/app/views/admin/shipping_methods/_form.html.erb +26 -0
  280. data/app/views/admin/shipping_methods/edit.html.erb +16 -0
  281. data/app/views/admin/shipping_methods/index.html.erb +49 -0
  282. data/app/views/admin/shipping_methods/new.html.erb +17 -0
  283. data/app/views/admin/states/_form.html.erb +9 -0
  284. data/app/views/admin/states/_state_list.html.erb +34 -0
  285. data/app/views/admin/states/edit.html.erb +10 -0
  286. data/app/views/admin/states/index.html.erb +16 -0
  287. data/app/views/admin/states/new.erb +8 -0
  288. data/app/views/admin/tax_categories/_form.html.erb +12 -0
  289. data/app/views/admin/tax_categories/edit.html.erb +10 -0
  290. data/app/views/admin/tax_categories/index.html.erb +44 -0
  291. data/app/views/admin/tax_categories/new.html.erb +10 -0
  292. data/app/views/admin/tax_categories/show.html.erb +1 -0
  293. data/app/views/admin/tax_rates/_form.html.erb +16 -0
  294. data/app/views/admin/tax_rates/edit.html.erb +6 -0
  295. data/app/views/admin/tax_rates/index.html.erb +34 -0
  296. data/app/views/admin/tax_rates/new.html.erb +8 -0
  297. data/app/views/admin/tax_settings/edit.html.erb +17 -0
  298. data/app/views/admin/tax_settings/show.html.erb +14 -0
  299. data/app/views/admin/taxonomies/_form.html.erb +10 -0
  300. data/app/views/admin/taxonomies/_form.html.erb~ +11 -0
  301. data/app/views/admin/taxonomies/_js_head.html.erb +9 -0
  302. data/app/views/admin/taxonomies/_list.html.erb +19 -0
  303. data/app/views/admin/taxonomies/_list.html.erb~ +20 -0
  304. data/app/views/admin/taxonomies/_taxon.html.erb +12 -0
  305. data/app/views/admin/taxonomies/edit.erb +49 -0
  306. data/app/views/admin/taxonomies/get_children.json.erb +9 -0
  307. data/app/views/admin/taxonomies/index.html.erb +16 -0
  308. data/app/views/admin/taxonomies/new.html.erb +12 -0
  309. data/app/views/admin/taxons/_form.html.erb +23 -0
  310. data/app/views/admin/taxons/_taxon_table.html.erb +23 -0
  311. data/app/views/admin/taxons/available.js.erb +33 -0
  312. data/app/views/admin/taxons/edit.html.erb +11 -0
  313. data/app/views/admin/taxons/remove.html.erb +1 -0
  314. data/app/views/admin/taxons/select.js.erb +2 -0
  315. data/app/views/admin/taxons/selected.html.erb +43 -0
  316. data/app/views/admin/trackers/_form.html.erb +26 -0
  317. data/app/views/admin/trackers/edit.html.erb +8 -0
  318. data/app/views/admin/trackers/index.html.erb +41 -0
  319. data/app/views/admin/trackers/new.html.erb +9 -0
  320. data/app/views/admin/users/_form.html.erb +35 -0
  321. data/app/views/admin/users/edit.html.erb +14 -0
  322. data/app/views/admin/users/index.html.erb +63 -0
  323. data/app/views/admin/users/new.html.erb +14 -0
  324. data/app/views/admin/users/show.html.erb +21 -0
  325. data/app/views/admin/variants/_form.html.erb +40 -0
  326. data/app/views/admin/variants/edit.html.erb +13 -0
  327. data/app/views/admin/variants/index.html.erb +66 -0
  328. data/app/views/admin/variants/new.erb +11 -0
  329. data/app/views/admin/zones/_country_member.html.erb +5 -0
  330. data/app/views/admin/zones/_form.html.erb +29 -0
  331. data/app/views/admin/zones/_member_type.html.erb +15 -0
  332. data/app/views/admin/zones/_state_member.html.erb +5 -0
  333. data/app/views/admin/zones/_zone_member.html.erb +5 -0
  334. data/app/views/admin/zones/edit.html.erb +10 -0
  335. data/app/views/admin/zones/index.html.erb +41 -0
  336. data/app/views/admin/zones/new.html.erb +10 -0
  337. data/app/views/checkout/_address.html.erb +163 -0
  338. data/app/views/checkout/_confirm.html.erb +11 -0
  339. data/app/views/checkout/_delivery.html.erb +25 -0
  340. data/app/views/checkout/_payment.html.erb +30 -0
  341. data/app/views/checkout/_summary.html.erb +21 -0
  342. data/app/views/checkout/edit.html.erb +20 -0
  343. data/app/views/checkout/payment/_check.html.erb +0 -0
  344. data/app/views/checkout/payment/_gateway.html.erb +31 -0
  345. data/app/views/checkout/registration.html.erb +20 -0
  346. data/app/views/content/cvv.html.erb +13 -0
  347. data/app/views/layouts/admin.html.erb +75 -0
  348. data/app/views/layouts/spree_application.html.erb +52 -0
  349. data/app/views/order_mailer/cancel_email.text.erb +16 -0
  350. data/app/views/order_mailer/confirm_email.text.erb +19 -0
  351. data/app/views/orders/_form.html.erb +19 -0
  352. data/app/views/orders/_line_item.html.erb +41 -0
  353. data/app/views/orders/edit.html.erb +41 -0
  354. data/app/views/orders/new.html.erb +9 -0
  355. data/app/views/orders/show.html.erb +14 -0
  356. data/app/views/products/_cart_form.html.erb +54 -0
  357. data/app/views/products/_cart_form.html.erb~ +54 -0
  358. data/app/views/products/_image.html.erb +5 -0
  359. data/app/views/products/_image.html.erb~ +5 -0
  360. data/app/views/products/_properties.html.erb +8 -0
  361. data/app/views/products/_taxons.html.erb +16 -0
  362. data/app/views/products/_thumbnails.html.erb +40 -0
  363. data/app/views/products/index.html.erb +37 -0
  364. data/app/views/products/show.html.erb +31 -0
  365. data/app/views/shared/_additional_field.html.erb +7 -0
  366. data/app/views/shared/_admin_head.html.erb +34 -0
  367. data/app/views/shared/_basic_layout.html.erb +44 -0
  368. data/app/views/shared/_edit_resource_links.html.erb +1 -0
  369. data/app/views/shared/_end_soon.html.erb +43 -0
  370. data/app/views/shared/_error_messages.html.erb +11 -0
  371. data/app/views/shared/_filters.html.erb +27 -0
  372. data/app/views/shared/_footer.html.erb +13 -0
  373. data/app/views/shared/_google_analytics.html.erb +40 -0
  374. data/app/views/shared/_head.html.erb +10 -0
  375. data/app/views/shared/_method_error_message.html.erb +4 -0
  376. data/app/views/shared/_nav_bar.html.erb +5 -0
  377. data/app/views/shared/_new_release.html.erb +42 -0
  378. data/app/views/shared/_new_resource_links.html.erb +1 -0
  379. data/app/views/shared/_order_details.html.erb +50 -0
  380. data/app/views/shared/_products.html.erb +42 -0
  381. data/app/views/shared/_search.html.erb +9 -0
  382. data/app/views/shared/_show_resource_links.html.erb +3 -0
  383. data/app/views/shared/_store_menu.html.erb +3 -0
  384. data/app/views/shared/_taxonomies.html.erb +19 -0
  385. data/app/views/shared/_test_hook.html.erb +1 -0
  386. data/app/views/shared/_upcoming_products.html.erb +42 -0
  387. data/app/views/shipment_mailer/shipped_email.text.erb +15 -0
  388. data/app/views/states/index.js.erb +1 -0
  389. data/app/views/taxons/_taxon.html.erb +4 -0
  390. data/app/views/taxons/show.html.erb +19 -0
  391. data/config/cucumber.yml +10 -0
  392. data/config/initializers/form_builder.rb +19 -0
  393. data/config/initializers/load_unobtrusive_date_picker.rb +8 -0
  394. data/config/initializers/spree.rb +29 -0
  395. data/config/initializers/workarounds_for_ruby19.rb +72 -0
  396. data/config/locales/en.yml +1015 -0
  397. data/config/routes.rb +207 -0
  398. data/db/default/countries.yml +1583 -0
  399. data/db/default/roles.yml +7 -0
  400. data/db/default/states.yml +256 -0
  401. data/db/default/zone_members.yml +169 -0
  402. data/db/default/zones.yml +13 -0
  403. data/db/migrate/20090823005402_spree_zero_nine_zero.rb +442 -0
  404. data/db/migrate/20090904192342_create_indexes_for_inventory_units.rb +12 -0
  405. data/db/migrate/20090923100315_add_count_on_hand_to_variants_and_products.rb +36 -0
  406. data/db/migrate/20091007134354_change_taxons_to_nested_set.rb +40 -0
  407. data/db/migrate/20091008091614_move_to_configurable_gateways.rb +55 -0
  408. data/db/migrate/20091012120519_product_groups_and_scopes.rb +25 -0
  409. data/db/migrate/20091015110842_add_open_id_authentication_tables.rb +20 -0
  410. data/db/migrate/20091015153048_add_openid_field_to_users.rb +19 -0
  411. data/db/migrate/20091016174634_change_preference_value_type.rb +10 -0
  412. data/db/migrate/20091017175558_create_billing_integrations.rb +16 -0
  413. data/db/migrate/20091021133257_charge_refactoring.rb +35 -0
  414. data/db/migrate/20091104151730_add_some_indexes.rb +21 -0
  415. data/db/migrate/20091126190904_checkout_state_machine.rb +13 -0
  416. data/db/migrate/20091209153045_state_for_shipments.rb +9 -0
  417. data/db/migrate/20091209202200_make_state_events_polymorphic.rb +12 -0
  418. data/db/migrate/20091211203813_ship_address_id_for_checkouts.rb +9 -0
  419. data/db/migrate/20091212161118_shipping_method_id_for_checkouts.rb +9 -0
  420. data/db/migrate/20091213222815_creditcard_last_four_digits.rb +19 -0
  421. data/db/migrate/20091214183826_populate_legacy_shipment_state.rb +19 -0
  422. data/db/migrate/20100105090147_add_cost_price.rb +9 -0
  423. data/db/migrate/20100105132138_shipment_id_for_inventory_units.rb +21 -0
  424. data/db/migrate/20100111205525_cim_fields_for_creditcards.rb +11 -0
  425. data/db/migrate/20100112151511_create_return_authorizations.rb +16 -0
  426. data/db/migrate/20100113090919_add_return_authorization_to_inventory_units.rb +9 -0
  427. data/db/migrate/20100113203104_create_trackers.rb +14 -0
  428. data/db/migrate/20100121160010_creditcard_id_for_creditcard_txns.rb +9 -0
  429. data/db/migrate/20100121183934_original_creditcard_txn_id_for_creditcard_txns.rb +9 -0
  430. data/db/migrate/20100125145351_add_test_mode_to_billing_integration.rb +11 -0
  431. data/db/migrate/20100126103714_create_products_product_groups.rb +12 -0
  432. data/db/migrate/20100209025806_create_payment_methods.rb +20 -0
  433. data/db/migrate/20100209144531_polymorphic_payments.rb +29 -0
  434. data/db/migrate/20100213103131_change_payments_payment_method_to_belongs_to.rb +11 -0
  435. data/db/migrate/20100214212536_assign_creditcard_txns_to_payment.rb +16 -0
  436. data/db/migrate/20100223170312_sti_for_transactions.rb +14 -0
  437. data/db/migrate/20100223183812_drop_billing_integrations.rb +16 -0
  438. data/db/migrate/20100224153127_deleted_at_for_payment_methods.rb +13 -0
  439. data/db/migrate/20100301163454_add_adjustments_index.rb +10 -0
  440. data/db/migrate/20100306153445_fix_by_popularity.rb +8 -0
  441. data/db/migrate/20100317120946_add_alt_text_to_images.rb +9 -0
  442. data/db/migrate/20100427121301_add_display_to_payment_methods.rb +9 -0
  443. data/db/migrate/20100504142133_add_addresses_checkouts_indexes.rb +16 -0
  444. data/db/migrate/20100506180619_add_icon_to_taxons.rb +18 -0
  445. data/db/migrate/20100506185838_add_description_to_taxons.rb +11 -0
  446. data/db/migrate/20100528155333_index_for_shipments_number.rb +9 -0
  447. data/db/migrate/20100528185820_add_index_on_users_persistence_token.rb +9 -0
  448. data/db/migrate/20100605152042_add_default_to_tax_categories.rb +9 -0
  449. data/db/migrate/20100624110730_add_display_to_shipping_methods.rb +9 -0
  450. data/db/migrate/20100624123336_rename_payment_method_display.rb +9 -0
  451. data/db/migrate/20100624175547_rename_preferences_field.rb +8 -0
  452. data/db/migrate/20100811163637_add_guest_flag.rb +13 -0
  453. data/db/migrate/20100811205836_drop_order_token.rb +11 -0
  454. data/db/migrate/20100812162326_payments_state_and_assigned_to_order_only.rb +11 -0
  455. data/db/migrate/20100813023502_create_address_keys_for_order.rb +15 -0
  456. data/db/migrate/20100813185745_payment_total_for_orders.rb +9 -0
  457. data/db/migrate/20100816212146_shipping_method_id_for_orders.rb +9 -0
  458. data/db/migrate/20100817152723_add_shipment_and_payment_state.rb +15 -0
  459. data/db/migrate/20100819170125_refactor_adjustments.rb +19 -0
  460. data/db/migrate/20100820135707_response_code_and_avs_response_for_payments.rb +11 -0
  461. data/db/migrate/20100901171814_change_guest_flag_to_anonymous.rb +13 -0
  462. data/db/migrate/20100903203949_email_for_orders.rb +9 -0
  463. data/db/migrate/20100923162011_create_mail_methods.rb +12 -0
  464. data/db/migrate/20100929151905_rename_frozen_to_locked.rb +8 -0
  465. data/db/migrate/20101008190536_move_special_instructions_to_orders.rb +11 -0
  466. data/db/migrate/20101026184700_create_log_entries.rb +15 -0
  467. data/db/migrate/20101026184714_migrate_transactions_to_payment_state.rb +94 -0
  468. data/db/migrate/20101026184746_delete_in_progress_orders.rb +18 -0
  469. data/db/migrate/20101026184808_migrate_checkout_to_orders.rb +27 -0
  470. data/db/migrate/20101026184833_migrate_adjustments.rb +9 -0
  471. data/db/migrate/20101026184855_remove_shipped_state.rb +14 -0
  472. data/db/migrate/20101026184916_prevent_nil_payment_total.rb +8 -0
  473. data/db/migrate/20101026184932_prevent_nil_email.rb +9 -0
  474. data/db/migrate/20101026184959_generate_anonymous_users.rb +14 -0
  475. data/db/migrate/20101026185022_update_order_state.rb +8 -0
  476. data/db/migrate/20101026192225_cleanup_legacy_tables.rb +11 -0
  477. data/db/migrate/20101028151745_remove_number_and_cvv_from_credicard.rb +9 -0
  478. data/db/migrate/20101103212716_drop_anonymous_field_for_user.rb +8 -0
  479. data/db/migrate/20101111133551_renamed_rma_cancelled_state.rb +10 -0
  480. data/db/migrate/20101117031806_fix_problematic_index_names.rb +13 -0
  481. data/db/migrate/20101223215658_add_position_to_variants.rb +9 -0
  482. data/db/migrate/20110110130847_add_next_state_to_state_events.rb +9 -0
  483. data/db/migrate/20110111122537_add_position_to_option_types.rb +9 -0
  484. data/db/migrate/20110314192118_remove_trailing_slashes_in_taxon_permalinks.rb +17 -0
  485. data/db/sample/users.rb +61 -0
  486. data/db/seeds.rb +3 -0
  487. data/lib/custom_fixtures.rb +7 -0
  488. data/lib/generators/spree_core/upgrade_generator.rb +23 -0
  489. data/lib/generators/templates/config/initializers/%file_name%.rb.tt +1 -0
  490. data/lib/generators/templates/config/locales/%current_locale%.yml.tt +2 -0
  491. data/lib/generators/templates/config/routes.rb +3 -0
  492. data/lib/middleware/seo_assist.rb +44 -0
  493. data/lib/product_filters.rb +179 -0
  494. data/lib/redirect_legacy_product_url.rb +13 -0
  495. data/lib/scopes.rb +69 -0
  496. data/lib/scopes/dynamic.rb +31 -0
  497. data/lib/scopes/product.rb +266 -0
  498. data/lib/scopes/variant.rb +18 -0
  499. data/lib/spree/calculated_adjustments.rb +69 -0
  500. data/lib/spree/config.rb +33 -0
  501. data/lib/spree/current_order.rb +30 -0
  502. data/lib/spree/file_utilz.rb +73 -0
  503. data/lib/spree/gateway_error.rb +3 -0
  504. data/lib/spree/mail_interceptor.rb +23 -0
  505. data/lib/spree/mail_settings.rb +33 -0
  506. data/lib/spree/preference_access.rb +27 -0
  507. data/lib/spree/search/base.rb +64 -0
  508. data/lib/spree_base.rb +116 -0
  509. data/lib/spree_core.rb +94 -0
  510. data/lib/spree_core/action_callbacks.rb +26 -0
  511. data/lib/spree_core/authorize_net_cim_hack.rb +871 -0
  512. data/lib/spree_core/delegate_belongs_to.rb +89 -0
  513. data/lib/spree_core/enumerable_constants.rb +209 -0
  514. data/lib/spree_core/ext/active_record.rb +15 -0
  515. data/lib/spree_core/ext/array.rb +14 -0
  516. data/lib/spree_core/ext/hash.rb +75 -0
  517. data/lib/spree_core/ext/string.rb +10 -0
  518. data/lib/spree_core/preferences/model_hooks.rb +293 -0
  519. data/lib/spree_core/preferences/preference_definition.rb +53 -0
  520. data/lib/spree_core/railtie.rb +63 -0
  521. data/lib/spree_core/spree_custom_responder.rb +29 -0
  522. data/lib/spree_core/spree_respond_with.rb +57 -0
  523. data/lib/spree_core/ssl_requirement.rb +104 -0
  524. data/lib/spree_core/testing_support/factories.rb +13 -0
  525. data/lib/spree_core/testing_support/factories/address_factory.rb +20 -0
  526. data/lib/spree_core/testing_support/factories/adjustment_factory.rb +6 -0
  527. data/lib/spree_core/testing_support/factories/calculator_factory.rb +5 -0
  528. data/lib/spree_core/testing_support/factories/configuraion_factory.rb +4 -0
  529. data/lib/spree_core/testing_support/factories/country_factory.rb +7 -0
  530. data/lib/spree_core/testing_support/factories/creditcard_factory.rb +11 -0
  531. data/lib/spree_core/testing_support/factories/inventory_unit_factory.rb +7 -0
  532. data/lib/spree_core/testing_support/factories/line_item_factory.rb +8 -0
  533. data/lib/spree_core/testing_support/factories/mail_method_factory.rb +4 -0
  534. data/lib/spree_core/testing_support/factories/options_factory.rb +10 -0
  535. data/lib/spree_core/testing_support/factories/order_factory.rb +18 -0
  536. data/lib/spree_core/testing_support/factories/payment_factory.rb +26 -0
  537. data/lib/spree_core/testing_support/factories/payment_method_factory.rb +17 -0
  538. data/lib/spree_core/testing_support/factories/product_factory.rb +16 -0
  539. data/lib/spree_core/testing_support/factories/product_group_factory.rb +3 -0
  540. data/lib/spree_core/testing_support/factories/product_option_type_factory.rb +4 -0
  541. data/lib/spree_core/testing_support/factories/product_property_factory.rb +4 -0
  542. data/lib/spree_core/testing_support/factories/product_scope_factory.rb +6 -0
  543. data/lib/spree_core/testing_support/factories/property_factory.rb +4 -0
  544. data/lib/spree_core/testing_support/factories/prototype_factory.rb +4 -0
  545. data/lib/spree_core/testing_support/factories/return_authorization_factory.rb +8 -0
  546. data/lib/spree_core/testing_support/factories/role_factory.rb +9 -0
  547. data/lib/spree_core/testing_support/factories/shipment_factory.rb +9 -0
  548. data/lib/spree_core/testing_support/factories/shipping_category_factory.rb +5 -0
  549. data/lib/spree_core/testing_support/factories/shipping_method_factory.rb +11 -0
  550. data/lib/spree_core/testing_support/factories/state_factory.rb +11 -0
  551. data/lib/spree_core/testing_support/factories/tax_category_factory.rb +8 -0
  552. data/lib/spree_core/testing_support/factories/tax_rate_factory.rb +5 -0
  553. data/lib/spree_core/testing_support/factories/taxon_factory.rb +5 -0
  554. data/lib/spree_core/testing_support/factories/taxonomy_factory.rb +3 -0
  555. data/lib/spree_core/testing_support/factories/tracker_factory.rb +5 -0
  556. data/lib/spree_core/testing_support/factories/user_factory.rb +15 -0
  557. data/lib/spree_core/testing_support/factories/variant_factory.rb +14 -0
  558. data/lib/spree_core/testing_support/factories/zone_factory.rb +18 -0
  559. data/lib/spree_core/theme_support.rb +4 -0
  560. data/lib/spree_core/theme_support/hook.rb +51 -0
  561. data/lib/spree_core/theme_support/hook_listener.rb +68 -0
  562. data/lib/spree_core/theme_support/hook_modifier.rb +35 -0
  563. data/lib/spree_core/theme_support/more_patches.rb +118 -0
  564. data/lib/spree_core/version.rb +5 -0
  565. data/lib/store_helpers.rb +10 -0
  566. data/lib/tasks/common.rb +30 -0
  567. data/lib/tasks/core.rake +105 -0
  568. data/lib/tasks/install.rake +26 -0
  569. data/lib/tasks/rake_util.rb +19 -0
  570. data/lib/tasks/taxon.rake +14 -0
  571. data/lib/tasks/themes.rake +34 -0
  572. data/public/images/add-to-cart.png +0 -0
  573. data/public/images/admin/bg/active-tab.png +0 -0
  574. data/public/images/admin/bg/admin_tab_back.png +0 -0
  575. data/public/images/admin/bg/admin_tab_selected_back.png +0 -0
  576. data/public/images/admin/bg/content-back-blue.png +0 -0
  577. data/public/images/admin/bg/content-back-green.png +0 -0
  578. data/public/images/admin/bg/content-back.png +0 -0
  579. data/public/images/admin/bg/flash-error.png +0 -0
  580. data/public/images/admin/bg/flash-notice.png +0 -0
  581. data/public/images/admin/bg/green-stripes.gif +0 -0
  582. data/public/images/admin/bg/green-stripes.png +0 -0
  583. data/public/images/admin/bg/grid_header_back.png +0 -0
  584. data/public/images/admin/bg/grid_header_back_green.png +0 -0
  585. data/public/images/admin/bg/header-bg.png +0 -0
  586. data/public/images/admin/bg/header.png +0 -0
  587. data/public/images/admin/bg/header_bg.jpg +0 -0
  588. data/public/images/admin/bg/menu-current.png +0 -0
  589. data/public/images/admin/bg/red-stripes.gif +0 -0
  590. data/public/images/admin/bg/red-stripes.png +0 -0
  591. data/public/images/admin/bg/spree_50.png +0 -0
  592. data/public/images/admin/bg/subnav-divider.png +0 -0
  593. data/public/images/admin/bg/subnav.png +0 -0
  594. data/public/images/admin/bg/tab-back.png +0 -0
  595. data/public/images/admin/buttons/blue/left_01.png +0 -0
  596. data/public/images/admin/buttons/blue/right_01.png +0 -0
  597. data/public/images/admin/buttons/drag-handle-green.png +0 -0
  598. data/public/images/admin/buttons/green/left_01.png +0 -0
  599. data/public/images/admin/buttons/green/right_01.png +0 -0
  600. data/public/images/admin/buttons/left_01.png +0 -0
  601. data/public/images/admin/buttons/left_01_small.png +0 -0
  602. data/public/images/admin/buttons/orange/left_03.png +0 -0
  603. data/public/images/admin/buttons/orange/right_03.png +0 -0
  604. data/public/images/admin/buttons/right_01.png +0 -0
  605. data/public/images/admin/buttons/right_01_small.png +0 -0
  606. data/public/images/admin/icons/16x16/1.png +0 -0
  607. data/public/images/admin/icons/16x16/10.png +0 -0
  608. data/public/images/admin/icons/16x16/2.png +0 -0
  609. data/public/images/admin/icons/16x16/3.png +0 -0
  610. data/public/images/admin/icons/16x16/4.png +0 -0
  611. data/public/images/admin/icons/16x16/5.png +0 -0
  612. data/public/images/admin/icons/16x16/6.png +0 -0
  613. data/public/images/admin/icons/16x16/7.png +0 -0
  614. data/public/images/admin/icons/16x16/8.png +0 -0
  615. data/public/images/admin/icons/16x16/9.png +0 -0
  616. data/public/images/admin/icons/32x32/1.png +0 -0
  617. data/public/images/admin/icons/32x32/10.png +0 -0
  618. data/public/images/admin/icons/32x32/11.png +0 -0
  619. data/public/images/admin/icons/32x32/2.png +0 -0
  620. data/public/images/admin/icons/32x32/3.png +0 -0
  621. data/public/images/admin/icons/32x32/4.png +0 -0
  622. data/public/images/admin/icons/32x32/5.png +0 -0
  623. data/public/images/admin/icons/32x32/6.png +0 -0
  624. data/public/images/admin/icons/32x32/7.png +0 -0
  625. data/public/images/admin/icons/32x32/8.png +0 -0
  626. data/public/images/admin/icons/32x32/9.png +0 -0
  627. data/public/images/admin/icons/accept.png +0 -0
  628. data/public/images/admin/icons/add.gif +0 -0
  629. data/public/images/admin/icons/add.png +0 -0
  630. data/public/images/admin/icons/arrow-down.gif +0 -0
  631. data/public/images/admin/icons/cross.png +0 -0
  632. data/public/images/admin/icons/delete.gif +0 -0
  633. data/public/images/admin/icons/delete.png +0 -0
  634. data/public/images/admin/icons/drag.gif +0 -0
  635. data/public/images/admin/icons/edit.gif +0 -0
  636. data/public/images/admin/icons/edit.png +0 -0
  637. data/public/images/admin/icons/email.png +0 -0
  638. data/public/images/admin/icons/error.png +0 -0
  639. data/public/images/admin/icons/exclamation.png +0 -0
  640. data/public/images/admin/icons/feed.png +0 -0
  641. data/public/images/admin/icons/pdf.png +0 -0
  642. data/public/images/admin/icons/reorder.gif +0 -0
  643. data/public/images/admin/icons/search.gif +0 -0
  644. data/public/images/admin/icons/send-email.png +0 -0
  645. data/public/images/admin/icons/stop.png +0 -0
  646. data/public/images/admin/icons/tick.png +0 -0
  647. data/public/images/admin/icons/up.gif +0 -0
  648. data/public/images/admin/icons/xls.png +0 -0
  649. data/public/images/admin/tabs/off-left.png +0 -0
  650. data/public/images/admin/tabs/off-right.png +0 -0
  651. data/public/images/admin/tabs/on-left.png +0 -0
  652. data/public/images/admin/tabs/on-right.png +0 -0
  653. data/public/images/ajax_loader.gif +0 -0
  654. data/public/images/amex_cid.gif +0 -0
  655. data/public/images/bg-button-hover.png +0 -0
  656. data/public/images/bg-button-pressed.png +0 -0
  657. data/public/images/bg-button.gif +0 -0
  658. data/public/images/bg-button.png +0 -0
  659. data/public/images/blue/left_01.png +0 -0
  660. data/public/images/blue/right_01.png +0 -0
  661. data/public/images/body-back.png +0 -0
  662. data/public/images/bottom_shine.png +0 -0
  663. data/public/images/breadcrumb.gif +0 -0
  664. data/public/images/button-dark-hover.png +0 -0
  665. data/public/images/button-dark.png +0 -0
  666. data/public/images/buttons/bg-button-hover.png +0 -0
  667. data/public/images/buttons/bg-button-pressed.png +0 -0
  668. data/public/images/buttons/bg-button.gif +0 -0
  669. data/public/images/buttons/bg-button.png +0 -0
  670. data/public/images/buttons/blue/left_01.png +0 -0
  671. data/public/images/buttons/blue/right_01.png +0 -0
  672. data/public/images/buttons/button-dark-hover.png +0 -0
  673. data/public/images/buttons/button-dark.png +0 -0
  674. data/public/images/buttons/drag-handle-green.png +0 -0
  675. data/public/images/buttons/green/left_01.png +0 -0
  676. data/public/images/buttons/green/right_01.png +0 -0
  677. data/public/images/buttons/left_01.png +0 -0
  678. data/public/images/buttons/left_01_small.png +0 -0
  679. data/public/images/buttons/orange/left_03.png +0 -0
  680. data/public/images/buttons/orange/right_03.png +0 -0
  681. data/public/images/buttons/right_01.png +0 -0
  682. data/public/images/buttons/right_01_small.png +0 -0
  683. data/public/images/buttons/sxsw-ribbon-v1.png +0 -0
  684. data/public/images/buttons/top-shine.png +0 -0
  685. data/public/images/calendar_date_select/calendar.gif +0 -0
  686. data/public/images/cart-empty.png +0 -0
  687. data/public/images/cart-empty_x32.png +0 -0
  688. data/public/images/cart-full.png +0 -0
  689. data/public/images/cart-full_x32.png +0 -0
  690. data/public/images/checkout.png +0 -0
  691. data/public/images/creditcard.gif +0 -0
  692. data/public/images/datepicker/backstripes.gif +0 -0
  693. data/public/images/datepicker/bg_header.jpg +0 -0
  694. data/public/images/datepicker/bullet1.gif +0 -0
  695. data/public/images/datepicker/bullet2.gif +0 -0
  696. data/public/images/datepicker/cal.gif +0 -0
  697. data/public/images/datepicker/gradient-e5e5e5-ffffff.gif +0 -0
  698. data/public/images/discover_cid.gif +0 -0
  699. data/public/images/drag-handle-green.png +0 -0
  700. data/public/images/favicon.ico +0 -0
  701. data/public/images/green/left_01.png +0 -0
  702. data/public/images/green/right_01.png +0 -0
  703. data/public/images/grid.png +0 -0
  704. data/public/images/left_01.png +0 -0
  705. data/public/images/left_01_small.png +0 -0
  706. data/public/images/master_cid.jpg +0 -0
  707. data/public/images/menu-current.png +0 -0
  708. data/public/images/menu-hover.png +0 -0
  709. data/public/images/noimage/mini.jpg +0 -0
  710. data/public/images/noimage/product.jpg +0 -0
  711. data/public/images/noimage/small.jpg +0 -0
  712. data/public/images/openid-inputicon.gif +0 -0
  713. data/public/images/orange/left_03.png +0 -0
  714. data/public/images/orange/right_03.png +0 -0
  715. data/public/images/progress.gif +0 -0
  716. data/public/images/reorder.jpg +0 -0
  717. data/public/images/right_01.png +0 -0
  718. data/public/images/right_01_small.png +0 -0
  719. data/public/images/separator.png +0 -0
  720. data/public/images/shadow-top.png +0 -0
  721. data/public/images/shadow_top.png +0 -0
  722. data/public/images/spinner.gif +0 -0
  723. data/public/images/spree.jpg +0 -0
  724. data/public/images/spree/progress.gif +0 -0
  725. data/public/images/spree/spinner.gif +0 -0
  726. data/public/images/spree/spree.jpg +0 -0
  727. data/public/images/step-progress/completed-completed.gif +0 -0
  728. data/public/images/step-progress/completed-current.gif +0 -0
  729. data/public/images/step-progress/completed-first.gif +0 -0
  730. data/public/images/step-progress/current-first.gif +0 -0
  731. data/public/images/step-progress/current-incomplete.gif +0 -0
  732. data/public/images/step-progress/current-right.gif +0 -0
  733. data/public/images/step-progress/incomplete-incomplete.gif +0 -0
  734. data/public/images/step-progress/incomplete-right.gif +0 -0
  735. data/public/images/steps/1.png +0 -0
  736. data/public/images/steps/1_small.png +0 -0
  737. data/public/images/steps/2.png +0 -0
  738. data/public/images/steps/2_small.png +0 -0
  739. data/public/images/steps/3.png +0 -0
  740. data/public/images/steps/3_small.png +0 -0
  741. data/public/images/steps/4.png +0 -0
  742. data/public/images/steps/4_small.png +0 -0
  743. data/public/images/steps/5.png +0 -0
  744. data/public/images/steps/5_small.png +0 -0
  745. data/public/images/steps/6.png +0 -0
  746. data/public/images/steps/6_small.png +0 -0
  747. data/public/images/sxsw-ribbon-v1.png +0 -0
  748. data/public/images/tab_bottom.gif +0 -0
  749. data/public/images/tile-header.png +0 -0
  750. data/public/images/tile-slider.png +0 -0
  751. data/public/images/top-shine.png +0 -0
  752. data/public/images/tree-nav-icons/bullet.gif +0 -0
  753. data/public/images/tree-nav-icons/minus.gif +0 -0
  754. data/public/images/tree-nav-icons/plus.gif +0 -0
  755. data/public/images/tree-nav-icons/treeview-loading.gif +0 -0
  756. data/public/images/tree-nav-icons/treeview-sprite.gif +0 -0
  757. data/public/images/update.png +0 -0
  758. data/public/images/visa_cid.gif +0 -0
  759. data/public/images/wrapper-back-2.png +0 -0
  760. data/public/images/wrapper-back.png +0 -0
  761. data/public/images/yui-menubaritem_submenuindicator.png +0 -0
  762. data/public/images/yui-menubaritem_submenuindicator_disabled.png +0 -0
  763. data/public/images/yui-menuitem_checkbox.png +0 -0
  764. data/public/images/yui-menuitem_checkbox_disabled.png +0 -0
  765. data/public/images/yui-menuitem_submenuindicator.png +0 -0
  766. data/public/images/yui-menuitem_submenuindicator_disabled.png +0 -0
  767. data/public/images/yui-sprite.png +0 -0
  768. data/public/javascripts/additional-methods.js +236 -0
  769. data/public/javascripts/admin.js +232 -0
  770. data/public/javascripts/admin/address_states.js +25 -0
  771. data/public/javascripts/admin/checkouts/edit.js +130 -0
  772. data/public/javascripts/admin/orders/edit.js +23 -0
  773. data/public/javascripts/admin/orders/edit_form.js +16 -0
  774. data/public/javascripts/admin/payments/new.js +9 -0
  775. data/public/javascripts/admin/unobtrusive_handlers.js +43 -0
  776. data/public/javascripts/application.js +12 -0
  777. data/public/javascripts/calculator.js +15 -0
  778. data/public/javascripts/checkout.js +75 -0
  779. data/public/javascripts/datepicker.js +1445 -0
  780. data/public/javascripts/gateway.js +13 -0
  781. data/public/javascripts/jquery-1.4.2.min.js +154 -0
  782. data/public/javascripts/jquery-ui.js +188 -0
  783. data/public/javascripts/jquery.alerts/images/help.gif +0 -0
  784. data/public/javascripts/jquery.alerts/images/important.gif +0 -0
  785. data/public/javascripts/jquery.alerts/images/info.gif +0 -0
  786. data/public/javascripts/jquery.alerts/images/title.gif +0 -0
  787. data/public/javascripts/jquery.alerts/jquery.alerts.css +57 -0
  788. data/public/javascripts/jquery.alerts/jquery.alerts.js +235 -0
  789. data/public/javascripts/jquery.alerts/jquery.alerts.spree.css +30 -0
  790. data/public/javascripts/jquery.autocomplete.min.js +13 -0
  791. data/public/javascripts/jquery.cookie.js +96 -0
  792. data/public/javascripts/jquery.delayedobserver.js +35 -0
  793. data/public/javascripts/jquery.suggest.js +276 -0
  794. data/public/javascripts/jquery.template.js +255 -0
  795. data/public/javascripts/jquery.tokeninput.js +618 -0
  796. data/public/javascripts/jquery.validate.min.js +16 -0
  797. data/public/javascripts/jsTree/jquery.jstree.js +3510 -0
  798. data/public/javascripts/jsTree/themes/apple/bg.jpg +0 -0
  799. data/public/javascripts/jsTree/themes/apple/d.png +0 -0
  800. data/public/javascripts/jsTree/themes/apple/dot_for_ie.gif +0 -0
  801. data/public/javascripts/jsTree/themes/apple/style.css +60 -0
  802. data/public/javascripts/jsTree/themes/apple/throbber.gif +0 -0
  803. data/public/javascripts/lang/af.js +40 -0
  804. data/public/javascripts/lang/ar.js +50 -0
  805. data/public/javascripts/lang/de.js +40 -0
  806. data/public/javascripts/lang/du.js +40 -0
  807. data/public/javascripts/lang/en.js +42 -0
  808. data/public/javascripts/lang/es.js +41 -0
  809. data/public/javascripts/lang/fi.js +40 -0
  810. data/public/javascripts/lang/fr.js +44 -0
  811. data/public/javascripts/lang/gr.js +40 -0
  812. data/public/javascripts/lang/he.js +49 -0
  813. data/public/javascripts/lang/it.js +13 -0
  814. data/public/javascripts/lang/nl.js +40 -0
  815. data/public/javascripts/lang/no.js +40 -0
  816. data/public/javascripts/lang/pt.js +50 -0
  817. data/public/javascripts/lang/ro.js +40 -0
  818. data/public/javascripts/lang/ru.js +40 -0
  819. data/public/javascripts/lang/sp.js +40 -0
  820. data/public/javascripts/lang/sv.js +41 -0
  821. data/public/javascripts/lang/ua.js +40 -0
  822. data/public/javascripts/localization/messages_cn.js +24 -0
  823. data/public/javascripts/localization/messages_cs.js +23 -0
  824. data/public/javascripts/localization/messages_da.js +21 -0
  825. data/public/javascripts/localization/messages_de.js +21 -0
  826. data/public/javascripts/localization/messages_es.js +24 -0
  827. data/public/javascripts/localization/messages_fr.js +23 -0
  828. data/public/javascripts/localization/messages_hu.js +21 -0
  829. data/public/javascripts/localization/messages_it.js +26 -0
  830. data/public/javascripts/localization/messages_kk.js +23 -0
  831. data/public/javascripts/localization/messages_nl.js +23 -0
  832. data/public/javascripts/localization/messages_no.js +23 -0
  833. data/public/javascripts/localization/messages_pl.js +23 -0
  834. data/public/javascripts/localization/messages_ptbr.js +30 -0
  835. data/public/javascripts/localization/messages_ro.js +24 -0
  836. data/public/javascripts/localization/messages_ru.js +23 -0
  837. data/public/javascripts/localization/messages_se.js +23 -0
  838. data/public/javascripts/localization/messages_sk.js +21 -0
  839. data/public/javascripts/localization/messages_tr.js +24 -0
  840. data/public/javascripts/localization/messages_tw.js +24 -0
  841. data/public/javascripts/localization/messages_ua.js +24 -0
  842. data/public/javascripts/nested-attribute.js +26 -0
  843. data/public/javascripts/open_id.js +15 -0
  844. data/public/javascripts/product.js +49 -0
  845. data/public/javascripts/rails.js +127 -0
  846. data/public/javascripts/taxonomy.js +201 -0
  847. data/public/javascripts/zone.js +39 -0
  848. data/public/stylesheets/admin/admin-forms.css +154 -0
  849. data/public/stylesheets/admin/admin-reset.css +69 -0
  850. data/public/stylesheets/admin/admin-tables.css +39 -0
  851. data/public/stylesheets/admin/admin-typography.css +117 -0
  852. data/public/stylesheets/admin/admin.css +614 -0
  853. data/public/stylesheets/admin/autocomplete.css +73 -0
  854. data/public/stylesheets/admin/dashboard.css +143 -0
  855. data/public/stylesheets/admin/edit_checkouts.css +57 -0
  856. data/public/stylesheets/admin/grids.css +314 -0
  857. data/public/stylesheets/admin/reset-fonts-grids-2-6-0.css +7 -0
  858. data/public/stylesheets/admin/token-input.css +109 -0
  859. data/public/stylesheets/admin/yui-includes.css +14 -0
  860. data/public/stylesheets/datepicker.css +263 -0
  861. data/public/stylesheets/jquery.autocomplete.css +48 -0
  862. data/public/stylesheets/screen.css +916 -0
  863. metadata +1072 -0
@@ -0,0 +1,119 @@
1
+ class Payment < ActiveRecord::Base
2
+ belongs_to :order
3
+ belongs_to :source, :polymorphic => true
4
+ belongs_to :payment_method
5
+
6
+ has_many :offsets, :class_name => 'Payment', :foreign_key => 'source_id', :conditions => "source_type = 'Payment' AND amount < 0 AND state = 'completed'"
7
+ has_many :log_entries, :as => :source
8
+
9
+ after_save :create_payment_profile, :if => :profiles_supported?
10
+
11
+ # update the order totals, etc.
12
+ after_save :update_order
13
+
14
+ accepts_nested_attributes_for :source
15
+
16
+ scope :from_creditcard, where(:source_type => 'Creditcard')
17
+ scope :with_state, lambda {|s| where(:state => s)}
18
+ scope :completed, with_state('completed')
19
+ scope :pending, with_state('pending')
20
+ scope :failed, with_state('failed')
21
+
22
+ # order state machine (see http://github.com/pluginaweek/state_machine/tree/master for details)
23
+ state_machine :initial => 'checkout' do
24
+ # With card payments, happens before purchase or authorization happens
25
+ event :started_processing do
26
+ transition :from => ['checkout', 'pending', 'completed'], :to => 'processing'
27
+ end
28
+ # When processing during checkout fails
29
+ event :fail do
30
+ transition :from => 'processing', :to => 'failed'
31
+ end
32
+ # With card payments this represents authorizing the payment
33
+ event :pend do
34
+ transition :from => 'processing', :to => 'pending'
35
+ end
36
+ # With card payments this represents completing a purchase or capture transaction
37
+ event :complete do
38
+ transition :from => ['processing', 'pending'], :to => 'completed'
39
+ end
40
+ event :void do
41
+ transition :from => ['pending', 'completed'], :to => 'void'
42
+ end
43
+ end
44
+
45
+
46
+ def offsets_total
47
+ offsets.map(&:amount).sum
48
+ end
49
+
50
+ def credit_allowed
51
+ amount - offsets_total
52
+ end
53
+
54
+ def can_credit?
55
+ credit_allowed > 0
56
+ end
57
+
58
+ def credit(amount)
59
+ return if amount > credit_allowed
60
+ started_processing!
61
+ source.credit(self, amount)
62
+ end
63
+
64
+ # With nested attributes, Rails calls build_[association_name] for the nested model which won't work for a polymorphic association
65
+ def build_source(params)
66
+ if payment_method and payment_method.payment_source_class
67
+ self.source = payment_method.payment_source_class.new(params)
68
+ end
69
+ end
70
+
71
+ def process!
72
+ if payment_method && payment_method.source_required?
73
+ if source
74
+ if !processing? && source.respond_to?(:process!)
75
+ started_processing!
76
+ source.process!(self) # source is responsible for updating the payment state when it's done processing
77
+ end
78
+ else
79
+ raise Spree::GatewayError.new(I18n.t(:payment_processing_failed))
80
+ end
81
+ end
82
+ end
83
+
84
+ def actions
85
+ return [] unless payment_source and payment_source.respond_to? :actions
86
+ payment_source.actions.select { |action| !payment_source.respond_to?("can_#{action}?") or payment_source.send("can_#{action}?", self) }
87
+ end
88
+
89
+ def payment_source
90
+ res = source.is_a?(Payment) ? source.source : source
91
+ res || payment_method
92
+ end
93
+
94
+ private
95
+
96
+ def amount_is_valid_for_outstanding_balance_or_credit
97
+ return unless order
98
+ if amount != order.outstanding_balance
99
+ errors.add(:amount, "does not match outstanding balance (#{order.outstanding_balance})")
100
+ end
101
+ end
102
+
103
+ def profiles_supported?
104
+ payment_method.respond_to?(:payment_profiles_supported?) && payment_method.payment_profiles_supported?
105
+ end
106
+
107
+ def create_payment_profile
108
+ return unless source.is_a?(Creditcard) && source.number && !source.has_payment_profile?
109
+ payment_method.create_profile(self)
110
+ rescue ActiveMerchant::ConnectionError => e
111
+ gateway_error I18n.t(:unable_to_connect_to_gateway)
112
+ end
113
+
114
+ def update_order
115
+ order.payments.reload
116
+ order.update!
117
+ end
118
+
119
+ end
@@ -0,0 +1,56 @@
1
+ class PaymentMethod < ActiveRecord::Base
2
+ DISPLAY = [:both, :front_end, :back_end]
3
+ default_scope where(:deleted_at => nil)
4
+
5
+ @provider = nil
6
+ @@providers = Set.new
7
+ def self.register
8
+ @@providers.add(self)
9
+ end
10
+
11
+ def self.providers
12
+ @@providers.to_a
13
+ end
14
+
15
+ def provider_class
16
+ raise "You must implement provider_class method for this gateway."
17
+ end
18
+
19
+ # The class that will process payments for this payment type, used for @payment.source
20
+ # e.g. Creditcard in the case of a the Gateway payment type
21
+ # nil means the payment method doesn't require a source e.g. check
22
+ def payment_source_class
23
+ raise "You must implement payment_source_class method for this gateway."
24
+ end
25
+
26
+ def self.available(display_on='both')
27
+ PaymentMethod.all.select { |p| p.active && (p.display_on == display_on.to_s || p.display_on.blank?) && (p.environment == Rails.env || p.environment.blank?) }
28
+ end
29
+
30
+ def self.active?
31
+ self.count(:conditions => {:type => self.to_s, :environment => Rails.env, :active => true}) > 0
32
+ end
33
+
34
+ def self.current
35
+ PaymentMethod.find(:first, :conditions => {:active => true, :environment => Rails.env})
36
+ end
37
+
38
+ def method_type
39
+ type.demodulize.downcase
40
+ end
41
+
42
+ def destroy
43
+ self.update_attribute(:deleted_at, Time.now.utc)
44
+ end
45
+
46
+ def self.find_with_destroyed *args
47
+ self.with_exclusive_scope { find(*args) }
48
+ end
49
+
50
+ def payment_profiles_supported?
51
+ false
52
+ end
53
+ def source_required?
54
+ true
55
+ end
56
+ end
@@ -0,0 +1,27 @@
1
+ class PaymentMethod::Check < PaymentMethod
2
+ def actions
3
+ %w{capture void}
4
+ end
5
+
6
+ # Indicates whether its possible to capture the payment
7
+ def can_capture?(payment)
8
+ ['checkout', 'pending'].include?(payment.state)
9
+ end
10
+
11
+ # Indicates whether its possible to void the payment.
12
+ def can_void?(payment)
13
+ payment.state != 'void'
14
+ end
15
+
16
+ def capture(payment)
17
+ payment.update_attribute(:state, 'pending') if payment.state == 'checkout'
18
+ payment.complete
19
+ true
20
+ end
21
+
22
+ def void(payment)
23
+ payment.update_attribute(:state, 'pending') if payment.state == 'checkout'
24
+ payment.void
25
+ true
26
+ end
27
+ end
@@ -0,0 +1,51 @@
1
+ # Represents a preferred value for a particular preference on a model.
2
+ #
3
+ # == Targeted preferences
4
+ #
5
+ # In addition to simple named preferences, preferences can also be targeted for
6
+ # a particular record. For example, a User may have a preferred color for a
7
+ # particular Car. In this case, the +owner+ is the User, the +preference+ is
8
+ # the color, and the +target+ is the Car. This allows preferences to have a sort
9
+ # of context around them.
10
+ class Preference < ActiveRecord::Base
11
+ belongs_to :owner, :polymorphic => true
12
+ belongs_to :group, :polymorphic => true
13
+
14
+ validates :name, :owner_id, :owner_type, :presence => true
15
+ validates :group_type, :presence => true, :if => :group_id?
16
+
17
+ class << self
18
+ # Splits the given group into its corresponding id and type
19
+ def split_group(group = nil)
20
+ if group.is_a?(ActiveRecord::Base)
21
+ group_id, group_type = group.id, group.class.base_class.name.to_s
22
+ else
23
+ group_id, group_type = nil, group
24
+ end
25
+ return group_id, group_type
26
+ end
27
+ end
28
+
29
+ # The definition for the attribute
30
+ def definition
31
+ owner.preference_definitions[name] unless owner_type.blank?
32
+ end
33
+
34
+ # Typecasts the value depending on the preference definition's declared type
35
+ def value
36
+ value = read_attribute(:value)
37
+ value = definition.type_cast(value) if definition
38
+ value
39
+ end
40
+
41
+ # Only searches for the group record if the group id is specified
42
+ def group_with_optional_lookup
43
+ group_id ? group_without_optional_lookup : group_type
44
+ end
45
+ alias_method_chain :group, :optional_lookup
46
+ end
47
+
48
+
49
+ # Most of this code is taken from the preferences plugin available
50
+ # at http://github.com/pluginaweek/preferences/tree/master
51
+
@@ -0,0 +1,258 @@
1
+ # PRODUCTS
2
+ # Products represent an entity for sale in a store.
3
+ # Products can have variations, called variants
4
+ # Products properties include description, permalink, availability,
5
+ # shipping category, etc. that do not change by variant.
6
+ #
7
+ # MASTER VARIANT
8
+ # Every product has one master variant, which stores master price and sku, size and weight, etc.
9
+ # The master variant does not have option values associated with it.
10
+ # Price, SKU, size, weight, etc. are all delegated to the master variant.
11
+ # Contains on_hand inventory levels only when there are no variants for the product.
12
+ #
13
+ # VARIANTS
14
+ # All variants can access the product properties directly (via reverse delegation).
15
+ # Inventory units are tied to Variant.
16
+ # The master variant can have inventory units, but not option values.
17
+ # All other variants have option values and may have inventory units.
18
+ # Sum of on_hand each variant's inventory level determine "on_hand" level for the product.
19
+ #
20
+ class Product < ActiveRecord::Base
21
+ has_many :product_option_types, :dependent => :destroy
22
+ has_many :option_types, :through => :product_option_types
23
+ has_many :product_properties, :dependent => :destroy
24
+ has_many :properties, :through => :product_properties
25
+ has_many :images, :as => :viewable, :order => :position, :dependent => :destroy
26
+ has_and_belongs_to_many :product_groups
27
+ belongs_to :tax_category
28
+ has_and_belongs_to_many :taxons
29
+ belongs_to :shipping_category
30
+
31
+ has_one :master,
32
+ :class_name => 'Variant',
33
+ :conditions => ["variants.is_master = ? AND variants.deleted_at IS NULL", true]
34
+
35
+ delegate_belongs_to :master, :sku, :price, :weight, :height, :width, :depth, :is_master
36
+ delegate_belongs_to :master, :cost_price if Variant.table_exists? && Variant.column_names.include?("cost_price")
37
+
38
+ after_create :set_master_variant_defaults
39
+ after_create :add_properties_and_option_types_from_prototype
40
+ before_save :recalculate_count_on_hand
41
+ before_update :sanitize_permalink
42
+ after_save :update_memberships if ProductGroup.table_exists?
43
+ after_save :set_master_on_hand_to_zero_when_product_has_variants
44
+ after_save :save_master
45
+
46
+ has_many :variants,
47
+ :conditions => ["variants.is_master = ? AND variants.deleted_at IS NULL", false],
48
+ :order => 'variants.position ASC'
49
+
50
+
51
+ has_many :variants_including_master,
52
+ :class_name => 'Variant',
53
+ :conditions => ["variants.deleted_at IS NULL"],
54
+ :dependent => :destroy
55
+
56
+ has_many :variants_with_only_master,
57
+ :class_name => 'Variant',
58
+ :conditions => ["variants.deleted_at IS NULL AND variants.is_master = ?", true],
59
+ :dependent => :destroy
60
+
61
+
62
+ validates :name, :price, :permalink,:available_on, :presence => true
63
+
64
+ accepts_nested_attributes_for :product_properties, :allow_destroy => true, :reject_if => lambda { |pp| pp[:property_name].blank? }
65
+
66
+ make_permalink
67
+
68
+ alias :options :product_option_types
69
+
70
+ include ::Scopes::Product
71
+
72
+ #RAILS3 TODO - scopes are duplicated here and in scopres/product.rb - can we DRY it up?
73
+ # default product scope only lists available and non-deleted products
74
+ scope :not_deleted, where("products.deleted_at is NULL")
75
+
76
+ scope :available, lambda { |*on| where("products.available_on <= ?", on.first || Time.zone.now ) }
77
+
78
+ #RAILS 3 TODO - this scope doesn't match the original 2.3.x version, needs attention (but it works)
79
+ scope :active, lambda{ not_deleted.available }
80
+
81
+ scope :on_hand, where("products.count_on_hand > 0")
82
+
83
+ if (ActiveRecord::Base.connection.adapter_name == 'PostgreSQL')
84
+ if ActiveRecord::Base.connection.tables.include?("products")
85
+ scope :group_by_products_id, { :group => "products." + Product.column_names.join(", products.") }
86
+ end
87
+ else
88
+ scope :group_by_products_id, { :group => "products.id" }
89
+ end
90
+ search_methods :group_by_products_id
91
+
92
+ scope :id_equals, lambda { |input_id| where("products.id = ?", input_id) }
93
+
94
+ scope :taxons_name_eq, lambda { |name| joins(:taxons).where("taxons.name = ?", name) }
95
+
96
+ # ----------------------------------------------------------------------------------------------------------
97
+ #
98
+ # The following methods are deprecated and will be removed in a future version of Spree
99
+ #
100
+ # ----------------------------------------------------------------------------------------------------------
101
+
102
+ def master_price
103
+ warn "[DEPRECATION] `Product.master_price` is deprecated. Please use `Product.price` instead. (called from #{caller[0]})"
104
+ self.price
105
+ end
106
+
107
+ def master_price=(value)
108
+ warn "[DEPRECATION] `Product.master_price=` is deprecated. Please use `Product.price=` instead. (called from #{caller[0]})"
109
+ self.price = value
110
+ end
111
+
112
+ def variants?
113
+ warn "[DEPRECATION] `Product.variants?` is deprecated. Please use `Product.has_variants?` instead. (called from #{caller[0]})"
114
+ self.has_variants?
115
+ end
116
+
117
+ def variant
118
+ warn "[DEPRECATION] `Product.variant` is deprecated. Please use `Product.master` instead. (called from #{caller[0]})"
119
+ self.master
120
+ end
121
+
122
+ # ----------------------------------------------------------------------------------------------------------
123
+ # end deprecation region
124
+ # ----------------------------------------------------------------------------------------------------------
125
+
126
+ def to_param
127
+ return permalink if permalink.present?
128
+ name.to_url
129
+ end
130
+
131
+ # returns true if the product has any variants (the master variant is not a member of the variants array)
132
+ def has_variants?
133
+ !variants.empty?
134
+ end
135
+
136
+ # returns the number of inventory units "on_hand" for this product
137
+ def on_hand
138
+ has_variants? ? variants.inject(0){|sum, v| sum + v.on_hand} : master.on_hand
139
+ end
140
+
141
+ # adjusts the "on_hand" inventory level for the product up or down to match the given new_level
142
+ def on_hand=(new_level)
143
+ raise "cannot set on_hand of product with variants" if has_variants? && Spree::Config[:track_inventory_levels]
144
+ master.on_hand = new_level
145
+ end
146
+
147
+ # Returns true if there are inventory units (any variant) with "on_hand" state for this product
148
+ def has_stock?
149
+ master.in_stock? || !!variants.detect{|v| v.in_stock?}
150
+ end
151
+
152
+ def tax_category
153
+ if self[:tax_category_id].nil?
154
+ TaxCategory.first(:conditions => {:is_default => true})
155
+ else
156
+ TaxCategory.find(self[:tax_category_id])
157
+ end
158
+ end
159
+
160
+ # Adding properties and option types on creation based on a chosen prototype
161
+ attr_reader :prototype_id
162
+ def prototype_id=(value)
163
+ @prototype_id = value.to_i
164
+ end
165
+
166
+ def add_properties_and_option_types_from_prototype
167
+ if prototype_id && prototype = Prototype.find_by_id(prototype_id)
168
+ prototype.properties.each do |property|
169
+ product_properties.create(:property => property)
170
+ end
171
+ self.option_types = prototype.option_types
172
+ end
173
+ end
174
+
175
+ # for adding products which are closely related to existing ones
176
+ # define "duplicate_extra" for site-specific actions, eg for additional fields
177
+ def duplicate
178
+ p = self.clone
179
+ p.name = 'COPY OF ' + self.name
180
+ p.deleted_at = nil
181
+ p.created_at = p.updated_at = nil
182
+ p.taxons = self.taxons
183
+
184
+ p.product_properties = self.product_properties.map {|q| r = q.clone; r.created_at = r.updated_at = nil; r}
185
+
186
+ image_clone = lambda {|i| j = i.clone; j.attachment = i.attachment.clone; j}
187
+ p.images = self.images.map {|i| image_clone.call i}
188
+
189
+ variant = self.master.clone
190
+ variant.sku = 'COPY OF ' + self.master.sku
191
+ variant.deleted_at = nil
192
+ variant.images = self.master.images.map {|i| image_clone.call i}
193
+ p.master = variant
194
+
195
+ if self.has_variants?
196
+ # don't clone the actual variants, just the characterising types
197
+ p.option_types = self.option_types
198
+ else
199
+ end
200
+ # allow site to do some customization
201
+ p.send(:duplicate_extra) if p.respond_to?(:duplicate_extra)
202
+ p.save!
203
+ p
204
+ end
205
+
206
+ # use deleted? rather than checking the attribute directly. this
207
+ # allows extensions to override deleted? if they want to provide
208
+ # their own definition.
209
+ def deleted?
210
+ !!deleted_at
211
+ end
212
+
213
+ # split variants list into hash which shows mapping of opt value onto matching variants
214
+ # eg categorise_variants_from_option(color) => {"red" -> [...], "blue" -> [...]}
215
+ def categorise_variants_from_option(opt_type)
216
+ return {} unless option_types.include?(opt_type)
217
+ variants.active.group_by {|v| v.option_values.detect {|o| o.option_type == opt_type} }
218
+ end
219
+
220
+ def self.like_any(fields, values)
221
+ where_str = fields.map{|field| Array.new(values.size, "products.#{field} #{LIKE} ?").join(' OR ') }.join(' OR ')
222
+ self.where([where_str, values.map{|value| "%#{value}%"} * fields.size].flatten)
223
+ end
224
+
225
+ private
226
+
227
+ def sanitize_permalink
228
+ self.permalink = self.permalink.to_url
229
+ end
230
+
231
+ def recalculate_count_on_hand
232
+ product_count_on_hand = has_variants? ?
233
+ variants.inject(0) {|acc, v| acc + v.count_on_hand} :
234
+ (master ? master.count_on_hand : 0)
235
+ self.count_on_hand = product_count_on_hand
236
+ end
237
+
238
+ # the master on_hand is meaningless once a product has variants as the inventory
239
+ # units are now "contained" within the product variants
240
+ def set_master_on_hand_to_zero_when_product_has_variants
241
+ master.on_hand = 0 if has_variants? && Spree::Config[:track_inventory_levels]
242
+ end
243
+
244
+ # ensures the master variant is flagged as such
245
+ def set_master_variant_defaults
246
+ master.is_master = true
247
+ end
248
+
249
+ # there's a weird quirk with the delegate stuff that does not automatically save the delegate object
250
+ # when saving so we force a save using a hook.
251
+ def save_master
252
+ master.save if master && (master.changed? || master.new_record?)
253
+ end
254
+
255
+ def update_memberships
256
+ self.product_groups = ProductGroup.all.select{|pg| pg.include?(self)}
257
+ end
258
+ end