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,125 @@
1
+ module Gemgento
2
+ class Import < ActiveRecord::Base
3
+ enum state: { pending: 0, processing: 1, complete: 2, failed: 3 }
4
+
5
+ has_attached_file :file
6
+
7
+ after_initialize :set_default_options,
8
+ :set_default_process_errors
9
+
10
+ before_create :set_total_rows
11
+
12
+ after_commit :process_later, if: Proc.new { |r| r.transaction_include_any_action?([:create]) }
13
+
14
+ validates :file, presence: :true
15
+ validates_attachment_content_type :file, content_type: [
16
+ 'application/octet-stream', # TODO: remove this once Paperclip fixes this problem wth Chrome and FF
17
+ 'application/vnd.ms-excel', # .xls
18
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', # .xlsx
19
+ 'application/vnd.ms-excel.sheet.macroEnabled.12', # .xlsm
20
+ 'text/csv', # .csv
21
+ 'application/vnd.oasis.opendocument.spreadsheet', # .ods
22
+ ]
23
+
24
+ attr_accessor :spreadsheet, :header_row, :row
25
+
26
+ serialize :options, Hash
27
+ serialize :process_errors, Array
28
+
29
+ def set_default_process_errors
30
+ self.process_errors ||= []
31
+ end
32
+
33
+ def set_default_options
34
+ self.options = default_options.merge(self.options || {})
35
+
36
+ self.options.keys.each do |key|
37
+ self.class.send :define_method, key do |*args|
38
+ self.options[key.to_sym]
39
+ end
40
+
41
+ self.class.send :define_method, "#{key}=" do |*args|
42
+ self.options[key.to_sym] = args.first
43
+ end
44
+ end
45
+ end
46
+
47
+ def default_options
48
+ {}
49
+ end
50
+
51
+ def set_total_rows
52
+ self.total_rows = spreadsheet.last_row - spreadsheet.first_row
53
+ end
54
+
55
+ def percentage_complete
56
+ total_rows > 0 ? ((current_row.to_f / total_rows.to_f) * 100.0) : 0.0
57
+ end
58
+
59
+ def spreadsheet
60
+ @spreadsheet ||= begin
61
+ if self.new_record?
62
+ Roo::Spreadsheet.open(self.file.queued_for_write[:original].path).sheet(0)
63
+ else
64
+ Roo::Spreadsheet.open(File.open(self.file.path)).sheet(0)
65
+ end
66
+ end
67
+ end
68
+
69
+ def header_row
70
+ @header_row ||= spreadsheet.row spreadsheet.first_row
71
+ end
72
+
73
+ def process
74
+ Rails.logger.debug "Start #{self.class}.process"
75
+ Rails.logger.debug " header_row: #{self.header_row}"
76
+
77
+ self.current_row = 0
78
+ self.processing!
79
+
80
+ while self.current_row < self.total_rows do
81
+ self.current_row += 1
82
+
83
+ self.row = spreadsheet.row(self.current_row + spreadsheet.first_row)
84
+ Rails.logger.debug " Working on Row #{self.current_row} - #{self.row}"
85
+
86
+ self.process_row
87
+ self.save!
88
+ end
89
+
90
+ self.complete!
91
+
92
+ Rails.logger.debug "Complete #{self.class}.process"
93
+
94
+ rescue Exception => e
95
+ # don't raise so that we have a record of the import and don't cause stacking with retries
96
+ self.process_errors << e.message
97
+ self.failed!
98
+ Rails.logger.error e
99
+ end
100
+
101
+ def process_later
102
+ Gemgento::ImportJob.perform_later(self)
103
+ end
104
+
105
+ # @return [Range]
106
+ def content_index_range
107
+ ((spreadsheet.first_row + 1)..spreadsheet.last_row)
108
+ end
109
+
110
+ def value(code, type = :string)
111
+ index = header_row.index(code)
112
+ value = row[index]
113
+
114
+ case type
115
+ when :boolean
116
+ return value.to_bool
117
+ when :string
118
+ return value.to_s.strip
119
+ else
120
+ return value
121
+ end
122
+ end
123
+
124
+ end
125
+ end
@@ -0,0 +1,60 @@
1
+ module Gemgento
2
+
3
+ # @author Gemgento LLC
4
+ class Inventory < ActiveRecord::Base
5
+ include Gemgento::ProductTouches
6
+
7
+ belongs_to :product, class_name: 'Gemgento::Product'
8
+ belongs_to :store, class_name: 'Gemgento::Store'
9
+
10
+ # Inventory.backorder may have one of the following values:
11
+ # 0 - no backorders
12
+ # 1 - allow qty below 0
13
+ # 2 - allow qty below 0 and notify customer
14
+ validates :backorders, inclusion: 0..2
15
+ validates :product, uniqueness: { scope: :store }
16
+
17
+ before_save :sync_local_to_magento, if: -> { sync_needed? }
18
+
19
+ attr_accessor :use_config_manage_stock
20
+
21
+ # Push the inventory data to Magento.
22
+ #
23
+ # @return [Boolean] true if the inventory data was successfully pushed to Magento
24
+ def push
25
+ API::SOAP::CatalogInventory::StockItem.update(self.product);
26
+ end
27
+
28
+ # Determine if the specified quantity is in stock.
29
+ #
30
+ # @param quantity [Integer] the required quantity
31
+ # @return [Boolean] true if the required quantity is in stock
32
+ def in_stock?(quantity = 1)
33
+ if !self.manage_stock?
34
+ return true
35
+ elsif self.is_in_stock && ((quantity.to_f <= self.quantity.to_f || quantity.to_f == 0) || self.backorders > 0)
36
+ return true
37
+ else
38
+ return false
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ # Push local inventory changes to magento.
45
+ #
46
+ # @return [Void]
47
+ def sync_local_to_magento
48
+ response = API::SOAP::CatalogInventory::StockItem.update(self)
49
+
50
+ if response.success?
51
+ self.sync_needed = false
52
+ return true
53
+ else
54
+ errors.add(:base, response.body[:faultstring])
55
+ return false
56
+ end
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,51 @@
1
+ require 'spreadsheet'
2
+ require 'open-uri'
3
+
4
+ module Gemgento
5
+
6
+ # @author Gemgento LLC
7
+ class InventoryImport < Import
8
+ attr_accessor :product
9
+
10
+ validates_with InventoryImportValidator, on: :create
11
+
12
+ # Set the Inventory for a Product.
13
+ #
14
+ # @return [Void]
15
+ def process_row
16
+ self.product = Gemgento::Product.not_deleted.find_by(sku: row[header_row.index('sku').to_i])
17
+
18
+ return if self.product.magento_type == 'configurable'
19
+ Gemgento::Store.all.each do |store|
20
+ inventory = self.product.inventories.find_or_initialize_by(store: store)
21
+
22
+ inventory.use_config_manage_stock = true
23
+ inventory.use_config_backorders = true
24
+ inventory.use_config_min_qty = true
25
+
26
+ header_row.each do |attribute|
27
+ next unless Gemgento::Inventory.column_names.include?(attribute)
28
+
29
+ value = value(attribute, Gemgento::Inventory.columns_hash[attribute].type)
30
+ inventory.assign_attributes(attribute => value)
31
+ end
32
+
33
+ inventory.sync_needed = true
34
+
35
+ unless inventory.save
36
+ self.process_errors << "Row ##{current_row}: #{inventory.errors[:base]}"
37
+ end
38
+ end
39
+ rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique => e
40
+ retries ||= 0
41
+ if retries += 1 <= @stores.count
42
+ retry
43
+ else
44
+ self.process_errors << "Row ##{current_row}: #{e.message}"
45
+ end
46
+ rescue Exception => e
47
+ self.process_errors << "Row ##{current_row}: #{e.message}"
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,142 @@
1
+ module Gemgento
2
+
3
+ # @author Gemgento LLC
4
+ class LineItem < ActiveRecord::Base
5
+ scope :refunded, -> { where.not(qty_refunded: 0) }
6
+
7
+ serialize :options, Hash
8
+
9
+ attr_accessor :async, :destroy_quote_after_rollback
10
+
11
+ belongs_to :itemizable, polymorphic: true, touch: true
12
+ belongs_to :product
13
+
14
+ has_many :bundle_options, class_name: 'Gemgento::LineItemOption', foreign_key: :line_item_id
15
+
16
+ before_save :push_magento_quote_item, if: -> { itemizable_type == 'Gemgento::Quote' && !async.to_bool }
17
+
18
+ after_save :push_magento_quote_item_async, if: -> { itemizable_type == 'Gemgento::Quote' && async.to_bool }
19
+
20
+ before_destroy :destroy_magento_quote_item, if: -> { itemizable_type == 'Gemgento::Quote' }
21
+
22
+ after_rollback :destroy_quote, if: -> { destroy_quote_after_rollback == true && itemizable_type == 'Gemgento::Quote' }
23
+
24
+ accepts_nested_attributes_for :bundle_options
25
+
26
+ validates :itemizable, :product, presence: true
27
+ validates :magento_id, uniqueness: { scope: :itemizable_type }, allow_nil: true
28
+ validates_with InventoryValidator, if: -> { itemizable_type == 'Gemgento::Quote' }
29
+
30
+ # JSON representation of the LineItem.
31
+ #
32
+ # @param options [Hash]
33
+ # @return [Void]
34
+ def as_json(options = nil)
35
+ result = super
36
+ result['product'] = self.product.as_json({ store: Store.find(self.itemizable.store.id) })
37
+ return result
38
+ end
39
+
40
+ # Get the associated Product price.
41
+ #
42
+ # @return [BigDecimal]
43
+ def price
44
+ return super.to_d unless super.nil?
45
+
46
+ if product.magento_type == 'giftvoucher'
47
+ self.options[:amount].to_d
48
+ elsif self.options[:custom_price]
49
+ self.options[:custom_price].to_d
50
+ else
51
+ user_group = itemizable.user ? itemizable.user.user_group : nil
52
+ product.price(user_group, itemizable.store, self.qty_ordered).to_d
53
+ end
54
+
55
+ end
56
+
57
+ private
58
+
59
+ # Create or Update the associated Magento Quote Item.
60
+ #
61
+ # @return [Boolean]
62
+ def push_magento_quote_item
63
+ if new_record?
64
+ response = API::SOAP::Checkout::Product.add(itemizable, [self])
65
+ else
66
+ response = API::SOAP::Checkout::Product.update(itemizable, [self])
67
+ end
68
+
69
+ if response.success?
70
+ return true
71
+ else
72
+ handle_magento_response(response)
73
+ return false
74
+ end
75
+ end
76
+
77
+ # Create or Update the associated Magento Quote Item asynchronously.
78
+ #
79
+ # @return [Void]
80
+ def push_magento_quote_item_async
81
+ if id_was.nil?
82
+ Cart::AddItemWorker.perform_async(self.id)
83
+ else
84
+ Cart::UpdateItemWorker.perform_async(self.id, self.qty_ordered_was)
85
+ end
86
+ end
87
+
88
+ # Destroy the associated Magento Quote Item.
89
+ #
90
+ # @return [Boolean]
91
+ def destroy_magento_quote_item
92
+ response = API::SOAP::Checkout::Product.remove(itemizable, [self])
93
+
94
+ if response.success?
95
+ return true
96
+ elsif response.body[:faultcode].to_i == 1026 # item does not belong to quote
97
+ return true
98
+ else
99
+ handle_magento_response(response)
100
+ return false
101
+ end
102
+ end
103
+
104
+ # Handle the Magento create/update/destroy response. Mark quote for destroy if it no longer exists in Magento.
105
+ #
106
+ # @param response [Gemgento::MagentoResponse]
107
+ # @return [Void]
108
+ def handle_magento_response(response)
109
+ if response.body[:faultcode].to_i == 1002 && itemizable_type == 'Gemgento::Quote' # quote doesn't exist in Magento.
110
+ self.destroy_quote_after_rollback = true
111
+ else
112
+ self.errors.add(:base, response.body[:faultstring])
113
+ end
114
+ end
115
+
116
+ # Destroy the associated quote.
117
+ #
118
+ # @return [Void]
119
+ def destroy_quote
120
+ LineItem.skip_callback(:destroy, :before, :destroy_magento_quote_item)
121
+ self.itemizable.destroy
122
+ LineItem.set_callback(:destroy, :before, :destroy_magento_quote_item)
123
+ end
124
+
125
+
126
+ def self.serialized_attr_accessor(*args)
127
+ args.each do |method_name|
128
+ eval "
129
+ def #{method_name}
130
+ (self.options || {})[:#{method_name}]
131
+ end
132
+ def #{method_name}=(value)
133
+ self.options ||= {}
134
+ self.options[:#{method_name}] = value
135
+ end
136
+ "
137
+ end
138
+ end
139
+
140
+
141
+ end
142
+ end
@@ -0,0 +1,10 @@
1
+ module Gemgento
2
+
3
+ # @author Gemgento LLC
4
+ class LineItemOption < ActiveRecord::Base
5
+ belongs_to :line_item, class_name: 'Gemgento::LineItem'
6
+ belongs_to :bundle_item, class_name: 'Gemgento::Bundle::Item'
7
+
8
+ validates :bundle_item, uniqueness: { scope: :line_item }
9
+ end
10
+ end
@@ -0,0 +1,35 @@
1
+ module Gemgento
2
+
3
+ # @author Gemgento LLC
4
+ class MagentoDB < ActiveRecord::Base
5
+
6
+ # Associate configurable and simple Products by reading directly from the Magento table with the association data.
7
+ #
8
+ # @param configurable_product [Gemgento::Product]
9
+ # @return [Array(Gemgento::Product)]
10
+ def self.associated_simple_products(configurable_product)
11
+ establish_connection("magento_#{Rails.env}".to_sym)
12
+
13
+ self.table_name = "#{Config[:magento][:table_prefix]}catalog_product_super_link"
14
+ simple_products = []
15
+
16
+ self.where('parent_id = ?', configurable_product.magento_id).each do |association|
17
+ simple_product = Product.where(magento_id: association.product_id).first
18
+ simple_products << simple_product unless simple_product.nil?
19
+ end
20
+
21
+ simple_products
22
+ end
23
+
24
+ # Query the Magento database using ActiveRecord.
25
+ #
26
+ # @param table_name [String]
27
+ # @return [ActiveRecord::Result]
28
+ def self.query(table_name)
29
+ establish_connection("magento_#{Rails.env}".to_sym)
30
+
31
+ self.table_name = Config[:magento][:table_prefix] + table_name
32
+ return self
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,10 @@
1
+ module Gemgento
2
+
3
+ # @author Gemgento LLC
4
+ class MagentoResponse < ActiveRecord::Base
5
+ serialize :request, Hash
6
+ serialize :body, Hash
7
+
8
+ attr_accessor :body_overflow
9
+ end
10
+ end
@@ -0,0 +1,56 @@
1
+ module Gemgento
2
+
3
+ # @author Gemgento LLC
4
+ class Order < ActiveRecord::Base
5
+ belongs_to :store, class_name: 'Gemgento::Store'
6
+ belongs_to :user, class_name: 'Gemgento::User'
7
+ belongs_to :user_group, class_name: 'Gemgento::UserGroup'
8
+ belongs_to :quote, class_name: 'Gemgento::Quote'
9
+
10
+ has_many :api_jobs, class_name: 'Gemgento::ApiJob', as: :source, dependent: :destroy
11
+ has_many :line_items, as: :itemizable, class_name: 'Gemgento::LineItem', dependent: :destroy
12
+ has_many :order_statuses, class_name: 'Gemgento::OrderStatus', dependent: :destroy
13
+ has_many :products, through: :line_items, class_name: 'Gemgento::Product'
14
+ has_many :shipments, class_name: 'Gemgento::Shipment', dependent: :destroy
15
+ has_many :shipment_tracks, class_name: 'Gemgento::ShipmentTrack', through: :shipments
16
+
17
+ has_one :payment, as: :payable, class_name: 'Gemgento::Payment', dependent: :destroy
18
+ has_one :billing_address, -> { where is_billing: true }, class_name: 'Gemgento::Address', as: :addressable, dependent: :destroy
19
+ has_one :shipping_address, -> { where is_shipping: true }, class_name: 'Gemgento::Address', as: :addressable, dependent: :destroy
20
+
21
+ attr_accessor :tax, :total, :push_cart_customer, :subscribe
22
+
23
+ validates :customer_email, format: /@/, allow_nil: true
24
+ validates :status, presence: true
25
+ validates :increment_id, :magento_id, uniqueness: true
26
+
27
+ after_save :mark_quote_converted, if: -> { quote && quote.converted_at.nil? && !state.blank? }
28
+
29
+ # Return the increment_id instead of id. This is for privacy purposes.
30
+ #
31
+ # @return [String]
32
+ def to_param
33
+ self.increment_id
34
+ end
35
+
36
+ # Set associated quote converted_at.
37
+ #
38
+ # @return [Void]
39
+ def mark_quote_converted
40
+ quote.update(converted_at: Time.now)
41
+ end
42
+
43
+ # Find or fetch an order by increment_id.
44
+ #
45
+ # @param increment_id [String]
46
+ # @return [Gemgento::Order]
47
+ def self.find_or_fetch(increment_id)
48
+ Gemgento::Order.find_by(increment_id: increment_id) || Gemgento::Magento::OrderAdapter.find(increment_id).import
49
+ end
50
+
51
+ def placed_at
52
+ super || self.created_at
53
+ end
54
+
55
+ end
56
+ end