예제 #1
0
        /// <summary>
        /// 为出库单分配库存。
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="outboundOrder">要分配库存的出库单</param>
        /// <param name="options">分配选项</param>
        public async Task AllocateAsync(OutboundOrder outboundOrder, AllocatStockOptions options)
        {
            if (outboundOrder == null)
            {
                throw new ArgumentNullException(nameof(outboundOrder));
            }
            if (outboundOrder.Closed)
            {
                throw new InvalidOperationException("出库单已关闭");
            }
            if (options == null)
            {
                options = new AllocatStockOptions();
            }
            options.Normalize();

            _logger.Information("正在为出库单 {outboundOrderCode} 分配库存", outboundOrder.OutboundOrderCode);
            _logger.Information("区域:{areas}", options.Areas == null ? "" : string.Join(", ", options.Areas));
            //_logger.Information("跳过脱机的巷道:{skipOfflineLaneways}", options.SkipOfflineLaneways);
            //_logger.Information("排除的巷道:{excludeLanewasys}", string.Join(", ", options.ExcludeLaneways.Select(x => x.LanewayCode)));
            _logger.Information("包含的托盘:{includePallets}", string.Join(", ", options.IncludePallets));
            _logger.Information("排除的托盘:{excludePallets}", string.Join(", ", options.ExcludePallets));
            //_logger.Information("跳过禁止出站的货位:{skipLocationsOutboundDisabled}", options.SkipLocationsOutboundDisabled);

            foreach (var line in outboundOrder.Lines)
            {
                await ProcessLineAsync(line, options).ConfigureAwait(false);
            }
        }
예제 #2
0
        /// <summary>
        /// 处理单个出库行
        /// </summary>
        /// <param name="line">出库行</param>
        /// <param name="laneways">用于分配的货载所在的巷道</param>
        /// <param name="includeUnitloads">要在分配中包含的货载,这些货载优先参与分配。</param>
        /// <param name="excludeUnitloads">要在分配中排除的货载,这些货载不会参与分配,即使出现在 includeUnitloads 中,也不参与分配。</param>
        async Task ProcessLineAsync(OutboundLine line, AllocatStockOptions options)
        {
            _logger.Information("正在为出库单明细 {outboundLine} 分配库存", line);

            {
                var shortage = line.ComputeShortage();
                _logger.Debug("出库单明细 {outboundLine} 的分配欠数是 {shortage}", line, shortage);
                if (shortage <= 0)
                {
                    _logger.Debug("不需要分配");
                    return;
                }
            }

            // 显式包含的货载项
            List <UnitloadItem> included = new List <UnitloadItem>();

            if (options.IncludePallets.Length > 0)
            {
                included = await _session.Query <UnitloadItem>()
                           .Where(x => options.IncludePallets.Contains(x.Unitload.PalletCode) &&
                                  x.Material == line.Material)
                           .ToListAsync()
                           .ConfigureAwait(false);
            }
            // 库内候选项
            var candidateItems = _session
                                 .Query <UnitloadItem>()
                                 .Where(x =>
                                        included.Contains(x) == false && // 显式包含的货载项已在上面处理过,这里需排除
                                        x.Material == line.Material)
                                 .OrderBy(x => x.OutOrdering)
                                 .ThenBy(x => x.Unitload.CurrentLocation.Cell.oByShape)
                                 .ThenBy(x => x.Unitload.CurrentLocation.Cell.o1)
                                 .ThenBy(x => x.Unitload.CurrentLocation.Rack.Deep)
                                 .LoadInChunksAsync(options.ChunkSize);

            await foreach (var item in Union(included, candidateItems))
            {
                if (item.Quantity == 0)
                {
                    _logger.Warning("货载项 {unitloadItem} 的数量为 0", item);
                    continue;
                }

                var taken = await AllocateItemAsync(line, item, options);

                var shortage = line.ComputeShortage();
                _logger.Debug("出库单明细 {outboundLine} 的分配欠数是 {shortage}", line, shortage);
                if (shortage <= 0)
                {
                    _logger.Information("出库单明细 {outboundLine} 分配库存完成", line);
                    return;
                }
            }

            _logger.Information("出库单明细 {outboundLine} 分配库存完成", line);