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.
- checksums.yaml +4 -4
- data/app/assets/images/payment_icons/ach.svg +1 -0
- data/app/assets/images/payment_icons/achdirectdebit.svg +1 -0
- data/app/assets/images/payment_icons/ada.svg +1 -0
- data/app/assets/images/payment_icons/adyen.svg +1 -0
- data/app/assets/images/payment_icons/affinbank.svg +1 -0
- data/app/assets/images/payment_icons/affirm.svg +1 -0
- data/app/assets/images/payment_icons/afterpay.svg +1 -0
- data/app/assets/images/payment_icons/airtel_money.svg +1 -0
- data/app/assets/images/payment_icons/airteltigo_mobile_money.svg +1 -0
- data/app/assets/images/payment_icons/alandsbanken.svg +1 -0
- data/app/assets/images/payment_icons/alipay.svg +1 -0
- data/app/assets/images/payment_icons/alipay_hk.svg +1 -0
- data/app/assets/images/payment_icons/alliancebank.svg +1 -0
- data/app/assets/images/payment_icons/alma.svg +1 -0
- data/app/assets/images/payment_icons/amazon.svg +1 -0
- data/app/assets/images/payment_icons/ambank.svg +1 -0
- data/app/assets/images/payment_icons/american_express.svg +1 -0
- data/app/assets/images/payment_icons/apecoin.svg +1 -0
- data/app/assets/images/payment_icons/apple_pay.svg +1 -0
- data/app/assets/images/payment_icons/arbitrum.svg +1 -0
- data/app/assets/images/payment_icons/atome.svg +1 -0
- data/app/assets/images/payment_icons/authorizenet.svg +1 -0
- data/app/assets/images/payment_icons/avalanche.svg +1 -0
- data/app/assets/images/payment_icons/bacs.svg +1 -0
- data/app/assets/images/payment_icons/bancontact.svg +1 -0
- data/app/assets/images/payment_icons/bangkokbank.svg +1 -0
- data/app/assets/images/payment_icons/bankislam.svg +1 -0
- data/app/assets/images/payment_icons/bankmuamalat.svg +1 -0
- data/app/assets/images/payment_icons/bankofamerica.svg +1 -0
- data/app/assets/images/payment_icons/bankrakyat.svg +1 -0
- data/app/assets/images/payment_icons/base.svg +1 -0
- data/app/assets/images/payment_icons/becs.svg +1 -0
- data/app/assets/images/payment_icons/benefit.svg +1 -0
- data/app/assets/images/payment_icons/billie.svg +1 -0
- data/app/assets/images/payment_icons/bitcoin.svg +1 -0
- data/app/assets/images/payment_icons/bitcoin_cash.svg +1 -0
- data/app/assets/images/payment_icons/bizum.svg +1 -0
- data/app/assets/images/payment_icons/blik.svg +1 -0
- data/app/assets/images/payment_icons/bnbchain.svg +1 -0
- data/app/assets/images/payment_icons/bogus.svg +1 -0
- data/app/assets/images/payment_icons/bogus_app_coin.svg +1 -0
- data/app/assets/images/payment_icons/boleto.svg +1 -0
- data/app/assets/images/payment_icons/boost.svg +1 -0
- data/app/assets/images/payment_icons/braintree.svg +1 -0
- data/app/assets/images/payment_icons/buckaroopaybybank.svg +1 -0
- data/app/assets/images/payment_icons/busd.svg +1 -0
- data/app/assets/images/payment_icons/cartes_bancaires.svg +1 -0
- data/app/assets/images/payment_icons/cash.svg +1 -0
- data/app/assets/images/payment_icons/cashappafterpay.svg +1 -0
- data/app/assets/images/payment_icons/cashapppay.svg +1 -0
- data/app/assets/images/payment_icons/checkout_finance.svg +1 -0
- data/app/assets/images/payment_icons/chinabank.svg +1 -0
- data/app/assets/images/payment_icons/clearpay.svg +1 -0
- data/app/assets/images/payment_icons/collector_bank.svg +1 -0
- data/app/assets/images/payment_icons/dai.svg +1 -0
- data/app/assets/images/payment_icons/dana.svg +1 -0
- data/app/assets/images/payment_icons/dankort.svg +1 -0
- data/app/assets/images/payment_icons/danske_bank.svg +1 -0
- data/app/assets/images/payment_icons/deutschebank.svg +1 -0
- data/app/assets/images/payment_icons/diners_club.svg +1 -0
- data/app/assets/images/payment_icons/directbanktransferlatinamerica.svg +1 -0
- data/app/assets/images/payment_icons/discover.svg +1 -0
- data/app/assets/images/payment_icons/dogecoin.svg +1 -0
- data/app/assets/images/payment_icons/duitnow.svg +1 -0
- data/app/assets/images/payment_icons/eft_secure.svg +1 -0
- data/app/assets/images/payment_icons/eftpos_au.svg +1 -0
- data/app/assets/images/payment_icons/eftposau.svg +1 -0
- data/app/assets/images/payment_icons/elo.svg +1 -0
- data/app/assets/images/payment_icons/eos.svg +1 -0
- data/app/assets/images/payment_icons/eps.svg +1 -0
- data/app/assets/images/payment_icons/ethereum.svg +1 -0
- data/app/assets/images/payment_icons/eurobonuscheckout.svg +1 -0
- data/app/assets/images/payment_icons/ezcash.svg +1 -0
- data/app/assets/images/payment_icons/fantom.svg +1 -0
- data/app/assets/images/payment_icons/fpx.svg +1 -0
- data/app/assets/images/payment_icons/gcash.svg +1 -0
- data/app/assets/images/payment_icons/generic.svg +1 -0
- data/app/assets/images/payment_icons/genericbank.svg +1 -0
- data/app/assets/images/payment_icons/gift-card.svg +1 -0
- data/app/assets/images/payment_icons/giropay.svg +1 -0
- data/app/assets/images/payment_icons/glbepaypal.svg +1 -0
- data/app/assets/images/payment_icons/gmobanktransfer.svg +1 -0
- data/app/assets/images/payment_icons/gnosis.svg +1 -0
- data/app/assets/images/payment_icons/google_pay.svg +1 -0
- data/app/assets/images/payment_icons/google_wallet.svg +1 -0
- data/app/assets/images/payment_icons/gopay.svg +1 -0
- data/app/assets/images/payment_icons/grabpay.svg +1 -0
- data/app/assets/images/payment_icons/gusd.svg +1 -0
- data/app/assets/images/payment_icons/handelsbanken.svg +1 -0
- data/app/assets/images/payment_icons/hongleongbank.svg +1 -0
- data/app/assets/images/payment_icons/hypercard.svg +1 -0
- data/app/assets/images/payment_icons/hypercash.svg +1 -0
- data/app/assets/images/payment_icons/ideal.svg +1 -0
- data/app/assets/images/payment_icons/in3viaideal.svg +1 -0
- data/app/assets/images/payment_icons/inbank.svg +1 -0
- data/app/assets/images/payment_icons/jcb.svg +1 -0
- data/app/assets/images/payment_icons/kakao_pay.svg +1 -0
- data/app/assets/images/payment_icons/kasikornbank.svg +1 -0
- data/app/assets/images/payment_icons/klarna-pay-later.svg +1 -0
- data/app/assets/images/payment_icons/klarna-pay-now.svg +1 -0
- data/app/assets/images/payment_icons/klarna-slice-it.svg +1 -0
- data/app/assets/images/payment_icons/klarna.svg +1 -0
- data/app/assets/images/payment_icons/knet.svg +1 -0
- data/app/assets/images/payment_icons/krungthaibank.svg +1 -0
- data/app/assets/images/payment_icons/landbank.svg +1 -0
- data/app/assets/images/payment_icons/laybuybyklarna.svg +1 -0
- data/app/assets/images/payment_icons/litecoin.svg +1 -0
- data/app/assets/images/payment_icons/lunchcheck.svg +1 -0
- data/app/assets/images/payment_icons/mach.svg +1 -0
- data/app/assets/images/payment_icons/mada.svg +1 -0
- data/app/assets/images/payment_icons/maestro.svg +1 -0
- data/app/assets/images/payment_icons/master.svg +1 -0
- data/app/assets/images/payment_icons/mayabank.svg +1 -0
- data/app/assets/images/payment_icons/maybank.svg +1 -0
- data/app/assets/images/payment_icons/maybankm2u.svg +1 -0
- data/app/assets/images/payment_icons/maybankqrpay.svg +1 -0
- data/app/assets/images/payment_icons/mbway.svg +1 -0
- data/app/assets/images/payment_icons/mcash.svg +1 -0
- data/app/assets/images/payment_icons/medicinosbankas.svg +1 -0
- data/app/assets/images/payment_icons/mercadopago.svg +1 -0
- data/app/assets/images/payment_icons/metrobank.svg +1 -0
- data/app/assets/images/payment_icons/mobilepay.svg +1 -0
- data/app/assets/images/payment_icons/momopay.svg +1 -0
- data/app/assets/images/payment_icons/monero.svg +1 -0
- data/app/assets/images/payment_icons/mtn_mobile_money.svg +1 -0
- data/app/assets/images/payment_icons/mybank.svg +1 -0
- data/app/assets/images/payment_icons/naver_pay.svg +1 -0
- data/app/assets/images/payment_icons/nelo.svg +1 -0
- data/app/assets/images/payment_icons/netbanking.svg +1 -0
- data/app/assets/images/payment_icons/novalnetdirectdebitach.svg +1 -0
- data/app/assets/images/payment_icons/nubank.svg +1 -0
- data/app/assets/images/payment_icons/ocbcbank.svg +1 -0
- data/app/assets/images/payment_icons/offlinebanktransferlatinamerica.svg +1 -0
- data/app/assets/images/payment_icons/ola_money.svg +1 -0
- data/app/assets/images/payment_icons/oney.svg +1 -0
- data/app/assets/images/payment_icons/onlinebanking.svg +1 -0
- data/app/assets/images/payment_icons/onlinebanktransfer.svg +1 -0
- data/app/assets/images/payment_icons/orangemobilemoney.svg +1 -0
- data/app/assets/images/payment_icons/otpbank.svg +1 -0
- data/app/assets/images/payment_icons/oxxo.svg +1 -0
- data/app/assets/images/payment_icons/paybybank.svg +1 -0
- data/app/assets/images/payment_icons/paybybankmollie.svg +1 -0
- data/app/assets/images/payment_icons/paybybankus.svg +1 -0
- data/app/assets/images/payment_icons/paycash.svg +1 -0
- data/app/assets/images/payment_icons/payco.svg +1 -0
- data/app/assets/images/payment_icons/payeverpaybybank.svg +1 -0
- data/app/assets/images/payment_icons/payme.svg +1 -0
- data/app/assets/images/payment_icons/paynow.svg +1 -0
- data/app/assets/images/payment_icons/paynowmbank.svg +1 -0
- data/app/assets/images/payment_icons/paypal.svg +1 -0
- data/app/assets/images/payment_icons/paypo.svg +1 -0
- data/app/assets/images/payment_icons/payrexxbanktransfer.svg +1 -0
- data/app/assets/images/payment_icons/payrexxpaybybank.svg +1 -0
- data/app/assets/images/payment_icons/paysafecash.svg +1 -0
- data/app/assets/images/payment_icons/pix.svg +1 -0
- data/app/assets/images/payment_icons/polygon.svg +1 -0
- data/app/assets/images/payment_icons/przelewy24.svg +1 -0
- data/app/assets/images/payment_icons/publicbank.svg +1 -0
- data/app/assets/images/payment_icons/publicbank_pbe.svg +1 -0
- data/app/assets/images/payment_icons/qr_promptpay.svg +1 -0
- data/app/assets/images/payment_icons/rabobank.svg +1 -0
- data/app/assets/images/payment_icons/revolut.svg +1 -0
- data/app/assets/images/payment_icons/rhbbank.svg +1 -0
- data/app/assets/images/payment_icons/riverty.svg +1 -0
- data/app/assets/images/payment_icons/safetypaybanktransfer.svg +1 -0
- data/app/assets/images/payment_icons/samsung_pay.svg +1 -0
- data/app/assets/images/payment_icons/satispay.svg +1 -0
- data/app/assets/images/payment_icons/scalapay.svg +1 -0
- data/app/assets/images/payment_icons/scotiabank.svg +1 -0
- data/app/assets/images/payment_icons/seabankid.svg +1 -0
- data/app/assets/images/payment_icons/seabankph.svg +1 -0
- data/app/assets/images/payment_icons/sepa_bank_transfer.svg +1 -0
- data/app/assets/images/payment_icons/sepadirectdebit.svg +1 -0
- data/app/assets/images/payment_icons/seveneleven.svg +1 -0
- data/app/assets/images/payment_icons/shib.svg +1 -0
- data/app/assets/images/payment_icons/shopcash.svg +1 -0
- data/app/assets/images/payment_icons/siauliubankas.svg +1 -0
- data/app/assets/images/payment_icons/skeps.svg +1 -0
- data/app/assets/images/payment_icons/snap_checkout.svg +1 -0
- data/app/assets/images/payment_icons/sofort.svg +1 -0
- data/app/assets/images/payment_icons/softbank.svg +1 -0
- data/app/assets/images/payment_icons/spei.svg +1 -0
- data/app/assets/images/payment_icons/storecredit.svg +1 -0
- data/app/assets/images/payment_icons/stripe.svg +1 -0
- data/app/assets/images/payment_icons/sveacheckout.svg +1 -0
- data/app/assets/images/payment_icons/swedbank.svg +1 -0
- data/app/assets/images/payment_icons/swish.svg +1 -0
- data/app/assets/images/payment_icons/tbibank.svg +1 -0
- data/app/assets/images/payment_icons/thanachartbank.svg +1 -0
- data/app/assets/images/payment_icons/tnmmoney.svg +1 -0
- data/app/assets/images/payment_icons/touchngo.svg +1 -0
- data/app/assets/images/payment_icons/trustly.svg +1 -0
- data/app/assets/images/payment_icons/twint.svg +1 -0
- data/app/assets/images/payment_icons/uaevisa.svg +1 -0
- data/app/assets/images/payment_icons/unionpay.svg +1 -0
- data/app/assets/images/payment_icons/unzerbanktransfer.svg +1 -0
- data/app/assets/images/payment_icons/upi.svg +1 -0
- data/app/assets/images/payment_icons/usbank.svg +1 -0
- data/app/assets/images/payment_icons/usdc.svg +1 -0
- data/app/assets/images/payment_icons/usdt.svg +1 -0
- data/app/assets/images/payment_icons/venmo.svg +1 -0
- data/app/assets/images/payment_icons/vipps.svg +1 -0
- data/app/assets/images/payment_icons/visa.svg +1 -0
- data/app/assets/images/payment_icons/volksbank.svg +1 -0
- data/app/assets/images/payment_icons/waavepaybybank.svg +1 -0
- data/app/assets/images/payment_icons/walley.svg +1 -0
- data/app/assets/images/payment_icons/wbtc.svg +1 -0
- data/app/assets/images/payment_icons/wechatpay.svg +1 -0
- data/app/assets/images/payment_icons/whishcheckout.svg +1 -0
- data/app/assets/images/payment_icons/wingbank.svg +1 -0
- data/app/assets/images/payment_icons/xrp.svg +1 -0
- data/app/assets/images/payment_icons/zip.svg +1 -0
- data/app/finders/spree/posts/find.rb +137 -0
- data/app/helpers/spree/addresses_helper.rb +9 -3
- data/app/helpers/spree/base_helper.rb +8 -4
- data/app/jobs/spree/images/save_from_url_job.rb +70 -0
- data/app/jobs/spree/imports/create_rows_job.rb +72 -0
- data/app/jobs/spree/imports/process_rows_job.rb +19 -0
- data/app/models/concerns/spree/adjustment_source.rb +3 -3
- data/app/models/concerns/spree/admin_user_methods.rb +52 -0
- data/app/models/concerns/spree/display_on.rb +7 -1
- data/app/models/concerns/spree/has_image_alt_text.rb +18 -0
- data/app/models/concerns/spree/has_one_link.rb +1 -1
- data/app/models/concerns/spree/has_page_links.rb +1 -1
- data/app/models/concerns/spree/linkable.rb +9 -0
- data/app/models/concerns/spree/metadata.rb +2 -0
- data/app/models/concerns/spree/metafields.rb +94 -0
- data/app/models/concerns/spree/named_type.rb +1 -1
- data/app/models/concerns/spree/user_methods.rb +20 -7
- data/app/models/concerns/spree/user_payment_source.rb +1 -1
- data/app/models/concerns/spree/user_roles.rb +3 -2
- data/app/models/spree/ability.rb +4 -0
- data/app/models/spree/address.rb +3 -1
- data/app/models/spree/adjustable/adjuster/tax.rb +2 -2
- data/app/models/spree/adjustable/adjustments_updater.rb +26 -3
- data/app/models/spree/adjustment.rb +4 -1
- data/app/models/spree/asset.rb +16 -0
- data/app/models/spree/base.rb +1 -1
- data/app/models/spree/credit_card.rb +1 -0
- data/app/models/spree/current.rb +5 -1
- data/app/models/spree/custom_domain.rb +5 -0
- data/app/models/spree/customer_return.rb +1 -0
- data/app/models/spree/export.rb +39 -2
- data/app/models/spree/exports/customers.rb +17 -0
- data/app/models/spree/exports/gift_cards.rb +13 -0
- data/app/models/spree/exports/newsletter_subscribers.rb +13 -0
- data/app/models/spree/exports/orders.rb +6 -4
- data/app/models/spree/exports/products.rb +9 -3
- data/app/models/spree/gift_card.rb +7 -1
- data/app/models/spree/gift_card_batch.rb +0 -1
- data/app/models/spree/import.rb +279 -0
- data/app/models/spree/import_mapping.rb +46 -0
- data/app/models/spree/import_row.rb +108 -0
- data/app/models/spree/import_schema.rb +25 -0
- data/app/models/spree/import_schemas/products.rb +45 -0
- data/app/models/spree/imports/products.rb +9 -0
- data/app/models/spree/invitation.rb +1 -1
- data/app/models/spree/legacy_user.rb +0 -1
- data/app/models/spree/line_item.rb +2 -7
- data/app/models/spree/metafield.rb +53 -0
- data/app/models/spree/metafield_definition.rb +91 -0
- data/app/models/spree/metafields/boolean.rb +15 -0
- data/app/models/spree/metafields/json.rb +27 -0
- data/app/models/spree/metafields/long_text.rb +7 -0
- data/app/models/spree/metafields/number.rb +15 -0
- data/app/models/spree/metafields/rich_text.rb +18 -0
- data/app/models/spree/metafields/short_text.rb +7 -0
- data/app/models/spree/newsletter_subscriber/emails.rb +12 -0
- data/app/models/spree/newsletter_subscriber.rb +64 -0
- data/app/models/spree/option_type.rb +2 -0
- data/app/models/spree/option_value.rb +1 -0
- data/app/models/spree/order/checkout.rb +7 -0
- data/app/models/spree/order.rb +8 -3
- data/app/models/spree/order_merger.rb +2 -4
- data/app/models/spree/order_promotion.rb +3 -0
- data/app/models/spree/order_updater.rb +2 -2
- data/app/models/spree/page.rb +5 -1
- data/app/models/spree/page_block.rb +4 -0
- data/app/models/spree/page_blocks/image.rb +3 -0
- data/app/models/spree/page_blocks/metafields.rb +18 -0
- data/app/models/spree/page_blocks/products/brand.rb +15 -0
- data/app/models/spree/page_blocks/products/buy_buttons.rb +5 -1
- data/app/models/spree/page_blocks/products/description.rb +18 -0
- data/app/models/spree/page_blocks/products/price.rb +1 -1
- data/app/models/spree/page_blocks/products/quantity_selector.rb +6 -2
- data/app/models/spree/page_blocks/products/title.rb +5 -1
- data/app/models/spree/page_blocks/products/variant_picker.rb +1 -1
- data/app/models/spree/page_section.rb +2 -2
- data/app/models/spree/page_sections/breadcrumbs.rb +12 -0
- data/app/models/spree/page_sections/footer.rb +20 -13
- data/app/models/spree/page_sections/image_banner.rb +6 -1
- data/app/models/spree/page_sections/image_with_text.rb +5 -0
- data/app/models/spree/page_sections/newsletter.rb +7 -0
- data/app/models/spree/page_sections/product_details.rb +38 -1
- data/app/models/spree/pages/account.rb +4 -0
- data/app/models/spree/pages/cart.rb +10 -0
- data/app/models/spree/pages/checkout.rb +6 -0
- data/app/models/spree/pages/custom.rb +4 -0
- data/app/models/spree/pages/homepage.rb +4 -0
- data/app/models/spree/pages/login.rb +4 -0
- data/app/models/spree/pages/password.rb +2 -0
- data/app/models/spree/pages/post_list.rb +4 -0
- data/app/models/spree/pages/product_details.rb +1 -0
- data/app/models/spree/pages/shop_all.rb +4 -0
- data/app/models/spree/pages/wishlist.rb +4 -0
- data/app/models/spree/payment.rb +1 -0
- data/app/models/spree/payment_method.rb +4 -5
- data/app/models/spree/payment_source.rb +1 -0
- data/app/models/spree/policy.rb +70 -0
- data/app/models/spree/post.rb +4 -2
- data/app/models/spree/post_category.rb +1 -0
- data/app/models/spree/product.rb +16 -9
- data/app/models/spree/promotion/actions/free_shipping.rb +3 -3
- data/app/models/spree/promotion.rb +24 -8
- data/app/models/spree/promotion_action.rb +1 -1
- data/app/models/spree/promotion_handler/cart.rb +1 -1
- data/app/models/spree/promotion_handler/coupon.rb +1 -1
- data/app/models/spree/promotion_rule.rb +1 -1
- data/app/models/spree/property.rb +18 -0
- data/app/models/spree/refund.rb +2 -1
- data/app/models/spree/role_user.rb +1 -1
- data/app/models/spree/shipment.rb +1 -0
- data/app/models/spree/shipping_method.rb +1 -0
- data/app/models/spree/stock_item.rb +1 -0
- data/app/models/spree/stock_transfer.rb +1 -0
- data/app/models/spree/store.rb +45 -3
- data/app/models/spree/store_credit.rb +2 -1
- data/app/models/spree/tax_category.rb +1 -1
- data/app/models/spree/tax_rate.rb +18 -3
- data/app/models/spree/taxon.rb +12 -2
- data/app/models/spree/taxonomy.rb +11 -0
- data/app/models/spree/theme.rb +1 -1
- data/app/models/spree/variant.rb +17 -0
- data/app/presenters/spree/csv/customer_presenter.rb +59 -0
- data/app/presenters/spree/csv/gift_card_presenter.rb +49 -0
- data/app/presenters/spree/csv/metafields_helper.rb +17 -0
- data/app/presenters/spree/csv/newsletter_subscriber_presenter.rb +39 -0
- data/app/presenters/spree/csv/order_line_item_presenter.rb +12 -5
- data/app/presenters/spree/csv/product_variant_presenter.rb +9 -5
- data/app/services/spree/cart/recalculate.rb +6 -4
- data/app/services/spree/cart/remove_line_item.rb +1 -2
- data/app/services/spree/imports/row_processors/base.rb +19 -0
- data/app/services/spree/imports/row_processors/product_variant.rb +228 -0
- data/app/services/spree/line_items/destroy.rb +1 -1
- data/app/services/spree/newsletter/subscribe.rb +43 -0
- data/app/services/spree/newsletter/verify.rb +30 -0
- data/app/sorters/spree/posts/sort.rb +40 -0
- data/app/views/spree/shared/_payment.html.erb +3 -3
- data/config/locales/en.yml +56 -2
- data/db/migrate/20250605131334_add_missing_fields_to_users.rb +23 -13
- data/db/migrate/20250728095629_create_spree_metafields.rb +27 -0
- data/db/migrate/20250730102644_add_missing_unique_indexes_to_spree_option_types_and_values.rb +40 -0
- data/db/migrate/20250730154601_add_unique_index_on_spree_properties_name.rb +24 -0
- data/db/migrate/20250811112056_create_spree_policies.rb +22 -0
- data/db/migrate/20250821211705_fix_unique_index_on_spree_order_promotions.rb +20 -0
- data/db/migrate/20250825175217_add_missing_page_builder_indexes.rb +7 -0
- data/db/migrate/20250826093602_create_spree_newsletter_subscribers.rb +12 -0
- data/db/migrate/20250902143122_fix_policies_store_association.rb +18 -0
- data/db/migrate/20250911205659_add_missing_index_on_spree_products_promotionable.rb +5 -0
- data/db/migrate/20250913130044_add_page_links_counter_cache_to_spree_stores.rb +10 -0
- data/db/migrate/20250914101955_add_missing_indexes_on_spree_adjustments.rb +6 -0
- data/db/migrate/20250915093930_add_metadata_to_spree_newsletter_subscribers.rb +20 -0
- data/db/migrate/20250923141845_create_spree_imports.rb +47 -0
- data/lib/generators/spree/cursor_rules/cursor_rules_generator.rb +19 -0
- data/lib/generators/spree/cursor_rules/templates/spree_rules.mdc +387 -0
- data/lib/generators/spree/dummy/dummy_generator.rb +0 -1
- data/lib/generators/spree/install/templates/config/initializers/spree.rb +5 -0
- data/lib/spree/core/configuration.rb +1 -0
- data/lib/spree/core/dependencies.rb +3 -0
- data/lib/spree/core/engine.rb +57 -2
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +3 -1
- data/lib/spree/permitted_attributes.rb +18 -3
- data/lib/spree/testing_support/capybara_config.rb +9 -3
- data/lib/spree/testing_support/factories/export_factory.rb +5 -17
- data/lib/spree/testing_support/factories/import_factory.rb +20 -0
- data/lib/spree/testing_support/factories/import_mapping_factory.rb +7 -0
- data/lib/spree/testing_support/factories/import_row_factory.rb +7 -0
- data/lib/spree/testing_support/factories/metafield_definition_factory.rb +72 -0
- data/lib/spree/testing_support/factories/metafield_factory.rb +68 -0
- data/lib/spree/testing_support/factories/newsletter_subscriber_factory.rb +18 -0
- data/lib/spree/testing_support/factories/policy_factory.rb +8 -0
- data/lib/spree/testing_support/factories/post_factory.rb +8 -0
- data/lib/spree/testing_support/store.rb +11 -0
- data/lib/tasks/core.rake +128 -0
- metadata +279 -6
- data/app/models/action_text/rich_text_decorator.rb +0 -11
- data/app/presenters/spree/csv/product_presenter.rb +0 -63
|
@@ -5,6 +5,7 @@ module Spree
|
|
|
5
5
|
include Spree::Core::NumberGenerator.new(prefix: 'H', length: 11)
|
|
6
6
|
include Spree::NumberIdentifier
|
|
7
7
|
include Spree::NumberAsParam
|
|
8
|
+
include Spree::Metafields
|
|
8
9
|
include Spree::Metadata
|
|
9
10
|
if defined?(Spree::Security::Shipments)
|
|
10
11
|
include Spree::Security::Shipments
|
|
@@ -3,6 +3,7 @@ module Spree
|
|
|
3
3
|
include Spree::Core::NumberGenerator.new(prefix: 'T')
|
|
4
4
|
include Spree::NumberIdentifier
|
|
5
5
|
include Spree::NumberAsParam
|
|
6
|
+
include Spree::Metafields
|
|
6
7
|
include Spree::Metadata
|
|
7
8
|
if defined?(Spree::Webhooks::HasWebhooks)
|
|
8
9
|
include Spree::Webhooks::HasWebhooks
|
data/app/models/spree/store.rb
CHANGED
|
@@ -8,12 +8,14 @@ module Spree
|
|
|
8
8
|
|
|
9
9
|
include FriendlyId
|
|
10
10
|
include Spree::TranslatableResource
|
|
11
|
+
include Spree::Metafields
|
|
11
12
|
include Spree::Metadata
|
|
12
13
|
include Spree::Stores::Setup
|
|
13
14
|
include Spree::Stores::Socials
|
|
14
15
|
include Spree::Webhooks::HasWebhooks if defined?(Spree::Webhooks::HasWebhooks)
|
|
15
16
|
include Spree::Security::Stores if defined?(Spree::Security::Stores)
|
|
16
17
|
include Spree::UserManagement
|
|
18
|
+
include Spree::HasPageLinks
|
|
17
19
|
|
|
18
20
|
#
|
|
19
21
|
# Magic methods
|
|
@@ -111,6 +113,8 @@ module Spree
|
|
|
111
113
|
|
|
112
114
|
has_many :gift_cards, class_name: 'Spree::GiftCard', dependent: :destroy
|
|
113
115
|
|
|
116
|
+
has_many :policies, class_name: 'Spree::Policy', dependent: :destroy, as: :owner
|
|
117
|
+
|
|
114
118
|
#
|
|
115
119
|
# Page Builder associations
|
|
116
120
|
#
|
|
@@ -123,6 +127,7 @@ module Spree
|
|
|
123
127
|
inverse_of: :store,
|
|
124
128
|
dependent: :destroy
|
|
125
129
|
has_one :default_theme, -> { without_previews.where(default: true) }, class_name: 'Spree::Theme', inverse_of: :store
|
|
130
|
+
alias theme default_theme
|
|
126
131
|
has_many :theme_pages, class_name: 'Spree::Page', through: :themes, source: :pages
|
|
127
132
|
has_many :theme_page_previews, class_name: 'Spree::Page', through: :theme_pages, source: :previews
|
|
128
133
|
has_many :pages, -> { without_previews.custom }, class_name: 'Spree::Pages::Custom', dependent: :destroy, as: :pageable
|
|
@@ -185,6 +190,7 @@ module Spree
|
|
|
185
190
|
after_create :import_products_from_store, if: -> { import_products_from_store_id.present? }
|
|
186
191
|
after_create :import_payment_methods_from_store, if: -> { import_payment_methods_from_store_id.present? }
|
|
187
192
|
after_create :create_default_theme
|
|
193
|
+
after_create :create_default_policies
|
|
188
194
|
before_destroy :validate_not_last, unless: :skip_validate_not_last
|
|
189
195
|
before_destroy :pass_default_flag_to_other_store
|
|
190
196
|
after_commit :clear_cache
|
|
@@ -203,7 +209,11 @@ module Spree
|
|
|
203
209
|
delegate :iso, to: :default_country, prefix: true, allow_nil: true
|
|
204
210
|
|
|
205
211
|
def self.current(url = nil)
|
|
206
|
-
|
|
212
|
+
if url.present?
|
|
213
|
+
Spree::Dependencies.current_store_finder.constantize.new(url: url).execute
|
|
214
|
+
else
|
|
215
|
+
Spree::Current.store
|
|
216
|
+
end
|
|
207
217
|
end
|
|
208
218
|
|
|
209
219
|
# FIXME: we need to drop `or_initialize` in v5
|
|
@@ -320,15 +330,20 @@ module Spree
|
|
|
320
330
|
formatted_custom_domain || formatted_url
|
|
321
331
|
end
|
|
322
332
|
|
|
333
|
+
# Returns the countries available for checkout for the store or creates a new one if it doesn't exist
|
|
334
|
+
# @return [Array<Spree::Country>]
|
|
323
335
|
def countries_available_for_checkout
|
|
324
336
|
@countries_available_for_checkout ||= Rails.cache.fetch(countries_available_for_checkout_cache_key) do
|
|
325
|
-
checkout_zone.try(:country_list) || Spree::Country.all
|
|
337
|
+
(checkout_zone.try(:country_list) || Spree::Country.all).to_a
|
|
326
338
|
end
|
|
327
339
|
end
|
|
328
340
|
|
|
341
|
+
# Returns the states available for checkout for the store or creates a new one if it doesn't exist
|
|
342
|
+
# @param country [Spree::Country] the country to get the states for
|
|
343
|
+
# @return [Array<Spree::State>]
|
|
329
344
|
def states_available_for_checkout(country)
|
|
330
345
|
Rails.cache.fetch(states_available_for_checkout_cache_key(country)) do
|
|
331
|
-
checkout_zone.try(:state_list_for, country) || country.states
|
|
346
|
+
(checkout_zone.try(:state_list_for, country) || country.states).to_a
|
|
332
347
|
end
|
|
333
348
|
end
|
|
334
349
|
|
|
@@ -403,6 +418,21 @@ module Spree
|
|
|
403
418
|
StorePaymentMethod.insert_all(payment_method_ids.map { |payment_method_id| { store_id: id, payment_method_id: payment_method_id } })
|
|
404
419
|
end
|
|
405
420
|
|
|
421
|
+
%w[customer_terms_of_service customer_privacy_policy customer_returns_policy customer_shipping_policy].each do |policy_method|
|
|
422
|
+
define_method policy_method do
|
|
423
|
+
Spree::Deprecation.warn("Store##{policy_method} is deprecated and will be removed in Spree 6.0. Please use Store#policies instead.")
|
|
424
|
+
|
|
425
|
+
ActionText::RichText.find_by(name: policy_method, record: self)
|
|
426
|
+
end
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
# Returns all active webhooks subscribers for the store
|
|
430
|
+
#
|
|
431
|
+
# @return [Array<Spree::Webhooks::Subscriber>]
|
|
432
|
+
def active_webhooks_subscribers
|
|
433
|
+
@active_webhooks_subscribers ||= Spree::Webhooks::Subscriber.active
|
|
434
|
+
end
|
|
435
|
+
|
|
406
436
|
private
|
|
407
437
|
|
|
408
438
|
def countries_available_for_checkout_cache_key
|
|
@@ -496,6 +526,18 @@ module Spree
|
|
|
496
526
|
post_categories.find_or_create_by(title: Spree.t('default_post_categories.news'))
|
|
497
527
|
end
|
|
498
528
|
|
|
529
|
+
def create_default_policies
|
|
530
|
+
policies.find_or_create_by(name: Spree.t('terms_of_service'))
|
|
531
|
+
policies.find_or_create_by(name: Spree.t('privacy_policy'))
|
|
532
|
+
policies.find_or_create_by(name: Spree.t('returns_policy'))
|
|
533
|
+
policies.find_or_create_by(name: Spree.t('shipping_policy'))
|
|
534
|
+
|
|
535
|
+
# Create checkout links to the policies
|
|
536
|
+
policies.each do |policy|
|
|
537
|
+
links.find_or_create_by(linkable: policy)
|
|
538
|
+
end
|
|
539
|
+
end
|
|
540
|
+
|
|
499
541
|
# code is slug, so we don't want to generate new slug when code changes
|
|
500
542
|
# we use friendlyId only for history feature
|
|
501
543
|
def should_generate_new_friendly_id?
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
class StoreCredit < Spree.base_class
|
|
3
3
|
include Spree::SingleStoreResource
|
|
4
|
+
include Spree::Metafields
|
|
4
5
|
include Spree::Metadata
|
|
5
6
|
if defined?(Spree::Webhooks::HasWebhooks)
|
|
6
7
|
include Spree::Webhooks::HasWebhooks
|
|
@@ -19,7 +20,7 @@ module Spree
|
|
|
19
20
|
belongs_to :store, class_name: 'Spree::Store'
|
|
20
21
|
belongs_to :user, class_name: "::#{Spree.user_class}", foreign_key: 'user_id'
|
|
21
22
|
belongs_to :category, class_name: 'Spree::StoreCreditCategory', optional: true
|
|
22
|
-
belongs_to :created_by, class_name:
|
|
23
|
+
belongs_to :created_by, class_name: Spree.admin_user_class.to_s, foreign_key: 'created_by_id', optional: true
|
|
23
24
|
belongs_to :credit_type, class_name: 'Spree::StoreCreditType', foreign_key: 'type_id', optional: true
|
|
24
25
|
belongs_to :originator, polymorphic: true, optional: true
|
|
25
26
|
|
|
@@ -5,7 +5,7 @@ module Spree
|
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
acts_as_paranoid
|
|
8
|
-
validates :name, presence: true, uniqueness: { case_sensitive: false, scope: spree_base_uniqueness_scope
|
|
8
|
+
validates :name, presence: true, uniqueness: { case_sensitive: false, scope: spree_base_uniqueness_scope + [:deleted_at] }
|
|
9
9
|
|
|
10
10
|
has_many :tax_rates, dependent: :destroy, inverse_of: :tax_category
|
|
11
11
|
has_many :products, dependent: :nullify
|
|
@@ -4,6 +4,7 @@ module Spree
|
|
|
4
4
|
|
|
5
5
|
include Spree::CalculatedAdjustments
|
|
6
6
|
include Spree::AdjustmentSource
|
|
7
|
+
include Spree::Metafields
|
|
7
8
|
include Spree::Metadata
|
|
8
9
|
if defined?(Spree::Webhooks::HasWebhooks)
|
|
9
10
|
include Spree::Webhooks::HasWebhooks
|
|
@@ -71,15 +72,21 @@ module Spree
|
|
|
71
72
|
# Deletes all tax adjustments, then applies all applicable rates
|
|
72
73
|
# to relevant items.
|
|
73
74
|
def self.adjust(order, items)
|
|
75
|
+
return if items.none?
|
|
76
|
+
|
|
74
77
|
rates = match(order.tax_zone)
|
|
75
78
|
tax_category_ids = rates.map(&:tax_category_id)
|
|
76
79
|
|
|
77
80
|
# using destroy_all to ensure adjustment destroy callback fires.
|
|
78
81
|
Spree::Adjustment.where(adjustable: items).tax.destroy_all
|
|
79
82
|
|
|
80
|
-
relevant_items =
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
relevant_items = if tax_category_ids.any?
|
|
84
|
+
items.select do |item|
|
|
85
|
+
tax_category_ids.include?(item.tax_category_id)
|
|
86
|
+
end
|
|
87
|
+
else
|
|
88
|
+
[]
|
|
89
|
+
end
|
|
83
90
|
|
|
84
91
|
relevant_items.each do |item|
|
|
85
92
|
relevant_rates = rates.select do |rate|
|
|
@@ -115,6 +122,14 @@ module Spree
|
|
|
115
122
|
compute(item)
|
|
116
123
|
end
|
|
117
124
|
|
|
125
|
+
def included?
|
|
126
|
+
included_in_price
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def additional?
|
|
130
|
+
!included_in_price
|
|
131
|
+
end
|
|
132
|
+
|
|
118
133
|
private
|
|
119
134
|
|
|
120
135
|
def label
|
data/app/models/spree/taxon.rb
CHANGED
|
@@ -16,8 +16,10 @@ module Spree
|
|
|
16
16
|
|
|
17
17
|
include Spree::TranslatableResource
|
|
18
18
|
include Spree::TranslatableResourceSlug
|
|
19
|
+
include Spree::Metafields
|
|
19
20
|
include Spree::Metadata
|
|
20
21
|
include Spree::MemoizedData
|
|
22
|
+
include Spree::Linkable
|
|
21
23
|
if defined?(Spree::Webhooks::HasWebhooks)
|
|
22
24
|
include Spree::Webhooks::HasWebhooks
|
|
23
25
|
end
|
|
@@ -46,8 +48,6 @@ module Spree
|
|
|
46
48
|
has_many :promotion_rule_taxons, class_name: 'Spree::PromotionRuleTaxon', dependent: :destroy
|
|
47
49
|
has_many :promotion_rules, through: :promotion_rule_taxons, class_name: 'Spree::PromotionRule'
|
|
48
50
|
|
|
49
|
-
has_many :page_links, as: :linkable, class_name: 'Spree::PageLink', dependent: :destroy
|
|
50
|
-
|
|
51
51
|
#
|
|
52
52
|
# Attachments
|
|
53
53
|
#
|
|
@@ -118,6 +118,16 @@ module Spree
|
|
|
118
118
|
end
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
+
scope :with_matching_name, ->(name_to_match) do
|
|
122
|
+
value = name_to_match.to_s.strip.downcase
|
|
123
|
+
|
|
124
|
+
if Spree.use_translations?
|
|
125
|
+
i18n { name.lower.eq(value) }
|
|
126
|
+
else
|
|
127
|
+
where(arel_table[:name].lower.eq(value))
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
121
131
|
#
|
|
122
132
|
# Ransack
|
|
123
133
|
#
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
class Taxonomy < Spree.base_class
|
|
3
3
|
include Spree::TranslatableResource
|
|
4
|
+
include Spree::Metafields
|
|
4
5
|
include Spree::Metadata
|
|
5
6
|
include Spree::SingleStoreResource
|
|
6
7
|
if defined?(Spree::Webhooks::HasWebhooks)
|
|
@@ -24,6 +25,16 @@ module Spree
|
|
|
24
25
|
|
|
25
26
|
default_scope { order("#{table_name}.position, #{table_name}.created_at") }
|
|
26
27
|
|
|
28
|
+
scope :with_matching_name, ->(name_to_match) do
|
|
29
|
+
value = name_to_match.to_s.strip.downcase
|
|
30
|
+
|
|
31
|
+
if Spree.use_translations?
|
|
32
|
+
i18n { name.lower.eq(value) }
|
|
33
|
+
else
|
|
34
|
+
where(arel_table[:name].lower.eq(value))
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
27
38
|
self.whitelisted_ransackable_attributes = %w[name]
|
|
28
39
|
self.whitelisted_ransackable_associations = %w[root]
|
|
29
40
|
|
data/app/models/spree/theme.rb
CHANGED
|
@@ -21,7 +21,7 @@ module Spree
|
|
|
21
21
|
has_many :previews, class_name: 'Spree::Theme', foreign_key: :parent_id, dependent: :destroy_async
|
|
22
22
|
has_many :pages, -> { without_previews }, class_name: 'Spree::Page', dependent: :destroy, as: :pageable
|
|
23
23
|
has_many :page_previews, -> { only_previews }, class_name: 'Spree::Page', dependent: :destroy_async, as: :pageable
|
|
24
|
-
has_many :layout_sections, class_name: 'Spree::PageSection', dependent: :destroy, as: :pageable
|
|
24
|
+
has_many :layout_sections, -> { order(position: :asc) }, class_name: 'Spree::PageSection', dependent: :destroy, as: :pageable
|
|
25
25
|
alias sections layout_sections
|
|
26
26
|
|
|
27
27
|
#
|
data/app/models/spree/variant.rb
CHANGED
|
@@ -4,6 +4,7 @@ module Spree
|
|
|
4
4
|
acts_as_list scope: :product
|
|
5
5
|
|
|
6
6
|
include Spree::MemoizedData
|
|
7
|
+
include Spree::Metafields
|
|
7
8
|
include Spree::Metadata
|
|
8
9
|
include Spree::Variant::Webhooks
|
|
9
10
|
|
|
@@ -393,6 +394,22 @@ module Spree
|
|
|
393
394
|
price_in(currency).try(:compare_at_amount)
|
|
394
395
|
end
|
|
395
396
|
|
|
397
|
+
def set_price(currency, amount, compare_at_amount = nil)
|
|
398
|
+
price = prices.find_or_initialize_by(currency: currency)
|
|
399
|
+
price.amount = amount
|
|
400
|
+
price.compare_at_amount = compare_at_amount if compare_at_amount.present?
|
|
401
|
+
price.save!
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def set_stock(count_on_hand, backorderable = nil, stock_location = nil)
|
|
405
|
+
stock_location ||= Spree::Store.current.default_stock_location
|
|
406
|
+
stock_items.find_or_initialize_by(stock_location: stock_location) do |stock_item|
|
|
407
|
+
stock_item.count_on_hand = count_on_hand
|
|
408
|
+
stock_item.backorderable = backorderable if backorderable.present?
|
|
409
|
+
stock_item.save!
|
|
410
|
+
end
|
|
411
|
+
end
|
|
412
|
+
|
|
396
413
|
def price_modifier_amount_in(currency, options = {})
|
|
397
414
|
return 0 unless options.present?
|
|
398
415
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module CSV
|
|
3
|
+
class CustomerPresenter
|
|
4
|
+
include Spree::CSV::MetafieldsHelper
|
|
5
|
+
|
|
6
|
+
HEADERS = [
|
|
7
|
+
'First Name',
|
|
8
|
+
'Last Name',
|
|
9
|
+
'Email',
|
|
10
|
+
'Accepts Email Marketing',
|
|
11
|
+
'Company',
|
|
12
|
+
'Address 1',
|
|
13
|
+
'Address 2',
|
|
14
|
+
'City',
|
|
15
|
+
'Province',
|
|
16
|
+
'Province Code',
|
|
17
|
+
'Country',
|
|
18
|
+
'Country Code',
|
|
19
|
+
'Zip',
|
|
20
|
+
'Phone',
|
|
21
|
+
'Total Spent',
|
|
22
|
+
'Total Orders',
|
|
23
|
+
'Tags'
|
|
24
|
+
].freeze
|
|
25
|
+
|
|
26
|
+
def initialize(customer)
|
|
27
|
+
@customer = customer
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
attr_accessor :customer
|
|
31
|
+
|
|
32
|
+
def call
|
|
33
|
+
csv = [
|
|
34
|
+
customer.first_name,
|
|
35
|
+
customer.last_name,
|
|
36
|
+
customer.email,
|
|
37
|
+
customer.accepts_email_marketing ? Spree.t(:say_yes) : Spree.t(:say_no),
|
|
38
|
+
customer.address&.company,
|
|
39
|
+
customer.address&.address1,
|
|
40
|
+
customer.address&.address2,
|
|
41
|
+
customer.address&.city,
|
|
42
|
+
customer.address&.state_text,
|
|
43
|
+
customer.address&.state_abbr,
|
|
44
|
+
customer.address&.country&.name,
|
|
45
|
+
customer.address&.country&.iso,
|
|
46
|
+
customer.address&.zipcode,
|
|
47
|
+
customer.phone,
|
|
48
|
+
customer.amount_spent_in(Spree::Store.current.default_currency),
|
|
49
|
+
customer.completed_orders.count,
|
|
50
|
+
customer.tag_list
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
csv += metafields_for_csv(customer)
|
|
54
|
+
|
|
55
|
+
csv
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module CSV
|
|
3
|
+
class GiftCardPresenter
|
|
4
|
+
include Spree::CSV::MetafieldsHelper
|
|
5
|
+
|
|
6
|
+
HEADERS = [
|
|
7
|
+
'Code',
|
|
8
|
+
'Amount',
|
|
9
|
+
'Amount Used',
|
|
10
|
+
'Amount Remaining',
|
|
11
|
+
'Currency',
|
|
12
|
+
'Status',
|
|
13
|
+
'Expires At',
|
|
14
|
+
'Customer Email',
|
|
15
|
+
'Customer First Name',
|
|
16
|
+
'Customer Last Name',
|
|
17
|
+
'Created At',
|
|
18
|
+
'Updated At'
|
|
19
|
+
].freeze
|
|
20
|
+
|
|
21
|
+
def initialize(gift_card)
|
|
22
|
+
@gift_card = gift_card
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
attr_accessor :gift_card
|
|
26
|
+
|
|
27
|
+
def call
|
|
28
|
+
csv = [
|
|
29
|
+
gift_card.display_code,
|
|
30
|
+
gift_card.display_amount,
|
|
31
|
+
gift_card.display_amount_used,
|
|
32
|
+
gift_card.display_amount_remaining,
|
|
33
|
+
gift_card.currency,
|
|
34
|
+
gift_card.display_state,
|
|
35
|
+
gift_card.expires_at&.strftime('%Y-%m-%d'),
|
|
36
|
+
gift_card.user&.email,
|
|
37
|
+
gift_card.user&.first_name,
|
|
38
|
+
gift_card.user&.last_name,
|
|
39
|
+
gift_card.created_at&.strftime('%Y-%m-%d %H:%M:%S'),
|
|
40
|
+
gift_card.updated_at&.strftime('%Y-%m-%d %H:%M:%S')
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
csv += metafields_for_csv(gift_card)
|
|
44
|
+
|
|
45
|
+
csv
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module CSV
|
|
3
|
+
module MetafieldsHelper
|
|
4
|
+
private
|
|
5
|
+
|
|
6
|
+
def metafield_definitions_for_csv(resource)
|
|
7
|
+
Spree::MetafieldDefinition.for_resource_type(resource.class.to_s).order(:namespace, :key)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def metafields_for_csv(resource)
|
|
11
|
+
Spree::MetafieldDefinition.for_resource_type(resource.class.to_s).order(:namespace, :key).map do |mf_def|
|
|
12
|
+
resource.metafields.find { |mf| mf.metafield_definition_id == mf_def.id }&.csv_value
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module CSV
|
|
3
|
+
class NewsletterSubscriberPresenter
|
|
4
|
+
include Spree::CSV::MetafieldsHelper
|
|
5
|
+
|
|
6
|
+
HEADERS = [
|
|
7
|
+
'Email',
|
|
8
|
+
'Customer Name',
|
|
9
|
+
'Customer ID',
|
|
10
|
+
'Verified',
|
|
11
|
+
'Verified At',
|
|
12
|
+
'Created At',
|
|
13
|
+
'Updated At'
|
|
14
|
+
].freeze
|
|
15
|
+
|
|
16
|
+
def initialize(newsletter_subscriber)
|
|
17
|
+
@newsletter_subscriber = newsletter_subscriber
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
attr_accessor :newsletter_subscriber
|
|
21
|
+
|
|
22
|
+
def call
|
|
23
|
+
csv = [
|
|
24
|
+
newsletter_subscriber.email,
|
|
25
|
+
newsletter_subscriber.user&.full_name,
|
|
26
|
+
newsletter_subscriber.user_id,
|
|
27
|
+
newsletter_subscriber.verified? ? Spree.t(:say_yes) : Spree.t(:say_no),
|
|
28
|
+
newsletter_subscriber.verified_at,
|
|
29
|
+
newsletter_subscriber.created_at,
|
|
30
|
+
newsletter_subscriber.updated_at
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
csv += metafields_for_csv(newsletter_subscriber)
|
|
34
|
+
|
|
35
|
+
csv
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -59,16 +59,17 @@ module Spree
|
|
|
59
59
|
'Notes'
|
|
60
60
|
].freeze
|
|
61
61
|
|
|
62
|
-
def initialize(order, line_item, index)
|
|
62
|
+
def initialize(order, line_item, index, metafields = [])
|
|
63
63
|
@order = order
|
|
64
64
|
@line_item = line_item
|
|
65
65
|
@index = index
|
|
66
|
+
@metafields = metafields
|
|
66
67
|
end
|
|
67
68
|
|
|
68
|
-
attr_accessor :order, :line_item, :index
|
|
69
|
+
attr_accessor :order, :line_item, :index, :metafields
|
|
69
70
|
|
|
70
71
|
def call
|
|
71
|
-
[
|
|
72
|
+
csv = [
|
|
72
73
|
order.number,
|
|
73
74
|
index.zero? ? order.email : nil,
|
|
74
75
|
index.zero? ? order.state : nil,
|
|
@@ -85,7 +86,7 @@ module Spree
|
|
|
85
86
|
index.zero? ? order.total.to_f : nil,
|
|
86
87
|
index.zero? ? order.shipping_method&.name : nil,
|
|
87
88
|
index.zero? ? order.total_weight.to_f : nil,
|
|
88
|
-
index.zero?
|
|
89
|
+
index.zero? ? order.payments.valid&.first&.display_source_name : nil,
|
|
89
90
|
line_item.product_id,
|
|
90
91
|
line_item.quantity,
|
|
91
92
|
line_item.sku,
|
|
@@ -94,7 +95,7 @@ module Spree
|
|
|
94
95
|
line_item.promo_total.abs,
|
|
95
96
|
line_item.total,
|
|
96
97
|
!line_item.product.digital?,
|
|
97
|
-
line_item.product.
|
|
98
|
+
line_item.product.tax_category_id.present?,
|
|
98
99
|
line_item.product.try(:vendor_name),
|
|
99
100
|
taxon_dict(line_item.product.main_taxon)[0],
|
|
100
101
|
taxon_dict(line_item.product.main_taxon)[1],
|
|
@@ -125,6 +126,12 @@ module Spree
|
|
|
125
126
|
index.zero? ? order.canceler&.email : nil,
|
|
126
127
|
index.zero? ? order.special_instructions : nil
|
|
127
128
|
]
|
|
129
|
+
|
|
130
|
+
if index.zero?
|
|
131
|
+
csv += metafields
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
csv
|
|
128
135
|
end
|
|
129
136
|
|
|
130
137
|
private
|
|
@@ -47,7 +47,7 @@ module Spree
|
|
|
47
47
|
'category3',
|
|
48
48
|
].freeze
|
|
49
49
|
|
|
50
|
-
def initialize(product, variant, index = 0, properties = [], taxons = [], store = nil)
|
|
50
|
+
def initialize(product, variant, index = 0, properties = [], taxons = [], store = nil, metafields = [])
|
|
51
51
|
@product = product
|
|
52
52
|
@variant = variant
|
|
53
53
|
@index = index
|
|
@@ -55,9 +55,10 @@ module Spree
|
|
|
55
55
|
@taxons = taxons
|
|
56
56
|
@store = store || product.stores.first
|
|
57
57
|
@currency = @store.default_currency
|
|
58
|
+
@metafields = metafields
|
|
58
59
|
end
|
|
59
60
|
|
|
60
|
-
attr_accessor :product, :variant, :index, :properties, :taxons, :store, :currency
|
|
61
|
+
attr_accessor :product, :variant, :index, :properties, :taxons, :store, :currency, :metafields
|
|
61
62
|
|
|
62
63
|
##
|
|
63
64
|
# Generates an array representing a CSV row of product variant data.
|
|
@@ -71,11 +72,13 @@ module Spree
|
|
|
71
72
|
#
|
|
72
73
|
# @return [Array] An array containing the combined product and variant CSV data.
|
|
73
74
|
def call
|
|
75
|
+
total_on_hand = variant.total_on_hand
|
|
76
|
+
|
|
74
77
|
csv = [
|
|
75
78
|
product.id,
|
|
76
79
|
variant.sku,
|
|
77
80
|
index.zero? ? product.name : nil,
|
|
78
|
-
|
|
81
|
+
product.slug,
|
|
79
82
|
index.zero? ? product.status : nil,
|
|
80
83
|
index.zero? ? product.try(:vendor_name) : nil,
|
|
81
84
|
index.zero? ? product.try(:brand_name) : nil,
|
|
@@ -86,7 +89,7 @@ module Spree
|
|
|
86
89
|
index.zero? ? product.tag_list.to_s : nil,
|
|
87
90
|
index.zero? ? product.label_list.to_s : nil,
|
|
88
91
|
variant.amount_in(currency).to_f,
|
|
89
|
-
variant.
|
|
92
|
+
variant.compare_at_amount_in(currency).to_f,
|
|
90
93
|
currency,
|
|
91
94
|
variant.width,
|
|
92
95
|
variant.height,
|
|
@@ -97,7 +100,7 @@ module Spree
|
|
|
97
100
|
variant.available_on&.strftime('%Y-%m-%d %H:%M:%S'),
|
|
98
101
|
(variant.discontinue_on || product.discontinue_on)&.strftime('%Y-%m-%d %H:%M:%S'),
|
|
99
102
|
variant.track_inventory?,
|
|
100
|
-
|
|
103
|
+
total_on_hand == BigDecimal::INFINITY ? '∞' : total_on_hand,
|
|
101
104
|
variant.backorderable?,
|
|
102
105
|
variant.tax_category&.name,
|
|
103
106
|
variant.digital?,
|
|
@@ -115,6 +118,7 @@ module Spree
|
|
|
115
118
|
if index.zero?
|
|
116
119
|
csv += taxons
|
|
117
120
|
csv += properties
|
|
121
|
+
csv += metafields
|
|
118
122
|
end
|
|
119
123
|
|
|
120
124
|
csv
|
|
@@ -4,11 +4,13 @@ module Spree
|
|
|
4
4
|
prepend Spree::ServiceModule::Base
|
|
5
5
|
|
|
6
6
|
def call(order:, line_item:, line_item_created: false, options: {})
|
|
7
|
-
|
|
8
|
-
order_updater = ::Spree::OrderUpdater.new(order)
|
|
7
|
+
order_updater = order.updater
|
|
9
8
|
|
|
10
|
-
order.
|
|
11
|
-
|
|
9
|
+
order.remove_gift_card if order.gift_card.present?
|
|
10
|
+
order.payments.store_credits.checkout.destroy_all if order.payments.store_credits.checkout.any?
|
|
11
|
+
order_updater.update_item_count
|
|
12
|
+
order_updater.update_totals
|
|
13
|
+
order_updater.persist_totals
|
|
12
14
|
|
|
13
15
|
shipment = options[:shipment]
|
|
14
16
|
if shipment.present?
|
|
@@ -6,12 +6,11 @@ module Spree
|
|
|
6
6
|
def call(order:, line_item:, options: nil)
|
|
7
7
|
options ||= {}
|
|
8
8
|
ActiveRecord::Base.transaction do
|
|
9
|
-
|
|
9
|
+
order.line_items.destroy(line_item)
|
|
10
10
|
Spree::Dependencies.cart_recalculate_service.constantize.new.call(order: order,
|
|
11
11
|
line_item: line_item,
|
|
12
12
|
options: options)
|
|
13
13
|
end
|
|
14
|
-
order.reload
|
|
15
14
|
success(line_item)
|
|
16
15
|
end
|
|
17
16
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Imports
|
|
3
|
+
module RowProcessors
|
|
4
|
+
class Base
|
|
5
|
+
def initialize(row)
|
|
6
|
+
@row = row
|
|
7
|
+
@import = row.import
|
|
8
|
+
@attributes = row.to_schema_hash
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
attr_reader :row, :import, :attributes
|
|
12
|
+
|
|
13
|
+
def process!
|
|
14
|
+
raise NotImplementedError, 'Subclasses must implement the process! method'
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|