flamingo.me/flamingo-commerce/v3@v3.11.0/sourcing/domain/fake/sourcing_service.go (about) 1 package fake 2 3 import ( 4 "context" 5 _ "embed" 6 "encoding/json" 7 "os" 8 9 cartDomain "flamingo.me/flamingo-commerce/v3/cart/domain/cart" 10 "flamingo.me/flamingo-commerce/v3/cart/domain/decorator" 11 productDomain "flamingo.me/flamingo-commerce/v3/product/domain" 12 commerceSourcingDomain "flamingo.me/flamingo-commerce/v3/sourcing/domain" 13 ) 14 15 type ( 16 SourcingService struct { 17 fakeSource *fakeSource 18 } 19 20 fakeSource struct { 21 DeliveryCodes map[string]int 22 Products map[string]int 23 } 24 ) 25 26 var _ commerceSourcingDomain.SourcingService = &SourcingService{} 27 28 func (s *SourcingService) Inject( 29 cfg *struct { 30 FakeSourceData string `inject:"config:commerce.sourcing.fake.jsonPath,optional"` 31 }, 32 ) { 33 if cfg.FakeSourceData == "" { 34 panic("fake sourcing service enabled but jsonPath was not set") 35 } 36 37 fileBytes, err := os.ReadFile(cfg.FakeSourceData) 38 if err != nil { 39 panic(err) 40 } 41 42 fakeSource := &fakeSource{} 43 err = json.Unmarshal(fileBytes, fakeSource) 44 if err != nil { 45 panic(err) 46 } 47 48 s.fakeSource = fakeSource 49 } 50 51 func (s *SourcingService) AllocateItems(ctx context.Context, decoratedCart *decorator.DecoratedCart) (commerceSourcingDomain.ItemAllocations, error) { 52 var ( 53 itemAllocations = commerceSourcingDomain.ItemAllocations{} 54 overallError error 55 ) 56 for _, decoratedDelivery := range decoratedCart.DecoratedDeliveries { 57 for _, decoratedItem := range decoratedDelivery.DecoratedItems { 58 if decoratedItem.Item.ID == "" { 59 continue 60 } 61 62 availableSources, err := s.GetAvailableSources(ctx, decoratedItem.Product, &decoratedDelivery.Delivery.DeliveryInfo, decoratedCart) 63 availableSourcesForProduct := availableSources[commerceSourcingDomain.ProductID(decoratedItem.Product.GetIdentifier())] 64 65 itemAllocation := commerceSourcingDomain.ItemAllocation{ 66 AllocatedQtys: map[commerceSourcingDomain.ProductID]commerceSourcingDomain.AllocatedQtys{ 67 commerceSourcingDomain.ProductID(decoratedItem.Product.GetIdentifier()): commerceSourcingDomain.AllocatedQtys(availableSourcesForProduct), 68 }, 69 Error: err, 70 } 71 72 itemAllocations[commerceSourcingDomain.ItemID(decoratedItem.Item.ID)] = itemAllocation 73 } 74 } 75 76 return itemAllocations, overallError 77 } 78 79 func (s *SourcingService) GetAvailableSources(_ context.Context, product productDomain.BasicProduct, deliveryInfo *cartDomain.DeliveryInfo, _ *decorator.DecoratedCart) (commerceSourcingDomain.AvailableSourcesPerProduct, error) { 80 if product.Type() == productDomain.TypeBundle || product.Type() == productDomain.TypeConfigurable { 81 return nil, commerceSourcingDomain.ErrUnsupportedProductType 82 } 83 84 productId := product.GetIdentifier() 85 86 if productId == "" { 87 return nil, commerceSourcingDomain.ErrEmptyProductIdentifier 88 } 89 90 allocationQty, found := s.fakeSource.Products[productId] 91 if found { 92 return commerceSourcingDomain.AvailableSourcesPerProduct{ 93 commerceSourcingDomain.ProductID(productId): s.makeAvailableSources(allocationQty, productId), 94 }, nil 95 } 96 97 if deliveryInfo.Code != "" { 98 allocationQty, found := s.fakeSource.DeliveryCodes[deliveryInfo.Code] 99 if found { 100 return commerceSourcingDomain.AvailableSourcesPerProduct{ 101 commerceSourcingDomain.ProductID(productId): s.makeAvailableSources(allocationQty, deliveryInfo.Code), 102 }, nil 103 } 104 } 105 106 return nil, commerceSourcingDomain.ErrNoSourceAvailable 107 } 108 109 func (s *SourcingService) makeAvailableSources(qty int, id string) commerceSourcingDomain.AvailableSources { 110 return map[commerceSourcingDomain.Source]int{ 111 commerceSourcingDomain.Source{ 112 LocationCode: id, 113 ExternalLocationCode: id, 114 }: qty, 115 } 116 }