├── .editorconfig ├── LICENSE.md ├── composer.json ├── example-templates ├── dist │ └── shop │ │ ├── _private │ │ ├── address │ │ │ ├── fields.twig │ │ │ ├── fieldset.twig │ │ │ └── list.twig │ │ ├── images │ │ │ ├── placeholder.svg │ │ │ └── spinner.svg │ │ ├── layouts │ │ │ ├── includes │ │ │ │ ├── footer.twig │ │ │ │ ├── header.twig │ │ │ │ ├── nav-checkout.twig │ │ │ │ ├── nav-customer.twig │ │ │ │ └── nav-main.twig │ │ │ └── index.twig │ │ ├── payments │ │ │ └── payment-post-redirect.twig │ │ └── receipt │ │ │ └── index.twig │ │ ├── cart │ │ ├── _includes │ │ │ └── shipping-estimator.twig │ │ ├── index.twig │ │ └── load.twig │ │ ├── checkout │ │ ├── _includes │ │ │ ├── currencies.twig │ │ │ ├── gateways.twig │ │ │ ├── order-summary.twig │ │ │ └── partial-payment.twig │ │ ├── _paymentLegacyStripeExample.twig │ │ ├── addresses.twig │ │ ├── complete.twig │ │ ├── email.twig │ │ ├── index.twig │ │ ├── options.twig │ │ ├── pay-static.twig │ │ ├── payment-method.twig │ │ ├── payment.twig │ │ ├── register-signin.twig │ │ └── shipping.twig │ │ ├── customer │ │ ├── _includes │ │ │ ├── register.twig │ │ │ └── sign-in.twig │ │ ├── addresses │ │ │ ├── edit.twig │ │ │ └── index.twig │ │ ├── cards.twig │ │ ├── forgot-password.twig │ │ ├── index.twig │ │ ├── order.twig │ │ ├── orders.twig │ │ └── sign-in.twig │ │ ├── donations │ │ └── index.twig │ │ ├── index.twig │ │ ├── plans │ │ ├── index.twig │ │ ├── subscription │ │ │ └── index.twig │ │ └── update-billing-details.twig │ │ └── products │ │ ├── _includes │ │ ├── grid.twig │ │ └── pagination.twig │ │ ├── _product.twig │ │ └── index.twig └── src │ └── shop │ ├── _private │ ├── address │ │ ├── fields.twig │ │ ├── fieldset.twig │ │ └── list.twig │ ├── images │ │ ├── placeholder.svg │ │ └── spinner.svg │ ├── layouts │ │ ├── includes │ │ │ ├── footer.twig │ │ │ ├── header.twig │ │ │ ├── nav-checkout.twig │ │ │ ├── nav-customer.twig │ │ │ └── nav-main.twig │ │ └── index.twig │ ├── payments │ │ └── payment-post-redirect.twig │ └── receipt │ │ └── index.twig │ ├── cart │ ├── _includes │ │ └── shipping-estimator.twig │ ├── index.twig │ └── load.twig │ ├── checkout │ ├── _includes │ │ ├── currencies.twig │ │ ├── gateways.twig │ │ ├── order-summary.twig │ │ └── partial-payment.twig │ ├── _paymentLegacyStripeExample.twig │ ├── addresses.twig │ ├── complete.twig │ ├── email.twig │ ├── index.twig │ ├── options.twig │ ├── pay-static.twig │ ├── payment-method.twig │ ├── payment.twig │ ├── register-signin.twig │ └── shipping.twig │ ├── customer │ ├── _includes │ │ ├── register.twig │ │ └── sign-in.twig │ ├── addresses │ │ ├── edit.twig │ │ └── index.twig │ ├── cards.twig │ ├── forgot-password.twig │ ├── index.twig │ ├── order.twig │ ├── orders.twig │ └── sign-in.twig │ ├── donations │ └── index.twig │ ├── index.twig │ ├── plans │ ├── index.twig │ ├── subscription │ │ └── index.twig │ └── update-billing-details.twig │ └── products │ ├── _includes │ ├── grid.twig │ └── pagination.twig │ ├── _product.twig │ └── index.twig ├── rector.php └── src ├── Plugin.php ├── adjusters ├── Discount.php ├── Shipping.php └── Tax.php ├── base ├── AdjusterInterface.php ├── CatalogPricingConditionRuleInterface.php ├── EnumHelpersTrait.php ├── Gateway.php ├── GatewayInterface.php ├── GatewayTrait.php ├── HasStoreInterface.php ├── InventoryItemTrait.php ├── InventoryLocationTrait.php ├── InventoryMovement.php ├── InventoryMovementInterface.php ├── Model.php ├── Plan.php ├── PlanInterface.php ├── PlanTrait.php ├── Purchasable.php ├── PurchasableInterface.php ├── RequestResponseInterface.php ├── ShippingMethod.php ├── ShippingMethodInterface.php ├── ShippingRuleInterface.php ├── Stat.php ├── StatInterface.php ├── StatTrait.php ├── StatWidgetTrait.php ├── StoreRecordTrait.php ├── StoreTrait.php ├── SubscriptionGateway.php ├── SubscriptionGatewayInterface.php ├── SubscriptionResponseInterface.php ├── TaxEngineInterface.php ├── TaxIdValidatorInterface.php ├── Zone.php └── ZoneInterface.php ├── behaviors ├── CurrencyAttributeBehavior.php ├── CustomerAddressBehavior.php ├── CustomerBehavior.php ├── StoreBehavior.php ├── StoreLocationBehavior.php └── ValidateOrganizationTaxIdBehavior.php ├── collections ├── InventoryMovementCollection.php └── UpdateInventoryLevelCollection.php ├── console ├── Controller.php └── controllers │ ├── ExampleTemplatesController.php │ ├── GatewaysController.php │ ├── PricingCatalogController.php │ ├── ResetDataController.php │ └── TransferCustomerDataController.php ├── controllers ├── BaseAdminController.php ├── BaseController.php ├── BaseCpController.php ├── BaseFrontEndController.php ├── BaseShippingSettingsController.php ├── BaseStoreManagementController.php ├── BaseTaxSettingsController.php ├── CartController.php ├── CatalogPricingController.php ├── CatalogPricingRulesController.php ├── DiscountsController.php ├── DonationsController.php ├── DownloadsController.php ├── EmailPreviewController.php ├── EmailsController.php ├── FormulasController.php ├── GatewaysController.php ├── InventoryController.php ├── InventoryLocationsController.php ├── LineItemStatusesController.php ├── OrderSettingsController.php ├── OrderStatusesController.php ├── OrdersController.php ├── PaymentCurrenciesController.php ├── PaymentSourcesController.php ├── PaymentsController.php ├── PdfsController.php ├── PlansController.php ├── ProductTypesController.php ├── ProductsController.php ├── PromotionsController.php ├── SalesController.php ├── SettingsController.php ├── ShippingCategoriesController.php ├── ShippingMethodsController.php ├── ShippingRulesController.php ├── ShippingZonesController.php ├── StoreManagementController.php ├── StoresController.php ├── SubscriptionsController.php ├── TaxCategoriesController.php ├── TaxRatesController.php ├── TaxZonesController.php ├── TransfersController.php ├── UserOrdersController.php ├── UsersController.php ├── VariantsController.php └── WebhooksController.php ├── db └── Table.php ├── debug └── CommercePanel.php ├── elements ├── Donation.php ├── Order.php ├── Product.php ├── Subscription.php ├── Transfer.php ├── Variant.php ├── VariantCollection.php ├── actions │ ├── CopyLoadCartUrl.php │ ├── CreateDiscount.php │ ├── CreateSale.php │ ├── DownloadOrderPdfAction.php │ ├── SetDefaultVariant.php │ └── UpdateOrderStatus.php ├── conditions │ ├── addresses │ │ ├── DiscountAddressCondition.php │ │ ├── PostalCodeFormulaConditionRule.php │ │ └── ZoneAddressCondition.php │ ├── customers │ │ ├── CatalogPricingRuleCustomerCondition.php │ │ ├── DiscountCustomerCondition.php │ │ ├── HasOrdersConditionRule.php │ │ └── SignedInConditionRule.php │ ├── orders │ │ ├── CompletedConditionRule.php │ │ ├── CouponCodeConditionRule.php │ │ ├── CustomerConditionRule.php │ │ ├── DateOrderedConditionRule.php │ │ ├── DiscountOrderCondition.php │ │ ├── DiscountedItemSubtotalConditionRule.php │ │ ├── HasPurchasableConditionRule.php │ │ ├── ItemSubtotalConditionRule.php │ │ ├── ItemTotalConditionRule.php │ │ ├── OrderCondition.php │ │ ├── OrderCurrencyValuesAttributeConditionRule.php │ │ ├── OrderSiteConditionRule.php │ │ ├── OrderStatusConditionRule.php │ │ ├── OrderTextValuesAttributeConditionRule.php │ │ ├── OrderValuesAttributeConditionRule.php │ │ ├── PaidConditionRule.php │ │ ├── PaymentGatewayConditionRule.php │ │ ├── ReferenceConditionRule.php │ │ ├── ShippingAddressZoneConditionRule.php │ │ ├── ShippingMethodConditionRule.php │ │ ├── ShippingMethodOrderCondition.php │ │ ├── ShippingRuleOrderCondition.php │ │ ├── TotalConditionRule.php │ │ ├── TotalDiscountConditionRule.php │ │ ├── TotalPaidConditionRule.php │ │ ├── TotalPriceConditionRule.php │ │ ├── TotalQtyConditionRule.php │ │ ├── TotalTaxConditionRule.php │ │ └── TotalWeightConditionRule.php │ ├── products │ │ ├── CatalogPricingRuleProductCondition.php │ │ ├── ProductCondition.php │ │ ├── ProductTypeConditionRule.php │ │ ├── ProductVariantHasUnlimitedStockConditionRule.php │ │ ├── ProductVariantInventoryTrackedConditionRule.php │ │ ├── ProductVariantPriceConditionRule.php │ │ ├── ProductVariantSearchConditionRule.php │ │ ├── ProductVariantSkuConditionRule.php │ │ └── ProductVariantStockConditionRule.php │ ├── purchasables │ │ ├── CatalogPricingCondition.php │ │ ├── CatalogPricingCustomerConditionRule.php │ │ ├── CatalogPricingPurchasableConditionRule.php │ │ ├── CatalogPricingRulePurchasableCategoryConditionRule.php │ │ ├── CatalogPricingRulePurchasableCondition.php │ │ ├── PurchasableConditionRule.php │ │ ├── PurchasableTypeConditionRule.php │ │ └── SkuConditionRule.php │ ├── transfers │ │ └── TransferCondition.php │ ├── users │ │ └── DiscountGroupConditionRule.php │ └── variants │ │ ├── CatalogPricingRuleVariantCondition.php │ │ ├── ProductConditionRule.php │ │ └── VariantCondition.php ├── db │ ├── DonationQuery.php │ ├── OrderQuery.php │ ├── ProductQuery.php │ ├── PurchasableQuery.php │ ├── SubscriptionQuery.php │ ├── TransferQuery.php │ └── VariantQuery.php └── traits │ ├── OrderElementTrait.php │ ├── OrderNoticesTrait.php │ └── OrderValidatorsTrait.php ├── engines └── Tax.php ├── enums ├── InventoryTransactionType.php ├── InventoryUpdateQuantityType.php ├── LineItemType.php └── TransferStatusType.php ├── errors ├── CurrencyException.php ├── EmailException.php ├── GatewayException.php ├── LineItemException.php ├── NotImplementedException.php ├── OrderStatusException.php ├── PaymentException.php ├── PaymentSourceCreatedLaterException.php ├── PaymentSourceException.php ├── ProductTypeNotFoundException.php ├── RefundException.php ├── ShippingMethodException.php ├── StoreNotFoundException.php ├── SubscriptionException.php └── TransactionException.php ├── etc ├── commands.php └── currencies.php ├── events ├── AddLineItemEvent.php ├── CancelSubscriptionEvent.php ├── CartEvent.php ├── CartPurgeEvent.php ├── CommerceDebugPanelDataEvent.php ├── CreateSubscriptionEvent.php ├── CustomizeProductSnapshotDataEvent.php ├── CustomizeProductSnapshotFieldsEvent.php ├── CustomizeVariantSnapshotDataEvent.php ├── CustomizeVariantSnapshotFieldsEvent.php ├── DefaultLineItemStatusEvent.php ├── DefaultOrderStatusEvent.php ├── DeleteStoreEvent.php ├── DiscountAdjustmentsEvent.php ├── DiscountEvent.php ├── EmailEvent.php ├── LineItemEvent.php ├── MailEvent.php ├── MatchLineItemEvent.php ├── MatchOrderEvent.php ├── ModifyCartInfoEvent.php ├── ModifyPurchasablesTableQueryEvent.php ├── OrderLineItemsRefreshEvent.php ├── OrderNoticeEvent.php ├── OrderStatusEmailsEvent.php ├── OrderStatusEvent.php ├── PaymentSourceEvent.php ├── PdfEvent.php ├── PdfRenderEvent.php ├── PdfRenderOptionsEvent.php ├── PlanEvent.php ├── ProcessPaymentEvent.php ├── ProductEvent.php ├── ProductTypeEvent.php ├── PurchasableAvailableEvent.php ├── PurchasableOutOfStockPurchasesAllowedEvent.php ├── PurchasableShippableEvent.php ├── PurchaseVariantEvent.php ├── PurgeAddressesEvent.php ├── RefundTransactionEvent.php ├── RegisterAvailableShippingMethodsEvent.php ├── ReportEvent.php ├── SaleEvent.php ├── SaleMatchEvent.php ├── StoreEvent.php ├── SubscriptionEvent.php ├── SubscriptionPaymentEvent.php ├── SubscriptionSwitchPlansEvent.php ├── TaxEngineEvent.php ├── TaxIdValidatorsEvent.php ├── TransactionEvent.php ├── UpdatePrimaryPaymentSourceEvent.php ├── UpgradeEvent.php └── WebhookEvent.php ├── exports ├── Expanded.php ├── LineItemExport.php └── OrderExport.php ├── fieldlayoutelements ├── ProductTitleField.php ├── PurchasableAllowedQtyField.php ├── PurchasableAvailableForPurchaseField.php ├── PurchasableDimensionsField.php ├── PurchasableFreeShippingField.php ├── PurchasablePriceField.php ├── PurchasablePromotableField.php ├── PurchasableSkuField.php ├── PurchasableStockField.php ├── PurchasableWeightField.php ├── TransferManagementField.php ├── UserAddressSettings.php ├── VariantTitleField.php └── VariantsField.php ├── fields ├── Products.php └── Variants.php ├── gateways ├── Dummy.php ├── Manual.php └── MissingGateway.php ├── gql ├── arguments │ └── elements │ │ ├── Product.php │ │ └── Variant.php ├── interfaces │ └── elements │ │ ├── Product.php │ │ └── Variant.php ├── queries │ ├── Product.php │ └── Variant.php ├── resolvers │ └── elements │ │ ├── Product.php │ │ └── Variant.php └── types │ ├── SaleType.php │ ├── elements │ ├── Product.php │ └── Variant.php │ ├── generators │ ├── ProductType.php │ └── VariantType.php │ └── input │ ├── IntFalse.php │ ├── Product.php │ └── Variant.php ├── helpers ├── Cp.php ├── Currency.php ├── DebugPanel.php ├── Gql.php ├── LineItem.php ├── Locale.php ├── Localization.php ├── Order.php ├── PaymentForm.php ├── ProjectConfigData.php └── Purchasable.php ├── icon-mask.svg ├── icon.svg ├── linktypes └── Product.php ├── migrations ├── Install.php ├── m210614_073359_detailed_permission.php ├── m210831_080542_rename_variant_title_format_field.php ├── m210901_211323_not_null_booleans.php ├── m210922_133729_add_discount_order_condition_builder.php ├── m211118_101920_split_coupon_codes.php ├── m220301_022054_user_addresses.php ├── m220302_133730_add_discount_user_addresses_condition_builders.php ├── m220304_094835_discount_conditions.php ├── m220308_221717_orderhistory_name.php ├── m220329_075053_convert_gateway_frontend_enabled_column.php ├── m220706_132118_add_purchasable_tax_type.php ├── m220812_104819_add_primary_payment_source_column.php ├── m220817_135050_add_purchase_total_back_if_missing.php ├── m220912_111800_add_order_total_qty_column.php ├── m221025_083940_add_purchasables_stores_table.php ├── m221026_105212_add_catalog_pricing_table.php ├── m221027_070322_add_tax_shipping_category_soft_delete.php ├── m221027_074805_update_shipping_tax_category_indexes.php ├── m221028_192112_add_indexes_to_address_columns_on_orders.php ├── m221122_055724_move_general_settings_to_per_store_settings.php ├── m221122_055725_multi_store.php ├── m221122_155735_update_orders_shippingMethodHandle_default.php ├── m221124_114239_add_date_deleted_to_stores.php ├── m221206_094303_add_store_to_order.php ├── m221213_052623_drop_lite.php ├── m221213_070807_initial_storeId_records_transition.php ├── m230103_122549_add_product_type_max_variants.php ├── m230110_052712_site_stores.php ├── m230111_112916_update_lineitems_table.php ├── m230113_110914_remove_soft_delete.php ├── m230118_114424_add_purchasables_stores_indexes.php ├── m230126_105337_rename_discount_sales_references.php ├── m230126_114655_add_catalog_pricing_rule_metadata_column.php ├── m230208_130445_add_store_id_to_shipping_categories.php ├── m230210_093749_add_store_id_to_shipping_methods.php ├── m230210_141514_add_store_id_to_shipping_zones.php ├── m230214_094122_add_total_weight_column_to_orders.php ├── m230214_095055_update_name_index_on_shipping_zones.php ├── m230215_083820_add_order_condition_to_shipping_rules.php ├── m230215_114552_migrate_shipping_rule_conditions_to_condition_builder.php ├── m230217_095845_remove_shipping_rules_columns.php ├── m230217_143255_add_shipping_method_order_condition.php ├── m230220_075106_add_store_id_to_tax_rates.php ├── m230220_080107_add_store_id_to_tax_zones.php ├── m230307_091520_add_sort_order_to_stores.php ├── m230308_084340_add_store_id_to_order_statuses.php ├── m230310_102639_add_store_id_to_line_item_statuses.php ├── m230313_095359_add_store_id_to_emails.php ├── m230317_102521_add_store_id_to_pdfs.php ├── m230322_091615_move_email_settings_to_model.php ├── m230328_130343_move_pdf_settings_to_model.php ├── m230525_081243_add_has_update_pending_property.php ├── m230530_100604_add_complete_email_column.php ├── m230705_124845_add_save_address_columns.php ├── m230719_082348_discount_nullable_conditions.php ├── m230724_080855_entrify_promotions.php ├── m230920_051125_move_primary_currency_to_store_settings.php ├── m230928_095544_fix_unique_on_some_tables.php ├── m230928_155052_move_shipping_category_id_to_purchasable_stores.php ├── m231006_034833_add_indexes_for_source_address_on_order.php ├── m231019_110814_update_variant_ownership.php ├── m231110_081143_inventory_movement_table.php ├── m231201_100454_update_discount_base_discount_type.php ├── m240119_073924_content_refactor_elements.php ├── m240119_075036_content_refactor_subscription_elements.php ├── m240208_083054_add_purchasable_stores_purchasable_fk.php ├── m240219_194855_donation_multi_store.php ├── m240220_045806_product_versioning.php ├── m240220_105746_remove_store_from_donations_table.php ├── m240221_030027_transfer_items.php ├── m240223_101158_update_recent_orders_widget_settings.php ├── m240226_002943_remove_lite.php ├── m240228_054005_rename_movements_table.php ├── m240228_060604_add_fufilled_type_to_inventorytransactions.php ├── m240228_120911_drop_order_id_and_make_line_item_cascade.php ├── m240301_113924_add_line_item_types.php ├── m240306_091057_move_element_ids_on_discount_to_columns.php ├── m240308_133451_tidy_shipping_categories.php ├── m240313_131445_tidy_shipping_methods.php ├── m240315_072659_add_fk_cascade_fixes.php ├── m240430_161804_add_index_to_transaction_hash.php ├── m240507_081904_fix_store_pc_location.php ├── m240516_035616_update_permissions.php ├── m240516_035617_update_currency_and_store_general_permissions.php ├── m240528_124101_add_extra_lineitem_columns.php ├── m240529_095819_remove_commerce_user_field.php ├── m240605_110755_add_title_translations_product_types.php ├── m240619_082224_add_product_and_variant_conditions_to_catalog_pricing_rules.php ├── m240710_125204_ensure_shippingCategoryId_column_is_nullable.php ├── m240711_092240_fix_fks.php ├── m240715_045506_drop_available_if_exists.php ├── m240717_044256_add_return_url_to_subscription.php ├── m240718_073046_remove_sortOrder_variants_column_if_exists.php ├── m240808_090256_cascade_delete_variants_on_product_delete.php ├── m240808_093934_product_type_propagation.php ├── m240812_025615_add_transfer_details_table.php ├── m240815_035618_fix_transfer_permission.php ├── m240830_081410_add_extra_indexes_to_catalog_pricing.php ├── m240905_130549_add_require_coupon_code_discount_setting.php ├── m240906_105809_update_existing_coupon_discounts.php ├── m240906_115901_add_orderable_to_product_types.php ├── m240923_132625_remove_orphaned_variants_sites.php ├── m241010_061430_rename_orderable_product_type_type.php ├── m241017_072151_fix_temp_skus.php ├── m241022_075144_add_missing_variant_revision_records.php ├── m241128_174712_fix_maxLevels_structured_productTypes.php ├── m241204_045158_enable_tax_rate.php ├── m241204_091901_fix_store_environment_variables.php ├── m241213_083338_update_promotional_price_in_line_items.php ├── m241219_071723_add_inventory_backorder.php ├── m241220_082900_remove_inventory_for_non_inventory_purchasables.php ├── m250120_080035_move_to_tax_id_validators.php ├── m250128_083515_add_make_primary_addresses_to_orders.php ├── m250129_080909_fix_discount_conditions.php └── m250210_125139_fix_cart_recalculation_modes.php ├── models ├── CatalogPricing.php ├── CatalogPricingRule.php ├── Coupon.php ├── Discount.php ├── Email.php ├── InventoryFulfillmentLevel.php ├── InventoryItem.php ├── InventoryLevel.php ├── InventoryLocation.php ├── InventoryTransaction.php ├── LineItem.php ├── LineItemStatus.php ├── OrderAdjustment.php ├── OrderHistory.php ├── OrderNotice.php ├── OrderStatus.php ├── PaymentCurrency.php ├── PaymentSource.php ├── Pdf.php ├── ProductType.php ├── ProductTypeSite.php ├── PurchasableStore.php ├── Sale.php ├── Settings.php ├── ShippingAddressZone.php ├── ShippingCategory.php ├── ShippingMethod.php ├── ShippingMethodOption.php ├── ShippingRule.php ├── ShippingRuleCategory.php ├── SiteStore.php ├── Store.php ├── StoreSettings.php ├── TaxAddressZone.php ├── TaxCategory.php ├── TaxRate.php ├── Transaction.php ├── TransferDetail.php ├── inventory │ ├── DeactivateInventoryLocation.php │ ├── InventoryCommittedMovement.php │ ├── InventoryFulfillMovement.php │ ├── InventoryLocationDeactivatedMovement.php │ ├── InventoryManualMovement.php │ ├── InventoryRestockMovement.php │ ├── InventoryTransferMovement.php │ ├── UpdateInventoryLevel.php │ └── UpdateInventoryLevelInTransfer.php ├── payments │ ├── BasePaymentForm.php │ ├── CreditCardPaymentForm.php │ ├── DummyPaymentForm.php │ └── OffsitePaymentForm.php ├── responses │ ├── Dummy.php │ ├── DummySubscriptionResponse.php │ └── Manual.php └── subscriptions │ ├── CancelSubscriptionForm.php │ ├── DummyPlan.php │ ├── SubscriptionForm.php │ ├── SubscriptionPayment.php │ └── SwitchPlansForm.php ├── plugin ├── Routes.php ├── Services.php └── Variables.php ├── queue └── jobs │ ├── CatalogPricing.php │ └── SendEmail.php ├── records ├── CatalogPricing.php ├── CatalogPricingRule.php ├── CatalogPricingRuleUser.php ├── Coupon.php ├── Customer.php ├── CustomerDiscountUse.php ├── Discount.php ├── DiscountCategory.php ├── DiscountPurchasable.php ├── Donation.php ├── Email.php ├── EmailDiscountUse.php ├── Gateway.php ├── InventoryItem.php ├── InventoryLocation.php ├── LineItem.php ├── LineItemStatus.php ├── Order.php ├── OrderAdjustment.php ├── OrderHistory.php ├── OrderNotice.php ├── OrderStatus.php ├── OrderStatusEmail.php ├── PaymentCurrency.php ├── PaymentSource.php ├── Pdf.php ├── Plan.php ├── Product.php ├── ProductType.php ├── ProductTypeShippingCategory.php ├── ProductTypeSite.php ├── ProductTypeTaxCategory.php ├── Purchasable.php ├── PurchasableStore.php ├── Sale.php ├── SaleCategory.php ├── SalePurchasable.php ├── SaleUserGroup.php ├── ShippingCategory.php ├── ShippingMethod.php ├── ShippingRule.php ├── ShippingRuleCategory.php ├── ShippingZone.php ├── SiteStore.php ├── Store.php ├── StoreSettings.php ├── Subscription.php ├── TaxCategory.php ├── TaxRate.php ├── TaxZone.php ├── Transaction.php ├── Transfer.php ├── TransferDetail.php └── Variant.php ├── services ├── Carts.php ├── CatalogPricing.php ├── CatalogPricingRules.php ├── Coupons.php ├── Currencies.php ├── Customers.php ├── Discounts.php ├── Emails.php ├── Formulas.php ├── Gateways.php ├── Inventory.php ├── InventoryLocations.php ├── LineItemStatuses.php ├── LineItems.php ├── OrderAdjustments.php ├── OrderHistories.php ├── OrderNotices.php ├── OrderStatuses.php ├── Orders.php ├── PaymentCurrencies.php ├── PaymentSources.php ├── Payments.php ├── Pdfs.php ├── Plans.php ├── ProductTypes.php ├── Products.php ├── Purchasables.php ├── Sales.php ├── ShippingCategories.php ├── ShippingMethods.php ├── ShippingRuleCategories.php ├── ShippingRules.php ├── ShippingZones.php ├── Store.php ├── StoreSettings.php ├── Stores.php ├── Subscriptions.php ├── TaxCategories.php ├── TaxRates.php ├── TaxZones.php ├── Taxes.php ├── Transactions.php ├── Transfers.php ├── Variants.php ├── Vat.php └── Webhooks.php ├── stats ├── AverageOrderTotal.php ├── NewCustomers.php ├── RepeatCustomers.php ├── TopCustomers.php ├── TopProductTypes.php ├── TopProducts.php ├── TopPurchasables.php ├── TotalOrders.php ├── TotalOrdersByCountry.php └── TotalRevenue.php ├── taxidvalidators └── EuVatIdValidator.php ├── templates ├── _components │ ├── elementactions │ │ └── DownloadOrderPdf │ │ │ └── trigger.twig │ ├── gateways │ │ ├── _creditCardFields.twig │ │ └── _modalWrapper.twig │ └── widgets │ │ ├── _includes │ │ ├── _dateRangeField.twig │ │ ├── _orderStatusesField.twig │ │ └── _storeField.twig │ │ ├── customers │ │ ├── new │ │ │ ├── body.twig │ │ │ └── settings.twig │ │ ├── repeat │ │ │ ├── body.twig │ │ │ └── settings.twig │ │ └── top │ │ │ ├── body.twig │ │ │ └── settings.twig │ │ ├── orders │ │ ├── average │ │ │ ├── body.twig │ │ │ └── settings.twig │ │ ├── country │ │ │ ├── body.twig │ │ │ └── settings.twig │ │ ├── recent │ │ │ ├── body.twig │ │ │ └── settings.twig │ │ ├── revenue │ │ │ ├── body.twig │ │ │ └── settings.twig │ │ └── total │ │ │ ├── body.twig │ │ │ └── settings.twig │ │ ├── products │ │ └── top │ │ │ ├── body.twig │ │ │ └── settings.twig │ │ ├── producttypes │ │ └── top │ │ │ ├── body.twig │ │ │ └── settings.twig │ │ └── purchasables │ │ └── top │ │ ├── body.twig │ │ └── settings.twig ├── _data │ ├── data.tsv │ └── tsv.tsv ├── _includes │ ├── _storeManagementNav.twig │ ├── forms │ │ ├── commerceForms.twig │ │ └── inventoryLocationSelect.twig │ ├── orders │ │ └── address.twig │ └── settings.twig ├── _layouts │ ├── cp.twig │ ├── settings.twig │ ├── store-management.twig │ └── tax.twig ├── donation │ └── _edit.twig ├── gateways │ └── manualGatewaySettings.twig ├── index.twig ├── inventory-locations │ ├── _deleteModal.twig │ ├── _edit.twig │ ├── _index.twig │ └── _sidebar.twig ├── inventory │ ├── item │ │ └── _edit.twig │ ├── levels │ │ ├── _index.twig │ │ ├── _inventoryMovementModal.twig │ │ ├── _unfulfilledOrdersModal.twig │ │ └── _updateInventoryLevelModal.twig │ └── transfers │ │ └── _index.twig ├── orders │ ├── _edit.twig │ ├── _history.twig │ ├── _index.twig │ ├── _paymentForms.twig │ ├── _paymentmodal.twig │ ├── _transactions.twig │ ├── includes │ │ ├── _capture.twig │ │ └── _refund.twig │ └── modals │ │ └── _fulfillmentModal.twig ├── prices │ ├── _index.twig │ ├── _polling.twig │ ├── _status.twig │ └── _table.twig ├── products │ └── _index.twig ├── promotions │ ├── index.twig │ └── sales │ │ ├── _edit.twig │ │ └── index.twig ├── settings │ ├── emails │ │ ├── _edit.twig │ │ ├── _previewError.twig │ │ └── index.twig │ ├── gateways │ │ ├── _edit.twig │ │ └── index.twig │ ├── general │ │ └── index.twig │ ├── index.twig │ ├── lineitemstatuses │ │ ├── _edit.twig │ │ └── index.twig │ ├── ordersettings │ │ └── _edit.twig │ ├── orderstatuses │ │ ├── _edit.twig │ │ └── index.twig │ ├── pdfs │ │ ├── _edit.twig │ │ └── index.twig │ ├── producttypes │ │ ├── _edit.twig │ │ └── index.twig │ ├── stores │ │ ├── _edit.twig │ │ ├── _siteStore.twig │ │ └── index.twig │ ├── subscriptions │ │ └── _edit.twig │ └── transfers │ │ └── _edit.twig ├── store-management │ ├── discounts │ │ ├── _edit.twig │ │ └── index.twig │ ├── general │ │ └── _edit.twig │ ├── index.twig │ ├── paymentcurrencies │ │ ├── _edit.twig │ │ └── index.twig │ ├── pricing-rules │ │ ├── _actions-fields.twig │ │ ├── _edit.twig │ │ ├── _sidebar.twig │ │ ├── _slideout.twig │ │ └── index.twig │ ├── shipping │ │ ├── index.twig │ │ ├── shippingcategories │ │ │ ├── _edit.twig │ │ │ ├── _fields.twig │ │ │ └── index.twig │ │ ├── shippingmethods │ │ │ ├── _edit.twig │ │ │ └── index.twig │ │ ├── shippingrules │ │ │ └── _edit.twig │ │ └── shippingzones │ │ │ ├── _edit.twig │ │ │ ├── _fields.twig │ │ │ └── index.twig │ └── tax │ │ ├── taxcategories │ │ ├── _edit.twig │ │ ├── _fields.twig │ │ └── index.twig │ │ ├── taxrates │ │ ├── _edit.twig │ │ ├── _fields.twig │ │ └── index.twig │ │ └── taxzones │ │ ├── _edit.twig │ │ ├── _fields.twig │ │ └── index.twig ├── subscriptions │ ├── _edit.twig │ ├── _index.twig │ └── plans │ │ ├── _edit.twig │ │ └── index.twig └── variants │ └── _index.twig ├── test ├── fixtures │ └── elements │ │ └── ProductFixture.php └── mockclasses │ └── Purchasable.php ├── translations ├── de │ └── commerce.php ├── en-GB │ └── commerce.php ├── en │ └── commerce.php ├── fr-CA │ └── commerce.php ├── fr │ └── commerce.php ├── it │ └── commerce.php ├── ja │ └── commerce.php ├── nb │ └── commerce.php ├── nl │ └── commerce.php ├── pt │ └── commerce.php └── sk │ └── commerce.php ├── validators └── CouponsValidator.php ├── views └── debug │ └── commerce │ ├── detail.php │ ├── model.php │ └── summary.php ├── web ├── assets │ ├── catalogpricing │ │ ├── CatalogPricingAsset.php │ │ ├── dist │ │ │ ├── CatalogPricing.js │ │ │ ├── CatalogPricing.js.map │ │ │ └── css │ │ │ │ ├── CatalogPricing.css │ │ │ │ └── CatalogPricing.css.map │ │ ├── src │ │ │ ├── css │ │ │ │ └── catalogpricing.scss │ │ │ └── js │ │ │ │ └── CatalogPricing.js │ │ └── webpack.config.js │ ├── chartjs │ │ ├── ChartJsAsset.php │ │ ├── dist │ │ │ ├── Chart.bundle.min.js │ │ │ ├── Chart.bundle.min.js.LICENSE.txt │ │ │ ├── chartjs-adapter-moment.min.js │ │ │ ├── chartjs-adapter-moment.min.js.LICENSE.txt │ │ │ └── moment-with-locales.min.js │ │ └── webpack.config.js │ ├── commercecp │ │ ├── CommerceCpAsset.php │ │ ├── dist │ │ │ ├── commercecp.js │ │ │ ├── commercecp.js.map │ │ │ ├── css │ │ │ │ ├── commercecp.css │ │ │ │ └── commercecp.css.map │ │ │ └── images │ │ │ │ ├── error.png │ │ │ │ ├── promotional_price.png │ │ │ │ └── spinner_big.gif │ │ ├── src │ │ │ ├── commercecp.js │ │ │ ├── images │ │ │ │ ├── error.png │ │ │ │ ├── promotional_price.png │ │ │ │ └── spinner_big.gif │ │ │ ├── js │ │ │ │ ├── Commerce.js │ │ │ │ ├── CommerceOrderEdit.js │ │ │ │ ├── CommerceOrderIndex.js │ │ │ │ ├── CommercePaymentModal.js │ │ │ │ ├── CommerceProductSalesModal.js │ │ │ │ ├── CommerceSubscriptionIndex.js │ │ │ │ ├── CommerceUpdateOrderStatusModal.js │ │ │ │ ├── DownloadOrderPdf.js │ │ │ │ └── TableRowAdditionalInfoIcon.js │ │ │ └── scss │ │ │ │ ├── addresses.scss │ │ │ │ ├── commerce.scss │ │ │ │ ├── order.scss │ │ │ │ ├── prices.scss │ │ │ │ ├── purchasables.scss │ │ │ │ ├── registration.scss │ │ │ │ ├── stores.scss │ │ │ │ └── subscriptions.scss │ │ └── webpack.config.js │ ├── commerceui │ │ ├── .env.example │ │ ├── .gitignore │ │ ├── CommerceOrderAsset.php │ │ ├── CommerceUiAsset.php │ │ ├── dist │ │ │ ├── css │ │ │ │ ├── order.css │ │ │ │ └── order.css.map │ │ │ ├── js │ │ │ │ ├── app.js │ │ │ │ ├── app.js.LICENSE.txt │ │ │ │ └── app.js.map │ │ │ └── manifest.json │ │ ├── src │ │ │ ├── js │ │ │ │ ├── base │ │ │ │ │ ├── components │ │ │ │ │ │ ├── BtnLink.vue │ │ │ │ │ │ ├── Field.vue │ │ │ │ │ │ ├── Lightswitch.vue │ │ │ │ │ │ ├── Modal.vue │ │ │ │ │ │ └── SelectInput.vue │ │ │ │ │ └── filters │ │ │ │ │ │ └── craft.js │ │ │ │ └── order │ │ │ │ │ ├── api │ │ │ │ │ ├── addresses.js │ │ │ │ │ └── orders.js │ │ │ │ │ ├── app.js │ │ │ │ │ ├── apps │ │ │ │ │ ├── OrderActions.vue │ │ │ │ │ ├── OrderCustomer.vue │ │ │ │ │ ├── OrderDetails.vue │ │ │ │ │ ├── OrderErrors.vue │ │ │ │ │ ├── OrderMeta.vue │ │ │ │ │ ├── OrderNotices.vue │ │ │ │ │ └── OrderSecondaryActions.vue │ │ │ │ │ ├── components │ │ │ │ │ ├── InputError.vue │ │ │ │ │ ├── OrderBlock.vue │ │ │ │ │ ├── OrderTitle.vue │ │ │ │ │ ├── actions │ │ │ │ │ │ ├── OptionShortcutLabel.vue │ │ │ │ │ │ └── UpdateOrderBtn.vue │ │ │ │ │ ├── customer │ │ │ │ │ │ ├── AddressEdit.vue │ │ │ │ │ │ ├── AddressSelect.vue │ │ │ │ │ │ └── Customer.vue │ │ │ │ │ ├── details │ │ │ │ │ │ ├── AddLineItem.vue │ │ │ │ │ │ ├── Adjustment.vue │ │ │ │ │ │ ├── Adjustments.vue │ │ │ │ │ │ ├── LineItem.vue │ │ │ │ │ │ ├── LineItemAdjustments.vue │ │ │ │ │ │ ├── LineItemNotes.vue │ │ │ │ │ │ ├── LineItemOptions.vue │ │ │ │ │ │ ├── LineItemProperty.vue │ │ │ │ │ │ ├── LineItemStatus.vue │ │ │ │ │ │ ├── LineItemStatusInput.vue │ │ │ │ │ │ ├── LineItems.vue │ │ │ │ │ │ ├── OrderAdjustments.vue │ │ │ │ │ │ ├── QtyInput.vue │ │ │ │ │ │ ├── Snapshot.vue │ │ │ │ │ │ └── Total.vue │ │ │ │ │ └── meta │ │ │ │ │ │ ├── CustomerSelect.vue │ │ │ │ │ │ ├── DateOrderedInput.vue │ │ │ │ │ │ ├── OpenIndicator.vue │ │ │ │ │ │ ├── OrderSite.vue │ │ │ │ │ │ ├── OrderStatus.vue │ │ │ │ │ │ └── ShippingMethod.vue │ │ │ │ │ ├── helpers │ │ │ │ │ └── utils.js │ │ │ │ │ ├── mixins │ │ │ │ │ └── index.js │ │ │ │ │ └── store │ │ │ │ │ └── index.js │ │ │ └── sass │ │ │ │ ├── base │ │ │ │ ├── _common.scss │ │ │ │ ├── _craft-classes.scss │ │ │ │ └── _vue-select.scss │ │ │ │ └── order │ │ │ │ ├── _modal.scss │ │ │ │ └── app.scss │ │ └── webpack.config.js │ ├── commercewidgets │ │ ├── CommerceWidgetsAsset.php │ │ ├── dist │ │ │ ├── CommerceWidgets.js │ │ │ └── CommerceWidgets.js.map │ │ ├── src │ │ │ └── CommerceWidgets.js │ │ └── webpack.config.js │ ├── coupons │ │ ├── CouponsAsset.php │ │ ├── dist │ │ │ ├── coupons.js │ │ │ ├── coupons.js.map │ │ │ └── css │ │ │ │ ├── coupons.css │ │ │ │ └── coupons.css.map │ │ ├── src │ │ │ ├── css │ │ │ │ └── coupons.scss │ │ │ └── js │ │ │ │ └── coupons.js │ │ └── webpack.config.js │ ├── deepmerge │ │ ├── DeepMergeAsset.php │ │ ├── dist │ │ │ └── umd.js │ │ └── webpack.config.js │ ├── editproduct │ │ ├── EditProductAsset.php │ │ ├── dist │ │ │ ├── CommerceProductEdit.js │ │ │ ├── CommerceProductEdit.js.map │ │ │ └── css │ │ │ │ ├── CommerceProductEdit.css │ │ │ │ └── CommerceProductEdit.css.map │ │ ├── src │ │ │ ├── CommerceProductEdit.js │ │ │ └── product.css │ │ └── webpack.config.js │ ├── inventory │ │ ├── InventoryAsset.php │ │ ├── dist │ │ │ ├── css │ │ │ │ ├── inventory.css │ │ │ │ └── inventory.css.map │ │ │ ├── inventory.js │ │ │ └── inventory.js.map │ │ ├── src │ │ │ ├── css │ │ │ │ └── inventory.scss │ │ │ ├── inventory.js │ │ │ └── js │ │ │ │ ├── InventoryLevelsManager.js │ │ │ │ ├── InventoryMovementModal.js │ │ │ │ └── UpdateInventoryLevelModal.js │ │ └── webpack.config.js │ ├── orderswidget │ │ ├── OrdersWidgetAsset.php │ │ ├── dist │ │ │ ├── OrdersWidgetSettings.js │ │ │ └── OrdersWidgetSettings.js.map │ │ ├── src │ │ │ └── OrdersWidgetSettings.js │ │ └── webpack.config.js │ ├── productindex │ │ ├── ProductIndexAsset.php │ │ ├── dist │ │ │ ├── CommerceProductIndex.js │ │ │ └── CommerceProductIndex.js.map │ │ ├── src │ │ │ └── CommerceProductIndex.js │ │ └── webpack.config.js │ ├── purchasablepricefield │ │ ├── PurchasablePriceFieldAsset.php │ │ ├── dist │ │ │ ├── purchasablepricefield.js │ │ │ └── purchasablepricefield.js.map │ │ ├── src │ │ │ └── js │ │ │ │ └── PurchasablePriceField.js │ │ └── webpack.config.js │ ├── statwidgets │ │ ├── StatWidgetsAsset.php │ │ ├── dist │ │ │ ├── CommerceChart.js │ │ │ ├── CommerceChart.js.map │ │ │ └── css │ │ │ │ ├── CommerceChart.css │ │ │ │ └── CommerceChart.css.map │ │ ├── src │ │ │ ├── CommerceChart.js │ │ │ └── scss │ │ │ │ └── stat-widgets.scss │ │ └── webpack.config.js │ ├── transfers │ │ ├── TransfersAsset.php │ │ ├── dist │ │ │ ├── css │ │ │ │ └── transfers.css │ │ │ ├── transfers.js │ │ │ └── transfers.js.map │ │ ├── src │ │ │ ├── css │ │ │ │ └── transfers.scss │ │ │ ├── js │ │ │ │ ├── ReceiveTransferScreen.js │ │ │ │ └── TransferEdit.js │ │ │ └── transfers.js │ │ └── webpack.config.js │ └── variantmatrix │ │ ├── VariantMatrixAsset.php │ │ ├── dist │ │ ├── VariantMatrix.js │ │ └── VariantMatrix.js.map │ │ ├── src │ │ └── VariantMatrix.js │ │ └── webpack.config.js └── twig │ ├── CraftVariableBehavior.php │ └── Extension.php └── widgets ├── AverageOrderTotal.php ├── NewCustomers.php ├── Orders.php ├── RepeatCustomers.php ├── TopCustomers.php ├── TopProductTypes.php ├── TopProducts.php ├── TopPurchasables.php ├── TotalOrders.php ├── TotalOrdersByCountry.php └── TotalRevenue.php /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.vue] 2 | indent_size = 4 3 | ij_html_attribute_wrap = on_every_item -------------------------------------------------------------------------------- /example-templates/dist/shop/_private/images/spinner.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /example-templates/dist/shop/_private/layouts/includes/header.twig: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 | 5 | {{- siteName ~ ' Shop' -}} 6 | 7 |

8 | {% if craft.app.sites.getAllSites()|length > 1 %} 9 |
10 | 15 |
16 | {% endif %} 17 |
18 |
-------------------------------------------------------------------------------- /example-templates/dist/shop/_private/payments/payment-post-redirect.twig: -------------------------------------------------------------------------------- 1 | {# 2 | Outputs a payment redirect page. 3 | 4 | @var actionUrl string 5 | @var inputs string 6 | #} 7 | 8 | 9 | 10 | 11 | {{ 'Redirecting'|t }}... 12 | 13 | 14 |
15 |

{{ 'Redirecting to payment page'|t }}...

16 |

17 | {{ inputs|raw }} 18 | {{ tag('button', { 19 | type: 'submit', 20 | text: 'Continue'|t 21 | }) }} 22 |

23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /example-templates/dist/shop/checkout/index.twig: -------------------------------------------------------------------------------- 1 | {% redirect 'shop/checkout/email' %} -------------------------------------------------------------------------------- /example-templates/dist/shop/customer/index.twig: -------------------------------------------------------------------------------- 1 | {% redirect 'shop/customer/orders' %} -------------------------------------------------------------------------------- /example-templates/dist/shop/customer/sign-in.twig: -------------------------------------------------------------------------------- 1 | {% extends 'shop/_private/layouts' %} 2 | 3 | {% set extraHead %} 4 | 5 | {% endset %} 6 | 7 | {% block main %} 8 | 9 |
10 |
11 |
12 | {% include 'shop/customer/_includes/sign-in' with { 13 | redirectUrl : 'shop/customer' 14 | } %} 15 |
16 |
17 |
18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /example-templates/dist/shop/index.twig: -------------------------------------------------------------------------------- 1 | {% redirect 'shop/products' %} -------------------------------------------------------------------------------- /example-templates/dist/shop/products/index.twig: -------------------------------------------------------------------------------- 1 | {% extends 'shop/_private/layouts' %} 2 | 3 | {% block main %} 4 | 5 |

6 | {{- 'Products'|t -}} 7 |

8 | {% paginate craft.products.limit(6) as pageInfo, pageProducts %} 9 | 10 | {{ include('shop/products/_includes/grid', { 11 | products: pageProducts 12 | }) }} 13 | 14 | {{ include('shop/products/_includes/pagination', { 15 | products: pageProducts, 16 | pageInfo: pageInfo 17 | }) }} 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /example-templates/src/shop/_private/images/spinner.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /example-templates/src/shop/_private/layouts/includes/header.twig: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 | 5 | {{- siteName ~ ' Shop' -}} 6 | 7 |

8 | {% if craft.app.sites.getAllSites()|length > 1 %} 9 |
10 | 15 |
16 | {% endif %} 17 |
18 |
-------------------------------------------------------------------------------- /example-templates/src/shop/_private/payments/payment-post-redirect.twig: -------------------------------------------------------------------------------- 1 | {# 2 | Outputs a payment redirect page. 3 | 4 | @var actionUrl string 5 | @var inputs string 6 | #} 7 | 8 | 9 | 10 | 11 | {{ 'Redirecting'|t }}... 12 | 13 | 14 |
15 |

{{ 'Redirecting to payment page'|t }}...

16 |

17 | {{ inputs|raw }} 18 | {{ tag('button', { 19 | type: 'submit', 20 | text: 'Continue'|t 21 | }) }} 22 |

23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /example-templates/src/shop/checkout/index.twig: -------------------------------------------------------------------------------- 1 | {% redirect '[[folderName]]/checkout/email' %} -------------------------------------------------------------------------------- /example-templates/src/shop/customer/index.twig: -------------------------------------------------------------------------------- 1 | {% redirect '[[folderName]]/customer/orders' %} -------------------------------------------------------------------------------- /example-templates/src/shop/customer/sign-in.twig: -------------------------------------------------------------------------------- 1 | {% extends '[[folderName]]/_private/layouts' %} 2 | 3 | {% set extraHead %} 4 | 5 | {% endset %} 6 | 7 | {% block main %} 8 | 9 |
10 |
11 |
12 | {% include '[[folderName]]/customer/_includes/sign-in' with { 13 | redirectUrl : '[[folderName]]/customer' 14 | } %} 15 |
16 |
17 |
18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /example-templates/src/shop/index.twig: -------------------------------------------------------------------------------- 1 | {% redirect '[[folderName]]/products' %} -------------------------------------------------------------------------------- /example-templates/src/shop/products/index.twig: -------------------------------------------------------------------------------- 1 | {% extends '[[folderName]]/_private/layouts' %} 2 | 3 | {% block main %} 4 | 5 |

6 | {{- 'Products'|t -}} 7 |

8 | {% paginate craft.products.limit(6) as pageInfo, pageProducts %} 9 | 10 | {{ include('[[folderName]]/products/_includes/grid', { 11 | products: pageProducts 12 | }) }} 13 | 14 | {{ include('[[folderName]]/products/_includes/pagination', { 15 | products: pageProducts, 16 | pageInfo: pageInfo 17 | }) }} 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /rector.php: -------------------------------------------------------------------------------- 1 | withPaths([ 9 | __DIR__ . '/src', 10 | __DIR__ . '/tests/unit', 11 | ]) 12 | ->withPhpSets(php73: true); 13 | -------------------------------------------------------------------------------- /src/base/AdjusterInterface.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | interface AdjusterInterface 20 | { 21 | /** 22 | * Returns adjustments to add to the order 23 | * 24 | * @return OrderAdjustment[] 25 | */ 26 | public function adjust(Order $order): array; 27 | } 28 | -------------------------------------------------------------------------------- /src/base/EnumHelpersTrait.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 5.0.0 17 | */ 18 | interface HasStoreInterface 19 | { 20 | /** 21 | * @return Store 22 | */ 23 | public function getStore(): Store; 24 | } 25 | -------------------------------------------------------------------------------- /src/base/Model.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class Model extends BaseModel 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/base/PlanInterface.php: -------------------------------------------------------------------------------- 1 | 14 | * @since 2.0 15 | * @todo remove ignore: https://github.com/phpstan/phpstan/issues/6778 16 | * @phpstan-ignore-next-line 17 | * @mixin PlanTrait 18 | */ 19 | interface PlanInterface 20 | { 21 | /** 22 | * Returns whether it's possible to switch to this plan from a different plan. 23 | * TODO: Fix typo in next major release currentPlant -> currentPlan 24 | */ 25 | public function canSwitchFrom(PlanInterface $currentPlant): bool; 26 | } 27 | -------------------------------------------------------------------------------- /src/base/StoreRecordTrait.php: -------------------------------------------------------------------------------- 1 | 13 | * @since 5.0.0 14 | */ 15 | trait StoreRecordTrait 16 | { 17 | /** 18 | * @return ActiveQueryInterface 19 | */ 20 | public function getStore(): ActiveQueryInterface 21 | { 22 | /** @var ActiveRecord $this */ 23 | return $this->hasOne(Store::class, ['id' => 'storeId']); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/base/ZoneInterface.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 3.3 17 | */ 18 | class Controller extends CraftController 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/controllers/BaseAdminController.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class BaseAdminController extends BaseCpController 20 | { 21 | /** 22 | * @inheritdoc 23 | * @throws ForbiddenHttpException 24 | */ 25 | public function init(): void 26 | { 27 | parent::init(); 28 | $this->requireAdmin(false); 29 | } 30 | 31 | protected function isReadOnlyScreen(): bool 32 | { 33 | return !Craft::$app->getConfig()->getGeneral()->allowAdminChanges; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/controllers/BaseController.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | abstract class BaseController extends Controller 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/controllers/BaseCpController.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class BaseCpController extends BaseController 20 | { 21 | /** 22 | * @inheritdoc 23 | * @throws ForbiddenHttpException 24 | */ 25 | public function init(): void 26 | { 27 | parent::init(); 28 | 29 | // All system setting actions require access to commerce 30 | $this->requirePermission('accessPlugin-commerce'); 31 | 32 | $this->getView()->registerAssetBundle(CommerceCpAsset::class); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/controllers/BaseShippingSettingsController.php: -------------------------------------------------------------------------------- 1 | 14 | * @since 2.0 15 | */ 16 | class BaseShippingSettingsController extends BaseStoreManagementController 17 | { 18 | /** 19 | * @inheritdoc 20 | */ 21 | public function init(): void 22 | { 23 | parent::init(); 24 | 25 | // All system setting actions require access to commerce 26 | $this->requirePermission('commerce-manageShipping'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/controllers/BaseTaxSettingsController.php: -------------------------------------------------------------------------------- 1 | 14 | * @since 2.0 15 | */ 16 | class BaseTaxSettingsController extends BaseStoreManagementController 17 | { 18 | /** 19 | * @inheritdoc 20 | */ 21 | public function init(): void 22 | { 23 | parent::init(); 24 | 25 | // All system setting actions require access to commerce 26 | $this->requirePermission('commerce-manageTaxes'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/controllers/PromotionsController.php: -------------------------------------------------------------------------------- 1 | 14 | * @since 2.0 15 | */ 16 | class PromotionsController extends BaseCpController 17 | { 18 | public function actionIndex(): void 19 | { 20 | $this->redirect('commerce/promotions/sales'); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/controllers/VariantsController.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 5.0.0 17 | */ 18 | class VariantsController extends BaseController 19 | { 20 | /** 21 | * @return Response 22 | */ 23 | public function actionIndex(): Response 24 | { 25 | return $this->renderTemplate('commerce/variants/_index'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/elements/conditions/customers/DiscountCustomerCondition.php: -------------------------------------------------------------------------------- 1 | 13 | * @since 4.0.0 14 | */ 15 | class DiscountCustomerCondition extends UserElementCondition 16 | { 17 | /** 18 | * @inheritdoc 19 | */ 20 | public ?string $elementType = User::class; 21 | 22 | /** 23 | * @inheritdoc 24 | */ 25 | protected function selectableConditionRules(): array 26 | { 27 | return array_merge(parent::selectableConditionRules(), [ 28 | HasOrdersConditionRule::class, 29 | SignedInConditionRule::class, 30 | DiscountGroupConditionRule::class, 31 | ]); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/elements/conditions/orders/ItemSubtotalConditionRule.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 4.2.0 12 | * 13 | * @property-read float|int $orderAttributeValue 14 | */ 15 | class ItemSubtotalConditionRule extends OrderCurrencyValuesAttributeConditionRule 16 | { 17 | public string $orderAttribute = 'itemSubtotal'; 18 | 19 | /** 20 | * @inheritdoc 21 | */ 22 | public function getLabel(): string 23 | { 24 | return Craft::t('commerce', 'Item Subtotal'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/elements/conditions/orders/ItemTotalConditionRule.php: -------------------------------------------------------------------------------- 1 | 11 | * @since 4.2.0 12 | * 13 | * @property-read float|int $orderAttributeValue 14 | */ 15 | class ItemTotalConditionRule extends OrderCurrencyValuesAttributeConditionRule 16 | { 17 | public string $orderAttribute = 'itemTotal'; 18 | 19 | /** 20 | * @inheritdoc 21 | */ 22 | public function getLabel(): string 23 | { 24 | return Craft::t('commerce', 'Item Total'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/elements/conditions/orders/ReferenceConditionRule.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 4.2.0 17 | */ 18 | class ReferenceConditionRule extends OrderTextValuesAttributeConditionRule 19 | { 20 | public string $orderAttribute = 'reference'; 21 | 22 | /** 23 | * @inheritdoc 24 | */ 25 | public function getLabel(): string 26 | { 27 | return Craft::t('commerce', 'Reference'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/elements/conditions/orders/TotalConditionRule.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 4.2.0 17 | * 18 | * @property-read float|int $orderAttributeValue 19 | */ 20 | class TotalConditionRule extends OrderCurrencyValuesAttributeConditionRule 21 | { 22 | public string $orderAttribute = 'total'; 23 | 24 | /** 25 | * @inheritdoc 26 | */ 27 | public function getLabel(): string 28 | { 29 | return Craft::t('commerce', 'Total'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/elements/conditions/orders/TotalPaidConditionRule.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 4.2.0 17 | * 18 | * @property-read float|int $orderAttributeValue 19 | */ 20 | class TotalPaidConditionRule extends OrderCurrencyValuesAttributeConditionRule 21 | { 22 | public string $orderAttribute = 'totalPaid'; 23 | 24 | /** 25 | * @inheritdoc 26 | */ 27 | public function getLabel(): string 28 | { 29 | return Craft::t('commerce', 'Total Paid'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/elements/conditions/orders/TotalPriceConditionRule.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 4.0.0 17 | * 18 | * @property-read float|int $orderAttributeValue 19 | */ 20 | class TotalPriceConditionRule extends OrderCurrencyValuesAttributeConditionRule 21 | { 22 | public string $orderAttribute = 'totalPrice'; 23 | 24 | /** 25 | * @inheritdoc 26 | */ 27 | public function getLabel(): string 28 | { 29 | return Craft::t('commerce', 'Total Price'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/elements/conditions/orders/TotalQtyConditionRule.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 4.2.0 17 | */ 18 | class TotalQtyConditionRule extends OrderValuesAttributeConditionRule 19 | { 20 | public string $orderAttribute = 'totalQty'; 21 | 22 | /** 23 | * @inheritdoc 24 | */ 25 | public function getLabel(): string 26 | { 27 | return Craft::t('commerce', 'Total Qty'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/elements/conditions/orders/TotalTaxConditionRule.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 4.2.0 17 | * 18 | * @property-read float|int $orderAttributeValue 19 | */ 20 | class TotalTaxConditionRule extends OrderCurrencyValuesAttributeConditionRule 21 | { 22 | public string $orderAttribute = 'totalTax'; 23 | 24 | /** 25 | * @inheritdoc 26 | */ 27 | public function getLabel(): string 28 | { 29 | return Craft::t('commerce', 'Total Tax'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/elements/conditions/orders/TotalWeightConditionRule.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 4.2.0 17 | */ 18 | class TotalWeightConditionRule extends OrderValuesAttributeConditionRule 19 | { 20 | public string $orderAttribute = 'totalWeight'; 21 | 22 | /** 23 | * @inheritdoc 24 | */ 25 | public function getLabel(): string 26 | { 27 | return Craft::t('commerce', 'Total Weight'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/elements/conditions/products/CatalogPricingRuleProductCondition.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 5.1.0 17 | */ 18 | class CatalogPricingRuleProductCondition extends ProductCondition 19 | { 20 | /** 21 | * @inheritdoc 22 | */ 23 | protected function selectableConditionRules(): array 24 | { 25 | $rules = parent::selectableConditionRules(); 26 | 27 | return ArrayHelper::withoutValue($rules, ProductVariantHasUnlimitedStockConditionRule::class); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/elements/conditions/transfers/TransferCondition.php: -------------------------------------------------------------------------------- 1 | 14 | * @since 5.1.0 15 | */ 16 | class CatalogPricingRuleVariantCondition extends VariantCondition 17 | { 18 | } 19 | -------------------------------------------------------------------------------- /src/elements/conditions/variants/VariantCondition.php: -------------------------------------------------------------------------------- 1 | 13 | * @since 4.0.0 14 | */ 15 | class VariantCondition extends ElementCondition 16 | { 17 | /** 18 | * @inheritdoc 19 | */ 20 | public ?string $elementType = Variant::class; 21 | 22 | /** 23 | * @inheritdoc 24 | */ 25 | protected function selectableConditionRules(): array 26 | { 27 | return array_merge(parent::selectableConditionRules(), [ 28 | ProductConditionRule::class, 29 | SkuConditionRule::class, 30 | ]); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/enums/InventoryUpdateQuantityType.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class CurrencyException extends Exception 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/errors/EmailException.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class EmailException extends Exception 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/errors/GatewayException.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class GatewayException extends Exception 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/errors/LineItemException.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class LineItemException extends Exception 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/errors/NotImplementedException.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class NotImplementedException extends BadMethodCallException 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/errors/OrderStatusException.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class OrderStatusException extends Exception 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/errors/PaymentException.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class PaymentException extends Exception 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/errors/PaymentSourceCreatedLaterException.php: -------------------------------------------------------------------------------- 1 | 14 | * @since 4.3 15 | */ 16 | class PaymentSourceCreatedLaterException extends PaymentSourceException 17 | { 18 | } 19 | -------------------------------------------------------------------------------- /src/errors/PaymentSourceException.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class PaymentSourceException extends Exception 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/errors/ProductTypeNotFoundException.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class ProductTypeNotFoundException extends Exception 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/errors/RefundException.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class RefundException extends Exception 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/errors/ShippingMethodException.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class ShippingMethodException extends Exception 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/errors/StoreNotFoundException.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 5.0.0 17 | */ 18 | class StoreNotFoundException extends Exception 19 | { 20 | /** 21 | * @return string the user-friendly name of this exception 22 | */ 23 | public function getName(): string 24 | { 25 | return 'Store not found'; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/errors/SubscriptionException.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class SubscriptionException extends Exception 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/errors/TransactionException.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class TransactionException extends Exception 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/etc/commands.php: -------------------------------------------------------------------------------- 1 | 'Commerce Orders', 14 | 'type' => 'Link', 15 | 'url' => UrlHelper::cpUrl('commerce/orders'), 16 | ], 17 | [ 18 | 'name' => 'Commerce Products', 19 | 'type' => 'Link', 20 | 'url' => UrlHelper::cpUrl('commerce/products'), 21 | ], 22 | [ 23 | 'name' => 'Commerce Promotions', 24 | 'type' => 'Link', 25 | 'url' => UrlHelper::cpUrl('commerce/promotions'), 26 | ], 27 | [ 28 | 'name' => 'Commerce Settings', 29 | 'type' => 'Link', 30 | 'url' => UrlHelper::cpUrl('commerce/settings'), 31 | ], 32 | ]; 33 | -------------------------------------------------------------------------------- /src/events/AddLineItemEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class AddLineItemEvent extends CancelableEvent 20 | { 21 | /** 22 | * @var LineItem The line item model. 23 | */ 24 | public LineItem $lineItem; 25 | 26 | /** 27 | * @var bool If this is a new line item. 28 | */ 29 | public bool $isNew = false; 30 | } 31 | -------------------------------------------------------------------------------- /src/events/CancelSubscriptionEvent.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 2.0 19 | */ 20 | class CancelSubscriptionEvent extends CancelableEvent 21 | { 22 | /** 23 | * @var Subscription Subscription 24 | */ 25 | public Subscription $subscription; 26 | 27 | /** 28 | * @var CancelSubscriptionForm parameters 29 | */ 30 | public CancelSubscriptionForm $parameters; 31 | } 32 | -------------------------------------------------------------------------------- /src/events/CartEvent.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 2.0 19 | */ 20 | class CartEvent extends CancelableEvent 21 | { 22 | /** 23 | * @var LineItem The line item model. 24 | */ 25 | public LineItem $lineItem; 26 | 27 | /** 28 | * @var Order The order element 29 | */ 30 | public Order $order; 31 | } 32 | -------------------------------------------------------------------------------- /src/events/CartPurgeEvent.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 5.3 19 | */ 20 | class CartPurgeEvent extends CancelableEvent 21 | { 22 | /** 23 | * @var Query The query that identifies the order IDs to be purged. 24 | */ 25 | public Query $inactiveCartsQuery; 26 | } 27 | -------------------------------------------------------------------------------- /src/events/CommerceDebugPanelDataEvent.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 4.0 17 | */ 18 | class CommerceDebugPanelDataEvent extends Event 19 | { 20 | /** 21 | * @var array 22 | */ 23 | public array $nav; 24 | 25 | /** 26 | * @var array 27 | */ 28 | public array $content; 29 | } 30 | -------------------------------------------------------------------------------- /src/events/CreateSubscriptionEvent.php: -------------------------------------------------------------------------------- 1 | 19 | * @since 2.0 20 | */ 21 | class CreateSubscriptionEvent extends CancelableEvent 22 | { 23 | /** 24 | * @var User The subscribing user 25 | */ 26 | public User $user; 27 | 28 | /** 29 | * @var Plan The subscription plan 30 | */ 31 | public Plan $plan; 32 | 33 | /** 34 | * @var SubscriptionForm Additional parameters 35 | */ 36 | public SubscriptionForm $parameters; 37 | } 38 | -------------------------------------------------------------------------------- /src/events/CustomizeProductSnapshotDataEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class CustomizeProductSnapshotDataEvent extends Event 20 | { 21 | /** 22 | * @var Product The product 23 | */ 24 | public Product $product; 25 | 26 | /** 27 | * @var array The captured data 28 | */ 29 | public array $fieldData; 30 | } 31 | -------------------------------------------------------------------------------- /src/events/CustomizeProductSnapshotFieldsEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class CustomizeProductSnapshotFieldsEvent extends Event 20 | { 21 | /** 22 | * @var Product The product 23 | */ 24 | public Product $product; 25 | 26 | /** 27 | * @var array|null The fields to be captured 28 | */ 29 | public ?array $fields = null; 30 | } 31 | -------------------------------------------------------------------------------- /src/events/CustomizeVariantSnapshotDataEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class CustomizeVariantSnapshotDataEvent extends Event 20 | { 21 | /** 22 | * @var Variant The variant 23 | */ 24 | public Variant $variant; 25 | 26 | /** 27 | * @var array The captured data 28 | */ 29 | public array $fieldData; 30 | } 31 | -------------------------------------------------------------------------------- /src/events/CustomizeVariantSnapshotFieldsEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class CustomizeVariantSnapshotFieldsEvent extends Event 20 | { 21 | /** 22 | * @var Variant The variant 23 | */ 24 | public Variant $variant; 25 | 26 | /** 27 | * @var array|null The fields to be captured 28 | */ 29 | public ?array $fields = null; 30 | } 31 | -------------------------------------------------------------------------------- /src/events/DefaultLineItemStatusEvent.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 2.0 19 | */ 20 | class DefaultLineItemStatusEvent extends Event 21 | { 22 | /** 23 | * @var LineItemStatus|null The default line item status based on the line item 24 | */ 25 | public ?LineItemStatus $lineItemStatus = null; 26 | 27 | /** 28 | * @var LineItem The line item used to determine the line item status. 29 | */ 30 | public LineItem $lineItem; 31 | } 32 | -------------------------------------------------------------------------------- /src/events/DefaultOrderStatusEvent.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 2.0 19 | */ 20 | class DefaultOrderStatusEvent extends Event 21 | { 22 | /** 23 | * @var OrderStatus The default order status based on the order 24 | */ 25 | public OrderStatus $orderStatus; 26 | 27 | /** 28 | * @var Order The order used to determine the order status. 29 | */ 30 | public Order $order; 31 | } 32 | -------------------------------------------------------------------------------- /src/events/DeleteStoreEvent.php: -------------------------------------------------------------------------------- 1 | 14 | * @since 5.0.0 15 | */ 16 | class DeleteStoreEvent extends StoreEvent 17 | { 18 | } 19 | -------------------------------------------------------------------------------- /src/events/DiscountAdjustmentsEvent.php: -------------------------------------------------------------------------------- 1 | 19 | * @since 2.0 20 | */ 21 | class DiscountAdjustmentsEvent extends CancelableEvent 22 | { 23 | /** 24 | * @var Order The order the discount generated the adjustments for. Do not mutate. 25 | */ 26 | public Order $order; 27 | 28 | /** 29 | * @var Discount The discount that matched. 30 | */ 31 | public Discount $discount; 32 | 33 | /** 34 | * @var OrderAdjustment[] The adjustments generated by the discount. 35 | */ 36 | public array $adjustments; 37 | } 38 | -------------------------------------------------------------------------------- /src/events/DiscountEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class DiscountEvent extends Event 20 | { 21 | /** 22 | * @var Discount The discount model 23 | */ 24 | public Discount $discount; 25 | 26 | /** 27 | * @var bool If this is a new discount 28 | */ 29 | public bool $isNew; 30 | } 31 | -------------------------------------------------------------------------------- /src/events/EmailEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class EmailEvent extends Event 20 | { 21 | /** 22 | * @var Email Email 23 | */ 24 | public Email $email; 25 | 26 | /** 27 | * @var bool Whether the email is brand new. 28 | */ 29 | public bool $isNew = false; 30 | } 31 | -------------------------------------------------------------------------------- /src/events/LineItemEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class LineItemEvent extends Event 20 | { 21 | /** 22 | * @var LineItem The line item model. 23 | */ 24 | public LineItem $lineItem; 25 | 26 | /** 27 | * @var bool If this is a new line item. 28 | */ 29 | public bool $isNew = false; 30 | } 31 | -------------------------------------------------------------------------------- /src/events/MatchLineItemEvent.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 2.0 19 | */ 20 | class MatchLineItemEvent extends CancelableEvent 21 | { 22 | /** 23 | * @var LineItem The matched line item. 24 | */ 25 | public LineItem $lineItem; 26 | 27 | /** 28 | * @var Discount The discount that matched. 29 | */ 30 | public Discount $discount; 31 | } 32 | -------------------------------------------------------------------------------- /src/events/MatchOrderEvent.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 3.1.5 19 | */ 20 | class MatchOrderEvent extends CancelableEvent 21 | { 22 | /** 23 | * @var Order The matched order. 24 | */ 25 | public Order $order; 26 | 27 | /** 28 | * @var Discount The discount that matched. 29 | */ 30 | public Discount $discount; 31 | } 32 | -------------------------------------------------------------------------------- /src/events/ModifyCartInfoEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.2 18 | */ 19 | class ModifyCartInfoEvent extends Event 20 | { 21 | /** 22 | * @var array The cart info that is allowed to be modified 23 | */ 24 | public array $cartInfo = []; 25 | 26 | /** 27 | * The cart object that can be used to modify the cart info. 28 | * Do not mutate this object. 29 | * 30 | * @var Order|null 31 | * @since 3.1.11 32 | */ 33 | public ?Order $cart = null; 34 | } 35 | -------------------------------------------------------------------------------- /src/events/ModifyPurchasablesTableQueryEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 4.3.0 18 | */ 19 | class ModifyPurchasablesTableQueryEvent extends Event 20 | { 21 | /** 22 | * @var Query 23 | */ 24 | public Query $query; 25 | 26 | /** 27 | * @var string|null The search term that is being used in the query, if any 28 | */ 29 | public ?string $search = null; 30 | } 31 | -------------------------------------------------------------------------------- /src/events/OrderLineItemsRefreshEvent.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 5.1.0 17 | */ 18 | class OrderLineItemsRefreshEvent extends Event 19 | { 20 | /** 21 | * @var array 22 | */ 23 | public array $lineItems; 24 | 25 | public bool $recalculate = false; 26 | } 27 | -------------------------------------------------------------------------------- /src/events/OrderNoticeEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 4.1.0 18 | */ 19 | class OrderNoticeEvent extends CancelableEvent 20 | { 21 | /** 22 | * @var OrderNotice The line item model. 23 | */ 24 | public $orderNotice; 25 | } 26 | -------------------------------------------------------------------------------- /src/events/OrderStatusEmailsEvent.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 4.0 19 | */ 20 | class OrderStatusEmailsEvent extends CancelableEvent 21 | { 22 | /** 23 | * @var OrderHistory The order history 24 | */ 25 | public OrderHistory $orderHistory; 26 | 27 | /** 28 | * @var Order The order 29 | */ 30 | public Order $order; 31 | 32 | /** 33 | * @var array The emails to send 34 | */ 35 | public array $emails; 36 | } 37 | -------------------------------------------------------------------------------- /src/events/OrderStatusEvent.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 2.0 19 | */ 20 | class OrderStatusEvent extends Event 21 | { 22 | /** 23 | * @var OrderHistory The order history 24 | */ 25 | public OrderHistory $orderHistory; 26 | 27 | /** 28 | * @var Order The order 29 | */ 30 | public Order $order; 31 | } 32 | -------------------------------------------------------------------------------- /src/events/PaymentSourceEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class PaymentSourceEvent extends CancelableEvent 20 | { 21 | /** 22 | * @var PaymentSource Payment source 23 | */ 24 | public PaymentSource $paymentSource; 25 | } 26 | -------------------------------------------------------------------------------- /src/events/PdfEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class PdfEvent extends Event 20 | { 21 | /** 22 | * @var Pdf The PDF model associated with the event. 23 | */ 24 | public Pdf $pdf; 25 | 26 | /** 27 | * @var bool Whether the PDF is brand new 28 | */ 29 | public bool $isNew = false; 30 | } 31 | -------------------------------------------------------------------------------- /src/events/PdfRenderOptionsEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 3.2.10 18 | */ 19 | class PdfRenderOptionsEvent extends Event 20 | { 21 | /** 22 | * @var Options 23 | */ 24 | public Options $options; 25 | } 26 | -------------------------------------------------------------------------------- /src/events/PlanEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class PlanEvent extends Event 20 | { 21 | /** 22 | * @var Plan Plan 23 | */ 24 | public Plan $plan; 25 | } 26 | -------------------------------------------------------------------------------- /src/events/ProcessPaymentEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class ProductEvent extends CancelableEvent 20 | { 21 | /** 22 | * @var Product The address model 23 | */ 24 | public Product $product; 25 | 26 | /** 27 | * @var bool If this is a new product 28 | */ 29 | public bool $isNew; 30 | } 31 | -------------------------------------------------------------------------------- /src/events/ProductTypeEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class ProductTypeEvent extends Event 20 | { 21 | /** 22 | * @var ProductType|null The product type model associated with the event. 23 | */ 24 | public ?ProductType $productType = null; 25 | 26 | /** 27 | * @var bool Whether the product type is brand new 28 | */ 29 | public bool $isNew = false; 30 | } 31 | -------------------------------------------------------------------------------- /src/events/PurchaseVariantEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class PurchaseVariantEvent extends Event 20 | { 21 | /** 22 | * @var Variant The variant model 23 | */ 24 | public Variant $variant; 25 | } 26 | -------------------------------------------------------------------------------- /src/events/PurgeAddressesEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 3.3 18 | */ 19 | class PurgeAddressesEvent extends CancelableEvent 20 | { 21 | /** 22 | * @var Query|null The query to get the purgeable addresses 23 | */ 24 | public ?Query $addressesQuery = null; 25 | } 26 | -------------------------------------------------------------------------------- /src/events/RefundTransactionEvent.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class RefundTransactionEvent extends TransactionEvent 19 | { 20 | /** 21 | * @var float The amount to refund 22 | */ 23 | public float $amount; 24 | 25 | /** 26 | * @var Transaction The transaction created which is the refund 27 | */ 28 | public Transaction $refundTransaction; 29 | } 30 | -------------------------------------------------------------------------------- /src/events/ReportEvent.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class ReportEvent extends Event 19 | { 20 | public mixed $startDate = null; 21 | public mixed $endDate = null; 22 | public mixed $status = null; 23 | public mixed $orderQuery = null; 24 | public mixed $columns = null; 25 | public mixed $orders = null; 26 | public mixed $format = null; 27 | } 28 | -------------------------------------------------------------------------------- /src/events/SaleEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.2 18 | */ 19 | class SaleEvent extends Event 20 | { 21 | /** 22 | * @var Sale sale 23 | */ 24 | public Sale $sale; 25 | 26 | /** 27 | * @var bool Whether the sale is brand new 28 | */ 29 | public bool $isNew = false; 30 | } 31 | -------------------------------------------------------------------------------- /src/events/SaleMatchEvent.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 2.0 19 | */ 20 | class SaleMatchEvent extends CancelableEvent 21 | { 22 | /** 23 | * @var Sale The sale 24 | */ 25 | public Sale $sale; 26 | 27 | /** 28 | * @var PurchasableInterface The purchasable matched 29 | */ 30 | public PurchasableInterface $purchasable; 31 | 32 | /** 33 | * @var bool If this is a new sale 34 | */ 35 | public bool $isNew; 36 | } 37 | -------------------------------------------------------------------------------- /src/events/StoreEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 5.0.0 18 | */ 19 | class StoreEvent extends CancelableEvent 20 | { 21 | /** 22 | * @var Store The store model associated with the event. 23 | */ 24 | public Store $store; 25 | 26 | /** 27 | * @var bool Whether the store is brand new 28 | */ 29 | public bool $isNew = false; 30 | } 31 | -------------------------------------------------------------------------------- /src/events/SubscriptionEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class SubscriptionEvent extends CancelableEvent 20 | { 21 | /** 22 | * @var Subscription Subscription 23 | */ 24 | public Subscription $subscription; 25 | } 26 | -------------------------------------------------------------------------------- /src/events/SubscriptionPaymentEvent.php: -------------------------------------------------------------------------------- 1 | 19 | * @since 2.0 20 | */ 21 | class SubscriptionPaymentEvent extends Event 22 | { 23 | /** 24 | * @var Subscription Subscription 25 | */ 26 | public Subscription $subscription; 27 | 28 | /** 29 | * @var SubscriptionPayment Subscription payment 30 | */ 31 | public SubscriptionPayment $payment; 32 | 33 | /** 34 | * @var DateTime Date subscription paid until 35 | */ 36 | public DateTime $paidUntil; 37 | } 38 | -------------------------------------------------------------------------------- /src/events/TaxEngineEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 3.1 18 | */ 19 | class TaxEngineEvent extends Event 20 | { 21 | /** 22 | * @var TaxEngineInterface The tax engine 23 | */ 24 | public TaxEngineInterface $engine; 25 | } 26 | -------------------------------------------------------------------------------- /src/events/TaxIdValidatorsEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 5.3.0 18 | */ 19 | class TaxIdValidatorsEvent extends Event 20 | { 21 | /** 22 | * @var TaxIdValidatorInterface[] Holds the registered tax ID validators. 23 | */ 24 | public array $validators = []; 25 | } 26 | -------------------------------------------------------------------------------- /src/events/TransactionEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class TransactionEvent extends Event 20 | { 21 | /** 22 | * @var Transaction The transaction model 23 | */ 24 | public Transaction $transaction; 25 | } 26 | -------------------------------------------------------------------------------- /src/events/UpdatePrimaryPaymentSourceEvent.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 4.2.8 18 | */ 19 | class UpdatePrimaryPaymentSourceEvent extends Event 20 | { 21 | /** 22 | * @var ?int The previous payment source ID 23 | */ 24 | public ?int $previousPrimaryPaymentSourceId = null; 25 | 26 | /** 27 | * @var ?int The new payment source ID 28 | */ 29 | public ?int $newPrimaryPaymentSourceId = null; 30 | 31 | /** 32 | * @var User The user that the payment source belongs to 33 | */ 34 | public User $customer; 35 | } 36 | -------------------------------------------------------------------------------- /src/events/UpgradeEvent.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class UpgradeEvent extends Event 18 | { 19 | /** 20 | * @var array $columns 21 | */ 22 | public array $v3columnMap = []; 23 | 24 | /** 25 | * @var array $v3tables 26 | */ 27 | public array $v3tables = []; 28 | } 29 | -------------------------------------------------------------------------------- /src/events/WebhookEvent.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 3.2.9 19 | */ 20 | class WebhookEvent extends Event 21 | { 22 | /** 23 | * @var GatewayInterface 24 | */ 25 | public GatewayInterface $gateway; 26 | 27 | /** 28 | * @var Response 29 | */ 30 | public Response $response; 31 | } 32 | -------------------------------------------------------------------------------- /src/gql/types/input/Product.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 3.2.4 19 | */ 20 | class Product extends InputObjectType 21 | { 22 | /** 23 | * @return mixed 24 | */ 25 | public static function getType(): mixed 26 | { 27 | $typeName = 'ProductInput'; 28 | 29 | return GqlEntityRegistry::getEntity($typeName) ?: GqlEntityRegistry::createEntity($typeName, new InputObjectType([ 30 | 'name' => $typeName, 31 | 'fields' => function() { 32 | return ProductArguments::getArguments(); 33 | }, 34 | ])); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/gql/types/input/Variant.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 3.1.11 19 | */ 20 | class Variant extends InputObjectType 21 | { 22 | /** 23 | * @return mixed 24 | */ 25 | public static function getType(): mixed 26 | { 27 | $typeName = 'VariantInput'; 28 | 29 | return GqlEntityRegistry::getEntity($typeName) ?: GqlEntityRegistry::createEntity($typeName, new InputObjectType([ 30 | 'name' => $typeName, 31 | 'fields' => function() { 32 | return VariantArguments::getArguments(); 33 | }, 34 | ])); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/helpers/Cp.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 5.0 17 | */ 18 | class Cp 19 | { 20 | /** 21 | * Renders an inventory locations select field’s HTML. 22 | * 23 | * @param array $config 24 | * @return string 25 | * @since 5.0.0 26 | */ 27 | public static function inventoryLocationFieldHtml(array $config): string 28 | { 29 | $config['id'] = $config['id'] ?? 'inventorylocationselect' . mt_rand(); 30 | return CraftCp::fieldHtml('template:commerce/_includes/forms/inventoryLocationSelect.twig', $config); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/helpers/Gql.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 3.0 17 | */ 18 | class Gql extends GqlHelper 19 | { 20 | /** 21 | * Return true if active schema can query products. 22 | */ 23 | public static function canQueryProducts(): bool 24 | { 25 | $allowedEntities = self::extractAllowedEntitiesFromSchema(); 26 | return isset($allowedEntities['productTypes']); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/helpers/LineItem.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.1 17 | */ 18 | class LineItem 19 | { 20 | /** 21 | * @return string The generated options signature 22 | */ 23 | public static function generateOptionsSignature(array $options = [], ?int $lineItemId = null): string 24 | { 25 | if ($lineItemId) { 26 | $options['lineItemId'] = $lineItemId; 27 | } 28 | ksort($options); 29 | return md5(Json::encode($options)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/icon-mask.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/migrations/m210922_133729_add_discount_order_condition_builder.php: -------------------------------------------------------------------------------- 1 | db->columnExists('{{%commerce_discounts}}', 'orderCondition')) { 18 | $this->addColumn('{{%commerce_discounts}}', 'orderCondition', $this->text()->after('description')); 19 | } 20 | 21 | return true; 22 | } 23 | 24 | /** 25 | * @inheritdoc 26 | */ 27 | public function safeDown(): bool 28 | { 29 | echo "m210922_133729_add_discount_order_condition_builder cannot be reverted.\n"; 30 | return false; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/migrations/m220329_075053_convert_gateway_frontend_enabled_column.php: -------------------------------------------------------------------------------- 1 | alterColumn('{{%commerce_gateways}}', 'isFrontendEnabled', $this->string(500)->notNull()->defaultValue('1')); 18 | return true; 19 | } 20 | 21 | /** 22 | * @inheritdoc 23 | */ 24 | public function safeDown(): bool 25 | { 26 | echo "m220329_075053_convert_gateway_frontend_enabled_column cannot be reverted.\n"; 27 | return false; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/migrations/m220817_135050_add_purchase_total_back_if_missing.php: -------------------------------------------------------------------------------- 1 | db->columnExists('{{%commerce_discounts}}', 'purchaseTotal')) { 18 | $this->addColumn('{{%commerce_discounts}}', 'purchaseTotal', $this->decimal(14, 4)->notNull()->defaultValue(0)); 19 | } 20 | 21 | return true; 22 | } 23 | 24 | /** 25 | * @inheritdoc 26 | */ 27 | public function safeDown(): bool 28 | { 29 | echo "m220817_135050_add_purchase_total_back_if_missing cannot be reverted.\n"; 30 | return false; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/migrations/m221027_074805_update_shipping_tax_category_indexes.php: -------------------------------------------------------------------------------- 1 | dropIndexIfExists('{{%commerce_taxcategories}}', 'handle', true); 18 | $this->dropIndexIfExists('{{%commerce_shippingcategories}}', 'handle', true); 19 | 20 | return true; 21 | } 22 | 23 | /** 24 | * @inheritdoc 25 | */ 26 | public function safeDown(): bool 27 | { 28 | echo "m221027_074805_update_shipping_tax_category_indexes cannot be reverted.\n"; 29 | return false; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/migrations/m221124_114239_add_date_deleted_to_stores.php: -------------------------------------------------------------------------------- 1 | db->columnExists('{{%commerce_stores}}', 'dateDeleted')) { 19 | $this->addColumn('{{%commerce_stores}}', 'dateDeleted', $this->dateTime()->null()); 20 | } 21 | 22 | return true; 23 | } 24 | 25 | /** 26 | * @inheritdoc 27 | */ 28 | public function safeDown(): bool 29 | { 30 | echo "m221124_114239_add_date_deleted_to_stores cannot be reverted.\n"; 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/migrations/m230111_112916_update_lineitems_table.php: -------------------------------------------------------------------------------- 1 | addColumn(Table::LINEITEMS, 'promotionalPrice', $this->decimal(14, 4)->after('price')->null()->unsigned()); 19 | 20 | $this->renameColumn(Table::LINEITEMS, 'saleAmount', 'promotionalAmount'); 21 | 22 | return true; 23 | } 24 | 25 | /** 26 | * @inheritdoc 27 | */ 28 | public function safeDown(): bool 29 | { 30 | echo "m230111_112916_update_lineitems_table cannot be reverted.\n"; 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/migrations/m230113_110914_remove_soft_delete.php: -------------------------------------------------------------------------------- 1 | db->columnExists('{{%commerce_stores}}', 'dateDeleted')) { 18 | $this->dropColumn('{{%commerce_stores}}', 'dateDeleted'); 19 | } 20 | 21 | return true; 22 | } 23 | 24 | /** 25 | * @inheritdoc 26 | */ 27 | public function safeDown(): bool 28 | { 29 | echo "m230113_110914_remove_soft_delete cannot be reverted.\n"; 30 | return false; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/migrations/m230118_114424_add_purchasables_stores_indexes.php: -------------------------------------------------------------------------------- 1 | createIndexIfMissing(Table::PURCHASABLES_STORES, ['purchasableId']); 19 | $this->createIndexIfMissing(Table::PURCHASABLES_STORES, ['storeId']); 20 | 21 | return true; 22 | } 23 | 24 | /** 25 | * @inheritdoc 26 | */ 27 | public function safeDown(): bool 28 | { 29 | echo "m230118_114424_add_purchasables_stores_indexes cannot be reverted.\n"; 30 | return false; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/migrations/m230126_105337_rename_discount_sales_references.php: -------------------------------------------------------------------------------- 1 | renameColumn(Table::DISCOUNTS, 'excludeOnSale', 'excludeOnPromotion'); 19 | $this->renameColumn(Table::DISCOUNTS, 'ignoreSales', 'ignorePromotions'); 20 | 21 | return true; 22 | } 23 | 24 | /** 25 | * @inheritdoc 26 | */ 27 | public function safeDown(): bool 28 | { 29 | echo "m230126_105337_rename_discount_sales_references cannot be reverted.\n"; 30 | return false; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/migrations/m230126_114655_add_catalog_pricing_rule_metadata_column.php: -------------------------------------------------------------------------------- 1 | addColumn(Table::CATALOG_PRICING_RULES, 'metadata', $this->text()); 19 | 20 | return true; 21 | } 22 | 23 | /** 24 | * @inheritdoc 25 | */ 26 | public function safeDown(): bool 27 | { 28 | echo "m230126_114655_add_catalog_pricing_rule_metadata_column cannot be reverted.\n"; 29 | return false; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/migrations/m230214_095055_update_name_index_on_shipping_zones.php: -------------------------------------------------------------------------------- 1 | getDb()); 20 | $this->createIndex(null, Table::SHIPPINGZONES, ['name'], false); 21 | 22 | return true; 23 | } 24 | 25 | /** 26 | * @inheritdoc 27 | */ 28 | public function safeDown(): bool 29 | { 30 | echo "m230214_095055_update_name_index_on_shipping_zones cannot be reverted.\n"; 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/migrations/m230215_083820_add_order_condition_to_shipping_rules.php: -------------------------------------------------------------------------------- 1 | addColumn(Table::SHIPPINGRULES, 'orderCondition', $this->text()); 19 | 20 | return true; 21 | } 22 | 23 | /** 24 | * @inheritdoc 25 | */ 26 | public function safeDown(): bool 27 | { 28 | echo "m230215_083820_add_order_condition_to_shipping_rules cannot be reverted.\n"; 29 | return false; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/migrations/m230217_143255_add_shipping_method_order_condition.php: -------------------------------------------------------------------------------- 1 | addColumn(Table::SHIPPINGMETHODS, 'orderCondition', $this->text()); 19 | 20 | return true; 21 | } 22 | 23 | /** 24 | * @inheritdoc 25 | */ 26 | public function safeDown(): bool 27 | { 28 | echo "m230217_143255_add_shipping_method_order_condition cannot be reverted.\n"; 29 | return false; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/migrations/m230307_091520_add_sort_order_to_stores.php: -------------------------------------------------------------------------------- 1 | addColumn(Table::STORES, 'sortOrder', $this->integer()); 19 | 20 | $this->update(Table::STORES, ['sortOrder' => 1], ['primary' => true], [], false); 21 | 22 | return true; 23 | } 24 | 25 | /** 26 | * @inheritdoc 27 | */ 28 | public function safeDown(): bool 29 | { 30 | echo "m230307_091520_add_sort_order_to_stores cannot be reverted.\n"; 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/migrations/m230525_081243_add_has_update_pending_property.php: -------------------------------------------------------------------------------- 1 | addColumn(Table::CATALOG_PRICING, 'hasUpdatePending', $this->boolean()->notNull()->defaultValue(false)); 19 | 20 | return true; 21 | } 22 | 23 | /** 24 | * @inheritdoc 25 | */ 26 | public function safeDown(): bool 27 | { 28 | echo "m230525_081243_add_has_update_pending_property cannot be reverted.\n"; 29 | return false; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/migrations/m230530_100604_add_complete_email_column.php: -------------------------------------------------------------------------------- 1 | addColumn(Table::ORDERS, 'orderCompletedEmail', $this->string()); 21 | 22 | // Update existing data 23 | $this->update(Table::ORDERS, ['orderCompletedEmail' => new Expression('email')], ['isCompleted' => true], [], false); 24 | 25 | return true; 26 | } 27 | 28 | /** 29 | * @inheritdoc 30 | */ 31 | public function safeDown(): bool 32 | { 33 | echo "m230530_100604_add_complete_email_column cannot be reverted.\n"; 34 | return false; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/migrations/m230705_124845_add_save_address_columns.php: -------------------------------------------------------------------------------- 1 | addColumn(Table::ORDERS, 'saveBillingAddressOnOrderComplete', $this->boolean()->notNull()->defaultValue(false)); 19 | $this->addColumn(Table::ORDERS, 'saveShippingAddressOnOrderComplete', $this->boolean()->notNull()->defaultValue(false)); 20 | 21 | return true; 22 | } 23 | 24 | /** 25 | * @inheritdoc 26 | */ 27 | public function safeDown(): bool 28 | { 29 | echo "m230705_124845_add_save_address_columns cannot be reverted.\n"; 30 | return false; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/migrations/m230928_095544_fix_unique_on_some_tables.php: -------------------------------------------------------------------------------- 1 | dropIndexIfExists(Table::SHIPPINGMETHODS, 'name', true); 19 | $this->dropIndexIfExists(Table::TAXZONES, 'name', true); 20 | 21 | $this->createIndex(null, Table::SHIPPINGMETHODS, 'name', false); 22 | $this->createIndex(null, Table::TAXZONES, 'name', false); 23 | 24 | return true; 25 | } 26 | 27 | /** 28 | * @inheritdoc 29 | */ 30 | public function safeDown(): bool 31 | { 32 | echo "m230928_095544_fix_unique_on_some_tables cannot be reverted.\n"; 33 | return false; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/migrations/m231006_034833_add_indexes_for_source_address_on_order.php: -------------------------------------------------------------------------------- 1 | createIndex(null, Table::ORDERS, 'sourceBillingAddressId', false); 19 | $this->createIndex(null, Table::ORDERS, 'sourceShippingAddressId', false); 20 | 21 | return true; 22 | } 23 | 24 | /** 25 | * @inheritdoc 26 | */ 27 | public function safeDown(): bool 28 | { 29 | echo "m231006_034833_add_indexes_for_source_address_on_order cannot be reverted.\n"; 30 | return false; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/migrations/m240220_045806_product_versioning.php: -------------------------------------------------------------------------------- 1 | addColumn(Table::PRODUCTTYPES, 'enableVersioning', $this->boolean()->defaultValue(false)->notNull()->after('handle')); 19 | return true; 20 | } 21 | 22 | /** 23 | * @inheritdoc 24 | */ 25 | public function safeDown(): bool 26 | { 27 | echo "m240220_045806_product_versioning cannot be reverted.\n"; 28 | return false; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/migrations/m240220_105746_remove_store_from_donations_table.php: -------------------------------------------------------------------------------- 1 | db->columnExists(Table::DONATIONS, 'storeId')) { 19 | $this->dropForeignKeyIfExists(Table::DONATIONS, 'storeId'); 20 | $this->dropColumn(Table::DONATIONS, 'storeId'); 21 | } 22 | 23 | return true; 24 | } 25 | 26 | /** 27 | * @inheritdoc 28 | */ 29 | public function safeDown(): bool 30 | { 31 | echo "m240220_105746_remove_store_from_donations_table cannot be reverted.\n"; 32 | return false; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/migrations/m240228_054005_rename_movements_table.php: -------------------------------------------------------------------------------- 1 | renameTable('{{%commerce_inventorymovements}}', '{{%commerce_inventorytransactions}}'); 19 | 20 | return true; 21 | } 22 | 23 | /** 24 | * @inheritdoc 25 | */ 26 | public function safeDown(): bool 27 | { 28 | echo "m240228_054005_rename_movements_table cannot be reverted.\n"; 29 | return false; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/migrations/m240228_060604_add_fufilled_type_to_inventorytransactions.php: -------------------------------------------------------------------------------- 1 | alterColumn('{{%commerce_inventorytransactions}}', 'type', $this->enum('type', ['available', 'reserved', 'damaged', 'safety', 'qualityControl', 'committed', 'fulfilled', 'incoming'])->notNull()); 18 | 19 | return true; 20 | } 21 | 22 | /** 23 | * @inheritdoc 24 | */ 25 | public function safeDown(): bool 26 | { 27 | echo "m240228_060604_add_fufilled_column_to_inventorytransactions cannot be reverted.\n"; 28 | return false; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/migrations/m240301_113924_add_line_item_types.php: -------------------------------------------------------------------------------- 1 | addColumn(Table::LINEITEMS, 'type', $this->enum('type', [ 19 | 'purchasable', 20 | 'custom', 21 | ])->defaultValue('purchasable')->notNull()); 22 | 23 | return true; 24 | } 25 | 26 | /** 27 | * @inheritdoc 28 | */ 29 | public function safeDown(): bool 30 | { 31 | echo "m240301_113924_add_line_item_types cannot be reverted.\n"; 32 | return false; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/migrations/m240430_161804_add_index_to_transaction_hash.php: -------------------------------------------------------------------------------- 1 | createIndexIfMissing(Table::TRANSACTIONS, 'hash', false); 19 | 20 | return true; 21 | } 22 | 23 | /** 24 | * @inheritdoc 25 | */ 26 | public function safeDown(): bool 27 | { 28 | echo "m240430_161804_add_index_to_transaction_hash cannot be reverted.\n"; 29 | return false; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/migrations/m240528_124101_add_extra_lineitem_columns.php: -------------------------------------------------------------------------------- 1 | addColumn(Table::LINEITEMS, 'hasFreeShipping', $this->boolean()); 19 | 20 | $this->addColumn(Table::LINEITEMS, 'isPromotable', $this->boolean()); 21 | 22 | $this->addColumn(Table::LINEITEMS, 'isShippable', $this->boolean()); 23 | 24 | $this->addColumn(Table::LINEITEMS, 'isTaxable', $this->boolean()); 25 | 26 | return true; 27 | } 28 | 29 | /** 30 | * @inheritdoc 31 | */ 32 | public function safeDown(): bool 33 | { 34 | echo "m240528_124101_add_extra_lineitem_columns cannot be reverted.\n"; 35 | return false; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/migrations/m240710_125204_ensure_shippingCategoryId_column_is_nullable.php: -------------------------------------------------------------------------------- 1 | alterColumn('{{%commerce_purchasables_stores}}', 'shippingCategoryId', $this->integer()->null()); 18 | 19 | return true; 20 | } 21 | 22 | /** 23 | * @inheritdoc 24 | */ 25 | public function safeDown(): bool 26 | { 27 | echo "m240710_125204_ensure_shippingCategoryId_column_is_nullable cannot be reverted.\n"; 28 | return false; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/migrations/m240715_045506_drop_available_if_exists.php: -------------------------------------------------------------------------------- 1 | db->columnExists('{{%commerce_donations}}', 'availableForPurchase')) { 19 | $this->dropColumn('{{%commerce_donations}}', 'availableForPurchase'); 20 | } 21 | 22 | return true; 23 | } 24 | 25 | /** 26 | * @inheritdoc 27 | */ 28 | public function safeDown(): bool 29 | { 30 | echo "m240715_045506_drop_available_if_exists cannot be reverted.\n"; 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/migrations/m240717_044256_add_return_url_to_subscription.php: -------------------------------------------------------------------------------- 1 | addColumn('{{%commerce_subscriptions}}', 'returnUrl', $this->text()->after('isExpired')); 19 | 20 | return true; 21 | } 22 | 23 | /** 24 | * @inheritdoc 25 | */ 26 | public function safeDown(): bool 27 | { 28 | echo "m240717_044256_add_return_url_to_subscription cannot be reverted.\n"; 29 | return false; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/migrations/m240718_073046_remove_sortOrder_variants_column_if_exists.php: -------------------------------------------------------------------------------- 1 | db->columnExists('{{%commerce_variants}}', 'sortOrder')) { 18 | $this->dropColumn('{{%commerce_variants}}', 'sortOrder'); 19 | } 20 | 21 | return true; 22 | } 23 | 24 | /** 25 | * @inheritdoc 26 | */ 27 | public function safeDown(): bool 28 | { 29 | echo "m240718_073046_remove_sortOrder_variants_column_if_exists cannot be reverted.\n"; 30 | return false; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/migrations/m240830_081410_add_extra_indexes_to_catalog_pricing.php: -------------------------------------------------------------------------------- 1 | createIndex(null, '{{%commerce_catalogpricing}}', ['purchasableId', 'storeId', 'isPromotionalPrice', 'price'], false); 18 | $this->createIndex(null, '{{%commerce_catalogpricing}}', ['purchasableId', 'storeId', 'isPromotionalPrice', 'price', 'catalogPricingRuleId', 'dateFrom', 'dateTo'], false); 19 | 20 | return true; 21 | } 22 | 23 | /** 24 | * @inheritdoc 25 | */ 26 | public function safeDown(): bool 27 | { 28 | echo "m240830_081410_add_extra_indexes_to_catalog_pricing cannot be reverted.\n"; 29 | return false; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/migrations/m240905_130549_add_require_coupon_code_discount_setting.php: -------------------------------------------------------------------------------- 1 | addColumn('{{%commerce_discounts}}', 'requireCouponCode', $this->boolean()->notNull()->defaultValue(false)->after('billingAddressCondition')); 18 | 19 | return true; 20 | } 21 | 22 | /** 23 | * @inheritdoc 24 | */ 25 | public function safeDown(): bool 26 | { 27 | echo "m240905_130549_add_require_coupon_code_discount_setting cannot be reverted.\n"; 28 | return false; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/migrations/m240906_105809_update_existing_coupon_discounts.php: -------------------------------------------------------------------------------- 1 | from('{{%commerce_coupons}}') 20 | ->select(['discountId']) 21 | ->groupBy('discountId'); 22 | 23 | $this->update('{{%commerce_discounts}}', ['requireCouponCode' => true], ['id' => $couponDiscountIds]); 24 | 25 | return true; 26 | } 27 | 28 | /** 29 | * @inheritdoc 30 | */ 31 | public function safeDown(): bool 32 | { 33 | echo "m240906_105809_update_existing_coupon_discounts cannot be reverted.\n"; 34 | return false; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/migrations/m241204_045158_enable_tax_rate.php: -------------------------------------------------------------------------------- 1 | db->columnExists('{{%commerce_taxrates}}', 'enabled')) { 19 | $this->addColumn('{{%commerce_taxrates}}', 'enabled', $this->boolean()->notNull()->defaultValue(true)); 20 | } 21 | 22 | return true; 23 | } 24 | 25 | /** 26 | * @inheritdoc 27 | */ 28 | public function safeDown(): bool 29 | { 30 | echo "m241204_045158_enable_tax_rate cannot be reverted.\n"; 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/migrations/m241219_071723_add_inventory_backorder.php: -------------------------------------------------------------------------------- 1 | db->columnExists(Table::PURCHASABLES_STORES, 'allowOutOfStockPurchases')) { 19 | $this->addColumn(Table::PURCHASABLES_STORES, 'allowOutOfStockPurchases', $this->boolean()->after('inventoryTracked')->notNull()->defaultValue(false)); 20 | } 21 | 22 | return true; 23 | } 24 | 25 | /** 26 | * @inheritdoc 27 | */ 28 | public function safeDown(): bool 29 | { 30 | echo "m241219_071723_add_inventory_backorder cannot be reverted.\n"; 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/migrations/m250128_083515_add_make_primary_addresses_to_orders.php: -------------------------------------------------------------------------------- 1 | addColumn(Table::ORDERS, 'makePrimaryShippingAddress', $this->boolean()->defaultValue(false)->after('saveShippingAddressOnOrderComplete')); 19 | $this->addColumn(Table::ORDERS, 'makePrimaryBillingAddress', $this->boolean()->defaultValue(false)->after('saveBillingAddressOnOrderComplete')); 20 | 21 | return true; 22 | } 23 | 24 | /** 25 | * @inheritdoc 26 | */ 27 | public function safeDown(): bool 28 | { 29 | echo "m250128_083515_add_make_primary_addresses_to_orders cannot be reverted.\n"; 30 | return false; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/migrations/m250210_125139_fix_cart_recalculation_modes.php: -------------------------------------------------------------------------------- 1 | update(Table::ORDERS, ['recalculationMode' => Order::RECALCULATION_MODE_ALL], [ 20 | 'recalculationMode' => Order::RECALCULATION_MODE_NONE, 21 | 'isCompleted' => false, 22 | ], [], false); 23 | 24 | return true; 25 | } 26 | 27 | /** 28 | * @inheritdoc 29 | */ 30 | public function safeDown(): bool 31 | { 32 | echo "m250210_125139_fix_cart_recalculation_modes cannot be reverted.\n"; 33 | return false; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/models/inventory/InventoryTransferMovement.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 2.0 19 | */ 20 | abstract class BasePaymentForm extends Model 21 | { 22 | public bool $savePaymentSource = false; 23 | 24 | /** 25 | * Populate the payment form from a payment form. 26 | * 27 | * @param PaymentSource $paymentSource the source to ue 28 | * @throws NotSupportedException if not supported by current gateway. 29 | */ 30 | public function populateFromPaymentSource(PaymentSource $paymentSource): void 31 | { 32 | throw new NotSupportedException(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/models/payments/DummyPaymentForm.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class DummyPaymentForm extends CreditCardPaymentForm 19 | { 20 | public function populateFromPaymentSource(PaymentSource $paymentSource): void 21 | { 22 | $this->token = (string)$paymentSource->id; 23 | } 24 | 25 | /** 26 | * @inheritdoc 27 | */ 28 | protected function defineRules(): array 29 | { 30 | if ($this->token) { 31 | return []; //No validation of form if using a token 32 | } 33 | 34 | return parent::defineRules(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/models/payments/OffsitePaymentForm.php: -------------------------------------------------------------------------------- 1 | 14 | * @since 2.0 15 | */ 16 | class OffsitePaymentForm extends BasePaymentForm 17 | { 18 | } 19 | -------------------------------------------------------------------------------- /src/models/subscriptions/CancelSubscriptionForm.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class CancelSubscriptionForm extends Model 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/models/subscriptions/DummyPlan.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class DummyPlan extends Plan 20 | { 21 | /** 22 | * @inheritdoc 23 | * TODO: Fix typo in next major release currentPlant -> currentPlan 24 | */ 25 | public function canSwitchFrom(PlanInterface $currentPlant): bool 26 | { 27 | return true; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/models/subscriptions/SubscriptionForm.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class SubscriptionForm extends Model 19 | { 20 | /** 21 | * Trial days for the subscription. 22 | * 23 | * @var int 24 | */ 25 | public int $trialDays = 0; 26 | 27 | /** 28 | * @inheritdoc 29 | */ 30 | protected function defineRules(): array 31 | { 32 | return [ 33 | [['trialDays'], 'integer', 'integerOnly' => true, 'min' => 0], 34 | ]; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/models/subscriptions/SwitchPlansForm.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class SwitchPlansForm extends Model 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/plugin/Variables.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | trait Variables 20 | { 21 | /** 22 | * Returns the donation purchasable 23 | * 24 | * @return Donation|null The donation purchasable 25 | */ 26 | public function getDonation(): ?Donation 27 | { 28 | return Donation::find()->status(null)->one(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/records/Coupon.php: -------------------------------------------------------------------------------- 1 | 22 | * @since 4.0 23 | */ 24 | class Coupon extends ActiveRecord 25 | { 26 | /** 27 | * @inheritdoc 28 | */ 29 | public static function tableName(): string 30 | { 31 | return Table::COUPONS; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/records/Donation.php: -------------------------------------------------------------------------------- 1 | 24 | * @since 2.0 25 | */ 26 | class Donation extends ActiveRecord 27 | { 28 | /** 29 | * @inheritdoc 30 | */ 31 | public static function tableName(): string 32 | { 33 | return Table::DONATIONS; 34 | } 35 | 36 | public function getElement(): ActiveQueryInterface 37 | { 38 | return $this->hasOne(Element::class, ['id', 'id']); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/records/Gateway.php: -------------------------------------------------------------------------------- 1 | 28 | * @since 2.0 29 | */ 30 | class Gateway extends ActiveRecord 31 | { 32 | /** 33 | * @inheritdoc 34 | */ 35 | public static function tableName(): string 36 | { 37 | return Table::GATEWAYS; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/records/InventoryLocation.php: -------------------------------------------------------------------------------- 1 | ['handle']], 34 | ]; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/records/OrderNotice.php: -------------------------------------------------------------------------------- 1 | 24 | * @since 3.3 25 | */ 26 | class OrderNotice extends ActiveRecord 27 | { 28 | /** 29 | * @inheritdoc 30 | */ 31 | public static function tableName(): string 32 | { 33 | return Table::ORDERNOTICES; 34 | } 35 | 36 | public function getOrder(): ActiveQueryInterface 37 | { 38 | return $this->hasOne(Order::class, ['id' => 'orderId']); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/records/PaymentCurrency.php: -------------------------------------------------------------------------------- 1 | 22 | * @since 2.0 23 | */ 24 | class PaymentCurrency extends ActiveRecord 25 | { 26 | /** 27 | * @inheritdoc 28 | */ 29 | public static function tableName(): string 30 | { 31 | return Table::PAYMENTCURRENCIES; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/records/ShippingCategory.php: -------------------------------------------------------------------------------- 1 | 25 | * @since 2.0 26 | */ 27 | class ShippingCategory extends ActiveRecord 28 | { 29 | use SoftDeleteTrait; 30 | use StoreRecordTrait; 31 | 32 | /** 33 | * @inheritdoc 34 | */ 35 | public static function tableName(): string 36 | { 37 | return Table::SHIPPINGCATEGORIES; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/records/ShippingZone.php: -------------------------------------------------------------------------------- 1 | 23 | * @since 2.0 24 | */ 25 | class ShippingZone extends ActiveRecord 26 | { 27 | use StoreRecordTrait; 28 | 29 | /** 30 | * @inheritdoc 31 | */ 32 | public static function tableName(): string 33 | { 34 | return Table::SHIPPINGZONES; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/records/SiteStore.php: -------------------------------------------------------------------------------- 1 | 20 | * @since 4.0 21 | */ 22 | class SiteStore extends ActiveRecord 23 | { 24 | use StoreRecordTrait; 25 | 26 | /** 27 | * @inheritDoc 28 | */ 29 | public static function primaryKey(): array 30 | { 31 | return ['siteId']; 32 | } 33 | 34 | /** 35 | * @inheritdoc 36 | */ 37 | public static function tableName(): string 38 | { 39 | return Table::SITESTORES; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/records/TaxCategory.php: -------------------------------------------------------------------------------- 1 | 23 | * @since 2.0 24 | */ 25 | class TaxCategory extends ActiveRecord 26 | { 27 | use SoftDeleteTrait; 28 | 29 | public static function tableName(): string 30 | { 31 | return Table::TAXCATEGORIES; 32 | } 33 | 34 | /** 35 | * @inheritdoc 36 | */ 37 | public function rules(): array 38 | { 39 | return [ 40 | [['handle'], 'required'], 41 | ]; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/records/TaxZone.php: -------------------------------------------------------------------------------- 1 | 24 | * @since 2.0 25 | */ 26 | class TaxZone extends ActiveRecord 27 | { 28 | use StoreRecordTrait; 29 | 30 | /** 31 | * @inheritdoc 32 | */ 33 | public static function tableName(): string 34 | { 35 | return Table::TAXZONES; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/records/Transfer.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 3.0 18 | */ 19 | class AverageOrderTotal extends Stat 20 | { 21 | /** 22 | * @inheritdoc 23 | */ 24 | protected string $_handle = 'averageOrderTotal'; 25 | 26 | /** 27 | * @inheritDoc 28 | */ 29 | public function getData(): string|int|bool|null 30 | { 31 | $query = $this->_createStatQuery(); 32 | $query->select([new Expression('ROUND(SUM([[total]]) / COUNT([[orders.id]]), 4) as averageOrderTotal')]); 33 | 34 | return $query->scalar(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/stats/NewCustomers.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 3.0 18 | */ 19 | class NewCustomers extends Stat 20 | { 21 | /** 22 | * @inheritdoc 23 | */ 24 | protected string $_handle = 'newCustomers'; 25 | 26 | /** 27 | * @inheritDoc 28 | */ 29 | public function getData(): string|int|bool|null 30 | { 31 | $query = $this->_createStatQuery(); 32 | $query->select([new Expression('COUNT(DISTINCT [[customerId]]) as newCustomers')]); 33 | 34 | return $query->scalar(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/templates/_components/elementactions/DownloadOrderPdf/trigger.twig: -------------------------------------------------------------------------------- 1 |
{{ 'Download PDF…'|t('commerce') }}
-------------------------------------------------------------------------------- /src/templates/_components/widgets/_includes/_orderStatusesField.twig: -------------------------------------------------------------------------------- 1 | {# Date Range picker JS field #} 2 | {% import "_includes/forms" as forms %} 3 | {% set id = id is not defined ? null : id %} 4 | {% set widget = widget is not defined ? null : widget %} 5 | 6 | {% if not id %} 7 |

{{ 'An ID must be provided'|t('commerce') }}

8 | {% else %} 9 | {{ forms.selectizeField({ 10 | label: 'Order Statuses'|t('commerce'), 11 | instructions: 'Only orders with the following order statuses will be included. Leave blank to include all statuses.'|t('commerce'), 12 | id: 'orderStatuses', 13 | name: 'orderStatuses', 14 | options : orderStatuses, 15 | values : widget.orderStatuses, 16 | errors: widget.getErrors('orderStatuses') ?? null, 17 | containerAttributes: {class: 'selectize fullwidth multiselect order-status-multiselect'}, 18 | multi: true 19 | }) }} 20 | {% endif %} 21 | -------------------------------------------------------------------------------- /src/templates/_components/widgets/customers/new/body.twig: -------------------------------------------------------------------------------- 1 |
2 | {% apply spaceless %} 3 | {{ number ? number : 0 }}
4 | {{ 'new customers'|t('commerce')|e }}
5 | {{ timeFrame|e }} 6 | {% endapply %} 7 |
-------------------------------------------------------------------------------- /src/templates/_components/widgets/customers/new/settings.twig: -------------------------------------------------------------------------------- 1 | {% import "_includes/forms" as forms %} 2 | 3 |
4 | {% include 'commerce/_components/widgets/_includes/_storeField' with { id: namespaceId, widget: widget, updateOrderStatuses: true } %} 5 | 6 | {% include 'commerce/_components/widgets/_includes/_dateRangeField' with { id: namespaceId, widget: widget } %} 7 | 8 | {% include 'commerce/_components/widgets/_includes/_orderStatusesField' with { id: namespaceId, widget: widget } %} 9 |
-------------------------------------------------------------------------------- /src/templates/_components/widgets/customers/repeat/body.twig: -------------------------------------------------------------------------------- 1 |
2 | {% apply spaceless %} 3 | {{ numbers['percentage'] ?? 0 }}%
4 | {{ 'repeat customers'|t('commerce')|e }}
5 | {{ timeFrame|e }} 6 | {% endapply %} 7 |
-------------------------------------------------------------------------------- /src/templates/_components/widgets/customers/repeat/settings.twig: -------------------------------------------------------------------------------- 1 | {% import "_includes/forms" as forms %} 2 | 3 |
4 | {% include 'commerce/_components/widgets/_includes/_storeField' with { id: namespaceId, widget: widget, updateOrderStatuses: true } %} 5 | 6 | {% include 'commerce/_components/widgets/_includes/_dateRangeField' with { id: namespaceId, widget: widget } %} 7 | 8 | {% include 'commerce/_components/widgets/_includes/_orderStatusesField' with { id: namespaceId, widget: widget } %} 9 |
-------------------------------------------------------------------------------- /src/templates/_components/widgets/customers/top/body.twig: -------------------------------------------------------------------------------- 1 | {% do view.registerTranslations('commerce', [ 2 | 'Email', 3 | ]) %} 4 |
5 |
6 |
7 | 8 | {% set tableData = [] %} 9 | {% for stat in stats %} 10 | {% set tableData = tableData|merge([{ 11 | title: stat.email, 12 | url: stat.customer is defined and stat.customer ? stat.customer.getCpEditUrl() : '', 13 | total: stat.total|commerceCurrency(craft.commerce.paymentCurrencies.getPrimaryPaymentCurrencyIso()), 14 | average: stat.average|commerceCurrency(craft.commerce.paymentCurrencies.getPrimaryPaymentCurrencyIso()), 15 | }]) %} 16 | {% endfor %} 17 | 18 | {% js %} 19 | var columns = [ 20 | { name: '__slot:title', title: Craft.escapeHtml(Craft.t('commerce', 'Email')) }, 21 | { name: '{{ type }}', title: '{{ typeLabel|e }}' } 22 | ]; 23 | 24 | new Craft.VueAdminTable({ 25 | columns: columns, 26 | container: '#{{ id }}', 27 | tableData: {{ tableData|json_encode|raw }} 28 | }); 29 | {% endjs %} -------------------------------------------------------------------------------- /src/templates/_components/widgets/customers/top/settings.twig: -------------------------------------------------------------------------------- 1 | {% import "_includes/forms" as forms %} 2 | 3 |
4 | {% include 'commerce/_components/widgets/_includes/_storeField' with { id: namespaceId, widget: widget, updateOrderStatuses: true } %} 5 | 6 | {% include 'commerce/_components/widgets/_includes/_dateRangeField' with { id: namespaceId, widget: widget } %} 7 | 8 | {{ forms.selectField({ 9 | label: 'Type'|t('commerce'), 10 | id: 'type', 11 | name: 'type', 12 | value: widget.type, 13 | options: typeOptions 14 | }) }} 15 | 16 | {% include 'commerce/_components/widgets/_includes/_orderStatusesField' with { id: namespaceId, widget: widget } %} 17 |
-------------------------------------------------------------------------------- /src/templates/_components/widgets/orders/average/body.twig: -------------------------------------------------------------------------------- 1 |
2 | {% apply spaceless %} 3 | {{ (number ?? 0)|commerceCurrency(craft.commerce.paymentCurrencies.getPrimaryPaymentCurrencyIso()) }}
4 | {{ 'average order total'|t('commerce')|e }}
5 | {{ timeFrame|e }} 6 | {% endapply %} 7 |
-------------------------------------------------------------------------------- /src/templates/_components/widgets/orders/average/settings.twig: -------------------------------------------------------------------------------- 1 | {% import "_includes/forms" as forms %} 2 | 3 |
4 | {% include 'commerce/_components/widgets/_includes/_storeField' with { id: namespaceId, widget: widget, updateOrderStatuses: true } %} 5 | 6 | {% include 'commerce/_components/widgets/_includes/_dateRangeField' with { id: namespaceId, widget: widget } %} 7 | 8 | {% include 'commerce/_components/widgets/_includes/_orderStatusesField' with { id: namespaceId, widget: widget } %} 9 |
-------------------------------------------------------------------------------- /src/templates/_components/widgets/orders/country/body.twig: -------------------------------------------------------------------------------- 1 | {% do view.registerTranslations('commerce', [ 2 | 'Order count' 3 | ]) %} 4 |
5 | 6 |
7 | {% js %} 8 | var revChart = new Craft.Commerce.Chart('{{ namespaceId }}', { 9 | chart: { 10 | type: 'doughnut', 11 | data: { 12 | labels: {{ labels|json_encode|raw }}, 13 | datasets: [ 14 | { 15 | label: Craft.escapeHtml(Craft.t('commerce', 'Order count')), 16 | data: {{ totalOrders|json_encode|raw }} 17 | } 18 | ] 19 | } 20 | } 21 | }); 22 | 23 | {% endjs %} -------------------------------------------------------------------------------- /src/templates/_components/widgets/orders/country/settings.twig: -------------------------------------------------------------------------------- 1 | {% import "_includes/forms" as forms %} 2 | 3 |
4 | {% include 'commerce/_components/widgets/_includes/_storeField' with { id: namespaceId, widget: widget, updateOrderStatuses: true } %} 5 | 6 | {% include 'commerce/_components/widgets/_includes/_dateRangeField' with { id: namespaceId, widget: widget } %} 7 | 8 | {{ forms.selectField({ 9 | label: 'Type'|t('commerce'), 10 | id: 'type', 11 | name: 'type', 12 | value: widget.type, 13 | options: typeOptions 14 | }) }} 15 | 16 | {% include 'commerce/_components/widgets/_includes/_orderStatusesField' with { id: namespaceId, widget: widget } %} 17 |
-------------------------------------------------------------------------------- /src/templates/_components/widgets/orders/recent/settings.twig: -------------------------------------------------------------------------------- 1 | {% import "_includes/forms" as forms %} 2 | 3 |
4 | {% include 'commerce/_components/widgets/_includes/_storeField' with { id: namespaceId, widget: widget, updateOrderStatuses: true } %} 5 | 6 | {% include 'commerce/_components/widgets/_includes/_orderStatusesField' with { id: namespaceId, widget: widget } %} 7 | 8 | {{ forms.textField({ 9 | label: "Limit"|t('commerce'), 10 | name: 'limit', 11 | value: widget.limit, 12 | size: 2, 13 | errors: widget.getErrors('limit') 14 | }) }} 15 | 16 |
17 | -------------------------------------------------------------------------------- /src/templates/_components/widgets/orders/revenue/settings.twig: -------------------------------------------------------------------------------- 1 | {% import '_includes/forms' as forms %} 2 |
3 | {% include 'commerce/_components/widgets/_includes/_storeField' with { id: namespaceId, widget: widget, updateOrderStatuses: true } %} 4 | 5 | {% include 'commerce/_components/widgets/_includes/_dateRangeField' with { id: namespaceId, widget: widget } %} 6 | 7 | {{ forms.lightswitchField({ 8 | label: 'Show Order Count?'|t('commerce'), 9 | id: 'showOrderCount', 10 | name: 'showOrderCount', 11 | value: 1, 12 | on: widget.showOrderCount, 13 | instructions: 'Show order count line on chart.'|t('commerce') 14 | }) }} 15 | 16 | {{ forms.selectField({ 17 | label: 'Total'|t('commerce'), 18 | name: 'type', 19 | id: 'type', 20 | options: types, 21 | value: widget.type, 22 | }) }} 23 | 24 | {% include 'commerce/_components/widgets/_includes/_orderStatusesField' with { id: namespaceId, widget: widget } %} 25 |
-------------------------------------------------------------------------------- /src/templates/_components/widgets/orders/total/settings.twig: -------------------------------------------------------------------------------- 1 | {% import "_includes/forms" as forms %} 2 | 3 |
4 | {% include 'commerce/_components/widgets/_includes/_storeField' with { id: namespaceId, widget: widget, updateOrderStatuses: true } %} 5 | 6 | {% include 'commerce/_components/widgets/_includes/_dateRangeField' with { id: namespaceId, widget: widget } %} 7 | 8 | {{ forms.lightswitchField({ 9 | label: "Show Chart?"|t('commerce'), 10 | id: 'showChart', 11 | name: 'showChart', 12 | value: 1, 13 | on: widget.showChart 14 | }) }} 15 | 16 | {% include 'commerce/_components/widgets/_includes/_orderStatusesField' with { id: namespaceId, widget: widget } %} 17 |
-------------------------------------------------------------------------------- /src/templates/_components/widgets/producttypes/top/body.twig: -------------------------------------------------------------------------------- 1 | {% do view.registerTranslations('commerce', [ 2 | 'Name', 3 | ]) %} 4 | 5 |
6 |
7 |
8 | 9 | {% set tableData = [] %} 10 | {% for stat in stats %} 11 | {% set tableData = tableData|merge([{ 12 | title: (stat.productType ? stat.productType.name : stat.name), 13 | qty: stat.qty, 14 | revenue: stat.revenue|commerceCurrency(craft.commerce.paymentCurrencies.getPrimaryPaymentCurrencyIso()), 15 | }]) %} 16 | {% endfor %} 17 | 18 | {% js %} 19 | var columns = [ 20 | { name: '__slot:title', title: Craft.escapeHtml(Craft.t('commerce', 'Name')) }, 21 | { name: '{{ type }}', title: '{{ typeLabel|e }}' } 22 | ]; 23 | 24 | new Craft.VueAdminTable({ 25 | columns: columns, 26 | container: '#{{ id }}', 27 | tableData: {{ tableData|json_encode|raw }} 28 | }); 29 | {% endjs %} 30 | -------------------------------------------------------------------------------- /src/templates/_components/widgets/producttypes/top/settings.twig: -------------------------------------------------------------------------------- 1 | {% import "_includes/forms" as forms %} 2 | 3 |
4 | {% include 'commerce/_components/widgets/_includes/_storeField' with { id: namespaceId, widget: widget, updateOrderStatuses: true } %} 5 | 6 | {% include 'commerce/_components/widgets/_includes/_dateRangeField' with { id: namespaceId, widget: widget } %} 7 | 8 | {{ forms.selectField({ 9 | label: 'Type'|t('commerce'), 10 | id: 'type', 11 | name: 'type', 12 | value: widget.type, 13 | options: typeOptions 14 | }) }} 15 | 16 | {% include 'commerce/_components/widgets/_includes/_orderStatusesField' with { id: namespaceId, widget: widget } %} 17 |
-------------------------------------------------------------------------------- /src/templates/_components/widgets/purchasables/top/body.twig: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | {% set tableData = [] %} 6 | {% for stat in stats %} 7 | {% set tableData = tableData|merge([{ 8 | title: (stat[nameField] ?? stat.description), 9 | qty: stat.qty, 10 | revenue: stat.revenue|commerceCurrency(craft.commerce.paymentCurrencies.getPrimaryPaymentCurrencyIso()), 11 | }]) %} 12 | {% endfor %} 13 | 14 | {% js %} 15 | var columns = [ 16 | { name: '__slot:title', title: '{{ nameFieldLabel|e }}' }, 17 | { name: '{{ type }}', title: '{{ typeLabel|e }}' } 18 | ]; 19 | 20 | new Craft.VueAdminTable({ 21 | columns: columns, 22 | container: '#{{ id }}', 23 | tableData: {{ tableData|json_encode|raw }} 24 | }); 25 | {% endjs %} -------------------------------------------------------------------------------- /src/templates/_components/widgets/purchasables/top/settings.twig: -------------------------------------------------------------------------------- 1 | {% import "_includes/forms" as forms %} 2 | 3 |
4 | {% include 'commerce/_components/widgets/_includes/_storeField' with { id: namespaceId, widget: widget, updateOrderStatuses: true } %} 5 | 6 | {% include 'commerce/_components/widgets/_includes/_dateRangeField' with { id: namespaceId, widget: widget } %} 7 | 8 | {{ forms.selectField({ 9 | label: 'Name Field'|t('commerce'), 10 | id: 'nameField', 11 | name: 'nameField', 12 | value: widget.nameField, 13 | options: nameFieldOptions, 14 | instructions: 'Which data to display in the name column in the results table.'|t('commerce') 15 | }) }} 16 | 17 | {{ forms.selectField({ 18 | label: 'Type'|t('commerce'), 19 | id: 'type', 20 | name: 'type', 21 | value: widget.type, 22 | options: typeOptions 23 | }) }} 24 | 25 | {% include 'commerce/_components/widgets/_includes/_orderStatusesField' with { id: namespaceId, widget: widget } %} 26 |
-------------------------------------------------------------------------------- /src/templates/_data/data.tsv: -------------------------------------------------------------------------------- 1 | date close 2 | 1-Nov-15 99.00 3 | 30-Oct-15 198.00 4 | 27-Oct-15 99.00 5 | 26-Oct-15 198.00 6 | 25-Oct-15 99.00 7 | 24-Oct-15 297.00 8 | 23-Oct-15 0.00 -------------------------------------------------------------------------------- /src/templates/_data/tsv.tsv: -------------------------------------------------------------------------------- 1 | {{ data|raw }} -------------------------------------------------------------------------------- /src/templates/_includes/_storeManagementNav.twig: -------------------------------------------------------------------------------- 1 | {% set storeSettingsNav = storeSettingsNav is defined ? storeSettingsNav : [] %} 2 | {% set store = store is defined ? store : null %} 3 | {% set selectedItem = selectedItem is defined ? selectedItem : null %} 4 | 5 | {% if store and storeSettingsNav|length %} 6 | 25 | {% endif %} -------------------------------------------------------------------------------- /src/templates/_includes/forms/inventoryLocationSelect.twig: -------------------------------------------------------------------------------- 1 | {% include '_includes/forms/componentSelect.twig' with { 2 | options: options ?? craft.commerce.inventoryLocations.getAllInventoryLocations().all(), 3 | createAction: (create ?? false) ? 'commerce/inventory-locations/edit' : null, 4 | } %} 5 | -------------------------------------------------------------------------------- /src/templates/_includes/orders/address.twig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftcms/commerce/b7ef900ecefcf697c7cb7e232b9aa3e486db4690/src/templates/_includes/orders/address.twig -------------------------------------------------------------------------------- /src/templates/_includes/settings.twig: -------------------------------------------------------------------------------- 1 | {% macro indexInlineList(things) %} 2 | {{ things|slice(0, 3)|join(', ') }} 3 | {%- if things|length > 3 -%} 4 | , {{ "{number} more…"|t('commerce', { number: things|length - 3 }) }} 6 | {% endif %} 7 | {% endmacro %} 8 | -------------------------------------------------------------------------------- /src/templates/_layouts/cp.twig: -------------------------------------------------------------------------------- 1 | {# @var craft \craft\web\twig\variables\CraftVariable #} 2 | {% extends "_layouts/cp" %} 3 | {% set bodyClass = (bodyClass is defined ? bodyClass~' ' : '') ~ "commerce" %} 4 | -------------------------------------------------------------------------------- /src/templates/gateways/manualGatewaySettings.twig: -------------------------------------------------------------------------------- 1 | {% from "_includes/forms" import booleanMenuField %} 2 | 3 | {{ booleanMenuField({ 4 | label: "Only allow this gateway to be used for zero value orders?"|t('commerce'), 5 | name: 'onlyAllowForZeroPriceOrders', 6 | includeEnvVars: true, 7 | errors: gateway.getErrors('onlyAllowForZeroPriceOrders'), 8 | value: gateway.getOnlyAllowForZeroPriceOrders(false), 9 | }) }} -------------------------------------------------------------------------------- /src/templates/inventory-locations/_deleteModal.twig: -------------------------------------------------------------------------------- 1 | {% import '_includes/forms' as forms %} 2 | 3 |

{{ "Deleting the {location} location."|t('commerce', { location : deactivateInventoryLocation.inventoryLocation.name }) }}

4 | 5 |
6 | 7 | {{ forms.selectField({ 8 | label: "Destination Inventory Location"|t('commerce'), 9 | instructions: "Choose the destination inventory location for the existing on hand stock."|t('commerce'), 10 | options: inventoryLocationOptions, 11 | id: 'destinationInventoryLocation', 12 | value: deactivateInventoryLocation.destinationInventoryLocation.id, 13 | name: 'destinationInventoryLocation' 14 | }) }} 15 | 16 | {{ hiddenInput('inventoryLocation', deactivateInventoryLocation.inventoryLocation.id) }} -------------------------------------------------------------------------------- /src/templates/inventory-locations/_edit.twig: -------------------------------------------------------------------------------- 1 | {% namespace 'inventoryLocationAddress' %} 2 | {{ form.render()|raw }} 3 | {% endnamespace %} 4 | 5 | {% hook "cp.commerce.inventoryLocation.edit" %} 6 | 7 | {% if not inventoryLocation.id %} 8 | {% js "new Craft.HandleGenerator('##{'name'|namespaceInputId}', '##{'handle'|namespaceInputId}');" %} 9 | {% endif %} -------------------------------------------------------------------------------- /src/templates/inventory-locations/_sidebar.twig: -------------------------------------------------------------------------------- 1 | {% if inventoryLocation and inventoryLocation.id %} 2 |
3 |
4 |
{{ "Created at"|t('app') }}
5 |
{{ inventoryLocation.dateCreated|datetime('short') }}
6 |
7 |
8 |
{{ "Updated at"|t('app') }}
9 |
{{ inventoryLocation.dateUpdated|datetime('short') }}
10 |
11 |
12 | {% endif %} -------------------------------------------------------------------------------- /src/templates/inventory/levels/_index.twig: -------------------------------------------------------------------------------- 1 | {% do view.registerTranslations('commerce', [ 2 | 'Search inventory', 3 | ]) %} 4 | 5 | {% set selectedSubnavItem = "inventory" %} 6 | {% set title = 'Manage Inventory'|t('commerce') %} 7 | 8 | {% block content %} 9 |
10 | 11 | {% hook "cp.commerce.inventory.index" %} 12 | {% endblock %} 13 | 14 | {% js %} 15 | 16 | new Craft.Commerce.InventoryLevelsManager('#inventory-levels',{ 17 | inventoryLocationId: '{{ currentLocation.id }}', 18 | inventoryItemId: {{ inventoryItemId ? inventoryItemId : 'null'}}, 19 | }); 20 | {% endjs %} -------------------------------------------------------------------------------- /src/templates/inventory/levels/_unfulfilledOrdersModal.twig: -------------------------------------------------------------------------------- 1 | {% import '_includes/forms' as forms %} 2 | 3 |
4 |

{{ title }}

5 | {% for order in orders %} 6 | {{ order.getLink(order.reference, { 'data-icon': 'external', target: '_blank' }) }}
7 | {% endfor %} 8 |
-------------------------------------------------------------------------------- /src/templates/inventory/transfers/_index.twig: -------------------------------------------------------------------------------- 1 | {% extends '_layouts/elementindex' %} 2 | {% set title = 'Transfers'|t('app') %} 3 | {% set elementType = 'craft\\commerce\\elements\\Transfer' %} 4 | {% set canHaveDrafts = true %} 5 | {% set selectedSubnavItem = "inventory-transfers" %} 6 | {% set crumbs = [ 7 | { label: 'Commerce'|t('commerce'), url: url('commerce') }, 8 | ] %} 9 | 10 | {% block actionButton %} 11 | {{ tag('a', { 12 | class: 'btn submit add icon', 13 | href: actionUrl('elements/create', { 14 | elementType: elementType 15 | }), 16 | text: 'New transfer'|t('commerce'), 17 | }) }} 18 | {% endblock %} -------------------------------------------------------------------------------- /src/templates/orders/_paymentForms.twig: -------------------------------------------------------------------------------- 1 | {% import "_includes/forms" as forms %} 2 | 3 |
4 | {% set paymentFormOptions = [{ label: "Select a gateway"|t('commerce') }] %} 5 | 6 | {% for gateway in gateways %} 7 | {% set paymentFormOptions = paymentFormOptions|merge([{ label: gateway.name, value: gateway.id }]) %} 8 | {% endfor %} 9 | 10 | {{ forms.selectField({ 11 | id: 'payment-form-select', 12 | label: "Payment Method"|t('commerce'), 13 | name: 'gatewayId', 14 | options: paymentFormOptions, 15 | value: order.gatewayId, 16 | class: 'payment-form-select' 17 | }) }} 18 | 19 | {{ paymentForms|raw }} 20 |
21 | -------------------------------------------------------------------------------- /src/templates/orders/_paymentmodal.twig: -------------------------------------------------------------------------------- 1 |
2 | {% include 'commerce/orders/_paymentForms' %} 3 |
4 | -------------------------------------------------------------------------------- /src/templates/orders/includes/_capture.twig: -------------------------------------------------------------------------------- 1 | {% if currentUser.can('commerce-capturePayment') and transaction.canCapture() %} 2 |
3 | {{ csrfInput() }} 4 | {{ 'Capture'|t('commerce') }} 10 |
11 | {% endif %} -------------------------------------------------------------------------------- /src/templates/prices/_polling.twig: -------------------------------------------------------------------------------- 1 | {% if areCatalogPricingJobsRunning %} 2 |

{{ 'Pricing jobs are currently running.'|t('commerce') }}

3 | {% endif %} -------------------------------------------------------------------------------- /src/templates/prices/_status.twig: -------------------------------------------------------------------------------- 1 |
7 |
{% include 'commerce/prices/_polling' %}
8 |
9 | 10 |
11 |
-------------------------------------------------------------------------------- /src/templates/products/_index.twig: -------------------------------------------------------------------------------- 1 | {% extends "_layouts/elementindex" %} 2 | {% set title = "Products"|t('commerce') %} 3 | {% set docTitle = title~' - '~'Commerce' %} 4 | {% set elementType = 'craft\\commerce\\elements\\Product' %} 5 | {% set selectedTab = 'products' %} 6 | {% set selectedSubnavItem = "products" %} 7 | 8 | {% if productTypeHandle is defined %} 9 | {% js %} 10 | window.defaultProductTypeHandle = '{{ productTypeHandle }}'; 11 | {% endjs %} 12 | {% endif %} 13 | -------------------------------------------------------------------------------- /src/templates/promotions/index.twig: -------------------------------------------------------------------------------- 1 | {% redirect 'commerce/promotions/sales' %} 2 | -------------------------------------------------------------------------------- /src/templates/settings/emails/_previewError.twig: -------------------------------------------------------------------------------- 1 | {{ 'Can’t preview this email.'|t('commerce') }} 2 | {% for error in errors %} 3 |
  • {{ error }}
  • 4 | {% endfor %} 5 | -------------------------------------------------------------------------------- /src/templates/settings/index.twig: -------------------------------------------------------------------------------- 1 | {% if currentUser.admin %} 2 | {% redirect 'commerce/settings/general' %} 3 | {% endif %} -------------------------------------------------------------------------------- /src/templates/settings/ordersettings/_edit.twig: -------------------------------------------------------------------------------- 1 | {% extends "commerce/_layouts/settings" %} 2 | 3 | {% set selectedTab = 'settings' %} 4 | {% import "_includes/forms" as forms %} 5 | 6 | {% set crumbs = [ 7 | { label: 'Commerce'|t('commerce'), url: url('commerce') }, 8 | ] %} 9 | 10 | {% set fullPageForm = true %} 11 | 12 | {% if readOnly %} 13 | {% set contentNotice = readOnlyNotice() %} 14 | {% endif %} 15 | 16 | {% block content %} 17 | 18 | {{ redirectInput('commerce/settings/ordersettings') }} 19 | 20 | {{ csrfInput() }} 21 | 22 | {{ forms.fieldLayoutDesignerField({ 23 | fieldLayout: fieldLayout, 24 | disabled: readOnly, 25 | withCardViewDesigner: true, 26 | }) }} 27 | {% endblock %} 28 | -------------------------------------------------------------------------------- /src/templates/settings/subscriptions/_edit.twig: -------------------------------------------------------------------------------- 1 | {% extends "commerce/_layouts/settings" %} 2 | 3 | {% import "_includes/forms" as forms %} 4 | 5 | {% set selectedItem = 'subscriptions' %} 6 | 7 | {% set crumbs = [ 8 | { label: 'Commerce'|t('commerce'), url: url('commerce') }, 9 | ] %} 10 | 11 | {% set fullPageForm = not readOnly %} 12 | 13 | {% if readOnly %} 14 | {% set contentNotice = readOnlyNotice() %} 15 | {% endif %} 16 | 17 | {% block content %} 18 | {% if not readOnly %} 19 | {{ actionInput('commerce/settings/save-subscription-settings') }} 20 | {{ csrfInput() }} 21 | {% endif %} 22 | {{ redirectInput('commerce/settings/subscriptions') }} 23 | 24 | {{ forms.fieldLayoutDesignerField({ 25 | fieldLayout: fieldLayout, 26 | withCardViewDesigner: true, 27 | disabled: readOnly, 28 | }) }} 29 | 30 | {% endblock %} 31 | -------------------------------------------------------------------------------- /src/templates/settings/transfers/_edit.twig: -------------------------------------------------------------------------------- 1 | {% extends "commerce/_layouts/settings" %} 2 | 3 | {% import "_includes/forms" as forms %} 4 | 5 | {% set selectedItem = 'transfers' %} 6 | 7 | {% set crumbs = [ 8 | { label: 'Commerce'|t('commerce'), url: url('commerce') }, 9 | ] %} 10 | 11 | {% set fullPageForm = not readOnly %} 12 | 13 | {% if readOnly %} 14 | {% set contentNotice = readOnlyNotice() %} 15 | {% endif %} 16 | 17 | {% block content %} 18 | {% if not readOnly %} 19 | {{ actionInput('commerce/settings/save-transfer-settings') }} 20 | {{ csrfInput() }} 21 | {% endif %} 22 | {{ redirectInput('commerce/settings/transfers') }} 23 | 24 | {{ forms.fieldLayoutDesignerField({ 25 | fieldLayout: fieldLayout, 26 | withCardViewDesigner: true, 27 | disabled: readOnly, 28 | }) }} 29 | 30 | 31 | {% endblock %} 32 | -------------------------------------------------------------------------------- /src/templates/store-management/index.twig: -------------------------------------------------------------------------------- 1 | {% extends "commerce/_layouts/store-management" %} 2 | 3 | {% block content %} 4 | {{ 'No access given to any specific store management features.'|t('commerce') }} 5 | {% endblock %} -------------------------------------------------------------------------------- /src/templates/store-management/shipping/index.twig: -------------------------------------------------------------------------------- 1 | {% redirect 'commerce/shipping/shippingmethods' %} 2 | -------------------------------------------------------------------------------- /src/templates/subscriptions/_index.twig: -------------------------------------------------------------------------------- 1 | {% extends "_layouts/elementindex" %} 2 | 3 | {% set title = "Subscriptions"|t('commerce') %} 4 | {% set docTitle = title~' - '~'Commerce' %} 5 | {% set elementType = 'craft\\commerce\\elements\\Subscription' %} 6 | {% set selectedTab = 'subscriptions' %} 7 | {% set selectedSubnavItem = "subscriptions" %} 8 | {% set bodyClass = (bodyClass is defined ? bodyClass~' ' : '') ~ "commercesubscriptions commercesubscriptionsindex" %} 9 | 10 | {% set crumbs = [ 11 | { label: 'Commerce'|t('commerce'), url: url('commerce') }, 12 | ] %} 13 | 14 | {% js %} 15 | if (typeof Craft.Commerce === 'undefined') { 16 | Craft.Commerce = {}; 17 | } 18 | 19 | {% endjs %} 20 | -------------------------------------------------------------------------------- /src/templates/variants/_index.twig: -------------------------------------------------------------------------------- 1 | {% extends "_layouts/elementindex" %} 2 | 3 | {% set title = "Product Variants"|t('commerce') %} 4 | {% set docTitle = title~' - '~'Commerce' %} 5 | {% set elementType = 'craft\\commerce\\elements\\Variant' %} 6 | {% set selectedTab = 'products' %} 7 | {% set selectedSubnavItem = "products" %} 8 | {% set bodyClass = (bodyClass is defined ? bodyClass~' ' : '') ~ "commerceproducts commerceproductsindex" %} 9 | 10 | {% if productTypeHandle is defined %} 11 | {% js %} 12 | window.defaultProductTypeHandle = '{{ productTypeHandle }}'; 13 | {% endjs %} 14 | {% endif %} 15 | -------------------------------------------------------------------------------- /src/test/mockclasses/Purchasable.php: -------------------------------------------------------------------------------- 1 | 17 | * @author Global Network Group | Giel Tettelaar 18 | * @since 2.1 19 | */ 20 | class Purchasable extends BasePurchasable 21 | { 22 | public bool $isPromotable = true; 23 | 24 | public float $price = 25.10; 25 | 26 | public function getIsPromotable(): bool 27 | { 28 | return $this->isPromotable; 29 | } 30 | 31 | public function getPrice(string|Store|null $store = null): ?float 32 | { 33 | return 25.10; 34 | } 35 | 36 | public function getSku(): string 37 | { 38 | return 'commerce_testing_unique_sku'; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/views/debug/commerce/summary.php: -------------------------------------------------------------------------------- 1 | 4 |
    5 | 6 | Commerce 7 | 8 |
    9 | -------------------------------------------------------------------------------- /src/web/assets/catalogpricing/dist/css/CatalogPricing.css: -------------------------------------------------------------------------------- 1 | #commerce-catalog-prices{position:relative}#commerce-catalog-prices.busy{min-height:200px}#commerce-catalog-prices.busy:after{background:hsla(0,0%,100%,.75);border-radius:var(--large-border-radius);content:"";display:block;font-size:0;height:100%;left:-24px;position:absolute;top:0;width:calc(100% + 48px)}#commerce-catalog-prices.busy .update-spinner{z-index:1} 2 | /*# sourceMappingURL=CatalogPricing.css.map*/ -------------------------------------------------------------------------------- /src/web/assets/catalogpricing/dist/css/CatalogPricing.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"css/CatalogPricing.css","mappings":"AAAA,yBACE,kBAEA,8BACE,iBAEA,oCASE,+BACA,yCARA,WADA,cAEA,YAKA,YAFA,WAFA,kBACA,MAEA,uBAGA,CAGF,8CACE","sources":["webpack:///./css/catalogpricing.scss"],"sourcesContent":["#commerce-catalog-prices {\n position: relative;\n\n &.busy {\n min-height: 200px;\n\n &:after {\n display: block;\n content: '';\n font-size: 0;\n position: absolute;\n top: 0;\n left: -24px;\n width: calc(100% + #{24 + 24}px);\n height: 100%;\n background: transparentize(#fff, 0.25);\n border-radius: var(--large-border-radius);\n }\n\n .update-spinner {\n z-index: 1;\n }\n }\n}\n"],"names":[],"sourceRoot":""} -------------------------------------------------------------------------------- /src/web/assets/catalogpricing/src/css/catalogpricing.scss: -------------------------------------------------------------------------------- 1 | #commerce-catalog-prices { 2 | position: relative; 3 | 4 | &.busy { 5 | min-height: 200px; 6 | 7 | &:after { 8 | display: block; 9 | content: ''; 10 | font-size: 0; 11 | position: absolute; 12 | top: 0; 13 | left: -24px; 14 | width: calc(100% + #{24 + 24}px); 15 | height: 100%; 16 | background: transparentize(#fff, 0.25); 17 | border-radius: var(--large-border-radius); 18 | } 19 | 20 | .update-spinner { 21 | z-index: 1; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/web/assets/catalogpricing/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | /* globals module, require, __dirname */ 3 | const {getConfig} = require('@craftcms/webpack'); 4 | 5 | module.exports = getConfig({ 6 | context: __dirname, 7 | config: { 8 | entry: { 9 | CatalogPricing: './js/CatalogPricing.js', 10 | }, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /src/web/assets/chartjs/ChartJsAsset.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 3.0 17 | */ 18 | class ChartJsAsset extends AssetBundle 19 | { 20 | /** 21 | * @inheritdoc 22 | */ 23 | public function init(): void 24 | { 25 | $this->sourcePath = __DIR__ . '/dist'; 26 | 27 | $this->js = [ 28 | 'Chart.bundle.min.js', 29 | 'moment-with-locales.min.js', 30 | 'chartjs-adapter-moment.min.js', 31 | ]; 32 | 33 | parent::init(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/web/assets/chartjs/dist/Chart.bundle.min.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /*! 2 | * Chart.js v2.9.4 3 | * https://www.chartjs.org 4 | * (c) 2020 Chart.js Contributors 5 | * Released under the MIT License 6 | */ 7 | -------------------------------------------------------------------------------- /src/web/assets/chartjs/dist/chartjs-adapter-moment.min.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /*! 2 | * chartjs-adapter-moment v0.1.2 3 | * https://www.chartjs.org 4 | * (c) 2020 Chart.js Contributors 5 | * Released under the MIT license 6 | */ 7 | -------------------------------------------------------------------------------- /src/web/assets/chartjs/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | /* globals module, require, __dirname */ 3 | const {getConfig} = require('@craftcms/webpack'); 4 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 5 | 6 | module.exports = getConfig({ 7 | context: __dirname, 8 | config: { 9 | plugins: [ 10 | new CopyWebpackPlugin({ 11 | patterns: [ 12 | {from: require.resolve('chart.js/dist/Chart.bundle.min.js')}, 13 | {from: require.resolve('moment/min/moment-with-locales.min.js')}, 14 | { 15 | from: require.resolve( 16 | 'chartjs-adapter-moment/dist/chartjs-adapter-moment.min.js' 17 | ), 18 | }, 19 | ], 20 | }), 21 | ], 22 | }, 23 | }); 24 | -------------------------------------------------------------------------------- /src/web/assets/commercecp/dist/images/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftcms/commerce/b7ef900ecefcf697c7cb7e232b9aa3e486db4690/src/web/assets/commercecp/dist/images/error.png -------------------------------------------------------------------------------- /src/web/assets/commercecp/dist/images/promotional_price.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftcms/commerce/b7ef900ecefcf697c7cb7e232b9aa3e486db4690/src/web/assets/commercecp/dist/images/promotional_price.png -------------------------------------------------------------------------------- /src/web/assets/commercecp/dist/images/spinner_big.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftcms/commerce/b7ef900ecefcf697c7cb7e232b9aa3e486db4690/src/web/assets/commercecp/dist/images/spinner_big.gif -------------------------------------------------------------------------------- /src/web/assets/commercecp/src/commercecp.js: -------------------------------------------------------------------------------- 1 | // SCSS 2 | import './scss/addresses.scss'; 3 | import './scss/commerce.scss'; 4 | import './scss/order.scss'; 5 | import './scss/purchasables.scss'; 6 | import './scss/prices.scss'; 7 | import './scss/registration.scss'; 8 | import './scss/stores.scss'; 9 | import './scss/subscriptions.scss'; 10 | 11 | // JS 12 | import './js/Commerce'; 13 | import './js/CommerceOrderEdit'; 14 | import './js/CommerceOrderIndex'; 15 | import './js/CommercePaymentModal'; 16 | import './js/CommerceProductSalesModal'; 17 | import './js/CommerceSubscriptionIndex'; 18 | import './js/CommerceUpdateOrderStatusModal'; 19 | import './js/DownloadOrderPdf'; 20 | import './js/TableRowAdditionalInfoIcon'; 21 | -------------------------------------------------------------------------------- /src/web/assets/commercecp/src/images/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftcms/commerce/b7ef900ecefcf697c7cb7e232b9aa3e486db4690/src/web/assets/commercecp/src/images/error.png -------------------------------------------------------------------------------- /src/web/assets/commercecp/src/images/promotional_price.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftcms/commerce/b7ef900ecefcf697c7cb7e232b9aa3e486db4690/src/web/assets/commercecp/src/images/promotional_price.png -------------------------------------------------------------------------------- /src/web/assets/commercecp/src/images/spinner_big.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftcms/commerce/b7ef900ecefcf697c7cb7e232b9aa3e486db4690/src/web/assets/commercecp/src/images/spinner_big.gif -------------------------------------------------------------------------------- /src/web/assets/commercecp/src/js/Commerce.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | if (typeof Craft.Commerce === typeof undefined) { 3 | Craft.Commerce = {}; 4 | } 5 | 6 | Craft.Commerce.initUnlimitedStockCheckbox = function ($container) { 7 | $container 8 | .find('input.unlimited-stock:first') 9 | .change(Craft.Commerce.handleUnlimitedStockCheckboxChange); 10 | }; 11 | 12 | Craft.Commerce.handleUnlimitedStockCheckboxChange = function (ev) { 13 | var $checkbox = $(ev.currentTarget), 14 | $text = $checkbox 15 | .parent() 16 | .prevAll('.textwrapper:first') 17 | .children('.text:first'); 18 | 19 | if ($checkbox.prop('checked')) { 20 | $text.prop('disabled', true).addClass('disabled').val(''); 21 | } else { 22 | $text.prop('disabled', false).removeClass('disabled').focus(); 23 | } 24 | }; 25 | })(jQuery); 26 | -------------------------------------------------------------------------------- /src/web/assets/commercecp/src/js/CommerceSubscriptionIndex.js: -------------------------------------------------------------------------------- 1 | if (typeof Craft.Commerce === typeof undefined) { 2 | Craft.Commerce = {}; 3 | } 4 | 5 | /** 6 | * Class Craft.Commerce.SubscriptionIndex 7 | */ 8 | Craft.Commerce.SubscriptionsIndex = Craft.BaseElementIndex.extend({}); 9 | 10 | // Register the Commerce order index class 11 | Craft.registerElementIndexClass( 12 | 'craft\\commerce\\elements\\Subscription', 13 | Craft.Commerce.SubscriptionsIndex 14 | ); 15 | -------------------------------------------------------------------------------- /src/web/assets/commercecp/src/scss/addresses.scss: -------------------------------------------------------------------------------- 1 | .address-boxes { 2 | display: flex; 3 | flex-wrap: wrap; 4 | margin: 0 -10px; 5 | } 6 | 7 | .address-box { 8 | box-sizing: border-box; 9 | padding: 0 10px; 10 | margin-bottom: 1em; 11 | width: 100%; 12 | 13 | &.address-box--full { 14 | width: 100%; 15 | } 16 | } 17 | 18 | @media only screen and (min-width: 768px) { 19 | .address-box { 20 | width: 50%; 21 | 22 | &.address-box--full { 23 | width: 100%; 24 | } 25 | } 26 | } 27 | 28 | @media only screen and (min-width: 1200px) { 29 | .address-box { 30 | width: 33%; 31 | 32 | &.address-box--full { 33 | width: 100%; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/web/assets/commercecp/src/scss/prices.scss: -------------------------------------------------------------------------------- 1 | .commerce-promotional-price { 2 | &::before { 3 | content: ''; 4 | // @TODO replace this with an approved icon and do it the same way as Craft 5 | background-image: url(../images/promotional_price.png); 6 | background-repeat: no-repeat; 7 | background-size: contain; 8 | display: inline-block; 9 | width: 1em; 10 | height: 1em; 11 | opacity: 0.6; 12 | margin-right: 0.25em; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/web/assets/commercecp/src/scss/purchasables.scss: -------------------------------------------------------------------------------- 1 | /* Purchasable Cards */ 2 | .purchasable-cards { 3 | display: grid; 4 | gap: var(--m) var(--m); 5 | grid-template-columns: repeat(1, minmax(0, 1fr)); 6 | } 7 | 8 | .purchasable-cards__add-btn { 9 | } 10 | 11 | .purchasable-card.error { 12 | border: 1px solid #cf1124; 13 | } 14 | 15 | .purchasable-card.error:hover { 16 | border-color: #cf1124; 17 | } 18 | 19 | .purchasable-card { 20 | border: 1px solid #eee; 21 | border-radius: 0.375rem; 22 | padding: 1rem; 23 | } 24 | 25 | .purchasable-card:hover { 26 | border-color: #ddd; 27 | background-color: #fafafa; 28 | cursor: pointer; 29 | } 30 | 31 | .purchasable-card .purchasable-card-header { 32 | display: flex; 33 | flex-wrap: nowrap; 34 | justify-content: space-between; 35 | align-items: center; 36 | } 37 | 38 | .purchasable-card .purchasable-card-header-actions { 39 | display: flex; 40 | justify-content: flex-end; 41 | } 42 | -------------------------------------------------------------------------------- /src/web/assets/commercecp/src/scss/stores.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | .store-selector { 4 | position: relative; 5 | 6 | &::after { 7 | pointer-events: none; 8 | } 9 | 10 | > select { 11 | appearance: none; 12 | background: transparent; 13 | margin: -7px -26px -7px -14px; 14 | padding: 7px 24px 7px 14px; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/web/assets/commercecp/src/scss/subscriptions.scss: -------------------------------------------------------------------------------- 1 | .payment-status-unpaid { 2 | color: #d0021b; 3 | } 4 | 5 | .payment-status-paid { 6 | color: #27ae60; 7 | } 8 | -------------------------------------------------------------------------------- /src/web/assets/commercecp/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | /* globals module, require */ 3 | const {getConfig} = require('@craftcms/webpack'); 4 | 5 | module.exports = getConfig({ 6 | context: __dirname, 7 | config: { 8 | entry: { 9 | commercecp: './commercecp.js', 10 | }, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /src/web/assets/commerceui/.env.example: -------------------------------------------------------------------------------- 1 | DEV_SERVER_PUBLIC="http://localhost:8082/" 2 | DEV_SERVER_PORT="8082" 3 | DEV_SERVER_LOOPBACK="http://host.docker.internal:8082" 4 | # Until we have admintable as a package or everything in a mono repo we need this 5 | # to be able to directly include components from the craftcms/cms repo. 6 | CRAFT_ASSETS_PATH='./../../../../../cms/src/web/assets/' -------------------------------------------------------------------------------- /src/web/assets/commerceui/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | 4 | # local env files 5 | .env 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | -------------------------------------------------------------------------------- /src/web/assets/commerceui/CommerceOrderAsset.php: -------------------------------------------------------------------------------- 1 | 14 | * @since 3.1.4 15 | */ 16 | class CommerceOrderAsset extends CommerceUiAsset 17 | { 18 | /** 19 | * @inheritdoc 20 | */ 21 | public $js = [ 22 | 'js/app.js', 23 | ]; 24 | 25 | /** 26 | * @inheritdoc 27 | */ 28 | public $css = [ 29 | 'css/order.css', 30 | ]; 31 | } 32 | -------------------------------------------------------------------------------- /src/web/assets/commerceui/dist/js/app.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /*! 2 | * escape-html 3 | * Copyright(c) 2012-2013 TJ Holowaychuk 4 | * Copyright(c) 2015 Andreas Lubbe 5 | * Copyright(c) 2015 Tiancheng "Timothy" Gu 6 | * MIT Licensed 7 | */ 8 | 9 | /*! 10 | * is-extendable 11 | * 12 | * Copyright (c) 2015, Jon Schlinkert. 13 | * Licensed under the MIT License. 14 | */ 15 | 16 | /** 17 | * @license 18 | * Lodash 19 | * Copyright OpenJS Foundation and other contributors 20 | * Released under MIT license 21 | * Based on Underscore.js 1.8.3 22 | * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 23 | */ 24 | 25 | /**! 26 | * Sortable 1.15.0 27 | * @author RubaXa 28 | * @author owenm 29 | * @license MIT 30 | */ 31 | -------------------------------------------------------------------------------- /src/web/assets/commerceui/dist/manifest.json: -------------------------------------------------------------------------------- 1 | {"order.css":"/css/order.css","order.js":"/js/app.js","order.css.map":"/css/order.css.map","app.js.map":"/js/app.js.map"} -------------------------------------------------------------------------------- /src/web/assets/commerceui/src/js/base/components/BtnLink.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 22 | 23 | 45 | -------------------------------------------------------------------------------- /src/web/assets/commerceui/src/js/base/filters/craft.js: -------------------------------------------------------------------------------- 1 | /* global Craft */ 2 | 3 | export function t(message, category, params) { 4 | return Craft.t(category, message, params); 5 | } 6 | -------------------------------------------------------------------------------- /src/web/assets/commerceui/src/js/order/api/addresses.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6, strict: false */ 2 | /* globals Craft */ 3 | 4 | import axios from 'axios/index'; 5 | 6 | export default { 7 | validate(address) { 8 | const data = { 9 | address: address, 10 | }; 11 | return axios.post( 12 | Craft.getActionUrl('commerce/orders/validate-address'), 13 | data, 14 | { 15 | headers: { 16 | 'X-CSRF-Token': Craft.csrfTokenValue, 17 | }, 18 | } 19 | ); 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /src/web/assets/commerceui/src/js/order/components/InputError.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 26 | -------------------------------------------------------------------------------- /src/web/assets/commerceui/src/js/order/components/OrderBlock.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | -------------------------------------------------------------------------------- /src/web/assets/commerceui/src/js/order/components/OrderTitle.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | -------------------------------------------------------------------------------- /src/web/assets/commerceui/src/js/order/components/details/QtyInput.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 32 | -------------------------------------------------------------------------------- /src/web/assets/commerceui/src/js/order/components/details/Total.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 17 | -------------------------------------------------------------------------------- /src/web/assets/commerceui/src/js/order/components/meta/OpenIndicator.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/web/assets/commerceui/src/js/order/mixins/index.js: -------------------------------------------------------------------------------- 1 | /* global $ */ 2 | 3 | import utils from '../helpers/utils'; 4 | 5 | export default { 6 | methods: { 7 | saveOrder: function (draft) { 8 | if (this.$store.state.saveLoading) { 9 | return false; 10 | } 11 | 12 | this.$store.commit('updateSaveLoading', true); 13 | 14 | const data = utils.buildDraftData(draft); 15 | const dataString = JSON.stringify(data); 16 | 17 | this.$store.commit('updateOrderData', dataString); 18 | 19 | this.$nextTick(() => { 20 | $('#main-form').submit(); 21 | }); 22 | }, 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /src/web/assets/commerceui/src/sass/base/_craft-classes.scss: -------------------------------------------------------------------------------- 1 | /* Spacer */ 2 | 3 | .spacer { 4 | width: 14px; 5 | } 6 | -------------------------------------------------------------------------------- /src/web/assets/commerceui/src/sass/order/_modal.scss: -------------------------------------------------------------------------------- 1 | .order-edit-modal.modal { 2 | padding-bottom: 58px; 3 | 4 | .body { 5 | height: 100%; 6 | overflow-y: scroll; 7 | } 8 | 9 | .footer { 10 | position: absolute; 11 | left: 0; 12 | right: 0; 13 | bottom: 0; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/web/assets/commerceui/src/sass/order/app.scss: -------------------------------------------------------------------------------- 1 | @import 'craftcms-sass/mixins'; 2 | $lightGrey: #eee; 3 | 4 | @import '../base/craft-classes'; 5 | @import '../base/vue-select'; 6 | @import '../base/common'; 7 | @import './modal'; 8 | 9 | .order-box-sizing * { 10 | box-sizing: border-box; 11 | } 12 | 13 | .order-flex { 14 | display: flex; 15 | } 16 | 17 | .order-flex-grow { 18 | flex-grow: 1; 19 | } 20 | 21 | .order-flex-wrap { 22 | flex-wrap: wrap; 23 | } 24 | 25 | .order-opacity-50 { 26 | opacity: 0.5; 27 | } 28 | 29 | .orderedit-border-t { 30 | border-top: 1px solid; 31 | } 32 | 33 | .orderedit-border-b { 34 | border-bottom: 1px solid; 35 | } 36 | 37 | .orderedit-border-color { 38 | border-color: #eee; 39 | } 40 | -------------------------------------------------------------------------------- /src/web/assets/commerceui/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | /* globals module, require */ 3 | const path = require('path'); 4 | const webpack = require('webpack'); 5 | const {getConfig} = require('@craftcms/webpack'); 6 | 7 | module.exports = getConfig({ 8 | context: __dirname, 9 | type: 'vue', 10 | config: { 11 | entry: {order: './js/order/app.js'}, 12 | output: { 13 | filename: 'js/app.js', 14 | chunkFilename: 'js/[name].js', 15 | }, 16 | plugins: [new webpack.DefinePlugin({'process.env.BUILD': '"web"'})], 17 | }, 18 | }); 19 | -------------------------------------------------------------------------------- /src/web/assets/commercewidgets/CommerceWidgetsAsset.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 5.0.0 17 | */ 18 | class CommerceWidgetsAsset extends AssetBundle 19 | { 20 | /** 21 | * @inheritdoc 22 | */ 23 | public function init(): void 24 | { 25 | $this->sourcePath = __DIR__ . '/dist'; 26 | 27 | $this->js[] = 'CommerceWidgets.js'; 28 | 29 | parent::init(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/web/assets/commercewidgets/dist/CommerceWidgets.js: -------------------------------------------------------------------------------- 1 | !function(){function t(e){return t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},t(e)}"undefined"===t(Craft.Commerce)&&(Craft.Commerce={}),Craft.Commerce.CommerceWidgets={updateOrderStatuses:function(t,e){var r=$("#".concat(e,' [data-attribute="orderStatuses"] .selectize select'));if(r){var o=r[0].selectize;Craft.sendActionRequest("get","commerce/order-statuses/get-order-statuses",{params:{storeId:t}}).then((function(t){t.data.orderStatuses,o.clear(!0),o.clearOptions(!0),t.data.orderStatuses.forEach((function(t){o.addOption({text:t.name,value:t.uid,status:t.color})})),o.refreshOptions(!1)})).catch((function(t){Craft.cp.displayError(t)}))}else Craft.cp.displayError("Could not find order status field.")}}}(); 2 | //# sourceMappingURL=CommerceWidgets.js.map -------------------------------------------------------------------------------- /src/web/assets/commercewidgets/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | /* globals module, require, __dirname */ 3 | const {getConfig} = require('@craftcms/webpack'); 4 | 5 | module.exports = getConfig({ 6 | context: __dirname, 7 | config: { 8 | entry: { 9 | CommerceWidgets: './CommerceWidgets.js', 10 | }, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /src/web/assets/coupons/dist/css/coupons.css: -------------------------------------------------------------------------------- 1 | #commerce-coupons>.field>.heading{display:-webkit-flex;display:flex;-webkit-justify-content:space-between;justify-content:space-between}#commerce-coupons-hud{max-width:22rem} 2 | /*# sourceMappingURL=coupons.css.map*/ -------------------------------------------------------------------------------- /src/web/assets/coupons/dist/css/coupons.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"css/coupons.css","mappings":"AACE,kCACE,kCACA,oEAIJ,sBACE","sources":["webpack:///./css/coupons.scss"],"sourcesContent":["#commerce-coupons {\n > .field > .heading {\n display: flex;\n justify-content: space-between;\n }\n}\n\n#commerce-coupons-hud {\n max-width: 22rem;\n}\n"],"names":[],"sourceRoot":""} -------------------------------------------------------------------------------- /src/web/assets/coupons/src/css/coupons.scss: -------------------------------------------------------------------------------- 1 | #commerce-coupons { 2 | > .field > .heading { 3 | display: flex; 4 | justify-content: space-between; 5 | } 6 | } 7 | 8 | #commerce-coupons-hud { 9 | max-width: 22rem; 10 | } 11 | -------------------------------------------------------------------------------- /src/web/assets/coupons/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | /* globals module, require, __dirname */ 3 | const {getConfig} = require('@craftcms/webpack'); 4 | 5 | module.exports = getConfig({ 6 | context: __dirname, 7 | config: { 8 | entry: { 9 | coupons: './js/coupons.js', 10 | }, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /src/web/assets/deepmerge/DeepMergeAsset.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 3.0 17 | */ 18 | class DeepMergeAsset extends AssetBundle 19 | { 20 | /** 21 | * @inheritdoc 22 | */ 23 | public function init(): void 24 | { 25 | $this->sourcePath = __DIR__ . '/dist'; 26 | 27 | $this->js[] = 'umd.js'; 28 | 29 | parent::init(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/web/assets/deepmerge/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | /* globals module, require, __dirname */ 3 | const {getConfig} = require('@craftcms/webpack'); 4 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 5 | 6 | module.exports = getConfig({ 7 | context: __dirname, 8 | config: { 9 | plugins: [ 10 | new CopyWebpackPlugin({ 11 | patterns: [{from: require.resolve('deepmerge/dist/umd.js')}], 12 | }), 13 | ], 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /src/web/assets/editproduct/EditProductAsset.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class EditProductAsset extends AssetBundle 20 | { 21 | /** 22 | * @inheritdoc 23 | */ 24 | public function init(): void 25 | { 26 | $this->sourcePath = __DIR__ . '/dist'; 27 | 28 | $this->depends = [ 29 | CommerceCpAsset::class, 30 | ]; 31 | 32 | $this->css = [ 33 | 'css/CommerceProductEdit.css', 34 | ]; 35 | 36 | $this->js = [ 37 | 'CommerceProductEdit.js', 38 | ]; 39 | 40 | parent::init(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/web/assets/editproduct/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | /* globals module, require */ 3 | const {getConfig} = require('@craftcms/webpack'); 4 | 5 | module.exports = getConfig({ 6 | context: __dirname, 7 | config: { 8 | entry: { 9 | CommerceProductEdit: './CommerceProductEdit.js', 10 | }, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /src/web/assets/inventory/dist/css/inventory.css: -------------------------------------------------------------------------------- 1 | .ltr .inventory-cell,.ltr .inventory-headers{text-align:right}.rtl .inventory-cell,.rtl .inventory-headers{text-align:left}.ltr .inventory-cell{text-align:right}.ltr .inventory-cell .action-btn{right:calc(var(--touch-target-size)*-1/1.5)}.rtl .inventory-cell{text-align:left}.rtl .inventory-cell .action-btn{left:calc(var(--touch-target-size)*-1/1.5)}#inventory-levels .inventory-cell{position:relative}#inventory-levels .inventory-cell .action-btn{opacity:0;position:absolute;z-index:99}#inventory-levels .inventory-cell .action-btn[aria-expanded=true],#inventory-levels .vue-admin-table tbody tr:hover .inventory-cell .action-btn{opacity:1} 2 | /*# sourceMappingURL=inventory.css.map*/ -------------------------------------------------------------------------------- /src/web/assets/inventory/src/css/inventory.scss: -------------------------------------------------------------------------------- 1 | .inventory-headers, 2 | .inventory-cell { 3 | .ltr & { 4 | text-align: right; 5 | } 6 | 7 | .rtl & { 8 | text-align: left; 9 | } 10 | } 11 | 12 | .ltr { 13 | .inventory-cell { 14 | text-align: right; 15 | } 16 | 17 | .inventory-cell .action-btn { 18 | right: calc(var(--touch-target-size) * -1 / 1.5); 19 | } 20 | } 21 | 22 | .rtl { 23 | .inventory-cell { 24 | text-align: left; 25 | } 26 | 27 | .inventory-cell .action-btn { 28 | left: calc(var(--touch-target-size) * -1 / 1.5); 29 | } 30 | } 31 | 32 | #inventory-levels { 33 | .inventory-cell { 34 | position: relative; 35 | } 36 | 37 | .inventory-cell .action-btn { 38 | opacity: 0; 39 | position: absolute; 40 | z-index: 99; 41 | } 42 | 43 | .inventory-cell .action-btn[aria-expanded='true'] { 44 | opacity: 1; 45 | } 46 | 47 | .vue-admin-table tbody tr:hover { 48 | .inventory-cell .action-btn { 49 | opacity: 1; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/web/assets/inventory/src/inventory.js: -------------------------------------------------------------------------------- 1 | // SCSS 2 | import './css/inventory.scss'; 3 | 4 | // JS 5 | import './js/InventoryLevelsManager'; 6 | import './js/UpdateInventoryLevelModal'; 7 | import './js/InventoryMovementModal'; 8 | -------------------------------------------------------------------------------- /src/web/assets/inventory/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | /* globals module, require */ 3 | const {getConfig} = require('@craftcms/webpack'); 4 | 5 | module.exports = getConfig({ 6 | context: __dirname, 7 | config: { 8 | entry: { 9 | inventory: './inventory.js', 10 | }, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /src/web/assets/orderswidget/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | /* globals module, require */ 3 | const {getConfig} = require('@craftcms/webpack'); 4 | 5 | module.exports = getConfig({ 6 | context: __dirname, 7 | config: { 8 | entry: { 9 | OrdersWidgetSettings: './OrdersWidgetSettings.js', 10 | }, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /src/web/assets/productindex/ProductIndexAsset.php: -------------------------------------------------------------------------------- 1 | 17 | * @since 2.0 18 | */ 19 | class ProductIndexAsset extends AssetBundle 20 | { 21 | /** 22 | * @inheritdoc 23 | */ 24 | public function init(): void 25 | { 26 | $this->sourcePath = __DIR__ . '/dist'; 27 | 28 | $this->depends = [ 29 | CommerceCpAsset::class, 30 | ]; 31 | 32 | $this->js = [ 33 | 'CommerceProductIndex.js', 34 | ]; 35 | 36 | parent::init(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/web/assets/productindex/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | /* globals module, require */ 3 | const {getConfig} = require('@craftcms/webpack'); 4 | 5 | module.exports = getConfig({ 6 | context: __dirname, 7 | config: { 8 | entry: { 9 | CommerceProductIndex: './CommerceProductIndex.js', 10 | }, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /src/web/assets/purchasablepricefield/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | /* globals module, require, __dirname */ 3 | const {getConfig} = require('@craftcms/webpack'); 4 | 5 | module.exports = getConfig({ 6 | context: __dirname, 7 | config: { 8 | entry: { 9 | purchasablepricefield: './js/purchasablepricefield.js', 10 | }, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /src/web/assets/statwidgets/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | /* globals module, require */ 3 | const {getConfig} = require('@craftcms/webpack'); 4 | 5 | module.exports = getConfig({ 6 | context: __dirname, 7 | config: { 8 | entry: { 9 | CommerceChart: './CommerceChart.js', 10 | }, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /src/web/assets/transfers/dist/css/transfers.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftcms/commerce/b7ef900ecefcf697c7cb7e232b9aa3e486db4690/src/web/assets/transfers/dist/css/transfers.css -------------------------------------------------------------------------------- /src/web/assets/transfers/src/css/transfers.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftcms/commerce/b7ef900ecefcf697c7cb7e232b9aa3e486db4690/src/web/assets/transfers/src/css/transfers.scss -------------------------------------------------------------------------------- /src/web/assets/transfers/src/js/TransferEdit.js: -------------------------------------------------------------------------------- 1 | /** global: Craft */ 2 | /** global: Garnish */ 3 | /** 4 | * Transfer Edit class 5 | */ 6 | if (typeof Craft.Commerce === typeof undefined) { 7 | Craft.Commerce = {}; 8 | } 9 | 10 | Craft.Commerce.TransferEdit = Garnish.Base.extend({ 11 | $container: null, 12 | 13 | init: function (container, settings) { 14 | this.$container = $(container); 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /src/web/assets/transfers/src/transfers.js: -------------------------------------------------------------------------------- 1 | // SCSS 2 | import './css/transfers.scss'; 3 | 4 | // JS 5 | import './js/TransferEdit'; 6 | import './js/ReceiveTransferScreen'; 7 | -------------------------------------------------------------------------------- /src/web/assets/transfers/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | /* globals module, require */ 3 | const {getConfig} = require('@craftcms/webpack'); 4 | 5 | module.exports = getConfig({ 6 | context: __dirname, 7 | config: { 8 | entry: { 9 | transfers: './transfers.js', 10 | }, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /src/web/assets/variantmatrix/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* jshint esversion: 6 */ 2 | /* globals module, require */ 3 | const {getConfig} = require('@craftcms/webpack'); 4 | 5 | module.exports = getConfig({ 6 | context: __dirname, 7 | config: { 8 | entry: { 9 | VariantMatrix: './VariantMatrix.js', 10 | }, 11 | }, 12 | }); 13 | --------------------------------------------------------------------------------