{"record":{"id":"c0268c25d482c519","repo":"nopSolutions/nopCommerce","slug":"this-shipment-is-not-shipped-yet","errorCode":null,"errorMessage":"This shipment is not shipped yet","messagePattern":"This shipment is not shipped yet","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Libraries/Nop.Services/Orders/OrderProcessingService.cs","lineNumber":2323,"sourceCode":"        }\r\n\r\n        await _eventPublisher.PublishShipmentReadyForPickupAsync(shipment);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Marks a shipment as delivered\r\n    /// </summary>\r\n    /// <param name=\"shipment\">Shipment</param>\r\n    /// <param name=\"notifyCustomer\">True to notify customer</param>\r\n    /// <returns>A task that represents the asynchronous operation</returns>\r\n    public virtual async Task DeliverAsync(Shipment shipment, bool notifyCustomer)\r\n    {\r\n        ArgumentNullException.ThrowIfNull(shipment);\r\n\r\n        var order = await _orderService.GetOrderByIdAsync(shipment.OrderId) ?? throw new Exception(\"Order cannot be loaded\");\r\n\r\n        if (!order.PickupInStore && !shipment.ShippedDateUtc.HasValue)\r\n            throw new Exception(\"This shipment is not shipped yet\");\r\n\r\n        if (order.PickupInStore && !shipment.ReadyForPickupDateUtc.HasValue)\r\n            throw new Exception(\"This shipment is not yet ready for pickup\");\r\n\r\n        if (shipment.DeliveryDateUtc.HasValue)\r\n            throw new Exception(\"This shipment is already delivered\");\r\n\r\n        shipment.DeliveryDateUtc = DateTime.UtcNow;\r\n        await _shipmentService.UpdateShipmentAsync(shipment);\r\n\r\n        if (!await _orderService.HasItemsToAddToShipmentAsync(order) &&\r\n            !await _orderService.HasItemsToShipAsync(order) &&\r\n            !await _orderService.HasItemsToReadyForPickupAsync(order) &&\r\n            !await _orderService.HasItemsToDeliverAsync(order))\r\n        {\r\n            order.ShippingStatusId = (int)ShippingStatus.Delivered;\r\n            await _orderService.UpdateOrderAsync(order);\r\n        }\r","sourceCodeStart":2305,"sourceCodeEnd":2341,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Libraries/Nop.Services/Orders/OrderProcessingService.cs#L2305-L2341","documentation":"Thrown by OrderProcessingService.DeliverAsync for a non-pickup order when the shipment has no ShippedDateUtc. It enforces the delivery lifecycle: a normal shipped order must be marked Shipped before it can be marked Delivered. The condition is (!order.PickupInStore && !shipment.ShippedDateUtc.HasValue), so it only applies to standard (non in-store-pickup) shipments.","triggerScenarios":"Calling DeliverAsync on a standard shipment whose ShipAsync has not been called (or whose ShippedDateUtc is null). Happens when an admin jumps straight to 'Deliver' from the shipment screen, or an integration tries to deliver before the carrier handoff event arrives.","commonSituations":"Custom order-fulfillment automation that skips the Ship step; a carrier webhook firing the 'delivered' event before the 'shipped' event; admin users clicking Deliver on a freshly created shipment.","solutions":["Ensure ShipAsync is called first: if (!order.PickupInStore && !shipment.ShippedDateUtc.HasValue) await _orderProcessingService.ShipAsync(shipment, true);","Inspect shipment.ShippedDateUtc before calling DeliverAsync and surface a meaningful message to the user if it is null.","If the shipment truly was shipped but the date was not recorded, backfill ShippedDateUtc then retry DeliverAsync.","Fix the integration to send events in shipped->delivered order."],"exampleFix":"// before\nawait _orderProcessingService.DeliverAsync(shipment, true);\n\n// after\nif (!order.PickupInStore && !shipment.ShippedDateUtc.HasValue)\n    await _orderProcessingService.ShipAsync(shipment, true);\n\nawait _orderProcessingService.DeliverAsync(shipment, true);","handlingStrategy":"validation","validationCode":"var order = await _orderService.GetOrderByIdAsync(shipment.OrderId);\nif (order is null) return;\nif (!order.PickupInStore && !shipment.ShippedDateUtc.HasValue)\n{\n    // must ship first\n    return;\n}\n\nawait _orderProcessingService.DeliverAsync(shipment, true);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call ShipAsync before DeliverAsync for non-pickup orders.","Hide the 'Deliver' UI action until shipment.ShippedDateUtc is set.","Order integration events as shipped -> delivered."],"tags":["shipment","delivery","workflow","lifecycle"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}