using System;
using System.Linq;
using System.Text;
using AwesomeAssertions;
using NUnit.Framework;
using Soneta.Kadry;
using Soneta.Place;
using Soneta.Types;
using Prac = Soneta.Kadry.Pracownik;
namespace Soneta.Skills.Test.KadryPlace.Pracownik;
///
/// Rozdział H (część rozszerzona) — „Płace: odczyt i operacje na naliczonych wypłatach"
/// (receptury H5–H11).
///
/// Każdy test najpierw nalicza wypłatę etatową pracownika Demo workerem
/// Soneta.Place.NaliczanieSeryjne (wzorzec z H1: PracownikParams(Context) +
/// DataWypłaty w okresie etatu + Nalicz()), a następnie odczytuje elementy
/// (Wyplata.Elementy / WypElement.Podatki) albo wykonuje operację publicznym
/// workerem płacowym (zaliczka, przeliczenie podatków, dochód, storno, bufor).
///
///
/// Testy operują wyłącznie na publicznym kontrakcie platformy (jak dodatek programisty
/// zewnętrznego) i na bazie Demo (GoldStandard) z automatycznym rollbackiem po teście.
/// Nie ustawiamy PracownikParams.Naliczanie (setter rzuca bez licencji „PL Złoty").
///
///
[TestFixture]
public class RozdzialHrest_WyplatyTest : PracownikTestBase
{
// ====================================================================================
// Helpery wspólne (skopiowane z RozdzialH_WyplatyTest — ten sam, sprawdzony wzorzec H1).
// ====================================================================================
// Dobiera datę wypłaty mieszczącą się w okresie etatu pracownika: koniec miesiąca początku
// etatu, nie wcześniej niż From i nie później niż To okresu etatu.
private static Date DataWyplatyWEtacie(Prac pracownik)
{
var okres = pracownik.Last.Etat.Okres;
var from = okres.From;
var koniecMiesiaca = new Date(from.Year, from.Month, 1).AddMonths(1).AddDays(-1);
if (koniecMiesiaca < from) koniecMiesiaca = from;
if (okres.To != Date.MaxValue && koniecMiesiaca > okres.To) koniecMiesiaca = okres.To;
return koniecMiesiaca;
}
// Diagnostyka: powody niepoliczenia (Nienaliczeni) w czytelnym komunikacie asercji.
private static string OpisNienaliczonych(NaliczanieWypłat wynik)
{
if (wynik.Nienaliczeni == null) return "(brak kolekcji Nienaliczeni)";
var sb = new StringBuilder();
foreach (var b in wynik.Nienaliczeni)
sb.Append(b).Append(" | ");
return sb.Length == 0 ? "(brak nienaliczonych)" : sb.ToString();
}
// Nalicza pojedynczą wypłatę etatową pracownika (wzorzec H1) i zwraca pierwszą wypłatę.
// Nalicz() otwiera i commituje własną transakcję — nie owijamy w InTransaction.
private Wyplata NaliczWyplateEtatowa(Prac pracownik, Date dataWyplaty)
{
var pars = new NaliczanieSeryjne.PracownikParams(Context);
pars.DataWypłaty = dataWyplaty; // ustawia Okres i MiesiącDeklaracji automatycznie
pars.DataListy = pars.DataWypłaty;
pars.TypWypłaty = TypWyplaty.Etat;
var naliczanie = new NaliczanieSeryjne.Pracownika(pars) { Pracownik = pracownik };
NaliczanieWypłat wynik = naliczanie.Nalicz();
var wyplaty = wynik.WszystkieWypłaty.Cast().ToList();
wyplaty.Should().NotBeEmpty(
"naliczenie etatu pracownika Demo w okresie etatu powinno dać wypłatę; " +
$"data={dataWyplaty}, nienaliczeni: {OpisNienaliczonych(wynik)}");
return wyplaty[0];
}
// ====================================================================================
// H5 — Odczyt elementów wypłaty (brutto/składki/podatek/netto)
// ====================================================================================
[Test]
[Description("H5: składniki naliczonej wypłaty czytamy z Wyplata.Elementy (WypElement). " +
"Pola elementu: Wartosc/Netto/DoWypłaty (decimal), Podatki (subrow Podatki). " +
"Podatki: ZalFIS (zaliczka PIT), Emerytalna/Rentowa/Chorobowa/Zdrowotna (SkladkaZUS " +
"z polami Prac/Firma). Agregaty liczymy ręcznie z elementów; Wyplata.Wartosc to " +
"Currency (kwota do wypłaty) -> .Value na decimal.")]
public void H5_OdczytElementowWyplaty_WartoscNettoPodatki()
{
var pracownik = Pracownik(Pracownik_.Andrzejewski);
pracownik.Should().NotBeNull();
var dataWyplaty = DataWyplatyWEtacie(pracownik);
var wyplata = NaliczWyplateEtatowa(pracownik, dataWyplaty);
// Składniki muszą istnieć (wypłata etatowa zawsze ma elementy wynagrodzenia).
var elementy = wyplata.Elementy.Cast().ToList();
elementy.Should().NotBeEmpty("naliczona wypłata etatowa zawiera składniki Elementy");
// Ręczna agregacja z elementów (wzorzec z dokumentacji H5).
decimal brutto = 0m, netto = 0m, zalPit = 0m, zusPrac = 0m, zusFirma = 0m;
foreach (WypElement e in elementy)
{
e.Definicja.Should().NotBeNull("każdy składnik ma definicję elementu");
brutto += e.Wartosc; // decimal — wartość brutto składnika
netto += e.Netto; // decimal — wartość netto składnika
// Struktura podatkowo-składkowa elementu.
Podatki p = e.Podatki;
p.Should().NotBeNull("WypElement ma subrow Podatki");
zalPit += p.ZalFIS; // zaliczka PIT (fiskus)
// SkladkaZUS: Prac = część pracownika, Firma = część pracodawcy.
zusPrac += p.Emerytalna.Prac + p.Rentowa.Prac + p.Chorobowa.Prac + p.Zdrowotna.Prac;
zusFirma += p.Emerytalna.Firma + p.Rentowa.Firma + p.Wypadkowa.Firma;
}
decimal doWyplaty = wyplata.Wartosc.Value; // Currency -> decimal
brutto.Should().BeGreaterThan(0m, "wypłata etatowa ma dodatni przychód brutto");
netto.Should().BeGreaterThan(0m, "wypłata etatowa ma dodatnie netto");
zusPrac.Should().BeGreaterThan(0m, "od wynagrodzenia etatowego naliczane są składki pracownika");
zusFirma.Should().BeGreaterThan(0m, "pracodawca opłaca część składek (narzuty)");
doWyplaty.Should().BeGreaterThan(0m, "kwota do wypłaty jest dodatnia");
// Zaliczka PIT bywa 0 (np. niska podstawa / ulgi) — sprawdzamy tylko brak ujemności.
zalPit.Should().BeGreaterThanOrEqualTo(0m, "zaliczka PIT nie jest ujemna");
SaveDispose();
}
[Test]
[Description("H5 (worker-agregator): Wyplata.PITInfoWorker (publiczny, [Context] Wypłata) udostępnia " +
"gotowe sumy: DoOpodatkowania/Nieopodatkowane (Currency), Razem/NettoRazem/SkładkiZUS/" +
"SkładkaZdrow/ZalFIS (decimal). Używamy zamiast ręcznej agregacji elementów.")]
public void H5_PITInfoWorker_GotoweAgregaty()
{
var pracownik = Pracownik(Pracownik_.Bednarek);
pracownik.Should().NotBeNull();
var dataWyplaty = DataWyplatyWEtacie(pracownik);
var wyplata = NaliczWyplateEtatowa(pracownik, dataWyplaty);
// Worker-agregator wypłaty — przypinamy wypłatę przez property Wypłata.
var pit = new Wyplata.PITInfoWorker { Wypłata = wyplata };
decimal razem = pit.Razem; // przychód razem (opodatkowane + nieopodatkowane)
decimal nettoRazem = pit.NettoRazem; // wynagrodzenie netto razem
decimal zus = pit.SkładkiZUS; // składki ZUS pracownika
decimal zaliczka = pit.ZalFIS; // zaliczka PIT
razem.Should().BeGreaterThan(0m, "przychód razem wypłaty etatowej jest dodatni");
nettoRazem.Should().BeGreaterThan(0m, "netto razem jest dodatnie");
nettoRazem.Should().BeLessThanOrEqualTo(razem, "netto nie przekracza przychodu brutto");
zus.Should().BeGreaterThan(0m, "od etatu naliczane są składki ZUS pracownika");
zaliczka.Should().BeGreaterThanOrEqualTo(0m, "zaliczka PIT nie jest ujemna");
// DoOpodatkowania to Currency — konwersja przez .Value.
pit.DoOpodatkowania.Value.Should().BeGreaterThan(0m, "podstawa opodatkowania dodatnia");
SaveDispose();
}
// ====================================================================================
// H6 — Wypłata zaliczki (worker WypłaćZaliczkęWorker)
// ====================================================================================
[Test]
[Description("H6: zaliczkę wypłacamy publicznym workerem WypłaćZaliczkęWorker. Parametry: " +
"ZalParams(Context) { Data, Kwota } + ZalParams.Definicja (z WypElement.Params) — " +
"ISTNIEJĄCA definicja elementu z place.DefElementow o RodzajZrodla == RodzajŹródłaWypłaty.Zaliczka; " +
"Pracownicy: Pracownik[]. " +
"Akcja WypłataZaliczki() tworzy rekord Zaliczka i nalicza element realizacji; otwiera " +
"własną transakcję. Brak definicji zaliczki w Demo => Ignore (kontrakt workera udokumentowany).")]
public void H6_WyplataZaliczki_WorkerWyplacZaliczke()
{
var pracownik = Pracownik(Pracownik_.Bujak);
pracownik.Should().NotBeNull();
// Worker wymaga ISTNIEJĄCEJ definicji elementu typu zaliczka — identyfikujemy ją po publicznym
// dyskryminatorze DefinicjaElementu.RodzajZrodla == RodzajŹródłaWypłaty.Zaliczka (brak stałej
// DefinicjaElementu.* dla zaliczki). Sam Kod/Nazwa nie wystarcza (np. „Korekta zaliczki podatku"
// ma RodzajZrodla == Dodatek i worker odrzuca takie podstawienie).
DefinicjaElementu defZaliczki = Place.DefElementow.Cast()
.FirstOrDefault(d => d.RodzajZrodla == RodzajŹródłaWypłaty.Zaliczka);
if (defZaliczki == null)
Assert.Ignore("Baza Demo nie zawiera definicji elementu typu zaliczka — " +
"worker WypłaćZaliczkęWorker wymaga istniejącej DefinicjaElementu (ZalParams.Definicja). " +
"Kontrakt workera udokumentowany w H6.");
var dataWyplaty = DataWyplatyWEtacie(pracownik);
var pars = new WypłaćZaliczkęWorker.ZalParams(Context)
{
Data = dataWyplaty,
Kwota = new Currency(1000m),
};
pars.Definicja = defZaliczki; // z bazowej WypElement.Params
var worker = new WypłaćZaliczkęWorker { Params = pars, Pracownicy = new[] { pracownik } };
object wynik = worker.WypłataZaliczki(); // tworzy Zaliczka + nalicza; własna transakcja
wynik.Should().NotBeNull("akcja WypłataZaliczki zwraca obiekt wyniku");
SaveDispose();
// Po wypłaceniu zaliczki pracownik ma rekord Zaliczka z dodatnią wartością.
var zaliczki = Place.Zaliczki.Cast()
.Where(z => z.Pracownik != null && z.Pracownik.Guid == pracownik.Guid)
.ToList();
zaliczki.Should().NotBeEmpty("worker utworzył rekord Zaliczka dla pracownika");
zaliczki.Should().Contain(z => z.Wartosc.Value > 0m, "zaliczka ma dodatnią wartość");
}
// ====================================================================================
// H7 — Przelicz składki ZUS i podatki (worker NaliczaniePodatkówMiesięcznie)
// ====================================================================================
[Test]
[Description("H7: ponowne przeliczenie składek ZUS i zaliczek PIT na elementach wypłat z bufora " +
"za dany miesiąc deklaracji realizuje publiczny worker NaliczaniePodatkówMiesięcznie. " +
"ctor przyjmuje YearMonth (miesiąc deklaracji); property Pracownik [Context]; akcja " +
"PrzeliczPodatki() działa we własnej transakcji. Przelicza tylko elementy z bufora " +
"(Wyplata.Bufor) bez ręcznej korekty podatków.")]
public void H7_PrzeliczPodatki_WorkerNaliczaniePodatkowMiesiecznie()
{
var pracownik = Pracownik(Pracownik_.Strzelecki);
pracownik.Should().NotBeNull();
var dataWyplaty = DataWyplatyWEtacie(pracownik);
// Wypłata w buforze (świeżo naliczona, niezatwierdzona) — przeliczalna.
var wyplata = NaliczWyplateEtatowa(pracownik, dataWyplaty);
wyplata.Bufor.Should().BeTrue("świeżo naliczona wypłata jest w buforze");
// Miesiąc deklaracji = miesiąc daty wypłaty.
var miesiac = new YearMonth(dataWyplaty.Year, dataWyplaty.Month);
// Sumy zaliczki PIT przed przeliczeniem (powinny być stabilne — brak zmian danych kadrowych).
decimal zalPrzed = new Wyplata.PITInfoWorker { Wypłata = wyplata }.ZalFIS;
var worker = new NaliczaniePodatkówMiesięcznie(miesiac) { Pracownik = pracownik };
worker.PrzeliczPodatki(); // przelicza składki ZUS i zaliczki PIT; własna transakcja
SaveDispose();
// Po przeliczeniu odczytujemy wypłatę ponownie i sprawdzamy stabilność zaliczki PIT
// (przeliczenie bez zmian danych nie powinno zmienić wyniku).
var prac2 = Pracownik(Pracownik_.Strzelecki);
var od = new Date(dataWyplaty.Year, dataWyplaty.Month, 1);
var doD = new Date(dataWyplaty.Year, dataWyplaty.Month,
DateTime.DaysInMonth(dataWyplaty.Year, dataWyplaty.Month));
var wyplata2 = prac2.Wyplaty[(Wyplata x) => x.Data >= od && x.Data <= doD]
.Cast().First();
decimal zalPo = new Wyplata.PITInfoWorker { Wypłata = wyplata2 }.ZalFIS;
zalPo.Should().Be(zalPrzed,
"przeliczenie podatków bez zmiany danych kadrowych daje tę samą zaliczkę PIT");
}
// ====================================================================================
// H8 — Dochód z wypłaty (PITInfoWorker.Dochód_*) + dochód roczny
// ====================================================================================
[Test]
[Description("H8: dochód podatkowy wypłaty czytamy z Wyplata.PITInfoWorker: Dochód_Bez26 + Dochód_26 " +
"(decimal), Podstawa (podstawa naliczenia zaliczki), DoOpodatkowania (Currency). " +
"Dochód roczny sumujemy iterując wypłaty roku (filtr serwerowy po dacie) i sumując " +
"Dochód_Bez26+Dochód_26 z PITInfoWorker każdej wypłaty. RozliczanieManager jest internal — " +
"nie wywołujemy go bezpośrednio.")]
public void H8_DochodZWyplaty_IDochodRoczny()
{
var pracownik = Pracownik(Pracownik_.Andrzejewski);
pracownik.Should().NotBeNull();
var dataWyplaty = DataWyplatyWEtacie(pracownik);
var wyplata = NaliczWyplateEtatowa(pracownik, dataWyplaty);
var pit = new Wyplata.PITInfoWorker { Wypłata = wyplata };
decimal dochodWyplaty = pit.Dochód_Bez26 + pit.Dochód_26;
dochodWyplaty.Should().BeGreaterThan(0m, "wypłata etatowa daje dodatni dochód podatkowy");
pit.Podstawa.Should().BeGreaterThanOrEqualTo(0m, "podstawa naliczenia zaliczki nie jest ujemna");
pit.DoOpodatkowania.Value.Should().BeGreaterThan(0m, "podstawa opodatkowania dodatnia");
SaveDispose();
// Dochód roczny: suma dochodów z wypłat roku (filtr serwerowy po dacie — bez skanu tabeli).
int rok = dataWyplaty.Year;
var od = new Date(rok, 1, 1);
var doD = new Date(rok, 12, 31);
var prac2 = Pracownik(Pracownik_.Andrzejewski);
decimal dochodRoczny = 0m;
foreach (Wyplata w in prac2.Wyplaty[(Wyplata x) => x.Data >= od && x.Data <= doD])
{
var p = new Wyplata.PITInfoWorker { Wypłata = w };
dochodRoczny += p.Dochód_Bez26 + p.Dochód_26;
}
dochodRoczny.Should().BeGreaterThanOrEqualTo(dochodWyplaty,
"dochód roczny obejmuje co najmniej naliczoną wypłatę");
}
[Test]
[Ignore("H8.B/C: PobierzDochodRocznyWorker działa tylko dla właściciela (Pracownik is Wlasciciel), " +
"a RozliczaniePracownikowWorker tylko dla folderu pracowników zewnętrznych — pracownik " +
"etatowy Demo \"006\" nie spełnia tych warunków. Wewnętrzny Wyplata.RozliczenieManager jest " +
"niepubliczny. Dochód standardowego pracownika czytamy z PITInfoWorker (test H8 wyżej).")]
public void H8_PobierzDochodRoczny_TylkoWlasciciel()
{
// Udokumentowane jako niewykonalne dla zwykłego pracownika etatowego — patrz powód w [Ignore].
}
// ====================================================================================
// H9 — Kalkulator wynagrodzeń (przez naliczenie próbne + workery agregujące)
// ====================================================================================
[Test]
[Description("H9: brak dedykowanej publicznej klasy kalkulatora — brutto/netto/koszt pracodawcy " +
"liczymy z naliczenia próbnego (H1) i workerów agregujących: Wyplata.PITInfoWorker " +
"(brutto=Razem, netto=NettoRazem, składki pracownika=SkładkiZUS) oraz Wyplata.WyplataSkładkiWorker " +
"(Razem: ZestawienieSkładek z Narzuty = narzuty pracodawcy). " +
"Koszt pracodawcy ≈ brutto + Narzuty. Naliczenie próbne nie wymaga Save().")]
public void H9_KalkulatorWynagrodzen_NaliczenieProbne()
{
var pracownik = Pracownik(Pracownik_.Bednarek);
pracownik.Should().NotBeNull();
var dataWyplaty = DataWyplatyWEtacie(pracownik);
var wyplata = NaliczWyplateEtatowa(pracownik, dataWyplaty);
var pit = new Wyplata.PITInfoWorker { Wypłata = wyplata };
var skl = new WyplataSkładkiWorker { Wypłata = wyplata };
decimal brutto = pit.Razem;
decimal netto = pit.NettoRazem;
decimal narzuty = skl.Razem.Narzuty; // narzuty pracodawcy (ZUS firmy + FP/FGŚP/FEP)
decimal kosztPracodawcy = brutto + narzuty;
brutto.Should().BeGreaterThan(0m, "brutto dodatnie");
netto.Should().BeGreaterThan(0m, "netto dodatnie");
netto.Should().BeLessThanOrEqualTo(brutto, "netto nie przekracza brutto");
narzuty.Should().BeGreaterThan(0m, "pracodawca ponosi narzuty na wynagrodzenie etatowe");
kosztPracodawcy.Should().BeGreaterThan(brutto, "koszt pracodawcy = brutto + narzuty > brutto");
// Składki pracownika i firmy są spójne z ZestawienieSkładek.
skl.Razem.KosztyZUS.Should().BeGreaterThan(0m, "składki ZUS pracownika dodatnie");
skl.Razem.FirmaZUS.Should().BeGreaterThan(0m, "składki ZUS pracodawcy dodatnie");
// To była kalkulacja — nie utrwalamy (Save pominięty świadomie; rollback i tak wycofa).
}
// ====================================================================================
// H10 — Stornowanie elementów wypłaty
// ====================================================================================
[Test]
[Description("H10: oznaczenie elementu do storna realizuje publiczny worker " +
"StornoElementu.ElementDoPrzeliczeniaWorker (na WypElement): ZaznaczElementDoAnulowania()/" +
"ZaznaczElementDoPrzeliczenia()/WycofajZaznaczenie(). Oznaczać można tylko elementy wypłaty " +
"ZATWIERDZONEJ w stanie StanStorna == NieDotyczy. Najpierw zatwierdzamy wypłatę " +
"(Wyplata.ZatwierdźWorker, property Lista), potem oznaczamy i sprawdzamy StanStorna/Storno. " +
"Wytworzenie elementu stornującego (Wystornowany/Stornujący) następuje przy ponownym naliczeniu.")]
public void H10_StornowanieElementu_WorkerElementDoPrzeliczenia()
{
var pracownik = Pracownik(Pracownik_.Bujak);
pracownik.Should().NotBeNull();
var dataWyplaty = DataWyplatyWEtacie(pracownik);
var wyplata = NaliczWyplateEtatowa(pracownik, dataWyplaty);
// Storno dotyczy wypłaty ZATWIERDZONEJ — zatwierdzamy ją workerem (property Lista, nie Wypłata).
new Wyplata.ZatwierdźWorker { Lista = wyplata }.Zatwierdź();
SaveDispose();
var prac2 = Pracownik(Pracownik_.Bujak);
var od = new Date(dataWyplaty.Year, dataWyplaty.Month, 1);
var doD = new Date(dataWyplaty.Year, dataWyplaty.Month,
DateTime.DaysInMonth(dataWyplaty.Year, dataWyplaty.Month));
var wyplata2 = prac2.Wyplaty[(Wyplata x) => x.Data >= od && x.Data <= doD]
.Cast().First();
wyplata2.Zatwierdzona.Should().BeTrue("po Zatwierdź() wypłata jest zatwierdzona");
// Wybieramy element w stanie NieDotyczy (kandydat do storna).
WypElement element = wyplata2.Elementy.Cast()
.First(e => e.StanStorna == StanStornaElementu.NieDotyczy);
// Oznaczamy element do anulowania — worker otwiera własną transakcję.
var worker = new StornoElementu.ElementDoPrzeliczeniaWorker { Element = element };
worker.ZaznaczElementDoAnulowania();
SaveDispose();
// Po oznaczeniu element jest DoStornowania i ma powiązany rekord Storno.
var prac3 = Pracownik(Pracownik_.Bujak);
var wyplata3 = prac3.Wyplaty[(Wyplata x) => x.Data >= od && x.Data <= doD]
.Cast().First();
WypElement element3 = wyplata3.Elementy.Cast()
.First(e => e.StanStorna == StanStornaElementu.DoStornowania);
element3.StanStorna.Should().Be(StanStornaElementu.DoStornowania,
"oznaczenie ustawia element na DoStornowania");
element3.Storno.Should().NotBeNull("oznaczenie tworzy powiązany rekord StornoElementu");
}
// ====================================================================================
// H11 — Anulowanie/usunięcie naliczonej wypłaty (bufor)
// ====================================================================================
[Test]
[Description("H11: powrót zatwierdzonej wypłaty do bufora (do ponownego naliczenia) realizuje " +
"publiczny worker Wyplata.OtwórzWorker (property Wypłata, akcja Otwórz() => Zatwierdzona=false), " +
"zatwierdzanie — Wyplata.ZatwierdźWorker (property Lista). CanBufor jest protected (niedostępny " +
"z dodatku). Po Otwórz() wypłata jest znów w buforze i można ją przeliczyć ponownie (H1).")]
public void H11_PowrotDoBufora_WorkerOtworz()
{
var pracownik = Pracownik(Pracownik_.Strzelecki);
pracownik.Should().NotBeNull();
var dataWyplaty = DataWyplatyWEtacie(pracownik);
var wyplata = NaliczWyplateEtatowa(pracownik, dataWyplaty);
wyplata.Bufor.Should().BeTrue("świeżo naliczona wypłata jest w buforze");
// Zatwierdzamy (zejście z bufora).
new Wyplata.ZatwierdźWorker { Lista = wyplata }.Zatwierdź();
SaveDispose();
var od = new Date(dataWyplaty.Year, dataWyplaty.Month, 1);
var doD = new Date(dataWyplaty.Year, dataWyplaty.Month,
DateTime.DaysInMonth(dataWyplaty.Year, dataWyplaty.Month));
var prac2 = Pracownik(Pracownik_.Strzelecki);
var wyplata2 = prac2.Wyplaty[(Wyplata x) => x.Data >= od && x.Data <= doD]
.Cast().First();
wyplata2.Zatwierdzona.Should().BeTrue("po Zatwierdź() wypłata jest zatwierdzona");
wyplata2.Bufor.Should().BeFalse("zatwierdzona wypłata nie jest w buforze");
// Powrót do bufora workerem OtwórzWorker.
new Wyplata.OtwórzWorker { Wypłata = wyplata2 }.Otwórz();
SaveDispose();
var prac3 = Pracownik(Pracownik_.Strzelecki);
var wyplata3 = prac3.Wyplaty[(Wyplata x) => x.Data >= od && x.Data <= doD]
.Cast().First();
wyplata3.Bufor.Should().BeTrue("po Otwórz() wypłata wraca do bufora");
wyplata3.Zatwierdzona.Should().BeFalse("po Otwórz() wypłata nie jest zatwierdzona");
}
}