Skocz do zawartości

Sfera - Wystawianie PZ, na podstawie pozycji ZD

Polecane posty

Wystawiam PZ, na podstawie pozycji ZD. Jedno z przetwarzanych zamówień, zmodyfikowało mi ceny zakupu - błąd jest powtarzalny, więc obstawiam, że w tym przypadku brakuje jakiegoś ustawienia w Sferze. Parametry grupowania? Na innych dokumentach, nie ma takich problemów.

 

Więc na ZD pozycje wyglądają tak...

pz1.PNG.f1e2a5544ae11508784e5092d14fb097.PNG

 

... niektóre pozycje realizujemy częściowo, po ich realizacji PZ wygląda tak...

pz2.PNG.80b16442eb7ca7e09fbb4a15f64aa354.PNG

 

... a kod Sfery jest następujący:

// przygotowanie danych
IAsortymenty asortyment = sfera.PodajObiektTypu<IAsortymenty>();
IJednostkiMiar jednostkiMiary = sfera.PodajObiektTypu<IJednostkiMiar>();
IPodmioty podmioty = sfera.PodajObiektTypu<IPodmioty>();
IUzytkownicy uzytkownicy = sfera.PodajObiektTypu<IUzytkownicy>();
IStatusyDokumentowDaneDomyslne statusyDD = sfera.PodajObiektTypu<IStatusyDokumentow>().DaneDomyslne; 
Konfiguracja konfPz = sfera.PodajObiektTypu<IKonfiguracje>().DaneDomyslne.PrzyjecieZewnetrzne;
string stock; stock = results.stock;
Magazyn mag = sfera.PodajObiektTypu<IMagazyny>().Dane.Wszystkie().Where(m => m.Symbol == stock).FirstOrDefault();                   
IPrzyjeciaZewnetrzne dokumentPrzyjecia = sfera.PodajObiektTypu<IPrzyjeciaZewnetrzne>();
IZamowieniaDoDostawcow zamowienia = sfera.PodajObiektTypu<IZamowieniaDoDostawcow>();       

//Console.WriteLine(results.pos);
using (IPrzyjecieZewnetrzne pz = dokumentPrzyjecia.Utworz(konfPz))
  {
  // parametry grupowania
  ParametryGrupowaniaPodstawowe parametryGrupowania = new ParametryGrupowaniaPodstawowe();
  parametryGrupowania.MetodaGrupowaniaPozycji = MetodaGrupowaniaPozycji.BezKonsolidacji;
  parametryGrupowania.MetodaWyliczeniaCen = MetodaWyliczeniaCen.PrzepisanieZDokumentuGlownego;                  	
   
  // podstawowe dane
  pz.Dane.Magazyn = mag;
  pz.Dane.Uwagi = results.comment;
  pz.Dane.NumerZewnetrzny = results.number;
 
  IDokumentZRozbiciem dok = (IDokumentZRozbiciem)pz;
  // wypełnienie pozycji
  foreach(var posadd in results.pos)
    {
    int posdocid; int posid; decimal posq;
    posdocid = posadd.docid; posid = posadd.id; posq = posadd.quantity;
    var zamowienie = zamowienia.Dane.Wszystkie().Where(p => p.Id == posdocid).FirstOrDefault(); // znalezienie zamówienia
    var poz = pz.WypelnijNaPodstawieZD(zamowienie.Pozycje.Where(p => p.Id == posid),zamowienie,parametryGrupowania).Single(); 
    poz.UstawIlosc(posq);
    pz.Przelicz();
                 	
    // obsługa partii
    var r = dok.RozpocznijRozbicie(poz) as IRozbiciePozycjiPrzyjeciowe;
    IPozycjaRozbiciaPrzyjeciowa pr = r.Pozycje.FirstOrDefault();  //.First();  
    if(pr == null) { pr = r.DodajPozycje(); Console.WriteLine("Tworzę pozycję, bo pusta!"); }
    int batches = 1;
    foreach(var posbatch in posadd.batch)
      {
      decimal batchquantity; string batchcode; string batchhash;
      batchquantity = posbatch.quantity; batchcode = posbatch.code; batchhash = posbatch.hash;
      if(batches>1) pr = r.DodajPozycje();
      pr.KodDostawy = batchcode;
      pr.Ilosc = batchquantity;                       
      pr.OpisDostawy = batchhash;
      batches++;
      }
    r.ZakonczRozbicie();
    pz.Przelicz();
    }
  pz.Zapisz()
  } 

 

Link to postu

To raczej nie jest wina rozbicia. Zresztą można to sprawdzić - jaka jest cena na pozycji po wykonaniu rozbicia.

Winne jest najprawdopodobniej wypełnianie na podstawie, które, podstawiając ponownie kontrahenta, powoduje przeliczenie cen.

Proszę spróbować wywołać metodę WypelnijNaPodstawieZD tylko raz, przekazując listę pozycji z ZD, zamiast wielokrotnie, dla każdej pozycji z osobna.

Link to postu
3 minuty temu, Jarek K. napisał:

Proszę spróbować wywołać metodę WypelnijNaPodstawieZD tylko raz, przekazując listę pozycji z ZD, zamiast wielokrotnie, dla każdej pozycji z osobna.

 

No dobrze, to spore przebudowanie kodu, bo muszę podrasować jakoś warunek, bo mój system zakłada łączenie dowolnych pozycji z kilku dokumentów ZD i robi się kłopot :( No i w dodatku, potem muszę kobinować dopasowanie przebiegu przy rozbijaniu partii, ale na szczęście pozycja jest niepowtarzalna. Zaczynam się zastanawiać, czy nie lepiej zrobić "protezę" i jakąś tablicę tymczasową, w której będę trzymać ceny i na koniec je bym poprawił?

Link to postu

Dobra, zauważyłem coś jeszcze, co może mieć wpływ na problem. Wszystkie pozycje są tym samym asortymentem!

pz4.PNG.2edc329d2360aa47d434cf29c001b709.PNG

 

1 minutę temu, Jarek K. napisał:

Tworzona jest PZ i do niej dodawane pozycje. Mamy na wejściu listę id-ów pozycji. Wystarczy na jej podstawie zrobić kolekcję pozycji i ją przekazać do tej metody WypelnijNaPodstawieZD i zrobić to przed pętlą, która będzie rozbijać. To wszystkie zmiany.

No już dzisiaj nie dam rady - głowa już trochę weekendowa, a w domu mój miesięczny synek, za bardzo jeszcze nie chce pomagać w kodowaniu ;) Pewnie odezwę się po weekendzie w temacie.

Link to postu

Kolekcję pozycji źródłowych należy pobrac z bazy.

Potem tylko trzeba namierzyć pozycję, którą chcemy rozbić. Można to zrobić na podstawie identyfikatora pozycji realizowanej.

...
                    // podstawowe dane
                    pz.Dane.Magazyn = mag;
                    pz.Dane.Uwagi = results.comment;
                    pz.Dane.NumerZewnetrzny = results.number;

                    IDokumentZRozbiciem dok = (IDokumentZRozbiciem)pz;

                    // wybranie zamówienia
                    var docid = results.pos.First().docid;
                    var zamowienie = zamowienia.Dane.Wszystkie().Where(p => p.Id == docid).FirstOrDefault(); 
                    // znalezienie pozycji zamówień
                    var pozycjeZrodlowe = zamowienia.Dane.Wszystkie().SelectMany(zd => zd.Pozycje).Where(p => results.pos.Select(po => po.id).Contains(p.Id));
                    var pozycjeNowe = pz.WypelnijNaPodstawieZD(pozycjeZrodlowe, zamowienie, parametryGrupowania);

                    // wypełnienie pozycji
                    foreach (var posadd in results.pos)
                    {
                        int posdocid; int posid; decimal posq;
                        posdocid = posadd.docid; posid = posadd.id; posq = posadd.quantity;
                        //var zamowienie = zamowienia.Dane.Wszystkie().Where(p => p.Id == posdocid).FirstOrDefault(); // znalezienie zamówienia
                        //var poz = pz.WypelnijNaPodstawieZD(zamowienie.Pozycje.Where(p => p.Id == posid), zamowienie, parametryGrupowania).Single();
                        //poz.UstawIlosc(posq);
                        //pz.Przelicz();

                        //znalezienie pozycji
                        var poz = pozycjeNowe.Where(p => p.PozycjeRealizowane.Select(pre => pre.Id).Contains(posid)).Single();

                        // obsługa partii
                        var r = dok.RozpocznijRozbicie(poz) as IRozbiciePozycjiPrzyjeciowe;
                        IPozycjaRozbiciaPrzyjeciowa pr = r.Pozycje.FirstOrDefault();  //.First();  
                        if (pr == null) { pr = r.DodajPozycje(); Console.WriteLine("Tworzę pozycję, bo pusta!"); }
                        int batches = 1;
                        foreach (var posbatch in posadd.batch)

...

 

Edytowane przez Jarek K.
Link to postu
5 minut temu, Jarek K. napisał:

Kolekcję pozycji źródłowych należy pobrac z bazy.

 

No chodzi o to, jak przekazać je poprzez jednokrotne wywołanie WypelnijNaPodstawieZD jak pan to zasugerował. Napisał Pan "Wystarczy na jej podstawie zrobić kolekcję pozycji i ją przekazać do tej metody WypelnijNaPodstawieZD" i z tym kawałkiem kodu mam problem - próbowałem różnych metod stworzenia kolekcji poprzez PozycjaDokumentu oraz IPozycjeDokumentu, ale mi nie wyszło. Czyli mam wstępnie kod taki:

// [pozycje] - utworzenie koleckji - czy to: PozycjaDokumentu pozycje = sfera.PodajObiektTypu<PozycjaDokumentu>();
foreach(var posadd in results.pos)
  {
  int posdocid; int posid;
  posdocid = posadd.docid; posid = posadd.id;
                  	  
  Console.WriteLine("Przygotowanie pozycji do dopisania: "+posadd.id);
  var zamowienie = zamowienia.Dane.Wszystkie().Where(p => p.Id == posdocid).FirstOrDefault();
  var pozycja = zamowienie.Pozycje.Where(p => p.Id == posid);
  // dopisanie pozycji do kolekcji [pozycje], tylko jaką metodą, Add nie działa                	  
  }
// pz.WypelnijNaPodstawieZD(pozycje); użycie kolekcji [pozycje] do stworzenia PZ

 

Link to postu

Tak, z kodem jest wszystko zrozumiałe :) Niestety, mój obiekt results powstaje na podstawie komunikacji JSON przez Socket, w związku z tym, jest on typu Dynamic. Taka konstrukcja odrzuca go całkowicie z podane przez Pana zapytania, przez jakąś tam Lambdę i CS1977 :( Oczywiście, to jest moja wina, więc postanowiłem zrobić wstępną konwersję do specjalnej klasy:

public class zdPos
{
public int docid;
public int id;
public decimal quantity;
}

... i potem odpowiednie przygotowuję tą listę, z zadeklarowanymi typami i używam Pana kodu ...

// konwersja obiektu z dynamicznego na określony
var positions = new List<zdPos>();
foreach(var posadd in results.pos)
  {
  Console.WriteLine("Przygotowanie pozycji do pobrania: "+posadd.id);
  positions.Add(new zdPos(){ id=posadd.id, docid=posadd.docid, quantity=posadd.quantity });
  }         
// wybranie zamówienia
var docid = positions.First().docid;
var zamowienie = zamowienia.Dane.Wszystkie().Where(p => p.Id == docid).FirstOrDefault(); 
// znalezienie pozycji zamówień
var pozycjeZrodlowe = zamowienia.Dane.Wszystkie().SelectMany(zd => zd.Pozycje).Where(p => positions.Select(po => po.id).Contains(p.Id));
var pozycjeNowe = pz.WypelnijNaPodstawieZD(pozycjeZrodlowe, zamowienie, parametryGrupowania);

... i wyrzuca mi błąd:

System.NotSupportedException: Unable to create a constant value of type 'zdPos'. Only primitive types or enumeration types are supported in this context.

na linii var pozycjeNowe = pz.Wypeln....

Trochę nie rozumiem, czemu akurat tutaj wyrzuca błąd i odnosi się do mojego obiektu :( Za małą mam wiedzę z C# aby to ogarnąć.

Link to postu

Ja wpisałem maksymalnie dużo w każdą z linii, żeby idea była czytelna, ale faktycznie moga być problemy z wykonaniem takiego kodu przy pańskiej strukturze danych. Proszę postarać się uprościć poszczególne zapytania oraz zmusić do wykonania zapytań od razu, np.

var idy = positions.Select(p => p.Id).ToArray();
var pozycjeZrodlowe = zamowienia.Dane.Wszystkie().SelectMany(zd => zd.Pozycje).Where(p => idy.Contains(p.Id)).ToList();
var pozycjeNowe = pz.WypelnijNaPodstawieZD(pozycjeZrodlowe, zamowienie, parametryGrupowania);

 

Link to postu

Przeciągnięcie tego przez tablicę idy rozwiązało problem z dodawaniem pozycji masowo. Pozycje weszły, ale wywaliło błąd w momencie ich ponownego wyszukiwania. Po zdebugowaniu, znalazłem przyczynę w odwołaniu pozycji realizowanej z kodu który Pan zasugerował, więc powinno być tak:

var poz = pozycjeNowe.Where(p => p.PozycjeRealizowane.Select(pre => pre.PozycjaRealizowanaId).Contains(posid)).Single();

 

Wszystkie modyfikacje rozwiązały problem z ceną. Potestuję jeszcze kilka scenariuszy czy jest ok :) Ogromne dzięki za pomoc i czekamy na 15kę :D

Link to postu
23 minuty temu, Radomił Ząbik napisał:

...... powinno być tak:

var poz = pozycjeNowe.Where(p => p.PozycjeRealizowane.Select(pre => pre.PozycjaRealizowanaId).Contains(posid)).Single();

 Zgadza się. Przepraszam, ale nie byłem w stanie tego szybko przetestować i odpisałem teoretycznie. Tamto wyrażenie oczywiście było bez sensu, ale tak jak pisałem liczy się idea polegająca na tym, że można te nowe pozycje namierzyć po idzie pozycji, które realizują.

Link to postu
17 godzin temu, Jarek K. napisał:

Zgadza się. Przepraszam, ale nie byłem w stanie tego szybko przetestować i odpisałem teoretycznie.

 

Proszę nie przepraszać! To, że napisał pan "z głowy" ten kawałek kodu i pomógł mi rozwiązać problem z moim błędnym kodem, to i tak o wiele za dużo :D Dziękuje bardzo za pomoc, jeszcze raz!

 

Kod przetestowany na wiele scenariuszy, wszystko ok.

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