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
@@ -0,0 +1 @@
1
+ <svg width="38" height="24" viewBox="0 0 38 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-labelledby="pi-usdc" role="img"><title id="pi-usdc">USDC</title><g clip-path="url(#pi-usdc-clip0)"><path opacity=".07" d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3z" fill="#000"/><path d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32z" fill="#fff"/><path d="M19 20.2a8.2 8.2 0 100-16.4 8.2 8.2 0 000 16.4z" fill="#0B53BF"/><path d="M20.98 13.054c0-1.035-.629-1.384-1.847-1.552-.9-.13-1.075-.34-1.075-.76s.305-.682.888-.682c.53 0 .837.184.963.612a.225.225 0 00.214.164h.466a.208.208 0 00.208-.242c-.148-.675-.603-1.082-1.317-1.209v-.712a.222.222 0 00-.221-.222h-.445a.222.222 0 00-.222.222v.687c-.886.125-1.447.71-1.447 1.462 0 .97.592 1.348 1.828 1.515.84.138 1.08.32 1.08.797 0 .478-.406.798-.98.798-.773 0-1.035-.338-1.122-.777a.224.224 0 00-.218-.18h-.505a.206.206 0 00-.206.24c.13.74.604 1.28 1.57 1.41v.702a.222.222 0 00.222.222h.445a.222.222 0 00.221-.222v-.7c.917-.146 1.5-.779 1.5-1.573z" fill="#fff"/><path d="M17.32 16.597a4.896 4.896 0 010-9.195.354.354 0 00.211-.308v-.458a.232.232 0 00-.208-.253.231.231 0 00-.118.02 5.874 5.874 0 000 11.193.231.231 0 00.326-.233v-.456a.354.354 0 00-.21-.309l-.001-.001zm3.474-10.193a.232.232 0 00-.326.233v.457a.352.352 0 00.211.308 4.896 4.896 0 010 9.196.325.325 0 00-.21.309v.457a.233.233 0 00.326.233 5.874 5.874 0 000-11.193h-.001z" fill="#fff"/></g><defs><clipPath id="pi-usdc-clip0"><path fill="#fff" d="M0 0h38v24H0z"/></clipPath></defs></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 38 24" width="38" height="24" aria-labelledby="pi-usdt"><title id="pi-usdt">USDT</title><path fill="#000" opacity=".07" d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3z"/><path fill="#fff" d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32"/><g fill-rule="evenodd"><path d="M12.962 4.439l-3.249 6.825a.132.132 0 00.029.154l8.775 8.409a.134.134 0 00.186 0l8.775-8.409a.132.132 0 00.028-.154l-3.249-6.825a.131.131 0 00-.12-.077H13.083a.131.131 0 00-.12.077z" fill="#50af95"/><path d="M19.737 11.964c-.063.005-.388.024-1.114.024-.578 0-.987-.017-1.131-.024-2.232-.097-3.898-.486-3.898-.952s1.666-.853 3.898-.953v1.518c.145.011.564.036 1.141.036.693 0 1.04-.029 1.103-.035v-1.517c2.226.099 3.888.487 3.888.952s-1.66.852-3.889.95zm0-2.06V8.546h3.108V6.475h-8.461v2.071h3.107v1.357c-2.526.117-4.425.617-4.425 1.216s1.899 1.1 4.425 1.216v4.352h2.246v-4.354c2.52-.116 4.416-.615 4.416-1.215s-1.894-1.098-4.416-1.215zm0 0z" fill="#fff"/></g></svg>
@@ -0,0 +1 @@
1
+ <svg viewBox="0 0 38 24" width="38" height="24" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="pi-venmo"><title id="pi-venmo">Venmo</title><g fill="none" fill-rule="evenodd"><rect fill-opacity=".07" fill="#000" width="38" height="24" rx="3"/><path fill="#3D95CE" d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32"/><path d="M24.675 8.36c0 3.064-2.557 7.045-4.633 9.84h-4.74L13.4 6.57l4.151-.402 1.005 8.275c.94-1.566 2.099-4.025 2.099-5.702 0-.918-.154-1.543-.394-2.058l3.78-.783c.437.738.634 1.499.634 2.46z" fill="#FFF" fill-rule="nonzero"/></g></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="38" height="24" aria-labelledby="pi-vipps" role="img" viewBox="0 0 38 24"><title id="pi-vipps">Vipps</title><path fill="#000" d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3z" opacity=".07"/><path fill="#fff" d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32"/><path fill="#ff5b24" d="M3 2h32c.5 0 1 .4 1 1v18c0 .5-.4 1-1 1H3c-.5 0-1-.4-1-1V3c0-.5.4-1 1-1z"/><path fill="#fff" d="m7.45 9.26 1.2 3.52 1.2-3.52h1.4l-2.08 5.22H8.13L6.05 9.26zm6.91 4.38a2.17 2.17 0 0 0 1.84-1.04c.26-.32.59-.4.83-.2a.6.6 0 0 1 0 .88 3.27 3.27 0 0 1-2.67 1.43 3.54 3.54 0 0 1-3-1.81.56.56 0 0 1 .06-.8.57.57 0 0 1 .8.24 2.58 2.58 0 0 0 2.14 1.3zm1.63-2.9a.7.7 0 1 1-.7-.7.71.71 0 0 1 .7.7zm3.31-1.48v.71a1.97 1.97 0 0 1 1.7-.84c1.01 0 2.2.84 2.2 2.67 0 1.9-1.13 2.82-2.31 2.82a1.88 1.88 0 0 1-1.6-.83v2.5h-1.28V9.26zm0 2.6c0 1.05.61 1.62 1.3 1.62.67 0 1.31-.51 1.31-1.62 0-1.09-.64-1.6-1.31-1.6-.69 0-1.3.49-1.3 1.6zm6.13-2.6v.71a1.97 1.97 0 0 1 1.69-.84c1.02 0 2.2.84 2.2 2.67 0 1.9-1.13 2.82-2.3 2.82a1.88 1.88 0 0 1-1.6-.83v2.5h-1.28V9.26zm0 2.6c0 1.05.61 1.62 1.3 1.62.67 0 1.31-.51 1.31-1.62 0-1.09-.64-1.6-1.31-1.6-.69 0-1.3.49-1.3 1.6zm6.6-2.74a2.04 2.04 0 0 1 2.13 1.72l-1.15.18c-.02-.6-.4-.82-.96-.82-.43 0-.76.19-.76.5 0 .24.16.48.66.56l.88.17a1.47 1.47 0 0 1 1.3 1.48 1.8 1.8 0 0 1-1.97 1.7 2.15 2.15 0 0 1-2.31-1.8l1.15-.18c.08.65.48.89 1.14.89.49 0 .82-.2.82-.5 0-.28-.16-.5-.7-.6l-.8-.14a1.54 1.54 0 0 1-1.37-1.5 1.8 1.8 0 0 1 1.93-1.68z"/></svg>
@@ -0,0 +1 @@
1
+ <svg viewBox="0 0 38 24" xmlns="http://www.w3.org/2000/svg" role="img" width="38" height="24" aria-labelledby="pi-visa"><title id="pi-visa">Visa</title><path opacity=".07" d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3z"/><path fill="#fff" d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32"/><path d="M28.3 10.1H28c-.4 1-.7 1.5-1 3h1.9c-.3-1.5-.3-2.2-.6-3zm2.9 5.9h-1.7c-.1 0-.1 0-.2-.1l-.2-.9-.1-.2h-2.4c-.1 0-.2 0-.2.2l-.3.9c0 .1-.1.1-.1.1h-2.1l.2-.5L27 8.7c0-.5.3-.7.8-.7h1.5c.1 0 .2 0 .2.2l1.4 6.5c.1.4.2.7.2 1.1.1.1.1.1.1.2zm-13.4-.3l.4-1.8c.1 0 .2.1.2.1.7.3 1.4.5 2.1.4.2 0 .5-.1.7-.2.5-.2.5-.7.1-1.1-.2-.2-.5-.3-.8-.5-.4-.2-.8-.4-1.1-.7-1.2-1-.8-2.4-.1-3.1.6-.4.9-.8 1.7-.8 1.2 0 2.5 0 3.1.2h.1c-.1.6-.2 1.1-.4 1.7-.5-.2-1-.4-1.5-.4-.3 0-.6 0-.9.1-.2 0-.3.1-.4.2-.2.2-.2.5 0 .7l.5.4c.4.2.8.4 1.1.6.5.3 1 .8 1.1 1.4.2.9-.1 1.7-.9 2.3-.5.4-.7.6-1.4.6-1.4 0-2.5.1-3.4-.2-.1.2-.1.2-.2.1zm-3.5.3c.1-.7.1-.7.2-1 .5-2.2 1-4.5 1.4-6.7.1-.2.1-.3.3-.3H18c-.2 1.2-.4 2.1-.7 3.2-.3 1.5-.6 3-1 4.5 0 .2-.1.2-.3.2M5 8.2c0-.1.2-.2.3-.2h3.4c.5 0 .9.3 1 .8l.9 4.4c0 .1 0 .1.1.2 0-.1.1-.1.1-.1l2.1-5.1c-.1-.1 0-.2.1-.2h2.1c0 .1 0 .1-.1.2l-3.1 7.3c-.1.2-.1.3-.2.4-.1.1-.3 0-.5 0H9.7c-.1 0-.2 0-.2-.2L7.9 9.5c-.2-.2-.5-.5-.9-.6-.6-.3-1.7-.5-1.9-.5L5 8.2z" fill="#142688"/></svg>
@@ -0,0 +1 @@
1
+ <svg width="38" height="24" viewBox="0 0 38 24" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="pi-volksbank"><title id="pi-volksbank">Volksbank</title><g clip-path="url(#clip0_39_168)"><path opacity=".07" d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3z" fill="#000"/><path d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32z" fill="#fff"/><g clip-path="url(#clip1_39_168)"><path d="M5.91 3v18h26.18V3H5.91z" fill="#fff"/><path d="M21.852 17.146l-.562 2.959h10.049v-2.959h-9.487zm-15.4.027v2.959h9.977l-.666-2.959H6.451z" fill="#E05F0C"/><path d="M11.354 10.39l-.727-3.06h6.196l2.007 8.785h.086l1.264-5.628c.637-2.555.878-3.157 4.468-3.157h2.582s-.522 2.355-1.171 4.911c-.247.975-2.403.86-2.296-.051.012-.095.114-.78.194-1.268.118-.701-.7-.789-.847-.095-.104.498-.578 2.966-1.02 5.288h9.25V3.5H6.45v12.614h9.033l-1.287-5.72-2.842-.005z" fill="#0A438A"/></g></g><defs><clipPath id="pi-volksbank-clip0_39_168"><path fill="#fff" d="M0 0h38v24H0z"/></clipPath><clipPath id="pi-volksbank-clip1_39_168"><path fill="#fff" transform="translate(5.91 3)" d="M0 0h26.182v18H0z"/></clipPath></defs></svg>
@@ -0,0 +1 @@
1
+ <svg role="img" viewBox="0 0 38 24" width="38" height="24" aria-labelledby="pi-waavepaybybank" fill="none" xmlns="http://www.w3.org/2000/svg"><title id="pi-waavepaybybank">Waave Pay by Bank</title><g clip-path="url(#clip0_715_72196)"><path d="M2.84 1h32.328C36.176 1 37 1.824 37 2.836v18.328A1.838 1.838 0 0135.168 23H2.84a1.838 1.838 0 01-1.832-1.836V2.836C1.008 1.824 1.832 1 2.84 1z" fill="#7971ED" /><path d="M2.832 0H35.16c.781 0 1.492.32 2 .832v.004a2.83 2.83 0 01.832 2v18.328a2.83 2.83 0 01-.832 2v.004a2.816 2.816 0 01-2 .832H2.832c-.781 0-1.492-.32-2-.832v-.004a2.83 2.83 0 01-.832-2V2.836c0-.777.32-1.488.832-2V.832a2.816 2.816 0 012-.832zm0 1H35.16c1.008 0 1.832.824 1.832 1.836v18.328A1.838 1.838 0 0135.16 23H2.832A1.838 1.838 0 011 21.164V2.836C1 1.824 1.824 1 2.832 1z" fill="#000" fill-opacity=".071" /><path d="M31 6.014h-.8c-.33 0-.658.128-.915.34a1.363 1.363 0 00-.458.852 51.368 51.368 0 01-.457 2.85c-.8 4.299-1.244 5.93-2.716 5.93-.658 0-1.515-.355-1.987-2.61-.515-2.397-.743-3.872-1.344-5.135-.743-1.603-1.83-2.227-3.33-2.227-1.501 0-2.602.624-3.33 2.227-.587 1.263-.816 2.738-1.33 5.15C13.847 15.644 12.989 16 12.346 16c-1.472 0-1.915-1.631-2.716-5.93-.214-1.134-.329-1.97-.457-2.85-.043-.34-.2-.638-.458-.865A1.473 1.473 0 007.8 6H7l.043.397c.143 1.12.3 2.397.6 4.028.372 1.986.744 3.873 1.315 5.192.73 1.603 1.83 2.383 3.36 2.383 2.844 0 3.716-2.993 3.945-4.17.671-3.461 1.057-5.816 2.716-5.816 1.658 0 2.058 2.34 2.73 5.816.229 1.191 1.115 4.17 3.945 4.17 1.53 0 2.63-.794 3.36-2.383.6-1.32.942-3.192 1.314-5.192.315-1.645.472-2.907.6-4.028L30.971 6" fill="#fff" /></g><defs><clipPath id="pi-waavepaybybank-clip0_715_72196"><path fill="#fff" d="M0 0h38v24H0z" /></clipPath></defs></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 38 24" width="38" height="24" aria-labelledby="pi-walley"><title id="pi-walley">Walley</title><path fill="#000" opacity=".07" d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3z"/><path fill="#fff" d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32"/><path d="M11.5 9.39v3.28L8.16 11a.51.51 0 00-.45 0l-3.34 1.67V9.39H1.76l1.55.9v3.28a.46.46 0 00.69.35l4-2 3.94 2a.46.46 0 00.69-.35V9.39zM19.34 11.71V14h-1.12v-.56a6.84 6.84 0 01-2.9.69c-1.36 0-2.11-.46-2.11-1.5s1.26-1.56 2.68-1.56a9.1 9.1 0 012.33.33c0-1-1.22-1.11-1.88-1.11a8 8 0 00-2.43.39l-.33-.84a9.78 9.78 0 012.9-.45c1.88 0 2.84.59 2.86 2.33zm-1.12 1v-.45a8.2 8.2 0 00-2.22-.35c-1 0-1.59.19-1.59.67s.48.63 1.27.63a8.7 8.7 0 002.55-.54zM20 8h1.11v6H20zM21.84 8H23v6h-1.16zM28.48 12.47h1.16c-.27 1-1.3 1.64-2.95 1.64-1.85 0-3.13-.76-3.13-2.36s1.33-2.35 3.06-2.35 3.08.67 3.08 2.6h-5c.11.85.8 1.19 2 1.19s1.56-.29 1.77-.72zm-3.69-1.26h3.69c-.2-.66-.83-1-1.86-1s-1.62.28-1.83 1z"/><path d="M35 9.4h1.26l-2.69 4.9C33 15.4 32.38 16 31.19 16a7.43 7.43 0 01-1.56-.18v-1a6.28 6.28 0 001.36.17c.67 0 1-.19 1.44-1v-.07h-.61L29.33 9.4h1.28l2.18 4z"/></svg>
@@ -0,0 +1 @@
1
+ <svg width="38" height="24" viewBox="0 0 38 24" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="pi-wbtc"><title id="pi-wbtc">Wrapped Bitcoin</title><path opacity=".07" d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3z" fill="#000"/><path d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32z" fill="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M19 4c2.136 0 4.076.837 5.511 2.201A8 8 0 0119 20a8 8 0 010-16z" fill="#282A47"/><path d="M23.959 7.335l-.437.437a6.177 6.177 0 010 8.337l.437.436a6.801 6.801 0 000-9.22v.01zM14.782 7.373a6.178 6.178 0 018.337 0l.437-.436a6.801 6.801 0 00-9.22 0l.446.436zM14.373 16.113a6.177 6.177 0 010-8.333l-.436-.436a6.802 6.802 0 000 9.22l.436-.45zM23.113 16.516a6.177 6.177 0 01-8.337 0l-.436.437a6.801 6.801 0 009.22 0l-.447-.437z" fill="#54588C"/><path fill-rule="evenodd" clip-rule="evenodd" d="M21.701 10.49c-.087-.91-.873-1.216-1.866-1.309V7.927h-.768v1.23h-.614v-1.23h-.762V9.19h-1.558v.822s.567-.01.559 0a.397.397 0 01.436.337v3.456a.269.269 0 01-.093.188.266.266 0 01-.198.067c.01.008-.558 0-.558 0l-.146.917h1.543v1.283h.768v-1.264h.614v1.258h.77v-1.268c1.297-.078 2.202-.398 2.315-1.613.092-.977-.368-1.414-1.102-1.59.446-.22.723-.627.66-1.293zm-1.076 2.732c0 .876-1.378.856-2.007.847l-.149-.002v-1.693l.192-.003c.646-.014 1.964-.043 1.964.85zM18.6 11.605c.527.009 1.667.03 1.667-.769 0-.818-1.104-.789-1.641-.775l-.156.003v1.539c.037 0 .08 0 .13.002z" fill="#fff"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 38 24" width="38" height="24" aria-labelledby="pi-wechatpay"><title id="pi-wechatpay">WeChat Pay</title><path fill="#000" opacity=".07" d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3z"/><path fill="#fff" d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32"/><path fill="#39B54A" d="M17.1,9.6c-0.1,0-0.1,0-0.2,0.1c-0.2,0-0.3-0.1-0.4-0.2V9.3l-1.3-2.8c0,0,0-0.1,0-0.1c0-0.1,0.1-0.2,0.2-0.2c0.1,0,0.1,0,0.1,0.1L17,7.3c0.1,0.1,0.2,0.1,0.4,0.1c0.1,0,0.2,0,0.2,0l7.1-3.2c-1.5-1.6-3.5-2.5-5.7-2.5c-3.9,0-7,2.6-7,5.9c0,1.8,0.9,3.4,2.4,4.4c0.1,0.1,0.2,0.2,0.2,0.4c0,0,0,0.1,0,0.1c-0.1,0.4-0.3,1.1-0.3,1.2c0,0.1,0,0.1,0,0.2c0,0.1,0.1,0.2,0.2,0.2c0,0,0.1,0,0.1,0l1.5-0.9c0.1-0.1,0.2-0.1,0.4-0.1c0.1,0,0.1,0,0.2,0c0.7,0.2,1.5,0.3,2.3,0.3c3.9,0,7-2.6,7-5.9c0-0.9-0.3-1.8-0.8-2.6L17.1,9.6L17.1,9.6z"/><path fill="#505052" d="M10.5,19.8L10.4,20c-0.1,0.2-0.1,0.4-0.2,0.6c-0.1-0.3-0.1-0.6-0.2-0.9l-0.5-1.8l0,0H9.2l-0.6,1.9c-0.1,0.3-0.2,0.6-0.2,0.9L8.3,20l-0.5-2.1l0,0H7.4l0.9,3.4l0,0h0.3l0.6-1.9c0.1-0.3,0.2-0.6,0.2-0.8c0,0.2,0.1,0.5,0.2,0.8l0.5,1.9l0,0h0.3l1-3.3l0,0h-0.4L10.5,19.8z"/><path fill="#505052" d="M12.6,18.8c-0.7,0-1.1,0.5-1.1,1.3c-0.1,0.6,0.4,1.2,1,1.2c0,0,0.1,0,0.1,0c0.3,0,0.5,0,0.8-0.2h0.1l-0.2-0.2l0,0C13.1,21,12.9,21,12.7,21c-0.5,0-0.8-0.3-0.8-0.9h1.7v0c0,0,0-0.1,0-0.1c0-0.2-0.1-0.5-0.2-0.7C13.2,19,12.9,18.8,12.6,18.8 M11.8,19.8c0-0.4,0.3-0.7,0.7-0.7c0.2,0,0.3,0,0.4,0.2c0.1,0.1,0.2,0.3,0.2,0.5H11.8z"/><path fill="#505052" d="M16.3,20.9L16.3,20.9c-0.2,0.1-0.5,0.1-0.7,0.1c-0.7,0-1.3-0.5-1.3-1.1c0-0.1,0-0.2,0-0.2c-0.1-0.7,0.4-1.4,1.1-1.4c0.1,0,0.2,0,0.2,0c0.2,0,0.4,0,0.6,0.1l0,0l0.2-0.3l0,0c-0.2-0.1-0.5-0.2-0.8-0.2c-0.9,0-1.7,0.7-1.7,1.6c0,0.1,0,0.1,0,0.2c-0.1,0.9,0.5,1.6,1.4,1.7c0.1,0,0.1,0,0.2,0c0.3,0,0.6-0.1,0.9-0.2l0,0L16.3,20.9L16.3,20.9z"/><path fill="#505052" d="M18,18.8c-0.2,0-0.4,0.1-0.5,0.1c-0.1,0.1-0.2,0.1-0.2,0.2v-1.3h-0.4v3.5h0.3v-1.5c0-0.1,0-0.1,0-0.2c0.1-0.3,0.3-0.5,0.6-0.5c0.5,0,0.6,0.5,0.6,0.7v1.4h0.4v-1.5C18.8,18.8,18.1,18.8,18,18.8"/><path fill="#505052" d="M22.1,18.3h-0.4v0.5h-0.4v0.3h0.4v1.4c0,0.2,0,0.4,0.2,0.6c0.1,0.1,0.3,0.2,0.4,0.2c0.1,0,0.2,0,0.4-0.1h0.1L22.6,21l0,0h-0.2c-0.2,0-0.3-0.1-0.3-0.4v-1.5h0.7v-0.3h-0.7L22.1,18.3z"/><path fill="#505052" d="M25.1,17.9c-0.2,0-0.5,0-0.7,0.1l0,0v3.3h0.4v-1.4c0.1,0,0.2,0,0.3,0c0.4,0,0.7-0.1,1-0.4c0.2-0.2,0.3-0.4,0.2-0.7c0-0.3-0.1-0.5-0.3-0.7C25.8,18,25.5,17.8,25.1,17.9 M24.7,18.2c0.1,0,0.3,0,0.4,0c0.5,0,0.8,0.2,0.8,0.7s-0.3,0.7-0.9,0.7c-0.1,0-0.2,0-0.4,0L24.7,18.2z"/><path fill="#505052" d="M30.2,18.8l-0.6,1.5c0,0.1-0.1,0.2-0.1,0.4l-0.1-0.3l-0.6-1.5l0,0h-0.4l0.9,2.2c0,0,0,0.1,0,0.1c0,0,0,0,0,0.1c-0.1,0.2-0.2,0.4-0.4,0.6c-0.1,0.1-0.2,0.2-0.4,0.2h-0.1l0.3,0.3l0,0c0.1-0.1,0.2-0.2,0.3-0.2c0.4-0.4,0.6-0.9,0.8-1.4l0.7-1.8v-0.1L30.2,18.8z"/><path fill="#505052" d="M21,20.7v-0.9c0-0.6-0.3-1-0.9-1c-0.3,0-0.5,0.1-0.7,0.2l0,0l0.2,0.3l0,0c0.2-0.1,0.3-0.2,0.5-0.2l0,0c0.1,0,0.3,0,0.4,0.1c0.1,0.1,0.2,0.3,0.1,0.5c-0.4,0-0.9,0.1-1.2,0.4c-0.2,0.1-0.2,0.3-0.2,0.6c0,0.4,0.3,0.7,0.7,0.7c0,0,0,0,0.1,0c0.3,0,0.5-0.1,0.7-0.3v0.2h0.4v-0.1C21,21,21,20.8,21,20.7 M19.8,20.3c0.3-0.2,0.6-0.3,0.9-0.2l0,0v0.4c0,0,0,0.1,0,0.1C20.6,20.9,20.3,21,20,21c-0.2,0-0.4-0.2-0.4-0.4c0,0,0,0,0-0.1C19.6,20.5,19.7,20.3,19.8,20.3"/><path fill="#505052" d="M28.1,20.7v-0.9c0-0.6-0.3-1-0.9-1c-0.2,0-0.5,0.1-0.7,0.2l0,0l0.2,0.3l0,0c0.2-0.1,0.3-0.1,0.5-0.1l0,0c0.1,0,0.3,0,0.4,0.1c0.1,0.1,0.2,0.3,0.2,0.5c-0.4,0-0.9,0.1-1.2,0.4c-0.1,0.1-0.2,0.4-0.2,0.6c0,0.4,0.3,0.7,0.7,0.7c0,0,0,0,0.1,0c0.3,0,0.5-0.1,0.7-0.3v0.2h0.4v-0.1C28.2,21,28.2,20.8,28.1,20.7 M27.9,20.5c0,0,0,0.1,0,0.1c-0.1,0.3-0.4,0.4-0.6,0.4c-0.2,0-0.4-0.1-0.4-0.4c0,0,0,0,0-0.1c0-0.1,0-0.2,0.1-0.3c0.3-0.2,0.6-0.3,0.9-0.2h0L27.9,20.5z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 38 24" width="38" height="24" aria-labelledby="pi-whishcheckout"><title id="pi-whishcheckout">Whish Checkout</title><path fill="#000" opacity=".07" d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3z"/><path fill="#fff" d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32"/><path fill="#e81c48" d="M16.638 7.92h18.896v6.458c-.258.877-.863 1.481-1.759 1.702H18.447c-1.05-.256-1.73-1.046-1.811-2.126l.002-6.034zm3.203 3.016c-1.479.238-1.071 3.067.556 1.866-.233-.49-.225-.252-.516-.222-.712.074-.325-1.308.189-1.147.076.023.12.148.202.135.049-.007.317-.219.328-.276.056-.296-.54-.391-.759-.356zm5.901.63c.08.036.619-.249.241-.515-.578-.406-1.4.178-1.492.812-.103.706.131 1.342.964 1.21.166-.026.522-.181.435-.374-.156-.347-.235-.155-.435-.125-.786.118-.383-1.362.218-1.116.061.025.062.105.07.108zm3.247-.63c-1.081.146-1.306 2.05-.214 2.14 1.39.117 1.674-2.335.214-2.14zm-7.426.038c-.095.017-.522-.025-.55.002-.076.073-.287 1.803-.405 2.05.13-.023.465.044.556-.021.091-.066.105-.77.177-.783l.523.004-.15.8.558-.029.397-2.023c-.102.02-.506-.031-.548.005-.046.039-.082.615-.15.717-.049.073-.444.007-.559.028l.151-.75zm2.814 0h-1.306l-.402 2.052h1.357c.022 0 .043-.404.05-.45h-.754c.042-.576.358-.253.672-.358.116-.039.092-.37.132-.493h-.603c-.163-.524.712-.206.804-.301.015-.016.03-.377.05-.45zm2.714 0h-.552l-.403 2.052c.13-.023.466.044.557-.021.097-.07.031-.697.373-.73.043 0 .202.72.231.746.043.037.492-.015.598.005l-.435-1.177.737-.875c-.164.028-.526-.052-.653.025-.133.08-.365.541-.553.626l.1-.651zm3.92 0c-.117.024-.476-.038-.546.006-.055.035-.251 1.135-.258 1.272-.027.614.314.9.926.82.859-.113.74-1.464.983-2.074-.109-.014-.466-.068-.545-.018-.06.038-.216 1.17-.306 1.373-.08.184-.311.34-.46.152-.162-.205.206-1.23.206-1.53zm2.915 0h-1.533c-.073 0-.115.368-.125.45l.503.026-.303 1.576c.146-.026.4.037.523.003.098-.027.275-1.545.334-1.602.033-.032.524.024.55-.003.016-.016.03-.377.051-.45z"/><path fill="#e81c48" d="M15.934 7.92l.001 6.232c.085.762.449 1.372.954 1.928H2.466V9.672c.243-.908.894-1.527 1.809-1.752h11.66zm-5.653 2.303H7.994l.063.112 1.244.388H5.557c-.031 0-.097.104-.076.15l3.77.501H4.425c-.038.175.248.081.335.142l4.64.71H6.587l.128.147 3.138.603H8.094c-.018.108.048.12.127.15.496.192 2.088.572 2.625.638.234.029.463.053.609-.169.204-.31.322-.932.507-1.296.024-.048.032-.12.102-.124.07.055.41 1.273.603 1.478.098.103.189.12.326.128.401.021.427-.122.567-.441.266-.602.618-1.629.792-2.266.111-.41.087-.855-.453-.856-.571-.001-.67 1.113-.855 1.557-.02.048-.005.114-.074.1-.104-.318-.444-1.554-.74-1.642-.782-.23-.884 1.01-1.118 1.519-.023.05-.031.117-.102.123-.12-.34-.36-1.573-.73-1.652zM28.711 12.514c-.121-.121-.063-.59.002-.751.094-.237.425-.513.6-.225.283.464-.256 1.318-.602.976z"/></svg>
@@ -0,0 +1 @@
1
+ <svg width="38" height="24" viewBox="0 0 38 24" fill="none" role="img" aria-labelledby="pi-wingbank"><title id="pi-wingbank">Wing Bank</title><rect x="1" y="1" width="36" height="22" rx="2" fill="#AAD039"/><rect x=".5" y=".5" width="37" height="23" rx="2.5" stroke="#000" stroke-width="1" stroke-opacity=".07"/><path d="M4.085 13.86l1.797-4.547h.598l-.098 1.011L4.484 15h-.637l.238-1.14zm.016-4.547l.188 4.628L4.136 15h-.695l-.36-5.688h1.02zm2.86 4.515l1.585-4.515h1.067L7.473 15H6.78l.18-1.172zm-.192-4.515l.383 4.664L7.066 15h-.633L6 10.234l.171-.921h.598zm3.717 1.46L9.756 15H8.744l.735-4.227h1.007zm-.882-1.085a.507.507 0 01.16-.399.595.595 0 01.41-.16.575.575 0 01.398.14.468.468 0 01.172.383.497.497 0 01-.164.395.599.599 0 01-.406.156.584.584 0 01-.399-.137.48.48 0 01-.171-.379zm2.096 2.046L11.133 15h-1.011l.734-4.227h.945l-.101.961zm-.324 1l-.278.004c.031-.252.091-.501.18-.746.088-.247.208-.47.36-.668a1.7 1.7 0 01.558-.469c.219-.114.473-.169.762-.164.231.008.423.056.574.145a.933.933 0 01.355.355c.084.146.137.314.16.504.026.19.028.388.004.594L13.602 15h-1.015l.457-2.723c.015-.145.01-.276-.016-.39a.441.441 0 00-.16-.27c-.084-.068-.206-.103-.367-.105a.881.881 0 00-.454.097c-.13.07-.24.166-.332.286-.09.12-.164.253-.218.402a2.494 2.494 0 00-.121.437zm5.877-1.96h.926l-.7 4.093c-.051.38-.178.706-.378.977-.198.273-.452.48-.762.62a2.297 2.297 0 01-1.586.114 1.862 1.862 0 01-.512-.234 1.637 1.637 0 01-.406-.375l.512-.598c.117.156.255.279.414.367.159.089.336.136.531.14.211.006.397-.032.559-.112a1.04 1.04 0 00.402-.348c.104-.151.175-.33.211-.535l.543-3.195.246-.915zm-3.137 2.19l.012-.081c.031-.266.094-.529.188-.79.093-.262.218-.5.375-.714a1.77 1.77 0 01.582-.508 1.56 1.56 0 01.8-.176c.28.008.506.077.68.207.177.128.313.296.406.504.097.206.16.43.192.672.034.24.044.477.031.711l-.023.223c-.045.24-.116.483-.215.73a2.82 2.82 0 01-.38.676c-.153.206-.338.37-.554.492a1.39 1.39 0 01-.738.172c-.281-.008-.516-.077-.703-.207-.185-.13-.33-.3-.434-.508a2.175 2.175 0 01-.207-.68 3.207 3.207 0 01-.012-.722zm1.024-.085l-.012.086a3.45 3.45 0 00-.015.41c.005.146.028.285.07.418a.74.74 0 00.203.328.601.601 0 00.395.137.903.903 0 00.539-.13c.156-.098.283-.228.382-.39.1-.161.168-.336.207-.523l.09-.617c.01-.128.007-.256-.011-.383a1.01 1.01 0 00-.114-.348.671.671 0 00-.605-.352.822.822 0 00-.477.114 1.104 1.104 0 00-.336.332 1.829 1.829 0 00-.21.45 2.51 2.51 0 00-.106.468z" fill="#fff"/><path d="M21.871 12.465h-1.464l.128-.758 1.153.004c.18 0 .35-.026.512-.078.164-.055.3-.14.41-.258a.833.833 0 00.21-.469c.024-.18.007-.323-.05-.43a.489.489 0 00-.274-.234 1.328 1.328 0 00-.433-.078l-.906-.004-.84 4.84h-1.051l.984-5.688 1.844.004c.242.003.474.033.695.09.224.055.42.14.59.258.172.117.304.272.395.465.093.19.13.423.11.7-.02.299-.108.546-.267.741a1.481 1.481 0 01-.601.446c-.242.101-.5.161-.773.18l-.372.269zM21.4 15h-1.762l.582-.844 1.215.004a1.41 1.41 0 00.508-.098.92.92 0 00.598-.762.917.917 0 00-.028-.429.51.51 0 00-.219-.285.795.795 0 00-.414-.117l-1.14-.004.136-.758 1.34.004.184.289c.247.02.462.086.644.195.185.11.323.258.414.446.094.187.133.409.117.664-.028.4-.147.726-.355.976-.206.25-.469.434-.789.551-.32.115-.664.17-1.031.168zm4.588-.898l.309-1.965a.806.806 0 00-.024-.34.46.46 0 00-.164-.25.54.54 0 00-.328-.098.815.815 0 00-.34.063.697.697 0 00-.258.191.691.691 0 00-.144.305l-1.008.008a1.14 1.14 0 01.2-.594 1.4 1.4 0 01.445-.414 2.258 2.258 0 011.206-.312c.29.005.548.066.774.183.227.117.4.284.52.5.12.213.164.474.133.781l-.301 1.844c-.024.15-.04.307-.051.469-.01.159.01.31.062.457l-.003.07-.997.004a1.54 1.54 0 01-.066-.45 3.74 3.74 0 01.035-.452zm.426-1.676l-.102.613-.582-.004c-.12 0-.24.013-.363.04a1.24 1.24 0 00-.336.124.77.77 0 00-.262.223.694.694 0 00-.128.344.492.492 0 00.035.273.44.44 0 00.164.188.553.553 0 00.27.07 1.041 1.041 0 00.78-.332.85.85 0 00.215-.371l.239.453a1.596 1.596 0 01-.235.422 1.664 1.664 0 01-.343.332 1.586 1.586 0 01-.903.285 1.417 1.417 0 01-.644-.164 1.18 1.18 0 01-.457-.434 1.116 1.116 0 01-.153-.64 1.3 1.3 0 01.207-.688 1.38 1.38 0 01.492-.437c.201-.107.42-.184.657-.23.24-.048.475-.071.707-.071l.742.004zm2.315-.692L28.162 15H27.15l.734-4.227h.945l-.101.961zm-.324 1l-.278.004c.032-.252.091-.501.18-.746.089-.247.208-.47.36-.668a1.7 1.7 0 01.558-.469c.219-.114.473-.169.762-.164a1.2 1.2 0 01.574.145.934.934 0 01.356.355c.083.146.136.314.16.504.026.19.027.388.003.594L30.63 15h-1.015l.457-2.723c.015-.145.01-.276-.016-.39a.44.44 0 00-.16-.27c-.083-.068-.206-.103-.367-.105a.881.881 0 00-.453.097c-.13.07-.241.166-.332.286-.092.12-.165.253-.22.402a2.503 2.503 0 00-.12.437zM33 8.996L31.957 15h-1.012l1.043-6.004H33zm2.297 1.777l-2.137 2.059-1.172 1.04-.191-.872.89-.938 1.317-1.289h1.293zM33.527 15l-.949-2.012.742-.633L34.637 15h-1.11z" fill="#0C6DB6"/></svg>
@@ -0,0 +1 @@
1
+ <svg width="38" height="24" viewBox="0 0 38 24" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="pi-xrp"><title id="pi-xrp">XRP</title><path opacity=".07" d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3z" fill="#000"/><path d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32z" fill="#fff"/><circle cx="19" cy="12" r="8" fill="#000"/><mask id="pi-mask0_3_355" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="11" y="4" width="16" height="16"><circle cx="19" cy="12" r="8" fill="#fff"/></mask><g mask="url(#mask0_3_355)"><path fill-rule="evenodd" clip-rule="evenodd" d="M22.773 8.632h-1.095l-1.733 1.796a1.305 1.305 0 01-1.893 0L16.32 8.632h-1.095l2.28 2.364a2.06 2.06 0 002.988 0l2.28-2.364zm-7.563 6.576h1.096l1.75-1.812a1.305 1.305 0 011.892 0l1.746 1.812h1.096l-2.295-2.38a2.061 2.061 0 00-2.99 0l-2.294 2.38z" fill="#fff"/></g></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 38 24" width="38" height="24" aria-labelledby="pi-zip"><title id="pi-zip">Zip</title><path d="M34.9 23H3.1c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h31.8c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2z" fill="#fff"/><path fill="#1a0826" d="M6.5 14.7l.2 1.9h8l-.2-2.2h-3.8v-.2l3.4-2.4-.2-1.9h-8l.3 2.1h3.7v.3z"/><path fill="#aa8fff" d="M14.8 9.9l.9 6.7h8l-.8-6.7z"/><path d="M32.1 12.3c-.2-1.5-1.4-2.4-3-2.4h-5.3l.8 6.7H27l-.2-1.3h2.5c2.1-.1 3-1.3 2.8-3zm-3 1.1h-2.5l-.2-1.6h2.5c.6 0 .9.3.9.8.1.2 0 .8-.7.8z" fill="#1a0826"/><ellipse transform="rotate(-46.771 16.352 8.156)" cx="16.4" cy="8.2" rx="1.1" ry="1.3" fill="#1a0826"/><path d="M34.9 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3.1c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h31.8m0-1H3.1c-1.7 0-3 1.3-3 3v18c0 1.7 1.3 3 3 3h31.8c1.7 0 3-1.3 3-3V3c0-1.6-1.3-3-3-3z" opacity=".07"/></svg>
@@ -0,0 +1,137 @@
1
+ module Spree
2
+ module Posts
3
+ class Find < Spree::BaseFinder
4
+ def initialize(scope:, params:)
5
+ super(scope: scope, params: params)
6
+ @scope = scope
7
+ @query = params[:q].presence&.strip
8
+ @ids = String(params.dig(:filter, :ids)).split(',')
9
+ @slugs = String(params.dig(:filter, :slugs)).split(',')
10
+ @category_ids = String(params.dig(:filter, :category_ids)).split(',')
11
+ @author_ids = String(params.dig(:filter, :author_ids)).split(',')
12
+ @tags = params.dig(:filter, :tags).to_s.split(',').compact_blank
13
+ @sort_by = params[:sort_by]
14
+ @published = params.dig(:filter, :published)
15
+ end
16
+
17
+ def execute
18
+ posts = by_ids(scope)
19
+ posts = by_slugs(posts)
20
+ posts = by_query(posts)
21
+ posts = by_category_ids(posts)
22
+ posts = by_author_ids(posts)
23
+ posts = by_tags(posts)
24
+ posts = by_published(posts)
25
+ posts = ordered(posts)
26
+
27
+ posts.distinct
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :scope, :query, :ids, :slugs, :category_ids, :author_ids, :tags, :sort_by, :published
33
+
34
+ def query?
35
+ query.present?
36
+ end
37
+
38
+ def ids?
39
+ ids.present?
40
+ end
41
+
42
+ def slugs?
43
+ slugs.present?
44
+ end
45
+
46
+ def category_ids?
47
+ category_ids.present?
48
+ end
49
+
50
+ def author_ids?
51
+ author_ids.present?
52
+ end
53
+
54
+ def tags?
55
+ tags.present?
56
+ end
57
+
58
+ def published?
59
+ published.present?
60
+ end
61
+
62
+ def sort_by?
63
+ sort_by.present?
64
+ end
65
+
66
+ def by_query(posts)
67
+ return posts unless query?
68
+
69
+ posts.search_by_title(query)
70
+ end
71
+
72
+ def by_ids(posts)
73
+ return posts unless ids?
74
+
75
+ posts.where(id: ids)
76
+ end
77
+
78
+ def by_slugs(posts)
79
+ return posts unless slugs?
80
+
81
+ posts.where(slug: slugs)
82
+ end
83
+
84
+ def by_category_ids(posts)
85
+ return posts unless category_ids?
86
+
87
+ posts.where(post_category_id: category_ids)
88
+ end
89
+
90
+ def by_author_ids(posts)
91
+ return posts unless author_ids?
92
+
93
+ posts.where(author_id: author_ids)
94
+ end
95
+
96
+ def by_tags(posts)
97
+ return posts if tags.empty?
98
+
99
+ posts.tagged_with(tags, any: true)
100
+ end
101
+
102
+ def by_published(posts)
103
+ return posts unless published?
104
+
105
+ case published.to_s
106
+ when 'true'
107
+ posts.published
108
+ when 'false'
109
+ posts.where(published_at: nil)
110
+ else
111
+ posts
112
+ end
113
+ end
114
+
115
+ def ordered(posts)
116
+ return posts unless sort_by?
117
+
118
+ case sort_by
119
+ when 'newest-first'
120
+ posts.by_newest
121
+ when 'oldest-first'
122
+ posts.order(created_at: :asc)
123
+ when 'published-newest'
124
+ posts.order(published_at: :desc)
125
+ when 'published-oldest'
126
+ posts.order(published_at: :asc)
127
+ when 'title-a-z'
128
+ posts.order(title: :asc)
129
+ when 'title-z-a'
130
+ posts.order(title: :desc)
131
+ else
132
+ posts
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -67,16 +67,22 @@ module Spree
67
67
  end
68
68
 
69
69
  def current_store_countries_with_states_ids
70
- @current_store_countries_with_states_ids ||= current_store.countries_available_for_checkout.where(states_required: true).includes(:states).each_with_object([]) do |country, memo|
70
+ Spree::Deprecation.warn('current_store_countries_with_states_ids is deprecated and will be removed in Spree 5.3')
71
+
72
+ @current_store_countries_with_states_ids ||= current_store.countries_available_for_checkout.find_all { |country| country.states_required? }.each_with_object([]) do |country, memo|
71
73
  memo << current_store.states_available_for_checkout(country)
72
74
  end.flatten.pluck(:country_id)
73
75
  end
74
76
 
75
77
  def current_store_countries_without_states_ids
76
- @current_store_countries_without_states_ids ||= current_store.countries_available_for_checkout.where(states_required: false).ids
78
+ Spree::Deprecation.warn('current_store_countries_without_states_ids is deprecated and will be removed in Spree 5.3')
79
+
80
+ @current_store_countries_without_states_ids ||= current_store.countries_available_for_checkout.find_all { |country| !country.states_required? }.pluck(:id)
77
81
  end
78
82
 
79
83
  def current_store_supported_countries_ids
84
+ Spree::Deprecation.warn('current_store_supported_countries_ids is deprecated and will be removed in Spree 5.3')
85
+
80
86
  @current_store_supported_countries_ids ||= Rails.cache.fetch(['current_store_supported_countries_ids', current_store]) do
81
87
  (current_store_countries_with_states_ids + current_store_countries_without_states_ids).uniq
82
88
  end
@@ -90,7 +96,7 @@ module Spree
90
96
  addresses.
91
97
  includes(:country, :state).
92
98
  not_quick_checkout.
93
- where(country_id: current_store_supported_countries_ids).
99
+ where(country_id: current_store.countries_available_for_checkout.pluck(:id)).
94
100
  includes(:user)
95
101
  end
96
102
  end
@@ -203,7 +203,7 @@ module Spree
203
203
  "#{base_url + localize}/posts/#{resource.slug}#{preview_id}"
204
204
  elsif resource.is_a?(Spree::Taxon)
205
205
  "#{base_url + localize}/t/#{resource.permalink}"
206
- elsif resource.is_a?(Spree::Page) || resource.is_a?(ActionText::RichText)
206
+ elsif resource.is_a?(Spree::Page) || resource.is_a?(Spree::Policy)
207
207
  "#{base_url + localize}#{resource.page_builder_url}"
208
208
  elsif resource.is_a?(Spree::PageLink)
209
209
  resource.linkable_url
@@ -238,7 +238,7 @@ module Spree
238
238
  I18n.locale,
239
239
  (current_currency if defined?(current_currency)),
240
240
  defined?(try_spree_current_user) && try_spree_current_user.present?,
241
- defined?(try_spree_current_user) && try_spree_current_user.try(:has_spree_role?, 'admin')
241
+ defined?(try_spree_current_user) && try_spree_current_user.respond_to?(:role_users) && try_spree_current_user.role_users.cache_key_with_version
242
242
  ].compact
243
243
  end
244
244
 
@@ -251,8 +251,12 @@ module Spree
251
251
  end
252
252
 
253
253
  def payment_method_icon_tag(payment_method, opts = {})
254
- image_tag "payment_icons/#{payment_method}.svg", opts
255
- rescue Sprockets::Rails::Helper::AssetNotFound
254
+ return '' unless defined?(inline_svg)
255
+
256
+ opts[:width] ||= opts[:height] * 1.5 if opts[:height]
257
+ opts[:size] = "#{opts[:width]}x#{opts[:height]}" if opts[:width] && opts[:height]
258
+
259
+ inline_svg "payment_icons/#{payment_method}.svg", opts
256
260
  end
257
261
 
258
262
  private
@@ -1,18 +1,23 @@
1
1
  module Spree
2
2
  module CurrencyHelper
3
+ # Returns the list of all currencies as options for a select field.
4
+ # By default the value is the default currency of the default store.
5
+ # @param selected_value [String] the selected value
6
+ # @return [String] the options for a select field
3
7
  def currency_options(selected_value = nil)
4
8
  selected_value ||= Spree::Store.default.default_currency
5
9
  currencies = ::Money::Currency.table.map do |_code, details|
6
- iso = details[:iso_code]
7
- [iso, "#{details[:name]} (#{iso})"]
10
+ currency_presentation(details[:iso_code])
8
11
  end
9
- options_from_collection_for_select(currencies, :first, :last, selected_value)
12
+ options_from_collection_for_select(currencies, :last, :first, selected_value)
10
13
  end
11
14
 
15
+ # Returns the list of supported currencies for the current store as options for a select field.
16
+ # @return [String] the options for a select field
12
17
  def supported_currency_options
13
18
  return if current_store.nil?
14
19
 
15
- current_store.supported_currencies_list.map(&:iso_code).map { |currency| currency_presentation(currency) }
20
+ @supported_currency_options ||= current_store.supported_currencies_list.map(&:iso_code).map { |currency| currency_presentation(currency) }
16
21
  end
17
22
 
18
23
  def should_render_currency_dropdown?
@@ -21,22 +26,32 @@ module Spree
21
26
  current_store.supported_currencies_list.size > 1
22
27
  end
23
28
 
29
+ # Returns the currency symbol for the given currency.
30
+ # @param currency [String] the currency ISO code
31
+ # @return [String] the currency symbol
24
32
  def currency_symbol(currency)
25
33
  ::Money::Currency.find(currency).symbol
26
34
  end
27
35
 
36
+ # @param currency [String] the currency ISO code
37
+ # @return [Array] the currency presentation and ISO code
28
38
  def currency_presentation(currency)
29
- label = [currency_symbol(currency), currency].compact.join(' ')
39
+ currency_money = currency_money(currency)
40
+ label = "#{currency_money.name} (#{currency_money.iso_code})"
30
41
 
31
42
  [label, currency]
32
43
  end
33
44
 
45
+ # Returns the list of supported currencies for the current store.
46
+ # @return [Array<Money::Currency>] the list of supported currencies
34
47
  def preferred_currencies
48
+ Spree::Deprecation.warn('preferred_currencies is deprecated and will be removed in Spree 6.0. Use current_store.supported_currencies_list instead.')
35
49
  @preferred_currencies ||= current_store.supported_currencies_list
36
50
  end
37
51
 
38
52
  def preferred_currencies_select_options
39
- preferred_currencies.map { |currency| ["#{currency.name} - #{currency.iso_code}", currency] }
53
+ Spree::Deprecation.warn('preferred_currencies_select_options is deprecated and will be removed in Spree 6.0. Use supported_currency_options instead.')
54
+ preferred_currencies.map { |currency| currency_presentation(currency) }
40
55
  end
41
56
 
42
57
  def currency_money(currency = current_currency)
@@ -0,0 +1,70 @@
1
+ require 'open-uri'
2
+
3
+ module Spree
4
+ module Images
5
+ class SaveFromUrlJob < ::Spree::BaseJob
6
+ queue_as Spree.queues.images
7
+ retry_on ActiveRecord::RecordInvalid, OpenURI::HTTPError, wait: :polynomially_longer, attempts: 2
8
+ discard_on URI::InvalidURIError
9
+
10
+ def perform(viewable_id, viewable_type, external_url, external_id = nil, position = nil)
11
+ viewable = viewable_type.safe_constantize.find(viewable_id)
12
+
13
+ Spree::Image.ensure_metafield_definition_exists!(Spree::Image::EXTERNAL_URL_METAFIELD_KEY)
14
+
15
+ external_url = external_url.downcase.strip
16
+ external_id = external_id.to_s.downcase.strip if external_id.present?
17
+
18
+ image = find_or_initialize_image(viewable, external_url, external_id)
19
+
20
+ image.set_default_values_for_import if image.new_record? && image.respond_to?(:set_default_values_for_import)
21
+
22
+ return if image.skip_import?
23
+
24
+ image.restore if image.respond_to?(:deleted?) && image.deleted?
25
+ image.position = position if position.present?
26
+
27
+ # don't re-download the image if it's already been downloaded
28
+ # still trigger save! if position has changed
29
+ image.save! and return if image_already_saved?(image, external_url)
30
+
31
+ uri = URI.parse(external_url)
32
+ unless %w[http https].include?(uri.scheme)
33
+ raise URI::InvalidURIError, "Invalid URL scheme: #{uri.scheme}. Only http and https are allowed."
34
+ end
35
+
36
+ file = uri.open
37
+ filename = File.basename(uri.path)
38
+
39
+ image.attachment.attach(io: file, filename: filename)
40
+ image.external_url = external_url
41
+ image.external_id = external_id if external_id.present? && image.respond_to?(:external_id)
42
+ image.save!
43
+ rescue ActiveStorage::IntegrityError => e
44
+ raise e unless Rails.env.test?
45
+ end
46
+
47
+ private
48
+
49
+ def image_already_saved?(image, external_url)
50
+ image.persisted? && image.attachment.attached? && image.external_url.present? && external_url == image.external_url
51
+ end
52
+
53
+ def image_scope(viewable)
54
+ if Spree::Image.respond_to?(:with_deleted)
55
+ viewable.images.with_deleted
56
+ else
57
+ viewable.images
58
+ end
59
+ end
60
+
61
+ def find_or_initialize_image(viewable, external_url, external_id = nil)
62
+ if external_id.present? && viewable.respond_to?(:external_id)
63
+ image_scope(viewable).find_or_initialize_by(external_id: external_id)
64
+ else
65
+ image_scope(viewable).with_external_url(external_url).first || viewable.images.new
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,72 @@
1
+ module Spree
2
+ module Imports
3
+ class CreateRowsJob < Spree::BaseJob
4
+ queue_as Spree.queues.imports
5
+
6
+ discard_on ::CSV::MalformedCSVError, EncodingError do |job, error|
7
+ import = Spree::Import.find(job.arguments.first)
8
+ import.update_columns(processing_errors: error.message, status: :failed, updated_at: Time.current)
9
+ Rails.error.report error
10
+ end
11
+
12
+ BATCH_SIZE = 1000
13
+
14
+ def perform(import_id)
15
+ import = Spree::Import.find(import_id)
16
+ import.start_processing! if import.status != 'processing'
17
+
18
+ create_rows_sequentially(import)
19
+
20
+ # enqueue processing rows job after creating rows in a separate job
21
+ import.process_rows_async
22
+ end
23
+
24
+ private
25
+
26
+ def create_rows_sequentially(import)
27
+ rows_to_insert = []
28
+ row_number = 1
29
+
30
+ created_at = updated_at = Time.current
31
+
32
+ upsert_options = {}
33
+ if %w[PostgreSQL SQLite].include?(ActiveRecord::Base.connection.adapter_name)
34
+ upsert_options[:unique_by] = %i[import_id row_number]
35
+ end
36
+ # NOTE: Ensure a DB-level unique index on [:import_id, :row_number] for all adapters.
37
+
38
+ # Stream CSV to avoid loading entire file in memory
39
+ # This maintains order by processing sequentially
40
+ ::CSV.foreach(StringIO.new(import.attachment_file_content),
41
+ headers: true,
42
+ col_sep: import.preferred_delimiter,
43
+ encoding: 'UTF-8') do |csv_row|
44
+
45
+ rows_to_insert << {
46
+ import_id: import.id,
47
+ row_number: row_number,
48
+ data: csv_row.to_h.to_json,
49
+ status: 'pending',
50
+ created_at: created_at,
51
+ updated_at: updated_at
52
+ }
53
+
54
+ row_number += 1
55
+
56
+ # Bulk upsert when we reach batch size
57
+ if rows_to_insert.size >= BATCH_SIZE
58
+ Spree::ImportRow.upsert_all(rows_to_insert, **upsert_options)
59
+ rows_to_insert.clear
60
+ end
61
+ end
62
+
63
+ # Upsert any remaining rows
64
+ if rows_to_insert.any?
65
+ Spree::ImportRow.upsert_all(rows_to_insert, **upsert_options)
66
+ end
67
+
68
+ Spree::Import.reset_counters(import.id, :rows)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,19 @@
1
+ module Spree
2
+ module Imports
3
+ class ProcessRowsJob < Spree::BaseJob
4
+ queue_as Spree.queues.imports
5
+
6
+ def perform(import_id)
7
+ import = Spree::Import.find(import_id)
8
+
9
+ # process all rows in sequential order
10
+ import.rows.pending_and_failed.find_each(batch_size: 100) do |row|
11
+ row.process!
12
+ end
13
+
14
+ # mark as complete
15
+ import.complete!
16
+ end
17
+ end
18
+ end
19
+ end
@@ -14,12 +14,12 @@ module Spree
14
14
 
15
15
  return if amount.zero?
16
16
 
17
- adjustments.new(
18
- adjustable: adjustable,
17
+ adjustable.adjustments.new(
19
18
  amount: amount,
20
19
  included: included,
21
20
  label: label,
22
- order: order
21
+ order: order,
22
+ source: self
23
23
  ).save
24
24
  end
25
25
 
@@ -0,0 +1,52 @@
1
+ module Spree
2
+ module AdminUserMethods
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ # Associations
7
+ has_many :canceled_orders, class_name: 'Spree::Order', foreign_key: :canceler_id
8
+ has_many :created_orders, class_name: 'Spree::Order', foreign_key: :created_by_id
9
+ has_many :approved_orders, class_name: 'Spree::Order', foreign_key: :approver_id
10
+ has_many :created_gift_cards, class_name: 'Spree::GiftCard', foreign_key: :created_by_id
11
+ has_many :created_gift_card_batches, class_name: 'Spree::GiftCardBatch', foreign_key: :created_by_id
12
+ has_many :refunded_refunds, class_name: 'Spree::Refund', foreign_key: :refunder_id
13
+ has_many :performed_reimbursements, class_name: 'Spree::Reimbursement', foreign_key: :performed_by_id
14
+ has_many :authored_posts, class_name: 'Spree::Post', foreign_key: :author_id
15
+ has_many :created_store_credits, class_name: 'Spree::StoreCredit', foreign_key: :created_by_id
16
+ has_many :reports, class_name: 'Spree::Report', foreign_key: :user_id
17
+ has_many :exports, class_name: 'Spree::Export', foreign_key: :user_id
18
+
19
+ # Callbacks
20
+ after_destroy :nullify_approver_id_in_approved_orders
21
+ after_destroy :cleanup_admin_user_resources
22
+ end
23
+
24
+ private
25
+
26
+ def nullify_approver_id_in_approved_orders
27
+ return if self.class != Spree.admin_user_class
28
+
29
+ approved_orders.update_all(approver_id: nil, updated_at: Time.current)
30
+ end
31
+
32
+ def cleanup_admin_user_resources
33
+ return if self.class != Spree.admin_user_class
34
+
35
+ # resources to nullify
36
+ # TODO: we should change these associations to polymorphic and resolve this via standard rails association
37
+ # declarations with dependent: :nullify
38
+ canceled_orders.update_all(canceler_id: nil, updated_at: Time.current)
39
+ created_orders.update_all(created_by_id: nil, updated_at: Time.current)
40
+ created_gift_cards.update_all(created_by_id: nil, updated_at: Time.current)
41
+ created_gift_card_batches.update_all(created_by_id: nil, updated_at: Time.current)
42
+ refunded_refunds.update_all(refunder_id: nil, updated_at: Time.current)
43
+ performed_reimbursements.update_all(performed_by_id: nil, updated_at: Time.current)
44
+ authored_posts.update_all(author_id: nil, updated_at: Time.current)
45
+ created_store_credits.update_all(created_by_id: nil, updated_at: Time.current)
46
+
47
+ # resources to destroy
48
+ reports.destroy_all
49
+ exports.destroy_all
50
+ end
51
+ end
52
+ end
@@ -2,12 +2,18 @@ module Spree
2
2
  module DisplayOn
3
3
  extend ActiveSupport::Concern
4
4
 
5
- DISPLAY = [:both, :front_end, :back_end].freeze
5
+ DISPLAY = [:both, :front_end, :back_end]
6
6
 
7
7
  included do
8
8
  scope :available, -> { where(display_on: [:both]) }
9
9
  scope :available_on_front_end, -> { where(display_on: [:front_end, :both]) }
10
10
  scope :available_on_back_end, -> { where(display_on: [:back_end, :both]) }
11
+
12
+ validates :display_on, presence: true, inclusion: { in: DISPLAY.map(&:to_s) }
13
+
14
+ def available_on_front_end?
15
+ display_on == 'front_end' || display_on == 'both'
16
+ end
11
17
  end
12
18
  end
13
19
  end
@@ -0,0 +1,18 @@
1
+ module Spree
2
+ module HasImageAltText
3
+ extend ActiveSupport::Concern
4
+
5
+ # @return [String] Alt text resolved from preference, asset filename, or i18n fallback.
6
+ def image_alt
7
+ return preferred_image_alt if respond_to?(:preferred_image_alt) && preferred_image_alt.present?
8
+
9
+ if respond_to?(:asset) && asset&.filename.present?
10
+ filename = asset.filename.to_s
11
+ base = File.basename(filename, File.extname(filename))
12
+ return base.tr('-_.', ' ').squeeze(' ').strip
13
+ end
14
+
15
+ Spree.t(:image, default: 'Image')
16
+ end
17
+ end
18
+ end
@@ -12,7 +12,7 @@ module Spree
12
12
  [Spree.t(:product), 'Spree::Product'],
13
13
  [Spree.t(:post), 'Spree::Post'],
14
14
  [Spree.t(:taxon), 'Spree::Taxon'],
15
- [Spree.t(:policy), 'ActionText::RichText'],
15
+ [Spree.t(:policy), 'Spree::Policy'],
16
16
  [Spree.t(:url), nil]
17
17
  ]
18
18
  end