Giter Site home page Giter Site logo

ordercloud-api / headstart Goto Github PK

View Code? Open in Web Editor NEW
31.0 10.0 74.0 9.79 MB

A complete and opinionated eCommerce solution using OrderCloud as the backbone - built with .NET Core and Angular

License: MIT License

JavaScript 0.45% TypeScript 41.77% C# 32.28% HTML 23.32% SCSS 1.89% Shell 0.23% Dockerfile 0.05%
azure ordercloud-api ordercloud buyer-application ecommerce b2b b2c angular

headstart's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

headstart's Issues

Implement redirect to login on session expiration

Currently a poor UX when a session expires, multiple notifications will spawn as client-side functionality is not prevented after the first indication of session expiry. Would be good to implement this as a global error handler, however with a brief look into this it appears the javascript SDK may be preventing the buyer/seller apps from regaining control over thrown exceptions. Will need to evaluate further.

Bug - "Enable Inventory Tracking" is intermittently disabled

Steps to Reproduce

  1. Login to the Admin application as a Supplier
  2. Navigate to your Product List page
  3. Select a product, notice that the "Enable Inventory Tracking" checkbox is disabled
  4. On the same page, click to the Description tab of Product Edit
  5. Now click back to the Product tab of Product Edit
  6. View "Enable Inventory Tracking" again and notice that now the checkbox is able to be edited.

_oc.Me.GetProductAsync<HSMeProduct>(id, user.AccessToken); throwing Object not found

When in the buyer app, I click on a product and this is the network error I receive:

Data: "Object reference not set to an instance of an object."
ErrorCode: "InternalServerError"
Message: "Unknown error has occured."

Digging in a bit, it looks like like _oc.Me.GetProductAsync(id, user.AccessToken); is is not getting the product even though it shows up with the https://[middleware]/me/products query.

This is a bare bones, single product catalog with no additional properties - could that be it? Please let me know if you need more details.

Bug - Auto apply promo does not auto apply

Steps to reproduce:

  1. As an Admin user, create an Automatically applied promotion (I tested with both % off order and $ off specific item)
  2. As a Buyer, add items to cart that would trigger the promo to apply
  3. Notice that the discount does not get auto-applied at any point in checkout

New Product Form Defaults to Blank Page

When creating a new product in Headstart, the form defaults to a blank page and a user must click the appropriate tab to fill in product details.

  1. Login as an admin user to Headstart
  2. Navigate to Products > All Products
  3. Click Create New Product > Standard.
  4. Observe the form briefly display before being reduced to a single "Create" button.

image

Seller App - Prevent navigation away from 'touched' forms

When creating a new item or editing an existing item, it's easy to accidently navigate away from the form page and lose unsaved data.

Having a notification to confirm the user wishes to discard unsaved changes will improve the UX of the seller app.

Total calculation is incorrect

Even if the full discount was applied to the earrings, the Total for the line item would be incorrect and should be $0.50. The line item should have a total of $30.00, if discounts are not shown on the line items, instead of $5.00.

image

Add BOGO Promo Type

This promo type exists in another implementation. Bonus if we can just bring the BOGO Promo Type from that implementation into Headstart.

image

Bug - Default text showing throughout the RMA process

Steps to Reproduce

  1. Login as an Admin or Supplier User.
  2. Review the list of RMAs and select one to view
  3. Notice that default text is showing instead of user-friend text.

image

Make sure to check throughout the entire RMA approval process, as many of the screens are showing the default text.

Extract Sitecore.Foundation.SitecoreExtensions project from solution

The introduction of Sitecore.Foundation.SitecoreExtensions was intended to leverage the global logging mechanism, however this has introduced additional bloat and dependencies on Sitecore, which can be maintained outside of Headstart.

The proposal is to extract any agnostic logging helpers into a respective project and move the remaining Sitecore-specific helpers into a separate repo.

Replace Custom RMAs Implementation with Platform RMAs

The current RMA solution in Headstart was implemented prior to the platform RMA feature being available.

The Headstart solution should align with platform features as close as possible to demostrate/highlight platform functionality where possible.

Bug - Buyer cannot see Quote Orders

Due to the Order Search enhancements enabled in mid-March for Headstart, Buyers are not able to see their Quote Orders that are pending (Elastic Search does not allow the GET Orders call to retrieve both Submitted & Unsubmitted orders).

Steps to Reproduce

  1. As a Buyer, Submit a Quote Order with a Quote product (use the Hair Dryer chair by Supplier Beauty Buys)
  2. As the Supplier Beauty Buys, login to admin and view Quote Orders. Set a price for the recently submitted Quote order
  3. As the Buyer, go to My Orders to view the Quote amount that was set by the Supplier. You will see 0 orders here. (This is where the issues is. The Buyer cannot see any Quote Orders).

To resolve this, I believe all we need to do is add an Order.IsSubmitted=false or Order.Status=Unsubmitted filter on the Get MeOrders api call that is done when clicking on the Quote Order tab.

Bug - Incorrect formatting on Order Confirmation page

When submitting an order in Headstart, the Order Confirmation page is mis-formatted and contains translation text.

Steps to Reproduce

  1. Login as Buyer
  2. Add items to cart
  3. Go through checkout process
  4. Submit order
  5. Notice formatting and missing product information on Order Confirmation page. The only way to resolve is to refresh your browser, or log out and login again.

image

OrderController throwing 404 on PUT UpsertLineItem

When I attempt to add a product to my cart, there is a PUT something like:
/order/TieV_bI5yk-_XbAjBDUO7g/lineitems

but the reponse is:

{
  "ErrorCode": "NotFound",
  "Message": "Object not found.",
  "Data": {
    "ObjectType": "Order",
    "ObjectID": "TieV_bI5yk-_XbAjBDUO7g"
  }
}

There is actually an order with that ID in the system when looking into the API, but the method that is causing the error seems to be:
LineItemCommand.cs:
var existingLineItemsRequest = _oc.LineItems.ListAllAsync<HSLineItem>(OrderDirection.Outgoing, orderID, filters: $"Product.ID={liReq.ProductID}", accessToken: user.AccessToken);

Where the liReq.ProductID is a valid product Id.

Please let me know if you need more information.

Add ability to Sort Promos

As Marketplace Manager, I want the ability to sort and/or filter my promos so I can easily find the promos I need,

Requirements

  1. Add sorting capabilities on the Promo list page. To do this, I believe we need to add Start Date and End Date as columns in the list page so that they can be sorted by these values
  2. If possible, add a filter to this list page with the following options:
  • Active: true/false
  • Application: Auto/Code (Promo.xp.Automatic)
  • Applies to: Order/Product (Promo.xp.AppliesTo)

Add Sale Pricing Feature to Headstart

A new feature to support Sale Pricing was released to OrderCloud on March 9th. Let's add this feature to Headstart so other can try it out.

Admin Requirements - Products

  1. Allow an MPO or Supplier to set sale prices directly on products, including Start and End Date (these are new properties on Price Schedules). Ref: Exhibit 1
  2. All Price Editing permissions should stay intact (I.e. Supplier can set price on their products and MPO can override them)
  3. If Sale Price is active, show on Product Card in the Product Create/Edit Screens. Ref: Exhibit 2

Exhibit 1:
I'm envisioning just adding columns to the existing Price Table, like this:
image

Exhibit 2:
image

Admin Requirements - Orders

  1. Show on Order Line Items both the Sale Price and Regular price of the product if the Buyer got it on sale. (NOTE: this will have to be done at a later time because this data is not currently available on Order Line Items -- it's on the roadmap).

Buyer Requirements - Product Pages

  1. Show Regular Price and Sale Price on Product Cards if the Sale Price is Active. Ref: Exhibit 3
  2. Show Regular Price and Sale Price on Product Detail Page if the Sale Price is Active. Ref: Exhibit 4

Exhibit 3:
image

Exhibit 4:
image

Buyer Requirements - Checkout

  1. On cart page, display Regular and Sale price if the Sale Price is Active. Ref: Exhibit 5
  2. Do the same on the Shipping Selection section where it shows Line Items
  3. Do the same on Order Review page where it shows Line Items
  4. The platform will automatically use the sale price to calculate Line Total and Order Total. Nothing needed there.
  5. On Order Confirmation, display Regular and Sale price if the Sale Price is active. (NOTE: this will have to be done at a later time because this data is not currently available on Order Line Items -- it's on the roadmap).

Exhibit 5:
image

Other Considerations

  • Wondering how this impacts Return/Refund calculations. I'm hoping it won't impact it since the LineTotal will reflect the sale price, which is what would need to be referenced for the refund calculation
  • Add Regular & Sale Price to Order Confirmation page and Order History pages when PriceSchedule historical data is saved to LineItem/OrderWorksheet
  • Make sure that when a Sale Price expires, it is no longer showing to the Buyer (Front end price display will need to also look at PriceSchedule.IsOnSale boolean to determine whether or not to show the strikethrough pricing)

Error thrown when trying to run Headstart using Docker

When running Headstart using Docker, build is failing with the below error,
OrderCloud Docker Build Error - Imports

Steps to Reproduce:

  • Run Headstart using Docker by following the steps described here, https://github.com/ordercloud-api/headstart#docker
  • Error thrown when building seller app while running docker-compose up -d command
  • Existing users will need to take latest and run docker-compose up -d command after removing existing images (or rebuild images using docker-compose build --no-cache command) to reproduce the error

Improve Quote workflow

As a Buyer, I would like to submit a quote and receive the quote back from the Seller/Marketplace manager so that I can continue my order online and submit an order for the item at the quoted price.

Workflow:

  1. Buyer user locates a Quote product. They make their selections (often times quote products are quoted because you have custom selections which alter the state of the product), and request a quote.
  2. Buyer can see in their Order History that their quote is submitted (maybe it's not an actual submitted order, but there needs to be notation of the history of the quote request).
  3. Owner of the quote product gets notified that they have an incoming quote request
  4. Owner of the quote product sets pricing for that product for that Buyer.
  5. Owner of the quote product sends the quote back to the Buyer via some action within the application.
  6. Buyer is notified that quote has been returned, and can now see the quoted price.
  7. Buyer could write a comment back to the Owner of the product for a revised quote, and the same process would happen again. OR
  8. Buyer accepts the quoted price and submits order with the product at the quoted price.
  9. Order is processed like all other orders.

Considerations:

  • Quote products should not hold up orders of non-quote products, so I think they need to be on their own order
  • Potential to have the ability to put multiple quote products on a single order (MVP can just be a single quote product, like Headstart operates today)

Calling _portal.CreateMarketplace fails with error unless Region is specified

Using latest 'develop' and standard seed template. Calling /seed endpoint fails when creating a new Marketplace:

"Data": "Call failed with status code 400 (Bad Request): PUT https://portal.ordercloud.io/api/v1/organizations/200422f7-8adf-4fdc-bccc-08d3cfffd158"

However, if I add the code below to the "new Marketplace()" initializer:

Region = new Region()
                    {
                        AzureRegion = "westus",
                        Name = "Azure Us-West",
                        Id = "usw"
                    }

All works as expected. Is Region a required property now?

Bug - Inadvertent Supplier access to RMAs

Steps to Reproduce

  1. As a Buyer, submit an order with items from two different suppliers
  2. As each supplier, create a shipment for all the items
  3. As a Buyer, request a return for items from two different suppliers -- you'll see each time as "Return Requested"
  4. As one of the Suppliers, view the original order. Here you can see two RMAs on the order (one for Supplier 1 and one for Supplier 2). The issue is that when you click into the RMA that is not for your Supplier, you get an error.

Expected Result - As a supplier, only show the RMA link that contains my supplier items to me on the original order

Note: As a Supplier, when I view RMAs from the RMA list page, I do correctly only see the RMAs that contain my products

This view likely has something to do with showing all RMAs on an order for the MPO, so keep that in mind that the MPO should continue to see all RMAs tied to an order.

Enforce strongly typed xp on extended resource classes

Custom classes that extend a resource with a specified strongly-typed xp require the xp to be assigned in the constructor to enforce the strongly-typed xp. Currently no extended resource class adheres to this, allowing any xp to be used in code.

Prior to making the change to each class, we will need to validate that we don't introduce any data corruption to existing usages of the extended resource class or any instance of the base resource class.

The example provided in ordercloud-dotnet-sdk: Strongly Typed xp:

public class MyUser : User<MyUserXp> (
    public MyUser() {
        xp = new MyUserXp();
    }
)

public class MyUserXp
{
    public string Gender { get; set; }
}

var user = new MyUser();
user.xp.Gender = "male"; // strongly typed!

Add Clone Promo functionality

As a Marketplace Manager, I want the ability to duplicate or clone a promotion so that I can quickly make multiple promotions that are very similar.

Requirements

  1. To the Promo Detail page, add an action/button that says "Clone" or "Duplicate"
  2. Once clicked, this should bring the user to a Promotion Edit page for the new promotion, however the Name and Promo Code should be blank. All other "toggles" on the Promotion Edit page should match the previous promotion it was created from.
  3. The admin user should be able to edit anything about the promotion before saving

Docker | exchangerates/{currency} endpoint is throwing error

Hi,

I am using headstart with docker and the below endpoint throws an error:
http://api.headstart.localhost/exchangerates/USD

{
"ErrorCode": "InternalServerError",
"Message": "Unknown error has occured.",
"Data": "Connection refused"
}

This endpoint is only throwing error with Docker. When I run middleware in local using visual studio debug mode (Test profile) then there is no error. The issue is with {currency} endpoint. http://api.headstart.localhost/exchangerates/supportedrates gives the correct result. Any inputs?

Convert all xp classes into partials

To minimise null value bloat stored in xp of OrderCloud resources, we can update the strongly-typed xp classes to inherit from the OrderCloudModel and IPartial, which will remove unassigned properties during serialisation.

  • Inherit OrderCloudModel and IPartial
  • All properties getters and setters will also need to be reworked to utilise the Props dictionary.
  • The readme will need to be updated to reflect this as a standard practice.
  • Converting xp classes into partial xp classes will not allow default values to be set as this can unintentially override existing xp values during PATCH requests.
  • There is a dependency on updating the OrderCloud .NET SDK to support partial class deserialisation, before we can update xp classes to partials.

See the following example

// Before refactor
public class MyProductXp
{
    public string Note { get; set; }
    public string ProductType { get; set; }
    public bool IsNew { get; set; }
    public decimal Rating { get; set; }
}

// After refactor
public class MyProductXp : OrderCloudModel, IPartial
{
    public string Note { get => GetProp<string>("Note"); set => SetProp<string>("Note", value); }
    public string ProductType { get => GetProp<string>("ProductType"); set => SetProp<string>("ProductType", value); }
    public bool IsNew { get => GetProp<bool>("IsNew"); set => SetProp<bool>("IsNew", value); }
    public decimal Rating { get => GetProp<decimal>("Rating"); set => SetProp<decimal>("Rating", value); }
}

Improve contributions guide in readme.

  • Elaborate on Code Quality requirements using StyleCop.
  • Specify forking/branching requirements.
  • Detail commit and pull request criteria to pass PR acceptance.

Make certain Storefront configurations configurable in the Admin app

Storefronts are currently being driven by individual API clients, which we could leverage the API Client xp to drive storefront configurations, such as supported languages.

@crhistianramirez has also considered something more dynamic like mapping a domain to an API client. That requires a bit more set up the first time around but has some powerful implications. For example, if someone has a wildcard domain they could theoretically pop up new buyers pretty much at will without any kind of deployment process.

Rearchitect Middleware Solution

The current architecture of the middleware solution is difficult to work with

Current Architecture

current-middleware-architecture

Challenges with current architecture

  • Integration projects are strongly coupled to the Headstart.API and Headstart.Common.
  • Unwanted integration projects are complicated to remove from the solution.
  • Integration projects cannot reference headstart models from the Headstart.Common project. The integration-specific code currently resides in the Headstart.API and Headstart.Common projects.

Proposed Architecture

proposed-middleware-architecture

Enhancements with proposed architecture

  • Integration projects can isolate DI, which can then be referenced in the startup of the Headstart.API and Headstart.Jobs, keeping the solution more DRY.
  • Feature-specific controllers and commands will reside in their integration projects.
  • Feature projects can reference headstart models.
  • Headstart.Jobs no longer has a dependency on the Headstart.API project.
  • Added an abstract feature base layer to improve consistency in feature/integration-specific projects.
  • Simplified approach to adding integration projects.
  • Solution can employ helix principles for improved long-term maintenance.

Challenges with proposed architecture

  • Integration specific concrete classes used in headstart model xp would need to be specified in the Headstart.Common (renamed to Foundation.Headstart.Core in the diagram). xp is dynamic, so it is possible to utilise the dynamic class instead of strongly-typed classes.

Other notable proposed changes

  • The OrderCloud.Integration.Library will be split out into integration specific projects, e.g.:
    • Headstart.OrderCloud.Azure.Storage
    • Headstart.OrderCloud.Azure.CosmosDB
    • Headstart.OrderCloud.Taxation
  • Headstart.Common is changed to Foundation.Headstart.Core to provide a little better context and dissuade developers from using the project as a catch all bucket.
  • The Headstart.API and Headstart.Common projects will have features/integrations broken out into their own specific projects.
  • The following namespace naming convention will adopted <Company>.<Product>[.<Feature>][.<Subnamespace>]
    • 'Integration' is dropped from the namespace with context derived from the <Subnamespace>
    • <Company> being 'Headstart' would be swapped out for client company as part of solution getting started guide.

App Configuration import fails (AppSettingConfigTemplate.json)

I'm having trouble importing the "headstart/src/Middleware/src/Headstart.Common/AppSettingConfigTemplate.json" into my Azure App Configuration. I get the error "Keine gültige Json-Datei oder keine Elemente." (translated: "no valid json-file").

It seems to be an encoding issue, once I change this from UTF-8 BOM to UTF-8 it works.

Add Language switch function

For Seller and buyer app, I want to add language switcher function.

Requirements

  1. Buyer and Seller have language switcher.
  2. use language resource under src/Middleware/src/Headstart.Common/Assets

I made Japanese resource file and create pull request #345 to headstart/development.

Implement environment data refresh

Over time a lot of data pollution has been introduced into the headstart OrderCloud environment, which may also be impacted by breaking changes to the code base.

To remove invalid and incomplete data, not intended for demo purposes, from the solution this could either be achieved via a deployment process or a scheduled job.

This may also utilise the test data provided from #412 to be reimported after the environment data clean up process to provide a stable set of test data for demoing and learning purposes.

Add related products feature

This feature would allow admins to promote certain products and encourage customers to buy more.

To implement this we'll need to maintain product.xp.RelatedProductIDs for example:

{
    "ID": "my-awesome-product-id",
    "RelatedProductIDs": ["product1", "product2", "product3"]
}

On the admin side
this could be a simple multi-select dropdown that allows the user to search for products via the /products endpoint and upon selection patches the product to include the related product.

On the buyer side
When the user gets to the product detail page we can make a product list call via me/products with the product IDs. This would retrieve only the products the user can see and at the price they should see them at.

For example the following list call would retrieve the products (product1, product2, product3) based on visibility/pricing rules specific to that user.

/me/products?ID=product1|product2|product3

Pricing Overrides Not Working

When a user tries to set a Pricing Override for a specific buyer, the option to select a buyer to override is missing.

  1. Login to Headstart as an Admin user.
  2. Navigate to Products > All Products.
  3. Select a product.
  4. Select the Pricing tab.
  5. Under Buyer Pricing, select "Pricing Override." Note that the option to select a buyer to override is missing.

image

Critical Error Handling

It would be ideal to either display a dedicated error page or have a toaster notification when the apps are in a critical state, e.g. no defaultLanguage configuration has been provided, which throws and error and currently renders a blank screen to the user without any notification of an error occuring.

Order Submit Issue

Hi @crhistianramirez, please suggest how to place test order in development environment. we tried with dummy credit card and got "Order.CannotSubmitWithUnaccceptedPayments: Cannot submit an order with payments that have not been Accepted." error in await _oc.Orders.ValidateAsync(OrderDirection.Incoming, worksheet.Order.ID);

Create optional test data for headstart.

For demoing and quick start purposes, providing test data will allow onboarding devs to have more context towards expected entity relationships created as part of headstart, as well as a complete interactive set of data for end-to-end testing from completion of the seeding processes.

The Habitat test data is a recommended starting point for creating headstart test data as it contains quite an extensive test data that developers may also be familiar with from XC.

Allow Promo Assignment to specific Buyers

As a Marketplace Owner, I would like to create a promo and make it eligible only for a certain Buyer in my organization.

Currently, Headstart only allows that the promo is available to ALL Buyers. I'd like to also make the "specific buyers" eligibility selection available. We can skip the "Specific buyer group" eligibility at this time.

If possible, please allow multi-select so a promo can be assigned to multiple selected Buyers.

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.