{"record":{"id":"75c70717c9b8e7df","repo":"nopSolutions/nopCommerce","slug":"this-shipment-is-can-t-be-marked-as-ready-for-pic","errorCode":null,"errorMessage":"This shipment is can't be marked as 'ready for pickup'. The order has been placed without 'pickup in store' shipping option.","messagePattern":"This shipment is can't be marked as 'ready for pickup'\\. The order has been placed without 'pickup in store' shipping option\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Libraries/Nop.Services/Orders/OrderProcessingService.cs","lineNumber":2290,"sourceCode":"\r\n        //check order status\r\n        await CheckOrderStatusAsync(order);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Marks a shipment as ready for pickup\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 ReadyForPickupAsync(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)\r\n            throw new Exception(\"This shipment is can't be marked as 'ready for pickup'. The order has been placed without 'pickup in store' shipping option.\");\r\n\r\n        if (shipment.ReadyForPickupDateUtc.HasValue)\r\n            throw new Exception(\"This shipment is already marked as 'ready for pickup'\");\r\n\r\n        shipment.ReadyForPickupDateUtc = DateTime.UtcNow;\r\n        await _shipmentService.UpdateShipmentAsync(shipment);\r\n\r\n        await AddOrderNoteAsync(order, $\"Shipment# {shipment.Id} has been ready for pickup\");\r\n\r\n        if (notifyCustomer)\r\n        {\r\n            var queuedEmailIds = await _workflowMessageService.SendShipmentReadyForPickupNotificationAsync(shipment, order.CustomerLanguageId);\r\n            if (queuedEmailIds.Any())\r\n                await AddOrderNoteAsync(order, $\"\\\"Ready for pickup\\\" email (to customer) has been queued. Queued email identifiers: {string.Join(\", \", queuedEmailIds)}.\");\r\n        }\r\n\r\n        await _eventPublisher.PublishShipmentReadyForPickupAsync(shipment);\r\n    }\r","sourceCodeStart":2272,"sourceCodeEnd":2308,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Libraries/Nop.Services/Orders/OrderProcessingService.cs#L2272-L2308","documentation":"Thrown by ReadyForPickupAsync when order.PickupInStore is false. The order was placed for physical shipping, not store pickup, so marking it 'ready for pickup' is a domain violation - the correct action is Ship. Uses plain Exception. Note the message itself contains a grammatical typo ('is can't') present in the source.","triggerScenarios":"Admin/operator or API calls ReadyForPickupAsync on a shipment whose order is a normal shipped order (PickupInStore == false). Typically operator using the wrong action, or a unified fulfilment endpoint calling ReadyForPickup unconditionally.","commonSituations":"Operator confusion between Ship and ReadyForPickup; custom integration routing all fulfilments through one method; mixed-mode orders handled by a single code path.","solutions":["For non-pickup orders, call ShipAsync instead of ReadyForPickupAsync.","Branch the fulfilment action on order.PickupInStore.","Hide/disable the ReadyForPickup button for normal shipped orders."],"exampleFix":"// before\nawait _orderProcessingService.ReadyForPickupAsync(shipment, notify);\n\n// after\nif (order.PickupInStore)\n    await _orderProcessingService.ReadyForPickupAsync(shipment, notify);\nelse\n    await _orderProcessingService.ShipAsync(shipment, notify);","handlingStrategy":"validation","validationCode":"var order = await _orderService.GetOrderByIdAsync(shipment.OrderId);\nif (order is null)\n    return BadRequest(\"Order not found.\");\nif (!order.PickupInStore)\n    return BadRequest(\"Order is not pickup-in-store; use ShipAsync.\");\n\nawait _orderProcessingService.ReadyForPickupAsync(shipment, notifyCustomer);","typeGuard":"async Task<bool> IsPickupOrderAsync(Shipment shipment)\n{\n    var order = await _orderService.GetOrderByIdAsync(shipment.OrderId);\n    return order is not null && order.PickupInStore;\n}","tryCatchPattern":"try\n{\n    await _orderProcessingService.ReadyForPickupAsync(shipment, notifyCustomer);\n}\ncatch (Exception ex) when (ex.Message.Contains(\"without 'pickup in store'\"))\n{\n    // route to the correct action\n    await _orderProcessingService.ShipAsync(shipment, notifyCustomer);\n}","preventionTips":["Branch fulfilment actions on order.PickupInStore: ReadyForPickup for pickups, Ship for deliveries.","In the admin UI, hide the ReadyForPickup control for normal shipped orders.","Train operators on the distinction, or unify fulfilment behind a dispatcher that picks the right call."],"tags":["shipment","pickup","domain-violation","fulfilment","nopcommerce"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}