spree_core 5.1.8 → 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 (389) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/payment_icons/ach.svg +1 -0
  3. data/app/assets/images/payment_icons/achdirectdebit.svg +1 -0
  4. data/app/assets/images/payment_icons/ada.svg +1 -0
  5. data/app/assets/images/payment_icons/adyen.svg +1 -0
  6. data/app/assets/images/payment_icons/affinbank.svg +1 -0
  7. data/app/assets/images/payment_icons/affirm.svg +1 -0
  8. data/app/assets/images/payment_icons/afterpay.svg +1 -0
  9. data/app/assets/images/payment_icons/airtel_money.svg +1 -0
  10. data/app/assets/images/payment_icons/airteltigo_mobile_money.svg +1 -0
  11. data/app/assets/images/payment_icons/alandsbanken.svg +1 -0
  12. data/app/assets/images/payment_icons/alipay.svg +1 -0
  13. data/app/assets/images/payment_icons/alipay_hk.svg +1 -0
  14. data/app/assets/images/payment_icons/alliancebank.svg +1 -0
  15. data/app/assets/images/payment_icons/alma.svg +1 -0
  16. data/app/assets/images/payment_icons/amazon.svg +1 -0
  17. data/app/assets/images/payment_icons/ambank.svg +1 -0
  18. data/app/assets/images/payment_icons/american_express.svg +1 -0
  19. data/app/assets/images/payment_icons/apecoin.svg +1 -0
  20. data/app/assets/images/payment_icons/apple_pay.svg +1 -0
  21. data/app/assets/images/payment_icons/arbitrum.svg +1 -0
  22. data/app/assets/images/payment_icons/atome.svg +1 -0
  23. data/app/assets/images/payment_icons/authorizenet.svg +1 -0
  24. data/app/assets/images/payment_icons/avalanche.svg +1 -0
  25. data/app/assets/images/payment_icons/bacs.svg +1 -0
  26. data/app/assets/images/payment_icons/bancontact.svg +1 -0
  27. data/app/assets/images/payment_icons/bangkokbank.svg +1 -0
  28. data/app/assets/images/payment_icons/bankislam.svg +1 -0
  29. data/app/assets/images/payment_icons/bankmuamalat.svg +1 -0
  30. data/app/assets/images/payment_icons/bankofamerica.svg +1 -0
  31. data/app/assets/images/payment_icons/bankrakyat.svg +1 -0
  32. data/app/assets/images/payment_icons/base.svg +1 -0
  33. data/app/assets/images/payment_icons/becs.svg +1 -0
  34. data/app/assets/images/payment_icons/benefit.svg +1 -0
  35. data/app/assets/images/payment_icons/billie.svg +1 -0
  36. data/app/assets/images/payment_icons/bitcoin.svg +1 -0
  37. data/app/assets/images/payment_icons/bitcoin_cash.svg +1 -0
  38. data/app/assets/images/payment_icons/bizum.svg +1 -0
  39. data/app/assets/images/payment_icons/blik.svg +1 -0
  40. data/app/assets/images/payment_icons/bnbchain.svg +1 -0
  41. data/app/assets/images/payment_icons/bogus.svg +1 -0
  42. data/app/assets/images/payment_icons/bogus_app_coin.svg +1 -0
  43. data/app/assets/images/payment_icons/boleto.svg +1 -0
  44. data/app/assets/images/payment_icons/boost.svg +1 -0
  45. data/app/assets/images/payment_icons/braintree.svg +1 -0
  46. data/app/assets/images/payment_icons/buckaroopaybybank.svg +1 -0
  47. data/app/assets/images/payment_icons/busd.svg +1 -0
  48. data/app/assets/images/payment_icons/cartes_bancaires.svg +1 -0
  49. data/app/assets/images/payment_icons/cash.svg +1 -0
  50. data/app/assets/images/payment_icons/cashappafterpay.svg +1 -0
  51. data/app/assets/images/payment_icons/cashapppay.svg +1 -0
  52. data/app/assets/images/payment_icons/checkout_finance.svg +1 -0
  53. data/app/assets/images/payment_icons/chinabank.svg +1 -0
  54. data/app/assets/images/payment_icons/clearpay.svg +1 -0
  55. data/app/assets/images/payment_icons/collector_bank.svg +1 -0
  56. data/app/assets/images/payment_icons/dai.svg +1 -0
  57. data/app/assets/images/payment_icons/dana.svg +1 -0
  58. data/app/assets/images/payment_icons/dankort.svg +1 -0
  59. data/app/assets/images/payment_icons/danske_bank.svg +1 -0
  60. data/app/assets/images/payment_icons/deutschebank.svg +1 -0
  61. data/app/assets/images/payment_icons/diners_club.svg +1 -0
  62. data/app/assets/images/payment_icons/directbanktransferlatinamerica.svg +1 -0
  63. data/app/assets/images/payment_icons/discover.svg +1 -0
  64. data/app/assets/images/payment_icons/dogecoin.svg +1 -0
  65. data/app/assets/images/payment_icons/duitnow.svg +1 -0
  66. data/app/assets/images/payment_icons/eft_secure.svg +1 -0
  67. data/app/assets/images/payment_icons/eftpos_au.svg +1 -0
  68. data/app/assets/images/payment_icons/eftposau.svg +1 -0
  69. data/app/assets/images/payment_icons/elo.svg +1 -0
  70. data/app/assets/images/payment_icons/eos.svg +1 -0
  71. data/app/assets/images/payment_icons/eps.svg +1 -0
  72. data/app/assets/images/payment_icons/ethereum.svg +1 -0
  73. data/app/assets/images/payment_icons/eurobonuscheckout.svg +1 -0
  74. data/app/assets/images/payment_icons/ezcash.svg +1 -0
  75. data/app/assets/images/payment_icons/fantom.svg +1 -0
  76. data/app/assets/images/payment_icons/fpx.svg +1 -0
  77. data/app/assets/images/payment_icons/gcash.svg +1 -0
  78. data/app/assets/images/payment_icons/generic.svg +1 -0
  79. data/app/assets/images/payment_icons/genericbank.svg +1 -0
  80. data/app/assets/images/payment_icons/gift-card.svg +1 -0
  81. data/app/assets/images/payment_icons/giropay.svg +1 -0
  82. data/app/assets/images/payment_icons/glbepaypal.svg +1 -0
  83. data/app/assets/images/payment_icons/gmobanktransfer.svg +1 -0
  84. data/app/assets/images/payment_icons/gnosis.svg +1 -0
  85. data/app/assets/images/payment_icons/google_pay.svg +1 -0
  86. data/app/assets/images/payment_icons/google_wallet.svg +1 -0
  87. data/app/assets/images/payment_icons/gopay.svg +1 -0
  88. data/app/assets/images/payment_icons/grabpay.svg +1 -0
  89. data/app/assets/images/payment_icons/gusd.svg +1 -0
  90. data/app/assets/images/payment_icons/handelsbanken.svg +1 -0
  91. data/app/assets/images/payment_icons/hongleongbank.svg +1 -0
  92. data/app/assets/images/payment_icons/hypercard.svg +1 -0
  93. data/app/assets/images/payment_icons/hypercash.svg +1 -0
  94. data/app/assets/images/payment_icons/ideal.svg +1 -0
  95. data/app/assets/images/payment_icons/in3viaideal.svg +1 -0
  96. data/app/assets/images/payment_icons/inbank.svg +1 -0
  97. data/app/assets/images/payment_icons/jcb.svg +1 -0
  98. data/app/assets/images/payment_icons/kakao_pay.svg +1 -0
  99. data/app/assets/images/payment_icons/kasikornbank.svg +1 -0
  100. data/app/assets/images/payment_icons/klarna-pay-later.svg +1 -0
  101. data/app/assets/images/payment_icons/klarna-pay-now.svg +1 -0
  102. data/app/assets/images/payment_icons/klarna-slice-it.svg +1 -0
  103. data/app/assets/images/payment_icons/klarna.svg +1 -0
  104. data/app/assets/images/payment_icons/knet.svg +1 -0
  105. data/app/assets/images/payment_icons/krungthaibank.svg +1 -0
  106. data/app/assets/images/payment_icons/landbank.svg +1 -0
  107. data/app/assets/images/payment_icons/laybuybyklarna.svg +1 -0
  108. data/app/assets/images/payment_icons/litecoin.svg +1 -0
  109. data/app/assets/images/payment_icons/lunchcheck.svg +1 -0
  110. data/app/assets/images/payment_icons/mach.svg +1 -0
  111. data/app/assets/images/payment_icons/mada.svg +1 -0
  112. data/app/assets/images/payment_icons/maestro.svg +1 -0
  113. data/app/assets/images/payment_icons/master.svg +1 -0
  114. data/app/assets/images/payment_icons/mayabank.svg +1 -0
  115. data/app/assets/images/payment_icons/maybank.svg +1 -0
  116. data/app/assets/images/payment_icons/maybankm2u.svg +1 -0
  117. data/app/assets/images/payment_icons/maybankqrpay.svg +1 -0
  118. data/app/assets/images/payment_icons/mbway.svg +1 -0
  119. data/app/assets/images/payment_icons/mcash.svg +1 -0
  120. data/app/assets/images/payment_icons/medicinosbankas.svg +1 -0
  121. data/app/assets/images/payment_icons/mercadopago.svg +1 -0
  122. data/app/assets/images/payment_icons/metrobank.svg +1 -0
  123. data/app/assets/images/payment_icons/mobilepay.svg +1 -0
  124. data/app/assets/images/payment_icons/momopay.svg +1 -0
  125. data/app/assets/images/payment_icons/monero.svg +1 -0
  126. data/app/assets/images/payment_icons/mtn_mobile_money.svg +1 -0
  127. data/app/assets/images/payment_icons/mybank.svg +1 -0
  128. data/app/assets/images/payment_icons/naver_pay.svg +1 -0
  129. data/app/assets/images/payment_icons/nelo.svg +1 -0
  130. data/app/assets/images/payment_icons/netbanking.svg +1 -0
  131. data/app/assets/images/payment_icons/novalnetdirectdebitach.svg +1 -0
  132. data/app/assets/images/payment_icons/nubank.svg +1 -0
  133. data/app/assets/images/payment_icons/ocbcbank.svg +1 -0
  134. data/app/assets/images/payment_icons/offlinebanktransferlatinamerica.svg +1 -0
  135. data/app/assets/images/payment_icons/ola_money.svg +1 -0
  136. data/app/assets/images/payment_icons/oney.svg +1 -0
  137. data/app/assets/images/payment_icons/onlinebanking.svg +1 -0
  138. data/app/assets/images/payment_icons/onlinebanktransfer.svg +1 -0
  139. data/app/assets/images/payment_icons/orangemobilemoney.svg +1 -0
  140. data/app/assets/images/payment_icons/otpbank.svg +1 -0
  141. data/app/assets/images/payment_icons/oxxo.svg +1 -0
  142. data/app/assets/images/payment_icons/paybybank.svg +1 -0
  143. data/app/assets/images/payment_icons/paybybankmollie.svg +1 -0
  144. data/app/assets/images/payment_icons/paybybankus.svg +1 -0
  145. data/app/assets/images/payment_icons/paycash.svg +1 -0
  146. data/app/assets/images/payment_icons/payco.svg +1 -0
  147. data/app/assets/images/payment_icons/payeverpaybybank.svg +1 -0
  148. data/app/assets/images/payment_icons/payme.svg +1 -0
  149. data/app/assets/images/payment_icons/paynow.svg +1 -0
  150. data/app/assets/images/payment_icons/paynowmbank.svg +1 -0
  151. data/app/assets/images/payment_icons/paypal.svg +1 -0
  152. data/app/assets/images/payment_icons/paypo.svg +1 -0
  153. data/app/assets/images/payment_icons/payrexxbanktransfer.svg +1 -0
  154. data/app/assets/images/payment_icons/payrexxpaybybank.svg +1 -0
  155. data/app/assets/images/payment_icons/paysafecash.svg +1 -0
  156. data/app/assets/images/payment_icons/pix.svg +1 -0
  157. data/app/assets/images/payment_icons/polygon.svg +1 -0
  158. data/app/assets/images/payment_icons/przelewy24.svg +1 -0
  159. data/app/assets/images/payment_icons/publicbank.svg +1 -0
  160. data/app/assets/images/payment_icons/publicbank_pbe.svg +1 -0
  161. data/app/assets/images/payment_icons/qr_promptpay.svg +1 -0
  162. data/app/assets/images/payment_icons/rabobank.svg +1 -0
  163. data/app/assets/images/payment_icons/revolut.svg +1 -0
  164. data/app/assets/images/payment_icons/rhbbank.svg +1 -0
  165. data/app/assets/images/payment_icons/riverty.svg +1 -0
  166. data/app/assets/images/payment_icons/safetypaybanktransfer.svg +1 -0
  167. data/app/assets/images/payment_icons/samsung_pay.svg +1 -0
  168. data/app/assets/images/payment_icons/satispay.svg +1 -0
  169. data/app/assets/images/payment_icons/scalapay.svg +1 -0
  170. data/app/assets/images/payment_icons/scotiabank.svg +1 -0
  171. data/app/assets/images/payment_icons/seabankid.svg +1 -0
  172. data/app/assets/images/payment_icons/seabankph.svg +1 -0
  173. data/app/assets/images/payment_icons/sepa_bank_transfer.svg +1 -0
  174. data/app/assets/images/payment_icons/sepadirectdebit.svg +1 -0
  175. data/app/assets/images/payment_icons/seveneleven.svg +1 -0
  176. data/app/assets/images/payment_icons/shib.svg +1 -0
  177. data/app/assets/images/payment_icons/shopcash.svg +1 -0
  178. data/app/assets/images/payment_icons/siauliubankas.svg +1 -0
  179. data/app/assets/images/payment_icons/skeps.svg +1 -0
  180. data/app/assets/images/payment_icons/snap_checkout.svg +1 -0
  181. data/app/assets/images/payment_icons/sofort.svg +1 -0
  182. data/app/assets/images/payment_icons/softbank.svg +1 -0
  183. data/app/assets/images/payment_icons/spei.svg +1 -0
  184. data/app/assets/images/payment_icons/storecredit.svg +1 -0
  185. data/app/assets/images/payment_icons/stripe.svg +1 -0
  186. data/app/assets/images/payment_icons/sveacheckout.svg +1 -0
  187. data/app/assets/images/payment_icons/swedbank.svg +1 -0
  188. data/app/assets/images/payment_icons/swish.svg +1 -0
  189. data/app/assets/images/payment_icons/tbibank.svg +1 -0
  190. data/app/assets/images/payment_icons/thanachartbank.svg +1 -0
  191. data/app/assets/images/payment_icons/tnmmoney.svg +1 -0
  192. data/app/assets/images/payment_icons/touchngo.svg +1 -0
  193. data/app/assets/images/payment_icons/trustly.svg +1 -0
  194. data/app/assets/images/payment_icons/twint.svg +1 -0
  195. data/app/assets/images/payment_icons/uaevisa.svg +1 -0
  196. data/app/assets/images/payment_icons/unionpay.svg +1 -0
  197. data/app/assets/images/payment_icons/unzerbanktransfer.svg +1 -0
  198. data/app/assets/images/payment_icons/upi.svg +1 -0
  199. data/app/assets/images/payment_icons/usbank.svg +1 -0
  200. data/app/assets/images/payment_icons/usdc.svg +1 -0
  201. data/app/assets/images/payment_icons/usdt.svg +1 -0
  202. data/app/assets/images/payment_icons/venmo.svg +1 -0
  203. data/app/assets/images/payment_icons/vipps.svg +1 -0
  204. data/app/assets/images/payment_icons/visa.svg +1 -0
  205. data/app/assets/images/payment_icons/volksbank.svg +1 -0
  206. data/app/assets/images/payment_icons/waavepaybybank.svg +1 -0
  207. data/app/assets/images/payment_icons/walley.svg +1 -0
  208. data/app/assets/images/payment_icons/wbtc.svg +1 -0
  209. data/app/assets/images/payment_icons/wechatpay.svg +1 -0
  210. data/app/assets/images/payment_icons/whishcheckout.svg +1 -0
  211. data/app/assets/images/payment_icons/wingbank.svg +1 -0
  212. data/app/assets/images/payment_icons/xrp.svg +1 -0
  213. data/app/assets/images/payment_icons/zip.svg +1 -0
  214. data/app/finders/spree/posts/find.rb +137 -0
  215. data/app/helpers/spree/addresses_helper.rb +9 -3
  216. data/app/helpers/spree/base_helper.rb +8 -4
  217. data/app/jobs/spree/images/save_from_url_job.rb +70 -0
  218. data/app/jobs/spree/imports/create_rows_job.rb +72 -0
  219. data/app/jobs/spree/imports/process_rows_job.rb +19 -0
  220. data/app/models/concerns/spree/adjustment_source.rb +3 -3
  221. data/app/models/concerns/spree/admin_user_methods.rb +52 -0
  222. data/app/models/concerns/spree/display_on.rb +7 -1
  223. data/app/models/concerns/spree/has_image_alt_text.rb +18 -0
  224. data/app/models/concerns/spree/has_one_link.rb +1 -1
  225. data/app/models/concerns/spree/has_page_links.rb +1 -1
  226. data/app/models/concerns/spree/linkable.rb +9 -0
  227. data/app/models/concerns/spree/metadata.rb +2 -0
  228. data/app/models/concerns/spree/metafields.rb +94 -0
  229. data/app/models/concerns/spree/named_type.rb +1 -1
  230. data/app/models/concerns/spree/user_methods.rb +20 -7
  231. data/app/models/concerns/spree/user_payment_source.rb +1 -1
  232. data/app/models/concerns/spree/user_roles.rb +3 -2
  233. data/app/models/spree/ability.rb +4 -0
  234. data/app/models/spree/address.rb +3 -1
  235. data/app/models/spree/adjustable/adjuster/tax.rb +2 -2
  236. data/app/models/spree/adjustable/adjustments_updater.rb +26 -3
  237. data/app/models/spree/adjustment.rb +4 -1
  238. data/app/models/spree/asset.rb +16 -0
  239. data/app/models/spree/base.rb +1 -1
  240. data/app/models/spree/credit_card.rb +1 -0
  241. data/app/models/spree/current.rb +5 -1
  242. data/app/models/spree/custom_domain.rb +5 -0
  243. data/app/models/spree/customer_return.rb +1 -0
  244. data/app/models/spree/export.rb +39 -2
  245. data/app/models/spree/exports/customers.rb +17 -0
  246. data/app/models/spree/exports/gift_cards.rb +13 -0
  247. data/app/models/spree/exports/newsletter_subscribers.rb +13 -0
  248. data/app/models/spree/exports/orders.rb +6 -4
  249. data/app/models/spree/exports/products.rb +9 -3
  250. data/app/models/spree/gift_card.rb +7 -1
  251. data/app/models/spree/gift_card_batch.rb +0 -1
  252. data/app/models/spree/import.rb +279 -0
  253. data/app/models/spree/import_mapping.rb +46 -0
  254. data/app/models/spree/import_row.rb +108 -0
  255. data/app/models/spree/import_schema.rb +25 -0
  256. data/app/models/spree/import_schemas/products.rb +45 -0
  257. data/app/models/spree/imports/products.rb +9 -0
  258. data/app/models/spree/invitation.rb +1 -1
  259. data/app/models/spree/legacy_user.rb +0 -1
  260. data/app/models/spree/line_item.rb +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/imports/row_processors/base.rb +19 -0
  344. data/app/services/spree/imports/row_processors/product_variant.rb +228 -0
  345. data/app/services/spree/line_items/destroy.rb +1 -1
  346. data/app/services/spree/newsletter/subscribe.rb +43 -0
  347. data/app/services/spree/newsletter/verify.rb +30 -0
  348. data/app/sorters/spree/posts/sort.rb +40 -0
  349. data/app/views/spree/shared/_payment.html.erb +3 -3
  350. data/config/locales/en.yml +56 -2
  351. data/db/migrate/20250605131334_add_missing_fields_to_users.rb +23 -13
  352. data/db/migrate/20250728095629_create_spree_metafields.rb +27 -0
  353. data/db/migrate/20250730102644_add_missing_unique_indexes_to_spree_option_types_and_values.rb +40 -0
  354. data/db/migrate/20250730154601_add_unique_index_on_spree_properties_name.rb +24 -0
  355. data/db/migrate/20250811112056_create_spree_policies.rb +22 -0
  356. data/db/migrate/20250821211705_fix_unique_index_on_spree_order_promotions.rb +20 -0
  357. data/db/migrate/20250825175217_add_missing_page_builder_indexes.rb +7 -0
  358. data/db/migrate/20250826093602_create_spree_newsletter_subscribers.rb +12 -0
  359. data/db/migrate/20250902143122_fix_policies_store_association.rb +18 -0
  360. data/db/migrate/20250911205659_add_missing_index_on_spree_products_promotionable.rb +5 -0
  361. data/db/migrate/20250913130044_add_page_links_counter_cache_to_spree_stores.rb +10 -0
  362. data/db/migrate/20250914101955_add_missing_indexes_on_spree_adjustments.rb +6 -0
  363. data/db/migrate/20250915093930_add_metadata_to_spree_newsletter_subscribers.rb +20 -0
  364. data/db/migrate/20250923141845_create_spree_imports.rb +47 -0
  365. data/lib/generators/spree/cursor_rules/cursor_rules_generator.rb +19 -0
  366. data/lib/generators/spree/cursor_rules/templates/spree_rules.mdc +387 -0
  367. data/lib/generators/spree/dummy/dummy_generator.rb +0 -1
  368. data/lib/generators/spree/install/templates/config/initializers/spree.rb +5 -0
  369. data/lib/spree/core/configuration.rb +1 -0
  370. data/lib/spree/core/dependencies.rb +3 -0
  371. data/lib/spree/core/engine.rb +57 -2
  372. data/lib/spree/core/version.rb +1 -1
  373. data/lib/spree/core.rb +3 -1
  374. data/lib/spree/permitted_attributes.rb +18 -3
  375. data/lib/spree/testing_support/capybara_config.rb +9 -3
  376. data/lib/spree/testing_support/factories/export_factory.rb +5 -17
  377. data/lib/spree/testing_support/factories/import_factory.rb +20 -0
  378. data/lib/spree/testing_support/factories/import_mapping_factory.rb +7 -0
  379. data/lib/spree/testing_support/factories/import_row_factory.rb +7 -0
  380. data/lib/spree/testing_support/factories/metafield_definition_factory.rb +72 -0
  381. data/lib/spree/testing_support/factories/metafield_factory.rb +68 -0
  382. data/lib/spree/testing_support/factories/newsletter_subscriber_factory.rb +18 -0
  383. data/lib/spree/testing_support/factories/policy_factory.rb +8 -0
  384. data/lib/spree/testing_support/factories/post_factory.rb +8 -0
  385. data/lib/spree/testing_support/store.rb +11 -0
  386. data/lib/tasks/core.rake +128 -0
  387. metadata +279 -6
  388. data/app/models/action_text/rich_text_decorator.rb +0 -11
  389. data/app/presenters/spree/csv/product_presenter.rb +0 -63
@@ -0,0 +1,91 @@
1
+ module Spree
2
+ class MetafieldDefinition < Spree.base_class
3
+ include Spree::DisplayOn
4
+
5
+ DISPLAY = [:both, :back_end]
6
+
7
+ #
8
+ # Associations
9
+ #
10
+ has_many :metafields, class_name: 'Spree::Metafield', dependent: :destroy
11
+
12
+ #
13
+ # Validations
14
+ #
15
+ validates :namespace, :key, :name, :resource_type, presence: true
16
+ validates :metafield_type, presence: true, inclusion: { in: :valid_available_types }
17
+ validates :resource_type, presence: true, inclusion: { in: :valid_available_resources }
18
+ validates :key, uniqueness: { scope: spree_base_uniqueness_scope + [:resource_type, :namespace] }
19
+
20
+ #
21
+ # Scopes
22
+ #
23
+ scope :for_resource_type, ->(resource_type) { where(resource_type: resource_type) }
24
+ scope :multi_search, ->(search) do
25
+ return all if search.blank?
26
+
27
+ search_term = "%#{search.downcase}%"
28
+ namespace_condition = arel_table[:namespace].lower.matches(search_term)
29
+ key_condition = arel_table[:key].lower.matches(search_term)
30
+ name_condition = arel_table[:name].lower.matches(search_term)
31
+
32
+ where(namespace_condition.or(key_condition).or(name_condition))
33
+ end
34
+
35
+ #
36
+ # Callbacks
37
+ #
38
+ normalizes :key, with: ->(value) { value.to_s.parameterize.underscore.strip }
39
+ normalizes :namespace, with: ->(value) { value.to_s.parameterize.underscore.strip }
40
+ before_validation :set_default_type, if: -> { metafield_type.blank? }, on: :create
41
+ before_validation :set_name_from_key, if: -> { name.blank? }, on: :create
42
+
43
+ #
44
+ # Ransack
45
+ #
46
+ self.whitelisted_ransackable_attributes = %w[key namespace name resource_type display_on]
47
+ self.whitelisted_ransackable_scopes = %w[multi_search]
48
+
49
+ # Returns the full key with namespace
50
+ # @return [String] eg. custom.id
51
+ def full_key
52
+ "#{namespace}.#{key}"
53
+ end
54
+
55
+ # Returns the CSV header name for this metafield
56
+ # @return [String] eg. metafield.custom.id
57
+ def csv_header_name
58
+ "metafield.#{full_key}"
59
+ end
60
+
61
+ # Returns the available types
62
+ # @return [Array<Class>]
63
+ def self.available_types
64
+ Rails.application.config.spree.metafield_types
65
+ end
66
+
67
+ # Returns the available resources
68
+ # @return [Array<Class>]
69
+ def self.available_resources
70
+ Rails.application.config.spree.metafield_enabled_resources
71
+ end
72
+
73
+ private
74
+
75
+ def valid_available_types
76
+ self.class.available_types.map(&:to_s)
77
+ end
78
+
79
+ def valid_available_resources
80
+ self.class.available_resources.map(&:to_s)
81
+ end
82
+
83
+ def set_default_type
84
+ self.metafield_type ||= Rails.application.config.spree.metafield_types.first.to_s
85
+ end
86
+
87
+ def set_name_from_key
88
+ self.name ||= key.titleize
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,15 @@
1
+ module Spree
2
+ module Metafields
3
+ class Boolean < Spree::Metafield
4
+ normalizes :value, with: ->(value) { value.to_b.to_s }
5
+
6
+ def csv_value
7
+ value.to_b ? Spree.t(:say_yes) : Spree.t(:say_no)
8
+ end
9
+
10
+ def serialize_value
11
+ value.to_b
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,27 @@
1
+ module Spree
2
+ module Metafields
3
+ class Json < Spree::Metafield
4
+ validate :value_must_be_valid_json
5
+
6
+ def serialize_value
7
+ JSON.parse(value)
8
+ rescue JSON::ParserError
9
+ value
10
+ end
11
+
12
+ def csv_value
13
+ value.to_s
14
+ end
15
+
16
+ private
17
+
18
+ def value_must_be_valid_json
19
+ return if value.blank?
20
+
21
+ JSON.parse(value)
22
+ rescue JSON::ParserError => e
23
+ errors.add(:value, "must be valid JSON: #{e.message}")
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,7 @@
1
+ module Spree
2
+ module Metafields
3
+ class LongText < Spree::Metafield
4
+ normalizes :value, with: ->(value) { value.to_s.strip }
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ module Spree
2
+ module Metafields
3
+ class Number < Spree::Metafield
4
+ validates :value, numericality: true
5
+
6
+ def serialize_value
7
+ value.to_d
8
+ end
9
+
10
+ def csv_value
11
+ value.to_d.to_s
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ module Spree
2
+ module Metafields
3
+ class RichText < Spree::Metafield
4
+ # Avoid collision with the `value` column used by other metafield types
5
+ self.ignored_columns = %w[value]
6
+
7
+ has_rich_text :value
8
+
9
+ def serialize_value
10
+ value&.body&.to_s
11
+ end
12
+
13
+ def csv_value
14
+ value&.body&.to_plain_text || ''
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,7 @@
1
+ module Spree
2
+ module Metafields
3
+ class ShortText < Spree::Metafield
4
+ normalizes :value, with: ->(value) { value.to_s.strip }
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ module Spree
2
+ class NewsletterSubscriber < Spree.base_class
3
+ module Emails
4
+ extend ActiveSupport::Concern
5
+
6
+ def deliver_newsletter_email_verification
7
+ # you can overwrite this method in your application / extension to send out the confirmation email
8
+ # or use `spree_emails` gem
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,64 @@
1
+ require_dependency 'spree/newsletter_subscriber/emails'
2
+
3
+ module Spree
4
+ class NewsletterSubscriber < Spree.base_class
5
+ include Spree::NewsletterSubscriber::Emails
6
+ include Spree::Metafields
7
+
8
+ has_secure_token :verification_token
9
+
10
+ #
11
+ # Associations
12
+ #
13
+ belongs_to :user, optional: true, class_name: Spree.user_class&.name
14
+
15
+ #
16
+ # Validations
17
+ #
18
+ validates :email,
19
+ presence: true,
20
+ format: { with: URI::MailTo::EMAIL_REGEXP },
21
+ uniqueness: { case_sensitive: false, scope: spree_base_uniqueness_scope }
22
+
23
+ #
24
+ # Scopes
25
+ #
26
+ scope :verified, -> { where.not(verified_at: nil) }
27
+ scope :unverified, -> { where(verified_at: nil) }
28
+
29
+ #
30
+ # Callbacks
31
+ #
32
+ normalizes :email, with: ->(email) { email.to_s.strip.downcase.presence }
33
+
34
+ #
35
+ # Ransack filtering
36
+ #
37
+ self.whitelisted_ransackable_attributes = %w[email verified_at]
38
+ self.whitelisted_ransackable_scopes = %w[verified unverified]
39
+
40
+ def accepts_email_marketing
41
+ return user.accepts_email_marketing if user.present?
42
+
43
+ verified?
44
+ end
45
+
46
+ def verified?
47
+ verified_at.present?
48
+ end
49
+
50
+ def to_csv(_store = nil)
51
+ Spree::CSV::NewsletterSubscriberPresenter.new(self).call
52
+ end
53
+
54
+ def self.subscribe(email:, user: nil)
55
+ Spree::Newsletter::Subscribe.new(email: email, current_user: user).call
56
+ end
57
+
58
+ def self.verify(token:)
59
+ subscriber = unverified.find_by!(verification_token: token)
60
+
61
+ Spree::Newsletter::Verify.new(subscriber: subscriber).call
62
+ end
63
+ end
64
+ end
@@ -4,6 +4,7 @@ module Spree
4
4
 
5
5
  include Spree::ParameterizableName
6
6
  include Spree::UniqueName
7
+ include Spree::Metafields
7
8
  include Spree::Metadata
8
9
  include Spree::TranslatableResource
9
10
  if defined?(Spree::Webhooks::HasWebhooks)
@@ -61,6 +62,7 @@ module Spree
61
62
 
62
63
  # legacy, name itself is now parameterized before saving
63
64
  def filter_param
65
+ Spree::Deprecation.warn('Spree::OptionType#filter_param is deprecated and will be removed in Spree 6. Please use Spree::OptionType#name instead.')
64
66
  name.parameterize
65
67
  end
66
68
 
@@ -1,6 +1,7 @@
1
1
  module Spree
2
2
  class OptionValue < Spree.base_class
3
3
  include Spree::ParameterizableName
4
+ include Spree::Metafields
4
5
  include Spree::Metadata
5
6
  include Spree::TranslatableResource
6
7
  if defined?(Spree::Webhooks::HasWebhooks)
@@ -122,6 +122,7 @@ module Spree
122
122
  after_transition to: :complete, do: :redeem_gift_card
123
123
  after_transition to: :resumed, do: :after_resume
124
124
  after_transition to: :canceled, do: :after_cancel
125
+ after_transition to: :complete, do: :subscribe_to_newsletter
125
126
 
126
127
  after_transition from: any - :cart, to: any - [:confirm, :complete] do |order|
127
128
  order.update_totals
@@ -132,6 +133,12 @@ module Spree
132
133
  alias_method :save_state, :save
133
134
  end
134
135
 
136
+ def subscribe_to_newsletter
137
+ return unless accept_marketing?
138
+
139
+ Spree::NewsletterSubscriber.subscribe(email: email, user: user)
140
+ end
141
+
135
142
  def self.go_to_state(name, options = {})
136
143
  self.checkout_steps[name] = options
137
144
  self.previous_states.each { |state| add_transition({ from: state, to: name }.merge(options)) }
@@ -29,6 +29,7 @@ module Spree
29
29
  include Spree::NumberAsParam
30
30
  include Spree::SingleStoreResource
31
31
  include Spree::MemoizedData
32
+ include Spree::Metafields
32
33
  include Spree::Metadata
33
34
  include Spree::MultiSearchable
34
35
  if defined?(Spree::Security::Orders)
@@ -348,7 +349,7 @@ module Spree
348
349
  end
349
350
 
350
351
  def updater
351
- @updater ||= OrderUpdater.new(self)
352
+ @updater ||= Spree::Dependencies.order_updater.constantize.new(self)
352
353
  end
353
354
 
354
355
  def update_with_updater!
@@ -452,7 +453,7 @@ module Spree
452
453
 
453
454
  def full_name
454
455
  @full_name ||= if user.present? && user.name.present?
455
- user.name.full
456
+ user.full_name
456
457
  else
457
458
  billing_address&.full_name || email
458
459
  end
@@ -847,9 +848,13 @@ module Spree
847
848
  end
848
849
 
849
850
  def to_csv(_store = nil)
851
+ metafields_for_csv ||= Spree::MetafieldDefinition.for_resource_type('Spree::Order').order(:namespace, :key).map do |mf_def|
852
+ metafields.find { |mf| mf.metafield_definition_id == mf_def.id }&.csv_value
853
+ end
854
+
850
855
  csv_lines = []
851
856
  all_line_items.each_with_index do |line_item, index|
852
- csv_lines << Spree::CSV::OrderLineItemPresenter.new(self, line_item, index).call
857
+ csv_lines << Spree::CSV::OrderLineItemPresenter.new(self, line_item, index, metafields_for_csv).call
853
858
  end
854
859
  csv_lines
855
860
  end
@@ -57,7 +57,7 @@ module Spree
57
57
  current_line_item.quantity += other_order_line_item.quantity
58
58
  handle_error(current_line_item) unless current_line_item.save
59
59
  else
60
- other_order_line_item.order_id = order.id
60
+ order.line_items << other_order_line_item
61
61
  other_order_line_item.adjustments.update_all(order_id: order.id)
62
62
  handle_error(other_order_line_item) unless other_order_line_item.save
63
63
  end
@@ -69,9 +69,7 @@ module Spree
69
69
  end
70
70
 
71
71
  def persist_merge
72
- updater.update_item_count
73
- updater.update_item_total
74
- updater.persist_totals
72
+ updater.update
75
73
  end
76
74
 
77
75
  def handle_gift_card(other_order)
@@ -6,6 +6,9 @@ module Spree
6
6
  delegate :name, :description, :code, :public_metadata, to: :promotion
7
7
  delegate :currency, to: :order
8
8
 
9
+ validates :order, :promotion, presence: true
10
+ validates :order, uniqueness: { scope: :promotion }
11
+
9
12
  extend Spree::DisplayMoney
10
13
  money_methods :amount
11
14
 
@@ -69,7 +69,7 @@ module Spree
69
69
  end
70
70
 
71
71
  def update_shipment_total
72
- order.shipment_total = shipments.sum(:cost)
72
+ order.shipment_total = shipments.to_a.sum(&:cost)
73
73
  update_order_total
74
74
  end
75
75
 
@@ -97,7 +97,7 @@ module Spree
97
97
  end
98
98
 
99
99
  def update_item_total
100
- order.item_total = line_items.sum('price * quantity')
100
+ order.item_total = line_items.to_a.sum(&:amount)
101
101
  update_order_total
102
102
  end
103
103
 
@@ -1,6 +1,7 @@
1
1
  module Spree
2
2
  class Page < Spree.base_class
3
3
  include Spree::Previewable
4
+ include Spree::Linkable
4
5
 
5
6
  #
6
7
  # Magic methods
@@ -14,7 +15,6 @@ module Spree
14
15
  #
15
16
  belongs_to :pageable, polymorphic: true # this can be either Store or Theme
16
17
  has_many :sections, -> { order(position: :asc) }, class_name: 'Spree::PageSection', dependent: :destroy_async, as: :pageable
17
- has_many :page_links, as: :linkable, class_name: 'Spree::PageLink', dependent: :destroy
18
18
  alias page_sections sections
19
19
 
20
20
  #
@@ -103,6 +103,10 @@ module Spree
103
103
  false
104
104
  end
105
105
 
106
+ def linkable?
107
+ false
108
+ end
109
+
106
110
  def layout_sections?
107
111
  true
108
112
  end
@@ -56,6 +56,10 @@ module Spree
56
56
  name
57
57
  end
58
58
 
59
+ def form_partial_name
60
+ type.demodulize.underscore
61
+ end
62
+
59
63
  def icon_name
60
64
  'fullscreen'
61
65
  end
@@ -1,6 +1,8 @@
1
1
  module Spree
2
2
  module PageBlocks
3
3
  class Image < Spree::PageBlock
4
+ include Spree::HasImageAltText
5
+
4
6
  alias image asset
5
7
 
6
8
  TOP_PADDING_DEFAULT = 20
@@ -8,6 +10,7 @@ module Spree
8
10
 
9
11
  preference :height, :integer, default: 64
10
12
  preference :mobile_height, :integer, default: 32
13
+ preference :image_alt, :string
11
14
 
12
15
  def icon_name
13
16
  'photo'
@@ -0,0 +1,18 @@
1
+ module Spree
2
+ module PageBlocks
3
+ class Metafields < Spree::PageBlock
4
+ RESOURCE_TYPE_DEFAULT = 'Spree::Product'
5
+
6
+ preference :resource_type, :string, default: -> { self.class::RESOURCE_TYPE_DEFAULT if defined?(self.class::RESOURCE_TYPE_DEFAULT) }
7
+ preference :metafield_definition_ids, :array, default: -> { available_metafield_definitions.pluck(:id) }
8
+
9
+ def icon_name
10
+ 'list'
11
+ end
12
+
13
+ def available_metafield_definitions
14
+ @available_metafield_definitions ||= Spree::MetafieldDefinition.where(resource_type: preferred_resource_type).available_on_front_end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ module Spree
2
+ module PageBlocks
3
+ module Products
4
+ class Brand < Spree::PageBlocks::Heading
5
+ preference :text_color, :string
6
+
7
+ SIZE_DEFAULT = 'medium'
8
+
9
+ def display_name
10
+ Spree.t(:brand)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -2,7 +2,7 @@ module Spree
2
2
  module PageBlocks
3
3
  module Products
4
4
  class BuyButtons < Spree::PageBlock
5
- TOP_PADDING_DEFAULT = 20
5
+ TOP_PADDING_DEFAULT = 0
6
6
  BOTTOM_PADDING_DEFAULT = 20
7
7
 
8
8
  preference :text_color, :string
@@ -14,6 +14,10 @@ module Spree
14
14
  def display_name
15
15
  Spree.t('page_blocks.products.buy_buttons.display_name')
16
16
  end
17
+
18
+ def form_partial_name
19
+ 'products/buy_buttons'
20
+ end
17
21
  end
18
22
  end
19
23
  end
@@ -0,0 +1,18 @@
1
+ module Spree
2
+ module PageBlocks
3
+ module Products
4
+ class Description < Spree::PageBlocks::Text
5
+ TOP_PADDING_DEFAULT = 0
6
+ BOTTOM_PADDING_DEFAULT = 20
7
+
8
+ def form_partial_name
9
+ 'products/description'
10
+ end
11
+
12
+ def display_name
13
+ I18n.t('activerecord.attributes.spree/product.description')
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -10,7 +10,7 @@ module Spree
10
10
  end
11
11
 
12
12
  def display_name
13
- 'Price'
13
+ Spree.t(:price)
14
14
  end
15
15
  end
16
16
  end
@@ -2,13 +2,17 @@ module Spree
2
2
  module PageBlocks
3
3
  module Products
4
4
  class QuantitySelector < Spree::PageBlock
5
- TOP_PADDING_DEFAULT = 20
5
+ TOP_PADDING_DEFAULT = 0
6
6
  BOTTOM_PADDING_DEFAULT = 20
7
7
 
8
8
  preference :text_color, :string
9
9
 
10
10
  def icon_name
11
- 'selector'
11
+ 'plus-minus'
12
+ end
13
+
14
+ def form_partial_name
15
+ 'products/quantity_selector'
12
16
  end
13
17
  end
14
18
  end
@@ -7,7 +7,11 @@ module Spree
7
7
  preference :text_color, :string
8
8
 
9
9
  def display_name
10
- section.product_name.presence || 'Title'
10
+ I18n.t('activerecord.attributes.spree/product.name')
11
+ end
12
+
13
+ def icon_name
14
+ 'h-1'
11
15
  end
12
16
  end
13
17
  end
@@ -5,7 +5,7 @@ module Spree
5
5
  preference :text_color, :string
6
6
 
7
7
  def icon_name
8
- 'select'
8
+ 'list-details'
9
9
  end
10
10
  end
11
11
  end
@@ -5,7 +5,7 @@ module Spree
5
5
  # Magic methods
6
6
  #
7
7
  acts_as_paranoid
8
- acts_as_list scope: [:pageable_id, { deleted_at: nil }]
8
+ acts_as_list scope: [:pageable_type, :pageable_id, { deleted_at: nil }]
9
9
 
10
10
  #
11
11
  # Associations
@@ -123,7 +123,7 @@ module Spree
123
123
  end
124
124
 
125
125
  def can_be_sorted?
126
- role == 'content'
126
+ true
127
127
  end
128
128
 
129
129
  def lazy?
@@ -0,0 +1,12 @@
1
+ module Spree
2
+ module PageSections
3
+ class Breadcrumbs < Spree::PageSection
4
+ TOP_PADDING_DEFAULT = 20
5
+ BOTTOM_PADDING_DEFAULT = 20
6
+
7
+ def icon_name
8
+ 'chevron-right'
9
+ end
10
+ end
11
+ end
12
+ end
@@ -48,16 +48,32 @@ module Spree
48
48
  shop_default_links << Spree::PageLink.new(linkable: new_arrivals_collection) if new_arrivals_collection.present?
49
49
  end
50
50
 
51
+ default_info_links = []
52
+
53
+ if store.policies.find_by(name: Spree.t('terms_of_service')).present?
54
+ default_info_links << Spree::PageLink.new(
55
+ label: Spree.t('terms_of_service'),
56
+ linkable: store.policies.find_by(name: Spree.t('terms_of_service'))
57
+ )
58
+ end
59
+
60
+ if store.policies.find_by(name: Spree.t('privacy_policy')).present?
61
+ default_info_links << Spree::PageLink.new(
62
+ label: Spree.t('privacy_policy'),
63
+ linkable: store.policies.find_by(name: Spree.t('privacy_policy'))
64
+ )
65
+ end
66
+
51
67
  [
52
68
  Spree::PageBlocks::Nav.new(
53
69
  preferred_label: 'Shop',
54
70
  default_links: shop_default_links
55
71
  ),
56
72
  Spree::PageBlocks::Nav.new(
57
- preferred_label: 'Account',
73
+ preferred_label: Spree.t('account'),
58
74
  default_links: [
59
75
  Spree::PageLink.new(
60
- label: 'My Account',
76
+ label: Spree.t('my_account'),
61
77
  linkable: pages.find_by(type: 'Spree::Pages::Account')
62
78
  ),
63
79
  Spree::PageLink.new(
@@ -72,17 +88,8 @@ module Spree
72
88
  ),
73
89
  Spree::PageBlocks::Nav.new(
74
90
  preferred_label: 'Info',
75
- default_links: [
76
- Spree::PageLink.new(
77
- label: 'Privacy Policy',
78
- linkable: store.customer_privacy_policy
79
- ),
80
- Spree::PageLink.new(
81
- label: 'Terms of Service',
82
- linkable: store.customer_terms_of_service
83
- ),
84
- ]
85
- ),
91
+ default_links: default_info_links
92
+ )
86
93
  ]
87
94
  end
88
95