gemgento 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (429) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +8 -0
  5. data/README.md +9 -0
  6. data/Rakefile +21 -0
  7. data/app/adapters/gemgento/magento/address_adapter.rb +37 -0
  8. data/app/adapters/gemgento/magento/customer_adapter.rb +24 -0
  9. data/app/adapters/gemgento/magento/line_item_adapter.rb +41 -0
  10. data/app/adapters/gemgento/magento/order_adapter.rb +97 -0
  11. data/app/adapters/gemgento/magento/order_status_adapter.rb +24 -0
  12. data/app/adapters/gemgento/magento/payment_adapter.rb +38 -0
  13. data/app/adapters/gemgento/magento/product_adapater.rb +24 -0
  14. data/app/adapters/gemgento/magento/quote_adapter.rb +17 -0
  15. data/app/adapters/gemgento/magento/shipment_adapter.rb +74 -0
  16. data/app/adapters/gemgento/magento/shipment_item_adapter.rb +39 -0
  17. data/app/adapters/gemgento/magento/shipment_track_adapter.rb +31 -0
  18. data/app/adapters/gemgento/magento_adapter.rb +17 -0
  19. data/app/assets/fonts/FuturaStd-Bold.otf +0 -0
  20. data/app/assets/fonts/FuturaStd-Book.otf +0 -0
  21. data/app/assets/fonts/FuturaStd-Light.otf +0 -0
  22. data/app/assets/fonts/FuturaStd-Medium.otf +0 -0
  23. data/app/assets/fonts/Verlag-Black.otf +0 -0
  24. data/app/assets/fonts/Verlag-BlackItalic.otf +0 -0
  25. data/app/assets/fonts/Verlag-Bold.otf +0 -0
  26. data/app/assets/fonts/Verlag-BoldItalic.otf +0 -0
  27. data/app/assets/fonts/Verlag-Book.otf +0 -0
  28. data/app/assets/fonts/Verlag-BookItalic-2.otf +0 -0
  29. data/app/assets/fonts/Verlag-BookItalic-3.otf +0 -0
  30. data/app/assets/fonts/Verlag-BookItalic.otf +0 -0
  31. data/app/assets/fonts/Verlag-Light.otf +0 -0
  32. data/app/assets/fonts/Verlag-LightItalic.otf +0 -0
  33. data/app/assets/fonts/Verlag-XLight.otf +0 -0
  34. data/app/assets/fonts/Verlag-XLightItalic.otf +0 -0
  35. data/app/assets/images/about_store.jpg +0 -0
  36. data/app/assets/images/gemgento-icon-bolt.png +0 -0
  37. data/app/assets/javascripts/gemgento/active_admin.js.coffee +42 -0
  38. data/app/assets/javascripts/gemgento/checkout/address.coffee +23 -0
  39. data/app/assets/javascripts/gemgento/gemgento.js +1 -0
  40. data/app/assets/javascripts/gemgento/global.js.coffee +31 -0
  41. data/app/assets/stylesheets/gemgento/active_admin.css.scss +549 -0
  42. data/app/assets/stylesheets/gemgento/default-views/_address.scss +11 -0
  43. data/app/assets/stylesheets/gemgento/default-views/_category.scss +54 -0
  44. data/app/assets/stylesheets/gemgento/default-views/_checkout.scss +28 -0
  45. data/app/assets/stylesheets/gemgento/default-views/_footer.scss +13 -0
  46. data/app/assets/stylesheets/gemgento/default-views/_form.scss +127 -0
  47. data/app/assets/stylesheets/gemgento/default-views/_header.scss +32 -0
  48. data/app/assets/stylesheets/gemgento/default-views/_layout.css.scss +157 -0
  49. data/app/assets/stylesheets/gemgento/default-views/_pages.css.scss +83 -0
  50. data/app/assets/stylesheets/gemgento/default-views/_product.scss +57 -0
  51. data/app/assets/stylesheets/gemgento/default-views/_shopping_bag.scss +87 -0
  52. data/app/assets/stylesheets/gemgento/default-views/_subheader.css.scss +30 -0
  53. data/app/assets/stylesheets/gemgento/default-views/application.css.scss +1 -0
  54. data/app/controllers/concerns/gemgento/api/v1/base.rb +15 -0
  55. data/app/controllers/concerns/gemgento/api/v1/product_filters.rb +33 -0
  56. data/app/controllers/gemgento/addresses_controller.rb +14 -0
  57. data/app/controllers/gemgento/api/v1/categories_controller.rb +13 -0
  58. data/app/controllers/gemgento/api/v1/products_controller.rb +23 -0
  59. data/app/controllers/gemgento/api/v1/search_controller.rb +14 -0
  60. data/app/controllers/gemgento/application_controller.rb +5 -0
  61. data/app/controllers/gemgento/cart_controller.rb +99 -0
  62. data/app/controllers/gemgento/categories_controller.rb +37 -0
  63. data/app/controllers/gemgento/checkout/address_controller.rb +48 -0
  64. data/app/controllers/gemgento/checkout/confirm_controller.rb +72 -0
  65. data/app/controllers/gemgento/checkout/coupons_controller.rb +42 -0
  66. data/app/controllers/gemgento/checkout/gift_card_controller.rb +39 -0
  67. data/app/controllers/gemgento/checkout/gift_controller.rb +32 -0
  68. data/app/controllers/gemgento/checkout/login_controller.rb +123 -0
  69. data/app/controllers/gemgento/checkout/payment_controller.rb +70 -0
  70. data/app/controllers/gemgento/checkout/paypal_controller.rb +23 -0
  71. data/app/controllers/gemgento/checkout/shipping_controller.rb +46 -0
  72. data/app/controllers/gemgento/checkout/shipping_payment_controller.rb +58 -0
  73. data/app/controllers/gemgento/checkout/thank_you_controller.rb +45 -0
  74. data/app/controllers/gemgento/checkout_controller.rb +120 -0
  75. data/app/controllers/gemgento/countries_controller.rb +17 -0
  76. data/app/controllers/gemgento/errors_controller.rb +7 -0
  77. data/app/controllers/gemgento/footer_items_controller.rb +16 -0
  78. data/app/controllers/gemgento/home_controller.rb +7 -0
  79. data/app/controllers/gemgento/magento/addresses_controller.rb +61 -0
  80. data/app/controllers/gemgento/magento/base_controller.rb +18 -0
  81. data/app/controllers/gemgento/magento/categories_controller.rb +103 -0
  82. data/app/controllers/gemgento/magento/email/sales/credit_memos_controller.rb +21 -0
  83. data/app/controllers/gemgento/magento/email/sales/invoices_controller.rb +21 -0
  84. data/app/controllers/gemgento/magento/email/sales/orders_controller.rb +20 -0
  85. data/app/controllers/gemgento/magento/email/sales/shipments_controller.rb +25 -0
  86. data/app/controllers/gemgento/magento/emails_controller.rb +11 -0
  87. data/app/controllers/gemgento/magento/inventory_controller.rb +30 -0
  88. data/app/controllers/gemgento/magento/orders_controller.rb +12 -0
  89. data/app/controllers/gemgento/magento/price_rules_controller.rb +22 -0
  90. data/app/controllers/gemgento/magento/product_attribute_sets_controller.rb +37 -0
  91. data/app/controllers/gemgento/magento/product_attributes_controller.rb +70 -0
  92. data/app/controllers/gemgento/magento/products_controller.rb +240 -0
  93. data/app/controllers/gemgento/magento/recurring_profiles_controller.rb +42 -0
  94. data/app/controllers/gemgento/magento/stores_controller.rb +21 -0
  95. data/app/controllers/gemgento/magento/user_groups_controller.rb +23 -0
  96. data/app/controllers/gemgento/magento/users_controller.rb +63 -0
  97. data/app/controllers/gemgento/order_export_controller.rb +21 -0
  98. data/app/controllers/gemgento/orders_controller.rb +12 -0
  99. data/app/controllers/gemgento/products_controller.rb +12 -0
  100. data/app/controllers/gemgento/regions_controller.rb +18 -0
  101. data/app/controllers/gemgento/search_controller.rb +16 -0
  102. data/app/controllers/gemgento/shipments_controller.rb +5 -0
  103. data/app/controllers/gemgento/stock_notifications_controller.rb +22 -0
  104. data/app/controllers/gemgento/subscribers_controller.rb +35 -0
  105. data/app/controllers/gemgento/sync_controller.rb +50 -0
  106. data/app/controllers/gemgento/user/addresses_controller.rb +79 -0
  107. data/app/controllers/gemgento/user/base_controller.rb +14 -0
  108. data/app/controllers/gemgento/user/home_controller.rb +9 -0
  109. data/app/controllers/gemgento/user/orders_controller.rb +17 -0
  110. data/app/controllers/gemgento/user/passwords_controller.rb +18 -0
  111. data/app/controllers/gemgento/user/recurring_profiles_controller.rb +31 -0
  112. data/app/controllers/gemgento/user/registration_session_controller.rb +103 -0
  113. data/app/controllers/gemgento/user/registrations_controller.rb +28 -0
  114. data/app/controllers/gemgento/user/saved_credit_cards_controller.rb +56 -0
  115. data/app/controllers/gemgento/user/sessions_controller.rb +50 -0
  116. data/app/controllers/gemgento/user/wishlist_items_controller.rb +55 -0
  117. data/app/controllers/gemgento/users_controller.rb +36 -0
  118. data/app/helpers/gemgento/application_helper.rb +125 -0
  119. data/app/helpers/gemgento/categories_helper.rb +39 -0
  120. data/app/helpers/gemgento/checkout/payment_helper.rb +5 -0
  121. data/app/helpers/gemgento/products_helper.rb +23 -0
  122. data/app/jobs/gemgento/import_job.rb +12 -0
  123. data/app/mailers/gemgento/sales_mailer.rb +80 -0
  124. data/app/models/admin_user.rb +7 -0
  125. data/app/models/concerns/gemgento/product_touches.rb +26 -0
  126. data/app/models/gemgento.rb +5 -0
  127. data/app/models/gemgento/adapter/sellect/customer.rb +34 -0
  128. data/app/models/gemgento/adapter/sellect/order.rb +378 -0
  129. data/app/models/gemgento/adapter/sellect/product.rb +250 -0
  130. data/app/models/gemgento/adapter/sellect_adapter.rb +16 -0
  131. data/app/models/gemgento/adapter/shopify/address.rb +40 -0
  132. data/app/models/gemgento/adapter/shopify/category.rb +51 -0
  133. data/app/models/gemgento/adapter/shopify/customer.rb +66 -0
  134. data/app/models/gemgento/adapter/shopify/order.rb +334 -0
  135. data/app/models/gemgento/adapter/shopify/product.rb +377 -0
  136. data/app/models/gemgento/adapter/shopify/product_category_position.rb +58 -0
  137. data/app/models/gemgento/adapter/shopify_adapter.rb +63 -0
  138. data/app/models/gemgento/address.rb +206 -0
  139. data/app/models/gemgento/api_job.rb +68 -0
  140. data/app/models/gemgento/asset.rb +185 -0
  141. data/app/models/gemgento/asset_file.rb +57 -0
  142. data/app/models/gemgento/asset_type.rb +8 -0
  143. data/app/models/gemgento/bundle.rb +5 -0
  144. data/app/models/gemgento/bundle/item.rb +17 -0
  145. data/app/models/gemgento/bundle/option.rb +20 -0
  146. data/app/models/gemgento/category.rb +235 -0
  147. data/app/models/gemgento/country.rb +21 -0
  148. data/app/models/gemgento/gift_message.rb +8 -0
  149. data/app/models/gemgento/image_import.rb +141 -0
  150. data/app/models/gemgento/import.rb +125 -0
  151. data/app/models/gemgento/inventory.rb +60 -0
  152. data/app/models/gemgento/inventory_import.rb +51 -0
  153. data/app/models/gemgento/line_item.rb +142 -0
  154. data/app/models/gemgento/line_item_option.rb +10 -0
  155. data/app/models/gemgento/magento_db.rb +35 -0
  156. data/app/models/gemgento/magento_response.rb +10 -0
  157. data/app/models/gemgento/order.rb +56 -0
  158. data/app/models/gemgento/order_status.rb +7 -0
  159. data/app/models/gemgento/payment.rb +50 -0
  160. data/app/models/gemgento/price_rule.rb +258 -0
  161. data/app/models/gemgento/price_tier.rb +36 -0
  162. data/app/models/gemgento/product.rb +607 -0
  163. data/app/models/gemgento/product_attribute.rb +48 -0
  164. data/app/models/gemgento/product_attribute_option.rb +39 -0
  165. data/app/models/gemgento/product_attribute_set.rb +22 -0
  166. data/app/models/gemgento/product_attribute_value.rb +26 -0
  167. data/app/models/gemgento/product_category.rb +34 -0
  168. data/app/models/gemgento/product_import.rb +359 -0
  169. data/app/models/gemgento/quote.rb +586 -0
  170. data/app/models/gemgento/recurring_profile.rb +28 -0
  171. data/app/models/gemgento/region.rb +14 -0
  172. data/app/models/gemgento/relation.rb +10 -0
  173. data/app/models/gemgento/relation_type.rb +7 -0
  174. data/app/models/gemgento/saved_credit_card.rb +45 -0
  175. data/app/models/gemgento/search.rb +14 -0
  176. data/app/models/gemgento/session.rb +49 -0
  177. data/app/models/gemgento/shipment.rb +38 -0
  178. data/app/models/gemgento/shipment_comment.rb +19 -0
  179. data/app/models/gemgento/shipment_item.rb +11 -0
  180. data/app/models/gemgento/shipment_track.rb +21 -0
  181. data/app/models/gemgento/stock_notification.rb +17 -0
  182. data/app/models/gemgento/store.rb +31 -0
  183. data/app/models/gemgento/store_tag.rb +8 -0
  184. data/app/models/gemgento/subscriber.rb +30 -0
  185. data/app/models/gemgento/swatch.rb +9 -0
  186. data/app/models/gemgento/sync.rb +134 -0
  187. data/app/models/gemgento/tag.rb +64 -0
  188. data/app/models/gemgento/user.rb +161 -0
  189. data/app/models/gemgento/user_group.rb +13 -0
  190. data/app/models/gemgento/wishlist_item.rb +11 -0
  191. data/app/services/gemgento/magento_api.rb +173 -0
  192. data/app/services/gemgento/price.rb +67 -0
  193. data/app/validators/gemgento/credit_card_validator.rb +50 -0
  194. data/app/validators/gemgento/image_import_validator.rb +100 -0
  195. data/app/validators/gemgento/inventory_import_validator.rb +73 -0
  196. data/app/validators/gemgento/inventory_validator.rb +14 -0
  197. data/app/validators/gemgento/product_import_validator.rb +163 -0
  198. data/app/views/admin/product_positions/_index.html.haml +14 -0
  199. data/app/views/devise/registrations/edit.haml +37 -0
  200. data/app/views/gemgento/addresses/_address.json.jbuilder +6 -0
  201. data/app/views/gemgento/addresses/region_options.html.haml +1 -0
  202. data/app/views/gemgento/api/v1/categories/_category.json.jbuilder +52 -0
  203. data/app/views/gemgento/api/v1/categories/index.json.jbuilder +8 -0
  204. data/app/views/gemgento/api/v1/categories/show.json.jbuilder +7 -0
  205. data/app/views/gemgento/api/v1/products/_attributes.json.jbuilder +9 -0
  206. data/app/views/gemgento/api/v1/products/_product.json.jbuilder +18 -0
  207. data/app/views/gemgento/api/v1/products/_relationships.json.jbuilder +48 -0
  208. data/app/views/gemgento/api/v1/products/index.json.jbuilder +8 -0
  209. data/app/views/gemgento/api/v1/products/show.json.jbuilder +7 -0
  210. data/app/views/gemgento/api/v1/search/index.json.jbuilder +8 -0
  211. data/app/views/gemgento/api/v1/search/show.json.jbuilder +8 -0
  212. data/app/views/gemgento/assets/_asset.json.jbuilder +13 -0
  213. data/app/views/gemgento/cart/show.html.haml +67 -0
  214. data/app/views/gemgento/categories/_category.json.jbuilder +9 -0
  215. data/app/views/gemgento/categories/_product_tile.html.haml +16 -0
  216. data/app/views/gemgento/categories/index.html.haml +10 -0
  217. data/app/views/gemgento/categories/index.json.jbuilder +1 -0
  218. data/app/views/gemgento/categories/show.html.haml +16 -0
  219. data/app/views/gemgento/categories/show.json.jbuilder +1 -0
  220. data/app/views/gemgento/checkout/_checkout_header.html.haml +17 -0
  221. data/app/views/gemgento/checkout/address/error.js.erb +1 -0
  222. data/app/views/gemgento/checkout/address/show.html.haml +88 -0
  223. data/app/views/gemgento/checkout/address/success.js.erb +1 -0
  224. data/app/views/gemgento/checkout/confirm/error.js.erb +0 -0
  225. data/app/views/gemgento/checkout/confirm/show.html.haml +60 -0
  226. data/app/views/gemgento/checkout/confirm/success.js.erb +1 -0
  227. data/app/views/gemgento/checkout/login/login_fail.js.erb +1 -0
  228. data/app/views/gemgento/checkout/login/login_guest_fail.js.erb +1 -0
  229. data/app/views/gemgento/checkout/login/login_guest_success.js.erb +1 -0
  230. data/app/views/gemgento/checkout/login/login_success.js.erb +1 -0
  231. data/app/views/gemgento/checkout/login/registration_fail.js.erb +1 -0
  232. data/app/views/gemgento/checkout/login/registration_success.js.erb +1 -0
  233. data/app/views/gemgento/checkout/login/show.html.haml +50 -0
  234. data/app/views/gemgento/checkout/payment/error.js.erb +1 -0
  235. data/app/views/gemgento/checkout/payment/show.html.haml +56 -0
  236. data/app/views/gemgento/checkout/payment/success.js.erb +1 -0
  237. data/app/views/gemgento/checkout/shipping/error.js.erb +0 -0
  238. data/app/views/gemgento/checkout/shipping/show.html.haml +26 -0
  239. data/app/views/gemgento/checkout/shipping/success.js.erb +1 -0
  240. data/app/views/gemgento/checkout/shipping_payment/show.haml +52 -0
  241. data/app/views/gemgento/checkout/thank_you/show.html.haml +6 -0
  242. data/app/views/gemgento/countries/_country.json.jbuilder +4 -0
  243. data/app/views/gemgento/countries/index.json.jbuilder +3 -0
  244. data/app/views/gemgento/countries/show.json.jbuilder +1 -0
  245. data/app/views/gemgento/home/index.html.haml +1 -0
  246. data/app/views/gemgento/order/add_item.js.erb +0 -0
  247. data/app/views/gemgento/order/no_inventory.js.erb +1 -0
  248. data/app/views/gemgento/order/remove_item.js.erb +0 -0
  249. data/app/views/gemgento/order/update_item.js.erb +0 -0
  250. data/app/views/gemgento/order_export/index.html.haml +2 -0
  251. data/app/views/gemgento/order_items/_order_item.json.jbuilder +7 -0
  252. data/app/views/gemgento/orders/_order.json.jbuilder +29 -0
  253. data/app/views/gemgento/products/_product.json.jbuilder +40 -0
  254. data/app/views/gemgento/products/index.html.haml +19 -0
  255. data/app/views/gemgento/products/show.html.haml +67 -0
  256. data/app/views/gemgento/products/show.json.jbuilder +1 -0
  257. data/app/views/gemgento/sales_mailer/credit_memo_email.html.haml +1 -0
  258. data/app/views/gemgento/sales_mailer/invoice_email.html.haml +1 -0
  259. data/app/views/gemgento/sales_mailer/order_email.html.haml +1 -0
  260. data/app/views/gemgento/sales_mailer/shipment_email.html.haml +1 -0
  261. data/app/views/gemgento/search/index.html.haml +8 -0
  262. data/app/views/gemgento/shared/_asset.json.jbuilder +35 -0
  263. data/app/views/gemgento/shared/_asset_file.json.jbuilder +19 -0
  264. data/app/views/gemgento/shared/_asset_type.json.jbuilder +13 -0
  265. data/app/views/gemgento/shared/_error_messages.haml +7 -0
  266. data/app/views/gemgento/shared/_flash_messages.haml +4 -0
  267. data/app/views/gemgento/shared/_footer.haml +7 -0
  268. data/app/views/gemgento/shared/_header.haml +23 -0
  269. data/app/views/gemgento/shared/_mini_bag.haml +36 -0
  270. data/app/views/gemgento/shared/_product_image.haml +8 -0
  271. data/app/views/gemgento/shipments/_shipment.json.jbuilder +12 -0
  272. data/app/views/gemgento/subscribers/create.js.erb +2 -0
  273. data/app/views/gemgento/subscribers/errors.js.erb +1 -0
  274. data/app/views/gemgento/user/_user.json.jbuilder +2 -0
  275. data/app/views/gemgento/user/addresses/_form.haml +39 -0
  276. data/app/views/gemgento/user/addresses/errors.js.erb +1 -0
  277. data/app/views/gemgento/user/addresses/index.haml +33 -0
  278. data/app/views/gemgento/user/addresses/new.haml +11 -0
  279. data/app/views/gemgento/user/addresses/success.js.erb +1 -0
  280. data/app/views/gemgento/user/confirmations/new.haml +9 -0
  281. data/app/views/gemgento/user/home/index.haml +8 -0
  282. data/app/views/gemgento/user/mailer/confirmation_instructions.html.erb +5 -0
  283. data/app/views/gemgento/user/mailer/reset_password_instructions.html.erb +8 -0
  284. data/app/views/gemgento/user/mailer/unlock_instructions.html.erb +7 -0
  285. data/app/views/gemgento/user/orders/index.html.haml +29 -0
  286. data/app/views/gemgento/user/orders/show.html.haml +87 -0
  287. data/app/views/gemgento/user/passwords/edit.html.erb +18 -0
  288. data/app/views/gemgento/user/passwords/new.html.haml +21 -0
  289. data/app/views/gemgento/user/registration_session/new.haml +67 -0
  290. data/app/views/gemgento/user/registrations/new.html.haml +28 -0
  291. data/app/views/gemgento/user/saved_credit_cards/_form.haml +69 -0
  292. data/app/views/gemgento/user/saved_credit_cards/index.haml +25 -0
  293. data/app/views/gemgento/user/saved_credit_cards/new.haml +13 -0
  294. data/app/views/gemgento/user/sessions/new.html.haml +29 -0
  295. data/app/views/gemgento/user/shared/_links.erb +25 -0
  296. data/app/views/gemgento/user/shared/_user_header.haml +8 -0
  297. data/app/views/gemgento/user/wishlist_items/index.html.haml +20 -0
  298. data/app/views/kaminari/_first_page.html.haml +9 -0
  299. data/app/views/kaminari/_gap.html.haml +8 -0
  300. data/app/views/kaminari/_last_page.html.haml +9 -0
  301. data/app/views/kaminari/_next_page.html.haml +9 -0
  302. data/app/views/kaminari/_page.html.haml +10 -0
  303. data/app/views/kaminari/_paginator.html.haml +18 -0
  304. data/app/views/kaminari/_prev_page.html.haml +9 -0
  305. data/app/views/layouts/_footer.html.haml +5 -0
  306. data/app/views/layouts/_header.html.haml +39 -0
  307. data/app/views/layouts/gemgento.html.haml +22 -0
  308. data/app/workers/gemgento/apply_price_rule.rb +24 -0
  309. data/app/workers/gemgento/cart/add_item_worker.rb +23 -0
  310. data/app/workers/gemgento/cart/update_item_worker.rb +18 -0
  311. data/bin/rails +12 -0
  312. data/config/gemgento_config.yml +12 -0
  313. data/config/initializers/active_admin.rb +14 -0
  314. data/config/initializers/active_touch.rb +3 -0
  315. data/config/initializers/assets.rb +1 -0
  316. data/config/initializers/boolean_typecasting.rb +37 -0
  317. data/config/initializers/devise.rb +49 -0
  318. data/config/initializers/gemgento_config.rb +67 -0
  319. data/config/initializers/mime_types.rb +4 -0
  320. data/config/initializers/state_machine.rb +7 -0
  321. data/config/locales/en.yml +24 -0
  322. data/config/routes.rb +138 -0
  323. data/db/migrate/20151201231300_add_validation_indexes_to_gemgento_products.rb +22 -0
  324. data/db/migrate/20160122174450_gemgento2.rb +969 -0
  325. data/db/migrate/20160217142910_create_gemgento_imports.rb +15 -0
  326. data/db/migrate/20160219235858_add_timestamps_to_gemgento_asset_files.rb +6 -0
  327. data/gemgento.gemspec +44 -0
  328. data/lib/devise/models/validatable.rb +76 -0
  329. data/lib/gemgento.rb +24 -0
  330. data/lib/gemgento/admin/admin_user.rb +29 -0
  331. data/lib/gemgento/admin/api_jobs.rb +30 -0
  332. data/lib/gemgento/admin/image_import.rb +87 -0
  333. data/lib/gemgento/admin/inventory_import.rb +81 -0
  334. data/lib/gemgento/admin/product_import.rb +138 -0
  335. data/lib/gemgento/admin/product_positions.rb +49 -0
  336. data/lib/gemgento/admin/stores.rb +33 -0
  337. data/lib/gemgento/admin/subscribers.rb +31 -0
  338. data/lib/gemgento/admin/syncs.rb +26 -0
  339. data/lib/gemgento/api/soap/authnetcim/payment.rb +127 -0
  340. data/lib/gemgento/api/soap/catalog/category.rb +237 -0
  341. data/lib/gemgento/api/soap/catalog/product.rb +481 -0
  342. data/lib/gemgento/api/soap/catalog/product_attribute.rb +147 -0
  343. data/lib/gemgento/api/soap/catalog/product_attribute_media.rb +202 -0
  344. data/lib/gemgento/api/soap/catalog/product_attribute_set.rb +80 -0
  345. data/lib/gemgento/api/soap/catalog/product_tag.rb +146 -0
  346. data/lib/gemgento/api/soap/catalog/product_tier_price.rb +21 -0
  347. data/lib/gemgento/api/soap/catalog/search.rb +27 -0
  348. data/lib/gemgento/api/soap/catalog_inventory/stock_item.rb +87 -0
  349. data/lib/gemgento/api/soap/catalog_rule/rule.rb +54 -0
  350. data/lib/gemgento/api/soap/checkout/cart.rb +85 -0
  351. data/lib/gemgento/api/soap/checkout/coupon.rb +37 -0
  352. data/lib/gemgento/api/soap/checkout/customer.rb +87 -0
  353. data/lib/gemgento/api/soap/checkout/payment.rb +59 -0
  354. data/lib/gemgento/api/soap/checkout/product.rb +138 -0
  355. data/lib/gemgento/api/soap/checkout/shipping.rb +37 -0
  356. data/lib/gemgento/api/soap/customer/address.rb +143 -0
  357. data/lib/gemgento/api/soap/customer/customer.rb +200 -0
  358. data/lib/gemgento/api/soap/directory/country.rb +49 -0
  359. data/lib/gemgento/api/soap/directory/region.rb +50 -0
  360. data/lib/gemgento/api/soap/enterprise_gift_message/gift_message.rb +26 -0
  361. data/lib/gemgento/api/soap/gift_card.rb +35 -0
  362. data/lib/gemgento/api/soap/globalcollect/saved_cc.rb +58 -0
  363. data/lib/gemgento/api/soap/miscellaneous/store.rb +47 -0
  364. data/lib/gemgento/api/soap/sales/order.rb +249 -0
  365. data/lib/gemgento/api/soap/sales/order_shipment.rb +122 -0
  366. data/lib/gemgento/api/soap/sales/recurring_profile.rb +88 -0
  367. data/lib/gemgento/api/soap/stock_notification.rb +27 -0
  368. data/lib/gemgento/engine.rb +61 -0
  369. data/lib/gemgento/version.rb +3 -0
  370. data/lib/generators/gemgento/assets_generator.rb +11 -0
  371. data/lib/generators/gemgento/install_generator.rb +34 -0
  372. data/lib/generators/gemgento/templates/active_admin.css.scss +1 -0
  373. data/lib/generators/gemgento/templates/active_admin.js.coffee +1 -0
  374. data/lib/generators/gemgento/templates/active_admin.rb +3 -0
  375. data/lib/generators/gemgento/views_generator.rb +10 -0
  376. data/spec/dummy/README.rdoc +28 -0
  377. data/spec/dummy/Rakefile +6 -0
  378. data/spec/dummy/app/assets/images/.keep +0 -0
  379. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  380. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  381. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  382. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  383. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  384. data/spec/dummy/app/mailers/.keep +0 -0
  385. data/spec/dummy/app/models/.keep +0 -0
  386. data/spec/dummy/app/models/concerns/.keep +0 -0
  387. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  388. data/spec/dummy/bin/bundle +3 -0
  389. data/spec/dummy/bin/rails +4 -0
  390. data/spec/dummy/bin/rake +4 -0
  391. data/spec/dummy/bin/setup +29 -0
  392. data/spec/dummy/config.ru +4 -0
  393. data/spec/dummy/config/application.rb +32 -0
  394. data/spec/dummy/config/boot.rb +5 -0
  395. data/spec/dummy/config/database.yml +20 -0
  396. data/spec/dummy/config/environment.rb +5 -0
  397. data/spec/dummy/config/environments/development.rb +41 -0
  398. data/spec/dummy/config/environments/production.rb +79 -0
  399. data/spec/dummy/config/environments/test.rb +42 -0
  400. data/spec/dummy/config/gemgento_config.yml +22 -0
  401. data/spec/dummy/config/initializers/assets.rb +11 -0
  402. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  403. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  404. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  405. data/spec/dummy/config/initializers/inflections.rb +16 -0
  406. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  407. data/spec/dummy/config/initializers/session_store.rb +3 -0
  408. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  409. data/spec/dummy/config/locales/en.yml +23 -0
  410. data/spec/dummy/config/routes.rb +4 -0
  411. data/spec/dummy/config/secrets.yml +22 -0
  412. data/spec/dummy/lib/assets/.keep +0 -0
  413. data/spec/dummy/public/404.html +67 -0
  414. data/spec/dummy/public/422.html +67 -0
  415. data/spec/dummy/public/500.html +66 -0
  416. data/spec/dummy/public/favicon.ico +0 -0
  417. data/spec/factories/gemgento/price_tiers.rb +8 -0
  418. data/spec/factories/gemgento/product_attribute_sets.rb +22 -0
  419. data/spec/factories/gemgento/product_attributes.rb +5 -0
  420. data/spec/factories/gemgento/products.rb +14 -0
  421. data/spec/factories/gemgento/stores.rb +12 -0
  422. data/spec/factories/gemgento/user_groups.rb +6 -0
  423. data/spec/factories/gemgento/users.rb +13 -0
  424. data/spec/factories/gemgento_imports.rb +12 -0
  425. data/spec/model/gemgento/price_tier_spec.rb +45 -0
  426. data/spec/rails_helper.rb +55 -0
  427. data/spec/services/gemgento/price_spec.rb +152 -0
  428. data/spec/spec_helper.rb +87 -0
  429. metadata +919 -0
@@ -0,0 +1,57 @@
1
+ module Gemgento
2
+
3
+ # @author Gemgento LLC
4
+ class AssetFile < ActiveRecord::Base
5
+ has_many :assets
6
+ has_many :products, through: :assets
7
+ has_many :stores, through: :assets
8
+
9
+ has_attached_file :file, styles: { thumb: "200x", thumb_2x: "400x",
10
+ small: "400x", small_2x: "800x",
11
+ medium: "800x", medium_2x: "1600x",
12
+ large: "1600x", large_2x: "3200x"}
13
+
14
+ validates_attachment_content_type :file, content_type: /\Aimage\/.*\Z/
15
+
16
+ touch :assets, after_touch: :after_touch
17
+
18
+ # Check that a url is valid. Assumes url is pointing to Magento installation.
19
+ #
20
+ # @param url [String]
21
+ # @return [Boolean]
22
+ def self.valid_url(url)
23
+ uri = URI.parse(url)
24
+ req = Net::HTTP::Get.new(uri)
25
+
26
+ unless Gemgento::Config[:magento][:auth_username].blank?
27
+ req.basic_auth Gemgento::Config[:magento][:auth_username], Gemgento::Config[:magento][:auth_password]
28
+ end
29
+
30
+ http = Net::HTTP.new(uri.hostname, uri.port)
31
+ http.use_ssl = uri.port == 443
32
+ res = http.start do |http|
33
+ http.use_ssl = uri.port == 443
34
+ http.request(req)
35
+ end
36
+
37
+ return res.code == '200'
38
+ end
39
+
40
+ # Get file from Magento.
41
+ #
42
+ # @param url [String]
43
+ # @return [TempFile]
44
+ def self.from_url(url)
45
+ if Gemgento::Config[:magento][:auth_username].blank?
46
+ open(url)
47
+ else
48
+ open(url, http_basic_authentication: [
49
+ Gemgento::Config[:magento][:auth_username],
50
+ Gemgento::Config[:magento][:auth_password]
51
+ ]
52
+ )
53
+ end
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,8 @@
1
+ module Gemgento
2
+
3
+ # @author Gemgento LLC
4
+ class AssetType < ActiveRecord::Base
5
+ belongs_to :product_attribute_set, class_name: 'Gemgento::ProductAttributeSet'
6
+ has_and_belongs_to_many :assets, join_table: 'gemgento_assets_asset_types'
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module Gemgento::Bundle
2
+ def self.table_name_prefix
3
+ 'gemgento_bundle_'
4
+ end
5
+ end
@@ -0,0 +1,17 @@
1
+ module Gemgento
2
+ module Bundle
3
+
4
+ # @author Gemgento LLC
5
+ class Item < ActiveRecord::Base
6
+ enum price_type: { fixed: 0, percent: 1 }
7
+
8
+ belongs_to :option, class_name: 'Gemgento::Bundle::Option', foreign_key: :bundle_option_id
9
+ belongs_to :product, class_name: 'Gemgento::Product'
10
+
11
+ touch :option, after_touch: :after_touch
12
+
13
+ validates :option, :product, presence: true
14
+ validates :product, uniqueness: { scope: :product }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ module Gemgento
2
+ module Bundle
3
+
4
+ # @author Gemgento LLC
5
+ class Option < ActiveRecord::Base
6
+ include Gemgento::ProductTouches
7
+
8
+ enum input_type: { selection: 0, radio: 1, checkbox: 2, multi: 3 }
9
+
10
+ belongs_to :product, class_name: 'Gemgento::Product'
11
+
12
+ has_many :items, class_name: 'Gemgento::Bundle::Item', dependent: :destroy, foreign_key: :bundle_option_id
13
+ has_many :products, through: :items, class_name: 'Gemgento::Product'
14
+
15
+ validates :product, presence: true
16
+
17
+ default_scope -> { order :position }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,235 @@
1
+ module Gemgento
2
+
3
+ # @author Gemgento LLC
4
+ class Category < ActiveRecord::Base
5
+ has_many :product_categories, class_name: '::Gemgento::ProductCategory', dependent: :destroy
6
+ has_many :products, -> { distinct }, through: :product_categories
7
+ has_many :children, foreign_key: 'parent_id', class_name: '::Gemgento::Category'
8
+
9
+ has_one :shopify_adapter, class_name: 'Adapter::ShopifyAdapter', as: :gemgento_model
10
+
11
+ belongs_to :parent, foreign_key: 'parent_id', class_name: '::Gemgento::Category'
12
+
13
+ has_and_belongs_to_many :stores, -> { distinct }, join_table: 'gemgento_categories_stores', class_name: 'Store'
14
+
15
+ touch :parent, after_touch: :after_touch
16
+
17
+ has_attached_file :image
18
+
19
+ default_scope -> { where(deleted_at: nil).order(:position) }
20
+
21
+ scope :top_level, -> { where(parent: Gemgento::Category.find_by(parent_id: nil), is_active: true) }
22
+ scope :bottom_level, -> { where(is_active: true).where.not(id: Gemgento::Category.all.pluck(:parent_id).uniq.compact) }
23
+ scope :navigation, -> { where(include_in_menu: true) }
24
+ scope :root, -> { find_by(parent_id: nil) }
25
+ scope :active, -> { where(is_active: true) }
26
+
27
+ validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
28
+
29
+ after_save :enforce_positioning, if: :position_changed?
30
+
31
+ before_save :create_magento_category, if: Proc.new { |category| category.sync_needed? && category.magento_id.nil? }
32
+ before_save :update_magento_category, if: Proc.new { |category| category.sync_needed? && !category.magento_id.nil? }
33
+
34
+ attr_accessor :sync_needed
35
+
36
+ # Create a string representation of the path from the root to the Category.
37
+ #
38
+ # @return [String]
39
+ def tree_path
40
+ root = Category.root
41
+ parent = self.parent
42
+ path = self.name
43
+
44
+ while !parent.nil? && parent != root do
45
+ path = "#{parent.name} > #{path}"
46
+ parent = parent.parent
47
+ end
48
+
49
+ return path
50
+ end
51
+
52
+ def sync_needed?
53
+ self.sync_needed.to_bool
54
+ end
55
+
56
+ # Create an options array for use in an HTML select input. Categories are grouped under top level scoped
57
+ # categories.
58
+ #
59
+ # @return [Array(String, Array(Array(String, Integer)))]
60
+ def self.grouped_options
61
+ options = []
62
+
63
+ Gemgento::Category.top_level.each do |parent|
64
+
65
+ child_options = [["#{parent.name} (parent)", parent.id]]
66
+
67
+ parent.children.where(is_active: true, parent: parent).each do |child|
68
+ child_options << [child.name, child.id]
69
+ child_options << grouped_option(child) if child.children.where(is_active: true).any?
70
+ end
71
+
72
+ options << [parent.name, child_options]
73
+ end
74
+
75
+ return options
76
+ end
77
+
78
+ def descendents
79
+ @descendents ||= begin
80
+ children.includes(:children).map do |child|
81
+ [child] + child.descendents
82
+ end.flatten
83
+ end
84
+ end
85
+
86
+ # Ordered list from root to self, excluding self.
87
+ #
88
+ # @return [Array(Gemgento::Category)]
89
+ def hierarchy
90
+ parents = []
91
+ parent = self.parent
92
+
93
+ while parent && !parent.parent_id.nil?
94
+ parents << parent
95
+ parent = parent.parent
96
+ end
97
+
98
+ return parents.reverse
99
+ end
100
+
101
+ # Get the option value and any subsequent child values as a path.
102
+ #
103
+ # @param category [Gemgento::Category]
104
+ # @return [Array(String, Integer)]
105
+ def self.grouped_option(category)
106
+ options = []
107
+
108
+ category.children.where(is_active: true, parent: category).each do |child|
109
+ options << [child.name, child.id]
110
+
111
+ child.children.where(is_active: true).each do |nested_child|
112
+ path = nested_child.tree_path
113
+ path = path.slice((path.index("> #{child.name} >") + 2)..-1)
114
+ options << [path, nested_child.id]
115
+ end
116
+ end
117
+
118
+ return options
119
+ end
120
+
121
+ # Sets the deleted_at to the current timestamp.
122
+ #
123
+ # @return [void]
124
+ def mark_deleted
125
+ self.deleted_at = Time.now
126
+ self.shopify_adapter.destroy if self.shopify_adapter
127
+ end
128
+
129
+ # Marks the category as deleted and saves.
130
+ #
131
+ # @return [void]
132
+ def mark_deleted!
133
+ mark_deleted
134
+ self.save
135
+ end
136
+
137
+ # Increment the position on all categories that come after. Used to ensure correct positioning after changing the
138
+ # position of a single category.
139
+ #
140
+ # @return [void]
141
+ def enforce_positioning
142
+ Category.skip_callback(:save, :after, :enforce_positioning)
143
+
144
+ last_position = self.position
145
+ categories = Category.where('parent_id = ? AND position >= ? AND id != ?', self.parent_id, self.position, self.id)
146
+ categories.each do |category|
147
+ break if category.position != last_position
148
+
149
+ category.position = category.position + 1
150
+ category.save
151
+
152
+ last_position = category.position
153
+ end
154
+
155
+ Category.set_callback(:save, :after, :enforce_positioning)
156
+ end
157
+
158
+ # Returns list of ancestors, starting from parent until root.
159
+ #
160
+ # subchild1.ancestors # => [child1, root]
161
+ #
162
+ # @return [Array(Category)]
163
+ def ancestors
164
+ node, nodes = self, []
165
+ nodes << node = node.parent while node.parent
166
+ nodes
167
+ end
168
+
169
+ # Get products associated with the category. Optional scope of store.
170
+ #
171
+ # @param store [Store, nil]
172
+ # @return [ActiveRecord::Associations::CollectionProxy(Product)]
173
+ def products(store = nil)
174
+ return super if store.nil?
175
+
176
+ Product
177
+ .joins(:product_categories)
178
+ .where('gemgento_product_categories.store_id = ? AND gemgento_product_categories.category_id = ?', store.id, self.id)
179
+ .order('gemgento_product_categories.position ASC')
180
+ .uniq
181
+ end
182
+
183
+ def after_touch
184
+ # do nothing, plcaeholder
185
+ end
186
+
187
+ private
188
+
189
+ # Create an associated Category in Magento.
190
+ #
191
+ # @return [Boolean]
192
+ def create_magento_category
193
+ response = API::SOAP::Catalog::Category.create(self, self.stores.first)
194
+
195
+ if response.success?
196
+ self.magento_id = response.body[:attribute_id]
197
+ self.sync_needed = false
198
+
199
+ self.stores.each_with_index do |store, index|
200
+ next if index == 0
201
+ response = API::SOAP::Catalog::Category.update(self, store)
202
+
203
+ # If there was a problem updating on of the stores, then make sure the product will be synced on next save.
204
+ # The product needs to be saved regardless, since a Magento product was created and the id must be set. So,
205
+ # this will not return false.
206
+ self.sync_needed = true unless response.success?
207
+ end
208
+
209
+
210
+ return true
211
+ else
212
+ errors.add(:base, response.body[:faultstring])
213
+ return false
214
+ end
215
+ end
216
+
217
+ # Update associate Magento category.
218
+ #
219
+ # @return [Boolean]
220
+ def update_magento_category
221
+ self.stores.each do |store|
222
+ response = API::SOAP::Catalog::Category.update(self, store)
223
+
224
+ unless response.success?
225
+ errors.add(:base, response.body[:faultstring])
226
+ return false
227
+ end
228
+ end
229
+
230
+ self.sync_needed = false
231
+ return true
232
+ end
233
+
234
+ end
235
+ end
@@ -0,0 +1,21 @@
1
+ module Gemgento
2
+
3
+ # @author Gemgento LLC
4
+ class Country < ActiveRecord::Base
5
+ has_many :regions
6
+
7
+ default_scope -> { order :name }
8
+
9
+ # JSON representation of the Country.
10
+ #
11
+ # @param options [Hash]
12
+ # @return [Hash]
13
+ def as_json(options = nil)
14
+ result = super
15
+ result[:regions] = self.regions if self.regions.loaded?
16
+
17
+ return result
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ module Gemgento
2
+
3
+ # @author Gemgento LLC
4
+ class GiftMessage < ActiveRecord::Base
5
+ #belongs_to :line_item
6
+ #belongs_to :order
7
+ end
8
+ end
@@ -0,0 +1,141 @@
1
+ require 'spreadsheet'
2
+ require 'open-uri'
3
+
4
+ module Gemgento
5
+
6
+ # @author Gemgento LLC
7
+ class ImageImport < Import
8
+ attr_accessor :product
9
+
10
+ validates_with ImageImportValidator
11
+
12
+ def default_options
13
+ {
14
+ image_labels: [],
15
+ image_file_extensions: [],
16
+ image_types: [],
17
+ image_path: nil,
18
+ store_id: nil,
19
+ destroy_existing: false
20
+ }
21
+ end
22
+
23
+ def image_labels_raw
24
+ image_labels.join("\n")
25
+ end
26
+
27
+ def image_labels_raw=(values)
28
+ options[:image_labels] = values.gsub("\r", '').split("\n")
29
+ end
30
+
31
+ def image_file_extensions_raw
32
+ image_file_extensions.join(', ')
33
+ end
34
+
35
+ def image_file_extensions_raw=(values)
36
+ options[:image_file_extensions] = values.gsub(' ', '').split(',')
37
+ end
38
+
39
+ def image_types_raw
40
+ image_types.join("\n")
41
+ end
42
+
43
+ def image_types_raw=(values)
44
+ options[:image_types] = []
45
+ options[:image_types] = values.gsub("\r", '').split("\n").map { |t| t.split(',').collect(&:strip) }
46
+ end
47
+
48
+ def store
49
+ if options[:store_id].nil?
50
+ nil
51
+ else
52
+ @store ||= Gemgento::Store.find(options[:store_id])
53
+ end
54
+ end
55
+
56
+ def destroy_existing?
57
+ options[:destroy_existing].to_bool
58
+ end
59
+
60
+ def process_row
61
+ sku = value('sku')
62
+ self.product = Product.not_deleted.find_by(sku: sku)
63
+ return if self.product.nil?
64
+
65
+ API::SOAP::Catalog::ProductAttributeMedia.fetch(self.product, store)
66
+ destroy_existing_assets if destroy_existing?
67
+ create_images
68
+ end
69
+
70
+ # Destroy all Assets associated with self.product.
71
+ #
72
+ # @return [Void]
73
+ def destroy_existing_assets
74
+ self.product.assets.where(store: store).find_each do |asset|
75
+ begin
76
+ asset.destroy
77
+ rescue
78
+ # just making sure we don't have a problem if file no longer exists
79
+ end
80
+ end
81
+ end
82
+
83
+ # Search for and create all possible images for a product.
84
+ #
85
+ # @return [Void]
86
+ def create_images
87
+ # find the correct image file name and path
88
+ self.image_labels.each_with_index do |label, position|
89
+
90
+ self.image_file_extensions.each do |extension|
91
+ file_name = self.image_path + value('image') + '_' + label + extension
92
+ next unless File.exist?(file_name)
93
+
94
+ types = []
95
+
96
+ unless self.image_types[position].nil?
97
+ types = Gemgento::AssetType.where(product_attribute_set: self.product.product_attribute_set, code: self.image_types[position])
98
+ end
99
+
100
+ unless types.is_a? Array
101
+ types = [types]
102
+ end
103
+
104
+ create_image(file_name, types, position, label)
105
+ end
106
+ end
107
+
108
+ # clear the cache
109
+ Rails.cache.clear
110
+ end
111
+
112
+ # Create an image for the product.
113
+ #
114
+ # @param file_name [String]
115
+ # @param types [Array(String)]
116
+ # @param position [Integer]
117
+ # @param label [String]
118
+ # @return [Void]
119
+ def create_image(file_name, types, position, label)
120
+ asset = Asset.new
121
+ asset.product = self.product
122
+ asset.store = store
123
+ asset.position = position
124
+ asset.label = label
125
+ asset.set_file(File.open(file_name))
126
+
127
+ types.each do |type|
128
+ asset.asset_types << type
129
+ end
130
+
131
+ asset.sync_needed = false
132
+ asset.save
133
+
134
+ asset.sync_needed = true
135
+
136
+ unless asset.save
137
+ self.process_errors << "Row #{current_row}: #{asset.errors[:base]}"
138
+ end
139
+ end
140
+ end
141
+ end