{"record":{"id":"f6ae66ec60cff9bb","repo":"nopSolutions/nopCommerce","slug":"this-shipment-is-not-yet-ready-for-pickup","errorCode":null,"errorMessage":"This shipment is not yet ready for pickup","messagePattern":"This shipment is not yet ready for pickup","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Libraries/Nop.Services/Orders/OrderProcessingService.cs","lineNumber":2326,"sourceCode":"    }\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\n\r\n        //add a note\r\n        await AddOrderNoteAsync(order, $\"Shipment# {shipment.Id} has been delivered\");\r","sourceCodeStart":2308,"sourceCodeEnd":2344,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Libraries/Nop.Services/Orders/OrderProcessingService.cs#L2308-L2344","documentation":"Thrown by OrderProcessingService.DeliverAsync for an in-store-pickup order when the shipment has not yet been marked ready for pickup (ReadyForPickupDateUtc is null). The condition (order.PickupInStore && !shipment.ReadyForPickupDateUtc.HasValue) enforces the pickup lifecycle: a pickup order must first be flagged ReadyForPickup before it can be marked Delivered (i.e., handed to the customer).","triggerScenarios":"Calling DeliverAsync on a PickupInStore shipment without first calling ReadyForPickupAsync. Happens when an admin marks the order 'delivered/picked up' directly, or a webhook reports pickup before the 'ready for pickup' step was recorded.","commonSituations":"Staff handing the goods to the customer and clicking 'Delivered' without first clicking 'Ready for pickup'; an integration that only consumes a 'picked up' event and skips the ready step.","solutions":["Call ReadyForPickupAsync first: if (order.PickupInStore && !shipment.ReadyForPickupDateUtc.HasValue) await _orderProcessingService.ReadyForPickupAsync(shipment, false);","Before DeliverAsync, check shipment.ReadyForPickupDateUtc and prompt the user to mark the shipment ready first.","In the UI, hide/require the ReadyForPickup step before enabling Deliver for pickup orders.","Fix the integration to mark the shipment ready before or in the same flow as delivered."],"exampleFix":"// before\nawait _orderProcessingService.DeliverAsync(shipment, true);\n\n// after\nif (order.PickupInStore && !shipment.ReadyForPickupDateUtc.HasValue)\n    await _orderProcessingService.ReadyForPickupAsync(shipment, false);\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.ReadyForPickupDateUtc.HasValue)\n{\n    // mark ready for pickup first\n    return;\n}\n\nawait _orderProcessingService.DeliverAsync(shipment, true);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call ReadyForPickupAsync before DeliverAsync for in-store-pickup orders.","Require the ReadyForPickup step in the UI before enabling Deliver.","Integrations must mark ready before (or with) delivered."],"tags":["shipment","pickup-in-store","delivery","lifecycle"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}