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,64 @@
1
+ module Gemgento
2
+
3
+ # @author Gemgento LLC
4
+ class Tag < ActiveRecord::Base
5
+ has_many :store_tags, class_name: 'StoreTag'
6
+ has_many :stores, through: :store_tags
7
+
8
+ has_and_belongs_to_many :products, class_name: 'Product', join_table: 'gemgento_products_tags'
9
+
10
+ validates :name, uniqueness: true
11
+
12
+ before_save :create_magento_tag, if: -> { sync_needed? && magento_id.nil? }
13
+ before_save :update_magento_tag, if: -> { sync_needed? && !magento_id.nil? }
14
+
15
+ # Get the tag base popularity for a store.
16
+ #
17
+ # @param store [Store, nil]
18
+ # @return [Integer]
19
+ def base_popularity(store = nil)
20
+ self.store_tags.find_by(store: (store || self.stores.first)).base_popularity
21
+ end
22
+
23
+ private
24
+
25
+ # Create assocaited Magento Tag.
26
+ #
27
+ # @return [Boolean]
28
+ def create_magento_tag
29
+ response = API::SOAP::Catalog::ProductTag.manage(self, stores.first)
30
+
31
+ if response.success?
32
+ self.magento_id = response.body[:result]
33
+ self.sync_needed = false
34
+
35
+ stores.each_with_index do |store, i|
36
+ next if i == 0
37
+ response = API::SOAP::Catalog::ProductTag.manage(self, store)
38
+ self.sync_needed = true unless response.success?
39
+ end
40
+
41
+ return true
42
+ else
43
+ return false
44
+ end
45
+ end
46
+
47
+ # Update associated Magento Tag.
48
+ #
49
+ # @return [Boolean]
50
+ def update_magento_tag
51
+ self.stores.each do |store|
52
+ response = API::SOAP::Catalog::ProductTag.manage(self, store)
53
+
54
+ unless response.success?
55
+ errors.add(:base, response.body[:faultstring])
56
+ return false
57
+ end
58
+ end
59
+
60
+ self.sync_needed = false
61
+ return true
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,161 @@
1
+ module Gemgento
2
+
3
+ # @author Gemgento LLC
4
+ class User < ActiveRecord::Base
5
+ devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
6
+
7
+ belongs_to :user_group
8
+
9
+ has_many :addresses, as: :addressable, class_name: 'Gemgento::Address'
10
+ has_many :recurring_profiles, class_name: 'Gemgento::RecurringProfile'
11
+ has_many :saved_credit_cards, class_name: 'Gemgento::SavedCreditCard', dependent: :destroy
12
+ has_many :wishlist_items, class_name: 'Gemgento::WishlistItem'
13
+ has_many :orders, class_name: 'Gemgento::Order'
14
+ has_many :products, through: :wishlist_items, class_name: 'Gemgento::Product'
15
+
16
+ has_one :shopify_adapter, class_name: 'Adapter::ShopifyAdapter', as: :gemgento_model
17
+
18
+ has_and_belongs_to_many :stores, join_table: 'gemgento_stores_users', class_name: 'Store'
19
+
20
+ accepts_nested_attributes_for :orders
21
+
22
+ attr_accessor :subscribe
23
+
24
+ before_validation :manage_subscribe
25
+
26
+ before_create :magento_create, if: -> { magento_id.nil? }
27
+ after_save :magento_update, if: Proc.new { |u| u.sync_needed }
28
+
29
+ attr_accessor :sync_needed
30
+
31
+ default_scope -> { where(deleted_at: nil) }
32
+
33
+ validates :magento_id, uniqueness: true, allow_nil: true
34
+ validates :user_group, presence: true
35
+
36
+ def name
37
+ "#{self.first_name} #{self.last_name}".strip
38
+ end
39
+
40
+ def self.is_valid_login(email, password)
41
+
42
+ # If no customer with email is known, double check Magento
43
+ if !Gemgento::User.exists?(email: email) && customer = Gemgento::Magento::CustomerAdapter.find_by(email: email)
44
+ Gemgento::API::SOAP::Customer::Customer.fetch(customer[:customer_id])
45
+ end
46
+
47
+ user = User.find_by(email: email)
48
+
49
+ if user.nil? || !user.is_valid_password(password)
50
+ user = nil
51
+ end
52
+
53
+ user
54
+ end
55
+
56
+ def is_valid_password(password)
57
+ unless self.encrypted_password.blank?
58
+ return self.valid_password?(password)
59
+ else
60
+ if self.magento_password.blank? || !self.magento_password.include?(':') # if we don't have any passwords, get them from Magento
61
+ API::SOAP::Customer::Customer.fetch(self.magento_id)
62
+ self.reload
63
+ end
64
+
65
+ salt = self.magento_password.split(':')[1]
66
+ encrypted_password = Digest::MD5.hexdigest(salt + password)
67
+ encrypted_password += ':' + salt
68
+
69
+ if self.magento_password == encrypted_password
70
+ self.magento_password = nil
71
+ self.password = password
72
+ self.password_confirmation = password
73
+ self.sync_needed = false
74
+ self.save
75
+
76
+ return true
77
+ else
78
+ return false
79
+ end
80
+ end
81
+ end
82
+
83
+ def is_subscriber?
84
+ return !Subscriber.find_by(email: self.email).nil?
85
+ end
86
+
87
+ def mark_deleted
88
+ self.deleted_at = Time.now
89
+ end
90
+
91
+ def mark_deleted!
92
+ mark_deleted
93
+ self.save
94
+ end
95
+
96
+ def default_billing_address
97
+ self.addresses.find_by(is_billing: true)
98
+ end
99
+
100
+ def default_shipping_address
101
+ self.addresses.find_by(is_shipping: true)
102
+ end
103
+
104
+ def password_confirmation=(value)
105
+ @password_confirmation = value
106
+
107
+ # password changes must be pushed to magento, so that
108
+ # magento customer updates don't revert the password
109
+ self.sync_needed = true
110
+ end
111
+
112
+ def as_json(options = nil)
113
+ result = super
114
+ result['is_subscriber'] = self.is_subscriber?
115
+
116
+ return result
117
+ end
118
+
119
+ def subscribe
120
+ @subscribe ||= self.is_subscriber?
121
+ end
122
+
123
+ def manage_subscribe
124
+ self.subscribe = false if self.subscribe == 0 || self.subscribe == '0'
125
+ Subscriber.manage self, self.subscribe
126
+ end
127
+
128
+ private
129
+
130
+ # Create the user in Magento. Called as a before_save callback, a failure to create new user in Magento will cancel
131
+ # the transaction and set the Magento response as base error on object.
132
+ #
133
+ # @return [Boolean]
134
+ def magento_create
135
+ response = API::SOAP::Customer::Customer.create(self, self.stores.first)
136
+
137
+ if response.success?
138
+ self.magento_id = response.body[:result]
139
+ self.created_in = self.stores.first.name
140
+ return true
141
+ else
142
+ self.errors.add(:base, response.body[:faultstring])
143
+ return false
144
+ end
145
+ end
146
+
147
+ def magento_update
148
+ self.stores.each do |store|
149
+ response = API::SOAP::Customer::Customer.update(self, store)
150
+
151
+ unless response.success?
152
+ self.errors.add(:base, response.body[:faultstring])
153
+ return false
154
+ end
155
+ end
156
+
157
+ return true
158
+ end
159
+
160
+ end
161
+ end
@@ -0,0 +1,13 @@
1
+ module Gemgento
2
+
3
+ # @author Gemgento LLC
4
+ class UserGroup < ActiveRecord::Base
5
+ def self.index
6
+ if UserGroup.all.size == 0
7
+ API::SOAP::Customer::Customer.fetch_all_user_groups
8
+ end
9
+
10
+ UserGroup.all
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ module Gemgento
2
+
3
+ # @author Gemgento LLC
4
+ class WishlistItem < ActiveRecord::Base
5
+ belongs_to :product
6
+ belongs_to :user
7
+
8
+ validates :product, :user, presence: true
9
+ validates :product, uniqueness: { scope: :user }
10
+ end
11
+ end
@@ -0,0 +1,173 @@
1
+ module Gemgento
2
+
3
+ # @author Gemgento LLC
4
+ class MagentoApi
5
+ # Log into the Magento API and set the session and client.
6
+ #
7
+ # @param force_new_session [Boolean]
8
+ # @return [Void]
9
+ def self.api_login(force_new_session = false)
10
+ @client = Savon.client(client_config)
11
+ @session = Session.get(@client, force_new_session)
12
+ end
13
+
14
+ # Define the client configuration.
15
+ #
16
+ # @return [Hash]
17
+ def self.client_config
18
+ config = {
19
+ wsdl: wsdl_url,
20
+ log: Config[:magento][:debug],
21
+ raise_errors: false,
22
+ open_timeout: 300,
23
+ read_timeout: 300
24
+ }
25
+
26
+ if !Config[:magento][:auth_username].blank? && !Config[:magento][:auth_password].blank?
27
+ config[:basic_auth] = [Config[:magento][:auth_username].to_s, Config[:magento][:auth_password].to_s]
28
+ end
29
+
30
+ return config
31
+ end
32
+
33
+ # URL of the WSDL definition. Created from settings in /config/gemgento_config.yml.
34
+ #
35
+ # @return [String]
36
+ def self.wsdl_url
37
+ url = Gemgento::Config[:magento][:url].gsub(/\/$/, '') # ensure there is no trailing slash
38
+ url += "/index.php/api/v#{Gemgento::Config[:magento][:api_version]}_#{Gemgento::Config[:magento][:api_type]}/index/wsdl/1"
39
+
40
+ return url
41
+ end
42
+
43
+ # Make an API call to Magento and get the response
44
+ #
45
+ # @param [Symbol] function The API call to make
46
+ # @param [Hash] message Call parameters (does not need session)
47
+ # @return [Hash]
48
+ def self.create_call(function, message = {})
49
+ api_login if !defined? @client
50
+
51
+ message[:sessionId] = @session
52
+ Rails.logger.debug "Making Call - #{function}"
53
+
54
+ magento_response = MagentoResponse.new
55
+
56
+ # don't save some messages because they are just too big!
57
+ if [:catalog_product_attribute_media_create].include? function
58
+ magento_response.request = {function: function, message: ''}
59
+ else
60
+ magento_response.request = {function: function, message: message}
61
+ end
62
+
63
+ response = @client.call(function, message: message)
64
+ log_call(function, message, response)
65
+
66
+ if response.success?
67
+ magento_response.success = true
68
+
69
+ if [:customer_customer_list, :sales_order_list, :catalog_product_list].include? function
70
+ magento_response.body = response.body[:"body_too_big"]
71
+ magento_response.body_overflow = response.body[:"#{function}_response"]
72
+ else
73
+ magento_response.body = response.body[:"#{function}_response"]
74
+ end
75
+
76
+ # only save successful responses if debugging is enabled
77
+ magento_response.save if Config[:magento][:debug]
78
+
79
+ else
80
+ magento_response.success = false
81
+ magento_response.body = response.body[:fault]
82
+ Rails.logger.error "Magento API Call failure - #{magento_response.body[:faultcode]} - #{magento_response.body[:faultstring]}"
83
+
84
+ if !magento_response.body[:faultcode].nil? && magento_response.body[:faultcode].to_i == 5
85
+ Rails.logger.debug '--- Attempting To Start New Session ---'
86
+ api_login(true)
87
+ create_call(function, message)
88
+ end
89
+
90
+ magento_response.save
91
+ end
92
+
93
+ magento_response.body = replace_empty_strings(magento_response.body)
94
+ magento_response.body_overflow = replace_empty_strings(magento_response.body_overflow) unless magento_response.body_overflow.nil?
95
+
96
+ return magento_response
97
+ end
98
+
99
+ def self.log_call(function, message, response)
100
+ logger = Logger.new('log/magento_api.log')
101
+
102
+ if response.success? && Gemgento::Config[:magento][:debug]
103
+ logger.debug "SUCCESS - Function: #{function} - Message: #{sanitize_message message} - Response: #{response.body}"
104
+ elsif !response.success?
105
+ logger.error "FAIL - Function: #{function} - Message: #{sanitize_message message} - Response: #{response.body}"
106
+ end
107
+ end
108
+
109
+ # Fill in missing empty strings. Empty strings are represented by { :'@xsi:type' => 'xsd:string' }.
110
+ #
111
+ # @param subject [Hash]
112
+ # @return [Hash]
113
+ def self.replace_empty_strings(subject)
114
+ if subject == { :'@xsi:type' => 'xsd:string' }
115
+ return ''
116
+ elsif subject.is_a?(Array)
117
+ return subject.map{ |child| replace_empty_strings(child) }
118
+ elsif subject.is_a?(Hash)
119
+ return subject.each{ |key, value| subject[key] = replace_empty_strings(value) }
120
+ else
121
+ return subject
122
+ end
123
+ end
124
+
125
+ # Enforce string on subject. If it's not a String, an empty string is returned.
126
+ #
127
+ # @param subject [*]
128
+ # @return [String]
129
+ def self.enforce_savon_string(subject)
130
+ if subject.is_a? String
131
+ subject
132
+ else
133
+ ''
134
+ end
135
+ end
136
+
137
+ # Enforce an array on the subject. If the subject is not an array, it is inserted into a single element array.
138
+ #
139
+ # @param subject [*]
140
+ # @return [Array]
141
+ def self.enforce_savon_array(subject)
142
+ if subject.is_a? Array
143
+ subject
144
+ else
145
+ [subject]
146
+ end
147
+ end
148
+
149
+ def self.sanitize_message(message)
150
+ sanitized_keys = %w[cc_number cc_cid cc_exp_year cc_exp_month]
151
+
152
+ if message.is_a?(Hash)
153
+ message.each do |key, val|
154
+ next if val.nil?
155
+
156
+ if sanitized_keys.include? key.to_s
157
+ message[key] = '*' * val.size
158
+ else
159
+ message[key] = sanitize_message(val)
160
+ end
161
+ end
162
+
163
+ elsif message.is_a?(Array)
164
+ message.each_with_index do |val, i|
165
+ message[i] = sanitize_message(val)
166
+ end
167
+ end
168
+
169
+ return message
170
+ end
171
+
172
+ end
173
+ end
@@ -0,0 +1,67 @@
1
+ module Gemgento
2
+ class Price
3
+
4
+ attr_accessor :product, :store, :user_group, :quantity
5
+
6
+ # @param product [Gemgento::Product]
7
+ # @param user_group [Gemgento::UserGroup]
8
+ # @param store [Gemgento::Store]
9
+ # @param quantity [Float]
10
+ def initialize(product, user_group = nil, store = nil, quantity = 1.0)
11
+ @product = product
12
+ @store = store || Gemgento::Store.current
13
+ @user_group = user_group
14
+ @quantity = quantity
15
+ end
16
+
17
+ def calculate
18
+ return gift_price if product.magento_type == 'giftvoucher'
19
+
20
+ prices = []
21
+ prices << product.original_price(store)
22
+ prices << product.attribute_value('special_price', store).to_f if has_special?
23
+ prices << Gemgento::PriceRule.calculate_price(product, user_group, store)
24
+ prices << Gemgento::PriceTier.calculate_price(product, quantity, user_group, store)
25
+
26
+ return prices.min
27
+ end
28
+
29
+ # If product is a gift, determine gift value.
30
+ #
31
+ # @return [BigDecimal]
32
+ def gift_price
33
+ store = Gemgento::Store.current if store.nil?
34
+
35
+ case product.attribute_value('gift_price_type', store)
36
+ when 'Fixed number'
37
+ return product.attribute_value('gift_price', store).to_d
38
+ when 'Percent of Gift Card value'
39
+ return product.attribute_value('gift_value', store).to_d * (product.attribute_value('gift_price', store).to_d / 100.0)
40
+ else
41
+ return product.attribute_value('gift_value', store).to_d
42
+ end
43
+ end
44
+
45
+ # Determine if a product has a valid special price set.
46
+ #
47
+ # @return [Boolean]
48
+ def has_special?
49
+ special_price = product.attribute_value('special_price', store)
50
+ special_from_date = product.attribute_value('special_from_date', store)
51
+ special_to_date = product.attribute_value('special_to_date', store)
52
+
53
+ if special_price.nil? # no special price
54
+ return false
55
+ elsif special_from_date.nil? && special_to_date.nil?
56
+ return true
57
+ elsif special_from_date.nil? && !special_to_date.nil?
58
+ return Date.parse(special_to_date) >= Date.today
59
+ elsif special_to_date.nil? && !special_from_date.nil?
60
+ return Date.parse(special_from_date) <= Date.today
61
+ else
62
+ return Date.parse(special_from_date) <= Date.today && Date.parse(special_to_date) >= Date.today
63
+ end
64
+ end
65
+
66
+ end
67
+ end