Пример #1
0
        /// <inheritdoc />
        public async Task <IList <Lot> > TryGetAdjustedLots(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            string salesOrderNumber,
            string salesOrderItemNumber
            )
        {
            try
            {
                var lots = await _repository.ReadAllAsync(item => item.ItemNumber == salesOrderItemNumber).ConfigureAwait(false);

                var adjustmentTasks = lots.Select(lot => AdjustLot(
                                                      salesOrderWorkItemRepository,
                                                      salesOrderNumber,
                                                      lot
                                                      ));

                return(await Task.WhenAll(adjustmentTasks));
            }
            catch (Exception ex)
            {
                _logService.WriteErrorLogEntry($"Failed to read lots: {ex}");
                ex.Report();
                return(new List <Lot>());
            }
        }
        /// <summary>
        ///     Filter deliver sales order that has yet to be picked.
        /// </summary>
        /// <param name="salesOrderWorkItemRepository"></param>
        /// <param name="salesOrder"></param>
        /// <returns></returns>
        private async Task <SalesOrder> FilterUnPickedSalesOrder(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            SalesOrder salesOrder
            )
        {
            var atLeastOneItemPicked = await AtLeastOneSalesOrderWorkItemHasBeenPicked(
                salesOrderWorkItemRepository,
                salesOrder.SalesOrderNumber
                );

            if (!atLeastOneItemPicked)
            {
                return(null);
            }

            // The quantity is fulfilled, check the status of the work items.
            var allWorkItemsArePicked = await SalesOrderItemsAreAllOfStatus(
                salesOrderWorkItemRepository,
                salesOrder.SalesOrderNumber,
                SalesOrderWorkItemStatus.Picked
                ).ConfigureAwait(false);

            return(allWorkItemsArePicked
                   // All of the work item statuses were picked meaning could be displayed in Deliver.
                ? salesOrder
                   // Sales order pick has yet to be confirmed.
                : null);
        }
Пример #3
0
        public DashboardViewModel(
            IServiceBundle serviceBundle,
            ISalesOrderRepository salesOrderRepository,
            IInboundShipmentRepository inboundShipmentRepository,
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            ISalesOrderItemRepository salesOrderItemRepository,
            IInboundTransferRepository inboundTransferRepository,
            IConfigurationService configurationService,
            ICloudService cloudService,
            INetworkService networkService,
            ISyncService syncService,
            ILogService logService
            ) : base(serviceBundle)
        {
            _configurationService         = configurationService;
            _cloudService                 = cloudService;
            _networkService               = networkService;
            _syncService                  = syncService;
            _logService                   = logService;
            _salesOrderRepository         = salesOrderRepository;
            _inboundShipmentRepository    = inboundShipmentRepository;
            _salesOrderWorkItemRepository = salesOrderWorkItemRepository;
            _salesOrderItemRepository     = salesOrderItemRepository;
            _inboundTransferRepository    = inboundTransferRepository;

            SubscribeToEvents();
        }
 /// <inheritdoc />
 public async Task <int> TryGetUnfulfilledDeliveryCount(
     ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
     Expression <Func <SalesOrder, bool> > filter = null
     ) => (await TryGetUnfulfilledDeliveries(
               salesOrderWorkItemRepository,
               filter
               ).ConfigureAwait(false)).Count;
Пример #5
0
        /// <summary>
        ///     Adjust the provided SalesOrderItem instance by taking existing SalesOrderWorkItem
        ///     instances into account.
        /// </summary>
        /// <param name="salesOrderWorkItemRepository">An ISalesOrderWorkItemRepository instance.</param>
        /// <param name="salesOrderItem">The SalesOrderWorkItem instance to adjust.</param>
        /// <param name="salesOrderItemLotNumber">The lot number of the sales order item.</param>
        /// <returns>
        ///     An asynchronous Task that returns an adjusted SalesOrderWorkItem instance upon completion.
        /// </returns>
        private static async Task <SalesOrderItem> AdjustSalesOrderItem(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            SalesOrderItem salesOrderItem,
            string salesOrderItemLotNumber
            )
        {
            var workItems = await salesOrderWorkItemRepository.TryGetSalesOrderWorkItems(
                salesOrderItem.SalesOrderNumber,
                salesOrderItem.ItemNumber,
                salesOrderItemLotNumber
                ).ConfigureAwait(false);

            // Need to filter the workitems by OriginalSequence becuase we could have duplicate sales order items...
            workItems = workItems.Where(item => item.OriginalSequence == salesOrderItem.Seq).ToList();

            var workItemSum          = workItems.Sum(i => i.PickedQuantity);
            var workItemDeltaSum     = workItems.Sum(i => i.QuantityDelta);
            var accountedForQuantity = workItemSum + workItemDeltaSum;

            // All items accounted for set item quantity to 0.
            if (accountedForQuantity == salesOrderItem.ItemQuantity)
            {
                salesOrderItem.ItemQuantity = 0;
                return(salesOrderItem);
            }

            salesOrderItem.ItemQuantity -= workItemSum + workItemDeltaSum;

            return(salesOrderItem);
        }
 public LotSelectionViewModel(
     IServiceBundle serviceBundle,
     ILotRepository lotRepository,
     ISalesOrderWorkItemRepository salesOrderWorkItemRepository
     ) : base(serviceBundle)
 {
     _lotRepository = lotRepository;
     _salesOrderWorkItemRepository = salesOrderWorkItemRepository;
 }
Пример #7
0
 public DeliverViewModel(
     IServiceBundle serviceBundle,
     ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
     ISalesOrderRepository salesOrderRepository
     ) : base(serviceBundle)
 {
     _salesOrderWorkItemRepository = salesOrderWorkItemRepository;
     _salesOrderRepository         = salesOrderRepository;
 }
Пример #8
0
 public DeliverSalesOrderWorkItemDetailsViewModel(
     IServiceBundle serviceBundle,
     ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
     ILogService logService
     ) : base(serviceBundle)
 {
     _salesOrderWorkItemRepository = salesOrderWorkItemRepository;
     _logService = logService;
 }
 /// <inheritdoc />
 public async Task <bool> CanBatchConfirmSalesOrderPick(
     ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
     ISalesOrderItemRepository salesOrderItemRepository,
     string salesOrderNumber
     ) => (await salesOrderItemRepository.TryGetAdjustedSalesOrderItems(
               salesOrderWorkItemRepository,
               salesOrderNumber
               ).ConfigureAwait(false))
 // We are only concerned with items that had to have their lot number explicitly set.
 .Where(i => i.IsLotControlled && string.IsNullOrWhiteSpace(i.LotNumber))
 // The remaining item quantity for these items must sum to zero if they can be batch confirmed.
 .Sum(i => i.ItemQuantity) == 0;
Пример #10
0
 public SalesOrderDetailsEditViewModel(
     IServiceBundle serviceBundle,
     ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
     ISalesOrderItemRepository salesOrderItemRepository,
     ISalesOrderRepository salesOrderRepository,
     ILotRepository lotRepository
     ) : base(serviceBundle)
 {
     _salesOrderWorkItemRepository = salesOrderWorkItemRepository;
     _salesOrderItemRepository     = salesOrderItemRepository;
     _salesOrderRepository         = salesOrderRepository;
     _lotRepository = lotRepository;
 }
        /// <inheritdoc />
        public async Task <bool> IsSalesOrderQuantityFulfilled(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            ISalesOrderItemRepository salesOrderItemRepository,
            string salesOrderNumber
            )
        {
            var adjustedItems = await salesOrderItemRepository.TryGetAdjustedSalesOrderItems(
                salesOrderWorkItemRepository,
                salesOrderNumber
                ).ConfigureAwait(false);

            return(adjustedItems.Sum(i => i.ItemQuantity) <= 0);
        }
 public PickViewModel(
     IServiceBundle serviceBundle,
     ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
     ISalesOrderItemRepository salesOrderItemRepository,
     ISalesOrderRepository salesOrderRepository,
     ILogService logService
     ) : base(serviceBundle)
 {
     _salesOrderWorkItemRepository = salesOrderWorkItemRepository;
     _salesOrderItemRepository     = salesOrderItemRepository;
     _salesOrderRepository         = salesOrderRepository;
     _logService = logService;
 }
        /// <summary>
        ///     Batch confirm the sales order pick if possible. This will fulfill all sales order items that
        ///     are lot controlled and have their lot numbers set. This make it easier on the user so they don't
        ///     have to go into each sales order item and confirm it explicitly.
        /// </summary>
        /// <param name="salesOrderWorkItemRepository">An ISalesOrderWorkItemRepository instance.</param>
        /// <param name="salesOrderItemRepository">An ISalesOrderItemRepository instance.</param>
        /// <param name="salesOrderNumber">The sales order number.</param>
        /// <param name="lotRepository">An ILotRepository instance.</param>
        /// <returns>
        ///     An asynchronous Task that returns whether or not the batch confirm was successful.
        /// </returns>
        private async Task <bool> BatchConfirmSalesOrderPick(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            ISalesOrderItemRepository salesOrderItemRepository,
            ILotRepository lotRepository,
            string salesOrderNumber
            )
        {
            // Check if we can batch confirm the sales order.
            var canBatchConfirm = await CanBatchConfirmSalesOrderPick(
                salesOrderWorkItemRepository,
                salesOrderItemRepository,
                salesOrderNumber
                );

            // Can't batch confirm, do nothing.
            if (!canBatchConfirm)
            {
                return(false);
            }

            // Only lot controlled items with their lot numbers set from Cresco should remain.
            var adjustedItems = (await salesOrderItemRepository.TryGetAdjustedSalesOrderItems(
                                     salesOrderWorkItemRepository,
                                     salesOrderNumber
                                     ).ConfigureAwait(false))
                                // We only want lot controlled items with remaining quantities. These will unconfirmed
                                // read-only items pulled down from Cresco.
                                .Where(i => i.IsLotControlled &&
                                       !string.IsNullOrWhiteSpace(i.LotNumber) &&
                                       i.ItemQuantity != 0 ||
                                       (!i.IsLotControlled && i.ItemQuantity != 0)
                                       ).ToList();

            // Create a work item for each sales order that was lot controlled with a lot number set.
            await Task.WhenAll(adjustedItems.Select(item => salesOrderWorkItemRepository.TryUpsertSalesOrderWorkItem(
                                                        this,
                                                        salesOrderItemRepository,
                                                        lotRepository,
                                                        SalesOrderWorkflow.Pick,
                                                        salesOrderNumber,
                                                        item.ItemNumber,
                                                        item.Seq,
                                                        item.LotNumber,
                                                        item.LotNumber,
                                                        item.ItemQuantity,
                                                        item.ItemQuantity,
                                                        item.ItemQuantity
                                                        )));

            return(true);
        }
        public async Task IssueDeliveryNotification(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            ISalesOrderRepository salesOrderRepository,
            string salesOrderNumber,
            bool sendToCustomer,
            bool sendToSalesRep
            )
        {
            var salesOrder = await salesOrderRepository.TryGetSalesOrder(salesOrderNumber).ConfigureAwait(false);

            if (
                salesOrder == null ||
                (string.IsNullOrWhiteSpace(salesOrder.SalesRepMobileNumber) &&
                 (string.IsNullOrWhiteSpace(salesOrder.CustomerMobileNumber)))
                )
            {
                return;
            }

            var workItems = await salesOrderWorkItemRepository.TryGetSalesOrderWorkItems(salesOrderNumber).ConfigureAwait(false);

            // No work items (weird), do nothing.
            if (workItems.Count == 0)
            {
                return;
            }

            var notesWorkItemTable = await PinnacleApp.Get <ICloudService>().GetTableAsync <NoteWorkItem>();

            var noteItems = (await notesWorkItemTable.ReadItemsAsync(
                                 0,
                                 int.MaxValue,
                                 item => item.NoteParentFk == salesOrderNumber
                                 ).ConfigureAwait(false)).ToList();

            var salesOrderDelivery = BuildDeliveryRecord(salesOrder, workItems, noteItems, sendToCustomer, sendToSalesRep);

            var deliveryString = JsonConvert.SerializeObject(salesOrderDelivery);

            if (_networkService.IsConnected)
            {
                //await SendMessage(deliveryString).ConfigureAwait(false);
                await ProcessUnsentDeliveryNotification().ConfigureAwait(false);
            }
            else
            {
                await _salesOrderDeliveryRepository.CreateAsync(new SalesOrderDeliveryString { Body = deliveryString }).ConfigureAwait(false);
            }
        }
Пример #15
0
 public SalesOrderDetailsViewModel(
     IServiceBundle serviceBundle,
     ISalesOrderRepository salesOrderRepository,
     ISalesOrderItemRepository salesOrderItemRepository,
     ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
     ILotRepository lotRepository,
     ISyncService syncService
     ) : base(serviceBundle)
 {
     _salesOrderRepository         = salesOrderRepository;
     _salesOrderItemRepository     = salesOrderItemRepository;
     _salesOrderWorkItemRepository = salesOrderWorkItemRepository;
     _lotRepository = lotRepository;
     _syncService   = syncService;
 }
Пример #16
0
        /// <inheritdoc />
        public async Task <Lot> TryGetLotAdjusted(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            string salesOrderNumber,
            string lotNumber,
            string salesOrderItemNumber
            )
        {
            var lot = await TryGetLot(lotNumber, salesOrderItemNumber).ConfigureAwait(false);

            return(await AdjustLot(
                       salesOrderWorkItemRepository,
                       salesOrderNumber,
                       lot
                       ).ConfigureAwait(false));
        }
 public SubmitViewModel(
     IServiceBundle serviceBundle,
     ILogService logService,
     ICloudService cloudService,
     IInboundTransferRepository inboundTransferRepository,
     IInboundShipmentRepository inboundShipmentRepository,
     ISalesOrderWorkItemRepository salesOrderWorkItemRepository
     ) : base(serviceBundle)
 {
     _logService   = logService;
     _cloudService = cloudService;
     _inboundTransferRepository    = inboundTransferRepository;
     _inboundShipmentRepository    = inboundShipmentRepository;
     _salesOrderWorkItemRepository = salesOrderWorkItemRepository;
 }
 public DeliverSalesOrderConfirmViewModel(
     IServiceBundle serviceBundle,
     ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
     ISignatureWorkItemRepository signatureWorkItemRepository,
     ISalesOrderRepository salesOrderRepository,
     ISalesOrderDeliveryNotificationRepository salesOrderDeliveryNotificationRepositoy,
     ISyncService syncService
     ) : base(serviceBundle)
 {
     _salesOrderWorkItemRepository            = salesOrderWorkItemRepository;
     _signatureWorkItemRepository             = signatureWorkItemRepository;
     _salesOrderRepository                    = salesOrderRepository;
     _salesOrderDeliveryNotificationRepositoy = salesOrderDeliveryNotificationRepositoy;
     _syncService = syncService;
 }
        /// <summary>
        ///     Determine if any of the work items related to a sales order number have
        ///     been picked. This is done using the PickedWhen property.
        /// </summary>
        /// <param name="salesOrderWorkItemRepository">An ISalesOrderWorkItemRepository instance.</param>
        /// <param name="salesOrderNumber">The sales order number of the order to check.</param>
        /// <returns>If at least one picked, true. Else, false.</returns>
        private async Task <bool> AtLeastOneSalesOrderWorkItemHasBeenPicked(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            string salesOrderNumber
            )
        {
            if (string.IsNullOrWhiteSpace(salesOrderNumber))
            {
                return(false);
            }

            var workItems = await salesOrderWorkItemRepository.TryGetSalesOrderWorkItems(
                salesOrderNumber
                );

            return(workItems.Any(i => i.PickedWhen != null));
        }
        /// <inheritdoc />
        private async Task <bool> PickedSalesOrderItemsHaveLocationSet(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            string salesOrderNumber
            )
        {
            if (string.IsNullOrWhiteSpace(salesOrderNumber))
            {
                return(false);
            }

            var workItems = await salesOrderWorkItemRepository.TryGetSalesOrderWorkItems(
                salesOrderNumber
                ).ConfigureAwait(false);

            return(workItems.Count > 0 &&
                   workItems.All(item => (item.PickedLatitude != 0.0) && (item.PickedLongitude != 0.0)));
        }
        /// <inheritdoc />
        public async Task <bool> CompleteSalesOrderDelivery(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            ISignatureWorkItemRepository signatureWorkItemRepository,
            bool isDriverSignature,
            string salesOrderNumber,
            string encodedSignature,
            bool sendNotification = true
            )
        {
            // Signature is required, do nothing.
            if (string.IsNullOrWhiteSpace(encodedSignature))
            {
                return(false);
            }

            var workItems = await salesOrderWorkItemRepository.TryGetSalesOrderWorkItems(salesOrderNumber).ConfigureAwait(false);

            // No work items (weird), do nothing.
            if (workItems.Count == 0)
            {
                return(false);
            }

            var position = await _locationService.GetPositionAsync().ConfigureAwait(false);

            var userId = _configurationService.GetString(Constants.Config.UserId);

            // Set all sales order work item instances to delivered state.
            await Task.WhenAll(workItems.Select(item => SetSalesOrderWorkItemToDelivered(
                                                    salesOrderWorkItemRepository,
                                                    item,
                                                    position,
                                                    userId
                                                    )));

            // Create a new SignatureWorkItem instance.
            await signatureWorkItemRepository.TryCreateSignatureWorkItem(new SignatureWorkItem
            {
                SalesOrderNumber      = salesOrderNumber,
                EncodedSignatureImage = encodedSignature,
                IsDriverSignature     = isDriverSignature,
                SendNotification      = sendNotification
            }).ConfigureAwait(false);

            return(true);
        }
        /// <inheritdoc />
        public async Task ConfirmSalesOrderPick(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            ISalesOrderItemRepository salesOrderItemRepository,
            ILotRepository lotRepository,
            SalesOrder salesOrder
            )
        {
            var canBatchConfirm = await CanBatchConfirmSalesOrderPick(
                salesOrderWorkItemRepository,
                salesOrderItemRepository,
                salesOrder.SalesOrderNumber
                ).ConfigureAwait(false);

            // We can batch confirm so do it.
            if (canBatchConfirm)
            {
                await BatchConfirmSalesOrderPick(
                    salesOrderWorkItemRepository,
                    salesOrderItemRepository,
                    lotRepository,
                    salesOrder.SalesOrderNumber
                    ).ConfigureAwait(false);
            }

            var isFulfilled = await IsSalesOrderQuantityFulfilled(
                salesOrderWorkItemRepository,
                salesOrderItemRepository,
                salesOrder.SalesOrderNumber
                ).ConfigureAwait(false);

            // Sales order is not fulfilled, do nothing.
            if (!isFulfilled)
            {
                return;
            }

            // Get the device position.
            var position = await _locationService.GetPositionAsync().ConfigureAwait(false);

            // Set all of the work items to picked along with the device location.
            await salesOrderWorkItemRepository.TryConfirmSalesOrderWorkItems(
                salesOrder.SalesOrderNumber,
                position
                ).ConfigureAwait(false);
        }
Пример #23
0
        /// <inheritdoc />
        public async Task <IList <SalesOrderItem> > TryGetAdjustedSalesOrderItems(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            string salesOrderNumber
            )
        {
            var salesOrderItems = await TryGetSalesOrderItems(salesOrderNumber).ConfigureAwait(false);

            var adjustmentTasks = salesOrderItems
                                  .Select(async item => await AdjustSalesOrderItem(
                                              salesOrderWorkItemRepository,
                                              item,
                                              item.LotNumber
                                              ).ConfigureAwait(false));

            return(await Task.WhenAll(
                       adjustmentTasks
                       ));
        }
        /// <inheritdoc />
        public async Task <bool> SalesOrderItemsAreAllOfStatus(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            string salesOrderNumber,
            SalesOrderWorkItemStatus status
            )
        {
            if (string.IsNullOrWhiteSpace(salesOrderNumber))
            {
                return(false);
            }

            var workItems = await salesOrderWorkItemRepository.TryGetSalesOrderWorkItems(
                salesOrderNumber
                ).ConfigureAwait(false);

            return(workItems.Count > 0 &&
                   workItems.All(item => item.Status == status));
        }
Пример #25
0
        /// <summary>
        ///     Adjust the provided Lot instance using any existing work items.
        /// </summary>
        /// <param name="salesOrderWorkItemRepository">An ISalesOrderWorkItemRepository instance.</param>
        /// <param name="salesOrderNumber">The sales order number.</param>
        /// <param name="lot">The lot.</param>
        /// <returns>An asynchronous Task that returns an adjusted Lot on completion.</returns>
        private static async Task <Lot> AdjustLot(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            string salesOrderNumber,
            Lot lot
            )
        {
            if (lot == null)
            {
                return(null);
            }

            var salesOrderWorkItems = (await salesOrderWorkItemRepository.TryGetSalesOrderWorkItems(
                                           salesOrderNumber,
                                           lot.ItemNumber
                                           )).Where(i => i.LotNumber == lot.LotNumber);

            // Adjust the lot quantity by subtracting the sum of sales order work item quantities.
            lot.Quantity -= salesOrderWorkItems.Sum(i => i.PickedQuantity);

            return(lot);
        }
        /// <inheritdoc />
        public async Task <IList <SalesOrder> > TryGetUnfulfilledPicks(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            ISalesOrderItemRepository salesOrderItemRepository,
            Expression <Func <SalesOrder, bool> > filter = null
            )
        {
            // Get all sales orders
            var salesOrders = filter == null
                ? await _repository.ReadAllAsync().ConfigureAwait(false)
                : await _repository.ReadAllAsync(filter).ConfigureAwait(false);

            var result = await Task.WhenAll(salesOrders.Select(async s => await FilterUnfulfilledSalesOrderPick(
                                                                   salesOrderWorkItemRepository,
                                                                   salesOrderItemRepository,
                                                                   s
                                                                   )));

            return(result
                   .Where(i => i != null)
                   .ToList());
        }
        /// <summary>
        ///     Set the provided SalesOrderWorkItem insance to delivered. This is done by updating the
        ///     item delivered latitude and longitude properties as well as its status.
        /// </summary>
        /// <param name="salesOrderWorkItemRepository">An ISalesOrderWorkItemRepository instnace.</param>
        /// <param name="salesOrderWorkItem">The item to set as delivered.</param>
        /// <param name="position">The location of the device at the time of delivery.</param>
        /// <returns>An asynchronous Task.</returns>
        private static async Task SetSalesOrderWorkItemToDelivered(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            SalesOrderWorkItem salesOrderWorkItem,
            Location position,
            string deliveredByUser
            )
        {
            salesOrderWorkItem.DeliveredLatitude  = position?.Latitude ?? 0;
            salesOrderWorkItem.DeliveredLongitude = position?.Longitude ?? 0;
            salesOrderWorkItem.DeliveredBy        = deliveredByUser;
            salesOrderWorkItem.DeliveredByName    = PinnacleApp.Get <IAuthService>().CurrentUser.Name;
            salesOrderWorkItem.DeliveredWhen      = DateTime.UtcNow;
            if (salesOrderWorkItem.DeliveredQuantity == 0)
            {
                salesOrderWorkItem.DeliveredQuantity = salesOrderWorkItem.PickedQuantity;
            }

            salesOrderWorkItem.Status = SalesOrderWorkItemStatus.Delivered;

            await salesOrderWorkItemRepository
            .TryUpdateSalesOrderWorkItem(salesOrderWorkItem).ConfigureAwait(false);
        }
        /// <inheritdoc />
        public async Task <IList <SalesOrder> > TryGetUnfulfilledDeliveries(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            Expression <Func <SalesOrder, bool> > filter = null
            )
        {
            // Get all sales orders
            var salesOrders = filter == null
                ? await _repository.ReadAllAsync().ConfigureAwait(false)
                : await _repository.ReadAllAsync(filter).ConfigureAwait(false);

            var filterResults = await Task.WhenAll(salesOrders.Select(async salesOrder =>
                                                                      await FilterUnPickedSalesOrder(
                                                                          salesOrderWorkItemRepository,
                                                                          salesOrder
                                                                          )

                                                                      ));

            return(filterResults
                   .Where(salesOrder => salesOrder != null)
                   .ToList());
        }
Пример #29
0
        /// <inheritdoc />
        public async Task <SalesOrderItem> TryGetAdjustedSalesOrderItem(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            string salesOrderNumber,
            string salesOrderItemNumber,
            string salesOrderItemLotNumber,
            int seq
            )
        {
            var salesOrderItem = await TryGetSalesOrderItem(
                salesOrderNumber,
                salesOrderItemNumber,
                salesOrderItemLotNumber,
                seq
                ).ConfigureAwait(false);

            return(salesOrderItem == null
                ? null
                : await AdjustSalesOrderItem(
                       salesOrderWorkItemRepository,
                       salesOrderItem,
                       salesOrderItemLotNumber
                       ).ConfigureAwait(false));
        }
        /// <summary>
        ///     Filter pick sales order that has yet to be fulfilled or confirmed.
        /// </summary>
        /// <param name="salesOrderWorkItemRepository"></param>
        /// <param name="salesOrderItemRepository"></param>
        /// <param name="salesOrder"></param>
        /// <returns></returns>
        private async Task <SalesOrder> FilterUnfulfilledSalesOrderPick(
            ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
            ISalesOrderItemRepository salesOrderItemRepository,
            SalesOrder salesOrder
            )
        {
            // TODO: THIS IS A HACK TO PREVENT WORK ITEMS FROM MOVING FROM DELIVER BACK TO PICK.
            // The reason this exists is because we don't have a way, or the time, to track the status
            // outside of the work items. What we really need to do is create a sales order table and
            // track the status seperately.
            var atLeastOneItemPicked = await AtLeastOneSalesOrderWorkItemHasBeenPicked(
                salesOrderWorkItemRepository,
                salesOrder.SalesOrderNumber
                ).ConfigureAwait(false);

            if (atLeastOneItemPicked)
            {
                return(null);
            }

            var isFulfilled = await IsSalesOrderQuantityFulfilled(
                salesOrderWorkItemRepository,
                salesOrderItemRepository,
                salesOrder.SalesOrderNumber
                );

            // Quantity not fulfilled, return unfulfilled sales order.
            if (!isFulfilled)
            {
                return(salesOrder);
            }
            else
            {
                // Even if the quantities are fulfilled, we want to return the salesOrder
                // if the picked position is empty on any workitem
                var allPickedWorkItemsHaveLocation = await PickedSalesOrderItemsHaveLocationSet(
                    salesOrderWorkItemRepository,
                    salesOrder.SalesOrderNumber
                    ).ConfigureAwait(false);

                if (!allPickedWorkItemsHaveLocation)
                {
                    return(salesOrder);
                }
            }

            // The quantity is fulfilled, check the status of the work items.
            var allWorkItemsArePicked = await SalesOrderItemsAreAllOfStatus(
                salesOrderWorkItemRepository,
                salesOrder.SalesOrderNumber,
                SalesOrderWorkItemStatus.Picked
                ).ConfigureAwait(false);

            var allWorkItemsAreDelivered = await SalesOrderItemsAreAllOfStatus(
                salesOrderWorkItemRepository,
                salesOrder.SalesOrderNumber,
                SalesOrderWorkItemStatus.Delivered
                ).ConfigureAwait(false);

            return(allWorkItemsArePicked || allWorkItemsAreDelivered
                   // All of the work item statuses were picked or delivered, meaning fulfilled.
                ? null
                   // Sales order pick has yet to be confirmed.
                : salesOrder);
        }