spree_core 5.1.7 → 5.2.0.rc1

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 (400) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/payment_icons/ach.svg +1 -0
  3. data/app/assets/images/payment_icons/achdirectdebit.svg +1 -0
  4. data/app/assets/images/payment_icons/ada.svg +1 -0
  5. data/app/assets/images/payment_icons/adyen.svg +1 -0
  6. data/app/assets/images/payment_icons/affinbank.svg +1 -0
  7. data/app/assets/images/payment_icons/affirm.svg +1 -0
  8. data/app/assets/images/payment_icons/afterpay.svg +1 -0
  9. data/app/assets/images/payment_icons/airtel_money.svg +1 -0
  10. data/app/assets/images/payment_icons/airteltigo_mobile_money.svg +1 -0
  11. data/app/assets/images/payment_icons/alandsbanken.svg +1 -0
  12. data/app/assets/images/payment_icons/alipay.svg +1 -0
  13. data/app/assets/images/payment_icons/alipay_hk.svg +1 -0
  14. data/app/assets/images/payment_icons/alliancebank.svg +1 -0
  15. data/app/assets/images/payment_icons/alma.svg +1 -0
  16. data/app/assets/images/payment_icons/amazon.svg +1 -0
  17. data/app/assets/images/payment_icons/ambank.svg +1 -0
  18. data/app/assets/images/payment_icons/american_express.svg +1 -0
  19. data/app/assets/images/payment_icons/apecoin.svg +1 -0
  20. data/app/assets/images/payment_icons/apple_pay.svg +1 -0
  21. data/app/assets/images/payment_icons/arbitrum.svg +1 -0
  22. data/app/assets/images/payment_icons/atome.svg +1 -0
  23. data/app/assets/images/payment_icons/authorizenet.svg +1 -0
  24. data/app/assets/images/payment_icons/avalanche.svg +1 -0
  25. data/app/assets/images/payment_icons/bacs.svg +1 -0
  26. data/app/assets/images/payment_icons/bancontact.svg +1 -0
  27. data/app/assets/images/payment_icons/bangkokbank.svg +1 -0
  28. data/app/assets/images/payment_icons/bankislam.svg +1 -0
  29. data/app/assets/images/payment_icons/bankmuamalat.svg +1 -0
  30. data/app/assets/images/payment_icons/bankofamerica.svg +1 -0
  31. data/app/assets/images/payment_icons/bankrakyat.svg +1 -0
  32. data/app/assets/images/payment_icons/base.svg +1 -0
  33. data/app/assets/images/payment_icons/becs.svg +1 -0
  34. data/app/assets/images/payment_icons/benefit.svg +1 -0
  35. data/app/assets/images/payment_icons/billie.svg +1 -0
  36. data/app/assets/images/payment_icons/bitcoin.svg +1 -0
  37. data/app/assets/images/payment_icons/bitcoin_cash.svg +1 -0
  38. data/app/assets/images/payment_icons/bizum.svg +1 -0
  39. data/app/assets/images/payment_icons/blik.svg +1 -0
  40. data/app/assets/images/payment_icons/bnbchain.svg +1 -0
  41. data/app/assets/images/payment_icons/bogus.svg +1 -0
  42. data/app/assets/images/payment_icons/bogus_app_coin.svg +1 -0
  43. data/app/assets/images/payment_icons/boleto.svg +1 -0
  44. data/app/assets/images/payment_icons/boost.svg +1 -0
  45. data/app/assets/images/payment_icons/braintree.svg +1 -0
  46. data/app/assets/images/payment_icons/buckaroopaybybank.svg +1 -0
  47. data/app/assets/images/payment_icons/busd.svg +1 -0
  48. data/app/assets/images/payment_icons/cartes_bancaires.svg +1 -0
  49. data/app/assets/images/payment_icons/cash.svg +1 -0
  50. data/app/assets/images/payment_icons/cashappafterpay.svg +1 -0
  51. data/app/assets/images/payment_icons/cashapppay.svg +1 -0
  52. data/app/assets/images/payment_icons/checkout_finance.svg +1 -0
  53. data/app/assets/images/payment_icons/chinabank.svg +1 -0
  54. data/app/assets/images/payment_icons/clearpay.svg +1 -0
  55. data/app/assets/images/payment_icons/collector_bank.svg +1 -0
  56. data/app/assets/images/payment_icons/dai.svg +1 -0
  57. data/app/assets/images/payment_icons/dana.svg +1 -0
  58. data/app/assets/images/payment_icons/dankort.svg +1 -0
  59. data/app/assets/images/payment_icons/danske_bank.svg +1 -0
  60. data/app/assets/images/payment_icons/deutschebank.svg +1 -0
  61. data/app/assets/images/payment_icons/diners_club.svg +1 -0
  62. data/app/assets/images/payment_icons/directbanktransferlatinamerica.svg +1 -0
  63. data/app/assets/images/payment_icons/discover.svg +1 -0
  64. data/app/assets/images/payment_icons/dogecoin.svg +1 -0
  65. data/app/assets/images/payment_icons/duitnow.svg +1 -0
  66. data/app/assets/images/payment_icons/eft_secure.svg +1 -0
  67. data/app/assets/images/payment_icons/eftpos_au.svg +1 -0
  68. data/app/assets/images/payment_icons/eftposau.svg +1 -0
  69. data/app/assets/images/payment_icons/elo.svg +1 -0
  70. data/app/assets/images/payment_icons/eos.svg +1 -0
  71. data/app/assets/images/payment_icons/eps.svg +1 -0
  72. data/app/assets/images/payment_icons/ethereum.svg +1 -0
  73. data/app/assets/images/payment_icons/eurobonuscheckout.svg +1 -0
  74. data/app/assets/images/payment_icons/ezcash.svg +1 -0
  75. data/app/assets/images/payment_icons/fantom.svg +1 -0
  76. data/app/assets/images/payment_icons/fpx.svg +1 -0
  77. data/app/assets/images/payment_icons/gcash.svg +1 -0
  78. data/app/assets/images/payment_icons/generic.svg +1 -0
  79. data/app/assets/images/payment_icons/genericbank.svg +1 -0
  80. data/app/assets/images/payment_icons/gift-card.svg +1 -0
  81. data/app/assets/images/payment_icons/giropay.svg +1 -0
  82. data/app/assets/images/payment_icons/glbepaypal.svg +1 -0
  83. data/app/assets/images/payment_icons/gmobanktransfer.svg +1 -0
  84. data/app/assets/images/payment_icons/gnosis.svg +1 -0
  85. data/app/assets/images/payment_icons/google_pay.svg +1 -0
  86. data/app/assets/images/payment_icons/google_wallet.svg +1 -0
  87. data/app/assets/images/payment_icons/gopay.svg +1 -0
  88. data/app/assets/images/payment_icons/grabpay.svg +1 -0
  89. data/app/assets/images/payment_icons/gusd.svg +1 -0
  90. data/app/assets/images/payment_icons/handelsbanken.svg +1 -0
  91. data/app/assets/images/payment_icons/hongleongbank.svg +1 -0
  92. data/app/assets/images/payment_icons/hypercard.svg +1 -0
  93. data/app/assets/images/payment_icons/hypercash.svg +1 -0
  94. data/app/assets/images/payment_icons/ideal.svg +1 -0
  95. data/app/assets/images/payment_icons/in3viaideal.svg +1 -0
  96. data/app/assets/images/payment_icons/inbank.svg +1 -0
  97. data/app/assets/images/payment_icons/jcb.svg +1 -0
  98. data/app/assets/images/payment_icons/kakao_pay.svg +1 -0
  99. data/app/assets/images/payment_icons/kasikornbank.svg +1 -0
  100. data/app/assets/images/payment_icons/klarna-pay-later.svg +1 -0
  101. data/app/assets/images/payment_icons/klarna-pay-now.svg +1 -0
  102. data/app/assets/images/payment_icons/klarna-slice-it.svg +1 -0
  103. data/app/assets/images/payment_icons/klarna.svg +1 -0
  104. data/app/assets/images/payment_icons/knet.svg +1 -0
  105. data/app/assets/images/payment_icons/krungthaibank.svg +1 -0
  106. data/app/assets/images/payment_icons/landbank.svg +1 -0
  107. data/app/assets/images/payment_icons/laybuybyklarna.svg +1 -0
  108. data/app/assets/images/payment_icons/litecoin.svg +1 -0
  109. data/app/assets/images/payment_icons/lunchcheck.svg +1 -0
  110. data/app/assets/images/payment_icons/mach.svg +1 -0
  111. data/app/assets/images/payment_icons/mada.svg +1 -0
  112. data/app/assets/images/payment_icons/maestro.svg +1 -0
  113. data/app/assets/images/payment_icons/master.svg +1 -0
  114. data/app/assets/images/payment_icons/mayabank.svg +1 -0
  115. data/app/assets/images/payment_icons/maybank.svg +1 -0
  116. data/app/assets/images/payment_icons/maybankm2u.svg +1 -0
  117. data/app/assets/images/payment_icons/maybankqrpay.svg +1 -0
  118. data/app/assets/images/payment_icons/mbway.svg +1 -0
  119. data/app/assets/images/payment_icons/mcash.svg +1 -0
  120. data/app/assets/images/payment_icons/medicinosbankas.svg +1 -0
  121. data/app/assets/images/payment_icons/mercadopago.svg +1 -0
  122. data/app/assets/images/payment_icons/metrobank.svg +1 -0
  123. data/app/assets/images/payment_icons/mobilepay.svg +1 -0
  124. data/app/assets/images/payment_icons/momopay.svg +1 -0
  125. data/app/assets/images/payment_icons/monero.svg +1 -0
  126. data/app/assets/images/payment_icons/mtn_mobile_money.svg +1 -0
  127. data/app/assets/images/payment_icons/mybank.svg +1 -0
  128. data/app/assets/images/payment_icons/naver_pay.svg +1 -0
  129. data/app/assets/images/payment_icons/nelo.svg +1 -0
  130. data/app/assets/images/payment_icons/netbanking.svg +1 -0
  131. data/app/assets/images/payment_icons/novalnetdirectdebitach.svg +1 -0
  132. data/app/assets/images/payment_icons/nubank.svg +1 -0
  133. data/app/assets/images/payment_icons/ocbcbank.svg +1 -0
  134. data/app/assets/images/payment_icons/offlinebanktransferlatinamerica.svg +1 -0
  135. data/app/assets/images/payment_icons/ola_money.svg +1 -0
  136. data/app/assets/images/payment_icons/oney.svg +1 -0
  137. data/app/assets/images/payment_icons/onlinebanking.svg +1 -0
  138. data/app/assets/images/payment_icons/onlinebanktransfer.svg +1 -0
  139. data/app/assets/images/payment_icons/orangemobilemoney.svg +1 -0
  140. data/app/assets/images/payment_icons/otpbank.svg +1 -0
  141. data/app/assets/images/payment_icons/oxxo.svg +1 -0
  142. data/app/assets/images/payment_icons/paybybank.svg +1 -0
  143. data/app/assets/images/payment_icons/paybybankmollie.svg +1 -0
  144. data/app/assets/images/payment_icons/paybybankus.svg +1 -0
  145. data/app/assets/images/payment_icons/paycash.svg +1 -0
  146. data/app/assets/images/payment_icons/payco.svg +1 -0
  147. data/app/assets/images/payment_icons/payeverpaybybank.svg +1 -0
  148. data/app/assets/images/payment_icons/payme.svg +1 -0
  149. data/app/assets/images/payment_icons/paynow.svg +1 -0
  150. data/app/assets/images/payment_icons/paynowmbank.svg +1 -0
  151. data/app/assets/images/payment_icons/paypal.svg +1 -0
  152. data/app/assets/images/payment_icons/paypo.svg +1 -0
  153. data/app/assets/images/payment_icons/payrexxbanktransfer.svg +1 -0
  154. data/app/assets/images/payment_icons/payrexxpaybybank.svg +1 -0
  155. data/app/assets/images/payment_icons/paysafecash.svg +1 -0
  156. data/app/assets/images/payment_icons/pix.svg +1 -0
  157. data/app/assets/images/payment_icons/polygon.svg +1 -0
  158. data/app/assets/images/payment_icons/przelewy24.svg +1 -0
  159. data/app/assets/images/payment_icons/publicbank.svg +1 -0
  160. data/app/assets/images/payment_icons/publicbank_pbe.svg +1 -0
  161. data/app/assets/images/payment_icons/qr_promptpay.svg +1 -0
  162. data/app/assets/images/payment_icons/rabobank.svg +1 -0
  163. data/app/assets/images/payment_icons/revolut.svg +1 -0
  164. data/app/assets/images/payment_icons/rhbbank.svg +1 -0
  165. data/app/assets/images/payment_icons/riverty.svg +1 -0
  166. data/app/assets/images/payment_icons/safetypaybanktransfer.svg +1 -0
  167. data/app/assets/images/payment_icons/samsung_pay.svg +1 -0
  168. data/app/assets/images/payment_icons/satispay.svg +1 -0
  169. data/app/assets/images/payment_icons/scalapay.svg +1 -0
  170. data/app/assets/images/payment_icons/scotiabank.svg +1 -0
  171. data/app/assets/images/payment_icons/seabankid.svg +1 -0
  172. data/app/assets/images/payment_icons/seabankph.svg +1 -0
  173. data/app/assets/images/payment_icons/sepa_bank_transfer.svg +1 -0
  174. data/app/assets/images/payment_icons/sepadirectdebit.svg +1 -0
  175. data/app/assets/images/payment_icons/seveneleven.svg +1 -0
  176. data/app/assets/images/payment_icons/shib.svg +1 -0
  177. data/app/assets/images/payment_icons/shopcash.svg +1 -0
  178. data/app/assets/images/payment_icons/siauliubankas.svg +1 -0
  179. data/app/assets/images/payment_icons/skeps.svg +1 -0
  180. data/app/assets/images/payment_icons/snap_checkout.svg +1 -0
  181. data/app/assets/images/payment_icons/sofort.svg +1 -0
  182. data/app/assets/images/payment_icons/softbank.svg +1 -0
  183. data/app/assets/images/payment_icons/spei.svg +1 -0
  184. data/app/assets/images/payment_icons/storecredit.svg +1 -0
  185. data/app/assets/images/payment_icons/stripe.svg +1 -0
  186. data/app/assets/images/payment_icons/sveacheckout.svg +1 -0
  187. data/app/assets/images/payment_icons/swedbank.svg +1 -0
  188. data/app/assets/images/payment_icons/swish.svg +1 -0
  189. data/app/assets/images/payment_icons/tbibank.svg +1 -0
  190. data/app/assets/images/payment_icons/thanachartbank.svg +1 -0
  191. data/app/assets/images/payment_icons/tnmmoney.svg +1 -0
  192. data/app/assets/images/payment_icons/touchngo.svg +1 -0
  193. data/app/assets/images/payment_icons/trustly.svg +1 -0
  194. data/app/assets/images/payment_icons/twint.svg +1 -0
  195. data/app/assets/images/payment_icons/uaevisa.svg +1 -0
  196. data/app/assets/images/payment_icons/unionpay.svg +1 -0
  197. data/app/assets/images/payment_icons/unzerbanktransfer.svg +1 -0
  198. data/app/assets/images/payment_icons/upi.svg +1 -0
  199. data/app/assets/images/payment_icons/usbank.svg +1 -0
  200. data/app/assets/images/payment_icons/usdc.svg +1 -0
  201. data/app/assets/images/payment_icons/usdt.svg +1 -0
  202. data/app/assets/images/payment_icons/venmo.svg +1 -0
  203. data/app/assets/images/payment_icons/vipps.svg +1 -0
  204. data/app/assets/images/payment_icons/visa.svg +1 -0
  205. data/app/assets/images/payment_icons/volksbank.svg +1 -0
  206. data/app/assets/images/payment_icons/waavepaybybank.svg +1 -0
  207. data/app/assets/images/payment_icons/walley.svg +1 -0
  208. data/app/assets/images/payment_icons/wbtc.svg +1 -0
  209. data/app/assets/images/payment_icons/wechatpay.svg +1 -0
  210. data/app/assets/images/payment_icons/whishcheckout.svg +1 -0
  211. data/app/assets/images/payment_icons/wingbank.svg +1 -0
  212. data/app/assets/images/payment_icons/xrp.svg +1 -0
  213. data/app/assets/images/payment_icons/zip.svg +1 -0
  214. data/app/finders/spree/posts/find.rb +137 -0
  215. data/app/helpers/spree/addresses_helper.rb +9 -3
  216. data/app/helpers/spree/base_helper.rb +8 -4
  217. data/app/helpers/spree/currency_helper.rb +21 -6
  218. data/app/jobs/spree/images/save_from_url_job.rb +70 -0
  219. data/app/jobs/spree/imports/create_rows_job.rb +72 -0
  220. data/app/jobs/spree/imports/process_rows_job.rb +19 -0
  221. data/app/models/concerns/spree/adjustment_source.rb +3 -3
  222. data/app/models/concerns/spree/admin_user_methods.rb +52 -0
  223. data/app/models/concerns/spree/display_on.rb +7 -1
  224. data/app/models/concerns/spree/has_image_alt_text.rb +18 -0
  225. data/app/models/concerns/spree/has_one_link.rb +1 -1
  226. data/app/models/concerns/spree/has_page_links.rb +1 -1
  227. data/app/models/concerns/spree/linkable.rb +9 -0
  228. data/app/models/concerns/spree/metadata.rb +2 -0
  229. data/app/models/concerns/spree/metafields.rb +94 -0
  230. data/app/models/concerns/spree/named_type.rb +1 -1
  231. data/app/models/concerns/spree/user_methods.rb +26 -9
  232. data/app/models/concerns/spree/user_payment_source.rb +1 -1
  233. data/app/models/concerns/spree/user_roles.rb +3 -2
  234. data/app/models/spree/ability.rb +4 -0
  235. data/app/models/spree/address.rb +6 -2
  236. data/app/models/spree/adjustable/adjuster/tax.rb +2 -2
  237. data/app/models/spree/adjustable/adjustments_updater.rb +26 -3
  238. data/app/models/spree/adjustment.rb +4 -1
  239. data/app/models/spree/asset.rb +16 -0
  240. data/app/models/spree/base.rb +1 -1
  241. data/app/models/spree/calculator.rb +1 -1
  242. data/app/models/spree/credit_card.rb +1 -0
  243. data/app/models/spree/current.rb +5 -1
  244. data/app/models/spree/custom_domain.rb +5 -0
  245. data/app/models/spree/customer_return.rb +1 -0
  246. data/app/models/spree/export.rb +39 -2
  247. data/app/models/spree/exports/customers.rb +17 -0
  248. data/app/models/spree/exports/gift_cards.rb +13 -0
  249. data/app/models/spree/exports/newsletter_subscribers.rb +13 -0
  250. data/app/models/spree/exports/orders.rb +6 -4
  251. data/app/models/spree/exports/products.rb +9 -3
  252. data/app/models/spree/gateway/bogus.rb +4 -0
  253. data/app/models/spree/gateway/custom_payment_source_method.rb +4 -0
  254. data/app/models/spree/gift_card.rb +9 -1
  255. data/app/models/spree/gift_card_batch.rb +0 -1
  256. data/app/models/spree/import.rb +279 -0
  257. data/app/models/spree/import_mapping.rb +46 -0
  258. data/app/models/spree/import_row.rb +108 -0
  259. data/app/models/spree/import_schema.rb +25 -0
  260. data/app/models/spree/import_schemas/products.rb +45 -0
  261. data/app/models/spree/imports/products.rb +9 -0
  262. data/app/models/spree/invitation.rb +1 -1
  263. data/app/models/spree/legacy_user.rb +0 -1
  264. data/app/models/spree/line_item.rb +3 -8
  265. data/app/models/spree/metafield.rb +53 -0
  266. data/app/models/spree/metafield_definition.rb +91 -0
  267. data/app/models/spree/metafields/boolean.rb +15 -0
  268. data/app/models/spree/metafields/json.rb +27 -0
  269. data/app/models/spree/metafields/long_text.rb +7 -0
  270. data/app/models/spree/metafields/number.rb +15 -0
  271. data/app/models/spree/metafields/rich_text.rb +18 -0
  272. data/app/models/spree/metafields/short_text.rb +7 -0
  273. data/app/models/spree/newsletter_subscriber/emails.rb +12 -0
  274. data/app/models/spree/newsletter_subscriber.rb +64 -0
  275. data/app/models/spree/option_type.rb +2 -0
  276. data/app/models/spree/option_value.rb +1 -0
  277. data/app/models/spree/order/checkout.rb +7 -0
  278. data/app/models/spree/order/payments.rb +1 -1
  279. data/app/models/spree/order.rb +14 -11
  280. data/app/models/spree/order_merger.rb +2 -4
  281. data/app/models/spree/order_promotion.rb +3 -0
  282. data/app/models/spree/order_updater.rb +2 -2
  283. data/app/models/spree/page.rb +5 -1
  284. data/app/models/spree/page_block.rb +4 -0
  285. data/app/models/spree/page_blocks/image.rb +3 -0
  286. data/app/models/spree/page_blocks/metafields.rb +18 -0
  287. data/app/models/spree/page_blocks/products/brand.rb +15 -0
  288. data/app/models/spree/page_blocks/products/buy_buttons.rb +5 -1
  289. data/app/models/spree/page_blocks/products/description.rb +18 -0
  290. data/app/models/spree/page_blocks/products/price.rb +1 -1
  291. data/app/models/spree/page_blocks/products/quantity_selector.rb +6 -2
  292. data/app/models/spree/page_blocks/products/title.rb +5 -1
  293. data/app/models/spree/page_blocks/products/variant_picker.rb +1 -1
  294. data/app/models/spree/page_section.rb +2 -2
  295. data/app/models/spree/page_sections/breadcrumbs.rb +12 -0
  296. data/app/models/spree/page_sections/footer.rb +20 -13
  297. data/app/models/spree/page_sections/image_banner.rb +6 -1
  298. data/app/models/spree/page_sections/image_with_text.rb +5 -0
  299. data/app/models/spree/page_sections/newsletter.rb +7 -0
  300. data/app/models/spree/page_sections/product_details.rb +38 -1
  301. data/app/models/spree/pages/account.rb +4 -0
  302. data/app/models/spree/pages/cart.rb +10 -0
  303. data/app/models/spree/pages/checkout.rb +6 -0
  304. data/app/models/spree/pages/custom.rb +4 -0
  305. data/app/models/spree/pages/homepage.rb +4 -0
  306. data/app/models/spree/pages/login.rb +4 -0
  307. data/app/models/spree/pages/password.rb +2 -0
  308. data/app/models/spree/pages/post_list.rb +5 -1
  309. data/app/models/spree/pages/product_details.rb +1 -0
  310. data/app/models/spree/pages/search_results.rb +1 -1
  311. data/app/models/spree/pages/shop_all.rb +5 -1
  312. data/app/models/spree/pages/wishlist.rb +4 -0
  313. data/app/models/spree/payment.rb +1 -0
  314. data/app/models/spree/payment_method.rb +8 -5
  315. data/app/models/spree/payment_source.rb +1 -0
  316. data/app/models/spree/policy.rb +70 -0
  317. data/app/models/spree/post.rb +4 -2
  318. data/app/models/spree/post_category.rb +1 -0
  319. data/app/models/spree/product.rb +16 -9
  320. data/app/models/spree/promotion/actions/free_shipping.rb +3 -3
  321. data/app/models/spree/promotion.rb +24 -8
  322. data/app/models/spree/promotion_action.rb +1 -1
  323. data/app/models/spree/promotion_handler/cart.rb +1 -1
  324. data/app/models/spree/promotion_handler/coupon.rb +1 -1
  325. data/app/models/spree/promotion_rule.rb +1 -1
  326. data/app/models/spree/property.rb +18 -0
  327. data/app/models/spree/refund.rb +2 -1
  328. data/app/models/spree/role_user.rb +1 -1
  329. data/app/models/spree/shipment.rb +1 -0
  330. data/app/models/spree/shipping_method.rb +1 -0
  331. data/app/models/spree/stock_item.rb +1 -0
  332. data/app/models/spree/stock_transfer.rb +1 -0
  333. data/app/models/spree/store.rb +45 -3
  334. data/app/models/spree/store_credit.rb +2 -1
  335. data/app/models/spree/tax_category.rb +1 -1
  336. data/app/models/spree/tax_rate.rb +18 -3
  337. data/app/models/spree/taxon.rb +12 -2
  338. data/app/models/spree/taxonomy.rb +11 -0
  339. data/app/models/spree/theme.rb +1 -1
  340. data/app/models/spree/variant.rb +17 -0
  341. data/app/presenters/spree/csv/customer_presenter.rb +59 -0
  342. data/app/presenters/spree/csv/gift_card_presenter.rb +49 -0
  343. data/app/presenters/spree/csv/metafields_helper.rb +17 -0
  344. data/app/presenters/spree/csv/newsletter_subscriber_presenter.rb +39 -0
  345. data/app/presenters/spree/csv/order_line_item_presenter.rb +12 -5
  346. data/app/presenters/spree/csv/product_variant_presenter.rb +9 -5
  347. data/app/services/spree/addresses/update.rb +8 -1
  348. data/app/services/spree/cart/recalculate.rb +6 -4
  349. data/app/services/spree/cart/remove_line_item.rb +1 -2
  350. data/app/services/spree/imports/row_processors/base.rb +19 -0
  351. data/app/services/spree/imports/row_processors/product_variant.rb +228 -0
  352. data/app/services/spree/line_items/destroy.rb +1 -1
  353. data/app/services/spree/newsletter/subscribe.rb +43 -0
  354. data/app/services/spree/newsletter/verify.rb +30 -0
  355. data/app/services/spree/orders/create_user_account.rb +5 -1
  356. data/app/services/spree/products/prepare_nested_attributes.rb +44 -0
  357. data/app/sorters/spree/posts/sort.rb +40 -0
  358. data/app/{services → validators}/spree/addresses/phone_validator.rb +1 -1
  359. data/app/views/spree/shared/_payment.html.erb +11 -9
  360. data/config/locales/en.yml +56 -2
  361. data/db/migrate/20250605131334_add_missing_fields_to_users.rb +23 -13
  362. data/db/migrate/20250728095629_create_spree_metafields.rb +27 -0
  363. data/db/migrate/20250730102644_add_missing_unique_indexes_to_spree_option_types_and_values.rb +40 -0
  364. data/db/migrate/20250730154601_add_unique_index_on_spree_properties_name.rb +24 -0
  365. data/db/migrate/20250811112056_create_spree_policies.rb +22 -0
  366. data/db/migrate/20250821211705_fix_unique_index_on_spree_order_promotions.rb +20 -0
  367. data/db/migrate/20250825175217_add_missing_page_builder_indexes.rb +7 -0
  368. data/db/migrate/20250826093602_create_spree_newsletter_subscribers.rb +12 -0
  369. data/db/migrate/20250902143122_fix_policies_store_association.rb +18 -0
  370. data/db/migrate/20250911205659_add_missing_index_on_spree_products_promotionable.rb +5 -0
  371. data/db/migrate/20250913130044_add_page_links_counter_cache_to_spree_stores.rb +10 -0
  372. data/db/migrate/20250914101955_add_missing_indexes_on_spree_adjustments.rb +6 -0
  373. data/db/migrate/20250915093930_add_metadata_to_spree_newsletter_subscribers.rb +20 -0
  374. data/db/migrate/20250923141845_create_spree_imports.rb +47 -0
  375. data/lib/generators/spree/cursor_rules/cursor_rules_generator.rb +19 -0
  376. data/lib/generators/spree/cursor_rules/templates/spree_rules.mdc +387 -0
  377. data/lib/generators/spree/dummy/dummy_generator.rb +0 -1
  378. data/lib/generators/spree/install/templates/config/initializers/spree.rb +5 -0
  379. data/lib/spree/core/configuration.rb +1 -0
  380. data/lib/spree/core/dependencies.rb +3 -0
  381. data/lib/spree/core/engine.rb +57 -2
  382. data/lib/spree/core/version.rb +1 -1
  383. data/lib/spree/core.rb +3 -1
  384. data/lib/spree/permitted_attributes.rb +18 -3
  385. data/lib/spree/testing_support/capybara_config.rb +9 -3
  386. data/lib/spree/testing_support/common_rake.rb +5 -5
  387. data/lib/spree/testing_support/factories/export_factory.rb +5 -17
  388. data/lib/spree/testing_support/factories/import_factory.rb +20 -0
  389. data/lib/spree/testing_support/factories/import_mapping_factory.rb +7 -0
  390. data/lib/spree/testing_support/factories/import_row_factory.rb +7 -0
  391. data/lib/spree/testing_support/factories/metafield_definition_factory.rb +72 -0
  392. data/lib/spree/testing_support/factories/metafield_factory.rb +68 -0
  393. data/lib/spree/testing_support/factories/newsletter_subscriber_factory.rb +18 -0
  394. data/lib/spree/testing_support/factories/policy_factory.rb +8 -0
  395. data/lib/spree/testing_support/factories/post_factory.rb +8 -0
  396. data/lib/spree/testing_support/store.rb +11 -0
  397. data/lib/tasks/core.rake +130 -3
  398. metadata +280 -7
  399. data/app/models/action_text/rich_text_decorator.rb +0 -11
  400. data/app/presenters/spree/csv/product_presenter.rb +0 -63
@@ -53,6 +53,13 @@ en:
53
53
  spree/gift_card:
54
54
  amount_used: Amount used
55
55
  expires_at: Expires at
56
+ spree/import:
57
+ preferred_delimiter: Delimiter
58
+ spree/import_mapping:
59
+ file_column: File Column
60
+ schema_field: Schema Field
61
+ spree/import_row:
62
+ row_number: Number
56
63
  spree/inventory_unit:
57
64
  state: State
58
65
  spree/invitation:
@@ -60,6 +67,8 @@ en:
60
67
  spree/line_item:
61
68
  price: Price
62
69
  quantity: Quantity
70
+ spree/metafield_definition:
71
+ namespace: Namespace
63
72
  spree/option_type:
64
73
  filterable: Filterable
65
74
  name: Name
@@ -101,6 +110,9 @@ en:
101
110
  number: Number
102
111
  spree/payment_method:
103
112
  name: Name
113
+ spree/policy:
114
+ body: Body
115
+ owner: Policy for
104
116
  spree/product:
105
117
  available_on: Available On
106
118
  cost_currency: Cost Currency
@@ -165,6 +177,9 @@ en:
165
177
  preferred_limit_digital_download_days: Limit digital links download days
166
178
  seo_robots: SEO Robots
167
179
  seo_title: SEO Title
180
+ storefront_custom_code_body_end: Custom Code before closing body tag
181
+ storefront_custom_code_body_start: Custom Code after opening body tag
182
+ storefront_custom_code_head: Custom Code in page head
168
183
  url: Site URL
169
184
  spree/store_credit:
170
185
  amount_used: Amount used
@@ -241,6 +256,12 @@ en:
241
256
  attachment:
242
257
  attachment_must_be_present: must be present
243
258
  not_allowed_content_type: has not allowed content type
259
+ spree/import:
260
+ attributes:
261
+ attachment:
262
+ content_type: has not allowed content type
263
+ type:
264
+ inclusion: is not included in the list of allowed types
244
265
  spree/legacy_user:
245
266
  attributes:
246
267
  bill_address_id:
@@ -677,6 +698,9 @@ en:
677
698
  analytics: Analytics
678
699
  and: and
679
700
  api_keys: API keys
701
+ apis:
702
+ platform: Platform API
703
+ storefront: Storefront API
680
704
  apply: Apply
681
705
  apply_only_on_full_priced_items: Apply only on full priced items
682
706
  apply_store_credit: Apply Store Credit
@@ -728,6 +752,7 @@ en:
728
752
  body_tag_end: Body tag end
729
753
  body_tag_start: Body tag start
730
754
  both: Both
755
+ brand: Brand
731
756
  breadcrumbs: Breadcrumbs
732
757
  calculated_reimbursements: Calculated Reimbursements
733
758
  calculator: Calculator
@@ -821,6 +846,7 @@ en:
821
846
  continue_selling_when_out_of_stock: Continue selling when out of stock
822
847
  continue_shopping: Continue shopping
823
848
  continue_without_logging_in: Continue without logging in
849
+ copied: Copied!
824
850
  copy: Copy
825
851
  copy_id: Copy ID
826
852
  copy_link: Copy link
@@ -871,7 +897,6 @@ en:
871
897
  credits: Credits
872
898
  currencies: Currencies
873
899
  currency: Currency
874
- currency_and_country_help: This determines which vendors you can connect with and what customers see on your store.
875
900
  currency_settings: Currency Settings
876
901
  current: Current
877
902
  current_password: Current password
@@ -900,6 +925,7 @@ en:
900
925
  default_billing_address: Default billing address
901
926
  default_country: Default Country
902
927
  default_country_cannot_be_deleted: Default country cannot be deleted
928
+ default_country_help: Country that will be used for the default shipping and billing addresses on Checkout
903
929
  default_currency: Default currency
904
930
  default_locale: Default locale
905
931
  default_post_categories:
@@ -1061,6 +1087,7 @@ en:
1061
1087
  field: Field
1062
1088
  filename: Filename
1063
1089
  fill_in_customer_info: Please fill in customer info
1090
+ filled: Filled
1064
1091
  filter: Filter
1065
1092
  filter_results: Filter Results
1066
1093
  filterable: Filterable
@@ -1143,6 +1170,7 @@ en:
1143
1170
  images: Images
1144
1171
  implement_eligible_for_return: 'Must implement #eligible_for_return? for your EligibilityValidator.'
1145
1172
  implement_requires_manual_intervention: 'Must implement #requires_manual_intervention? for your EligibilityValidator.'
1173
+ import: Import
1146
1174
  import_payment_methods_from: Import payment methods from
1147
1175
  import_products_from: Import products from
1148
1176
  in_stock: In Stock
@@ -1165,6 +1193,8 @@ en:
1165
1193
  intercept_email_address: Intercept Email Address
1166
1194
  intercept_email_instructions: Override email recipient and replace with this address.
1167
1195
  internal_name: Internal Name
1196
+ internal_server_error: Internal Server Error
1197
+ internal_server_error_message: The server encountered an internal error and was unable to complete your request.
1168
1198
  internationalization: Internationalization
1169
1199
  invalid_credit_card: Invalid credit card.
1170
1200
  invalid_exchange_variant: Invalid exchange variant.
@@ -1209,6 +1239,7 @@ en:
1209
1239
  items_reimbursed: Items reimbursed
1210
1240
  items_to_be_reimbursed: Items to be reimbursed
1211
1241
  join_slack: Join Slack
1242
+ key: Key
1212
1243
  kind: Kind
1213
1244
  language: Language
1214
1245
  last_name: Last Name
@@ -1264,6 +1295,8 @@ en:
1264
1295
  meta_keywords: Meta Keywords
1265
1296
  meta_title: Meta Title
1266
1297
  metadata: Metadata
1298
+ metafield_definitions: Metafield Definitions
1299
+ metafields: Metafields
1267
1300
  min: Min
1268
1301
  minimal_amount: Minimal Amount
1269
1302
  minimum_password_length:
@@ -1301,7 +1334,7 @@ en:
1301
1334
  new_gift_card: New Gift Card
1302
1335
  new_image: New Image
1303
1336
  new_line_item: Add line item
1304
- new_market: New market
1337
+ new_metafield_definition: New Metafield Definition
1305
1338
  new_nested_taxon: New nested taxon
1306
1339
  new_option_type: New Option Type
1307
1340
  new_order: New Order
@@ -1311,6 +1344,7 @@ en:
1311
1344
  new_password: New password
1312
1345
  new_payment: New Payment
1313
1346
  new_payment_method: New Payment Method
1347
+ new_policy: New Policy
1314
1348
  new_post: New Post
1315
1349
  new_post_category: New Post Category
1316
1350
  new_product: New Product
@@ -1343,6 +1377,17 @@ en:
1343
1377
  new_user: New User
1344
1378
  new_variant: New Variant
1345
1379
  new_zone: New Zone
1380
+ newsletter_mailer:
1381
+ email_confirmation:
1382
+ dear_customer: Hey,
1383
+ ignore_disclaimer: If you didn't request this, please ignore this email.
1384
+ instructions: Please click the button below to verify your email address.
1385
+ message_copy_link: 'If the button doesn''t work please copy and paste the following link to your browser:'
1386
+ store_team: "%{store_name} Team"
1387
+ subject: Verify your email address
1388
+ thanks: Thank you
1389
+ verify_email_address_link: Verify email address
1390
+ newsletter_subscribers: Newsletter Subscribers
1346
1391
  newsletters: Newsletters
1347
1392
  next: Next
1348
1393
  no_actions_added: No actions added
@@ -1495,6 +1540,7 @@ en:
1495
1540
  buy_buttons:
1496
1541
  display_name: Add To Cart
1497
1542
  page_not_found: Sorry! Page you are looking can’t be found.
1543
+ page_not_found_message: This page just doesn't exist.
1498
1544
  page_sections:
1499
1545
  announcement_bar:
1500
1546
  default_text: Welcome to my Store!
@@ -1779,6 +1825,7 @@ en:
1779
1825
  resellable: Resellable
1780
1826
  resend: Resend
1781
1827
  reset_password: Reset my password
1828
+ resource: Resource
1782
1829
  response_code: Response Code
1783
1830
  restore_defaults: Restore defaults
1784
1831
  resume: resume
@@ -1813,6 +1860,7 @@ en:
1813
1860
  rma_value: RMA Value
1814
1861
  role_id: Role ID
1815
1862
  roles: Roles
1863
+ row: Row
1816
1864
  rules: Rules
1817
1865
  safe: Safe
1818
1866
  sale: Sale
@@ -1869,6 +1917,8 @@ en:
1869
1917
  seo_title: SEO Title
1870
1918
  server: Server
1871
1919
  server_error: The server returned an error
1920
+ service_unavailable: Service Unavailable
1921
+ service_unavailable_message: The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.
1872
1922
  settings: Settings
1873
1923
  ship: Ship
1874
1924
  ship_address: Ship Address
@@ -2205,6 +2255,8 @@ en:
2205
2255
  metric: metric
2206
2256
  metric_system: Metric system
2207
2257
  unlock: Unlock
2258
+ unprocessable_entity: Unprocessable Entity
2259
+ unprocessable_entity_message: Your request could not be processed. Please check the form for errors and try again.
2208
2260
  unrecognized_card_type: Unrecognized card type
2209
2261
  unshippable_items: Unshippable Items
2210
2262
  update: Update
@@ -2246,6 +2298,8 @@ en:
2246
2298
  variants_count: Variants count
2247
2299
  vendor: Vendor
2248
2300
  vendors: Vendors
2301
+ verified: Verified
2302
+ verified_at: Verified at
2249
2303
  version: Version
2250
2304
  view: View
2251
2305
  view_all: View all
@@ -1,25 +1,35 @@
1
- # this fields were not present when someone used a custom user class
1
+ # these fields were not present when someone used a custom user class
2
2
  # so we need to ensure this is setup properly
3
3
  class AddMissingFieldsToUsers < ActiveRecord::Migration[7.2]
4
4
  def change
5
5
  users_table = Spree.user_class.table_name
6
- add_column users_table, :login, :string, if_not_exists: true
6
+ admin_users_table = Spree.admin_user_class.table_name
7
7
 
8
- json_type = if respond_to?(:jsonb)
9
- :jsonb
10
- else
11
- :json
12
- end
8
+ change_table users_table do |t|
9
+ t.string :login unless column_exists?(users_table, :login)
13
10
 
14
- add_column users_table, :public_metadata, json_type, if_not_exists: true
15
- add_column users_table, :private_metadata, json_type, if_not_exists: true
11
+ if t.respond_to? :jsonb
12
+ t.jsonb :public_metadata unless column_exists?(users_table, :public_metadata)
13
+ t.jsonb :private_metadata unless column_exists?(users_table, :private_metadata)
14
+ else
15
+ t.json :public_metadata unless column_exists?(users_table, :public_metadata)
16
+ t.json :private_metadata unless column_exists?(users_table, :private_metadata)
17
+ end
18
+ end
16
19
 
17
20
  add_reference users_table, :bill_address, if_not_exists: true
18
21
  add_reference users_table, :ship_address, if_not_exists: true
19
22
 
20
- admin_users_table = Spree.admin_user_class.table_name
21
- add_column admin_users_table, :login, :string, if_not_exists: true
22
- add_column admin_users_table, :public_metadata, json_type, if_not_exists: true
23
- add_column admin_users_table, :private_metadata, json_type, if_not_exists: true
23
+ change_table admin_users_table do |t|
24
+ t.string :login unless column_exists?(admin_users_table, :login)
25
+
26
+ if t.respond_to? :jsonb
27
+ t.jsonb :public_metadata unless column_exists?(admin_users_table, :public_metadata)
28
+ t.jsonb :private_metadata unless column_exists?(admin_users_table, :private_metadata)
29
+ else
30
+ t.json :public_metadata unless column_exists?(admin_users_table, :public_metadata)
31
+ t.json :private_metadata unless column_exists?(admin_users_table, :private_metadata)
32
+ end
33
+ end
24
34
  end
25
35
  end
@@ -0,0 +1,27 @@
1
+ class CreateSpreeMetafields < ActiveRecord::Migration[7.2]
2
+ def change
3
+ create_table :spree_metafield_definitions do |t|
4
+ t.string :namespace, null: false
5
+ t.string :key, null: false
6
+ t.string :name, null: false
7
+ t.string :metafield_type, null: false
8
+ t.string :resource_type, null: false, index: true
9
+ t.string :display_on, null: false, default: 'both', index: true
10
+ t.timestamps
11
+
12
+ t.index [:namespace, :key]
13
+ t.index [:resource_type, :namespace, :key], unique: true
14
+ end
15
+
16
+ create_table :spree_metafields do |t|
17
+ t.string :type, null: false, index: true
18
+ t.references :resource, polymorphic: true, null: false, index: true
19
+ t.references :metafield_definition, null: false, index: true
20
+ t.text :value
21
+
22
+ t.timestamps
23
+
24
+ t.index [:resource_type, :resource_id, :metafield_definition_id], name: 'index_metafields_on_resource_and_definition', unique: true
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,40 @@
1
+ class AddMissingUniqueIndexesToSpreeOptionTypesAndValues < ActiveRecord::Migration[7.2]
2
+ def change
3
+ # we don't need to run this migration in multi-tenant mode as it's already handled there
4
+ return if defined?(SpreeMultiTenant)
5
+
6
+ # Rename duplicated option types
7
+ duplicates = Spree::OptionType.select(:name).group(:name).having('COUNT(*) > 1').reorder('').pluck(:name)
8
+
9
+ duplicates.each do |duplicate_name|
10
+ option_types = Spree::OptionType.where(name: duplicate_name)
11
+
12
+ option_types.each_with_index do |option_type, index|
13
+ next if index == 0 # Keep the first one unchanged
14
+
15
+ new_name = "#{duplicate_name}_#{index}"
16
+ option_type.update_columns(name: new_name, updated_at: Time.current)
17
+ end
18
+ end
19
+
20
+ # Handle duplicates in spree_option_values
21
+ duplicates = Spree::OptionValue.select(:option_type_id, :name).group(:option_type_id, :name).having('COUNT(*) > 1').reorder('')
22
+
23
+ duplicates.each do |dup|
24
+ option_values = Spree::OptionValue.where(option_type_id: dup.option_type_id, name: dup.name)
25
+
26
+ option_values.each_with_index do |option_value, index|
27
+ next if index == 0 # Keep the first one unchanged
28
+
29
+ new_name = "#{option_value.name}_#{index}"
30
+ option_value.update_columns(name: new_name, updated_at: Time.current)
31
+ end
32
+ end
33
+
34
+ # Add indexes
35
+ remove_index :spree_option_types, :name, if_exists: true
36
+ add_index :spree_option_types, :name, unique: true, if_not_exists: true
37
+
38
+ add_index :spree_option_values, %i[option_type_id name], unique: true, if_not_exists: true
39
+ end
40
+ end
@@ -0,0 +1,24 @@
1
+ class AddUniqueIndexOnSpreePropertiesName < ActiveRecord::Migration[7.2]
2
+ def change
3
+ # we don't need to run this migration in multi-tenant mode as it's already handled there
4
+ return if defined?(SpreeMultiTenant)
5
+
6
+ # Rename duplicated properties
7
+ duplicates = Spree::Property.select(:name).group(:name).having('COUNT(*) > 1').reorder('').pluck(:name)
8
+
9
+ duplicates.each do |duplicate_name|
10
+ properties = Spree::Property.where(name: duplicate_name)
11
+
12
+ properties.each_with_index do |property, index|
13
+ next if index == 0 # Keep the first one unchanged
14
+
15
+ new_name = "#{duplicate_name}_#{index}"
16
+ property.update_columns(name: new_name, updated_at: Time.current)
17
+ end
18
+ end
19
+
20
+ # Add indexes
21
+ remove_index :spree_properties, :name, if_exists: true
22
+ add_index :spree_properties, :name, unique: true, if_not_exists: true
23
+ end
24
+ end
@@ -0,0 +1,22 @@
1
+ class CreateSpreePolicies < ActiveRecord::Migration[7.2]
2
+ def change
3
+ create_table :spree_policies do |t|
4
+ t.belongs_to :store, null: false
5
+ t.string :slug, null: false
6
+ t.string :name, null: false
7
+
8
+ t.timestamps
9
+ end
10
+
11
+ add_index :spree_policies, [:store_id, :slug], unique: true
12
+ create_table :spree_policy_translations do |t|
13
+ t.string :locale, null: false
14
+ t.string :name
15
+ t.references :spree_policy, null: false
16
+
17
+ t.timestamps
18
+ end
19
+
20
+ add_index :spree_policy_translations, [:spree_policy_id, :locale], unique: true
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ class FixUniqueIndexOnSpreeOrderPromotions < ActiveRecord::Migration[7.2]
2
+ def change
3
+ remove_index :spree_order_promotions, name: 'index_spree_order_promotions_on_promotion_id_and_order_id', if_exists: true
4
+
5
+ # Remove duplicate records before adding unique index
6
+ duplicates = Spree::OrderPromotion.select(:promotion_id, :order_id).group(:promotion_id, :order_id).having('COUNT(*) > 1').reorder('').pluck(:promotion_id, :order_id)
7
+
8
+ duplicates.each do |duplicate_promotion_id, duplicate_order_id|
9
+ order_promotions = Spree::OrderPromotion.where(promotion_id: duplicate_promotion_id, order_id: duplicate_order_id)
10
+
11
+ order_promotions.each_with_index do |order_promotion, index|
12
+ next if index == 0 # Keep the first one unchanged
13
+
14
+ order_promotion.destroy
15
+ end
16
+ end
17
+
18
+ add_index :spree_order_promotions, [:promotion_id, :order_id], unique: true, name: 'index_spree_order_promotions_on_promotion_id_and_order_id'
19
+ end
20
+ end
@@ -0,0 +1,7 @@
1
+ class AddMissingPageBuilderIndexes < ActiveRecord::Migration[7.2]
2
+ def change
3
+ add_index :spree_themes, %w[store_id default], name: 'index_spree_themes_on_store_id_and_default', if_not_exists: true
4
+ add_index :spree_page_links, %w[parent_type parent_id position], name: 'index_spree_page_links_parent_with_position', if_not_exists: true
5
+ add_index :spree_page_blocks, :deleted_at, if_not_exists: true
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ class CreateSpreeNewsletterSubscribers < ActiveRecord::Migration[7.2]
2
+ def change
3
+ create_table :spree_newsletter_subscribers do |t|
4
+ t.string :email, index: { unique: true }, null: false
5
+ t.references :user, index: true
6
+ t.datetime :verified_at, index: true
7
+ t.string :verification_token, index: { unique: true }
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ class FixPoliciesStoreAssociation < ActiveRecord::Migration[7.2]
2
+ def change
3
+ add_reference :spree_policies, :owner, polymorphic: true, index: true
4
+
5
+ Spree::Policy.reset_column_information
6
+ Spree::Policy.all.each do |policy|
7
+ policy.update(owner_id: policy.store_id, owner_type: 'Spree::Store')
8
+ end
9
+
10
+ remove_index :spree_policies, [:store_id, :slug], unique: true, if_exists: true
11
+ remove_index :spree_policies, [:store_id, :position], if_exists: true
12
+ remove_column :spree_policies, :store_id, if_exists: true
13
+ remove_column :spree_policies, :show_in_checkout_footer, if_exists: true
14
+ remove_column :spree_policies, :position, if_exists: true
15
+
16
+ add_index :spree_policies, [:owner_id, :owner_type, :slug], unique: true
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ class AddMissingIndexOnSpreeProductsPromotionable < ActiveRecord::Migration[7.2]
2
+ def change
3
+ add_index :spree_products, :promotionable, if_not_exists: true
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ class AddPageLinksCounterCacheToSpreeStores < ActiveRecord::Migration[7.2]
2
+ def change
3
+ add_column :spree_stores, :page_links_count, :integer, default: 0, null: false
4
+
5
+ Spree::Store.reset_column_information
6
+ Spree::Store.find_each do |store|
7
+ Spree::Store.reset_counters(store.id, :links)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ class AddMissingIndexesOnSpreeAdjustments < ActiveRecord::Migration[7.2]
2
+ def change
3
+ add_index :spree_adjustments, :source_type, if_not_exists: true
4
+ add_index :spree_adjustments, :amount, if_not_exists: true
5
+ end
6
+ end
@@ -0,0 +1,20 @@
1
+ class AddMetadataToSpreeNewsletterSubscribers < ActiveRecord::Migration[7.2]
2
+ def up
3
+ change_table :spree_newsletter_subscribers do |t|
4
+ if t.respond_to? :jsonb
5
+ t.jsonb :public_metadata
6
+ t.jsonb :private_metadata
7
+ else
8
+ t.json :public_metadata
9
+ t.json :private_metadata
10
+ end
11
+ end
12
+ end
13
+
14
+ def down
15
+ change_table :spree_newsletter_subscribers do |t|
16
+ t.remove :public_metadata
17
+ t.remove :private_metadata
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,47 @@
1
+ class CreateSpreeImports < ActiveRecord::Migration[7.2]
2
+ def change
3
+ create_table :spree_imports do |t|
4
+ t.belongs_to :user, null: false
5
+ t.belongs_to :owner, polymorphic: true, null: false
6
+
7
+ t.string :status, null: false, index: true
8
+
9
+ t.string :number, limit: 32, null: false, index: { unique: true }
10
+ t.string :type, null: false, index: true
11
+
12
+ t.text :processing_errors
13
+
14
+ t.text :preferences
15
+
16
+ t.integer :rows_count, null: false, default: 0
17
+
18
+ t.timestamps
19
+ end
20
+
21
+ create_table :spree_import_rows do |t|
22
+ t.belongs_to :import, null: false
23
+ t.belongs_to :item, polymorphic: true
24
+
25
+ t.string :status, null: false, index: true
26
+ t.integer :row_number, null: false
27
+
28
+ t.text :data, null: false
29
+ t.text :validation_errors
30
+
31
+ t.timestamps
32
+ end
33
+
34
+ add_index :spree_import_rows, [:import_id, :row_number], unique: true
35
+
36
+ create_table :spree_import_mappings do |t|
37
+ t.belongs_to :import, null: false
38
+
39
+ t.string :schema_field, null: false
40
+ t.string :file_column, index: true
41
+
42
+ t.timestamps
43
+ end
44
+
45
+ add_index :spree_import_mappings, [:import_id, :schema_field], unique: true
46
+ end
47
+ end
@@ -0,0 +1,19 @@
1
+ module Spree
2
+ class CursorRulesGenerator < Rails::Generators::Base
3
+ desc 'Set up Cursor Rules - copies all Spree cursor rules to .cursor/rules directory'
4
+
5
+ def self.source_paths
6
+ paths = superclass.source_paths
7
+ paths << File.expand_path('templates', __dir__)
8
+ paths.flatten
9
+ end
10
+
11
+ def create_cursor_rules_directory
12
+ empty_directory '.cursor/rules'
13
+ end
14
+
15
+ def copy_cursor_rules
16
+ copy_file 'spree_rules.mdc', '.cursor/rules/spree_rules.mdc'
17
+ end
18
+ end
19
+ end