23 KiB
HANDEL02 — Wystawianie dokumentów
Wspólne fakty o typie, podstawowe typy i szablon wzorca: ../handel.md.
Rozdział pokazuje, jak utworzyć dokument handlowy od zera w różnych wariantach (faktura
sprzedaży, faktura zakupu, dokument magazynowy, zamówienie, dokument walutowy, dokument z usługą)
oraz jak dodawać i parametryzować pozycje. Wszystkie wzorce operują na publicznym kontrakcie
platformy: tabela DokHandlowe (session.GetHandel().DokHandlowe), definicje
DefDokHandlowych.WgSymbolu[...], pozycje PozycjaDokHandlowego.
Kolejność ustawiania pól jest istotna. Najpierw
AddRow(dok), potemDefinicja(inicjuje kategorię, kierunek magazynu, sposób liczenia VAT, walutę płatności), następnieMagazyn,Kontrahent, daty. Na pozycji najpierwTowar(inicjuje jednostkę, stawkę VAT, cenę i rabat), dopiero potemIlosc,Cena,Rabat. Cała operacja w jednej transakcjisession.Logout(editMode: true)zakończonejCommit()(kod biznesowy) /CommitUI()(worker/extender), a po niejsession.Save()— dopieroSave()księguje obroty magazynowe i wykrywa konflikty.
HANDEL-W4 — Faktura sprzedaży (FV)
Cel: wystawić fakturę sprzedaży: dokument rozchodowy z kontrahentem-nabywcą, pozycjami towarowymi, automatycznie wyliczoną tabelą VAT i płatnością.
Warianty:
| Wariant | Charakterystyka | Pola krytyczne |
|---|---|---|
| FV krajowa od netto | standardowa sprzedaż | Definicja=FV, LiczonaOd=Netto, Kontrahent krajowy |
| FV liczona od brutto | sprzedaż detaliczna / paragonowa | LiczonaOd=Brutto |
| FV z rabatem nagłówkowym | rabat przepisywany na pozycje | Rabat: Percent na dokumencie |
| FV dla odbiorcy unijnego | WDT — stawka 0% | kontrahent RodzajPodmiotu=Unijny, stawka z karty/UE (HANDEL-W11) |
| FV walutowa | sprzedaż w EUR/USD | patrz HANDEL-W9 |
Pola i typy: Definicja: DefDokHandlowego (DefDokHandlowych.WgSymbolu["FV"]),
Magazyn: Magazyn, Kontrahent: Kontrahent, Data: Date (data wystawienia),
DataOperacji: Date (faktyczna data sprzedaży), LiczonaOd: SposobLiczeniaVAT (Netto/Brutto),
Rabat: Percent. Wartości wyliczane: Suma: BruttoNetto, SumyVAT: SubTable<SumaVAT>,
Platnosci: SubTable<Soneta.Kasa.Platnosc> (powstaje automatycznie wg formy/terminu kontrahenta).
Snippet:
var handel = session.GetHandel();
var magazyny = session.GetMagazyny();
var crm = session.GetCRM();
using (var t = session.Logout(editMode: true))
{
var fv = new DokumentHandlowy();
session.AddRow(fv); // AddRow PRZED ustawianiem pól
fv.Definicja = handel.DefDokHandlowych.WgSymbolu["FV"]; // definicja PIERWSZA
fv.Magazyn = magazyny.Magazyny.WgSymbol["F"];
fv.Kontrahent = crm.Kontrahenci.WgKodu["Abc"]; // nabywca
fv.Data = Date.Today; // data wystawienia
fv.DataOperacji = Date.Today; // faktyczna data sprzedaży
fv.LiczonaOd = SposobLiczeniaVAT.Netto; // VAT liczony od netto
// Pozycja towarowa (szczegóły w HANDEL-W8):
var poz = new PozycjaDokHandlowego(fv);
session.AddRow(poz);
poz.Towar = session.GetTowary().Towary.WgKodu["BIKINI"]; // Towar PIERWSZY
poz.Ilosc = new Quantity(2, poz.Ilosc.Symbol);
poz.Cena = new DoubleCy(50m, poz.Cena.Symbol);
t.Commit(); // CommitUI() w workerze/extenderze
}
session.Save(); // tu księgują się obroty i VAT
// Odczyt wyliczonej tabeli VAT i wartości:
foreach (SumaVAT v in fv.SumyVAT) { /* v.Stawka, v.Suma (Netto/VAT/Brutto) */ }
BruttoNetto suma = fv.Suma;
Pułapki:
- Demo blokuje stan ujemny (
StanUjemnyVerifier): FV (rozchód) wymaga wcześniejszego zapisanego przyjęcia (PW/PZ) tego towaru. SamoCommitUInie księguje obrotów — magazyn aktualizuje się dopiero poSession.Save()dokumentu przychodowego. SumyVAT,Suma,Platnoscisą wyliczane z pozycji i parametrów dokumentu — nie ustawiaj ich ręcznie (ręczna korekta tabeli VAT to osobny mechanizm:KorektaVAT=true).LiczonaOdustaw przed pozycjami — zmiana po wprowadzeniu pozycji wymusza przeliczenie cen netto↔brutto.- Stawka VAT pozycji jest inicjowana z karty towaru — nie ustawiaj jej „z palca", jeśli nie musisz jej nadpisać.
HANDEL-W5 — Faktura zakupu (FZ)
Cel: wprowadzić fakturę zakupu otrzymaną od dostawcy: dokument przychodowy z numerem obcym dostawcy oraz datami zakupu i wystawienia dokumentu obcego.
Warianty:
| Wariant | Charakterystyka | Pola krytyczne |
|---|---|---|
| FZ krajowa | zakup od dostawcy PL | Definicja=FZ, Obcy.Numer, DataOperacji (data zakupu) |
| FZ z dostawą magazynową | zakup z przyjęciem na magazyn | Magazyn, kierunek przychodowy z definicji |
| FZ od dostawcy unijnego (WNT) | nabycie wewnątrzwspólnotowe | kontrahent RodzajPodmiotu=Unijny |
| FZ walutowa | zakup w walucie obcej | patrz HANDEL-W9 |
Pola i typy: Definicja=DefDokHandlowych.WgSymbolu["FZ"], Kontrahent = dostawca,
Obcy: DokumentObcy (subrow): Obcy.Numer: string (numer obcy nadany przez dostawcę),
Obcy.DataOtrzymania: Date (data dokumentu obcego). Data: Date (data wystawienia w naszym
systemie), DataOperacji: Date (faktyczna data zakupu).
Snippet:
var handel = session.GetHandel();
using (var t = session.Logout(editMode: true))
{
var fz = new DokumentHandlowy();
session.AddRow(fz);
fz.Definicja = handel.DefDokHandlowych.WgSymbolu["FZ"];
fz.Magazyn = session.GetMagazyny().Magazyny.WgSymbol["F"];
fz.Kontrahent = session.GetCRM().Kontrahenci.WgKodu["ZEFIR"]; // dostawca
fz.Data = Date.Today; // data wystawienia u nas
fz.DataOperacji = Date.Today.AddDays(-2); // faktyczna data zakupu
// Numer i data dokumentu obcego (od dostawcy):
fz.Obcy.Numer = "FV/2026/06/123"; // numer obcy
fz.Obcy.DataOtrzymania = Date.Today.AddDays(-2); // data dokumentu obcego
var poz = new PozycjaDokHandlowego(fz);
session.AddRow(poz);
poz.Towar = session.GetTowary().Towary.WgKodu["BIKINI"];
poz.Ilosc = new Quantity(10, poz.Ilosc.Symbol);
poz.Cena = new DoubleCy(30m, poz.Cena.Symbol);
t.Commit();
}
session.Save();
Pułapki:
Obcyto subrow (pole złożone) — nie da się przypisaćfz.Obcy = …; ustawiaj jego pola (fz.Obcy.Numer,fz.Obcy.DataOtrzymania).- Rozróżniaj trzy daty:
Data(wystawienia u nas),DataOperacji(faktyczna data zakupu/sprzedaży, decyduje o okresie magazynowym),Obcy.DataOtrzymania(data na dokumencie obcym). To trzy różne pola — nie myl ich. - FZ z przyjęciem na magazyn księguje przychód → po
Save()powstają zasoby (dok.Zasoby). - Indeks
WgKontrahentaObcy(Kontrahent + numer obcy) pozwala wykryć duplikat faktury od tego samego dostawcy — sprawdzaj przed dodaniem.
HANDEL-W6 — Dokument magazynowy (PZ / WZ / RW / PW)
Cel: wystawić czysto magazynowy dokument wpływający na stan magazynu, bez części handlowej (VAT/płatności) lub z minimalną.
Warianty:
| Wariant | Symbol | Kierunek | Zastosowanie |
|---|---|---|---|
| Przyjęcie zewnętrzne | PZ |
przychód | przyjęcie od dostawcy |
| Przyjęcie wewnętrzne | PW |
przychód | przyjęcie z produkcji / bilans otwarcia |
| Wydanie zewnętrzne | WZ |
rozchód | wydanie odbiorcy |
| Rozchód wewnętrzny | RW |
rozchód | zużycie wewnętrzne |
Pola i typy: Definicja=DefDokHandlowych.WgSymbolu["PW"] (itd.), Magazyn: Magazyn (wymagany),
Kontrahent (gdy dotyczy — PZ/WZ tak, RW/PW zwykle nie), Data, DataOperacji. Kierunek
magazynu (KierunekMagazynu: KierunekPartii — Przychód=1, Rozchód=-1) jest ustawiany z
definicji (readonly="set"). Wynik: dok.Zasoby (przy przychodzie), dok.Obroty.
Snippet:
var handel = session.GetHandel();
// Przyjęcie wewnętrzne PW (przychód — buduje stan magazynu pod późniejsze rozchody):
using (var t = session.Logout(editMode: true))
{
var pw = new DokumentHandlowy();
session.AddRow(pw);
pw.Definicja = handel.DefDokHandlowych.WgSymbolu["PW"]; // kierunek z definicji
pw.Magazyn = session.GetMagazyny().Magazyny.WgSymbol["F"];
pw.Data = Date.Today;
pw.DataOperacji = Date.Today;
var poz = new PozycjaDokHandlowego(pw);
session.AddRow(poz);
poz.Towar = session.GetTowary().Towary.WgKodu["BIKINI"];
poz.Ilosc = new Quantity(100, poz.Ilosc.Symbol);
poz.Cena = new DoubleCy(25m, poz.Cena.Symbol);
t.Commit();
}
session.Save(); // dopiero teraz powstają zasoby
// Stan magazynowy po przyjęciu:
foreach (var z in pw.Zasoby) { /* z.* — partia, ilość, magazyn */ }
Pułapki:
Magazynjest wymagany (required) dla dokumentów magazynowych — bez niegoSave()rzuciRowException.KierunekMagazynu/TypPartiisąreadonly="set"— wynikają z definicji, nie ustawiaj ich ręcznie.- Rozchód (WZ/RW) na bazie Demo wymaga wcześniejszego zapisanego przychodu (PW/PZ) — inaczej
StanUjemnyVerifierzablokujeSave(). - Obroty/zasoby księgują się po
Session.Save(), nie poCommit()/CommitUI(). Aby je odczytać, zapisz dokument i odśwież.
HANDEL-W7 — Zamówienie (ZO / ZD)
Cel: wystawić zamówienie od odbiorcy (ZO) lub zamówienie do dostawcy (ZD). Zamówienie nie wpływa na stan magazynowy (może tworzyć rezerwacje), jest dokumentem nadrzędnym dla realizacji (FV/WZ — patrz rozdział o relacjach).
Warianty:
| Wariant | Symbol | Strona | Realizacja |
|---|---|---|---|
| Zamówienie odbiorcy | ZO |
klient zamawia u nas | → FV / WZ przez IRelacjeService |
| Zamówienie do dostawcy | ZD |
my zamawiamy u dostawcy | → FZ / PZ przez IRelacjeService |
| ZO z rezerwacją | ZO |
jw. | rezerwacja zasobu (dok.Rezerwacja) |
| ZO z terminem dostawy | ZO |
jw. | Dostawa.Termin |
Pola i typy: Definicja=DefDokHandlowych.WgSymbolu["ZO"] / ["ZD"], Kontrahent,
Magazyn, Data, DataOperacji, Dostawa: DokumentDostawa (subrow): Dostawa.Termin: Date
(termin realizacji), Dostawa.Sposob: string. Powiązanie z realizacją: dok.Rezerwacja,
generowanie dokumentu podrzędnego przez IRelacjeService.NowyPodrzednyIndywidualny(...).
Snippet:
var handel = session.GetHandel();
using (var t = session.Logout(editMode: true))
{
var zo = new DokumentHandlowy();
session.AddRow(zo);
zo.Definicja = handel.DefDokHandlowych.WgSymbolu["ZO"]; // zamówienie odbiorcy
zo.Magazyn = session.GetMagazyny().Magazyny.WgSymbol["F"];
zo.Kontrahent = session.GetCRM().Kontrahenci.WgKodu["Abc"]; // zamawiający odbiorca
zo.Data = Date.Today;
zo.DataOperacji = Date.Today;
zo.Dostawa.Termin = Date.Today.AddDays(7); // oczekiwany termin dostawy
var poz = new PozycjaDokHandlowego(zo);
session.AddRow(poz);
poz.Towar = session.GetTowary().Towary.WgKodu["BIKINI"];
poz.Ilosc = new Quantity(5, poz.Ilosc.Symbol);
poz.Cena = new DoubleCy(50m, poz.Cena.Symbol);
t.Commit();
}
session.Save();
Pułapki:
- Zamówienie nie buduje stanu magazynu — to dokument planistyczny. Realizację (FV/WZ z ZO,
FZ/PZ z ZD) tworzysz przez
IRelacjeService(rozdział o relacjach) — dokument nadrzędny musi być wtedy zatwierdzony. Dostawato subrow — ustawiaj pola (zo.Dostawa.Termin), nie przypisuj całego obiektu.- Rezerwacja ilościowa zamówienia jest zarządzana wewnętrznym workerem
(
ZmienRezerwacjeIlosciowaWorker— internal, niedostępny z dodatku); z poziomu publicznego odczytujzo.Rezerwacja, a rezerwacje steruj przez definicję dokumentu i relacje.
HANDEL-W8 — Dodawanie pozycji (towar, ilość, cena, rabat, jednostka)
Cel: dodać pozycję towarową do dokumentu — z automatycznym pobraniem ceny/rabatu z cennika lub z ręcznym nadpisaniem.
Warianty:
| Wariant | Operacja | Pole |
|---|---|---|
| Pozycja z automatyczną ceną | cena i rabat pobrane z cennika/karty | tylko Towar + Ilosc |
| Ręczna cena | nadpisanie ceny | Cena: DoubleCy (ustawia KorektaCeny=true) |
| Ręczny rabat | nadpisanie rabatu | Rabat: Percent (ustawia KorektaRabatu=true) |
| Inna jednostka | sprzedaż w jednostce zbiorczej | Ilosc z symbolem jednostki towaru |
| Pozycja bez rabatu | wyłączenie rabatu | BezRabatu=true |
| Ręczna wartość | korekta wartości pozycji | WartoscCy: Currency |
Pola i typy (PozycjaDokHandlowego): Towar: Towar (ustaw pierwszy — inicjuje jednostkę,
stawkę VAT, cenę i rabat), Ilosc: Quantity (ilość + symbol jednostki), Cena: DoubleCy (cena
- symbol waluty; netto lub brutto wg
Dokument.LiczonaOd),Rabat: Percent,RabatCeny: DoubleCy(rabat kwotowy),WartoscCy: Currency(wartość pozycji),DefinicjaStawki: DefinicjaStawkiVat(stawka VAT). Flagi nadpisań:KorektaCeny: bool,KorektaRabatu: bool,BezRabatu: bool.
Snippet:
var towary = session.GetTowary();
using (var t = session.Logout(editMode: true))
{
// Wariant A — cena i rabat pobrane automatycznie z cennika/karty towaru:
var poz1 = new PozycjaDokHandlowego(dok);
session.AddRow(poz1);
poz1.Towar = towary.Towary.WgKodu["BIKINI"]; // ustawia jednostkę, cenę, rabat, stawkę VAT
poz1.Ilosc = new Quantity(3, poz1.Ilosc.Symbol); // symbol jednostki z towaru
// Cena i rabat zostają takie, jakie zaproponował cennik.
// Wariant B — ręczne nadpisanie ceny i rabatu:
var poz2 = new PozycjaDokHandlowego(dok);
session.AddRow(poz2);
poz2.Towar = towary.Towary.WgKodu["BIKINI"];
poz2.Ilosc = new Quantity(10, poz2.Ilosc.Symbol);
poz2.Cena = new DoubleCy(48m, poz2.Cena.Symbol); // nadpisanie ceny → KorektaCeny=true
poz2.Rabat = new Percent(0.1); // 10% rabatu → KorektaRabatu=true
t.Commit();
}
session.Save();
Pułapki:
Towarustawiaj jako pierwszy. Dopiero on inicjuje symbol jednostki naIlosc/Cena, stawkę VAT i proponowaną cenę/rabat. UstawienieIlosc/CenaprzedTowaroperowałoby na pustych symbolach.IlosctoQuantity(wartość + symbol jednostki),CenatoDoubleCy(wartość + symbol waluty) — twórz je z symbolem już ustawionym na pozycji:new Quantity(n, poz.Ilosc.Symbol),new DoubleCy(c, poz.Cena.Symbol). Nie wstawiaj „gołego"decimal.- Ręczne ustawienie
Cena/Rabatzapala flagiKorektaCeny/KorektaRabatu— od tej chwili platforma nie przeliczy już automatycznie tej wartości (np. po zmianie kontrahenta/ilości). Cenajest netto albo brutto zależnie odDokument.LiczonaOd— interpretuj ją spójnie z dokumentem.- Konstruktor pozycji wymaga dokumentu:
new PozycjaDokHandlowego(dok), a po nimsession.AddRow(poz).
HANDEL-W9 — Dokument w walucie obcej
Cel: wystawić dokument rozliczany w walucie obcej (EUR/USD): wskazać walutę płatności, tabelę kursową, datę kursu oraz — w razie potrzeby — wpisać kurs ręcznie.
Warianty:
| Wariant | Mechanizm | Pola |
|---|---|---|
| Kurs z tabeli na datę | kurs pobierany z TabelaKursowa |
TabelaKursowa, DataKursu |
| Kurs ręczny | użytkownik podaje kurs | KursWaluty: double |
| Zmiana waluty istniejącego dokumentu | przeliczenie dokumentu i cen | akcja „Zmień walutę dokumentu i cen..." (worker) |
| Waluta na pozycji | cena w walucie | poz.Cena: DoubleCy z symbolem waluty |
Pola i typy: TabelaKursowa: TabelaKursowa (wymagana — WalutyModule.GetInstance(session).TabeleKursowe),
DataKursu: Date, KursWaluty: double, BruttoCy: Currency (kwota płatności w walucie).
Waluta płatności wynika z definicji (DefDokHandlowego.WalutaPlatnosci). Zmianę waluty
istniejącego dokumentu realizuje akcja menu Czynności sterowana klasą parametrów
DokumentHandlowyZmianaWalutyWorkerParams (publiczna): Waluta, WalutaBazowa (read-only),
TabelaKursowa, Data, KursWaluty, ZmienCeny: bool.
Snippet:
using Microsoft.Extensions.DependencyInjection; // dla GetRequiredService, jeśli potrzebne
using Soneta.Waluty;
var wm = WalutyModule.GetInstance(session); // session.GetWaluty() jest internal
var eur = wm.Waluty.WgSymbolu["EUR"];
var tabela = wm.TabeleKursowe.NBP; // np. tabela NBP
// Zmiana waluty istniejącego (buforowego) dokumentu na EUR z ręcznym kursem.
// Worker uruchamiany jest jak akcja menu Czynności — parametry przekazujemy przez Context:
var paramy = new DokumentHandlowyZmianaWalutyWorkerParams(context, dok)
{
Waluta = eur,
TabelaKursowa = tabela,
KursWaluty = 4.3344, // kurs ręczny; przy zmianie tabeli/daty platforma proponuje kurs sama
ZmienCeny = true, // przelicz także ceny pozycji
};
context.Set(paramy);
// akcja „Zmień walutę dokumentu i cen..." (ZmienWalute) wykonuje przeliczenie w transakcji UI
// Dokument walutowy „od zera": ustaw tabelę i datę kursu przed pozycjami:
using (var t = session.Logout(editMode: true))
{
dok.TabelaKursowa = tabela;
dok.DataKursu = Date.Today;
// dok.KursWaluty = 4.3344; // tylko gdy chcesz wymusić kurs ręczny
t.Commit();
}
session.Save();
Pułapki:
- Brak kursu na datę = wyjątek. Jeśli w bazie nie ma kursu danej waluty na
DataKursu, operacja rzucaKursWalutyNotFoundException. Na bazie Demo nie ma kursu EUR „na dziś" — albo dodaj kurs do tabeli kursowej, albo wpisz kurs ręcznie (KursWaluty). TabelaKursowajest wymagana dla dokumentu walutowego.session.GetWaluty()jest internal — używajWalutyModule.GetInstance(session).- Worker
DokumentHandlowyZmianaWalutyWorkerjest klasą internal — z dodatku nie tworzysz jej instancji bezpośrednio; uruchamiasz akcję przez framework Czynności, przekazując publiczną klasęDokumentHandlowyZmianaWalutyWorkerParamsprzezContext. - Zmiana waluty dokumentu jest możliwa tylko w buforze (
dok.Bufor == true).
HANDEL-W10 — Dokument z usługą (pozycja usługowa bez wpływu na magazyn)
Cel: dodać do dokumentu pozycję usługową (np. „MONTAZ", „TRANSPORT") — towar typu usługa nie ma wpływu na stan magazynu, ale uczestniczy w wartości i tabeli VAT.
Warianty:
| Wariant | Charakterystyka |
|---|---|
| FV tylko z usługą | faktura za samą usługę (np. montaż) — brak obrotu magazynowego |
| FV mieszana | towar magazynowy + pozycja usługowa na jednym dokumencie |
| Usługa rozliczana ilościowo | usługa w jednostce (np. „TRANSPORT" w km) |
Pola i typy: identyczne jak w HANDEL-W8 (Towar, Ilosc, Cena, Rabat, DefinicjaStawki).
Różnica jest w karcie towaru: towar usługowy nie generuje obrotu magazynowego —
poz.IloscMagazynu pozostaje zerowa, dok.Zasoby/dok.Obroty nie powstają dla tej pozycji.
Snippet:
var handel = session.GetHandel();
var towary = session.GetTowary();
using (var t = session.Logout(editMode: true))
{
var fv = new DokumentHandlowy();
session.AddRow(fv);
fv.Definicja = handel.DefDokHandlowych.WgSymbolu["FV"];
fv.Magazyn = session.GetMagazyny().Magazyny.WgSymbol["F"];
fv.Kontrahent = session.GetCRM().Kontrahenci.WgKodu["Abc"];
fv.Data = Date.Today;
fv.DataOperacji = Date.Today;
// Pozycja usługowa — towar "MONTAZ" jest usługą (BEZ wpływu na magazyn):
var poz = new PozycjaDokHandlowego(fv);
session.AddRow(poz);
poz.Towar = towary.Towary.WgKodu["MONTAZ"]; // usługa
poz.Ilosc = new Quantity(1, poz.Ilosc.Symbol);
poz.Cena = new DoubleCy(200m, poz.Cena.Symbol);
t.Commit();
}
session.Save();
Pułapki:
- O tym, czy pozycja wpływa na magazyn, decyduje typ towaru (usługa vs towar magazynowy), a nie
pole na pozycji. Dla usługi
StanUjemnyVerifiernie blokuje wystawienia rozchodu — usługa nie pobiera ze stanu. - Faktura zawierająca wyłącznie usługi nie tworzy obrotów magazynowych, ale nadal liczy tabelę VAT i płatność.
- Usługa też ma jednostkę (np. „TRANSPORT" w km) —
Iloscużywa symbolu jednostki z karty towaru.
HANDEL-W11 — Odbiorca / płatnik inny niż kontrahent + miejsce dostawy
Cel: wystawić dokument, na którym nabywca (Kontrahent) różni się od odbiorcy towaru
(Odbiorca), wskazać miejsce dostawy oraz — gdy płatnikiem jest inny podmiot — rozliczyć
płatność na płatnika.
Warianty:
| Wariant | Pole / mechanizm |
|---|---|
| Inny odbiorca towaru | Odbiorca: Kontrahent |
| Miejsce dostawy odbiorcy | OdbiorcaMiejsceDostawy: Lokalizacja |
| Osoba odbierająca | OsobaKontrahenta: KontaktOsoba, Osoba: string (podpisujący) |
| Adres / parametry przesyłki | subrow Dostawa (Dostawa.Termin, Dostawa.Sposob, Dostawa.Odpowiedzialny) |
| Inny płatnik | dok.InnyPłatnik (kalkulowane — wynika z relacji podmiotów / płatności) |
Pola i typy: Kontrahent: Kontrahent (nabywca — strona transakcji/VAT),
Odbiorca: Kontrahent (odbiorca towaru — dane dostawy), OdbiorcaMiejsceDostawy: Lokalizacja
(miejsce docelowe dostawy), OsobaKontrahenta: KontaktOsoba, Osoba: string.
InnyPłatnik jest kalkulowane (read-only) — płatnika ustawia się przez relacje podmiotów
(płatnik podmiotu) lub przez płatność, nie przez bezpośrednie przypisanie na dokumencie.
Snippet:
var crm = session.GetCRM();
using (var t = session.Logout(editMode: true))
{
// dok utworzony jak w HANDEL-W4; Kontrahent = nabywca (np. centrala):
dok.Kontrahent = crm.Kontrahenci.WgKodu["Abc"]; // nabywca / strona VAT
dok.Odbiorca = crm.Kontrahenci.WgKodu["ZEFIR"]; // odbiorca towaru (inny podmiot)
// Miejsce dostawy odbiorcy (lokalizacja zdefiniowana u odbiorcy):
// dok.OdbiorcaMiejsceDostawy = ... // rekord Lokalizacja powiązany z odbiorcą
dok.Osoba = "Jan Kowalski"; // osoba podpisująca po stronie kontrahenta
// Parametry dostawy (subrow):
dok.Dostawa.Termin = Date.Today.AddDays(3);
dok.Dostawa.Sposob = "Kurier";
t.Commit();
}
session.Save();
// Odczyt płatnika (kalkulowane):
bool jestInnyPlatnik = dok.InnyPłatnik;
Pułapki:
Kontrahentto nabywca (strona transakcji i VAT),Odbiorcato fizyczny odbiorca towaru — to dwa różne pola, oba typuKontrahent. Faktura wystawiana jest naKontrahent, dostawa idzie doOdbiorca.InnyPłatnikjest kalkulowane — nie przypisuj go ręcznie. Innego płatnika ustala się przez relacje podmiotów (płatnik nadrzędny) lub przez konfigurację płatności dokumentu.OdbiorcaMiejsceDostawyto referencja do rekorduLokalizacja(zwykle zdefiniowanego u odbiorcy) — pobierz istniejącą lokalizację, nie twórz „w locie".Dostawato subrow — ustawiaj jego pola, nie przypisuj całego obiektu.- Zmiana płatnika rozkłada się na płatności; do podziału płatności na raty/płatników służy publiczny
worker
PodzialPlatnosciWorker.