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;
}
}