Kontrola wydania WZC i forki zapisu w bazie - dla wdrożeniowców
Strona opisuje, jak zatwierdzenie dokumentów PZC i WZC przechodzi przez forki zapytań zapisu, gdzie w transakcji leży kontrola celna i jak baza odmawia wydania kodem 50210. Dotyczy wdrożeniowca, który wgrywa moduł dozoru celnego na bazę klienta lub demo i musi umieć sprawdzić, czy kontrola faktycznie działa. Opis zakłada znajomość modelu danych modułu.
Na tej stronie
Forki zatwierdzenia PZC i WZC
Nowe typy dokumentów PZC i WZC nie mają własnych tabel ruchów ani własnych zapytań zapisu pozycji. Ruch zapisują istniejące zapytania zatwierdzenia dokumentów PZB, PW i WZ. Moduł dozoru dokłada do nich swoje wywołania przez fork, czyli kopię zapytania źródłowego rozszerzoną o dodatkowe polecenie. Powstają dwa forki, oznaczone w dokumentacji jako CE38 i CE43.
| Fork | Zapytanie źródłowe (UID) | Dołożone polecenie | Kolejność | Efekt |
|---|---|---|---|---|
| CE38 | 0E430063-D762-40C8-8934-89D4E7F5610F (zatwierdzenie PZB i PW) | EXEC sp_cel_pzc_zapisz | Treść źródłowa, potem procedura | Partie ze statusem celnym, wpis historii, kontener do kartoteki, powiązanie x_cel_pzc. |
| CE43 | 696AA17C-A7B3-48E7-9B14-EA8402B4FA49 (zatwierdzenie WZ) | EXEC sp_cel_sprawdz_wydanie | Procedura, potem treść źródłowa | Odmowa THROW 50210 przed zmianą ruchów magazynowych. |
Zapytania ekranów należą do jednej rodziny UID C3E1A7D5-2B48-4F6A-9C10-8E5D7B3FCExx, z rolą WMS i loginem dozor_celny. Fork zatwierdzenia PZC ma numer 38, fork zatwierdzenia WZC ma numer 43. Pozostałe numery w rodzinie obsługują odczyty i zapisy ekranów modułu, w tym 39 (kolizja kontenera), 40-42 i 44 (pomocnicze zapytania formularza WZC).
Fork jest budowany z bieżącej treści zapytania źródłowego na danej bazie, a nie z jego kopii zapisanej w skrypcie. Skrypt dbup czyta aktualną treść zapytań 0E430063 i 696AA17C i składa z nich zapytanie fork. Dzięki temu poprawka zapytania źródłowego, wprowadzona na bazie przed wgraniem modułu, trafia do forka.
Skutek braku zapytania źródłowego. Jeśli na bazie nie ma zapytania 0E430063 albo 696AA17C, skrypt pomija odpowiedni fork i wypisuje komunikat PRINT. Zatwierdzenie dokumentu działa wtedy jak zwykłe PZB lub WZ, bez zapisu partii celnych i bez kontroli celnej. Po wgraniu na bazę, której zapytania mogły zostać zmienione, sprawdź obecność obu forków zapytaniem diagnostycznym z sekcji o diagnostyce i nie zakładaj, że moduł zadziałał, bo skrypt zakończył się bez błędu.
Kolejność w transakcji zatwierdzenia
Zapytania zapisu są wykonywane sterownikiem ssExSQL, który owija je w transakcję serwera. Fork CE43 wywołuje procedurę sp_cel_sprawdz_wydanie jako pierwszą, przed treścią źródłową zatwierdzenia WZ. Dopiero po przejściu kontroli wykonuje się aktualizacja ruchów w dpmag, czyli zmiana ACH z roboczego na zatwierdzony i nadanie numeru. Gdy procedura rzuci błąd, aktualizacja nie rusza.
W forku CE38 kolejność jest odwrotna: najpierw zatwierdza się dokument według treści źródłowej, potem procedura sp_cel_pzc_zapisz zapisuje partie, wpis historii ze źródłem PZC i kontener. Cała sekwencja leży w jednej transakcji, więc błąd w zapisie partii cofa także numer dokumentu. Odczyty ekranów korzystają ze sterownika ssDataSQL i procedur z własną transakcją, co ma znaczenie przy wykrywaniu błędów (patrz sekcja o pułapkach).
Warunek odmowy i THROW 50210
Kontrola sprawdza tylko pozycje rozchodowe dokumentu, czyli wiersze z ilością ujemną (ILOSC mniejsza od zera) i z ACH równym 0 albo 1. Bufor (ACH inne niż 1) nie jest sprawdzany: kontrola uruchamia się w forku zapytania zatwierdzenia, a przycisk Bufor tego zapytania nie wywołuje.
- Warunek - STATUS spoza zbioru 3 i 4 albo (STATUS w zbiorze 1 i 2 oraz TERMIN_DOZORU wcześniejszy niż dziś).
- Zakres wierszy - tylko ILOSC mniejsza od zera i ACH równe 0 albo 1, czyli pozycje rozchodowe dokumentu.
- Odmowa - THROW 50210 z komunikatem "Wydanie zablokowane: partia bez zwolnienia celnego lub z przekroczonym terminem dozoru."
- Bufor - wiersze z ACH innym niż 1 nie są sprawdzane; zapis do bufora nie uruchamia odmowy.
Drugi człon warunku zawiera się w pierwszym: statusy 1 i 2 nie należą do zbioru 3 i 4, więc partia ze statusem Pod dozorem lub Zgłoszony jest odrzucana także bez względu na termin. W praktyce o odmowie decyduje więc status partii, a partie po terminie dostają status Zablokowany przy wejściu w kokpit, zwolnienia i blokady oraz terminy dozoru, bez zadania cyklicznego.
Powody odmowy dla okna Wydanie zablokowane zwraca osobne zapytanie (numer 42 w rodzinie). Treść komunikatu THROW 50210 jest stała, a lista partii z powodami pochodzi z tego odczytu.
Blokady wierszy i współbieżność z importem zwolnienia
Wiersze partii x_cel_partia są czytane przez procedurę sprawdzenia z podpowiedziami UPDLOCK i HOLDLOCK i z ustawieniem SET LOCK_TIMEOUT 5000. Blokada obejmuje wiersze wydawanych partii, a nie całą tabelę, i trzyma się do końca transakcji. Kontrola i zapis ruchu widzą w ten sposób ten sam stan partii.
Import zwolnienia z kolejki agencji zmienia status tej samej partii w jednej transakcji, więc obie operacje konkurują o ten sam wiersz. Kto zacznie później, czeka na tego, kto zaczął pierwszy, aż do zatwierdzenia lub cofnięcia jego transakcji. Jeśli oczekiwanie przekroczy 5000 milisekund, serwer zwraca błąd 1222. Dla użytkownika oba kierunki mają osobne komunikaty:
- Zatwierdzenie WZC czeka na import - komunikat "Trwa przetwarzanie komunikatu agencji dla tych partii".
- Import czeka na zatwierdzenie WZC - komunikat "Partie są właśnie zatwierdzane w wydaniu (blokada wiersza) - ponów komunikat za chwilę." Komunikat można ponowić przyciskiem Ponów wybrany komunikat w kolejce importu.
Skutek dla operatora jest łagodny: transakcja cofa się w całości, a operację wystarczy powtórzyć po kilku sekundach.
Zapisy PZC i kody błędów
Procedura zapisu PZC rzuca błędy aplikacyjne z zakresu 50201-50205. Wszystkie cofają transakcję zatwierdzenia, więc nic z zapisanego w transakcji nie zostaje w bazie. Odmowa wydania ma osobny kod 50210.
| Kod | Dotyczy | Treść komunikatu |
|---|---|---|
| 50201 | PZC | Wskaż dokument celny. |
| 50202 | PZC | Dokument celny należy do innego klienta. |
| 50203 | PZC | Kontener nie spełnia ISO 6346. |
| 50204 | PZC | Każda pozycja musi mieć numer partii (partia niesie status celny; wartość BRAK nie wystarcza). |
| 50205 | PZC | Partia jest już pod ewidencją celną (dokument ...). |
| 50210 | WZC | Wydanie zablokowane: partia bez zwolnienia celnego lub z przekroczonym terminem dozoru. |
Cały zakres kodów modułu to: 50001-50008 dokument, 50011-50014 pozycja, 50021-50022 usuwanie, 50031-50034 agencja, 50041-50044 kontener, 50051-50053 magazyn, 50061-50064 parametr, 50071-50078 zmiana statusu, 50101-50108 import, 50201-50205 PZC i 50210 WZC. Numer błędu pozwala odróżnić odmowę aplikacyjną od błędu serwera, takiego jak 1222.
Czego kontrola nie chroni
Kontrola leży w forku zatwierdzenia WZ, więc obejmuje wyłącznie dokument WZC. Dokumenty WZB i RW wystawione na partię celną, a także bezpośrednie zapisy do tabeli ruchów dpmag, nie przechodzą przez sp_cel_sprawdz_wydanie. Trigger na tabeli ruchów rozważono i odrzucono jako zbyt inwazyjny, więc zakres ochrony to świadoma decyzja.
Wdrożeniowiec nie powinien przedstawiać klientowi blokady jako ochrony wszystkich ścieżek wydania. Zakres ochrony jest zakresem dokumentu WZC. Jeżeli klient używa WZB lub RW do wydawania towaru ze składu celnego, ewidencja dozoru tego nie zatrzyma, a rozbieżność wykaże dopiero przegląd ruchów, na przykład zapytaniem z sekcji o diagnostyce. Uprawnienia CEL_* nie są wdrożone i dostęp wynika z menu roli.
Diagnostyka: zapytania SELECT
Zapytania poniżej tylko czytają dane. Zakładają, że ruch w dpmag niesie kolumny klucza partii o tych samych nazwach co x_cel_partia: MAGAZYN, NRIDODN, NRIDASN i NRSERII. Przed użyciem sprawdź to na swojej bazie, a parametr @refno zastąp numerem referencyjnym dokumentu.
Partie z odmową dla dokumentu o numerze referencyjnym @refno:
SELECT p.NRSERII, p.STATUS, p.TERMIN_DOZORU, p.POWOD_BLOKADY
FROM dpmag m
JOIN x_cel_partia p ON p.MAGAZYN = m.MAGAZYN AND p.NRIDODN = m.NRIDODN
AND p.NRIDASN = m.NRIDASN AND p.NRSERII = m.NRSERII AND p.ACH = '1'
WHERE m.REFNO = @refno AND m.ILOSC < 0 AND m.ACH IN ('0','1')
AND (p.STATUS NOT IN (3,4)
OR (p.STATUS IN (1,2) AND p.TERMIN_DOZORU < CAST(GETDATE() AS date)));
Liczba partii według statusu w magazynie:
SELECT STATUS, COUNT(*) AS partie
FROM x_cel_partia
WHERE ACH = '1' AND MAGAZYN = @magazyn
GROUP BY STATUS ORDER BY STATUS;
Partie po terminie dozoru, które nie mają zwolnienia:
SELECT NRSERII, STATUS, TERMIN_DOZORU, POWOD_BLOKADY
FROM x_cel_partia
WHERE ACH = '1' AND MAGAZYN = @magazyn AND STATUS IN (1,2,5)
AND TERMIN_DOZORU < CAST(GETDATE() AS date)
ORDER BY TERMIN_DOZORU;
Pierwsze zapytanie odtwarza warunek odmowy dla dokumentu i wskazuje, która partia zatrzymała zatwierdzenie. Trzecie może korzystać z indeksu filtrowanego terminów, założonego na statusach 1, 2 i 5. Wydania z partii celnych poza dokumentem WZC pokaże ta sama konstrukcja złączenia, jeśli zamiast filtra po REFNO dasz warunek TYPDOK różny od WZC przy ILOSC mniejszej od zera i wyłączysz przesunięcia (PRX równe ZL i MX).
Pułapki z testów
- ROLLBACK w CATCH - wolno wykonać tylko dla własnej transakcji, czyli po sprawdzeniu zmiennej @tc ustawionej z @@TRANCOUNT. Cofanie transakcji otwartej przez serwer owijający zapis powoduje błąd.
- INSERT...EXEC - ROLLBACK w procedurze wołanej w takim poleceniu jest niedozwolony. Dotyczy to także odczytów, które zwracają zbiór wierszy.
- Zmienne i wielkość liter - baza nie rozróżnia wielkości liter w nazwach, więc parametr @ID i zmienna @id to ta sama nazwa. Nie deklaruj obu.
- Weryfikacja - wykonawcza kontrola odbyła się na kopii SS_demo. Na żywym demo ST26 jej nie sprawdzano, więc po wgraniu wykonaj testy z strony o wdrożeniu i testach.
Dla wdrożeniowca ważna jest ostatnia pozycja: poprawne wykonanie skryptu dbup nie dowodzi działania kontroli. Dowodem jest odmowa kodem 50210 na dokumencie WZC z partią bez zwolnienia, wykonana w bazie demonstracyjnej na dokumencie roboczym, który po teście usuwa się z bufora.
Najczęstsze pytania
Gdzie leży kontrola wydania WZC w bazie?
W forku CE43: procedura sp_cel_sprawdz_wydanie jest wykonywana przed zapytaniem 696AA17C zatwierdzenia WZ, w tej samej transakcji. Odmowa to THROW 50210.
Które pozycje WZC sprawdza kontrola?
Tylko pozycje rozchodowe, czyli z ilością mniejszą od zera i ACH równym 0 albo 1. Zapis do bufora statusów nie sprawdza.
Dlaczego WZB i RW nie są blokowane?
Kontrola siedzi w forku zatwierdzenia WZ, nie w tabeli ruchów. Trigger na tabeli ruchów odrzucono jako zbyt inwazyjny, więc ochrona dotyczy wyłącznie dokumentu WZC.
Co się stanie, gdy na bazie nie ma zapytania źródłowego?
Skrypt pomija fork i wypisuje komunikat PRINT. Zatwierdzenie działa wtedy jak zwykłe PZB lub WZ, bez kontroli celnej, dlatego po wgraniu sprawdź oba forki.
Jak długo zatwierdzenie czeka na import zwolnienia tej samej partii?
Do 5000 milisekund (SET LOCK_TIMEOUT 5000). Po przekroczeniu serwer zwraca błąd 1222, a użytkownik dostaje komunikat o trwającym przetwarzaniu komunikatu agencji.
Słownik pojęć
- Fork zapytania
- Zapytanie zapisu zbudowane z bieżącej treści zapytania źródłowego, rozszerzone o dodatkowe polecenie modułu dozoru. W module są dwa: CE38 i CE43.
- CE38
- Fork zatwierdzenia PZC: treść zapytania 0E430063 (PZB i PW) plus EXEC sp_cel_pzc_zapisz.
- CE43
- Fork zatwierdzenia WZC: EXEC sp_cel_sprawdz_wydanie plus treść zapytania 696AA17C (WZ).
- THROW 50210
- Błąd aplikacyjny odmowy wydania, rzucany przed aktualizacją ruchów w dpmag. Cofa transakcję zatwierdzenia.
- UPDLOCK, HOLDLOCK
- Podpowiedzi blokad wiersza partii, trzymanych do końca transakcji. Dzięki nim import zwolnienia i zatwierdzenie WZC tej samej partii czekają na siebie.
- LOCK_TIMEOUT 5000
- Limit oczekiwania na blokadę w milisekundach. Po jego przekroczeniu serwer zwraca błąd 1222.
- ssExSQL i ssDataSQL
- Sterowniki zapytań: ssExSQL zapisuje i owija zapytanie w transakcję serwera, ssDataSQL czyta, a jego procedury mają własną transakcję.