vendure-ecommerce / vendure

The commerce platform with customization in its DNA.
https://www.vendure.io
Other
5.59k stars 990 forks source link

Improved Multi-Vendor Marketplace Support #1329

Closed michaelbromley closed 1 year ago

michaelbromley commented 2 years ago

Is your feature request related to a problem? Please describe. We get a lot of questions about support for multi-vendor marketplaces (MVM). In fact, this is probably the number 1 feature request at the moment. Though it technically is possible to implement this on top of the Channels feature, it is not straightforward and certain scenarios require a bit of hacking to get them working.

With certain changes to the DB schema etc we can 1) make MVM support ready to go "out of the box" and 2) support more advanced features such as multiple active orders for each vendor's products in cart.

Requested Features I requested suggestions for features on Slack. Here's the responses:

What i would like to have, is multi warehouses. Warehouses can have same products, but also different products. Same with prices, customers, shipping prices, orders. I think this would be same princip as multi-tenant / merchant.

We need a feature to make a product exclusive to channel(s) so that they do not appear in the product , products or search (shop-api) query on the default-channel anymore. Maybe we can make the enabled property channel-aware?

Maybe a tutorial on the "Permission - Role - Channel" relations would be helpful. In my case I want to have 3 Roles per Channel and thats too much. The problem is that users can have different roles per channel and that's why I need 3 unique Roles each. Maybe the relation between a User and a Role should be bound to a channel. "UserChannelRole" table with userId, channelId, roleId

With a new table like this we could make role assignments exclusive to channels. My usecase for this is that I want to create default roles like: Moderator, Member, Ambassador. But I don't want to create them for every channel because a user can be a Member of one Channel and a Moderator of another. This function userHasPermissionOnChannel in role.service should also be easy to do. Just query based on User and Channel from request context and we get all roles for the requesting user. image (4)

Hi, maybe with currentOrder group by channel? I mean if you add 2 products from 2 different shops, you should get 2 orders

AndersGerner commented 2 years ago

@michaelbromley We are very interested in this feature, and we are trying to create it right now, with channels. Currently, our setup does not require payment, but we are looking to create a cart, that is divided by the different channels.

Our current status is, that we are using Vercel Commerce as the storefront and have adjusted it, so "Designers" are channels and it sorts/filters products perfectly with name, price, and categories.

This is totally out of context so I understand if it does not make total sense, but: We would like to have a full-blown multi-vendor shop within the next 3 months, so if we can help with brainstorming you are more than welcome to reach out. I would also like to help with the development as well, but we are just a small startup and I am currently the only developer, so I don't have much spare time, but maybe by helping you, I would make it easier for us to reach the multi-vendor store we dream of.

Just a short description of us: We are a startup in Denmark, trying to help retail stores - especially those highly affected by Covid-19 - showcase what they have in their store, and make it easy for their customers to find them and their products. Our mission is to help them keep their dream of being a store owner alive :)

Bottom line: If we can help in any way, brainstorming, testing, development, or something else, don't hesitate to reach out

michaelbromley commented 2 years ago

Hi @AndersGerner! I'm definitely interested to learn more about your use-case & discuss the potential of collaboration. Reach out to me via contact[at]vendure.io or via Twitter and let's chat.

magick93 commented 2 years ago

Hello

I'm looking for similar functionality, though to call it multi-vendor is perhaps too overloaded.

Essentially I'm looking for the ability for a product buyer to immediately be able re-list that item for sale. Essentially a marketplace where users have the ability / role of both buyers and sellers.

Could this be done as a plugin, or would it need core level changes?

michaelbromley commented 2 years ago

@magick93 This could already be implemented in v1.x as a plugin - as to the exact implementation there are a number of ways to do it depending on your particular workflows & requirements. I know of several projects already under development that follow a similar model. If you join our Slack group you might be able to connect with someone about this.

Draykee commented 2 years ago

I'm still pretty curious about the restructuring of the channel roles relations. Are there any updates on that?

michaelbromley commented 2 years ago

@Draykee not started work on this feature yet.

pbalakri commented 2 years ago
pbalakri commented 2 years ago
  1. I can see the entire product catalog of the business.
  2. If the product I sell is already present in the catalog, I can create a new offer on the product where an Offer = Selling Price + Discount Price + Stock + Stock Location + Delivery Promise ( days to deliver)
  3. I can de-list an offer on a product if it goes out of stock or WILL no longer be sold
  4. If the product I see if NOT already present in the catalog, I can create the meta data of the product and submit for approval by business administrator. Once approved, I can list the offer using previous requirement.
  5. I can see shipment meta data of all orders placed that contain my (and ONLY MY) offers.
  6. I can change status of my shipments to ACCEPTED/REJECTED/PACKED/DISPATCHED (To be fleshed out some more i.e. do I want to change each item status in the shipment or the entire shipment as a whole)
  7. I can view reports on best selling items, my price competitiveness against other vendors, best selling categories, states of shipments, etc.
pbalakri commented 2 years ago
  1. If multiple vendors sell the same product, when I search for the product, I should see that product once in the search results with an indicator that there are multiple offers for that product.
  2. If multiple vendors sell the same product, when I am on the PDP of the product, I should be able to continue to see all variations of the product grouped by vendors.
  3. If multiple vendors sell the same product, when I land on the PDP of the product, I should be able to see if there are cheaper offers, faster delivery promises, or more reliable deliveries from other vendors.
  4. I should be able to review the delivery experience for a particular vendor which is available for the vendor and other future customers.
khawarizmus commented 2 years ago
  • As a Customer,
  1. If multiple vendors sell the same product, when I search for the product, I should see that product once in the search results with an indicator that there are multiple offers for that product.

I would say that if a customer searches for a product they should see all the products that are offered by the different vendors on the marketplace.

Draykee commented 2 years ago

I would say that if a customer searches for a product they should see all the products that are offered by the different vendors on the marketplace.

For my usecase this would be bad. I need all channels to be exclusive and only accessable to selected customers.

pbalakri commented 2 years ago
  • As a Customer,
  1. If multiple vendors sell the same product, when I search for the product, I should see that product once in the search results with an indicator that there are multiple offers for that product.

I would say that if a customer searches for a product they should see all the products that are offered by the different vendors on the marketplace.

Fair point to generalize this, merging some implementation detail. When I search in Default channel, I should see all products from all channels as usual. If the same product is sold by multiple vendors, we should still see one product with each vendor's offer as a possible variant for that product.

Example 1: Vendor A and B sell a FOOBAR brand Shirt in size XL and color RED with a globally identifiable SKU 1111. Additionally, Vendor A and B sell exclusive private label products with SKUs '2222' and '3333' respectively. In the DEFAULT channel, Customer when searching should see only ONE entry of "1111", instead of TWO. In the DEFAULT channel, Customer when searching should see TWO entries with '2222' and '3333'. In Vendor specific channels, Customer should only see that Vendor's offer as it is today.

alexcode commented 2 years ago

Hi @michaelbromley, very interesting feature. On my use-case, I'm using a Channel for each vendor. The problem I faced was to be able to retrieve multiple orders in the same cart. To circumvent the current limitations, I'm adding acustomField relation between a Session and an Order to be able to retrieve multiple orders.

{
    name: 'session',
    type: 'relation',
    entity: AnonymousSession,
    graphQLType: 'Session',
    nullable: true,
    eager: false,
    internal: false,
}

Currently, I'm using TypeORM events to update the relations and custom GraphQL to retrieve orders. As you imagine, in the frontend, activeOrder and activeChannel aren't that useful in my case.

On the payment side, I'm using a marketplace provider (Mangopay) with a e-wallet model which can be challenging on the payment handler side.

khawarizmus commented 2 years ago

I wanted to go ahead and describe a multi-tenant use case that we want to make it work with Vendure. The idea is to have a marketplace where people search for products to by and can also open a store (channel) to sell products. here are some of the point i think might need to happen for that to be possible:

I am not sure if i listed all the points but i would be open for discussions on how to do this with the current Vendure and with this initiative right here.

JustDenP commented 1 year ago

One of the necessary functions for marketplaces is the money withdraw for sellers.

In more complex systems, this is achieved by using separate payments, such as stripe Connect or PayPal marketplace. The data for withdrawal and the preferred payment system the vendor specifies in their dashboard.

In simpler systems, where the marketplace is only one of the system options and is not emphasized, the system works like this: Each seller has a virtual wallet inside dashboard, on which the amount of orders is summarized (minus marketplace commission), then he can make a payout request, entering how much of the available to him money he wants to withdraw and chooses a payment system (paypal, bank account, etc.), then this request sees superadmin, transfers money to the vendor manually and puts the status of the request as approved

Also, the marketplaces themselves exist on commissions from the sales of vendors. Do you plan to add this functionality in version 2.0? Thank you

michaelbromley commented 1 year ago

@JustDenP Thanks for this insight.

The most important thing I want to get in v2 is that we have a correct data model to support marketplace-like apps. It's likely that we will not ship v2 with full support for all the major features of a marketplace, but as long as the underlying data model is correct we'll be able to incrementally increase support for richer marketplace features in subsequent versions (or make it much simpler for you to implement such features as plugins).

amadeus-torwell commented 1 year ago

Is there a design picture of the fully fledged version of this feature? Like what happens to facets (will they be shared between channels etc.)

michaelbromley commented 1 year ago

@deusama no not yet, because it has not been designed yet.

But Facets are already channel-aware, so they can be assigned to channels (the UI part of this is coming very soon in the next minor version).

The main areas that are to change will relate to how orders are structured. But again, I can't say exactly what those changes will look like yet.

tonyellow commented 1 year ago

I am trying to build a multi tenant solution where multiple channels can have the same customer with the same email. Is this something that is possible to integrate or change?

HarunKilic commented 1 year ago

I am creating an B2B ecommerce, where the usecase looks like:

  1. A customer joins a customer group (companies)
  2. The customer can make orders on behalf of the customer groups in different channels (warehouse locations)

So to accomplish this, the user should have different carts based on the current selected channel and customer group.

michaelbromley commented 1 year ago

Alright everyone. The time has come! I'm starting the design phase of this feature.

The way I like to work is to start with some simple ideas and we can collectively poke them until they break and then we can design something even better.

So let's start by defining exactly what we want to handle in this issue

Scope

We need to define the necessary changes to the entity data model and GraphQL APIs to support the following marketplace features. Checkmark indicates existing support:

  1. A Seller can have their own shop (Channel) with products, variants ✅
  2. A Customer can create an Order which includes variants from any Channel ✅
  3. Payment for the Order can be split between the Sellers of the items in the order.
  4. When a Seller views an Order, they only have access to those parts of the order (lines, shipping, payments) that pertain to their portion of the order.
  5. The Admin can view the entire Order including all lines, shipping & payments from all channels ✅

Constraints

We want to minimise changes to the data model. We can make breaking changes, but the optimal design will try to minimise breaks so that migration of existing data is easier.

Suggestion: AggregateOrder

My initial idea is to define a new entity, AggregateOrder. This is a kind of "container" which holds reference to 1 or more Order entities.

image

The Order entity itself would work pretty much in the same way that it does currently. This has the advantage that non-marketplace apps will require little or no changes - they just keep working the same way they always did.

The AggregateOrder entity would look something like this:

export class AggregateOrder extends VendureEntity {
  code: string;
  customer: Customer;
  orders: Order[];
  total: number;
  shipping: number;
}

With an AggregateOrder, when adding a new item, we'd need to specify the token of the channel which the item is being added from:

mutation {
  addItemToOrder(productVariantId: 123, quantity: 1, channelToken: 'abc') {
    # ....
  }
}

Vendure would then create a new AggregateOrder, create a new Order linked to Channel 'abc', and add a new OrderLine to that order.

Shipping

An AggregateOrder should have a single ShippingAddress, and when it is set, this gets propagated to each individual Order. Each Order will have a separate ShippingLine, and the shipping total of the AggregateOrder will be the sum of each order's shipping.

We'll need a way to get eligibleShippingMethods in a way that makes sense for multiple orders at once. We might need some kind of AggregateShipping type to abstract over these, in order to be able to present a simple option to the customer.

Payment

As with shipping, payments will be handled at the individual Order level (as they currently are), but we'll need some API to allow us to map the payment of the AggregateOrder into individual Payments for each Order.

As part of this, we need to closely study how APIs like Stripe Connect and Mollie Connect work, so we can design an API that allows seamless integration with these products (and others).


I'd like to get some preliminary feedback on the above proposal. Do you see any fundamental issues with this approach? What other requirements have I not considered?

HarunKilic commented 1 year ago

This is amazing @michaelbromley! A nice starter point. But what if the admin wants to provide single shipment and/or payment method? So that the payment would go to the highest hierarchy instead of at the channel level?

I'm thinking something like Amazon, where shipment can be from the sellers warehouse or Amazon warehouse. The item is provided by the seller, but stored in common warehouse. So all the items within same warehouse is shipped at the same time without extra cost.

dlhck commented 1 year ago

Looks great!

I am not sure if we should keep the seller <> channel connection because I think channels should be used differently in marketplaces.

We must also not forget about taxes. The tax lines can be completely mixed in the AggregateOrder, because they depend on each seller.

michaelbromley commented 1 year ago

But what if the admin wants to provide single shipment and/or payment method? So that the payment would go to the highest hierarchy instead of at the channel level?

Yes I think this is a scenario we need to support - so either split shipping / payment or shared at the AggregateOrder level. So perhaps an AggregateShipping entity can either have ShippingLines directly related to it, or can point to the ShippingLines of the child Orders. Same with an AggregatePayment entity.

We'd probably need to provide a couple of strategies which allow the developer to define exactly the shipping & payments are distributed - either shared or separate.

I am not sure if we should keep the seller <> channel connection because I think channels should be used differently in marketplaces.

What are your thoughts about how channels should be used?

We must also not forget about taxes. The tax lines can be completely mixed in the AggregateOrder, because they depend on each seller.

My first thought is that we just leave TaxLines as they already are on each child Order, and at the AggregateOrder level we have a getter which just combines all of them for the tax summary. Does that sounds reasonable?

kyunal commented 1 year ago

One thing that is noticeably absent from the proposal is a way to list/search/.. products from all channels for those wanting to have an Amazon-like marketplace

michaelbromley commented 1 year ago

One thing that is noticeably absent from the proposal is a way to list/search/.. products from all channels for those wanting to have an Amazon-like marketplace

This is already possible by using the default channel in the storefront, which contains the contents of all channels.

michaelbromley commented 1 year ago

Some further thoughts about the AggregateOrder idea:

  1. Have 2 different types of order - Order and AggregateOrder will make certain things much more complex. For example, when we use the orders query to get a list of Orders, how do we also get AggregateOrders? Do we need a separate query for those? Or return a union type that includes both? We can't use a ListQueryBuilder to query and interleave 2 different entity types.
  2. All the APIs that operate on an Order instance need to be partially duplicated to operate on AggregateOrder. Having a common interface might make this easier. At the DB level this would mean entity inheritance.
  3. But inheritance of a common interface means that Order and AggregateOrder would have to be almost the same, sharing mostly the same properties. If that is the case, then does it really make sense to have them as separate entities?

This line of thinking has brought me to explore another possibility: we just stick with the existing Order entity to represent all orders, and if the order is a multi-seller order, we model this in a different way by storing reference to the Channel or Seller (if we decide to create a Seller entity) for each OrderLine, Payment, ShippingLine etc. image

This is roughly the way that people have been implementing marketplaces in Vendure v1.x as far as I am aware. It has the advantage that we can avoid a new entity and the issues enumerated above.

Using this model it might be possible to hide all of this from the end user. E.g. when Seller A calls the order(id: 123) query, Vendure sees that the current active Channel is "seller-a", and transparently removes all parts of Order 123 that do not pertain to that Channel. Thus the representation of Order 123 changes depending on the channel one is viewing it from. When viewed from the default Channel, the entire order is returned.

khawarizmus commented 1 year ago

The long awaited feature! Thanks for this @michaelbromley. I wanted to address something which i think haven't been discussed here. and that is the possibility for a customer to also be a seller and vice versa. So a user can have scoped permissions to a channel while still being able to buy from other channels like a normal customer. the use case here is that anyone can open an account to buy from the market place and use the same account (credentials) to create a store (channel) in the marketplace.

dlhck commented 1 year ago

@michaelbromley please also think about that every seller has its own number sequence for numbers (order numbers, shipment numbers, ...) - therefore a separate AggregateOrder is necessary in my eyes.

michaelbromley commented 1 year ago

@davidhoeck This could be solved with a kind of metadata object that holds seller-specific data related to the order. I was thinking about this but left it out of the diagram above for simplicity.

Something like this:

image

Which is essentially turning the existing Order entity into an aggregate, but could be an approach that introduces less complexity.

HarunKilic commented 1 year ago

@michaelbromley seems cool. Will the PartialOrder be extendable? I will in my case store the Sales order ID from ERP. And that will be different per store/channel.

Draykee commented 1 year ago

Will the concept with the one single activeOrder also change?

michaelbromley commented 1 year ago

@Draykee With the new ActiveOrderStrategy this aspect is already now much more flexible - you can have multiple active orders depending on input criteria that you are able to define.

@HarunKilic It seems like a good idea to make the PartialOrder extensible via custom fields.

michaelbromley commented 1 year ago

Another idea, in which I try not to create any new entities at all, just extend the existing Order entity in a way that could work for multi-vendor:

export class Order {
  orderType: 'single' | 'aggregate' | 'partial';
  partialOrders: Order[]; // default []
}

Workflow

  1. Customer visits marketplace and adds SellerAProduct1 to order
  2. Vendure creates a new Order with type aggregate, and an Order with type partial and joins them together.
  3. The SellerAProduct1 is added to the partial order only.
  4. Customer adds more products from different sellers, and Vendure creates a partial Order for each unique Seller.

This raises a few questions:


Although this idea does not require any new entities, I feel like the interaction between the aggregate and partial orders might have some pretty gnarly complexity implications.

ivasilov commented 1 year ago

PartialOrder can actually be a virtual type, present only in TS code (we're using it in this way in our custom implementation). You can extract all data from an existing orders and split it into several partial orders, right? With that being said, for best forward compatibility, I would say that PartialOrder should be its own DB table with relations to all its parts (order lines etc).

* How are totals calculated? Does the aggregate order add up the totals of each partial and use that as its total?

There's already this kind of data in Vendure order items price -> order total. You're basically adding another level there which is ok IMO.

* Can an aggregate Order have its own OrderLines? E.g. for some platform charge.

There's going to be an intermediate step where this is true (until all existing order lines are migrated to Partial Order) but I would say that it's going to be easier if it doesn't have its own order lines.

Just a note, VendorOrder or MerchantOrder is probably a better name than PartialOrder.

dnk8n commented 1 year ago

Is any of the work/discussion here useful to break down some of the unknowns? https://github.com/Saleor-Multi-Vendor/saleor-multi-vendor (also see the issue tracker for more info)

mariusa commented 1 year ago

While this is being considered, I think another use case is Multi-tenant support, within a single schema. This would allow a single instance of Vendore to host multiple merchants, each with their own store. Exactly like Shopify, anyone can signup to have their own shop, customers, orders, payment methods etc.

Could this be included in the redesign? It's a major request for other open source commerce apps (not supported out of the box, but with cumbersome workarounds such as https://medusajs.com/blog/medusa-extender ), and would be a great differentiator for Vendure.

michaelbromley commented 1 year ago

@dnk8n thanks for the pointer - I was searching for existing multivendor open source implementations to study and they are hard to find! I'll definitely look into this.

@mariusa the multi-tenant story is already fairly well supported - see these docs. There might well still be some improvements we can make, but I already know of multi-tenant projects already in production.

mariusa commented 1 year ago

Thanks Michael,

Sorry to say this, but the current multi-tenant support seems a workaround. If you compare with Shopify, a shop can have multiple markets (currencies, countries...) and multiple users, which are managed by the merchant (shop owner). The "Ace Parts" business from the docs example could simply signup at cloud.vendure.io, create channels for themselves (eg online store, Amazon, Etsy...), define markets and so on. They wouldn't need a super admin to create an user & channel for them.

michaelbromley commented 1 year ago

@mariusa I see. Yes, making Vendure as capable as a multi-tenant solution like Shopify is not a priority right now - the current multi-tenant functionality is more suitable to a project wherein the tenants are controlled by a central admin, who can grant access to owners of individual stores. But if you did want to make it self-serve like Shopify, you can create a custom mutation that does all the needed steps of creating a new channel, creating a role and admin, assigning permissions etc. I believe some projects have implemented such a feature.

michaelbromley commented 1 year ago

Update after experimenting for a couple of days of different approaches:

Using the Partial Order (VendorOrder) method does allow us to correctly split up OrderLines between the various vendors (channels), but there are numerous complexities that then need to be handled:

  1. Order history needs to be scoped to each vendor. I.e. we do not want a global history viewable by all vendors, as it may e.g. contain notes by Vendor A which are then visible by Vendor B.
  2. Calculation of totals. This could be done on-the-fly using a get total(): number getter, but this will very likely be a performance drag. So we'd probably end up calculating the prices for each VendorOrder whenever the order is modified. This quite significantly complicates the order calculation function.
  3. The question of order state is complex: if all VendorOrders share the state of the parent Order, it might be confusing to Vendor A why the order state is still "partially shipped" when all of their OrderLines have been shipped, yet Vendor B did not yet ship.
  4. If an Order needs modification after being placed, this will get really complex. We'd need to scope each modification to a given VendorOrder, but changes to it could affect prices for all VendorOrders, e.g. is a Order-level promotion becomes invalid, or if shipping costs change.
  5. We need to maintain both Order and VendorOrder entities, GraphQL types, and probably introduce GraphQL union types in those GraphQL queries that currently just return Order.

There are probably dozens more hidden complexities with this design. Thus I'm proposing a totally different approach which aims to eliminate all of these issues

Let's call this "nested orders"

Nested Orders

image

In this model, there are no new entities needed. Only the existing Order entity, but with a few additions:

class Order {
  type: 'regular' | 'aggregate' | 'vendor'
  vendorOrders: Order[];
  parentOrder?: Order;
}

A regular order works exactly like an Order currently works. Absolutely no changes should be needed for non-multivendor apps.

For multivendor apps, the flow would work like this:

  1. Customer adds items to Order as usual. This step works exactly as it does currently.
  2. When completing the order, we are now able to split this into an aggregate Order, and one or more vendor Orders. This would be handled by a configurable strategy, allowing each implementation to define exactly how this split should be determined. Each vendor order will be assigned to a specific Channel, and the aggregate Order will be assigned only to the default Channel.
  3. In this way, each vendor Order is totally isolated and stand-alone, containing only the lines, history, payments, fulfillments etc. that pertain to that specific vendor. This means we can basically re-use all the existing logic without needing to add all the complexity handling listed above.
Draykee commented 1 year ago

I like the idea of nested order. This would make the way migration easier!

I had a few other thoughts as well:

michaelbromley commented 1 year ago

@Draykee Thanks for the suggestions!

There should be custom calculation strategies for the order total. By using a configurable strategy we would be able to add vouchers, service fees and stuff like discounts for a certain quantity of products.

This sounds like a separate feature request, but may already be covered by existing & planned functionality: vouchers & discounts are handled by Promotions. Service fees can be implemented as Surcharges. Discounts based on quantity is planned as an extension to the OrderItemPriceCalculationStrategy by passing in the quantity.

Maybe we can add a new entity for the "Payout" that gives instructions on were to distribute the money a customer payed

Possibly - I've not figured out that part quite yet. Part of this depends on the business model of the marketplace: some marketplaces will not hold funds for sellers, but will use something like Stripe Connect so that the seller is paid immediately by the customer. In all cases, it might be possible to just use the existing Payment entity, and have a type of PaymentHandler which represents payouts as in your scenario. Needs further exploration.

For a 'marketplace' I though that a vendor can also be a user. Is it possible to connect the vendor with a user? Both vendor and customer should then have access to an order. Given the idea, that vendors can also have access to the Admin UI - I still think that the permission model needs an update (like the one ER model in your initial post)

I plan to revisit permissions & especially as they relate to Customers vs Admins. For now I'm just concentrating on the Order mechanics.


Split orders: prior art

Unrelated, but I'm just gonna dump some prior art links here that I've found:

gilesbutler commented 1 year ago

Hi there, I just came across this issue after looking for a multivendor marketplace solution. I'm wondering if you have a rough eta of when it will be released at all? I appreciate it's an ongoing issue and is very complex.

michaelbromley commented 1 year ago

Hi @gilesbutler I'm hoping to have a beta version available around the end of February. We publish pre-releases quite regularly on the next npm tag, it's likely that the next prerelease will include the work I've done so far on multivendor, which by the end of next week should hopefully be usable.

gilesbutler commented 1 year ago

Amazing to hear @michaelbromley and thanks for getting back so quickly! Look forward to giving it a test on the next tag next week!

michaelbromley commented 1 year ago

Video update on the latest progress (which is now merged into the major branch but not yet released to npm): https://youtu.be/jTOhzrA1baQ

dnk8n commented 1 year ago

Amazing work @michaelbromley

Just watched the video. Interested to know if you were able to study Spree's multivendor functionality. You have made an evidently tricky feature so much more accessible to the open-source community. You should be very proud of those achievements!

ivasilov commented 1 year ago

Great work @michaelbromley!

From the video, it looks like the aggregate order doesn't have a fullfilment. This could be useful if vendors are shipping to a common distributor which packs the partial orders together and ships them out.

JustDenP commented 1 year ago

Cool! Another question about future multi-vendor functionality: Can each vendor create their own variations with attributes or will only the superadmin be able to create a predefined template for them?