spree_core 5.1.9 → 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 (390) 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 +5 -2
  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 +2 -7
  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 +17 -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/checkout/update.rb +0 -24
  344. data/app/services/spree/imports/row_processors/base.rb +19 -0
  345. data/app/services/spree/imports/row_processors/product_variant.rb +228 -0
  346. data/app/services/spree/line_items/destroy.rb +1 -1
  347. data/app/services/spree/newsletter/subscribe.rb +43 -0
  348. data/app/services/spree/newsletter/verify.rb +30 -0
  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 -3
  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/cursor_rules/cursor_rules_generator.rb +19 -0
  367. data/lib/generators/spree/cursor_rules/templates/spree_rules.mdc +387 -0
  368. data/lib/generators/spree/dummy/dummy_generator.rb +0 -1
  369. data/lib/generators/spree/install/templates/config/initializers/spree.rb +5 -0
  370. data/lib/spree/core/configuration.rb +1 -0
  371. data/lib/spree/core/dependencies.rb +3 -0
  372. data/lib/spree/core/engine.rb +57 -2
  373. data/lib/spree/core/version.rb +1 -1
  374. data/lib/spree/core.rb +3 -1
  375. data/lib/spree/permitted_attributes.rb +18 -3
  376. data/lib/spree/testing_support/capybara_config.rb +9 -3
  377. data/lib/spree/testing_support/factories/export_factory.rb +5 -17
  378. data/lib/spree/testing_support/factories/import_factory.rb +20 -0
  379. data/lib/spree/testing_support/factories/import_mapping_factory.rb +7 -0
  380. data/lib/spree/testing_support/factories/import_row_factory.rb +7 -0
  381. data/lib/spree/testing_support/factories/metafield_definition_factory.rb +72 -0
  382. data/lib/spree/testing_support/factories/metafield_factory.rb +68 -0
  383. data/lib/spree/testing_support/factories/newsletter_subscriber_factory.rb +18 -0
  384. data/lib/spree/testing_support/factories/policy_factory.rb +8 -0
  385. data/lib/spree/testing_support/factories/post_factory.rb +8 -0
  386. data/lib/spree/testing_support/store.rb +11 -0
  387. data/lib/tasks/core.rake +128 -0
  388. metadata +279 -6
  389. data/app/models/action_text/rich_text_decorator.rb +0 -11
  390. data/app/presenters/spree/csv/product_presenter.rb +0 -63
@@ -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