Advertisement
Guest User

Untitled

a guest
Mar 20th, 2018
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 21.55 KB | None | 0 0
  1.         /// <summary>
  2.         /// Pobranie rekomendowanej lokalozacji
  3.         /// </summary>
  4.         /// <param name="article"></param>
  5.         /// <param name="lot"></param>
  6.         /// <param name="inboundMappingId"></param>
  7.         /// <param name="suListUserInOrderByUser"></param>
  8.         /// <param name="neededArticleVolume"></param>
  9.         /// <param name="currentLoc"></param>
  10.         /// <param name="locationType">Jeśli chcemy konkretny typ lokalizacji inny niz dtInboundMapping, jeśli nie wybieramy Undefined </param>
  11.         /// <param name="confirmPickReason"></param>
  12.         /// <returns></returns>
  13.         public dtLocation GetRecommendedLocation(dtArticle article, dtLot lot, long inboundMappingId, long[] suListUserInOrderByUser, decimal? neededArticleVolume, dtLocation currentLoc, LocationType? locationType, ConfirmPickingReason? confirmPickReason = ConfirmPickingReason.OK)
  14.         {
  15.             dtLocation recommendedLocation = null;
  16.             var mapping = Model.dtInboundMapping.FirstOrDefault(d => d.Id == inboundMappingId);
  17.  
  18.             //dla klienta Pneumat specjalna metoda szukania proponowanego miejsca - bez inbound mapping, z wieloma typami miejsc
  19.             if (FormicaConfig.Common.ProductOwner == ProductOwner.PNE || FormicaConfig.Common.ProductOwner == ProductOwner.KON || FormicaConfig.Common.ProductOwner == ProductOwner.HTL || FormicaConfig.Common.ProductOwner == ProductOwner.JUM)
  20.             {
  21.                 var articleVolume = neededArticleVolume ?? 0;
  22.  
  23.                 //pula miejsc z wyliczoną dostępną objętością - niezablokowane, niepełne, niezarezerwowane, nieinwentaryzowane, określonych typów
  24.                 var locations = Model.dtLocation.Where(loc => loc.Blocked == LocationBlocked.No && !loc.IsFull
  25.                                                               && !loc.IsVirtual
  26.                                                               && loc.Status != LocationStatus.RESERVED
  27.                                                               && !loc.StocktakingPos.Any(
  28.                                                                   x => x.Stocktaking.StocktakingType ==
  29.                                                                        StocktakingType.Place
  30.                                                                        && x.Stocktaking.Status != StocktakingStatus
  31.                                                                            .Cancelled
  32.                                                                        && x.Stocktaking.Status != StocktakingStatus
  33.                                                                            .Finished)
  34.                                                               && ((locationType == LocationType.Undefined  //dla przyjeć w HTL nie sprawdza tego warunku
  35.                                                                     && FormicaConfig.Common.ProductOwner == ProductOwner.HTL)
  36.                                                                     || loc.OwnerZone.TreeNames.Contains(dtOwnerZone.TREE_SEPARATOR +mapping.OwnerZone.Name + dtOwnerZone.TREE_SEPARATOR))
  37.                                                               && ((locationType == LocationType.Undefined && loc.LocationType ==
  38.                                                                    mapping.LocationType) || loc.LocationType ==
  39.                                                                   locationType)
  40.                 ).Select(loc =>
  41.                         //nowy obiekt - informacja o lokalizacji i dostępnej objętości
  42.                         new
  43.                         {
  44.                             location = loc,
  45.                             availableVolume =
  46.                             loc.Volume ??
  47.                             0 //wyliczenie dostępnego miejsca z objętości lokalizacji i pozycji jednostek
  48.                             - (loc.Su.Any(
  49.                                 su => su.SuPos.Any(
  50.                                     sp => sp.Lot.Article.ArticleBarcode.Any(ac => ac.Volume.HasValue)))
  51.                                 ? loc.Su.Sum(
  52.                                     su => su.SuPos.Sum(
  53.                                         sp => sp.Quantity *
  54.                                               sp.Lot.Article.ArticleBarcode.FirstOrDefault(ac => ac.Volume.HasValue)
  55.                                                   .Volume)).Value
  56.                                 : (decimal)0)
  57.                         }).ToList();
  58.  
  59.                 //Dodatkowe warunki w przypadku ponownego wyszukiwania lokalizacji
  60.                 //1. Zaproponuj następną jednostkę (inną niż ostatnio)
  61.                 if (confirmPickReason == Wms.Common.Classes.Rpm.ConfirmPickingReason.NextLocation && currentLoc != null)
  62.                 {
  63.                     locations = locations.Except(locations.Where(x => x.location.Id == currentLoc.Id)).ToList();
  64.                 }
  65.                 //2. Zaproponuj większą jednostkę niż ostatnio wybrana
  66.                 if (confirmPickReason == Wms.Common.Classes.Rpm.ConfirmPickingReason.BiggerLocation)
  67.                 {
  68.                     locations = locations.Except(locations.Where(x => x.availableVolume <= currentLoc.Volume)).ToList();
  69.                 }
  70.  
  71.  
  72.                 //1. Miejsca z danym artykułem
  73.                 recommendedLocation = locations.Where(l => l.location.Su.Any(s => s.SuPos.Any(sp => sp.Lot.fkArticleId == article.Id))
  74.                                                         && l.availableVolume >= articleVolume)
  75.                                                .OrderBy(l => l.availableVolume).ThenBy(l => l.location.PickPath).Select(l => l.location).FirstOrDefault();
  76.  
  77.                 //2. Miejsce wolne
  78.                 if (recommendedLocation == null)
  79.                     recommendedLocation = locations.Where(l => !l.location.Su.Any(s => s.SuPos.Any()) && l.availableVolume >= articleVolume)
  80.                                                    .OrderBy(l => l.availableVolume).ThenBy(l => l.location.PickPath).Select(l => l.location).FirstOrDefault();
  81.  
  82.                 //3. Miejsce z innym artykułem, pod warunkiem, że miejsce jest "wieloasortymentowe"
  83.                 if (recommendedLocation == null)
  84.                     recommendedLocation = locations.Where(l => l.location.MixOnLocation == MixOnLocation.MixedLotMixedArticle
  85.                                                             && l.availableVolume >= articleVolume)
  86.                                                    .OrderBy(l => l.availableVolume).ThenBy(l => l.location.PickPath).Select(l => l.location).FirstOrDefault();
  87.  
  88.                 //4. Największe miejsce w magazynie
  89.                 if (recommendedLocation == null)
  90.                 {
  91.                     recommendedLocation = locations.Where(l => (!l.location.Su.Any(s => s.SuPos.Any()) ||
  92.                                                                 l.location.MixOnLocation == MixOnLocation.MixedLotMixedArticle)
  93.                                                             && l.availableVolume >= articleVolume)
  94.                                                    .OrderByDescending(l => l.availableVolume).ThenBy(l => l.location.PickPath).Select(l => l.location).FirstOrDefault();
  95.                 }
  96.  
  97.                 // 6. Jeśli nie znaleziono miejsca na przełożenie całej ilości to sprawdzamy czy możemy dołożyć coś do miejsca, na którym znajduje się artykuł bądź do miejsca
  98.                 // z największą dostępną pojemnością
  99.                 if (recommendedLocation == null)
  100.                 {
  101.                     //// 5.1 Najpierw dla tego samego artykułu
  102.                     //recommendedLocation = locations.Where(l => l.location.TD_SU.Any(s => s.TD_SU_POS.Any(sp => sp.TD_LOT.TD_ARTICLE_ID == article.TD_ARTICLE_ID)))
  103.                     //                               .OrderByDescending(l => l.availableVolume).ThenBy(l => l.location.PICK_PATH).Select(l => l.location).FirstOrDefault();
  104.  
  105.                     //// 5.2 Jeśli nie było to największe dostępne
  106.                     //if (recommendedLocation == null)
  107.                     //{
  108.  
  109.                     var allAvialabled = locations
  110.                         .Where(l => !l.location.Su.Any(s => s.SuPos.Any()) ||
  111.                                     l.location.MixOnLocation == MixOnLocation.MixedLotMixedArticle)
  112.                         .OrderByDescending(l => l.availableVolume)
  113.                         .ThenBy(l => l.location.PickPath)
  114.                         .Select(l => l.location);
  115.  
  116.                     recommendedLocation = allAvialabled.FirstOrDefault(d => d.PickPriority != 0);
  117.                     //jeśli nie znaleziono żadnego miejsca z PickPriority != 0
  118.                     if (recommendedLocation == null)
  119.                     {
  120.                         recommendedLocation = allAvialabled.FirstOrDefault();
  121.                     }
  122.                 }
  123.  
  124.                 return recommendedLocation;
  125.             }
  126.             //pozostali klienci - dotychczasowe rozwiązanie
  127.             else
  128.             {
  129.                 bool newLot = lot == null;
  130.                 long? lotId = (newLot ? (long?)null : lot.Id);
  131.                 //   var destLocationType = destLocationTypes.FirstOrDefault();
  132.                 //  var inboundMapping = Model.dtInboundMapping.FirstOrDefault(x => x.LocationType == destLocationType);
  133.                 //   var zoneId = inboundMapping != null ? inboundMapping.fkOwnerZoneId : -1;
  134.  
  135.                 // Pula miejsc docelowych.
  136.                 var locations = (newLot ?
  137.  
  138.                                 //zapytanie dla nowotworzonej partii    
  139.  
  140.                                 ((from loc in Model.dtLocation
  141.                                       // Lokalizacja musi byc niezablokowana, niepelna, w dobrym statusie.
  142.                                   where loc.Blocked == LocationBlocked.No
  143.                                   where !loc.IsVirtual
  144.                                   where !loc.IsFull
  145.                                   where loc.Status != LocationStatus.RESERVED
  146.                                   where loc.fkOwnerZoneId == mapping.fkOwnerZoneId
  147.                                   where loc.LocationType != LocationType.ZoneOut
  148.                                   // musi być zmapowana strefa
  149.                                   where loc.fkOwnerZoneId != null && loc.OwnerZone.InboundMapping.Any(im => im.Id == inboundMappingId)
  150.                                   // Lokalizacja nie jest inwentaryzowana
  151.                                   where !Model.dtStocktakingPos.Any(x => x.Stocktaking.StocktakingType == StocktakingType.Place
  152.                                                                           && x.Stocktaking.Status != StocktakingStatus.Cancelled
  153.                                                                           && x.Stocktaking.Status != StocktakingStatus.Finished
  154.                                                                           && x.fkLocationId == loc.Id)
  155.                                   // Lista pozycji jednostek na tej lokalizacji.
  156.                                   let suPosList = loc.Su.SelectMany(el => el.SuPos)
  157.                                   // Nie mieszaj grup artykulowych.
  158.                                   where suPosList.All(el => el.Lot.Article.fkOwnerWarehouseId == article.fkOwnerWarehouseId)
  159.                                   // Nie mieszaj partii.
  160.                                   where suPosList.All(el => el.Lot.fkArticleId != article.Id) // Nowa partia - nie moze byc takiego artykulu
  161.                                   // Posortuj lokalizacje - zapelniaj zawsze w takim samym porzadku.
  162.                                   //orderby loc.AISLE, loc.X, loc.Y, loc.Z
  163.                                   select new
  164.                                   {
  165.                                       loc = loc,
  166.                                       availableVolume = loc.Volume  //wyliczenie dostępnego miejsca z objętości lokalizacji i pozycji jednostek
  167.                                                                           - (loc.Su.Any(su => su.SuPos.Any(sp => sp.Lot.Article.ArticleBarcode.Any(ac => ac.Volume.HasValue))) ?
  168.                                                                               loc.Su.Sum(su => su.SuPos.Sum(sp => sp.Quantity * sp.Lot.Article.ArticleBarcode.FirstOrDefault(ac => ac.Volume.HasValue).Volume)).Value
  169.                                                                           : (decimal)0)
  170.                                   }).Distinct())
  171.                                  :
  172.  
  173.                                  //Zapytanie dla istniejącej partii
  174.  
  175.                                  ((from loc in Model.dtLocation
  176.                                        // Znajdz strefe dla destLocationType
  177.                                        // Lokalizacja musi byc niezablokowana, niepelna, w dobrym statusie.
  178.                                    where loc.Blocked == LocationBlocked.No
  179.                                    where !loc.IsVirtual
  180.                                    where !loc.IsFull
  181.                                    where loc.Status != LocationStatus.RESERVED
  182.                                    where loc.fkOwnerZoneId == mapping.fkOwnerZoneId
  183.                                    where loc.LocationType != LocationType.ZoneOut
  184.  
  185.                                    // musi być zmapowana strefa
  186.                                    where loc.fkOwnerZoneId != null && loc.OwnerZone.InboundMapping.Any(im => im.Id == inboundMappingId)
  187.                                    // Lokalizacja nie jest inwentaryzowana
  188.                                    where !Model.dtStocktakingPos.Any(x => x.Stocktaking.StocktakingType == StocktakingType.Place
  189.                                                                            && x.Stocktaking.Status != StocktakingStatus.Cancelled
  190.                                                                            && x.Stocktaking.Status != StocktakingStatus.Finished
  191.                                                                            && x.fkLocationId == loc.Id)
  192.                                    // Lista pozycji jednostek na tej lokalizacji.
  193.                                    let suPosList = loc.Su.SelectMany(el => el.SuPos)
  194.                                    // Nie mieszaj grup artykulowych.
  195.                                    where suPosList.All(el => el.Lot.Article.fkOwnerWarehouseId == article.fkOwnerWarehouseId)
  196.                                    // Nie mieszaj partii.
  197.                                    where suPosList.Where(el => el.Lot.fkArticleId == article.Id).All(el => el.fkLotId == lotId) // Partia ustalona - musi byc tylko taka partia
  198.                                    // Posortuj lokalizacje - zapelniaj zawsze w takim samym porzadku.
  199.                                    //orderby loc.AISLE, loc.X, loc.Y, loc.Z
  200.                                    select new
  201.                                    {
  202.                                        loc = loc,
  203.                                        availableVolume = loc.Volume  //wyliczenie dostępnego miejsca z objętości lokalizacji i pozycji jednostek
  204.                                                                           - (loc.Su.Any(su => su.SuPos.Any(sp => sp.Lot.Article.ArticleBarcode.Any(ac => ac.Volume.HasValue))) ?
  205.                                                                               loc.Su.Sum(su => su.SuPos.Sum(sp => sp.Quantity * sp.Lot.Article.ArticleBarcode.FirstOrDefault(ac => ac.Volume.HasValue).Volume)).Value
  206.                                                                           : (decimal)0)
  207.                                    }).Distinct()));
  208.  
  209.                 //Dodatkowe warunki w przypadku ponownego wyszukiwania lokalizacji
  210.                 //1. Zaproponuj następną jednostkę (inną niż ostatnio)
  211.                 if (confirmPickReason == Wms.Common.Classes.Rpm.ConfirmPickingReason.NextLocation && currentLoc != null)
  212.                 {
  213.                     locations = locations.Except(locations.Where(x => x.loc.Id == currentLoc.Id));
  214.                 }
  215.                 //2. Zaproponuj większą jednostkę niż ostatnio wybrana
  216.                 if (confirmPickReason == Wms.Common.Classes.Rpm.ConfirmPickingReason.BiggerLocation)
  217.                 {
  218.                     locations = locations.Except(locations.Where(x => x.availableVolume <= currentLoc.Volume));
  219.                 }
  220.  
  221.                 // 1. Miejsce, które posiada wystarczającą ilość miejsca (objętości) do przyjęcia artykułu
  222.                 if (neededArticleVolume != null)
  223.                 {
  224.                     // bierzemy tylko miejsca, które mają możliwą do określenia pojemność
  225.                     var locs = locations.Where(d => d.loc.Container != null &&
  226.                         d.loc.Container.Height != null &&
  227.                         d.loc.Container.Width != null &&
  228.                         d.loc.Container.Length != null).ToList();
  229.  
  230.                     var locationsWithVolume = locs.Select(y => y.loc).Select(loc =>
  231.                     {
  232.                         var totalVolume = loc.fkContainerId == null ? null : loc.Container.Height * loc.Container.Width * loc.Container.Length;
  233.                         var occupiedVolume = loc.Su.SelectMany(d => d.SuPos).Sum(d => GetArticleVolume(d.Lot.Article, d.Quantity)) ?? 0;
  234.  
  235.                         return new
  236.                         {
  237.                             location = loc,
  238.                             totalVolume = totalVolume,
  239.                             occupiedVolume = occupiedVolume,
  240.                             freeVolume = totalVolume - occupiedVolume,
  241.                             enoughFreeSpace = (totalVolume - occupiedVolume) >= neededArticleVolume
  242.                         };
  243.                     }
  244.                     ).ToList();
  245.  
  246.                     locationsWithVolume = (from l in locationsWithVolume
  247.                                            orderby l.enoughFreeSpace ? 0 : 1, // sortujemy wedlug tego czy zmiesci sie tam nasz artykul
  248.                                            l.location.Su.Any(su => suListUserInOrderByUser.Contains(su.Id)) ? 0 : 1, // czy aktywny uzytkownik juz przyjal taka partie na to miejsce
  249.                                            l.location.Su.Any(su => su.SuPos.Any(el => el.fkLotId == lot.Id)) ? 0 : 1, // czy taka partia jest na tym miejscu
  250.                                            l.freeVolume descending, // jesli nie ma lokalizacji gdzie sie zmiesci, to najpierw bierzemy te o najwiekszej ilosci miejsca
  251.                                            l.location.PickPath, l.location.Aisle, l.location.X, l.location.Y, l.location.Z
  252.                                            select l).Distinct().ToList();
  253.  
  254.                     recommendedLocation = locationsWithVolume.Select(d => d.location).FirstOrDefault();
  255.                 }
  256.  
  257.                 // 2. Miejsce na ktore uzytkownik juz przyjal taka partie w ramach tego zlecenia.
  258.                 if ((recommendedLocation == null) && (lot != null) && suListUserInOrderByUser.Any())
  259.                 {
  260.  
  261.                     var recommendedLocations = (from location in locations.Select(x => x.loc)
  262.                                                 from su in location.Su
  263.                                                 where suListUserInOrderByUser.Contains(su.Id)
  264.                                                 where su.SuPos.Any(el => el.fkLotId == lot.Id)
  265.                                                 orderby location.PickPath, location.Aisle, location.X, location.Y, location.Z
  266.                                                 select location).Distinct().FirstOrDefault();
  267.  
  268.                     recommendedLocation = recommendedLocations;
  269.                 }
  270.  
  271.                 // 3. Miejsce z taka sama partia.
  272.                 if ((recommendedLocation == null) && (lot != null))
  273.                 {
  274.                     var recommendedLocations = (from location in locations.Select(x => x.loc)
  275.                                                 from su in location.Su
  276.                                                 where su.SuPos.Any(el => el.fkLotId == lot.Id)
  277.                                                 orderby location.PickPath, location.Aisle, location.X, location.Y, location.Z
  278.                                                 select location).Distinct().FirstOrDefault();
  279.  
  280.                     recommendedLocation = recommendedLocations;
  281.                 }
  282.  
  283.                 // 4. Miejsce puste.
  284.                 if (recommendedLocation == null)
  285.                 {
  286.                     var recommendedLocations = (from location in locations.Select(x => x.loc)
  287.                                                 where location.Status == LocationStatus.FREE
  288.                                                 orderby location.PickPath, location.Aisle, location.X, location.Y, location.Z
  289.                                                 select location).FirstOrDefault();
  290.  
  291.                     recommendedLocation = recommendedLocations;
  292.                 }
  293.  
  294.                 // 5. Miejsce pelne ale nie z tym artykulem (nie mieszamy partii).
  295.                 if (recommendedLocation == null)
  296.                 {
  297.                     var recommendedLocations = (from location in locations.Select(x => x.loc)
  298.                                                 from su in location.Su
  299.                                                 where su.SuPos.All(el => el.Lot.fkArticleId != article.Id)
  300.                                                 orderby location.PickPath, location.Aisle, location.X, location.Y, location.Z
  301.                                                 select location).Distinct().FirstOrDefault();
  302.  
  303.                     recommendedLocation = recommendedLocations;
  304.                 }
  305.  
  306.                 return recommendedLocation;
  307.             }
  308.         }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement