kontrahent.md
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
using AwesomeAssertions;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Soneta.Skills.Test.CRM.Kontrahenci;
|
||||
|
||||
/// <summary>
|
||||
/// W6 — Adres kontrahenta.
|
||||
/// Test pokazuje, że <c>Adres</c> to property zwracająca obiekt złożony (nie da się przypisać
|
||||
/// całego adresu) — modyfikujemy jego pola. Uwaga na typ <c>KodPocztowy</c> = <c>int</c>
|
||||
/// (do formatu „00-000" służy <c>KodPocztowyS</c>).
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class AdresKontrahentaTest : KontrahentTestBase
|
||||
{
|
||||
[Test]
|
||||
[Description("Ustawienie pól adresu głównego (ulica, kod pocztowy, miejscowość) jest zapisywane.")]
|
||||
public void UstawienieAdresuGlownego_JestZapisywane()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
UtworzKontrahenta(kod, "Firma Z Adresem");
|
||||
SaveDispose();
|
||||
|
||||
var k = Crm.Kontrahenci.WgKodu[kod];
|
||||
InTransaction(() =>
|
||||
{
|
||||
var a = k.Adres; // edytujemy pola obiektu adresu
|
||||
a.Ulica = "Wadowicka";
|
||||
a.NrDomu = "8A";
|
||||
a.NrLokalu = "2";
|
||||
a.KodPocztowyS = "30-415"; // string z myślnikiem; pole int KodPocztowy = 30415
|
||||
a.Miejscowosc = "Kraków";
|
||||
a.Poczta = "Kraków";
|
||||
a.Kraj = "Polska";
|
||||
});
|
||||
SaveDispose();
|
||||
|
||||
var a2 = Crm.Kontrahenci.WgKodu[kod].Adres;
|
||||
a2.Ulica.Should().Be("Wadowicka");
|
||||
a2.NrDomu.Should().Be("8A");
|
||||
a2.Miejscowosc.Should().Be("Kraków");
|
||||
a2.KodPocztowy.Should().Be(30415);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Description("Adres do korespondencji jest odrębnym obiektem od adresu głównego.")]
|
||||
public void AdresDoKorespondencji_JestOdrebnyOdGlownego()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
UtworzKontrahenta(kod, "Firma Z Korespondencja");
|
||||
SaveDispose();
|
||||
|
||||
var k = Crm.Kontrahenci.WgKodu[kod];
|
||||
InTransaction(() =>
|
||||
{
|
||||
k.Adres.Miejscowosc = "Kraków";
|
||||
k.AdresDoKorespondencji.Miejscowosc = "Warszawa";
|
||||
});
|
||||
SaveDispose();
|
||||
|
||||
var zapisany = Crm.Kontrahenci.WgKodu[kod];
|
||||
zapisany.Adres.Miejscowosc.Should().Be("Kraków");
|
||||
zapisany.AdresDoKorespondencji.Miejscowosc.Should().Be("Warszawa");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using System.Linq;
|
||||
using AwesomeAssertions;
|
||||
using NUnit.Framework;
|
||||
using Soneta.Core;
|
||||
|
||||
namespace Soneta.Skills.Test.CRM.Kontrahenci;
|
||||
|
||||
/// <summary>
|
||||
/// W7 — Dane kontaktowe i adresy WWW.
|
||||
/// Testy pokazują dodanie kanału e-mail do kolekcji <c>Kontakty</c> (typ rodzaju pobierany ze
|
||||
/// słownika <c>RodzajeKontaktow</c>) oraz dodanie adresu WWW (konstruktor z hostem
|
||||
/// <c>new AdresWWW(kontrahent)</c>, pole URL nazywa się <c>Adres</c>).
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class DaneKontaktoweTest : KontrahentTestBase
|
||||
{
|
||||
[Test]
|
||||
[Description("Dodanie domyślnego kontaktu e-mail pojawia się w kolekcji Kontakty kontrahenta.")]
|
||||
public void DodanieEmaila_PojawiaSieWKolekcjiKontakty()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
UtworzKontrahenta(kod, "Firma Z Mailem");
|
||||
SaveDispose();
|
||||
|
||||
var email = "kontakt@firma-" + kod + ".pl";
|
||||
var k = Crm.Kontrahenci.WgKodu[kod];
|
||||
var rodzajEmail = Session.GetCore().RodzajeKontaktow[RodzajeKontaktow.AdresEmail];
|
||||
|
||||
InUITransaction(() =>
|
||||
{
|
||||
var dk = Add(new DaneKontaktowe { Host = k });
|
||||
dk.Rodzaj = rodzajEmail;
|
||||
dk.Kontakt = email;
|
||||
dk.Domyslny = true;
|
||||
});
|
||||
SaveDispose();
|
||||
|
||||
var zapisany = Crm.Kontrahenci.WgKodu[kod];
|
||||
zapisany.Kontakty.Cast<DaneKontaktowe>()
|
||||
.Any(d => d.Kontakt == email)
|
||||
.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Description("Dodanie adresu WWW (new AdresWWW(host)) pojawia się w kolekcji AdresyWWW.")]
|
||||
public void DodanieAdresuWWW_PojawiaSieWKolekcji()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
UtworzKontrahenta(kod, "Firma Z WWW");
|
||||
SaveDispose();
|
||||
|
||||
var url = "https://www.firma-" + kod + ".pl";
|
||||
var k = Crm.Kontrahenci.WgKodu[kod];
|
||||
|
||||
InUITransaction(() =>
|
||||
{
|
||||
var www = Add(new AdresWWW(k)); // ctor przyjmuje IAdresyWWWHost
|
||||
www.Adres = url; // pole URL nazywa się Adres
|
||||
www.Domyslny = true;
|
||||
});
|
||||
SaveDispose();
|
||||
|
||||
var zapisany = Crm.Kontrahenci.WgKodu[kod];
|
||||
zapisany.AdresyWWW.Cast<AdresWWW>()
|
||||
.Any(w => w.Adres == url)
|
||||
.Should().BeTrue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System.Linq;
|
||||
using AwesomeAssertions;
|
||||
using NUnit.Framework;
|
||||
using Soneta.CRM;
|
||||
|
||||
namespace Soneta.Skills.Test.CRM.Kontrahenci;
|
||||
|
||||
/// <summary>
|
||||
/// W13/W14 — Klasyfikacja i powiązania (odczyt kontraktu publicznego).
|
||||
/// Testy dokumentują dostęp do kolekcji klasyfikacyjnych (<c>Kategorie</c>, <c>Branze</c>,
|
||||
/// <c>Features</c>) oraz powiązań (<c>Opiekunowie</c>, <c>Podrzedni</c>, <c>PodmiotNadrzedny</c>).
|
||||
/// Świeżo utworzony, samodzielny kontrahent ma te kolekcje puste i brak podmiotu nadrzędnego —
|
||||
/// co czyni asercje deterministycznymi.
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class KlasyfikacjaIPowiazaniaTest : KontrahentTestBase
|
||||
{
|
||||
[Test]
|
||||
[Description("Świeży kontrahent ma dostępne i puste kolekcje klasyfikacyjne; Features != null.")]
|
||||
public void NowyKontrahent_KolekcjeKlasyfikacjiSaPusteAleDostepne()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
UtworzKontrahenta(kod, "Firma Klasyfikacja");
|
||||
SaveDispose();
|
||||
|
||||
var k = Crm.Kontrahenci.WgKodu[kod];
|
||||
|
||||
k.Features.Should().NotBeNull(); // cechy definiowalne — dostęp po nazwie
|
||||
k.Kategorie.Cast<KategoriaKth>().Should().BeEmpty();
|
||||
k.Branze.Cast<BranzaKth>().Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Description("Świeży kontrahent nie ma opiekunów, podmiotów podrzędnych ani nadrzędnego.")]
|
||||
public void NowyKontrahent_BrakPowiazan()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
UtworzKontrahenta(kod, "Firma Powiazania");
|
||||
SaveDispose();
|
||||
|
||||
var k = Crm.Kontrahenci.WgKodu[kod];
|
||||
|
||||
k.Opiekunowie.Cast<Opiekun>().Should().BeEmpty();
|
||||
k.Podrzedni.Cast<RelacjaPodmiotu>().Should().BeEmpty();
|
||||
k.PodmiotNadrzedny.Should().BeNull();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using Soneta.Core;
|
||||
using Soneta.CRM;
|
||||
using Soneta.Test;
|
||||
|
||||
namespace Soneta.Skills.Test.CRM.Kontrahenci;
|
||||
|
||||
/// <summary>
|
||||
/// Wspólna baza testów kontrahenta. Dziedziczy z <see cref="TestBase"/>, dzięki czemu:
|
||||
/// <list type="bullet">
|
||||
/// <item>udostępnia gotową sesję operacyjną (<c>Session</c>) powiązaną z testową bazą Demo,</item>
|
||||
/// <item>automatycznie wycofuje (rollback) wszystkie zmiany w bazie po zakończeniu testu,</item>
|
||||
/// <item>daje metody pomocnicze <c>InTransaction</c>/<c>SaveDispose</c> do pracy w transakcjach.</item>
|
||||
/// </list>
|
||||
/// Baza dodaje skróty często powtarzane w testach kontrahenta (dostęp do modułu CRM,
|
||||
/// generowanie unikalnego kodu, utworzenie minimalnego kontrahenta).
|
||||
/// </summary>
|
||||
public abstract class KontrahentTestBase : TestBase
|
||||
{
|
||||
/// <summary>Moduł CRM bieżącej sesji operacyjnej.</summary>
|
||||
protected CRMModule Crm => Session.GetCRM();
|
||||
|
||||
/// <summary>Generuje krótki, unikalny kod kontrahenta (na potrzeby testów).</summary>
|
||||
protected static string UnikalnyKod() => Guid.NewGuid().ToString("N").Substring(0, 10);
|
||||
|
||||
/// <summary>
|
||||
/// Tworzy w bieżącej sesji nowego kontrahenta z minimalnym kompletem danych
|
||||
/// (kod, nazwa, status i rodzaj podmiotu) wewnątrz transakcji edycyjnej.
|
||||
/// Zwrócony obiekt żyje w bieżącej sesji — pozostaje ważny do czasu <c>SaveDispose</c>.
|
||||
/// </summary>
|
||||
protected Kontrahent UtworzKontrahenta(
|
||||
string kod,
|
||||
string nazwa = null,
|
||||
StatusPodmiotu status = StatusPodmiotu.PodmiotGospodarczy,
|
||||
RodzajPodmiotu rodzaj = RodzajPodmiotu.Krajowy)
|
||||
{
|
||||
Kontrahent k = null;
|
||||
InTransaction(() =>
|
||||
{
|
||||
// AddRow MUSI poprzedzać ustawianie pól — obiekt najpierw trafia do tabeli.
|
||||
k = new Kontrahent();
|
||||
Session.AddRow(k);
|
||||
k.Kod = kod;
|
||||
k.Nazwa = nazwa ?? kod;
|
||||
k.StatusPodmiotu = status;
|
||||
k.RodzajPodmiotu = rodzaj;
|
||||
});
|
||||
return k;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using AwesomeAssertions;
|
||||
using NUnit.Framework;
|
||||
using Soneta.CRM;
|
||||
|
||||
namespace Soneta.Skills.Test.CRM.Kontrahenci;
|
||||
|
||||
/// <summary>
|
||||
/// W4 — Modyfikacja danych i statusów kontrahenta.
|
||||
/// Testy pokazują zmianę nazwy oraz ustawienie statusów dostępności/handlowych:
|
||||
/// <c>Blokada</c> (ukrycie na listach) i <c>BlokadaSprzedazy</c> (zakaz dokumentów rozchodu).
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class ModyfikacjaIStatusyTest : KontrahentTestBase
|
||||
{
|
||||
[Test]
|
||||
[Description("Zmiana nazwy kontrahenta jest trwale zapisywana.")]
|
||||
public void ZmianaNazwy_JestZapisywana()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
UtworzKontrahenta(kod, "Nazwa Pierwotna");
|
||||
SaveDispose();
|
||||
|
||||
var k = Crm.Kontrahenci.WgKodu[kod];
|
||||
InTransaction(() => k.Nazwa = "Nazwa Zmieniona");
|
||||
SaveDispose();
|
||||
|
||||
Crm.Kontrahenci.WgKodu[kod].Nazwa.Should().Be("Nazwa Zmieniona");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Description("Ustawienie Blokada i BlokadaSprzedazy jest trwale zapisywane.")]
|
||||
public void UstawienieBlokad_JestZapisywane()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
UtworzKontrahenta(kod, "Do Zablokowania");
|
||||
SaveDispose();
|
||||
|
||||
var k = Crm.Kontrahenci.WgKodu[kod];
|
||||
InTransaction(() =>
|
||||
{
|
||||
k.Blokada = true; // ukrycie na listach
|
||||
k.BlokadaSprzedazy = true; // zakaz wystawiania dokumentów rozchodu
|
||||
});
|
||||
SaveDispose();
|
||||
|
||||
var zapisany = Crm.Kontrahenci.WgKodu[kod];
|
||||
zapisany.Blokada.Should().BeTrue();
|
||||
zapisany.BlokadaSprzedazy.Should().BeTrue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System.Linq;
|
||||
using AwesomeAssertions;
|
||||
using NUnit.Framework;
|
||||
using Soneta.CRM;
|
||||
|
||||
namespace Soneta.Skills.Test.CRM.Kontrahenci;
|
||||
|
||||
/// <summary>
|
||||
/// W8 — Osoby kontaktowe.
|
||||
/// Test pokazuje dodanie osoby kontaktowej i powiązanie jej z kontrahentem przez
|
||||
/// <c>KontaktOsoba.Kontrahent</c> — osoba pojawia się wtedy w kolekcji <c>Osoby</c> kontrahenta.
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class OsobyKontaktoweTest : KontrahentTestBase
|
||||
{
|
||||
[Test]
|
||||
[Description("Dodana i powiązana osoba kontaktowa pojawia się w kolekcji Osoby kontrahenta.")]
|
||||
public void DodanieOsoby_PojawiaSieWKolekcjiOsoby()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
UtworzKontrahenta(kod, "Firma Z Osoba");
|
||||
SaveDispose();
|
||||
|
||||
var email = "a.nowak@firma-" + kod + ".pl";
|
||||
var k = Crm.Kontrahenci.WgKodu[kod];
|
||||
|
||||
InTransaction(() =>
|
||||
{
|
||||
var os = new KontaktOsoba();
|
||||
Session.AddRow(os);
|
||||
os.Kontrahent = k; // powiązanie osoby z kontrahentem
|
||||
os.Imie = "Anna";
|
||||
os.Nazwisko = "Nowak";
|
||||
os.Stanowisko = "Kierownik zakupów";
|
||||
os.EMAIL = email;
|
||||
});
|
||||
SaveDispose();
|
||||
|
||||
var zapisany = Crm.Kontrahenci.WgKodu[kod];
|
||||
zapisany.Osoby.Cast<KontaktOsoba>()
|
||||
.Any(o => o.Nazwisko == "Nowak" && o.Imie == "Anna")
|
||||
.Should().BeTrue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using AwesomeAssertions;
|
||||
using NUnit.Framework;
|
||||
using Soneta.Core;
|
||||
using Soneta.CRM;
|
||||
|
||||
namespace Soneta.Skills.Test.CRM.Kontrahenci;
|
||||
|
||||
/// <summary>
|
||||
/// W3 — Tworzenie kontrahenta.
|
||||
/// Testy pokazują utworzenie rekordu z minimalnym kompletem danych w transakcji edycyjnej
|
||||
/// oraz trwały zapis (SaveDispose) i ponowny odczyt z nowej sesji. Pokrywają warianty:
|
||||
/// podmiot gospodarczy krajowy, podmiot unijny oraz osoba fizyczna (finalny).
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TworzenieKontrahentaTest : KontrahentTestBase
|
||||
{
|
||||
[Test]
|
||||
[Description("Tworzy krajowy podmiot gospodarczy z NIP i zapisuje go trwale w bazie.")]
|
||||
public void TworzeniePodmiotuKrajowego_ZapisujeRekord()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
|
||||
var k = UtworzKontrahenta(kod, "Krajowa Firma Sp. z o.o.");
|
||||
InTransaction(() =>
|
||||
{
|
||||
k.PodatnikVAT = true;
|
||||
k.NIP = "1234563218"; // ustawienie NIP synchronizuje EuVAT
|
||||
});
|
||||
SaveDispose();
|
||||
|
||||
// Ponowny odczyt z nowej sesji potwierdza trwały zapis.
|
||||
var zapisany = Crm.Kontrahenci.WgKodu[kod];
|
||||
zapisany.Should().NotBeNull();
|
||||
zapisany.Nazwa.Should().Be("Krajowa Firma Sp. z o.o.");
|
||||
zapisany.StatusPodmiotu.Should().Be(StatusPodmiotu.PodmiotGospodarczy);
|
||||
zapisany.RodzajPodmiotu.Should().Be(RodzajPodmiotu.Krajowy);
|
||||
zapisany.PodatnikVAT.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Description("Tworzy podmiot unijny (RodzajPodmiotu.Unijny).")]
|
||||
public void TworzeniePodmiotuUnijnego_UstawiaRodzajUnijny()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
|
||||
UtworzKontrahenta(kod, "EU Trading GmbH",
|
||||
status: StatusPodmiotu.PodmiotGospodarczy,
|
||||
rodzaj: RodzajPodmiotu.Unijny);
|
||||
SaveDispose();
|
||||
|
||||
var zapisany = Crm.Kontrahenci.WgKodu[kod];
|
||||
zapisany.Should().NotBeNull();
|
||||
zapisany.RodzajPodmiotu.Should().Be(RodzajPodmiotu.Unijny);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Description("Tworzy osobę fizyczną (StatusPodmiotu.Finalny).")]
|
||||
public void TworzenieOsobyFizycznej_UstawiaStatusFinalny()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
|
||||
UtworzKontrahenta(kod, "Jan Kowalski",
|
||||
status: StatusPodmiotu.Finalny,
|
||||
rodzaj: RodzajPodmiotu.Krajowy);
|
||||
SaveDispose();
|
||||
|
||||
var zapisany = Crm.Kontrahenci.WgKodu[kod];
|
||||
zapisany.Should().NotBeNull();
|
||||
zapisany.StatusPodmiotu.Should().Be(StatusPodmiotu.Finalny);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using AwesomeAssertions;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Soneta.Skills.Test.CRM.Kontrahenci;
|
||||
|
||||
/// <summary>
|
||||
/// W5 — Bezpieczne usuwanie kontrahenta.
|
||||
/// Test pokazuje czyste usunięcie świeżo utworzonego rekordu (brak powiązań) oraz alternatywę
|
||||
/// „miękkiego" wycofania (<c>Blokada=true</c>), zalecaną gdy istnieją dokumenty/rozrachunki.
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class UsuwanieKontrahentaTest : KontrahentTestBase
|
||||
{
|
||||
[Test]
|
||||
[Description("Usunięcie kontrahenta bez powiązań (DeleteRow) usuwa rekord z bazy.")]
|
||||
public void CzysteUsuniecie_UsuwaRekord()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
UtworzKontrahenta(kod, "Do Usuniecia");
|
||||
SaveDispose();
|
||||
|
||||
var k = Crm.Kontrahenci.WgKodu[kod];
|
||||
k.Should().NotBeNull();
|
||||
|
||||
InTransaction(() => k.Delete());
|
||||
SaveDispose();
|
||||
|
||||
// Po usunięciu indeksator zwraca null.
|
||||
Crm.Kontrahenci.WgKodu[kod].Should().BeNull();
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Description("Miękkie wycofanie: zamiast usuwać, ustawiamy Blokada=true (rekord pozostaje).")]
|
||||
public void MiekkieWycofanie_UstawiaBlokade()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
UtworzKontrahenta(kod, "Do Wycofania");
|
||||
SaveDispose();
|
||||
|
||||
var k = Crm.Kontrahenci.WgKodu[kod];
|
||||
InTransaction(() => k.Blokada = true);
|
||||
SaveDispose();
|
||||
|
||||
var zapisany = Crm.Kontrahenci.WgKodu[kod];
|
||||
zapisany.Should().NotBeNull();
|
||||
zapisany.Blokada.Should().BeTrue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using AwesomeAssertions;
|
||||
using NUnit.Framework;
|
||||
using Soneta.Core;
|
||||
|
||||
namespace Soneta.Skills.Test.CRM.Kontrahenci;
|
||||
|
||||
/// <summary>
|
||||
/// W2 — Walidacja NIP / REGON / EU VAT przed zapisem.
|
||||
/// Testy weryfikują publiczne, statyczne walidatory z <c>Soneta.Core</c>
|
||||
/// (<see cref="Nip"/>, <see cref="Regon"/>, <see cref="EuVat"/>) oraz normalizację numerów.
|
||||
/// Walidatory sprawdzają format i sumę kontrolną — to NIE jest weryfikacja w MF/VIES (patrz W15).
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class WalidacjaNipRegonTest : KontrahentTestBase
|
||||
{
|
||||
[Test]
|
||||
[Description("Nip.Test akceptuje poprawny NIP (10 cyfr i format z myślnikami), odrzuca błędny.")]
|
||||
public void NipTest_RozrozniaPoprawnyIBledny()
|
||||
{
|
||||
// 1234563218 ma poprawną sumę kontrolną.
|
||||
Nip.Test("1234563218").Should().BeTrue();
|
||||
Nip.Test("123-456-32-18").Should().BeTrue();
|
||||
|
||||
// Zmiana ostatniej cyfry psuje sumę kontrolną.
|
||||
Nip.Test("1234563219").Should().BeFalse();
|
||||
Nip.Test("123").Should().BeFalse();
|
||||
|
||||
// Normalizacja: Flat usuwa myślniki, Format dodaje.
|
||||
Nip.Flat("123-456-32-18").Should().Be("1234563218");
|
||||
Nip.Format("1234563218").Should().Be("123-456-32-18");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Description("Regon.Test akceptuje poprawny REGON 9-znakowy, odrzuca błędny i o złej długości.")]
|
||||
public void RegonTest_RozrozniaPoprawnyIBledny()
|
||||
{
|
||||
// 123456785 ma poprawną sumę kontrolną dla 9-znakowego REGON.
|
||||
Regon.Test("123456785").Should().BeTrue();
|
||||
Regon.Test("123456784").Should().BeFalse();
|
||||
Regon.Test("12345").Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Description("EuVat.Test akceptuje krajowy numer z prefiksem PL nad poprawnym NIP, odrzuca błędny.")]
|
||||
public void EuVatTest_PrefiksPL_DzialaNaPoprawnymNip()
|
||||
{
|
||||
// EuVat.Test wymaga ISessionable (sprawdza listę krajów UE w bazie).
|
||||
EuVat.Test("PL1234563218", Session).Should().BeTrue();
|
||||
EuVat.Test("PL1234563219", Session).Should().BeFalse();
|
||||
|
||||
// Rozbicie numeru na kod kraju + identyfikator.
|
||||
EuVat.Split("PL1234563218", out var kraj, out var numer);
|
||||
kraj.Should().Be("PL");
|
||||
numer.Should().Be("1234563218");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using AwesomeAssertions;
|
||||
using NUnit.Framework;
|
||||
using Soneta.CRM;
|
||||
using Soneta.Kasa;
|
||||
|
||||
namespace Soneta.Skills.Test.CRM.Kontrahenci;
|
||||
|
||||
/// <summary>
|
||||
/// W9 — Warunki płatności i limity kredytowe.
|
||||
/// Testy pokazują ustawienie sposobu zapłaty (rekord <c>FormaPlatnosci</c> z modułu Kasa),
|
||||
/// terminu płatności oraz typu limitu kredytowego. Pola kalkulowane (np.
|
||||
/// <c>LimitNieograniczony</c>) są tylko do odczytu i wynikają z ustawień.
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class WarunkiPlatnosciTest : KontrahentTestBase
|
||||
{
|
||||
[Test]
|
||||
[Description("Ustawienie sposobu zapłaty (Przelew) i terminu płatności jest zapisywane.")]
|
||||
public void WarunkiPlatnosci_SposobIZaplatyTermin_SaZapisywane()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
UtworzKontrahenta(kod, "Firma Z Platnosciami");
|
||||
SaveDispose();
|
||||
|
||||
var k = Crm.Kontrahenci.WgKodu[kod];
|
||||
var przelew = Session.GetKasa().FormyPlatnosci[FormaPlatnosci.Przelew];
|
||||
|
||||
InTransaction(() =>
|
||||
{
|
||||
k.SposobZaplaty = przelew;
|
||||
k.Termin = 14; // dni
|
||||
});
|
||||
SaveDispose();
|
||||
|
||||
var zapisany = Crm.Kontrahenci.WgKodu[kod];
|
||||
zapisany.SposobZaplaty.Should().NotBeNull();
|
||||
zapisany.Termin.Should().Be(14);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Description("Typ limitu kredytowego = Nieograniczony skutkuje kalkulowanym LimitNieograniczony=true.")]
|
||||
public void LimitKredytowy_Nieograniczony_UstawiaFlageKalkulowana()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
UtworzKontrahenta(kod, "Firma Bez Limitu");
|
||||
SaveDispose();
|
||||
|
||||
var k = Crm.Kontrahenci.WgKodu[kod];
|
||||
InTransaction(() => k.TypLimituKredytowego = TypLimituKredytowego.Nieograniczony);
|
||||
SaveDispose();
|
||||
|
||||
var zapisany = Crm.Kontrahenci.WgKodu[kod];
|
||||
zapisany.TypLimituKredytowego.Should().Be(TypLimituKredytowego.Nieograniczony);
|
||||
zapisany.LimitNieograniczony.Should().BeTrue(); // pole kalkulowane (read-only)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using System.Linq;
|
||||
using AwesomeAssertions;
|
||||
using NUnit.Framework;
|
||||
using Soneta.Core;
|
||||
using Soneta.CRM;
|
||||
|
||||
namespace Soneta.Skills.Test.CRM.Kontrahenci;
|
||||
|
||||
/// <summary>
|
||||
/// W1 — Wyszukiwanie i identyfikacja kontrahenta.
|
||||
/// Testy pokazują trzy podstawowe sposoby odnajdywania kontrahenta używane w kodzie dodatków:
|
||||
/// po kodzie (klucz unikalny), po nazwie (klucz nieunikalny) oraz po NIP (filtr serwerowy
|
||||
/// <c>SubTable[condition]</c>, zamiast iteracji całej tabeli w pamięci).
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class WyszukiwanieKontrahentaTest : KontrahentTestBase
|
||||
{
|
||||
[Test]
|
||||
[Description("Wyszukanie po kodzie (indeks WgKodu) zwraca dokładnie utworzony rekord.")]
|
||||
public void WyszukiwaniePoKodzie_ZwracaUtworzonyRekord()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
UtworzKontrahenta(kod, "Firma Po Kodzie");
|
||||
SaveDispose();
|
||||
|
||||
// WgKodu to klucz unikalny — indeksator zwraca pojedynczy rekord lub null.
|
||||
var znaleziony = Crm.Kontrahenci.WgKodu[kod];
|
||||
|
||||
znaleziony.Should().NotBeNull();
|
||||
znaleziony.Nazwa.Should().Be("Firma Po Kodzie");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Description("Wyszukanie po nazwie (indeks WgNazwy, nieunikalny) zwraca zbiór z rekordem.")]
|
||||
public void WyszukiwaniePoNazwie_ZwracaRekordWZbiorze()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
var nazwa = "Wyszukiwarka " + kod;
|
||||
UtworzKontrahenta(kod, nazwa);
|
||||
SaveDispose();
|
||||
|
||||
// WgNazwy jest kluczem nieunikalnym — zwraca zbiór, z którego bierzemy pierwszy.
|
||||
var znaleziony = Crm.Kontrahenci.WgNazwy[nazwa].FirstOrDefault();
|
||||
|
||||
znaleziony.Should().NotBeNull();
|
||||
znaleziony.Kod.Should().Be(kod);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Description("Wyszukanie po NIP filtrem serwerowym SubTable[condition] zwraca rekord; " +
|
||||
"dedup wykrywa istniejący podmiot.")]
|
||||
public void WyszukiwaniePoNip_FiltrSerwerowy_ZnajdujeISygnalizujeDuplikat()
|
||||
{
|
||||
var kod = UnikalnyKod();
|
||||
var nip = "1234563218"; // poprawny NIP (suma kontrolna)
|
||||
var k = UtworzKontrahenta(kod, "Firma Z NIP");
|
||||
InTransaction(() => k.NIP = nip);
|
||||
SaveDispose();
|
||||
|
||||
// Filtr po stronie serwera (klauzula WHERE w SQL), nie iteracja w pamięci.
|
||||
// Warunek aplikujemy na indeksie tabeli (WgNIP); porównania tekstowe są case-insensitive.
|
||||
var znaleziony = Crm.Kontrahenci.WgNIP[(Kontrahent x) => x.NIP == nip].FirstOrDefault();
|
||||
znaleziony.Should().NotBeNull();
|
||||
znaleziony.Kod.Should().Be(kod);
|
||||
|
||||
// Typowy dedup przed dodaniem nowego kontrahenta:
|
||||
bool juzIstnieje = Crm.Kontrahenci.WgNIP[(Kontrahent x) => x.NIP == nip].Any();
|
||||
juzIstnieje.Should().BeTrue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>$(SonetaTargetFramework)</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Soneta.Business\Soneta.Business.csproj" />
|
||||
<ProjectReference Include="..\Soneta.Core\Soneta.Core.csproj" />
|
||||
<ProjectReference Include="..\Soneta.CRM\Soneta.CRM.csproj" />
|
||||
<ProjectReference Include="..\Soneta.Kasa\Soneta.Kasa.csproj" />
|
||||
<ProjectReference Include="..\Soneta.Test\Soneta.Test.csproj" />
|
||||
<ProjectReference Include="..\Soneta.Types\Soneta.Types.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user