Skocz do zawartości

Użycie partii, zarezerwowanych w WZ

Polecane posty

Za pomocą rozwiązania Sferycznego, tworzę dokumenty WZ. Do pozycji tych dokumentów, pobieram pozycje ZK w następujący sposób:

var zamowienie = zamowienia.Dane.Wszystkie().Where(p => p.Id == posdocid).FirstOrDefault(); // znalezienie zamówienia
wz.Dane.StatusDokumentu = statusyDD.Rozchod_Odlozony; // ustawienie odłożonego statusu dokumentu
var poz = wz.WypelnijNaPodstawieZK(zamowienie.Pozycje.Where(p => p.Id == posid),zamowienie,parametryGrupowania).Single(); // dodanie pozycji z ZK
poz.Ilosc = 0; // ustawiamy na 0, wyjdzie z rozbicia
wz.Dane.StatusDokumentu = statusyDD.Rozchod_WydanyTowar; // przywrócenie statusu powodującego rezerwacje
wz.Przelicz();

Po wybraniu pozycji, rozbijam ją i przypisuje do niej ilość dla wybranej partii, kodem:

r.Pozycje.Where(p => p.PartiaZrodlowa.Id == posbatch).FirstOrDefault().Ilosc = posq;

I tutaj jest mój problem. W przypadku, gdy na zamówieniu źródłowym, z którego wziąłem pozycje, był status Pełna lub Częściowa rezerwacja dostaw, otrzymuje błąd na wprowadzaniu wartości pozycji "Ilość musi mieścić się w zakresie [0, 0]". Domyślam się, że wynika to z tego, że ZK zarezerwowało partię, którą chcę użyć w wystawiającym je WZ. Jak temu zaradzić?

Link to postu

Nie rozumiem, mam tą część kodu wcześniej jeśli o to chodzi:

IDokumentZRozbiciem dok = (IDokumentZRozbiciem)wz;

... czy tutaj powienienem coś zmienić:

var r = dok.RozpocznijRozbicie(poz) as IRozbiciePozycjiRozchodowe;

 

Wstawiam całą część kodu obsługującego partie, celem naświetlenia sytuacji:

// wypełnienie pozycji
foreach(var posadd in results.pos)
{
// dane pozycji do wprowadzenia
int posdocid; int posid; decimal posq; int posbatch;
posdocid = posadd.docid; posid = posadd.id; posq = posadd.quantity; posbatch = posadd.batch;
                  		
var zamowienie = zamowienia.Dane.Wszystkie().Where(p => p.Id == posdocid).FirstOrDefault(); // znalezienie zamówienia
wz.Dane.StatusDokumentu = statusyDD.Rozchod_Odlozony; // ustawienie odłożonego statusu dokumentu
var poz = wz.WypelnijNaPodstawieZK(zamowienie.Pozycje.Where(p => p.Id == posid),zamowienie,parametryGrupowania).Single(); // dodanie pozycji z ZK
Console.WriteLine("Dodanie pozycji: "+posid);
//var iloscWJednostceBazowej = poz.IloscWJednostceBazowej; // zapamiętanie ilości dodanej pierwotnie
//poz.Ilosc = posq;
//poz.IloscWJednostceBazowej = posq;
//poz.Ilosc = 
poz.Ilosc = 0; // ustawiamy na 0, wyjdzie z rozbicia
wz.Dane.StatusDokumentu = statusyDD.Rozchod_WydanyTowar; // przywrócenie statusu powodującego rezerwacje
wz.Przelicz();
                  	       
//var r = (IRozbiciePozycjiRozchodowe)dok.RozpocznijRozbicie(poz);
//r.Pozycje.Where(p => p.PartiaZrodlowa.Id == posbatch).FirstOrDefault().Ilosc = posq;
//r.ZakonczRozbicie();  
// IDokumentZRozbiciem dok = (IDokumentZRozbiciem)wz;
var r = dok.RozpocznijRozbicie(poz) as IRozbiciePozycjiRozchodowe;
var countZero = r.Pozycje.Where(p => p.Ilosc > 0).Count();
for(int i=1;i<=countZero;i++) { r.Pozycje.Where(p => p.Ilosc > 0).FirstOrDefault().Ilosc = 0; } // bardzo brunde roziwązanie, ale działa
Console.WriteLine("Wprowadzenie partii: "+posbatch+" w ilości "+posq);
r.Pozycje.Where(p => p.PartiaZrodlowa.Id == posbatch).FirstOrDefault().Ilosc = posq;
Console.WriteLine("Partia wprowadzona: "+posbatch);
r.ZakonczRozbicie();
wz.Przelicz();
}

 

Link to postu

Mamy 2 sztuki asortymentu na magazynie. Handlowiec wystawia ZK i wybiera status Rezerwacja stanów.

 

Logistyk, za pomocą rozwiązania sferycznego, zatwierdza WZ - tworzę WZ, a potem metodą WypelnijNaPodstawieZK wstawiam pozycję z ZK. Następnie rozbijam pozycje i wskazuje dokładnie tą samą partię, która była wskazana na ZK. Sfera odrzuca mi ilość, informując że dla wybranej partii ilość wynosi 0 - tak jakby nie zdjął tej rezerwacji z pozycji ZK, w momencie użycia jej przez mnie do WZ. Problem nie występuje w Insert nexo - dopuszcza działanie na tych wierszach.

Edytowane przez Radomił Ząbik
Link to postu

Na ZK powstają rezerwacje. Jeśli wykona się WypelnijNaPodstawieZK to powinny one zostać przejęte przez tworzoną WZ. Oczywiście przekazanie rezerwacji na rozchody powinno nastąpić przy zapisie. Odkładanie skutku magazynowego, tak jak w cytowanym kodzie, może jedynie zaburzyć ten proces. Generalnie sferycznie powinno się odtworzyć proces taki jaki jest w UI - operator nie odkłada skutku magazynowego na WZ na czas dodawania pozycji.

Link to postu

Zmiana na odłożony skutek magazynowy, powstała na waszą sugestię - z tego co pamiętam, chodziło o to, że pobranie pozycji z ZK, automatycznie przypisywało jakieś partie, niekoniecznie te zarezerwowane, co potem powodowało, że zostawały one w rozbiciu i jak na rozbiciu wskazywałem już konkretne partie, to robiła mi się podwójna ilość na WZ. Dlatego wchodzi skutek odłożony, zmiana ilości na 0, a potem zmieniam skutek na wydany towar.

 

Co do działania w UI, to jak robię zrealizuj jako WZ, to ma ona status odłożonego skutku magazynowego. Muszę go przestawić na wydany towar, aby można było działać na partiach.

Link to postu

No to musielibyśmy wrócić do tamtego problemu i odtworzyć o co chodziło. W tej chwili rozumiem, że ma zostać wystawiona WZ do ZK i przejąć jej rezerwacje. Przynajmniej u mnie w UI (dane prezentacyjne) tak to działa, że dodaję nową partię prze PW, rezerwuję ją na ZK i przy zrealizuj jako WZ (WZ domyślnie wywołuje skutek magazynowy) rozbicie pozycji na WZ jest prawidłowe - tzn. rozchodowuje dokładnie wskazaną partię.

Link to postu

Niestety, ta konwersacja była prowadzona przez mechanizm sugestii, więc nie wiem, czy będzie to czytelne, ale spróbuje:

 

Sfera, tworzę WZ i dodaję do niej pozycję na podstawie ZK, metodą WypelnijNaPodstawieZK, po czym zmieniam ilość realizowaną na mniejszą, bo np. jest częściowa realizacja dla klienta. Wszystko działa, ale jak następnie chcę wybrać konkretne partie w rozbiciu, to mają one już wybrane ilości do tej pierwotnej ilość na podstawie ZK. W efekcie muszę je pierw wyzerować, a dopiero następnie wybrać odpowiednią ilość wybranej przez mnie partii. Albo to jest błąd, albo założone działanie, w każdym razie przydała by się moim zdaniem metoda, zerująca całkowicie wybrane partie, celem ustalenia ich na nowo. Poniżej kod wraz z "brudnym" rozwiązaniem, którym obecnie zeruję partie:

var zamowienie = zamowienia.Dane.Wszystkie().Where(p => p.Id == posdocid).FirstOrDefault(); // znalezienie zamówienia wz.WypelnijNaPodstawieZK(zamowienie.Pozycje.Where(p => p.Id == posid),zamowienie); // dodanie pozycji z ZK

var poz = wz.Dane.Pozycje.LastOrDefault(); // wybranie dodanej pozycji poz.Ilosc = posq; wz.Przelicz();

var r = dok.RozpocznijRozbicie(poz) as IRozbiciePozycjiRozchodowe;

var countZero = r.Pozycje.Where(p => p.Ilosc > 0).Count(); for(int i=1;i<=countZero;i++) { r.Pozycje.Where(p => p.Ilosc > 0).FirstOrDefault().Ilosc = 0; } // bardzo brunde roziwązanie, ale działa

r.Pozycje.Where(p => p.PartiaZrodlowa.Id == posbatch).FirstOrDefault().Ilosc = poz.IloscWJednostceBazowej; r.ZakonczRozbicie(); wz.Przelicz();

 

Takie działanie jest jak najbardziej wskazane, ponieważ WZ ma domyślnie ustawiony status powodujący rezerwowanie towarów. Dodanie pozycji z ilością z ZK powoduje więc od razu zarezerwowanie i to od razu widać właśnie w rozbiciu. To daje gwarancję, że ten towar nam nie zniknie z magazynu bez kontroli. Jeśli się teraz, po zmniejszeniu ilości na pozycji, taką WZ zapisze, to nadmiar zostanie automatycznie zwolniony i zostanie wydane z magazynu tyle ile jest na pozycji. Jeśli chce się wpływać na ilość i na rozbicie to należy ustawić status WZ na odłożony, na czas wypełniania pozycji, żeby WZ sama nie robiła rezerwacji i żeby nie trzeba było z tym walczyć. Po ustawieniu ilości na 0 można przywrócić stan, żeby zaczął działać ruch na magazynie i ustawić odpowiednie rozbicie, a co za tym idzie – ilość na pozycji:

 

var zamowienie = zamowienia.Dane.Wszystkie().Where(p => p.Id == posdocid).FirstOrDefault(); // znalezienie zamówienia

var status = wz.Dane.StatusDokumentu; // zapamiętanie statusu dokumentu

wz.Dane.StatusDokumentu = statusyDD.Rozchod_Odlozony; // ustawienie statusu niepowodującego rezerwacji

var poz = wz.WypelnijNaPodstawieZK(zamowienie.Pozycje.Where(p => p.Id == posid),zamowienie).Single(); // dodanie pozycji z ZK

var iloscWJednostceBazowej = poz.IloscWJednostceBazowej; // zapamiętujemy tę wartość

poz.Ilosc = 0m; // na pozycji ustawiamy ilość 0, bo zostanie ona ustawiona na podstawie rozbicia

wz.Dane.StatusDokumentu = status; // przywrócenie oryginalnego statusu (powodującego rezerwację)

var r = (IRozbiciePozycjiRozchodowe)dok.RozpocznijRozbicie(poz);

r.Pozycje.Where(p => p.PartiaZrodlowa.Id == posbatch).FirstOrDefault().Ilosc = iloscWJednostceBazowej;

r.ZakonczRozbicie(); // ilość na pozycji zostanie zaktualizaowana do sumy ilości w rozbiciu

 

Jeśli chce się operować bez wyłączania mechanizmu rezerwacji, to faktycznie wyzerowanie pozycji rozbicia jest najlepszym rozwiązaniem, aczkolwiek nie wymaga ono, naszym zdaniem, dodatkowej metody. Tym sposobem omawianą operację można wykonać następująco:

 

var zamowienie = zamowienia.Dane.Wszystkie().Where(p => p.Id == posdocid).FirstOrDefault(); // znalezienie zamówienia

var poz = wz.WypelnijNaPodstawieZK(zamowienie.Pozycje.Where(p => p.Id == posid),zamowienie).Single(); // dodanie pozycji z ZK

var r = (IRozbiciePozycjiRozchodowe)dok.RozpocznijRozbicie(poz);

foreach (var pr in r.Pozycje.Where(p => p.Ilosc > 0))

    pr.Ilosc = 0m;

r.Pozycje.Where(p => p.PartiaZrodlowa.Id == posbatch).FirstOrDefault().Ilosc = poz.IloscWJednostceBazowej;

r.ZakonczRozbicie();

 

Należy tylko pamiętać, że to nie jest rozwiązanie optymalne, ponieważ w trakcie działania wymaga kilku dodatkowych zapisów do bazy związanych z rezerwacjami.

Link to postu

Wydaje mi się, że nie do końca się zrozumieliśmy. W tej chwili mam taki obraz sytuacji, tzn. tak rozumiem scenariusz:

1. Wystawiamy ZK z pełną rezerwacją (na konkretne partie).

2. Realizujemy ZK za pomocą WZ, ale nie w całości tylko częściowo, wykorzystując rezerwacje zrobione przez ZK.

 

W UI zrobiłbym to tak, że dodałbym nowe WZ dla kontrahenta. Potem dodawałbym pozycje z listy pozycji zamówień do realizacji, wchodziłbym w rozbicie takiej pozycji i zmniejszałbym ilość na wybranej partii (do ustalonego poziomu realizacji) a zerował (albo też odpowiednio zmniejszał) na pozostałych. Po zakończeniu rozbicia na pozycji, ilość jest aktualizowana do sumy ilości podanych w rozbiciu.

Po zapisaniu takiej WZ wydaje ona z partii wcześniej zarezerwowanych przez ZK tyle ile wpisałem, a na ZK zostaje zarezerwowana niewydana reszta.

 

Jeśli o to chodzi to sferycznie zrobiłbym dokładnie tak samo, bez sztucznego zerowania wszystkiego, bo to właśnie doprowadza do "odczepienia" WZ od rezerwacji z ZK.

Czyli na nowododanej WZ ze statusem wydania towarów dodaję nową pozycję na podstawie (WypelnijNaPodstawie) odnalezionej pozycji z ZK i to powoduje wstawienia pozycji na WZ, która w pełni wydaje towary. Teraz rozpoczynam rozbicie. Wyszukuję partię, która mnie interesuje i ustawiam dla niej żądaną ilość. Zeruję ilości na pozostałych pozycjach rozbicia. W ten sposób działam tak jak w UI i to się musi udać. Po zakończeniu rozbicia ilość na pozycji jest aktualizowana, a po zapisie WZ żądane partie są wydawane, a na ZK zostaje zarezerwowana niezrealizowana reszta.

Po zmodyfikowaniu wcześniej wpisanego kodu:

// wypełnienie pozycji
foreach (var posadd in results.pos)
{
    // dane pozycji do wprowadzenia
    int posdocid; int posid; decimal posq; int posbatch;
    posdocid = posadd.docid; posid = posadd.id; posq = posadd.quantity; posbatch = posadd.batch;

    var poz = wz.WypelnijNaPodstawieZK(zamowienie.Pozycje.Where(p => p.Id == posid), zamowienie, parametryGrupowania).Single(); // dodanie pozycji z ZK
    Console.WriteLine("Dodanie pozycji: " + posid);

    var r = dok.RozpocznijRozbicie(poz) as IRozbiciePozycjiRozchodowe;
    Console.WriteLine("Wprowadzenie partii: " + posbatch + " w ilości " + posq);
    r.Pozycje.Where(p => p.PartiaZrodlowa.Id == posbatch).Single().Ilosc = posq;
    foreach (var pozr in r.Pozycje.Where(p => p.PartiaZrodlowa.Id != posbatch && p.Ilosc > 0m))
        pozr.Ilosc = 0m;
    Console.WriteLine("Partia wprowadzona: " + posbatch);
    r.ZakonczRozbicie();
    wz.Przelicz();
}

 

Link to postu

Jeszcze nie zdążyłem wprowadzić rozwiązania - cały czas pracują, nie chcę rozwalić. Wprowadzę w weekend. Ale mam inny, bardzo ciekawy scenariusz, który wczoraj wynikł.

 

Mamy zamówienie, na którym handlowiec wprowadził Asortymenty A, w dwóch pozycjach: LP 1, 1000kg oraz  LP 2, 2000kg - dwie pozycje, ze względu na to, że są inne warunki cenowe dla obu. Przychodzi towar do tego zamówienia, zamówiony poprzez ZD, partia AAA w ilości 2000kg oraz partia BBB w ilości 1000kg - kolejność wejścia partii jest ważna. Rozpoczynamy realizację WZ. Jako, że mamy status do wydania, Nexo podłącza na rozbicia partii w kolejności FIFO (tak mi się wydaje, ale mogę się mylić). Więc mamy tak:

LP 1 = 1000kg z partii AAA

LP 2 = 1000kg z partii AAA oraz 1000 kg z partii BBB

Oczywiście, jeśli nie będziemy mieli zarezerwowanego stanu na ZK, to jako, że Sferą wczytuje pozycję po pozycji, powinno udać mi się te partie podpiąć, w odróżnieniu do UI Nexo, które podczas przetwarzania w WZ, doda od razu obie pozycje i podepnie wstępną rezerwację, przez co jedyną drogą jest wyzerowanie wszystkich rozbić i ustawienie ich na nowo. No ale jak będziemy mieli jednak rezerwację na ZK, to pojawia się problem. Wygląda na to, że jedyną opcją jest dodanie pierw przebiegu,który wczytuje pozycje z ZK, a potem zeruje ich ilości w rozbiciu, a potem w drugim przebiegu dopiero wejście w rozbicie tych pozycji i przypisania prawidłowych partii - uda się zwolnić wtedy te rezerwacje z ZK? Wersja ze statusami, tutaj całkowicie odpada, bo wtedy znowu nam się zblokują rezerwacje z ZK.

Link to postu

Przede wszystkim o jakiej rezerwacji na ZK mówimy. Jeśli nie mamy tego towaru i będziemy dopiero zamawiać to chyba o rezerwacji stanu, a nie dostaw.

Zacznijmy od UI. W UI nie trzeba wszystkiego zerować. Wystarczy wyzerować rozbicie na pozycji, gdzie jest  1000kg (zwolnić tę partię) i w rozbiciu pozycji z 2000kg poprawić tak, aby cała ilość była brana z partii AAA. Następnie wrócić do pozycji z 100kg i w rozbiciu ustawić 100 kg z partii BBB.

Tak może zrobić człowiek. Maszyna (czyt. rozwiązanie sferyczne) najłatwiej to zrealizuje przez wyzerowanie ilości na pozycjach i ponowne ich ustawienie od razu przez rozbicie. W sumie podobnie jak w UI, tylko przemiata wszystko. Zgadzam się, że statusem tu nie należy mieszać.

Link to postu
×
×
  • Dodaj nową pozycję...