Modyfikowanie danych w tabelach powiązanych

0

Mam w bazie danych dwie tabele do przechowywania danych np. o fakturach: Tablea FakturaNaglowek oraz FakturaPozycje (w relacji 1 do wielu).
Tworząc nowy dokument faktury dodaję do tabeli FakturaNaglowek nową pozycję a następnie do tabeli FakturaPozycje dodaję pozycje, które są na fakturze.
Załóżmy, że dodałem fakturę z 5 pozycjami.

Następnie z jakiegoś powodu chcę zmodyfikować dane na fakturze w ten sposób, że:

  1. Zmienię adres dostawy (tabela: FakturaNaglowek)
  2. usunę 2 pozycje, dodam 1 pozycję a 1 zmodyfikuję (tabela: FakturaPozycje)

Ad 1) jest proste - wystarczy, że zrobię update na tabeli FakturaNaglowek - tu nie mam wątpliwości.

Zastanawiam się jednak jak powinien być zrealizowany drugi punkt?
Mam przynajmniej dwie opcje:

  1. zrobię update w tabeli FakturaNaglowek a następnie usunę wszystkie pozycje powiązane z FakturaNaglowek (5 pozycji) i utworzę je ponownie (4 pozycje) - to rozwiązanie wydaje się proste, bo nie muszę analizować co i w jaki sposób się zmieniło - update robię tylko na głównej tabeli (nagłówkowej).
  2. zrobię update w tabeli FakturaNaglowek a następnie z tabeli FakturaPozycje usunę 2 pozycje, dodam 1 pozycję a 1 zmodyfikuję - problem jest tylko taki, że w tym rozwiązaniu muszę dokładnie wiedzieć co zostało zmienione tj. muszę porównać sobie praktycznie każdą wartość z każdej tabeli. Może nie jest to jakiś duży problem, ale zastanawiam się, jak powinno zostać to zrobione profesjonalnie :)

Jak wy byście do tego podeszli?

0

Czy dobrze rozumiem, że tabela nagłówka ma jakieś zagreowane informacje z tabeli z pozycjami, etc? Poczytaj, może się przyda:

  1. triggery na tabeli z pozycjami (insert,delete,update) -> możesz w nich zawrzeć jakieś wyliczenie/updaty do tabeli nagłówkowej
  2. jeżeli postreess ma merge, to jest fajna instrukcja do upgradowania danych w tabeli (insert,delete,update) - mam na myśli tabelę z pozycjami.
1
Kofcio napisał(a):

Ad 1) jest proste - wystarczy, że zrobię update na tabeli FakturaNaglowek - tu nie mam wątpliwości.

Dlaczego nie zastosujesz tego punktu również dla punktu nr 2? Dodanie pozycji czy zmiana nie różni się przecież niczym od dodania/zmiany faktury. Są jakieś ku temu przesłanki?

wemibo napisał(a):

Czy dobrze rozumiem, że tabela nagłówka ma jakieś zagreowane informacje z tabeli z pozycjami, etc? Poczytaj, może się przyda:

  1. triggery na tabeli z pozycjami (insert,delete,update) -> możesz w nich zawrzeć jakieś wyliczenie/updaty do tabeli nagłówkowej

Trigger jest nawet fajnym rozwiązaniem. Jednak tu jak zwykle zdania są podzielone. Albo baza danych jest głupia i trzyma tylko dane, ewentualnie więzy integralności w postaci kluczy zewnętrznych, zaś sam system czuwa nad poprawnością np. kwot netto, vat, brutto z pozycji na główce dokumentu. Można to zrobić triggerem. Ale wtedy baza danych nie jest już tylko pojemnikiem na dane i musi umieć trochę więcej. Co więcej czasami wyzwalacze stają się tak rozrośnięte, że są trudne w utrzymaniu. Potrafi również zajść sytuacja, że wyzwalacze są nieprzenośne pomiędzy różnymi RDBMS'ami i to może być skreślające te rozwiązanie. Kolejnym minusem jest to, że trigger jako taki trudno się testuje i to jest moim zdaniem jest na minus. Natomiast ortodoksyjni ludzie mówią, że takie dane naruszają postać normalną bazy danych i są zbędne, więc nie należy ich trzymać :D

wemibo napisał(a):
  1. jeżeli postreess ma merge, to jest fajna instrukcja do upgradowania danych w tabeli (insert,delete,update) - mam na myśli tabelę z pozycjami.

Jaki cel ma wykonanie polecenia merge na konkretnym rekordzie celem uaktualnienia np. ilości, ceny czy nazwy towaru na fakturze? Przecież pobierając dane można zapamiętać ID pozycji i następnie dokonać:
update POZYCJE set ILOSC = :ILOSC, CENA = :CENA, .... where ID = :ID
Nie ma tu żadnej potrzeby mergowania czegokolwiek ;)

Kofcio napisał(a):

Jak wy byście do tego podeszli?

Zależy jakie miałbym wymagania. W swoim systemie od razu po zapisie/usunięciu pozycji robię update albo delete na konkretnym rekordzie. Działa to bez problemów od wielu lat. Każde rozwiązanie ma swoje wady i zalety. Jednak odpowiedz dlaczego chcesz kombinować bardziej zaawansowane sposoby zrobienia prostej rzeczy :)

1

Masz błąd logiczny w aplikacji bo faktur się z reguły nie poprawia. Chyba ze opisujesz sytuację gdy faktura nie trafiła do obiegu prawnego.

2

@markone_dev większość systemów z jakimi miałem do czynienia blokuje fakturę dopiero po jej wydrukowaniu. Ale jeśli taki z Ciebie purysta, to zamień słowo faktura na zamówienie ;) Sytuacja będzie analogiczna.

Poza tym czemu ma błąd logiczny? Błędnym jest zakładanie, że fakturę da się zmienić w każdej sytuacji. Pytający nie napisał nic o warunkach w jakich zmienia dokumenty. A ogólnie to jest normalna rzecz i sam popełniasz błąd logiczny stosując pewne założenia które sam przyjąłeś :)

0

Jak już wystawiłeś fakturę, to jedyna poprawna opcja, to wystawić fakturę korygującą.

1

@yarel oczywiście, że nie. Kluczowe jest zdanie:

markone_dev napisał(a):

Chyba ze opisujesz sytuację gdy faktura nie trafiła do obiegu prawnego.

Ergo, faktura nie wydrukowana, nie wysłana do KSEF itp nie jest wprowadzona do obiegu prawnego. Zatem można taką fakturę skasować oraz dowolnie edytować.

0

@Mr.YaHooo masz rację, trochę uogólniłem 😀

0
Mr.YaHooo napisał(a):

Dlaczego nie zastosujesz tego punktu również dla punktu nr 2? Dodanie pozycji czy zmiana nie różni się przecież niczym od dodania/zmiany faktury. Są jakieś ku temu przesłanki?

Tak, dodanie pozycji i ewentualnie zmiana nie są problemem, ale w punkcie drugim główny problem jest taki, że z 5 pozycji 2 zostały usunięte, 1 została dodana a 1 zmieniona.
Aplikacja jest webowa i wszystko robione jest przez API, które otrzymuje JSON-a. Więc teraz API musi ustalić, które z tych danych zostały w jaki sposób zmienione/dodane/usunięte.
Może nie jest to jakieś wybitnie trudne, bo mogę dodać do każdego elementu jakiś status, ale zastanawiałem się czy nie będzie prościej usunąć wszystkie elementy i dodać te aktualne. Ale im dłużej nad tym myślę, tym bardziej wydaje mi się to głupie i chyba jednak zostanę przy tych statusach :)

Kofcio napisał(a):

Jak wy byście do tego podeszli?

Zależy jakie miałbym wymagania. W swoim systemie od razu po zapisie/usunięciu pozycji robię update albo delete na konkretnym rekordzie. Działa to bez problemów od wielu lat. Każde rozwiązanie ma swoje wady i zalety. Jednak odpowiedz dlaczego chcesz kombinować bardziej zaawansowane sposoby zrobienia prostej rzeczy :)

No tak, tylko jak utworzę dokument a następnie do niego wejdę w celu modyfikacji i usunę jakąś pozycję to nie mogę jej kasować od razu w bazie danych, bo user może chcieć zamknąć dokument bez zapisu (więc musiałbym cofnąć te zdarzenia). Tak więc do czasu ostatecznej decyzji usera o ponownym zapisaniu dokumentu wolałbym nie dokonywać żadnych zmian na bazie.

wemibo napisał(a):

Czy dobrze rozumiem, że tabela nagłówka ma jakieś zagreowane informacje z tabeli z pozycjami, etc? Poczytaj, może się przyda:

  1. triggery na tabeli z pozycjami (insert,delete,update) -> możesz w nich zawrzeć jakieś wyliczenie/updaty do tabeli nagłówkowej
  2. jeżeli postreess ma merge, to jest fajna instrukcja do upgradowania danych w tabeli (insert,delete,update) - mam na myśli tabelę z pozycjami.

Wiem czym są triggery, ale nie bardzo wiem co one mają do opisywanego problemu? O merge chyba nie słyszałem, ale jak teraz na szybko czytam to też chyba mało związane z tematem. Ale dzięki.

markone_dev napisał(a):

Masz błąd logiczny w aplikacji bo faktur się z reguły nie poprawia. Chyba ze opisujesz sytuację gdy faktura nie trafiła do obiegu prawnego.

yarel napisał(a):

Jak już wystawiłeś fakturę, to jedyna poprawna opcja, to wystawić fakturę korygującą.

Ehh... Z zawodu jestem księgowym, więc kojarzę ustawę o VAT, ale także wiem jak wygląda praktyka w tym zakresie. Poza tym nie znam programu księgowego, który nie pozwoliłby poprawić dokumentu (chyba, że został już zatwierdzony). Po drugie to był tylko przykład. Jak ma to w czymś pomóc możemy zmienić przykład na listę zakupów.
Ogólnie to dzięki za chęć pomocy, ale wydaje mi się, że takie dygresje nie pomagają :).

0
Kofcio napisał(a):

Ehh... Z zawodu jestem księgowym, więc kojarzę ustawę o VAT, ale także wiem jak wygląda praktyka w tym zakresie. Poza tym nie znam programu księgowego, który nie pozwoliłby poprawić dokumentu (chyba, że został już zatwierdzony). Po drugie to był tylko przykład. Jak ma to w czymś pomóc możemy zmienić przykład na listę zakupów.
Ogólnie to dzięki za chęć pomocy, ale wydaje mi się, że takie dygresje nie pomagają :).

A skąd mam wiedzieć kim jesteś z zawodu? Forum też czytają osoby które nie znają się na prawie podatkowym, więc bez szerszego kontekstu mogą sobie pomysleć, że tak można. Napisałem

Chyba ze opisujesz sytuację gdy faktura nie trafiła do obiegu prawnego.

co zamyka temat modyfikacji faktur.

0
markone_dev napisał(a):

A skąd mam wiedzieć kim jesteś z zawodu? Forum też czytają osoby które nie znają się na prawie podatkowym, więc bez szerszego kontekstu mogą sobie pomysleć, że tak można. Napisałem

Chyba ze opisujesz sytuację gdy faktura nie trafiła do obiegu prawnego.

co zamyka temat modyfikacji faktur.

Nie musisz wiedzieć kim jestem z zawodu, ale możesz ograniczyć swoje wypowiedzi do zadanego w wątku pytania a nie robić dygresję na tematy w zakresie których chyba nie masz zbyt dużego doświadczenia :).

1
Kofcio napisał(a):

No tak, tylko jak utworzę dokument a następnie do niego wejdę w celu modyfikacji i usunę jakąś pozycję to nie mogę jej kasować od razu w bazie danych, bo user może chcieć zamknąć dokument bez zapisu (więc musiałbym cofnąć te zdarzenia). Tak więc do czasu ostatecznej decyzji usera o ponownym zapisaniu dokumentu wolałbym nie dokonywać żadnych zmian na bazie.

Czyli dopiero kliknięcie w oknie klawisza 'Zapisz' zapisuje całość dokumentu do bazy? Trochę to komplikuje całą sytuację. Ogólnie kierowałbym się ku temu, że to jest nie do końca przemyślany pomysł. W przypadku faktur usługowych jeszcze mogę się zgodzić, że tak można robić. Ale w przypadku dokumentów jakie mają powiązanie z magazynem to nie do końca trafiony pomysł. Czasami użytkownik pisze długi dokument, pisze go długo bo w trakcie zadzwonił telefon i zostawił otwarte okno z w połowie wprowadzonym dokumentem na 15 minut. Pech chciał, że zdjął ze stanu magazynowego ostatnie sztuki danej rzeczy. Ale 15 minut nie było go przy komputerze ponieważ rozmawiał przez telefon. W tym czasie ktoś inny pisał kolejny dokument, zapisał go i zdjął wcześniej daną rzecz. Użytkownik nieświadomy wraca do komputera po 15 minutach, pisze kolejne 10 pozycji. Klika zapisz i dowiaduje się, że jednak to co chce sprzedać już nie istnieje na stanie? Trochę średnie rozwiązanie. Nie mniej jednak takie rzeczy zdarzają się w rzeczywistym świecie :D

Skoro aplikacja działa poprzez API i masz tak specyficzne wymaganie, to w zasadzie można również w dokumencie jaki przesyłasz po zmianach dać jakiś status pozycji, jak sam wcześniej zauważyłeś. Dodatkowo posłużyć się ID z tabeli w bazie. I taki status może mieć 1 z paru możliwości:

  • pozycja usunięta
  • pozycja zmodyfikowana
  • nowa pozycja

W przypadku 2-ch pierwszych ID musi zostać uzupełnione, bo to pokazuje do jakiego ID odnosi się delete albo update w przypadku nowej pozycji to baza danych nada nam ID rekordu więc te pole pozostawiamy puste. Potem jak serwer odbierze takiego JSON'a to modyfikuje/usuwa/dodaje odpowiednie rekordy. Gotowe. To chyba będzie najsensowniejsze rozwiązanie.

0
Kofcio napisał(a):

...

yarel napisał(a):

Jak już wystawiłeś fakturę, to jedyna poprawna opcja, to wystawić fakturę korygującą.

Ehh... Z zawodu jestem księgowym, więc kojarzę ustawę o VAT, ale także wiem jak wygląda praktyka w tym zakresie. Poza tym nie znam programu księgowego, który nie pozwoliłby poprawić dokumentu (chyba, że został już zatwierdzony). Po drugie to był tylko przykład. Jak ma to w czymś pomóc możemy zmienić przykład na listę zakupów.
Ogólnie to dzięki za chęć pomocy, ale wydaje mi się, że takie dygresje nie pomagają :).

Wybacz dygresję, ale czy wystawienie dokumentu (faktury) nie jest tożsame, z jego zatwierdzeniem? np. będąc u notariusza, widziałem, że miał wersję roboczą aktu notarialnego w wordzie, ale nie był to akt notarialny, a jego zapis w wordzie.

Od strony technicznej -> wersja robocza (nie została zatwierdzona), co szkodzi usunąć całość i utworzyć nowy dokument?
np. 1 transakcja:

  • usuń dokument
  • wstaw dane z pamięci programu
  • zatwierdź transakcję

albo inna transakcja:

  • usuń / wstaw pozycje
  • zmień numerację pozycji
0
Mr.YaHooo napisał(a):

Czyli dopiero kliknięcie w oknie klawisza 'Zapisz' zapisuje całość dokumentu do bazy? Trochę to komplikuje całą sytuację. Ogólnie kierowałbym się ku temu, że to jest nie do końca przemyślany pomysł. W przypadku faktur usługowych jeszcze mogę się zgodzić, że tak można robić. Ale w przypadku dokumentów jakie mają powiązanie z magazynem to nie do końca trafiony pomysł. Czasami użytkownik pisze długi dokument, pisze go długo bo w trakcie zadzwonił telefon i zostawił otwarte okno z w połowie wprowadzonym dokumentem na 15 minut. Pech chciał, że zdjął ze stanu magazynowego ostatnie sztuki danej rzeczy. Ale 15 minut nie było go przy komputerze ponieważ rozmawiał przez telefon. W tym czasie ktoś inny pisał kolejny dokument, zapisał go i zdjął wcześniej daną rzecz. Użytkownik nieświadomy wraca do komputera po 15 minutach, pisze kolejne 10 pozycji. Klika zapisz i dowiaduje się, że jednak to co chce sprzedać już nie istnieje na stanie? Trochę średnie rozwiązanie. Nie mniej jednak takie rzeczy zdarzają się w rzeczywistym świecie :D

Ja w opisanej sytuacji nie widzę problemu - można się przed nią na wiele sposobów zabezpieczyć m.in. w momencie zapisywania dokumentu można sprawdzić stan magazynu i w razie czego rzucić wyjątkiem a usera grzecznie poinformować, że nie udało się zapisać dokumentu.

Skoro aplikacja działa poprzez API i masz tak specyficzne wymaganie, to w zasadzie można również w dokumencie jaki przesyłasz po zmianach dać jakiś status pozycji, jak sam wcześniej zauważyłeś. Dodatkowo posłużyć się ID z tabeli w bazie. I taki status może mieć 1 z paru możliwości:

  • pozycja usunięta
  • pozycja zmodyfikowana
  • nowa pozycja

W przypadku 2-ch pierwszych ID musi zostać uzupełnione, bo to pokazuje do jakiego ID odnosi się delete albo update w przypadku nowej pozycji to baza danych nada nam ID rekordu więc te pole pozostawiamy puste. Potem jak serwer odbierze takiego JSON'a to modyfikuje/usuwa/dodaje odpowiednie rekordy. Gotowe. To chyba będzie najsensowniejsze rozwiązanie.

Tak, dokładnie o tym samym pisałem wyżej tylko już nie wspomniałem, że ten "status" to Update/Delete/Insert - ale dokładnie to miałem na myśli :-)

yarel napisał(a):

Wybacz dygresję, ale czy wystawienie dokumentu (faktury) nie jest tożsame, z jego zatwierdzeniem? np. będąc u notariusza, widziałem, że miał wersję roboczą aktu notarialnego w wordzie, ale nie był to akt notarialny, a jego zapis w wordzie.

Od strony technicznej -> wersja robocza (nie została zatwierdzona), co szkodzi usunąć całość i utworzyć nowy dokument?
np. 1 transakcja:

  • usuń dokument
  • wstaw dane z pamięci programu
  • zatwierdź transakcję

albo inna transakcja:

  • usuń / wstaw pozycje
  • zmień numerację pozycji

Nie, przed zatwierdzeniem dokumentu masz przeważnie jeszcze coś takiego jak "bufor" - do czasu gdy dokument jest w buforze można go dowolnie edytować w tym usunąć. Przeważnie jest tak, że sam decydujesz kiedy taki dokument zatwierdzić - jedni robią to od razu (po wystawieniu dokumentu), niektórzy czekają z tym do kolejnego miesiąca a jeszcze inni w ogóle tego nie robią - bo jak zatwierdzą, to już nie będzie można nic zmienić.

I ja wiem, że w teorii faktycznie jest tak, że jak dokument trafi do obiegu (zostanie przekazany klientowi) to nie powinno się go modyfikować. Praktyka jest jednak zupełnie inna. Są przeróżne sytuacje, gdzie klienci wolą podmienić dokument lub go "wyjąć z obiegu", niż bawić się w jego korygowanie - szczególnie, że w zależności od systemu pewne zmiany mogą nawet nie być możliwe (z technicznego punktu widzenia - wtedy trzeba sobie radzić np. z wystawianiem korekty w wordzie).

I ja rozumiem wasze dobre intencje i że chcecie się dostosować do panujących przepisów itd, ale bierzecie również pod uwagę, że to tylko głupi dokumentem księgowy, który nawet nie musi być podpisany :). Czasami narzucanie przez program pewnych czynności jest słuszne, ale w wielu sytuacjach tylko iryguje użytkownika, bo ludzie są różni i mają różne potrzeby i podejście do pewnych spraw i dla jednych będzie to miało znaczenie a dla innych nie. Dlatego programy powinny być elastyczne, aby każdy mógł sobie je skonfigurować pod siebie a nie z nimi ciągle walczyć :).

1
Kofcio napisał(a):

Ja w opisanej sytuacji nie widzę problemu - można się przed nią na wiele sposobów zabezpieczyć m.in. w momencie zapisywania dokumentu można sprawdzić stan magazynu i w razie czego rzucić wyjątkiem a usera grzecznie poinformować, że nie udało się zapisać dokumentu.

Ale powiedz to userowi. Mozolnie 10 minut pisze dokument złożony z 20 pozycji i na sam koniec dostaje komunikat brak na stanie. Ja bym się deczko zdenerwował na taki system :) Akurat mam dużo do czynienia z użyszkodnikami i i wiem czego akurat moi oczekują. U Ciebie może być z goła inaczej. Dlatego odpowiedź brzmi to zależy.

Kofcio napisał(a):

Tak, dokładnie o tym samym pisałem wyżej tylko już nie wspomniałem, że ten "status" to Update/Delete/Insert - ale dokładnie to miałem na myśli :-)

Akurat nie znam się zupełnie na pisaniu API, ale tak to chyba by było najlepiej zrobić. Chyba, że ktoś ma inne propozycje. Chętnie poczytam, jak to się robi w webie :)

Kofcio napisał(a):

Nie, przed zatwierdzeniem dokumentu masz przeważnie jeszcze coś takiego jak "bufor" - do czasu gdy dokument jest w buforze można go dowolnie edytować w tym usunąć. Przeważnie jest tak, że sam decydujesz kiedy taki dokument zatwierdzić - jedni robią to od razu (po wystawieniu dokumentu), niektórzy czekają z tym do kolejnego miesiąca a jeszcze inni w ogóle tego nie robią - bo jak zatwierdzą, to już nie będzie można nic zmienić.

Widziałem taki system i działało to nawet fajnie. Był sobie dokument w buforze, ale bez wpływu na stany magazynowe itp. Dopiero akceptacja powodowała zdjęcie/przyjęcie na stan w zależności od typu dokumentu.

Kofcio napisał(a):

I ja wiem, że w teorii faktycznie jest tak, że jak dokument trafi do obiegu (zostanie przekazany klientowi) to nie powinno się go modyfikować. Praktyka jest jednak zupełnie inna. Są przeróżne sytuacje, gdzie klienci wolą podmienić dokument lub go "wyjąć z obiegu", niż bawić się w jego korygowanie - szczególnie, że w zależności od systemu pewne zmiany mogą nawet nie być możliwe (z technicznego punktu widzenia - wtedy trzeba sobie radzić np. z wystawianiem korekty w wordzie).

Życie jest życiem i faktycznie zdarzają się poprawki dokumentów wysłanych do klientów. Jednak po wejściu KSeF już takich machinacji nie będzie. Z drugiej strony pamiętam jak robiłem zakupy w pewnym sklepie. Widać dziewczyna się uczyła, bo dostałem fakturę pierwotną, korektę do tej faktury oraz korektę do korekty. Trochę to słabe przy zwykłych zakupach biurowych.

Kofcio napisał(a):

I ja rozumiem wasze dobre intencje i że chcecie się dostosować do panujących przepisów itd, ale bierzecie również pod uwagę, że to tylko głupi dokumentem księgowy, który nawet nie musi być podpisany :). Czasami narzucanie przez program pewnych czynności jest słuszne, ale w wielu sytuacjach tylko iryguje użytkownika, bo ludzie są różni i mają różne potrzeby i podejście do pewnych spraw i dla jednych będzie to miało znaczenie a dla innych nie. Dlatego programy powinny być elastyczne, aby każdy mógł sobie je skonfigurować pod siebie a nie z nimi ciągle walczyć :).

Analogicznie jak słynny ZUS'owski "Płatnik" wymaga zmiany hasła co 30 dni. Jednak jeden wpis w rejestrze systemowym i wymuszanie da się obejść :D Już dawno tego nie robiłem, ale jak jeszcze chodziłem po klientach instalując podpisy, ZUS'y, banki w wolnej chwili to pierwsze pytanie było czy da się wyłączyć zmianę hasła w Płatniku :D

1

Jak zapisuje dokument który jest zapisywany "na raz", po zatwierdzeniu przez użytkownika, to updated na nagłówku, usunięcie pozycji, dodanie pozycji z "bufora".

Nie bardzo widzę sens w usuwaniu usuniętych, modyfikacji zmienionych i dodaniu nowych. To jest zbędne oprogramowanie czegoś co nie ma znaczenia, skoro efektem ma być to co faktycznie zostało wprowadzone przez użytkownika.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.