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?

1

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.
2
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 :)

2

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.

4

@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ś :)

1

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 :).

2
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ć :).

3
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.

2
Kofcio napisał(a):

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 :).

Księgowym nie jestem ale pracowałem przy systemach ecommerce i magazynowych (m.in. WMS - warehouse management systems), których nieodłącznym elementem jest moduł księgowy, więc jednak coś wiem, ale jak tam chcesz

4

2. usunę 2 pozycje, dodam 1 pozycję a 1 zmodyfikuję (tabela: FakturaPozycje)
Zastanawiam się jednak jak powinien być zrealizowany drugi punkt?
Mam przynajmniej dwie opcje: zrobię update w tabeli FakturaNaglowek

Ten fragment mnie zastanawia: skoro chcesz zmieniać pozycje faktury, to powinieneś to poprawiać w tabeli z pozycjami faktury. Po co chcesz grzebać w Nagłówkach?

Znaczy - nie znam dokładnie tego, jak masz zaplanowaną bazę oraz aplikację, ale ja to rozumiem w ten sposób, że masz coś w stylu

  1. tabela z nagłówkiem: masz tam dane dot. dokumentu: jego numer, datę wystawienia, formę płatności, może podsumowanie całościowe wartości dokumentu (nie poszczególnych pozycji), operatora który wystawił itp.
  2. w tabeli z elementami/pozycjami masz szczegóły, a jednym z elementów każdej pozycji jest ID faktury, której składnikiem ta pozycja jest.

I teraz pytanie - co chcesz poprawiać w pierwszej tabeli? Chodzi o kwotę/wartość całkowitą faktury, czy jeszcze coś innego? Bo OK, wartość dokumentu się zmieni, ale co jeszcze? I zastanawia mnie wszystkie pozycje powiązane z FakturaNaglowek (5 pozycji) - wydaje mi się, że jednak danych w nagłówku powinno być trochę więcej. Powiedz proszę, co tam masz/jakie informacje trzymasz. W ogóle - jak masz to obecnie zrobione, kiedy następuje podliczenie całości, czy trzymasz te wartości w tabeli z nagłówkiem czy jakoś inaczej?

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.

Ponownie - mam wrażenie, że albo źle opisałeś sytuację, albo jakoś się źle rozumiemy.
Skoro pisałeś tylko w podanym przykładzie o usunę 2 pozycje, dodam 1 pozycję a 1 zmodyfikuję to zasadniczo w nagłówku nic (poza wartościami zbiorczymi całej faktury) się nie zmienia. Więc ja bym zrobił to tak, że po prostu - poprawiasz elementy w tabeli z pozycjami zamówienia, a jak już to skończysz to robisz na tej tabeli SELECT SUM(cena_netto) AS suma_cen_netto FROM pozycje_zamowienia WHERE faktura_ID = XXX; i sumę wartości poszczególnych pozycji osadzasz w nagłówku.

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.

Z jednej strony - tak, masz rację. Od tego są mechanizmy w stylu korekty, noty korygujące itp. ALE to teoria, a w praktyce to różnie bywa ;) Poza tym, pomijając poprawianie faktury sprzed tygodnia, bo się dogadałeś inaczej z klientem, to jeszcze jest przypadek w którym wystawiłem fakturę i praktycznie natychmiast pojawia się potrzeba jej poprawienia/usunięcia - bo np. okazało się, że coś źle wpisałem na WZ, albo klient dostał telefon od swojego klienta (tudzież żony) że jednak remontu nie będzie/mebli nie zmieniamy. Uważam, że system powinien dawać możliwość grzebania oraz kasowania dokumentów - to na operatorze spoczywa odpowiedzialność za to, co z tym zrobi. Tak samo jak nóż - można wykorzystać zarówno do zrobienia obiadu, zbudowania szałasu albo zabicia sąsiada. I to nie producent noży odpowiada za to, co klient zrobi z jego produktem. Inną sprawą jest umożliwienie ustawienia uprawnień użytkowników tak, aby osoba zarządzająca systemem mogła uniemożliwić pracownikom takie działania - jak chcesz coś usuwać/poprawiać to sam nie możesz (jeśli jesteś szeregowym magazynierem czy sprzedawcą), tylko musisz mieć zgodę kierownika z odpowiednimi uprawnieniami.

0

@cerrato o nagłówku wspomniałem bo traktuję punkt 1 i 2 jako całość. Może źle to opisałem, ale tak masz rację, że jak zmieniam tylko pozycję dokumentu bez danych nagłówka to nie ma potrzeby aktualizacji nagłówka. Oczywiście w nagłówku mogą być jakieś podsumowania pozycji etc, więc również może być potrzeba jego aktualizacji, ale ten temat nie budzi u mnie wątpliwości.
Bardziej zastanawiałem się jak podejść do tych pozycji - bo SQL-em raczej nie chcę sprawdzać co się zmieniło, więc muszę przerzucić to na aplikację (jakiś status każdej pozycji co z nią zrobić Add/Update/Delete/None). Stąd było moje pytanie czy nie lepiej wszystko usunąć (bez nagłówka i utworzyć ponownie), ale jak już wcześniej napisałem im dłużej o tym myślę tym bardziej jestem przekonany, że to złe rozwiązanie i te statusy będą ok.

0

Ja chyba nie rozumiem, gdzie leży problem.
Jeśli dobre zrozumiałem, to masz aplikację, która zaczytuje z bazy listę pozycji. W aplikacji modyfikujesz tę listę i na koniec chcesz pod przyciskiem zaktualizować bazę o wszystkie zmiany.
I gdzie problem? Jeśli w trakcie pracy dodałeś pozycję, to puszczasz insert. Jeśli usunąłeś, puszczasz delete. Jeśli zmodyfikowałeś, puszczasz update. Dodaj sobie w klasie (tablicy, liście, kolekcji, jsonie, xmlu, czy co tam masz pod maską) przechowującej daną pozycję właściwość przechowującą status (puste/I/U/D), albo trzy właściwości bitowe pokroju isNew, isDeleted (tak, podczas usuwania pozycji w aplikacji nie usuwaj obiektu, tylko oznacz go jako usunięty), isUpdated. Podczas zapisu dokumentu iterujesz po pozycjach i sprawdzasz, co z nimi trzeba zrobić w bazie i właśnie to robisz.
Jeśli przy modyfikacji pozycji w aplikacji oznaczyłeś pozycję do aktualizacji, to nie musisz sprawdzać w bazie, czy coś się zmieniło, lecz po prostu aktualizujesz pozycję w bazie danymi z aplikacji (bo w końcu chcesz, żeby w bazie było to, co użyszkodnik zaakceptował klikając "zapisz").

Jeśli to nie rozwiązuje problemu, to nie wiem, na czym problem polega.

0

SQL-em raczej nie chcę sprawdzać co się zmieniło, więc muszę przerzucić to na aplikację (jakiś status każdej pozycji co z nią zrobić Add/Update/Delete/None)

Pytanie - wcześniej pisałeś, że to apka webowa, jakieś API/dżejson. Czy masz możliwość grzebania w endpointach/zmiany czegoś na serwerze, czy jedynie możemy działać w oparciu o front?

1

wywal tę fakturę i dodaj jeszcze raz

2
Kofcio napisał(a):

Bardziej zastanawiałem się jak podejść do tych pozycji - bo SQL-em raczej nie chcę sprawdzać co się zmieniło, więc muszę przerzucić to na aplikację (jakiś status każdej pozycji co z nią zrobić Add/Update/Delete/None). Stąd było moje pytanie czy nie lepiej wszystko usunąć (bez nagłówka i utworzyć ponownie), ale jak już wcześniej napisałem im dłużej o tym myślę tym bardziej jestem przekonany, że to złe rozwiązanie i te statusy będą ok.

Sprawdzanie przez alikację będzie na pewno dużo wolniejsze, niż po stronie bazy danych. Musisz pobrać stare dane, sprawdzić z nowymi, nadać statusy itd.
Odpisałem ci w komentarzu, jak to szybko, łatwo i przyjemnie zrobić w PostgreSQl, bo ma do tego odpowiednie mechanizmy...
Szybki UPDATE w postgreSQL....

0

Mam pytanie do tych którzy chcą tworzyć znaczniki na pozycjach i wykonowyać delete/update/insert dla poszczególnych pozycjach. Dlaczego?

Czysto pragmatycznie, na wejściu dostaje dane które musze umieścić w tabeli 1:1 lub zastąpić, jaki jest cel w pisaniu mechanizmów: od frontu zaznaczanie zmiany usunięcia dodania i obsługiwanie tego na backendzie? Kiedy prosty delete i insert załatwia sprawę. Droga inna a cel identyczny.

A co z numeracją - wstawić pod tym samym numerem? Trzeba zrobić jakieś zabezpieczenie, żeby w tym czasie ktoś nie wskoczył w dziurę. I co z datą takiego ponownie wystawionego, jeśli "wywal i wstaw na nowo" będzie robione po kilku dniach?

@cerrato jasne że pod tym samym numerem, w końcu zastapienie to usunięcie i dodanie nowego. Możemy mówić o zabezpieczeniach, ale np. w przypadku jak będę miał pozycję do modyfikacji, a nie będzie jej w bazie (bo np. ktoś w międzyczasie ją usunął) to jej nie zaktualizuje. Dla mnie to przerost formy nad treścią.

0

@cerrato a z datą to masz rację że też trzeba by mieć starą jeśli edytujesz bo może być powiązana z numerem faktury

1

Coś mi się wydaje, że OP przyszedł z jednym konkretnym pytaniem, a dostaje więcej innych pytań, niż odpowiedzi :)
Można dywagować o datach, problemach współużytkowania (jak @Panczo zauważył, mogę chcieć zmodyfikować pozycję, którą ktoś inny przed chwilką usunął). I z każdym takim pytaniem coraz bardziej odsuwamy się od początkowego pytania i dodajemy kolejne problemy pod rozważanie, choć równie dobrze problemy mogą nie występować w przypadku @Kofcio. Albo mogły zostać już dawno rozwiązane.

4

OP przyszedł z jednym konkretnym pytaniem, a dostaje więcej innych pytań, niż odpowiedzi

No ale przecież tak właśnie powinien wyglądać proces badania wymagań klienta/biznesowych: przychodzi klient z ogólnie opisaną potrzebą, a potem w trakcie rozmowy się krystalizuje wizja, pojawiają się problemy (lub potencjalne źródła problemów) do przemyślenia i usunięcia, z wizji czysto biznesowej - czyli "jak wcisnę tę ikonkę to ma się wystawić faktura", przechodzimy do spraw technicznych: jak ma się wystawić, gdzie zapisać, jak ma się podliczyć itp.

Oczywiście - możemy to zrobić na zasadzie "byle działało i jazda", ale nie chciałbym, żeby w ten sposób architekt mi projektował dom, albo lekarz operował - z nastawieniem że raczej powinno być OK, pewnie się uda, nie szukajmy na siłę problemów tam, gdzie (raczej) ich nie ma :P

1

@Kofcio podstawowe pytanie - robisz projekt dla siebie , na zaliczenie do szkoły, czy może masz kawałek czegoś do zrobienia w ramach projektu w firmie w której pracujesz?
jak to ostatnie to nie kombinuj sam tylko zadaj na piśmie właściwe pytania przełożonym i uzyskaj odpowiedź też na piśmie bo inaczej to będziesz bohaterem następnego nagrania na jutubie jak to słynne z MF, a nasze forum będzie tam przedstawione jako zły duch programisty dający złe porady;)

0
Kofcio napisał(a):

Jak wy byście do tego podeszli?

Tak jak to zrobił Linus projektując Gita - skoro diffy są trudne i błędogenne to zastąpmy je snapshotami stanu.

Reszta jest historią a dyski są tanie.

2
Panczo napisał(a):

Mam pytanie do tych którzy chcą tworzyć znaczniki na pozycjach i wykonowyać delete/update/insert dla poszczególnych pozycjach. Dlaczego?

Czysto pragmatycznie, na wejściu dostaje dane które musze umieścić w tabeli 1:1 lub zastąpić, jaki jest cel w pisaniu mechanizmów: od frontu zaznaczanie zmiany usunięcia dodania i obsługiwanie tego na backendzie? Kiedy prosty delete i insert załatwia sprawę. Droga inna a cel identyczny.

Wydało mi się to korzystne z punktu widzenia aktualnego mechanizmu działania. API zwraca dany dokument wraz z pozycjami w pliku JSON. Front renderuje sobie go. Użytkownik coś tam robi, dodaje, usuwa oraz zmienia pozycje. Na koniec wykonuje się żądanie zmiany dokumentu przesłanego tez w pliku JSON do API. Teraz metoda musi zapisać zmiany do bazy danych. Oczywiście da się sprawdzić którą z pozycji należy dodać, którą usunąć, a na którym rekordzie wykonać update. Dodanie flagi co zrobić z danym rekordem jest po prostu uproszczeniem metody zapisującej wszystko do bazy. Sam osobiście wolałbym, mieć kilka metod API jak AddInvoiceItem, UpdateInvoiceItem oraz DeleteInvoiceItem niż jedną wielką UpdateInvoiceWithItems Zaś same zmiany zapisywałbym bezpośrednio po zmianie wykonanej przez użytkownika, a nie całość na raz.

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.