spree_core 5.1.8 → 5.2.0.rc2

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 (393) 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/jobs/spree/images/save_from_url_job.rb +70 -0
  218. data/app/jobs/spree/imports/create_rows_job.rb +72 -0
  219. data/app/jobs/spree/imports/process_rows_job.rb +19 -0
  220. data/app/models/concerns/spree/adjustment_source.rb +3 -3
  221. data/app/models/concerns/spree/admin_user_methods.rb +52 -0
  222. data/app/models/concerns/spree/display_on.rb +7 -1
  223. data/app/models/concerns/spree/has_image_alt_text.rb +18 -0
  224. data/app/models/concerns/spree/has_one_link.rb +1 -1
  225. data/app/models/concerns/spree/has_page_links.rb +1 -1
  226. data/app/models/concerns/spree/linkable.rb +9 -0
  227. data/app/models/concerns/spree/metadata.rb +2 -0
  228. data/app/models/concerns/spree/metafields.rb +94 -0
  229. data/app/models/concerns/spree/named_type.rb +1 -1
  230. data/app/models/concerns/spree/user_methods.rb +20 -7
  231. data/app/models/concerns/spree/user_payment_source.rb +1 -1
  232. data/app/models/concerns/spree/user_roles.rb +3 -2
  233. data/app/models/spree/ability.rb +4 -0
  234. data/app/models/spree/address.rb +3 -1
  235. data/app/models/spree/adjustable/adjuster/tax.rb +2 -2
  236. data/app/models/spree/adjustable/adjustments_updater.rb +26 -3
  237. data/app/models/spree/adjustment.rb +4 -1
  238. data/app/models/spree/asset.rb +16 -0
  239. data/app/models/spree/base.rb +1 -1
  240. data/app/models/spree/credit_card.rb +1 -0
  241. data/app/models/spree/current.rb +5 -1
  242. data/app/models/spree/custom_domain.rb +5 -0
  243. data/app/models/spree/customer_return.rb +1 -0
  244. data/app/models/spree/export.rb +39 -2
  245. data/app/models/spree/exports/customers.rb +17 -0
  246. data/app/models/spree/exports/gift_cards.rb +13 -0
  247. data/app/models/spree/exports/newsletter_subscribers.rb +13 -0
  248. data/app/models/spree/exports/orders.rb +6 -4
  249. data/app/models/spree/exports/products.rb +9 -3
  250. data/app/models/spree/gift_card.rb +7 -1
  251. data/app/models/spree/gift_card_batch.rb +0 -1
  252. data/app/models/spree/import.rb +279 -0
  253. data/app/models/spree/import_mapping.rb +46 -0
  254. data/app/models/spree/import_row.rb +108 -0
  255. data/app/models/spree/import_schema.rb +25 -0
  256. data/app/models/spree/import_schemas/products.rb +45 -0
  257. data/app/models/spree/imports/products.rb +9 -0
  258. data/app/models/spree/invitation.rb +1 -1
  259. data/app/models/spree/legacy_user.rb +0 -1
  260. data/app/models/spree/line_item.rb +9 -8
  261. data/app/models/spree/metafield.rb +53 -0
  262. data/app/models/spree/metafield_definition.rb +91 -0
  263. data/app/models/spree/metafields/boolean.rb +15 -0
  264. data/app/models/spree/metafields/json.rb +27 -0
  265. data/app/models/spree/metafields/long_text.rb +7 -0
  266. data/app/models/spree/metafields/number.rb +15 -0
  267. data/app/models/spree/metafields/rich_text.rb +18 -0
  268. data/app/models/spree/metafields/short_text.rb +7 -0
  269. data/app/models/spree/newsletter_subscriber/emails.rb +12 -0
  270. data/app/models/spree/newsletter_subscriber.rb +64 -0
  271. data/app/models/spree/option_type.rb +2 -0
  272. data/app/models/spree/option_value.rb +1 -0
  273. data/app/models/spree/order/checkout.rb +7 -0
  274. data/app/models/spree/order.rb +8 -3
  275. data/app/models/spree/order_merger.rb +2 -4
  276. data/app/models/spree/order_promotion.rb +3 -0
  277. data/app/models/spree/order_updater.rb +2 -2
  278. data/app/models/spree/page.rb +5 -1
  279. data/app/models/spree/page_block.rb +4 -0
  280. data/app/models/spree/page_blocks/image.rb +3 -0
  281. data/app/models/spree/page_blocks/metafields.rb +18 -0
  282. data/app/models/spree/page_blocks/products/brand.rb +15 -0
  283. data/app/models/spree/page_blocks/products/buy_buttons.rb +5 -1
  284. data/app/models/spree/page_blocks/products/description.rb +18 -0
  285. data/app/models/spree/page_blocks/products/price.rb +1 -1
  286. data/app/models/spree/page_blocks/products/quantity_selector.rb +6 -2
  287. data/app/models/spree/page_blocks/products/title.rb +5 -1
  288. data/app/models/spree/page_blocks/products/variant_picker.rb +1 -1
  289. data/app/models/spree/page_section.rb +2 -2
  290. data/app/models/spree/page_sections/breadcrumbs.rb +12 -0
  291. data/app/models/spree/page_sections/footer.rb +20 -13
  292. data/app/models/spree/page_sections/image_banner.rb +6 -1
  293. data/app/models/spree/page_sections/image_with_text.rb +5 -0
  294. data/app/models/spree/page_sections/newsletter.rb +7 -0
  295. data/app/models/spree/page_sections/product_details.rb +38 -1
  296. data/app/models/spree/pages/account.rb +4 -0
  297. data/app/models/spree/pages/cart.rb +10 -0
  298. data/app/models/spree/pages/checkout.rb +6 -0
  299. data/app/models/spree/pages/custom.rb +4 -0
  300. data/app/models/spree/pages/homepage.rb +4 -0
  301. data/app/models/spree/pages/login.rb +4 -0
  302. data/app/models/spree/pages/password.rb +2 -0
  303. data/app/models/spree/pages/post_list.rb +4 -0
  304. data/app/models/spree/pages/product_details.rb +1 -0
  305. data/app/models/spree/pages/shop_all.rb +4 -0
  306. data/app/models/spree/pages/wishlist.rb +4 -0
  307. data/app/models/spree/payment.rb +1 -0
  308. data/app/models/spree/payment_method.rb +4 -5
  309. data/app/models/spree/payment_source.rb +1 -0
  310. data/app/models/spree/policy.rb +70 -0
  311. data/app/models/spree/post.rb +4 -2
  312. data/app/models/spree/post_category.rb +1 -0
  313. data/app/models/spree/product.rb +16 -9
  314. data/app/models/spree/promotion/actions/free_shipping.rb +3 -3
  315. data/app/models/spree/promotion.rb +24 -8
  316. data/app/models/spree/promotion_action.rb +1 -1
  317. data/app/models/spree/promotion_handler/cart.rb +1 -1
  318. data/app/models/spree/promotion_handler/coupon.rb +1 -1
  319. data/app/models/spree/promotion_rule.rb +1 -1
  320. data/app/models/spree/property.rb +18 -0
  321. data/app/models/spree/refund.rb +2 -1
  322. data/app/models/spree/role_user.rb +1 -1
  323. data/app/models/spree/shipment.rb +1 -0
  324. data/app/models/spree/shipping_method.rb +1 -0
  325. data/app/models/spree/stock_item.rb +1 -0
  326. data/app/models/spree/stock_transfer.rb +1 -0
  327. data/app/models/spree/store.rb +45 -3
  328. data/app/models/spree/store_credit.rb +2 -1
  329. data/app/models/spree/tax_category.rb +1 -1
  330. data/app/models/spree/tax_rate.rb +18 -3
  331. data/app/models/spree/taxon.rb +12 -2
  332. data/app/models/spree/taxonomy.rb +11 -0
  333. data/app/models/spree/theme.rb +1 -1
  334. data/app/models/spree/variant.rb +16 -0
  335. data/app/presenters/spree/csv/customer_presenter.rb +59 -0
  336. data/app/presenters/spree/csv/gift_card_presenter.rb +49 -0
  337. data/app/presenters/spree/csv/metafields_helper.rb +17 -0
  338. data/app/presenters/spree/csv/newsletter_subscriber_presenter.rb +39 -0
  339. data/app/presenters/spree/csv/order_line_item_presenter.rb +12 -5
  340. data/app/presenters/spree/csv/product_variant_presenter.rb +9 -5
  341. data/app/services/spree/cart/recalculate.rb +6 -4
  342. data/app/services/spree/cart/remove_line_item.rb +1 -2
  343. data/app/services/spree/imports/row_processors/base.rb +19 -0
  344. data/app/services/spree/imports/row_processors/product_variant.rb +238 -0
  345. data/app/services/spree/line_items/destroy.rb +1 -1
  346. data/app/services/spree/newsletter/subscribe.rb +43 -0
  347. data/app/services/spree/newsletter/verify.rb +30 -0
  348. data/app/services/spree/seeds/admin_user.rb +5 -5
  349. data/app/sorters/spree/posts/sort.rb +40 -0
  350. data/app/views/spree/shared/_payment.html.erb +3 -3
  351. data/config/locales/en.yml +56 -2
  352. data/db/migrate/20250605131334_add_missing_fields_to_users.rb +23 -13
  353. data/db/migrate/20250728095629_create_spree_metafields.rb +27 -0
  354. data/db/migrate/20250730102644_add_missing_unique_indexes_to_spree_option_types_and_values.rb +40 -0
  355. data/db/migrate/20250730154601_add_unique_index_on_spree_properties_name.rb +24 -0
  356. data/db/migrate/20250811112056_create_spree_policies.rb +22 -0
  357. data/db/migrate/20250821211705_fix_unique_index_on_spree_order_promotions.rb +20 -0
  358. data/db/migrate/20250825175217_add_missing_page_builder_indexes.rb +7 -0
  359. data/db/migrate/20250826093602_create_spree_newsletter_subscribers.rb +12 -0
  360. data/db/migrate/20250902143122_fix_policies_store_association.rb +18 -0
  361. data/db/migrate/20250911205659_add_missing_index_on_spree_products_promotionable.rb +5 -0
  362. data/db/migrate/20250913130044_add_page_links_counter_cache_to_spree_stores.rb +10 -0
  363. data/db/migrate/20250914101955_add_missing_indexes_on_spree_adjustments.rb +6 -0
  364. data/db/migrate/20250915093930_add_metadata_to_spree_newsletter_subscribers.rb +20 -0
  365. data/db/migrate/20250923141845_create_spree_imports.rb +47 -0
  366. data/lib/generators/spree/authentication/devise/devise_generator.rb +24 -0
  367. data/lib/generators/spree/cursor_rules/cursor_rules_generator.rb +19 -0
  368. data/lib/generators/spree/cursor_rules/templates/spree_rules.mdc +387 -0
  369. data/lib/generators/spree/dummy/dummy_generator.rb +0 -1
  370. data/lib/generators/spree/install/install_generator.rb +7 -2
  371. data/lib/generators/spree/install/templates/config/initializers/spree.rb +6 -2
  372. data/lib/spree/core/configuration.rb +1 -0
  373. data/lib/spree/core/dependencies.rb +3 -0
  374. data/lib/spree/core/engine.rb +57 -2
  375. data/lib/spree/core/version.rb +1 -1
  376. data/lib/spree/core.rb +3 -1
  377. data/lib/spree/permitted_attributes.rb +18 -3
  378. data/lib/spree/testing_support/capybara_config.rb +9 -3
  379. data/lib/spree/testing_support/common_rake.rb +1 -0
  380. data/lib/spree/testing_support/factories/export_factory.rb +5 -17
  381. data/lib/spree/testing_support/factories/import_factory.rb +20 -0
  382. data/lib/spree/testing_support/factories/import_mapping_factory.rb +7 -0
  383. data/lib/spree/testing_support/factories/import_row_factory.rb +7 -0
  384. data/lib/spree/testing_support/factories/metafield_definition_factory.rb +72 -0
  385. data/lib/spree/testing_support/factories/metafield_factory.rb +68 -0
  386. data/lib/spree/testing_support/factories/newsletter_subscriber_factory.rb +18 -0
  387. data/lib/spree/testing_support/factories/policy_factory.rb +8 -0
  388. data/lib/spree/testing_support/factories/post_factory.rb +8 -0
  389. data/lib/spree/testing_support/store.rb +11 -0
  390. data/lib/tasks/core.rake +128 -0
  391. metadata +279 -6
  392. data/app/models/action_text/rich_text_decorator.rb +0 -11
  393. data/app/presenters/spree/csv/product_presenter.rb +0 -63
@@ -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
@@ -48,6 +48,30 @@ module Spree
48
48
  say "Please replace < ApplicationRecord with < Spree.base_class in #{user_class_file}"
49
49
  end
50
50
 
51
+ if Spree.admin_user_class != Spree.user_class
52
+ admin_user_class_file = Rails.root.join('app', 'models', "#{Spree.admin_user_class.name.underscore}.rb")
53
+
54
+ if File.exist?(admin_user_class_file)
55
+ inject_into_file admin_user_class_file, after: "class #{Spree.admin_user_class.name} < ApplicationRecord\n" do
56
+ <<-RUBY
57
+ # Spree modules
58
+ include Spree::UserMethods
59
+ RUBY
60
+ end
61
+ gsub_file admin_user_class_file, "< ApplicationRecord", "< Spree.base_class"
62
+
63
+ say "Successfully added Spree admin user modules into #{admin_user_class_file}"
64
+ else
65
+ say "Could not locate admin user model file at #{admin_user_class_file}. Please add these lines manually:", :red
66
+ say <<~RUBY
67
+ # Spree modules
68
+ include Spree::UserMethods
69
+ RUBY
70
+
71
+ say "Please replace < ApplicationRecord with < Spree.base_class in #{admin_user_class_file}"
72
+ end
73
+ end
74
+
51
75
  append_file 'config/initializers/spree.rb' do
52
76
  %Q{
53
77
  if defined?(Devise) && Devise.respond_to?(:parent_controller)
@@ -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