Ejemplo n.º 1
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();
        }
Ejemplo n.º 2
0
 public SalesController(ISalesIndentRepository indrepo,
                        ISalesIndentItemRepository inditemrepo,
                        ISalesOrderRepository order,
                        ISalesOrderItemRepository orderitem,
                        IDeliveryOrderRepository Deliveryorder,
                        IDeliveryOrderItemRepository Deliveryorderitem,
                        IDeliveryChallanRepository challan,
                        ISalesInvoiceRepository invoicerepo,
                        ISalesReturnRepository retrn,
                        ISalesReturnItemRepository returnitem,
                        IInventoryItemRepository itemrepo,
                        IDistributorRepository disrepo)
 {
     ind_repo               = indrepo;
     ind_item_repo          = inditemrepo;
     order_repo             = order;
     orderitem_repo         = orderitem;
     Deliveryorder_repo     = Deliveryorder;
     Deliveryorderitem_repo = Deliveryorderitem;
     challan_repo           = challan;
     Invoice_repo           = invoicerepo;
     return_repo            = retrn;
     returnitem_repo        = returnitem;
     item_repo              = itemrepo;
     dis_repo               = disrepo;
 }
Ejemplo n.º 3
0
 public SalesOrderItemService(ISalesOrderItemRepository salesorderitemRepository, IUnitOfWork unitOfWork, IGetAllItemsFromStkDistrbtnRepository GetAllItemsFromStkDistrbtnRepository, IGetItemCodesByQuotAndItemCodeRepository GetItemCodesByQuotAndItemCodeRepository)
 {
     this._salesorderitemRepository = salesorderitemRepository;
     this._unitOfWork = unitOfWork;
     this._GetAllItemsFromStkDistrbtnRepository    = GetAllItemsFromStkDistrbtnRepository;
     this._GetItemCodesByQuotAndItemCodeRepository = GetItemCodesByQuotAndItemCodeRepository;
 }
        /// <inheritdoc />
        public async Task <SalesOrderWorkItem> TryUpsertSalesOrderWorkItem(
            ISalesOrderRepository salesOrderRepository,
            ISalesOrderItemRepository salesOrderItemRepository,
            ILotRepository lotRepository,
            SalesOrderWorkflow workflow,
            string salesOrderNumber,
            string salesOrderItemNumber,
            int seq,
            string salesOrderItemLotNumber,
            string updatedLotNumber,
            decimal itemQuantity,
            decimal updatedItemQuantity,
            decimal quantityTaken,
            string salesOrderWorkItemId = null)
        {
            SalesOrderWorkItem salesOrderWorkItem;

            if (!string.IsNullOrWhiteSpace(salesOrderWorkItemId))
            {
                salesOrderWorkItem = await TryUpdateSalesOrderWorkItem(
                    workflow,
                    salesOrderWorkItemId,
                    updatedLotNumber,
                    updatedItemQuantity,
                    quantityTaken
                    ).ConfigureAwait(false);
            }
            else
            {
                salesOrderWorkItem = await TryCreateSalesOrderWorkItem(
                    salesOrderRepository,
                    salesOrderItemRepository,
                    lotRepository,
                    salesOrderNumber,
                    salesOrderItemNumber,
                    seq,
                    salesOrderItemLotNumber,
                    updatedLotNumber,
                    itemQuantity,
                    updatedItemQuantity,
                    quantityTaken
                    ).ConfigureAwait(false);
            }

            if (itemQuantity != updatedItemQuantity)
            {
                //await _syncService.SyncWithRemoteAsync().ConfigureAwait(false);

                await _salesOrderUpdateNotificationRepository.IssueSalesOrderUpdateNotification(
                    salesOrderRepository,
                    salesOrderWorkItem,
                    workflow,
                    itemQuantity,
                    updatedItemQuantity
                    ).ConfigureAwait(false);
            }

            return(salesOrderWorkItem);
        }
 /// <inheritdoc />
 public async Task <int> TryGetUnfulfilledPickedCount(
     ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
     ISalesOrderItemRepository salesOrderItemRepository,
     Expression <Func <SalesOrder, bool> > filter = null
     ) => (await TryGetUnfulfilledPicks(
               salesOrderWorkItemRepository,
               salesOrderItemRepository,
               filter
               ).ConfigureAwait(false)).Count;
 /// <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;
 public PickViewModel(
     IServiceBundle serviceBundle,
     ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
     ISalesOrderItemRepository salesOrderItemRepository,
     ISalesOrderRepository salesOrderRepository,
     ILogService logService
     ) : base(serviceBundle)
 {
     _salesOrderWorkItemRepository = salesOrderWorkItemRepository;
     _salesOrderItemRepository     = salesOrderItemRepository;
     _salesOrderRepository         = salesOrderRepository;
     _logService = logService;
 }
        /// <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);
        }
Ejemplo n.º 9
0
 public SalesOrderDetailsEditViewModel(
     IServiceBundle serviceBundle,
     ISalesOrderWorkItemRepository salesOrderWorkItemRepository,
     ISalesOrderItemRepository salesOrderItemRepository,
     ISalesOrderRepository salesOrderRepository,
     ILotRepository lotRepository
     ) : base(serviceBundle)
 {
     _salesOrderWorkItemRepository = salesOrderWorkItemRepository;
     _salesOrderItemRepository     = salesOrderItemRepository;
     _salesOrderRepository         = salesOrderRepository;
     _lotRepository = lotRepository;
 }
        /// <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);
        }
Ejemplo n.º 11
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;
 }
        /// <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);
        }
 public SalesOrderWorkItemRepository(
     IConfigurationService configurationService,
     ISalesOrderUpdateNotificationRepository salesOrderUpdateNotificationRepository,
     ISalesOrderItemRepository salesOrderItemRepository,
     ICloudService cloudService,
     ISyncService syncService,
     ILogService logService,
     string userIdConfigKey
     )
 {
     _configurationService = configurationService;
     _cloudService         = cloudService;
     _syncService          = syncService;
     _logService           = logService;
     _userIdConfigKey      = userIdConfigKey;
     _salesOrderUpdateNotificationRepository = salesOrderUpdateNotificationRepository;
     _salesOrderItemRepository = salesOrderItemRepository;
 }
        /// <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>
        ///     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);
        }
        /// <inheritdoc />
        public async Task <SalesOrderWorkItem> TryCreateSalesOrderWorkItem(
            ISalesOrderRepository salesOrderRepository,
            ISalesOrderItemRepository salesOrderItemRepository,
            ILotRepository lotRepository,
            string salesOrderNumber,
            string salesOrderItemNumber,
            int seq,
            string salesOrderItemLotNumber,
            string updatedLotNumber,
            decimal itemQuantity,
            decimal updatedItemQuantity,
            decimal quantityTaken
            )
        {
            // Read all dependencies for creating a new work item.
            var salesOrder = await salesOrderRepository.TryGetSalesOrder(salesOrderNumber).ConfigureAwait(false);

            var adjustedSalesOrderItem = await salesOrderItemRepository
                                         .TryGetAdjustedSalesOrderItem(
                this,
                salesOrderNumber,
                salesOrderItemNumber,
                salesOrderItemLotNumber,
                seq
                ).ConfigureAwait(false);

            var lot = await lotRepository.TryGetLot(
                updatedLotNumber ?? salesOrderItemLotNumber,
                salesOrderItemNumber
                ).ConfigureAwait(false);

            var setSequenceNumberToZero = await ItemExistsWithSalesOrderNumberAndSequence(
                salesOrderNumber,
                adjustedSalesOrderItem.Seq
                ).ConfigureAwait(false);

            var userName = PinnacleApp.Get <IAuthService>().CurrentUser.Name;
            // Try to insert the newly created record.
            var workItem = SalesOrderWorkItemFactory.CreateSalesOrderWorkItem(
                setSequenceNumberToZero,
                salesOrder,
                adjustedSalesOrderItem,
                lot,
                itemQuantity,
                updatedItemQuantity,
                quantityTaken,
                _configurationService.GetString(_userIdConfigKey),
                userName
                );

            try
            {
                var table = await GetCloudTable().ConfigureAwait(false);

                return(await table.CreateItemAsync(workItem).ConfigureAwait(false));
            }
            catch (Exception ex)
            {
                _logService.WriteErrorLogEntry($"Failed to upsert SalesOrderWorkItem instance: {ex}");
                ex.Report();
                return(null);
            }
        }