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,88 @@
1
+ class Gateway::Braintree < Gateway
2
+ preference :merchant_id, :string
3
+ preference :public_key, :string
4
+ preference :private_key, :string
5
+
6
+ def provider_class
7
+ ActiveMerchant::Billing::BraintreeGateway
8
+ end
9
+
10
+ def authorize(money, creditcard, options = {})
11
+ adjust_options_for_braintree(creditcard, options)
12
+ payment_method = creditcard.gateway_customer_profile_id || creditcard
13
+ provider.authorize(money, payment_method, options)
14
+ end
15
+
16
+ def capture(authorization, ignored_creditcard, ignored_options)
17
+ amount = (authorization.amount * 100).to_i
18
+ provider.capture(amount, authorization.response_code)
19
+ end
20
+
21
+ def create_profile(payment)
22
+ if payment.source.gateway_customer_profile_id.nil?
23
+ response = provider.store(payment.source)
24
+ if response.success?
25
+ payment.source.update_attributes!(:gateway_customer_profile_id => response.params["customer_vault_id"])
26
+ else
27
+ payment.source.gateway_error response.message
28
+ end
29
+ end
30
+ end
31
+
32
+ def credit(*args)
33
+ if args.size == 4
34
+ credit_with_payment_profiles(*args)
35
+ elsif args.size == 3
36
+ credit_without_payment_profiles(*args)
37
+ else
38
+ raise ArgumentError, "Expected 3 or 4 arguments, received #{args.size}"
39
+ end
40
+ end
41
+
42
+ def credit_with_payment_profiles(amount, payment, response_code, option)
43
+ provider.credit(amount, payment)
44
+ end
45
+
46
+ def credit_without_payment_profiles(amount, response_code, options)
47
+ transaction = ::Braintree::Transaction.find(response_code)
48
+ if BigDecimal.new(amount.to_s) == (transaction.amount * 100)
49
+ provider.refund(response_code)
50
+ else
51
+ raise NotImplementedError
52
+ end
53
+ end
54
+
55
+ def payment_profiles_supported?
56
+ true
57
+ end
58
+
59
+ def purchase(money, creditcard, options = {})
60
+ authorize(money, creditcard, options.merge(:submit_for_settlement => true))
61
+ end
62
+
63
+ def void(response_code, ignored_options)
64
+ provider.void(response_code)
65
+ end
66
+
67
+ protected
68
+
69
+ def adjust_country_name(options)
70
+ [:billing_address, :shipping_address].each do |address|
71
+ if options[address] && options[address][:country] == "US"
72
+ options[address][:country] = "United States of America"
73
+ end
74
+ end
75
+ end
76
+
77
+ def adjust_billing_address(creditcard, options)
78
+ if creditcard.gateway_customer_profile_id
79
+ options.delete(:billing_address)
80
+ end
81
+ end
82
+
83
+ def adjust_options_for_braintree(creditcard, options)
84
+ adjust_country_name(options)
85
+ adjust_billing_address(creditcard, options)
86
+ end
87
+ end
88
+
@@ -0,0 +1,11 @@
1
+ class Gateway::Eway < Gateway
2
+ preference :login, :string
3
+
4
+ # Note: EWay supports purchase method only (no authorize method).
5
+ # Ensure Spree::Config[:auto_capture] is set to true
6
+
7
+ def provider_class
8
+ ActiveMerchant::Billing::EwayGateway
9
+ end
10
+
11
+ end
@@ -0,0 +1,8 @@
1
+ class Gateway::Linkpoint < Gateway
2
+ preference :login, :string
3
+ preference :pem, :text
4
+
5
+ def provider_class
6
+ ActiveMerchant::Billing::LinkpointGateway
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ class Gateway::PayPal < Gateway
2
+ preference :login, :string
3
+ preference :password, :string
4
+ preference :signature, :string
5
+ preference :currency_code, :string
6
+
7
+ def provider_class
8
+ ActiveMerchant::Billing::PaypalGateway
9
+ end
10
+
11
+ end
@@ -0,0 +1,9 @@
1
+ class Gateway::SagePay < Gateway
2
+ preference :login, :string
3
+ preference :password, :string
4
+ preference :account, :string
5
+
6
+ def provider_class
7
+ ActiveMerchant::Billing::SagePayGateway
8
+ end
9
+ end
@@ -0,0 +1,31 @@
1
+ class Image < Asset
2
+ validate :no_attachement_errors
3
+ has_attached_file :attachment,
4
+ :styles => { :mini => '48x48>', :small => '100x100>', :product => '240x240>', :large => '600x600>' },
5
+ :default_style => :product,
6
+ :url => "/assets/products/:id/:style/:basename.:extension",
7
+ :path => ":rails_root/public/assets/products/:id/:style/:basename.:extension"
8
+
9
+ # save the w,h of the original image (from which others can be calculated)
10
+ # we need to look at the write-queue for images which have not been saved yet
11
+ after_post_process :find_dimensions
12
+
13
+ def find_dimensions
14
+ temporary = attachment.queued_for_write[:original]
15
+ filename = temporary.path unless temporary.nil?
16
+ filename = attachment.path if filename.blank?
17
+ geometry = Paperclip::Geometry.from_file(filename)
18
+ self.attachment_width = geometry.width
19
+ self.attachment_height = geometry.height
20
+ end
21
+
22
+ # if there are errors from the plugin, then add a more meaningful message
23
+ def no_attachement_errors
24
+ unless attachment.errors.empty?
25
+ # uncomment this to get rid of the less-than-useful interrim messages
26
+ # errors.clear
27
+ errors.add :attachment, "Paperclip returned errors for file '#{attachment_file_name}' - check ImageMagick installation or image source file."
28
+ false
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,119 @@
1
+ class InventoryUnit < ActiveRecord::Base
2
+ belongs_to :variant
3
+ belongs_to :order
4
+ belongs_to :shipment
5
+ belongs_to :return_authorization
6
+
7
+ scope :backorder, where(:state => 'backordered')
8
+
9
+ # state machine (see http://github.com/pluginaweek/state_machine/tree/master for details)
10
+ state_machine :initial => 'on_hand' do
11
+ event :fill_backorder do
12
+ transition :to => 'sold', :from => 'backordered'
13
+ end
14
+ event :ship do
15
+ transition :to => 'shipped', :if => :allow_ship?
16
+ end
17
+ event :return do
18
+ transition :to => 'returned', :from => 'shipped'
19
+ end
20
+
21
+ after_transition :on => :fill_backorder, :do => :update_order
22
+ after_transition :to => 'returned', :do => :restock_variant
23
+ end
24
+
25
+ # method deprecated in favour of adjust_units (which creates & destroys units as needed).
26
+ def self.sell_units(order)
27
+ warn "[DEPRECATION] `InventoryUnits#sell_units` is deprecated. Please use `InventoryUnits#assign_opening_inventory` instead. (called from #{caller[0]})"
28
+ self.adjust_units(order)
29
+ end
30
+
31
+ # Assigns inventory to a newly completed order.
32
+ # Should only be called once during the life-cycle of an order, on transition to completed.
33
+ #
34
+ def self.assign_opening_inventory(order)
35
+ return [] unless order.completed?
36
+
37
+ #increase inventory to meet initial requirements
38
+ order.line_items.each do |line_item|
39
+ increase(order, line_item.variant, line_item.quantity)
40
+ end
41
+ end
42
+
43
+ # manages both variant.count_on_hand and inventory unit creation
44
+ #
45
+ def self.increase(order, variant, quantity)
46
+ back_order = determine_backorder(order, variant, quantity)
47
+ sold = quantity - back_order
48
+
49
+ #set on_hand if configured
50
+ if Spree::Config[:track_inventory_levels]
51
+ variant.decrement!(:count_on_hand, quantity)
52
+ end
53
+
54
+ #create units if configured
55
+ if Spree::Config[:create_inventory_units]
56
+ create_units(order, variant, sold, back_order)
57
+ end
58
+ end
59
+
60
+ def self.decrease(order, variant, quantity)
61
+ if Spree::Config[:track_inventory_levels]
62
+ variant.increment!(:count_on_hand, quantity)
63
+ end
64
+
65
+ if Spree::Config[:create_inventory_units]
66
+ destroy_units(order, variant, quantity)
67
+ end
68
+ end
69
+
70
+ # find the specified quantity of units with the specified status
71
+ def self.find_by_status(variant, quantity, status)
72
+ variant.inventory_units.where(:status => status).limit(quantity)
73
+ end
74
+
75
+ private
76
+ def allow_ship?
77
+ Spree::Config[:allow_backorder_shipping] || self.sold?
78
+ end
79
+
80
+ def self.determine_backorder(order, variant, quantity)
81
+ if variant.on_hand == 0
82
+ quantity
83
+ elsif variant.on_hand.present? and variant.on_hand < quantity
84
+ quantity - (variant.on_hand < 0 ? 0 : variant.on_hand)
85
+ else
86
+ 0
87
+ end
88
+ end
89
+
90
+ def self.destroy_units(order, variant, quantity)
91
+ variant_units = order.inventory_units.group_by(&:variant_id)[variant.id].sort_by(&:state)
92
+
93
+ quantity.times do
94
+ inventory_unit = variant_units.shift
95
+ inventory_unit.destroy
96
+ end
97
+ end
98
+
99
+ def self.create_units(order, variant, sold, back_order)
100
+ if back_order > 0 && !Spree::Config[:allow_backorders]
101
+ raise "Cannot request back orders when backordering is disabled"
102
+ end
103
+
104
+ shipment = order.shipments.detect {|shipment| !shipment.shipped? }
105
+
106
+ sold.times { order.inventory_units.create(:variant => variant, :state => "sold", :shipment => shipment) }
107
+ back_order.times { order.inventory_units.create(:variant => variant, :state => "backordered", :shipment => shipment) }
108
+ end
109
+
110
+ def update_order
111
+ self.order.update!
112
+ end
113
+
114
+ def restock_variant
115
+ self.variant.on_hand = (self.variant.on_hand + 1)
116
+ self.variant.save
117
+ end
118
+
119
+ end
@@ -0,0 +1,95 @@
1
+ class LineItem < ActiveRecord::Base
2
+ before_validation :adjust_quantity
3
+ belongs_to :order
4
+ belongs_to :variant
5
+
6
+ has_one :product, :through => :variant
7
+
8
+ before_validation :copy_price
9
+
10
+ validates :variant, :presence => true
11
+ validates :quantity, :numericality => { :only_integer => true, :message => I18n.t("validation.must_be_int") }
12
+ validates :price, :numericality => true
13
+ # validate :meta_validation_of_quantities
14
+
15
+ attr_accessible :quantity
16
+
17
+ before_save :update_inventory
18
+ before_destroy :ensure_not_shipped, :remove_inventory
19
+
20
+ after_save :update_order
21
+ after_destroy :update_order
22
+
23
+ def copy_price
24
+ self.price = variant.price if variant && self.price.nil?
25
+ end
26
+
27
+ # def meta_validation_of_quantities
28
+ # unless quantity && quantity >= 0
29
+ # errors.add(:quantity, I18n.t("validation.must_be_non_negative"))
30
+ # end
31
+ # # avoid reload of order.inventory_units by using direct lookup
32
+ # unless !Spree::Config[:track_inventory_levels] ||
33
+ # Spree::Config[:allow_backorders] ||
34
+ # order && InventoryUnit.order_id_equals(order).first.present? ||
35
+ # variant && quantity <= variant.on_hand
36
+ # errors.add(:quantity, I18n.t("validation.is_too_large") + " (#{self.variant.name})")
37
+ # end
38
+ #
39
+ # if shipped_count = order.shipped_units.nil? ? nil : order.shipped_units[variant]
40
+ # errors.add(:quantity, I18n.t("validation.cannot_be_less_than_shipped_units") ) if quantity < shipped_count
41
+ # end
42
+ # end
43
+
44
+ def increment_quantity
45
+ self.quantity += 1
46
+ end
47
+
48
+ def decrement_quantity
49
+ self.quantity -= 1
50
+ end
51
+
52
+ def amount
53
+ self.price * self.quantity
54
+ end
55
+ alias total amount
56
+
57
+ def adjust_quantity
58
+ self.quantity = 0 if self.quantity.nil? || self.quantity < 0
59
+ end
60
+
61
+ private
62
+ def update_inventory
63
+ return true unless self.order.completed?
64
+
65
+ if self.new_record?
66
+ InventoryUnit.increase(self.order, self.variant, self.quantity)
67
+ elsif old_quantity = self.changed_attributes["quantity"]
68
+ if old_quantity < self.quantity
69
+ InventoryUnit.increase(self.order, self.variant, (self.quantity - old_quantity))
70
+ elsif old_quantity > self.quantity
71
+ InventoryUnit.decrease(self.order, self.variant, (old_quantity - self.quantity))
72
+ end
73
+ end
74
+
75
+ end
76
+
77
+ def remove_inventory
78
+ return true unless self.order.completed?
79
+
80
+ InventoryUnit.decrease(self.order, self.variant, self.quantity)
81
+ end
82
+
83
+ def update_order
84
+ # update the order totals, etc.
85
+ order.update!
86
+ end
87
+
88
+ def ensure_not_shipped
89
+ if order.try(:inventory_units).to_a.any?{|unit| unit.variant_id == variant_id && unit.shipped?}
90
+ errors.add :base, I18n.t("cannot_destory_line_item_as_inventory_units_have_shipped")
91
+ return false
92
+ end
93
+ end
94
+ end
95
+
@@ -0,0 +1,3 @@
1
+ class LogEntry < ActiveRecord::Base
2
+ belongs_to :source, :polymorphic => true
3
+ end
@@ -0,0 +1,23 @@
1
+ class MailMethod < ActiveRecord::Base
2
+
3
+ MAIL_AUTH = ['none', 'plain', 'login', 'cram_md5']
4
+ SECURE_CONNECTION_TYPES = ['None','SSL','TLS']
5
+
6
+ preference :enable_mail_delivery, :boolean, :default => false
7
+ preference :mail_host, :string, :default => 'localhost'
8
+ preference :mail_domain, :string, :default => 'localhost'
9
+ preference :mail_port, :integer, :default => 25
10
+ preference :mail_auth_type, :string, :default => MailMethod::MAIL_AUTH[0]
11
+ preference :smtp_username, :string
12
+ preference :smtp_password, :string
13
+ preference :secure_connection_type, :string, :default => MailMethod::SECURE_CONNECTION_TYPES[0]
14
+ preference :mails_from, :string, :default => "no-reply@example.com"
15
+ preference :mail_bcc, :string, :default => "spree@example.com"
16
+ preference :intercept_email, :string, :default => nil
17
+
18
+ validates :environment, :presence => true
19
+
20
+ def self.current
21
+ MailMethod.where(:environment => Rails.env).first
22
+ end
23
+ end
@@ -0,0 +1,9 @@
1
+ class OptionType < ActiveRecord::Base
2
+ has_many :option_values, :order => :position, :dependent => :destroy
3
+ has_many :product_option_types, :dependent => :destroy
4
+ has_and_belongs_to_many :prototypes
5
+ validates :name, :presentation, :presence => true
6
+ default_scope :order => "option_types.position"
7
+
8
+ accepts_nested_attributes_for :option_values, :reject_if => lambda { |ov| ov[:name].blank? || ov[:presentation].blank? }, :allow_destroy => true
9
+ end
@@ -0,0 +1,5 @@
1
+ class OptionValue < ActiveRecord::Base
2
+ belongs_to :option_type
3
+ acts_as_list :scope => :option_type
4
+ has_and_belongs_to_many :variants
5
+ end
@@ -0,0 +1,484 @@
1
+ class Order < ActiveRecord::Base
2
+
3
+ attr_accessible :line_items, :bill_address_attributes, :ship_address_attributes, :payments_attributes,
4
+ :ship_address, :line_items_attributes,
5
+ :shipping_method_id, :email, :use_billing, :special_instructions
6
+
7
+ belongs_to :user
8
+ belongs_to :bill_address, :foreign_key => "bill_address_id", :class_name => "Address"
9
+ belongs_to :ship_address, :foreign_key => "ship_address_id", :class_name => "Address"
10
+ belongs_to :shipping_method
11
+
12
+ has_many :state_events, :as => :stateful
13
+ has_many :line_items, :dependent => :destroy
14
+ has_many :inventory_units
15
+ has_many :payments, :dependent => :destroy
16
+ has_many :shipments, :dependent => :destroy
17
+ has_many :return_authorizations, :dependent => :destroy
18
+ has_many :adjustments, :dependent => :destroy
19
+
20
+ accepts_nested_attributes_for :line_items
21
+ accepts_nested_attributes_for :bill_address
22
+ accepts_nested_attributes_for :ship_address
23
+ accepts_nested_attributes_for :payments
24
+ accepts_nested_attributes_for :shipments
25
+
26
+ before_create :create_user
27
+ before_create :generate_order_number
28
+ before_update:create_shipment!
29
+ # TODO: validate the format of the email as well (but we can't rely on authlogic anymore to help with validation)
30
+ validates :email, :presence => true, :format => /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i, :if => :require_email
31
+ validate :has_available_shipment
32
+
33
+ #delegate :ip_address, :to => :checkout
34
+ def ip_address
35
+ '192.168.1.100'
36
+ end
37
+
38
+ scope :by_number, lambda {|number| where("orders.number = ?", number)}
39
+ scope :between, lambda {|*dates| where("orders.created_at between ? and ?", dates.first.to_date, dates.last.to_date)}
40
+ scope :by_customer, lambda {|customer| joins(:user).where("users.email =?", customer)}
41
+ scope :by_state, lambda {|state| where("state = ?", state)}
42
+ scope :complete, where("orders.completed_at IS NOT NULL")
43
+ scope :incomplete, where("orders.completed_at IS NULL")
44
+
45
+ make_permalink :field => :number
46
+
47
+ attr_accessor :out_of_stock_items
48
+
49
+ class_attribute :update_hooks
50
+ self.update_hooks = Set.new
51
+
52
+ # Use this method in other gems that wish to register their own custom logic that should be called after Order#updat
53
+ def self.register_update_hook(hook)
54
+ self.update_hooks.add(hook)
55
+ end
56
+
57
+ def to_param
58
+ number.to_s.parameterize.upcase
59
+ end
60
+
61
+ def completed?
62
+ !! completed_at
63
+ end
64
+
65
+ # Indicates whether or not the user is allowed to proceed to checkout. Currently this is implemented as a
66
+ # check for whether or not there is at least one LineItem in the Order. Feel free to override this logic
67
+ # in your own application if you require additional steps before allowing a checkout.
68
+ def checkout_allowed?
69
+ line_items.count > 0
70
+ end
71
+
72
+ # Indicates the number of items in the order
73
+ def item_count
74
+ line_items.map(&:quantity).sum
75
+ end
76
+
77
+ # order state machine (see http://github.com/pluginaweek/state_machine/tree/master for details)
78
+ state_machine :initial => 'cart', :use_transactions => false do
79
+
80
+ event :next do
81
+ transition :from => 'cart', :to => 'address'
82
+ transition :from => 'address', :to => 'delivery'
83
+ transition :from => 'delivery', :to => 'payment'
84
+ transition :from => 'confirm', :to => 'complete'
85
+
86
+ # note: some payment methods will not support a confirm step
87
+ transition :from => 'payment', :to => 'confirm',
88
+ :if => Proc.new { Gateway.current && Gateway.current.payment_profiles_supported? }
89
+
90
+ transition :from => 'payment', :to => 'complete'
91
+ end
92
+
93
+ event :cancel do
94
+ transition :to => 'canceled', :if => :allow_cancel?
95
+ end
96
+ event :return do
97
+ transition :to => 'returned', :from => 'awaiting_return'
98
+ end
99
+ event :resume do
100
+ transition :to => 'resumed', :from => 'canceled', :if => :allow_resume?
101
+ end
102
+ event :authorize_return do
103
+ transition :to => 'awaiting_return'
104
+ end
105
+
106
+ before_transition :to => 'complete' do |order|
107
+ begin
108
+ order.process_payments!
109
+ rescue Spree::GatewayError
110
+ if Spree::Config[:allow_checkout_on_gateway_error]
111
+ true
112
+ else
113
+ false
114
+ end
115
+ end
116
+ end
117
+
118
+ after_transition :to => 'complete', :do => :finalize!
119
+ after_transition :to => 'delivery', :do => :create_tax_charge!
120
+ after_transition :to => 'payment', :do => :create_shipment!
121
+ after_transition :to => 'canceled', :do => :after_cancel
122
+
123
+ end
124
+
125
+ # Indicates whether there are any backordered InventoryUnits associated with the Order.
126
+ def backordered?
127
+ return false unless Spree::Config[:track_inventory_levels]
128
+ inventory_units.backorder.present?
129
+ end
130
+
131
+ # This is a multi-purpose method for processing logic related to changes in the Order. It is meant to be called from
132
+ # various observers so that the Order is aware of changes that affect totals and other values stored in the Order.
133
+ # This method should never do anything to the Order that results in a save call on the object (otherwise you will end
134
+ # up in an infinite recursion as the associations try to save and then in turn try to call +update!+ again.)
135
+ def update!
136
+ update_totals
137
+ update_payment_state
138
+
139
+ # give each of the shipments a chance to update themselves
140
+ shipments.each { |shipment| shipment.update!(self) }#(&:update!)
141
+ update_shipment_state
142
+ update_adjustments
143
+ # update totals a second time in case updated adjustments have an effect on the total
144
+ update_totals
145
+
146
+ update_attributes_without_callbacks({
147
+ :payment_state => payment_state,
148
+ :shipment_state => shipment_state,
149
+ :item_total => item_total,
150
+ :adjustment_total => adjustment_total,
151
+ :payment_total => payment_total,
152
+ :total => total
153
+ })
154
+ puts "ensure checkout payment"
155
+ #ensure checkout payment always matches order total
156
+ if payment and payment.checkout? and payment.amount != total
157
+ puts "payment update"
158
+ payment.update_attributes_without_callbacks(:amount => total)
159
+ end
160
+ puts "update hook"
161
+ update_hooks.each { |hook| self.send hook }
162
+ end
163
+
164
+ def restore_state
165
+ # pop the resume event so we can see what the event before that was
166
+ state_events.pop if state_events.last.name == "resume"
167
+ update_attribute("state", state_events.last.previous_state)
168
+
169
+ if paid?
170
+ raise "do something with inventory"
171
+ #InventoryUnit.assign_opening_inventory(self) if inventory_units.empty?
172
+ #shipment.inventory_units = inventory_units
173
+ #shipment.ready!
174
+ end
175
+
176
+ end
177
+
178
+ before_validation :clone_billing_address, :if => "@use_billing"
179
+ attr_accessor :use_billing
180
+
181
+ def clone_billing_address
182
+ if bill_address and self.ship_address.nil?
183
+ self.ship_address = bill_address.clone
184
+ else
185
+ self.ship_address.attributes = bill_address.attributes.except("id", "updated_at", "created_at")
186
+ end
187
+ true
188
+ end
189
+
190
+
191
+
192
+ def allow_cancel?
193
+ return false unless completed? and state != 'canceled'
194
+ %w{ready backorder pending}.include? shipment_state
195
+ end
196
+
197
+ def allow_resume?
198
+ # we shouldn't allow resume for legacy orders b/c we lack the information necessary to restore to a previous state
199
+ return false if state_events.empty? || state_events.last.previous_state.nil?
200
+ true
201
+ end
202
+
203
+ def add_variant(variant, quantity = 1)
204
+ current_item = contains?(variant)
205
+ if current_item
206
+ current_item.quantity += quantity
207
+ current_item.save
208
+ else
209
+ current_item = LineItem.new(:quantity => quantity)
210
+ current_item.variant = variant
211
+ current_item.price = variant.price
212
+ self.line_items << current_item
213
+ end
214
+
215
+ # populate line_items attributes for additional_fields entries
216
+ # that have populate => [:line_item]
217
+ Variant.additional_fields.select{|f| !f[:populate].nil? && f[:populate].include?(:line_item) }.each do |field|
218
+ value = ""
219
+
220
+ if field[:only].nil? || field[:only].include?(:variant)
221
+ value = variant.send(field[:name].gsub(" ", "_").downcase)
222
+ elsif field[:only].include?(:product)
223
+ value = variant.product.send(field[:name].gsub(" ", "_").downcase)
224
+ end
225
+ current_item.update_attribute(field[:name].gsub(" ", "_").downcase, value)
226
+ end
227
+
228
+ current_item
229
+ end
230
+
231
+ # FIXME refactor this method and implement validation using validates_* utilities
232
+ def generate_order_number
233
+ record = true
234
+ while record
235
+ random = "R#{Array.new(9){rand(9)}.join}"
236
+ record = self.class.find(:first, :conditions => ["number = ?", random])
237
+ end
238
+ self.number = random if self.number.blank?
239
+ self.number
240
+ end
241
+
242
+ # convenience method since many stores will not allow user to create multiple shipments
243
+ def shipment
244
+ @shipment ||= shipments.last
245
+ end
246
+
247
+ def contains?(variant)
248
+ line_items.detect{|line_item| line_item.variant_id == variant.id}
249
+ end
250
+
251
+ def ship_total
252
+ adjustments.shipping.map(&:amount).sum
253
+ end
254
+
255
+ def tax_total
256
+ adjustments.tax.map(&:amount).sum
257
+ end
258
+
259
+ # Creates a new tax charge if applicable. Uses the highest possible matching rate and destroys any previous
260
+ # tax charges if they were created by rates that no longer apply.
261
+ def create_tax_charge!
262
+ adjustments.tax.each {|e| e.destroy }
263
+ TaxRate.match(ship_address).each {|r| r.create_adjustment(I18n.t(:tax), self, self, true) }
264
+ end
265
+
266
+ # Creates a new shipment (adjustment is created by shipment model)
267
+ def create_shipment!
268
+ shipping_method(true)
269
+ if shipment.present?
270
+ shipment.update_attributes(:shipping_method => shipping_method)
271
+ else
272
+ self.shipments << Shipment.create(:order => self,
273
+ :shipping_method => shipping_method,
274
+ :address => self.ship_address)
275
+ end
276
+
277
+ end
278
+
279
+ def outstanding_balance
280
+ total - payment_total
281
+ end
282
+
283
+ def outstanding_balance?
284
+ self.outstanding_balance != 0
285
+ end
286
+
287
+ def destroy_inapplicable_adjustments
288
+ destroyed = adjustments.reject(&:applicable?).map(&:destroy)
289
+ adjustments.reload if destroyed.any?
290
+ end
291
+
292
+ def name
293
+ if (address = bill_address || ship_address)
294
+ "#{address.firstname} #{address.lastname}"
295
+ end
296
+ end
297
+
298
+ def creditcards
299
+ creditcard_ids = payments.from_creditcard.map(&:source_id).uniq
300
+ Creditcard.scoped(:conditions => {:id => creditcard_ids})
301
+ end
302
+
303
+ def process_payments!
304
+ ret = payments.each(&:process!)
305
+ end
306
+
307
+ # Finalizes an in progress order after checkout is complete.
308
+ # Called after transition to complete state when payments will have been processed
309
+ def finalize!
310
+ update_attribute(:completed_at, Time.now)
311
+ self.out_of_stock_items = InventoryUnit.assign_opening_inventory(self)
312
+ # lock any optional adjustments (coupon promotions, etc.)
313
+ adjustments.optional.each { |adjustment| adjustment.update_attribute("locked", true) }
314
+ OrderMailer.confirm_email(self).deliver
315
+
316
+ self.state_events.create({
317
+ :previous_state => "cart",
318
+ :next_state => "complete",
319
+ :name => "order" ,
320
+ :user_id => (User.respond_to?(:current) && User.current.try(:id)) || self.user_id
321
+ })
322
+ end
323
+
324
+
325
+ # Helper methods for checkout steps
326
+
327
+ def available_shipping_methods(display_on = nil)
328
+ return [] unless ship_address
329
+ ShippingMethod.all_available(self, display_on)
330
+ end
331
+
332
+ def rate_hash
333
+ @rate_hash ||= available_shipping_methods(:front_end).collect do |ship_method|
334
+ next unless cost = ship_method.calculator.compute(self)
335
+ { :id => ship_method.id,
336
+ :shipping_method => ship_method,
337
+ :name => ship_method.name,
338
+ :cost => cost
339
+ }
340
+ end.compact.sort_by{|r| r[:cost]}
341
+ end
342
+
343
+ def payment
344
+ payments.first
345
+ end
346
+
347
+ def available_payment_methods
348
+ @available_payment_methods ||= PaymentMethod.available(:front_end)
349
+ end
350
+
351
+ def payment_method
352
+ if payment and payment.payment_method
353
+ payment.payment_method
354
+ else
355
+ available_payment_methods.first
356
+ end
357
+ end
358
+
359
+ def billing_firstname
360
+ bill_address.try(:firstname)
361
+ end
362
+
363
+ def billing_lastname
364
+ bill_address.try(:lastname)
365
+ end
366
+
367
+ def products
368
+ line_items.map{|li| li.variant.product}
369
+ end
370
+
371
+ private
372
+ def create_user
373
+ self.email = user.email if self.user and not user.anonymous?
374
+ self.user ||= User.anonymous!
375
+ end
376
+
377
+ # Updates the +shipment_state+ attribute according to the following logic:
378
+ #
379
+ # shipped when all Shipments are in the "shipped" state
380
+ # partial when at least one Shipment has a state of "shipped" and there is another Shipment with a state other than "shipped"
381
+ # or there are InventoryUnits associated with the order that have a state of "sold" but are not associated with a Shipment.
382
+ # ready when all Shipments are in the "ready" state
383
+ # backorder when there is backordered inventory associated with an order
384
+ # pending when all Shipments are in the "pending" state
385
+ #
386
+ # The +shipment_state+ value helps with reporting, etc. since it provides a quick and easy way to locate Orders needing attention.
387
+ def update_shipment_state
388
+
389
+ self.shipment_state =
390
+ case shipments.count
391
+ when 0
392
+ nil
393
+ when shipments.shipped.count
394
+ "shipped"
395
+ when shipments.ready.count
396
+ "ready"
397
+ when shipments.pending.count
398
+ "pending"
399
+ else
400
+ "partial"
401
+ end
402
+ self.shipment_state = "backorder" if backordered?
403
+
404
+ if old_shipment_state = self.changed_attributes["shipment_state"]
405
+ self.state_events.create({
406
+ :previous_state => old_shipment_state,
407
+ :next_state => self.shipment_state,
408
+ :name => "shipment" ,
409
+ :user_id => (User.respond_to?(:current) && User.current && User.current.id) || self.user_id
410
+ })
411
+ end
412
+
413
+ end
414
+
415
+ # Updates the +payment_state+ attribute according to the following logic:
416
+ #
417
+ # paid when +payment_total+ is equal to +total+
418
+ # balance_due when +payment_total+ is less than +total+
419
+ # credit_owed when +payment_total+ is greater than +total+
420
+ # failed when most recent payment is in the failed state
421
+ #
422
+ # The +payment_state+ value helps with reporting, etc. since it provides a quick and easy way to locate Orders needing attention.
423
+ def update_payment_state
424
+ if payment_total < total
425
+ self.payment_state = "balance_due"
426
+ self.payment_state = "failed" if payments.present? and payments.last.state == "failed"
427
+ elsif payment_total > total
428
+ self.payment_state = "credit_owed"
429
+ else
430
+ self.payment_state = "paid"
431
+ end
432
+
433
+ if old_payment_state = self.changed_attributes["payment_state"]
434
+ self.state_events.create({
435
+ :previous_state => old_payment_state,
436
+ :next_state => self.payment_state,
437
+ :name => "payment" ,
438
+ :user_id => (User.respond_to?(:current) && User.current && User.current.id) || self.user_id
439
+ })
440
+ end
441
+ end
442
+
443
+ # Updates the following Order total values:
444
+ #
445
+ # +payment_total+ The total value of all finalized Payments (NOTE: non-finalized Payments are excluded)
446
+ # +item_total+ The total value of all LineItems
447
+ # +adjustment_total+ The total value of all adjustments (promotions, credits, etc.)
448
+ # +total+ The so-called "order total." This is equivalent to +item_total+ plus +adjustment_total+.
449
+ def update_totals
450
+ # update_adjustments
451
+ self.payment_total = payments.completed.map(&:amount).sum
452
+ self.item_total = line_items.map(&:amount).sum
453
+ self.adjustment_total = adjustments.map(&:amount).sum
454
+ self.total = item_total + adjustment_total
455
+ end
456
+
457
+ # Updates each of the Order adjustments. This is intended to be called from an Observer so that the Order can
458
+ # respond to external changes to LineItem, Shipment, other Adjustments, etc. Adjustments that are no longer
459
+ # applicable will be removed from the association and destroyed.
460
+ def update_adjustments
461
+ # separate into adjustments to keep and adjustements to toss
462
+ obsolete_adjustments = adjustments.select{|adjustment| !adjustment.applicable?}
463
+ obsolete_adjustments.each(&:destroy)
464
+ self.adjustments.reload.each(&:update!)
465
+ end
466
+
467
+ # Determine if email is required (we don't want validation errors before we hit the checkout)
468
+ def require_email
469
+ return true unless new_record? or state == 'cart'
470
+ end
471
+
472
+ def has_available_shipment
473
+ return unless :address == state_name.to_sym
474
+ return unless ship_address && ship_address.valid?
475
+ errors.add(:base, :no_shipping_methods_available) if available_shipping_methods.empty?
476
+ end
477
+
478
+ def after_cancel
479
+ # TODO: make_shipments_pending
480
+ # TODO: restock_inventory
481
+ OrderMailer.cancel_email(self).deliver
482
+ end
483
+
484
+ end