using System; using System.Linq; using Soneta.Business; using Soneta.CRM; using Soneta.Handel; using Soneta.Magazyny; using Soneta.Towary; using Soneta.Types; using Soneta.Test; namespace Soneta.Skills.Test.Handel.DokumentyHandlowe; /// /// Wspólna baza testów dokumentu handlowego. Dziedziczy z , dzięki czemu: /// /// udostępnia gotową sesję operacyjną (Session) powiązaną z testową bazą Demo, /// automatycznie wycofuje (rollback) wszystkie zmiany w bazie po zakończeniu testu, /// daje metody pomocnicze InTransaction/SaveDispose do pracy w transakcjach. /// /// Baza dodaje skróty często powtarzane w testach dokumentu handlowego: dostęp do modułów /// (Handel, Magazyny, Towary, CRM), pobieranie definicji dokumentów i danych słownikowych z bazy Demo /// oraz publiczne metody tworzenia dokumentu i jego pozycji. /// /// Cała baza operuje wyłącznie na publicznym kontrakcie platformy Soneta — tak jak dodatek /// programisty zewnętrznego, który nie ma dostępu do kodu źródłowego aplikacji. /// /// public abstract class DokumentHandlowyTestBase : TestBase { // === Moduły bieżącej sesji operacyjnej === /// Moduł Handel — definicje dokumentów, tabela dokumentów handlowych. protected HandelModule Handel => Session.GetHandel(); /// Moduł Magazyny — magazyny, zasoby, obroty, partie (grupy dostaw). protected MagazynyModule Magazyny => Session.GetMagazyny(); /// Moduł Towary — kartoteka towarów, jednostki, ceny. protected TowaryModule Towary => Session.GetTowary(); /// Moduł CRM — kartoteka kontrahentów. protected CRMModule Crm => Session.GetCRM(); // === Symbole danych dostępnych w bazie Demo (GoldStandard) === /// Symbole definicji dokumentów dostępnych w bazie Demo (pole DefDokHandlowego.Symbol). protected static class Definicje { public const string FakturaSprzedazy = "FV"; /// /// Zakup. UWAGA: w bazie Demo (GoldStandard) NIE ma faktury zakupu jako dokumentu handlowego — /// wszystkie definicje F* mają kategorię „Sprzedaż". Stronę zakupową reprezentuje przyjęcie /// magazynowe od dostawcy „PZ" (przychód). W produkcyjnym enova faktura zakupu ma zwykle symbol „FZ". /// public const string FakturaZakupu = "PZ"; public const string Paragon = "PAR"; public const string PrzyjecieZewnetrzne = "PZ"; public const string PrzyjecieWewnetrzne = "PW"; public const string WydanieZewnetrzne = "WZ"; public const string RozchodWewnetrzny = "RW"; public const string ZamowienieOdbiorcy = "ZO"; public const string ZamowienieDoDostawcy = "ZD"; public const string PrzesuniecieMM = "MM"; public const string Inwentaryzacja = "INW"; } /// Kody towarów z bazy Demo. protected static class Towar_ { /// Towar magazynowy w sztukach. public const string Bikini = "BIKINI"; /// Usługa (bez wpływu na magazyn). public const string Montaz = "MONTAZ"; /// Towar rozliczany w km. public const string Transport = "TRANSPORT"; } /// Kody kontrahentów z bazy Demo. protected static class Kontrahent_ { public const string Abc = "Abc"; public const string Zefir = "ZEFIR"; } /// Symbole magazynów z bazy Demo. protected static class Magazyn_ { /// Magazyn „Firma" (symbol „F"). public const string Firma = "F"; } // === Wyszukiwanie obiektów słownikowych / kartotekowych === /// Pobiera definicję dokumentu handlowego po symbolu (np. „FV", „PW"). protected DefDokHandlowego Definicja(string symbol) => Handel.DefDokHandlowych.WgSymbolu[symbol]; /// Pobiera kontrahenta po kodzie (klucz unikalny, case-insensitive). protected Kontrahent Kontrahent(string kod) => Crm.Kontrahenci.WgKodu[kod]; /// Pobiera towar po kodzie. protected Towar Towar(string kod) => Towary.Towary.WgKodu[kod]; /// Pobiera magazyn po symbolu (np. „F"). protected Magazyn Magazyn(string symbol) => Magazyny.Magazyny.WgSymbol[symbol]; // === Tworzenie dokumentu i pozycji (publiczne API) === /// /// Tworzy nowy dokument handlowy w bieżącej sesji wewnątrz transakcji edycyjnej. /// Kolejność jest istotna: najpierw AddRow, potem Definicja (wyznacza kierunek /// magazynu i przelicza parametry dokumentu), następnie kontrahent i magazyn. /// /// Symbol definicji dokumentu (np. „FV", „PW"). /// Kontrahent dokumentu; null dla dokumentów wewnętrznych. /// Magazyn dokumentu; null gdy definicja go nie wymaga. protected DokumentHandlowy UtworzDokument( string defSymbol, Kontrahent kontrahent = null, Magazyn magazyn = null) { DokumentHandlowy dok = null; InTransaction(() => { dok = new DokumentHandlowy(); Session.AddRow(dok); dok.Definicja = Definicja(defSymbol); if (magazyn != null) dok.Magazyn = magazyn; if (kontrahent != null) dok.Kontrahent = kontrahent; }); return dok; } /// /// Dodaje pozycję do dokumentu. Ustawienie Towar inicjuje jednostkę miary na polach /// Ilosc i Cena — dlatego ilość i cenę tworzymy z symbolem już ustawionym przez towar. /// Wywołuj wewnątrz transakcji edycyjnej (np. w InTransaction). /// /// Dokument, do którego dodajemy pozycję (musi być „żywy" w sesji). /// Towar pozycji. /// Ilość w jednostce towaru. /// Cena jednostkowa; null = nie nadpisuj (zostanie pobrana z cennika). protected static PozycjaDokHandlowego DodajPozycje( DokumentHandlowy dok, Towar towar, double ilosc, double? cena = null) { var poz = new PozycjaDokHandlowego(dok); dok.Session.AddRow(poz); poz.Towar = towar; poz.Ilosc = new Quantity(ilosc, poz.Ilosc.Symbol); if (cena.HasValue) poz.Cena = new DoubleCy(cena.Value, poz.Cena.Symbol); return poz; } /// /// Wprowadza towar na stan magazynu „F" przez utworzenie i zatwierdzenie przyjęcia (PW), /// a następnie zapis (SaveDispose). Dopiero zatwierdzone przyjęcie księguje zasoby/obroty — /// bez tego baza Demo (kontrola stanu ujemnego) odrzuci każdy rozchód (FV/WZ/RW) tego towaru. /// Wywołuj na początku testu rozchodowego; po nim pracuj na świeżej sesji (np. tworząc FV). /// /// Guid zapisanego, zatwierdzonego dokumentu przyjęcia. protected Guid PrzyjmijNaStan(string towarKod, double ilosc, double cena = 10) { var pw = UtworzDokument(Definicje.PrzyjecieWewnetrzne, magazyn: Magazyn(Magazyn_.Firma)); InTransaction(() => DodajPozycje(pw, Towar(towarKod), ilosc, cena)); InTransaction(() => pw.Stan = StanDokumentuHandlowego.Zatwierdzony); var guid = pw.Guid; SaveDispose(); return guid; } }