31 KiB
KADRY09 — Listy płac, przelewy, wydruki
Wspólne fakty o typie, podstawowe typy i szablon wzorca: ../kadry.md.
Model. Lista płac to dokument operacyjny
Soneta.Place.ListaPlac(rootGuidedRow, tabelaListyPlac,session.GetPlace().ListyPlac). Trzyma kolekcję wypłatListaPlac.Wyplaty: SubTable<Wyplata>. KażdaWyplata(rootGuidedRow, tabelaWyplaty) wskazuje wstecz listę (Wyplata.ListaPlac: IRow) i pracownika (Wyplata.Pracownik: IRow). Wzorzec listy toDefinicjaListyPlac(tabela konfiguracyjnaDefListPlac,session.GetPlace().DefListPlac, dostępWgSymbolu/WgNazwy).
Wyplatajest abstrakcyjna — konkretne typy:WyplataEtat,WyplataUmowa,WyplataInne(ctor(ListaPlac listaplac, Pracownik pracownik)oraz wariant zIPowiązanieWypłaty). W praktyce wypłat nie tworzy się ręcznie — robi to worker naliczania.
KADRY-I1 — Naliczanie/generowanie list płac (★)
Cel: utworzyć listę płac dla wybranego okresu i naliczyć na niej wypłaty pracowników
(etat/umowy), tak by ListaPlac.Wyplaty zawierała policzone Wyplata.
Warianty:
| Wariant | Mechanizm | Uwaga |
|---|---|---|
| Ręczne utworzenie pustej listy | new ListaPlac() + ListyPlac.AddRow(lp) + pola |
sterujesz wszystkim sam |
| Naliczanie wypłat na istniejącej liście | worker Soneta.Place.NaliczanieWypłat (akcja Nalicz) |
tworzy Wyplata* i liczy elementy |
| Naliczanie planowanych list (zbiorczo) | worker Soneta.Place.NaliczaniePlanowanychListPłacWorker (akcja Nalicz) |
wg DefinicjaPlanowanejListyPłac |
Pola i typy (ListaPlac, kolejność ustawiania jest istotna):
| Pole | Typ | Uwaga |
|---|---|---|
Definicja |
Soneta.Place.DefinicjaListyPlac |
wzorzec listy; ustawić pierwsze po AddRow |
Wydzial |
Soneta.Kadry.Wydzial |
tylko gdy Definicja.Wydzial == true |
Seria |
string |
tylko gdy Definicja.Seria == true |
Data |
Soneta.Types.Date |
data naliczania listy |
Naliczanie |
Soneta.Place.TypNaliczenia |
wartości: PłatnaZGóry/PłatnaZDołu; nie ustawiaj — setter rzuca bez licencji „PL Złoty" |
DataWyplaty |
Soneta.Types.Date |
data postawienia środków; wyznacza mies./rok |
MiesiacZUS |
Soneta.Types.YearMonth |
miesiąc rozliczenia ZUS |
Okres |
Soneta.Types.FromTo |
okres listy; po DataWyplaty i Naliczanie |
MiesWstecz |
int |
|
Wyplaty |
SubTable<Wyplata> |
wypełniana przez worker naliczania |
Numer |
Soneta.Core.NumerDokumentu |
nadawany automatycznie |
Bufor / Zatwierdzona |
bool |
stan dokumentu |
Worker Soneta.Place.NaliczanieWypłat — [Context]: Context, ListaPłac: ListaPlac,
Pracownik: Soneta.Kadry.Pracownik; akcja NaliczanieWypłat Nalicz(); właściwości
wynikowe m.in. Wypłaty: IList, Nienaliczeni: IEnumerable<BłądNaliczaniaWynagrodzenia>,
DataWypłaty/DataListy/DataZUS: Date, Okres: FromTo, Naliczanie: TypNaliczenia.
Worker Soneta.Place.NaliczaniePlanowanychListPłacWorker — [Context]:
Pracownik: Pracownik[]; Params Pars z polami Definicja: DefinicjaPlanowanejListyPłac,
DataWypłaty: Date, Okres: FromTo, Naliczanie: TypNaliczenia, TypWypłaty: TypWyplaty,
MiesiącZUS/MiesiącDeklaracji: YearMonth, Seria: string, MiesWstecz: int,
UwzgledniajNieZatwierdzoneListyPlac/EdycjaMiesiącaZUS: bool;
akcja NaliczaniePlanowanychListPłac Nalicz().
Snippet (ręczne utworzenie listy + naliczenie wypłaty pracownika):
using Soneta.Business;
using Soneta.Place;
using Soneta.Kadry;
using Soneta.Types;
var place = session.GetPlace();
// 1. Wzorzec listy płac (definicja konfiguracyjna).
var def = place.DefListPlac.WgSymbolu["ETAT"]
?? throw new BusException("Brak definicji listy płac".Translate());
// 2. Pusta lista płac — KOLEJNOŚĆ: AddRow → Definicja → daty/naliczanie → Okres.
var lp = new ListaPlac();
place.ListyPlac.AddRow(lp);
lp.Definicja = def; // pierwsze po AddRow
lp.Data = new Date(2026, 6, 30);
lp.DataWyplaty = new Date(2026, 6, 30); // wyznacza miesiąc/rok
lp.MiesiacZUS = new YearMonth(2026, 6);
lp.Okres = new FromTo(new Date(2026, 6, 1), new Date(2026, 6, 30)); // po DataWyplaty
// Uwaga: NIE ustawiaj lp.Naliczanie — setter rzuca bez licencji „PL Złoty"; getter ma sensowny domyślny.
// 3. Naliczenie wypłaty pracownika — sprawdzona ścieżka to NaliczanieSeryjne (patrz sekcja H);
// naliczona wypłata zostaje automatycznie powiązana z bieżącą listą płac.
var pracownik = session.GetKadry().Pracownicy.WgKodu["006"];
var pars = new NaliczanieSeryjne.PracownikParams(context) // context: w UI z workera, w teście z TestBase
{
DataWypłaty = new Date(2026, 6, 30),
DataListy = new Date(2026, 6, 30),
TypWypłaty = TypWyplaty.Etat,
};
var wynik = new NaliczanieSeryjne.Pracownika(pars) { Pracownik = pracownik }.Nalicz();
// 4. Powiązanie wypłaty z listą jest dwukierunkowe (Wyplata.ListaPlac / Wyplata.Pracownik):
foreach (Wyplata w in wynik.WszystkieWypłaty)
{
// w.ListaPlac, w.Pracownik
}
session.Save();
Pułapki:
- Kolejność pól krytyczna:
OkresiMiesWsteczustaw poDataWyplatyiNaliczanie(wzajemne zależności wyliczeń) — patrz wzorzec w kodzie naliczania list. Wydzial/Seriaustawiaj warunkowo wgDefinicja.Wydzial/Definicja.Seria— inaczej ryzyko niespójności kluczaWgDefinicja.- Wypłat nie twórz przez
new WyplataEtat(...)ręcznie — naliczaj. Sprawdzoną ścieżką naliczania jestNaliczanieSeryjne.Pracownika(...).Nalicz()(sekcja H); sam workerNaliczanieWypłat { ListaPłac, Pracownik }.Nalicz()w bazie Demo potrafi zwrócić pustą listę. Wyplata.ListaPlac/Wyplata.Pracownikto relacje tylko do odczytu — powiązania nie ustawisz setterem; powstają w trakcie naliczania.ListyPlacto tabela operacyjna guided — przy odczycie filtruj zakresem (WgDatyWyplaty,WgOkresu,WgDefinicja), nie skanuj całości (safe-code §6.3).Wyplata.ListaPlac/Wyplata.PracowniktoIRow(relacje interfejsowe) — porównuj/rzutuj świadomie.
KADRY-I2 — Drukowanie/PDF kwitków (pasków) wypłaty (★)
Cel: wygenerować pasek (kwitek) wypłaty pracownika do PDF.
Mechanizm. Wydruk realizuje serwis IReportService (namespace Soneta.Business.UI,
identycznie jak wydruki handlowe — patrz handel.md rozdz. 12). Wzorce pasków to
szablony *.repx zarejestrowane atrybutem [DxReport] w assembly
Soneta.KadryPlace.Reports dla DataType = typeof(Soneta.Place.Wyplata):
| Wzorzec (ReportName) | Plik szablonu (TemplateFileName) |
DataType |
|---|---|---|
| „Pasek wypłaty" | PasekWyplaty.repx |
Soneta.Place.Wyplata |
| „Duży pasek wypłaty" | DuzyPasekWyplaty.repx |
Soneta.Place.Wyplata |
| „Paski wypłat" (zbiorczy) | PaskiWyplaty.repx |
Soneta.Place.ListaPlac |
API (IReportService / ReportResult — Soneta.Business.UI):
Stream GenerateReport(ReportResult rr),
ReportResult.TemplateFileName: string, .DataType: Type,
.OutputFormat: ReportFormats (PDF), .Context: Context, .Target: ReportTargets.
Snippet (pasek jednej wypłaty do strumienia PDF):
using Soneta.Business.UI; // IReportService, ReportResult, ReportFormats
using Soneta.Place;
var raporty = session.GetRequiredService<IReportService>();
var context = new Context(session.Context);
context.Set(wyplata); // pojedyncza Wyplata
var rr = new ReportResult {
TemplateFileName = "PasekWyplaty.repx",
DataType = typeof(Wyplata),
OutputFormat = ReportFormats.PDF,
Context = context,
};
using Stream pdf = raporty.GenerateReport(rr); // pierwsze 4 bajty == "%PDF"
Pułapki:
IReportServicepobierasz z kontenera:session.GetRequiredService<IReportService>()(potrzebneusing Microsoft.Extensions.DependencyInjection;). Serwis i silnik raportów (DevExpress) oraz szablony pasków zSoneta.KadryPlace.Reportssą dostępne transytywnie — generowanie PDF działa bez dodatkowych referencji (wzorzec jak whandel.mdrozdz. 12).- Poprawny PDF zaczyna się od bajtów
"%PDF"— to wygodna asercja w teście. - Druk na fizyczną drukarkę (
Target = Printer,PrintReport) wymaga sprzętu — NIE testować.
KADRY-I3 — Drukowanie/PDF list płac (★)
Cel: wygenerować wydruk całej listy płac (pełna lista, zestawienie wypłat) do PDF.
Mechanizm. Identyczny jak KADRY-I2 — IReportService.GenerateReport, szablony [DxReport]
w Soneta.KadryPlace.Reports, dla DataType = typeof(Soneta.Place.ListaPlac) /
typeof(Soneta.Place.ListyPlac):
| Wzorzec (ReportName) | Plik szablonu | DataType |
|---|---|---|
| „Pełna lista płac" | PelnaListaPlac.repx |
Soneta.Place.ListaPlac |
| „Wspólna pełna lista płac" | Wspolnapelnalistaplac.repx |
Soneta.Place.ListyPlac (zbiór) |
| „Paski wypłat" | PaskiWyplaty.repx |
Soneta.Place.ListaPlac |
| Zestawienie wypłat | ZestawienieWyplat.repx |
Soneta.Place.ListaPlac |
Snippet (pełna lista płac → PDF):
using Soneta.Business.UI;
using Soneta.Place;
var raporty = session.GetRequiredService<IReportService>();
var context = new Context(session.Context);
context.Set(listaPlac); // ListaPlac
var rr = new ReportResult {
TemplateFileName = "PelnaListaPlac.repx",
DataType = typeof(ListaPlac),
OutputFormat = ReportFormats.PDF,
Context = context,
};
using Stream pdf = raporty.GenerateReport(rr);
Pułapki:
- Mechanizm i dostępność serwisu — jak w KADRY-I2 (działa transytywnie, bez dodatkowych referencji).
- Lista musi być policzona (mieć
Wyplaty) — inaczej wydruk będzie pusty. - Niektóre szablony list wymagają pełnego kontekstu danych. W bazie Demo wzorzec
PelnaListaPlac.repxpotrafi rzucićInvalidOperationException(„Problem z przygotowaniem raportu") na sztucznie utworzonej liście — to ograniczenie konkretnego szablonu/kontekstu, nie brak referencji (pasek wypłatyPasekWyplaty.repxz KADRY-I2 generuje się poprawnie). - Do wydruku zbiorczego wielu list ustaw
DataType = typeof(Soneta.Place.ListyPlac)i przekaż zbiór przezContext.Set(...)/ReportResult.Rows.
KADRY-I4 — Generowanie przelewów wynagrodzeń (przygotowanie przelewów) (★)
Cel: z naliczonej, zatwierdzonej listy płac wygenerować dokumenty przelewu wynagrodzeń (do paczki przelewów), tak by wypłaty pracowników trafiły do zapłaty/preliminarza i mogły zostać wyeksportowane do banku (KADRY-I5).
Dwie różne klasy
Wyplata— nie myl ich. W domenie współistnieją:
Soneta.Place.Wyplata(modułPlaceModule, tabelaWyplaty) — naliczona wypłata pracownika (wynik naliczania z sekcji H/KADRY-I1); to dokument płacowy ze składnikami (Elementy), powiązany z listą płac (Wyplata.ListaPlac).Soneta.Kasa.Wyplata(modułKasaModule, tabelaWyplaty/Zaplaty) — zapłata kasowa (rozchód środków). To ona implementujeIDokumentPlatny/IDokumentKsiegowalny, ma pola rozliczeniowe (DoRozliczenia,Stan,StanRozliczenia,KwotaRozliczona,Rozliczono,Rozrachunki,Zaplaty,PreliminarzPoz,PozycjePrzelewu,BlokadaPrzelewow).Mechanizm „z wypłaty do przelewu” łączy oba światy: worker płacowy czyta
Place.Wyplataz listy płac i tworzy dokumenty przelewu w module Kasa (Soneta.Kasa.PrzelewBase, w paczcePaczkaPrzelewow).
Mechanizm (publiczny kontrakt — worker płacowy): sprawdzoną ścieżką tworzenia przelewów z
wynagrodzeń jest worker Soneta.Place.ListaPlac.PrzygotujPrzelewyWorker (assembly
Soneta.KadryPlace, akcja menu „Przygotuj przelewy” na liście/listach płac). Kontekstem
działania jest lista płac (Soneta.Place.ListaPlac) — przygotowuje przelewy dla zatwierdzonych
wypłat tej listy.
Parametry — PrzygotujPrzelewyWorker.Params:
| Pole | Typ | Uwaga |
|---|---|---|
Data |
Soneta.Types.Date |
data dokumentów przelewu |
Paczka |
Soneta.Kasa.PaczkaPrzelewow |
istniejąca paczka, do której trafią przelewy (opcjonalnie) |
DefinicjaPaczki |
Soneta.Kasa.DefinicjaPaczkiPrzelewu |
definicja, wg której utworzyć nową paczkę (gdy Paczka == null) |
ZRachunku |
Soneta.Kasa.RachunekBankowyFirmy |
rachunek firmy obciążany przelewami |
Łączone |
bool |
łączenie przelewów do jednego podmiotu w jeden dokument |
ListyPłac |
string |
opis/oznaczenie list płac (informacyjnie w tytule) |
ModyfikacjaTytułów |
bool |
czy nadpisać tytuły przelewu (Tytułem1/Tytułem2) |
Tytułem1, Tytułem2 |
string |
tytuł przelewu (gdy ModyfikacjaTytułów == true) |
ZEwidencjiZrodlowej |
bool |
bierz dane rachunku z ewidencji źródłowej |
Akcja: object PrzygotujPrzelewy() — tworzy w sesji dokumenty Soneta.Kasa.PrzelewBase
(tabela Przelewy) w paczce PaczkaPrzelewow; utrwalenie w bazie wymaga session.Save().
Model dokumentu przelewu (Soneta.Kasa.PrzelewBase, tabela Przelewy, root GuidedRow):
| Pole | Typ | Opis |
|---|---|---|
Kwota |
Soneta.Types.Currency |
kwota przelewu |
Podmiot |
Soneta.Kasa.IPodmiotKasowy |
odbiorca (m.in. Pracownik, ZUS, UrzadSkarbowy, Bank, Kontrahent) |
Rachunek |
Soneta.Kasa.RachunekBankowyPodmiotu |
rachunek odbiorcy |
RachunekZleceniodawcy |
Soneta.Kasa.NumerRachunku |
rachunek firmy (obciążany) |
Data |
Soneta.Types.Date |
data przelewu |
Definicja |
Soneta.Core.DefinicjaDokumentu |
definicja dokumentu |
Numer |
Soneta.Core.NumerDokumentu |
numer (nadawany automatycznie) |
Tytulem1, Tytulem2 |
string |
tytuł przelewu |
Typ2 |
Soneta.Kasa.TypPrzelewu2 |
wariant przelewu (zwykły / MPP / itp.) |
PaczkaPrzelewow |
Soneta.Kasa.PaczkaPrzelewow |
paczka, do której należy przelew |
Bufor / Zatwierdzony |
bool |
stan dokumentu |
Exported |
bool |
czy wyeksportowany (po KADRY-I5 — true, blokuje edycję) |
Przelewy okresowe / MPP:
- MPP (mechanizm podzielonej płatności) to wariant przelewu — wyrażany przez
PrzelewBase.Typ2: Soneta.Kasa.TypPrzelewu2(oraz naKasa.WyplatapolemKwotaMPP,MozliweMechanizmyMPP). Dla wynagrodzeń MPP zwykle nie dotyczy (to mechanizm faktur VAT), ale kontrakt go przewiduje. - Przelewy okresowe (cykliczne płatności np. składek z list) realizuje osobny worker
księgowy
Soneta.Ksiega.Kasowe.NaliczaniePrzelewowOkresowych(poza zakresem płac pracownika).
Powiązanie z wypłatą / preliminarzem (publiczne kolekcje na Pracownik):
Kolekcja na Pracownik |
Typ | Zawiera |
|---|---|---|
Pracownik.Przelewy |
SubTable<Soneta.Kasa.PrzelewBase> |
przelewy pracownika |
Pracownik.DokumentyPreliminarza |
SubTable<Soneta.Kasa.PreliminarzDokument> |
dokumenty preliminarza |
Pracownik.DokumentyRozliczeniowe |
SubTable<Soneta.Kasa.DokRozliczBase> |
dokumenty rozliczeniowe |
Pracownik.Rozrachunki |
SubTable<Soneta.Kasa.RozrachunekIdx> |
rozrachunki |
Pracownik.Rachunki |
SubTable<Soneta.Kasa.RachunekBankowyPodmiotu> |
rachunki bankowe pracownika |
Korekta (zweryfikowane kompilacją + skanem DLL):
Pracownik.Platnoscinie istnieje w publicznym kontrakcie kartoteki pracownika — kolekcjaPlatnosciwystępuje tylko na interfejsieSoneta.Kasa.IDokumentPlatny(np.Kasa.Wyplata.Platnosci), nie naPracownik. Płatności podmiotu czytaj przezPracownik.Rozrachunki/Pracownik.DokumentyRozliczeniowe.
Snippet (worker — w UI/teście z dostępnym Context):
using Soneta.Business;
using Soneta.Place; // ListaPlac, ListaPlac.PrzygotujPrzelewyWorker
using Soneta.Kasa; // PaczkaPrzelewow, PrzelewBase, RachunekBankowyFirmy
using Soneta.Types;
// listaPlac: zatwierdzona lista płac z naliczonymi wypłatami (sekcja KADRY-I1)
var pars = new ListaPlac.PrzygotujPrzelewyWorker.Params
{
Data = Date.Today,
// Paczka = istniejacaPaczka, // albo nowa wg DefinicjaPaczki:
// DefinicjaPaczki = session.GetKasa().DefPaczekPrzelewow.WgSymbolu["..."],
// ZRachunku = rachunekFirmy, // RachunekBankowyFirmy
Łączone = false,
};
var worker = new ListaPlac.PrzygotujPrzelewyWorker { Pars = pars };
// kontekstem workera jest lista płac; uruchomienie akcji:
worker.PrzygotujPrzelewy();
session.Save(); // utrwalenie dokumentów przelewu w bazie
Pułapki / ograniczenia (bądź szczery):
Place.Wyplata≠Kasa.Wyplata— pola rozliczeniowe (DoRozliczenia,Stan,StanRozliczenia,Rozrachunki,BlokadaPrzelewow) są na kasowejSoneta.Kasa.Wyplata(IDokumentPlatny), nie na płacowej. Skanując „Wyplata” trafia się na kasową.- Lista płac musi być zatwierdzona i naliczona —
PrzygotujPrzelewyna pustej/niezatwierdzonej liście nie ma czego przelać. - Wymaga konfiguracji modułu Kasa — definicji paczki przelewów (
DefinicjaPaczkiPrzelewu), rachunku firmy (RachunekBankowyFirmy) oraz rachunku pracownika (Pracownik.Rachunki). Brak rachunku odbiorcy → przelew nie powstanie albo będzie niekompletny. W bazie Demo te elementy mogą nie być skonfigurowane, dlatego generowanie przelewów w teście jednostkowym jest niepewne (patrz spec testowy). - Worker sam zatwierdza zmiany w sesji (otwiera transakcję) — nie owijaj w dodatkowy
session.Logout(true); do bazy idą wSave(). PrzelewBase.Podmiot/Powiazanieto relacje interfejsowe (IRow/IPodmiotKasowy) — rzutuj świadomie.Przelewyto tabela operacyjna guided — przy odczycie filtruj zakresem (safe-code §6.3).
KADRY-I5 — Eksport wynagrodzeń do banku / pliku przelewów (★)
UWAGA — operacja plikowa/integracyjna. Eksport zapisuje fizyczny plik w formacie bankowym (Elixir, MT940-pochodne, formaty walutowe). To wejście/wyjście do systemu zewnętrznego — nie jest to przedmiot testu jednostkowego (zależy od ścieżki na dysku, formatu banku, sterownika eksportu i — przy wysyłce online — od sieci). Dokumentujemy model i publiczny kontrakt, a sam eksport pliku oznaczamy jako nietestowalny jednostkowo.
Cel: wyeksportować przygotowane przelewy (KADRY-I4) do pliku przelewów dla systemu bankowości elektronicznej.
Mechanizm (publiczny kontrakt — worker Kasa): worker Soneta.Kasa.EksportPrzelewowWorker
(akcja menu „Eksport przelewów”, metoda Eksport()), sterowany przez
Soneta.Kasa.EksportPrzelewowParams.
Korekta (zweryfikowane kompilacją):
EksportPrzelewowParamsnie ma konstruktora bezparametrowego — wymagaEksportPrzelewowParams(Context ctx, RachunekBankowyFirmy rachunek, PrzelewBase[] przelewy). Co więcej, sam konstruktor waliduje rachunek i rzucaSystem.ApplicationException(„Eksport niemożliwy. Nie wskazano rachunku w filtrach listy.”), gdyrachunek == null. Dlatego nie da się utworzyć parametrów samym inicjalizatorem obiektu. W teście jednostkowym kontrakt API weryfikuj refleksją (istnienie typu, sygnatura konstruktora, propertyFileName/Params, metodaEksport), bez instancjonowania.
Parametry — Soneta.Kasa.EksportPrzelewowParams:
| Pole | Typ | Uwaga |
|---|---|---|
FileName |
string |
ścieżka pliku wyjściowego — operacja na dysku |
AppendToFile |
bool |
dopisanie do istniejącego pliku |
PrzelewyZgodne |
IList<Soneta.Kasa.PrzelewBase> |
przelewy do wyeksportowania |
Rachunek |
Soneta.Kasa.RachunekBankowyFirmy |
rachunek firmy (zleceniodawca) |
PrmDataPrzelewow |
Soneta.Types.Date |
data realizacji |
PrmNumerPaczki |
string |
numer paczki |
PrmZakres |
Soneta.Kasa.ZakresEksportuPrzelewow |
zakres (wszystkie / wg paczki / zaznaczone) |
EksportujWBuforze |
bool |
uwzględnij przelewy w buforze |
InfoBank, InfoFormatKraj, InfoFormatWalutowy, InfoRachunekBankowy |
string |
parametry formatu/banku |
WithoutHelper |
bool |
tryb bez kreatora |
Akcja: object Eksport() — zapisuje plik wg FileName. Po eksporcie przelewy są oznaczane
jako wyeksportowane (PrzelewBase.Exported == true, blokada dalszej edycji).
Powiązane (kontekst):
- Eksport całych paczek: worker
Soneta.Kasa.EksportPaczekPrzelewowWorker. - Eksport przelewów PPK z pulpitu KBR:
Soneta.EI.UI.PulpitKBR.Workers.PulpitKBEksportPrzelewowWorker.
Snippet (kontrakt — w realnej integracji, nie w teście jednostkowym):
using Soneta.Kasa; // EksportPrzelewowWorker, EksportPrzelewowParams, PrzelewBase
using System.Collections.Generic;
PrzelewBase[] przelewy = /* przelewy z KADRY-I4, np. z paczki */;
// Konstruktor jest WYMAGANY (brak ctora bezparametrowego) i waliduje rachunek (rzuca, gdy null):
var par = new EksportPrzelewowParams(context, rachunekFirmy, przelewy) // rachunekFirmy: RachunekBankowyFirmy
{
FileName = @"C:\przelewy\wynagrodzenia.txt", // ŚCIEŻKA PLIKU — operacja I/O
PrmDataPrzelewow = Date.Today,
EksportujWBuforze = false,
};
var worker = new EksportPrzelewowWorker { Params = par };
worker.Eksport(); // zapis pliku na dysk — efekt uboczny poza sesją
Pułapki / ograniczenia (bądź szczery):
- Eksport pliku NIE nadaje się do testu jednostkowego — pisze na dysk, zależy od formatu banku
i sterownika eksportu; w teście co najwyżej dokumentujemy istnienie API
(
EksportPrzelewowWorker,EksportPrzelewowParams.FileName), bez wywołaniaEksport(). - Format pliku zależy od konfiguracji formatu eksportu danego banku — nie ma jednego
uniwersalnego formatu;
InfoFormat*/InfoBankparametryzują wynik. - Wysyłka online (bankowość elektroniczna / API banku) to dodatkowo operacja sieciowa — poza zakresem testów jednostkowych.
- Po eksporcie
PrzelewBase.Exported = trueblokuje edycję — ponowny eksport wymagaEksportujWBuforze/zmiany stanu.
KADRY-I6 — Wystawienie faktury / faktury zbiorczej z zapłaty (rozliczenia) (★)
Zakres i szczerość. Faktura jest dokumentem handlowym (
Soneta.Handel.DokumentHandlowy), nie płacowym — to nie jest funkcja kartoteki pracownika ani list płac. Powiązanie „z zapłaty” dotyczy rozrachunków/rozliczeń (moduł Kasa): zapłata (Soneta.Kasa.Wyplata/Wplata—IDokumentPlatny) jest rozliczana z dokumentem płatnym (np. fakturą) przez rozrachunki. Wystawianie faktury z poziomu pracownika/płac w publicznym kontrakcie nie istnieje; tutaj dokumentujemy model rozliczeń, który łączy zapłatę z fakturą.
Cel: powiązać zapłatę z dokumentem płatnym (fakturą) na poziomie rozrachunków/rozliczeń — oraz wskazać, gdzie w publicznym API leży rozliczanie należności/zobowiązań pracownika.
Model rozliczeń (publiczny kontrakt, moduł KasaModule):
| Element | Typ / kolekcja | Rola |
|---|---|---|
| Zapłata (rozchód/wpływ) | Soneta.Kasa.Wyplata / Soneta.Kasa.Wplata |
dokument płatny (IDokumentPlatny) |
| Płatność (zobowiązanie/należność) | Soneta.Kasa.Platnosc (tabela Platnosci, IRozliczalny) |
to z nią rozlicza się zapłatę |
| Rozliczenie (powiązanie SP) | Soneta.Kasa.RozliczenieSP (tabela RozliczeniaSP, IRozliczenie) |
wiąże zapłatę z płatnością/dokumentem |
| Rozrachunek | Soneta.Kasa.RozrachunekIdx (tabela RozrachunkiIdx) |
indeks rozrachunkowy podmiotu |
| Stan rozliczenia zapłaty | Wyplata.StanRozliczenia: Soneta.Kasa.StanRozliczenia, Wyplata.DoRozliczenia, Wyplata.KwotaRozliczona, Wyplata.Rozliczono |
ile pozostało / czy rozliczono |
Kolekcje na zapłacie (Soneta.Kasa.Wyplata):
Wyplata.Zaplaty: SubTable<RozliczenieSP>orazWyplata.Dokumenty: SubTable<RozliczenieSP>— rozliczenia,Wyplata.Rozrachunki: SubTable<RozrachunekIdx>— rozrachunki,Wyplata.PreliminarzPoz: PreliminarzPozycja— pozycja preliminarza.
Kolekcje na Pracownik (rozrachunki/faktury podmiotu):
Pracownik.Rozrachunki,Pracownik.DokumentyRozliczeniowe,Pracownik.DokumentyPreliminarza(jak w tabeli KADRY-I4). Uwaga:Pracownik.Platnoscinie istnieje — kolekcjaPlatnoscijest tylko naIDokumentPlatny(np.Kasa.Wyplata.Platnosci).
Workery rozliczeniowe (publiczny kontrakt, akcje menu):
| Worker | Rola |
|---|---|
Soneta.Kasa.RozliczWgPrzelewowWyplataWorker |
rozliczenie zapłaty wg przelewów |
Soneta.Kasa.RozliczPreliminarzIdxWorker / ...TblWorker / ...FrmWorker |
rozliczenie z preliminarzem |
Soneta.Kasa.PreliminarzPozycja.DodajRozliczenieWorker |
dodanie rozliczenia do pozycji preliminarza |
Soneta.Ksiega.UtworzPlatnoscZZapisuWorker |
utworzenie płatności z zapisu (księga) |
Faktura zbiorcza: powstaje po stronie handlowej — z wielu zapłat/płatności tworzy się jeden
dokument handlowy (faktura) zbiorąc je jako rozliczenia. To domena handel.md
(wystawianie i rozliczanie faktur), nie kartoteki pracownika. Z poziomu rozliczeń pracownika
publiczny kontrakt udostępnia odczyt i rozliczanie rozrachunków, a nie „wystaw fakturę”.
Snippet (odczyt stanu rozliczenia zapłat — publiczny kontrakt):
using Soneta.Kasa; // Wyplata, StanRozliczenia
using Soneta.Types;
// Zapłaty pracownika rozliczane z dokumentami (np. fakturami) — odczyt stanu rozliczeń.
// Iteruj zawsze w zakresie/okresie (tabela operacyjna guided — safe-code §6.3).
foreach (RozrachunekIdx r in pracownik.Rozrachunki)
{
// r — pozycja rozrachunkowa pracownika (powiązanie zapłata ↔ dokument)
}
// Stan rozliczenia konkretnej zapłaty kasowej:
// Wyplata zaplata = ...;
// var doRozl = zaplata.DoRozliczenia; // ile pozostało do rozliczenia (Currency)
// var stan = zaplata.StanRozliczenia; // StanRozliczenia (enum)
// var czyRozl = zaplata.Rozliczono; // bool
Pułapki / ograniczenia (bądź szczery):
- „Wystaw fakturę z pracownika/płac” nie istnieje w publicznym kontrakcie. Faktura to dokument
handlowy; powiązanie z zapłatą realizują rozrachunki/rozliczenia (moduł Kasa), nie kartoteka
pracownika. To zadanie jest z pogranicza domen — opis kierujemy do
handel.md. - Pola rozliczeniowe (
DoRozliczenia,Stan,StanRozliczenia,KwotaRozliczona,Rozliczono,Rozrachunki) są naSoneta.Kasa.Wyplata(IDokumentPlatny), a nie na płacowejSoneta.Place.Wyplata. - Rozliczanie/tworzenie faktury zbiorczej wymaga skonfigurowanego modułu Kasa/Handel (definicje dokumentów, rachunki, płatności). W bazie Demo część konfiguracji może nie być gotowa — operacje zapisujące są niepewne w teście (patrz spec testowy).
Platnosc/RozliczenieSP/RozrachunekIdxto obiekty operacyjne — przy odczycie filtruj zakresem i nie skanuj całych tabel (safe-code §6.3).
Spec testowy (zwarty) — KADRY-I4 / KADRY-I5 / KADRY-I6
Konwencja: Soneta.Skills.Test/KadryPlace/Pracownik/, klasa RozdzialI_ListyWydrukiTest
(lub nowa RozdzialI_PrzelewyRozliczeniaTest : PracownikTestBase); baza Demo + rollback;
operujemy wyłącznie na publicznym kontrakcie.
KADRY-I4 — I4_PrzygotujPrzelewy_ZListyPlac
- Co testowalne: naliczenie wypłaty etatowej (
NaliczanieSeryjne.Pracownika, jak KADRY-I1b) → uzyskanieListaPlaczWyplata.ListaPlac; konstrukcjaListaPlac.PrzygotujPrzelewyWorkerzParams(asercja, że worker i typParamsistnieją w publicznym API; że polaData/Paczka/ZRachunkusą dostępne). Odczyt kolekcjiPracownik.Przelewy,Pracownik.DokumentyPreliminarza,Pracownik.Rozrachunki(asercja: kolekcje dostępne, iterowalne). - Niepewne /
[Ignore]/Assert.Ignore: faktyczne wywołanieworker.PrzygotujPrzelewy()i powstanie dokumentówPrzelewBase— zależy od konfiguracji modułu Kasa (definicja paczki,RachunekBankowyFirmy, rachunek pracownikaPracownik.Rachunki), której baza Demo nie gwarantuje. Owinąć wtry/catch+Assert.Ignorez opisem (wzorzec jak KADRY-I2/KADRY-I3) i asercję na powstaniu przelewu robić tylko, gdy się udało.
KADRY-I5 — I5_EksportPrzelewow_KontraktApi
- Co testowalne: istnienie publicznego API — weryfikacja refleksją (NIE instancjonuj!):
typ
EksportPrzelewowParams, konstruktor(Context, RachunekBankowyFirmy, PrzelewBase[]), propertyFileName; typEksportPrzelewowWorker, propertyParams, metodaEksport. Nie używaj inicjalizatoranew EksportPrzelewowParams { ... }— nie ma ctora bezparametrowego, a ctor(ctx, rachunek, przelewy)rzucaApplicationException, gdyrachunek == null(brak konfiguracji w Demo). - Niewykonalne w teście jednostkowym →
[Ignore]: wywołanieworker.Eksport()— operacja plikowa (zapis na dysk wgFileName), zależna od formatu banku/sterownika; wysyłka online = operacja sieciowa. Nie wołaćEksport()w teście; udokumentować jako[Ignore("operacja plikowa/sieciowa — poza testem jednostkowym")].
KADRY-I6 — I6_Rozliczenia_OdczytStanu
- Co testowalne: odczyt kolekcji rozliczeniowych pracownika —
Pracownik.Rozrachunki,Pracownik.DokumentyRozliczeniowe,Pracownik.DokumentyPreliminarza(asercja: dostępne, iterowalne, typy zgodne —RozrachunekIdx,DokRozliczBase,PreliminarzDokument).Pracownik.PlatnosciNIE istnieje — pomiń (kolekcjaPlatnoscijest tylko naIDokumentPlatny); odczyt pól rozliczeniowych zSoneta.Kasa.Wyplata(DoRozliczenia,Stan,StanRozliczenia,Rozliczono) — gdy istnieje zapłata kasowa w Demo. - Niewykonalne /
[Ignore]: wystawienie faktury (zbiorczej) z zapłaty — funkcja handlowa, brak w kontrakcie pracownika; rozliczanie zapisujące (RozliczWgPrzelewowWyplataWorker,RozliczPreliminarz*Worker) wymaga konfiguracji Kasa/Handel →Assert.Ignoreprzy braku danych. Dla wystawiania faktur kierować do testów domeny handlowej (handel.md).
Dokładne nazwy (do użycia w testach):
- Worker płacowy:
Soneta.Place.ListaPlac.PrzygotujPrzelewyWorker(+ zagn..Params; akcjaPrzygotujPrzelewy). - Worker eksportu:
Soneta.Kasa.EksportPrzelewowWorker+Soneta.Kasa.EksportPrzelewowParams(akcjaEksport); paczki:Soneta.Kasa.EksportPaczekPrzelewowWorker. - Dokumenty:
Soneta.Kasa.PrzelewBase(tabelaPrzelewy),Soneta.Kasa.PaczkaPrzelewow(tabelaPaczkiPrzelewow),Soneta.Kasa.DefinicjaPaczkiPrzelewu,Soneta.Kasa.RachunekBankowyFirmy. - Rozliczenia:
Soneta.Kasa.Platnosc,Soneta.Kasa.RozliczenieSP,Soneta.Kasa.RozrachunekIdx,Soneta.Kasa.PreliminarzDokument,Soneta.Kasa.PreliminarzPozycja. - Zapłata kasowa (
IDokumentPlatny):Soneta.Kasa.Wyplata(NIESoneta.Place.Wyplata). - Kolekcje na
Pracownik:Przelewy,Rozrachunki,DokumentyPreliminarza,DokumentyRozliczeniowe,Rachunki(bezPlatnosci— ta kolekcja jest tylko naIDokumentPlatny).