Skip to content

Cart fields not updating using Delivery API #648

Description

@nunoaguiar

Is your feature request related to a problem? Please describe.

PATCH /dwapi/ecommerce/carts/{secret} accepts purchaseOrderNumber in the body, returns 200 OK with an OrderViewModel, and then throws the value away. Nothing is stored, nothing is logged, and no validation error is returned — so from an integrator's point of view the API confirms a write that never happened.

Repro:

PATCH /dwapi/ecommerce/carts/{secret}
Content-Type: application/json

{ "purchaseOrderNumber": "PO-123456" }

200 OK. A follow-up GET /dwapi/ecommerce/carts/{secret} returns "purchaseOrderNumber": null, and EcomOrders.OrderPurchaseOrderNumber is still NULL.

Root cause: CartService.UpdateCartFromModel (Dynamicweb.Ecommerce/Frontend/Cart/CartService.cs) maps ~90 view-model properties onto the Order one by one, and PurchaseOrderNumber is not among them. The rest of the round-trip is fine — OrderViewModel.PurchaseOrderNumber binds correctly, Order.PurchaseOrderNumber exists, OrderRepository writes and reads OrderPurchaseOrderNumber, and ViewEngine.CreateView fills the property on GET. The write path is the only broken link, which makes this read-only-by-accident: the value can be persisted and returned, just never set.

The same omission affects three sibling fields that are likewise present on Order, persisted by OrderRepository, and returned by GET, but dropped by PATCH:

  • reference
  • dueDate
  • shippingDate

This is the same defect class as the already-fixed customerVatRegNumber / comment regression (see UpdateCartFromModel_MapsCustomerVatRegNumberAndComment in Dynamicweb.Ecommerce.Tests/Cart/CartServiceTests.cs), so a hand-maintained mapping list drifting behind the model is a recurring source of these.

Describe the solution you'd like

  1. Map the four missing fields in UpdateCartFromModel, using the existing null-guard convention (null means "not supplied", so omitted fields are never overwritten). Place them with the other order-level scalars, after the VoucherCode block:
if (cartModel.PurchaseOrderNumber is not null)
{
    cart.PurchaseOrderNumber = cartModel.PurchaseOrderNumber;
}

if (cartModel.Reference is not null)
{
    cart.Reference = cartModel.Reference;
}

if (cartModel.DueDate is not null)
{
    cart.DueDate = cartModel.DueDate;
}

if (cartModel.ShippingDate is not null)
{
    cart.ShippingDate = cartModel.ShippingDate;
}
  1. Add a regression test alongside UpdateCartFromModel_MapsCustomerVatRegNumberAndComment, asserting all four fields survive the mapping — e.g. UpdateCartFromModel_MapsPurchaseOrderNumberReferenceAndDates.

  2. Fix a related column-name bug found while tracing persistence. OrderRepository.SafeExtractOrderRow — used by OrderService when loading order version history — reads the wrong column names:

// current
PurchaseOrderNumber = GetStringOrNull(dataRow, "PurchaseOrderNumber"),
DueDate = Converter.ToDateTime(GetStringOrNull(dataRow, "DueDate")),

// should be
PurchaseOrderNumber = GetStringOrNull(dataRow, "OrderPurchaseOrderNumber"),
DueDate = Converter.ToDateTime(GetStringOrNull(dataRow, "OrderDueDate")),

The actual columns are OrderPurchaseOrderNumber and OrderDueDate (added in EcommerceUpdateProvider). GetStringOrNull returns null for a column that isn't in the DataTable, so this fails silently: both values are always empty in the version-history view. Every other field in that same object initialiser uses the Order-prefixed column name.

No public API changes, no new members, no behavioural change for callers that don't send these fields.

Describe alternatives you've considered

  • Set the value through orderFields instead.

Additional context

Candidates that may also warrant mapping but are out of scope here: CustomerAddressId, DeliveryAddressId, LedgerType, SecondaryUserId.

Affected files:

  • src/Features/Ecommerce/Dynamicweb.Ecommerce/Frontend/Cart/CartService.csUpdateCartFromModel
  • src/Features/Ecommerce/Dynamicweb.Ecommerce/Orders/OrderRepository.csSafeExtractOrderRow
  • src/Features/Ecommerce/Dynamicweb.Ecommerce.Tests/Cart/CartServiceTests.cs — regression test

Endpoint: Dynamicweb.Frontend.Classic.Api.Ecommerce/Controllers/CartsController.csUpdateCart.

Best Regards,
Nuno Aguiar

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions