flamingo.me/flamingo-commerce/v3@v3.11.0/cart/module.go (about)

     1  package cart
     2  
     3  import (
     4  	"flamingo.me/dingo"
     5  	"flamingo.me/flamingo/v3/framework/flamingo"
     6  	"flamingo.me/flamingo/v3/framework/web"
     7  	"flamingo.me/form"
     8  	formDomain "flamingo.me/form/domain"
     9  	flamingographql "flamingo.me/graphql"
    10  
    11  	"flamingo.me/flamingo-commerce/v3/cart/application"
    12  	"flamingo.me/flamingo-commerce/v3/cart/domain/cart"
    13  	"flamingo.me/flamingo-commerce/v3/cart/domain/events"
    14  	"flamingo.me/flamingo-commerce/v3/cart/domain/placeorder"
    15  	"flamingo.me/flamingo-commerce/v3/cart/infrastructure"
    16  	placeorderAdapter "flamingo.me/flamingo-commerce/v3/cart/infrastructure/placeorder"
    17  	"flamingo.me/flamingo-commerce/v3/cart/interfaces/controller"
    18  	"flamingo.me/flamingo-commerce/v3/cart/interfaces/controller/forms"
    19  	"flamingo.me/flamingo-commerce/v3/cart/interfaces/graphql"
    20  	"flamingo.me/flamingo-commerce/v3/cart/interfaces/templatefunctions"
    21  	"flamingo.me/flamingo-commerce/v3/customer"
    22  	"flamingo.me/flamingo-commerce/v3/product"
    23  )
    24  
    25  type (
    26  	// Module registers our profiler
    27  	Module struct {
    28  		routerRegistry                *web.RouterRegistry
    29  		enableDefaultCartAdapter      bool
    30  		enablePlaceOrderLoggerAdapter bool
    31  		enableCartCache               bool
    32  		cartMergeStrategy             string
    33  	}
    34  )
    35  
    36  // Inject dependencies
    37  func (m *Module) Inject(
    38  	routerRegistry *web.RouterRegistry,
    39  	config *struct {
    40  		EnableDefaultCartAdapter      bool   `inject:"config:commerce.cart.defaultCartAdapter.enabled,optional"`
    41  		EnableCartCache               bool   `inject:"config:commerce.cart.enableCartCache,optional"`
    42  		CartMergeStrategy             string `inject:"config:commerce.cart.mergeStrategy,optional"`
    43  		EnablePlaceOrderLoggerAdapter bool   `inject:"config:commerce.cart.placeOrderLogger.enabled,optional"`
    44  	},
    45  ) {
    46  	m.routerRegistry = routerRegistry
    47  	if config != nil {
    48  		m.enableDefaultCartAdapter = config.EnableDefaultCartAdapter
    49  		m.enableCartCache = config.EnableCartCache
    50  		m.cartMergeStrategy = config.CartMergeStrategy
    51  		m.enablePlaceOrderLoggerAdapter = config.EnablePlaceOrderLoggerAdapter
    52  	}
    53  }
    54  
    55  // Configure module
    56  func (m *Module) Configure(injector *dingo.Injector) {
    57  	if m.enableDefaultCartAdapter {
    58  		injector.Bind((*infrastructure.CartStorage)(nil)).To(infrastructure.InMemoryCartStorage{}).AsEagerSingleton()
    59  		injector.Bind((*infrastructure.GiftCardHandler)(nil)).To(infrastructure.DefaultGiftCardHandler{})
    60  		injector.Bind((*infrastructure.VoucherHandler)(nil)).To(infrastructure.DefaultVoucherHandler{})
    61  		injector.Bind((*cart.GuestCartService)(nil)).To(infrastructure.DefaultGuestCartService{})
    62  		injector.Bind((*cart.CustomerCartService)(nil)).To(infrastructure.DefaultCustomerCartService{})
    63  	}
    64  
    65  	if m.enablePlaceOrderLoggerAdapter {
    66  		injector.Bind((*placeorder.Service)(nil)).To(placeorderAdapter.PlaceOrderLoggerAdapter{})
    67  	}
    68  	// Register Default EventPublisher
    69  	injector.Bind((*events.EventPublisher)(nil)).To(events.DefaultEventPublisher{})
    70  
    71  	// Event
    72  	flamingo.BindEventSubscriber(injector).To(application.EventReceiver{})
    73  
    74  	// Cart merge strategy that is used by the event receiver to merge carts on during login
    75  	switch m.cartMergeStrategy {
    76  	case "replace":
    77  		injector.Bind((*application.CartMerger)(nil)).To(application.CartMergeStrategyReplace{})
    78  	case "none":
    79  		injector.Bind((*application.CartMerger)(nil)).To(application.CartMergeStrategyNone{})
    80  	default:
    81  		injector.Bind((*application.CartMerger)(nil)).To(application.CartMergeStrategyMerge{})
    82  	}
    83  
    84  	// TemplateFunction
    85  	flamingo.BindTemplateFunc(injector, "getCart", new(templatefunctions.GetCart))
    86  	flamingo.BindTemplateFunc(injector, "getDecoratedCart", new(templatefunctions.GetDecoratedCart))
    87  	flamingo.BindTemplateFunc(injector, "getQuantityAdjustmentDeletedItemsMessages", new(templatefunctions.GetQuantityAdjustmentDeletedItemsMessages))
    88  	flamingo.BindTemplateFunc(injector, "getQuantityAdjustmentUpdatedItemsMessages", new(templatefunctions.GetQuantityAdjustmentUpdatedItemsMessage))
    89  	flamingo.BindTemplateFunc(injector, "getQuantityAdjustmentCouponCodesRemoved", new(templatefunctions.GetQuantityAdjustmentCouponCodesRemoved))
    90  	flamingo.BindTemplateFunc(injector, "removeQuantityAdjustmentMessages", new(templatefunctions.RemoveQuantityAdjustmentMessages))
    91  
    92  	injector.Bind((*cart.DeliveryInfoBuilder)(nil)).To(cart.DefaultDeliveryInfoBuilder{})
    93  
    94  	if m.enableCartCache {
    95  		injector.Bind((*application.CartCache)(nil)).To(application.CartSessionCache{})
    96  	}
    97  
    98  	// Register Form Data Provider
    99  	injector.BindMap(new(formDomain.FormService), "commerce.cart.deliveryFormService").To(forms.DeliveryFormService{})
   100  	injector.BindMap(new(formDomain.FormService), "commerce.cart.billingFormService").To(forms.BillingAddressFormService{})
   101  	injector.BindMap(new(formDomain.FormService), "commerce.cart.personaldataFormService").To(forms.DefaultPersonalDataFormService{})
   102  
   103  	web.BindRoutes(injector, new(routes))
   104  
   105  	injector.BindMulti(new(flamingographql.Service)).To(graphql.Service{})
   106  
   107  	injector.Bind(new(application.Receiver)).To(application.BaseCartReceiver{})
   108  	injector.Bind(new(application.Service)).To(application.CartService{})
   109  }
   110  
   111  // CueConfig defines the cart module configuration
   112  func (*Module) CueConfig() string {
   113  	return `
   114  commerce: {
   115  	cart: {
   116  		defaultCartAdapter: {
   117  			enabled: bool | *true
   118  			storage: "inmemory"
   119  			defaultTaxRate?: number
   120  			productPrices: *"gross" | "net"
   121  			defaultCurrency: string | *"EUR"
   122  		}
   123  		placeOrderLogger: {
   124  			enabled: bool | *true
   125  			useFlamingoLog: bool | *true
   126  			logAsFile: bool | *true
   127  			logDirectory: string | *"./orders/"
   128  		}
   129  		enableCartCache: bool | *true
   130  		cacheLifetime: number | *1200
   131  		defaultUseBillingAddress: bool | *false
   132  		defaultDeliveryCode: string | *"delivery"
   133  		deleteEmptyDelivery: bool | *false
   134  		mergeStrategy: "none" | "replace" | *"merge"
   135  		showEmptyCartPageIfNoItems?: bool
   136  		adjustItemsToRestrictedQty?: bool
   137  		personalDataForm: {
   138  			additionalFormFields: [...string] | *[]
   139  			dateOfBirthRequired: bool | *false
   140  			passportCountryRequired: bool | *false
   141  			passportNumberRequired: bool | *false
   142  			minAge?: number
   143  		}
   144  		simplePaymentForm: {
   145  			giftCardPaymentMethod: string | *"voucher"
   146  		}
   147  	}
   148  }`
   149  }
   150  
   151  // FlamingoLegacyConfigAlias mapping
   152  func (*Module) FlamingoLegacyConfigAlias() map[string]string {
   153  	return map[string]string{
   154  		"commerce.cart.useEmailPlaceOrderAdapter":                 "commerce.cart.placeOrderLogger.enabled",
   155  		"commerce.cart.useInMemoryCartServiceAdapters":            "commerce.cart.defaultCartAdapter.enabled",
   156  		"commerce.cart.inMemoryCartServiceAdapter.defaultTaxRate": "commerce.cart.defaultCartAdapter.defaultTaxRate",
   157  	}
   158  }
   159  
   160  // Depends on other modules
   161  func (m *Module) Depends() []dingo.Module {
   162  	return []dingo.Module{
   163  		new(product.Module),
   164  		new(form.Module),
   165  		new(customer.Module),
   166  	}
   167  }
   168  
   169  type routes struct {
   170  	viewController *controller.CartViewController
   171  	apiController  *controller.CartAPIController
   172  }
   173  
   174  func (r *routes) Inject(viewController *controller.CartViewController, apiController *controller.CartAPIController) {
   175  	r.viewController = viewController
   176  	r.apiController = apiController
   177  }
   178  
   179  func (r *routes) Routes(registry *web.RouterRegistry) {
   180  	registry.HandleAny("cart.view", r.viewController.ViewAction)
   181  	registry.MustRoute("/cart", "cart.view")
   182  
   183  	registry.HandleAny("cart.add", r.viewController.AddAndViewAction)
   184  	registry.MustRoute("/cart/add/:marketplaceCode", `cart.add(marketplaceCode,variantMarketplaceCode?="",qty?="1",deliveryCode?="")`)
   185  
   186  	registry.HandleAny("cart.updateQty", r.viewController.UpdateQtyAndViewAction)
   187  	registry.MustRoute("/cart/update/:id", `cart.updateQty(id,qty?="1",deliveryCode?="")`)
   188  
   189  	registry.HandleAny("cart.deleteAllItems", r.viewController.DeleteAllAndViewAction)
   190  	registry.MustRoute("/cart/delete/all", "cart.deleteAllItems")
   191  
   192  	registry.HandleAny("cart.clean", r.viewController.CleanAndViewAction)
   193  	registry.MustRoute("/cart/clean", "cart.clean")
   194  
   195  	registry.HandleDelete("cart.clean", r.viewController.CleanAndViewAction)
   196  	registry.MustRoute("/cart/delivery/:deliveryCode", "cart.clean")
   197  
   198  	registry.HandleAny("cart.cleanDelivery", r.viewController.CleanDeliveryAndViewAction)
   199  	registry.MustRoute("/cart/delete/delivery/:deliveryCode", `cart.cleanDelivery(deliveryCode?="")`)
   200  
   201  	registry.HandleAny("cart.deleteItem", r.viewController.DeleteAndViewAction)
   202  	registry.MustRoute("/cart/delete/:id", `cart.deleteItem(id,deliveryCode?="")`)
   203  	r.apiRoutes(registry)
   204  }
   205  
   206  func (r *routes) apiRoutes(registry *web.RouterRegistry) {
   207  	// v1 Routes:
   208  	registry.MustRoute("/api/v1/cart", "cart.api.cart")
   209  	registry.HandleDelete("cart.api.cart", r.apiController.DeleteCartAction)
   210  	registry.HandleGet("cart.api.cart", r.apiController.GetAction)
   211  
   212  	registry.MustRoute("/api/v1/cart/billing", `cart.api.billing`)
   213  	registry.HandlePut("cart.api.billing", r.apiController.BillingAction)
   214  
   215  	registry.MustRoute("/api/v1/cart/payment-selection", `cart.api.payment-selection`)
   216  	registry.HandlePut("cart.api.payment-selection", r.apiController.UpdatePaymentSelectionAction)
   217  
   218  	registry.MustRoute("/api/v1/cart/deliveries/items", "cart.api.deliveries.items")
   219  	registry.HandleDelete("cart.api.deliveries.items", r.apiController.DeleteAllItemsAction)
   220  
   221  	registry.MustRoute("/api/v1/cart/delivery/:deliveryCode", `cart.api.delivery`)
   222  	registry.HandleDelete("cart.api.delivery", r.apiController.DeleteDelivery)
   223  	registry.HandlePut("cart.api.delivery", r.apiController.UpdateDeliveryInfoAction)
   224  
   225  	registry.MustRoute("/api/v1/cart/delivery/:deliveryCode/item", `cart.api.item(marketplaceCode?="",variantMarketplaceCode?="",qty?="1",deliveryCode?="")`)
   226  	registry.HandlePost("cart.api.item", r.apiController.AddAction)
   227  	registry.HandleDelete("cart.api.item", r.apiController.DeleteItemAction)
   228  	registry.HandlePut("cart.api.item", r.apiController.UpdateItemAction)
   229  
   230  	registry.MustRoute("/api/v1/cart/voucher", `cart.api.voucher(couponCode)`)
   231  	registry.HandlePost("cart.api.voucher", r.apiController.ApplyVoucherAndGetAction)
   232  	registry.HandleDelete("cart.api.voucher", r.apiController.RemoveVoucherAndGetAction)
   233  
   234  	registry.MustRoute("/api/v1/cart/gift-card", `cart.api.gift-card(couponCode)`)
   235  	registry.HandlePost("cart.api.gift-card", r.apiController.ApplyGiftCardAndGetAction)
   236  	registry.HandleDelete("cart.api.gift-card", r.apiController.RemoveGiftCardAndGetAction)
   237  
   238  	registry.MustRoute("/api/v1/cart/voucher-gift-card", `cart.api.voucher-gift-card(couponCode)`)
   239  	registry.HandlePost("cart.api.voucher-gift-card", r.apiController.ApplyCombinedVoucherGift)
   240  
   241  	// Legacy Routes:
   242  	registry.MustRoute("/api/cart", "cart.api.get")
   243  	registry.HandleDelete("cart.api.get", r.apiController.DeleteAllItemsAction)
   244  	registry.HandleGet("cart.api.get", r.apiController.GetAction)
   245  
   246  	registry.MustRoute("/api/cart/delivery/:deliveryCode/additem", `cart.api.add(marketplaceCode,variantMarketplaceCode?="",qty?="1",deliveryCode?="")`)
   247  	registry.HandlePost("cart.api.add", r.apiController.AddAction)
   248  
   249  	registry.MustRoute("/api/cart/applyvoucher", `cart.api.applyVoucher(couponCode)`)
   250  	registry.HandlePost("cart.api.applyVoucher", r.apiController.ApplyVoucherAndGetAction)
   251  	registry.HandlePut("cart.api.applyVoucher", r.apiController.ApplyVoucherAndGetAction)
   252  
   253  	registry.MustRoute("/api/cart/removevoucher", `cart.api.removeVoucher(couponCode)`)
   254  	registry.HandlePost("cart.api.removeVoucher", r.apiController.RemoveVoucherAndGetAction)
   255  	registry.HandleDelete("cart.api.removeVoucher", r.apiController.RemoveVoucherAndGetAction)
   256  
   257  	registry.MustRoute("/api/cart/applygiftcard", `cart.api.applyGiftCard(couponCode)`)
   258  	registry.HandlePost("cart.api.applyGiftCard", r.apiController.ApplyGiftCardAndGetAction)
   259  	registry.HandlePut("cart.api.applyGiftCard", r.apiController.ApplyGiftCardAndGetAction)
   260  
   261  	registry.MustRoute("/api/cart/removegiftcard", `cart.api.removeGiftCard(couponCode)`)
   262  	registry.HandlePost("cart.api.removeGiftCard", r.apiController.RemoveGiftCardAndGetAction)
   263  	registry.HandleDelete("cart.api.removeGiftCard", r.apiController.RemoveGiftCardAndGetAction)
   264  
   265  	registry.MustRoute("/api/cart/applycombinedvouchergift", `cart.api.applyCombinedVoucherGift(couponCode)`)
   266  	registry.HandlePost("cart.api.applyCombinedVoucherGift", r.apiController.ApplyCombinedVoucherGift)
   267  
   268  	registry.MustRoute("/api/cart/billing", `cart.api.billing`)
   269  	registry.HandlePost("cart.api.billing", r.apiController.BillingAction)
   270  
   271  	registry.MustRoute("/api/cart/delivery/:deliveryCode", `cart.api.delivery.delete`)
   272  	registry.HandleDelete("cart.api.delivery.delete", r.apiController.DeleteDelivery)
   273  
   274  	registry.MustRoute("/api/cart/delivery/:deliveryCode/deliveryinfo", `cart.api.delivery.update`)
   275  	registry.HandlePost("cart.api.delivery.update", r.apiController.UpdateDeliveryInfoAction)
   276  }