· 6 years ago · Oct 26, 2019, 04:20 PM
1--Funcoes de apoio
2CREATE OR REPLACE FUNCTION is_cadivend_saida(rede INTEGER, filial INTEGER, nota INTEGER) RETURNS boolean AS $$
3SELECT tip_venda IN ('V', 'O') AND flg_sitcaixa IS NOT NULL FROM cadcvend cv WHERE (cv.cod_rede, cv.cod_filial, cv.num_nota) = (rede, filial, nota)
4$$ LANGUAGE SQL IMMUTABLE;
5
6CREATE OR REPLACE FUNCTION is_lote_saida(rede INTEGER, filial INTEGER, nota INTEGER, sequencial_item INTEGER) RETURNS boolean AS $$
7SELECT tip_venda IN ('V', 'O') AND cv.flg_sitcaixa IS NOT NULL AND iv.flg_estoque = 'S' AND COALESCE(cv.flg_excluido, 'N') = 'N' AND COALESCE(iv.flg_excluido, 'N') = 'N' FROM cadcvend cv
8 JOIN cadivend iv USING (cod_rede, cod_filial, num_nota) WHERE (iv.cod_rede, iv.cod_filial, iv.num_nota, iv.num_sequencial) = (rede, filial, nota, sequencial_item)
9$$ LANGUAGE SQL IMMUTABLE;
10
11CREATE OR REPLACE FUNCTION is_cadivend_devolucao(rede INTEGER, filial INTEGER, nota INTEGER) RETURNS boolean AS $$
12SELECT tip_venda = 'D' FROM cadcvend cv WHERE (cv.cod_rede, cv.cod_filial, cv.num_nota) = (rede, filial, nota)
13$$ LANGUAGE SQL IMMUTABLE;
14
15CREATE OR REPLACE FUNCTION is_cadccomp_conferido(rede INTEGER, filial INTEGER, fornecedor INTEGER, nota INTEGER, sequencial_nota INTEGER) RETURNS boolean AS $$
16SELECT COALESCE(flg_estoque, 'S') = 'S' FROM cadccomp cc WHERE (cc.cod_rede, cc.cod_filial, cc.cod_fornec, cc.num_nota, cc.num_seqnota) = (rede, filial, fornecedor, nota, sequencial_nota)
17$$ LANGUAGE SQL IMMUTABLE;
18
19CREATE OR REPLACE FUNCTION estornar_operacao_saida(op_saida operacao_saida) RETURNS VOID AS $$
20INSERT INTO public.operacao_saida(
21 cod_operacao, qtd_operacao, cod_rede, cod_filial, cod_reduzido, num_nota, num_sequencial, num_lote, cod_local_armazenagem, flg_estorno)
22VALUES (op_saida.cod_operacao_estorno, op_saida.qtd_operacao * (-1), op_saida.cod_rede, op_saida.cod_filial, op_saida.cod_reduzido,
23 op_saida.num_nota, op_saida.num_sequencial, op_saida.num_lote, op_saida.cod_local_armazenagem, TRUE);
24$$ LANGUAGE SQL;
25
26CREATE OR REPLACE FUNCTION estornar_operacao_entrada(op_entrada operacao_entrada) RETURNS VOID AS $$
27INSERT INTO public.operacao_entrada(
28 cod_operacao, qtd_operacao, cod_rede, cod_filial, cod_reduzido,
29 num_nota_ivend, num_sequencial_ivend, cod_fornec_icomp, num_nota_icomp,
30 num_seqnota_icomp, num_sequencial_icomp, qtd_fator, num_lote, cod_local_armazenagem, flg_estorno)
31VALUES (op_entrada.cod_operacao_estorno, op_entrada.qtd_operacao * (-1), op_entrada.cod_rede, op_entrada.cod_filial,
32 op_entrada.cod_reduzido, op_entrada.num_nota_ivend, op_entrada.num_sequencial_ivend, op_entrada.cod_fornec_icomp, op_entrada.num_nota_icomp,
33 op_entrada.num_seqnota_icomp, op_entrada.num_sequencial_icomp, op_entrada.qtd_fator, op_entrada.num_lote, op_entrada.cod_local_armazenagem, TRUE);
34$$ LANGUAGE SQL;
35
36CREATE OR REPLACE FUNCTION public.compensar_item_devolucao(item cadivend) RETURNS VOID AS
37$BODY$
38DECLARE
39 total_operacoes NUMERIC;
40BEGIN
41
42 SELECT SUM(abs(qtd_operacao)) INTO total_operacoes FROM operacao_entrada
43 WHERE (cod_rede, cod_filial, num_nota_ivend, num_sequencial_ivend) = (item.cod_rede, item.cod_filial, item.num_nota, item.num_sequencial)
44 AND cod_operacao_estorno IS NULL
45 AND flg_estorno IS FALSE;
46
47 IF item.qtd_produto > coalesce(total_operacoes, 0) THEN
48 PERFORM efetivar_devolucao_estoque(item.cod_rede, item.cod_filial, item.num_nota, item.num_sequencial, item.cod_reduzido, '[SEM_LOTE]', 1, item.qtd_produto-coalesce(total_operacoes, 0));
49 END IF;
50
51END
52$BODY$ LANGUAGE plpgsql;
53
54CREATE OR REPLACE FUNCTION public.compensar_item_saida(item cadivend) RETURNS VOID AS
55$BODY$
56DECLARE
57 total_operacoes NUMERIC;
58BEGIN
59
60 SELECT SUM(abs(qtd_operacao)) INTO total_operacoes FROM operacao_saida
61 WHERE (cod_rede, cod_filial, num_nota, num_sequencial) = (item.cod_rede, item.cod_filial, item.num_nota, item.num_sequencial)
62 AND cod_operacao_estorno IS NULL
63 AND flg_estorno IS FALSE;
64
65 IF item.qtd_produto > coalesce(total_operacoes, 0) THEN
66 PERFORM efetivar_saida_estoque(item.cod_rede, item.cod_filial, item.num_nota, item.num_sequencial, item.cod_reduzido, '[SEM_LOTE]', 1, (item.qtd_produto-coalesce(total_operacoes, 0)) * -1);
67 END IF;
68
69END
70$BODY$ LANGUAGE plpgsql;
71
72CREATE OR REPLACE FUNCTION public.compensar_item_entrada(item cadicomp) RETURNS VOID AS
73$BODY$
74DECLARE
75 total_item NUMERIC := item.qtd_produto * COALESCE(item.qtd_fator, 1);
76 total_operacoes NUMERIC;
77BEGIN
78
79 SELECT SUM(qtd_operacao) INTO total_operacoes FROM operacao_entrada
80 WHERE (cod_rede, cod_filial, cod_fornec_icomp, num_nota_icomp, num_seqnota_icomp, num_sequencial_icomp) = (item.cod_rede, item.cod_filial, item.cod_fornec, item.num_nota, item.num_seqnota, item.num_sequencial)
81 AND cod_operacao_estorno IS NULL
82 AND flg_estorno IS FALSE;
83
84 IF total_item > COALESCE(total_operacoes, 0) THEN
85 PERFORM efetivar_entrada_estoque(item.cod_rede, item.cod_filial, item.cod_fornec, item.num_nota, item.num_seqnota, item.num_sequencial, item.cod_reduzido, '[SEM_LOTE]', 1, total_item - COALESCE(total_operacoes, 0), 1);
86 END IF;
87
88END
89$BODY$ LANGUAGE plpgsql;
90
91CREATE OR REPLACE FUNCTION public.compensar_lote_devolucao(lote cadlvend) RETURNS VOID AS
92$BODY$
93DECLARE
94 total_item NUMERIC;
95 total_operacoes NUMERIC;
96BEGIN
97
98 SELECT qtd_produto INTO total_item FROM cadivend iv WHERE (cod_rede, cod_filial, num_nota, num_sequencial) = (lote.cod_rede, lote.cod_filial, lote.num_nota, lote.num_seqcadivend);
99 SELECT SUM(abs(qtd_operacao)) INTO total_operacoes FROM operacao_entrada
100 WHERE (cod_rede, cod_filial, num_nota_ivend, num_sequencial_ivend) = (lote.cod_rede, lote.cod_filial, lote.num_nota, lote.num_seqcadivend)
101 AND cod_operacao_estorno IS NULL
102 AND flg_estorno IS FALSE;
103
104 IF total_item > coalesce(total_operacoes, 0) THEN
105 PERFORM efetivar_devolucao_estoque(lote.cod_rede, lote.cod_filial, lote.num_nota, lote.num_seqcadivend, lote.cod_reduzido, '[SEM_LOTE]', 1, total_item-coalesce(total_operacoes, 0));
106 END IF;
107
108END
109$BODY$ LANGUAGE plpgsql;
110
111CREATE OR REPLACE FUNCTION public.compensar_lote_saida(lote cadlvend) RETURNS VOID AS
112$BODY$
113DECLARE
114 total_item NUMERIC;
115 total_operacoes NUMERIC;
116BEGIN
117
118 SELECT qtd_produto INTO total_item FROM cadivend iv WHERE (cod_rede, cod_filial, num_nota, num_sequencial) = (lote.cod_rede, lote.cod_filial, lote.num_nota, lote.num_seqcadivend);
119 SELECT SUM(abs(qtd_operacao)) INTO total_operacoes FROM operacao_saida
120 WHERE (cod_rede, cod_filial, num_nota, num_sequencial) = (lote.cod_rede, lote.cod_filial, lote.num_nota, lote.num_seqcadivend)
121 AND cod_operacao_estorno IS NULL
122 AND flg_estorno IS FALSE;
123
124 IF total_item > coalesce(total_operacoes, 0) THEN
125 PERFORM efetivar_saida_estoque(lote.cod_rede, lote.cod_filial, lote.num_nota, lote.num_seqcadivend, lote.cod_reduzido, '[SEM_LOTE]', 1, (total_item-coalesce(total_operacoes, 0)) * -1);
126 END IF;
127
128END
129$BODY$ LANGUAGE plpgsql;
130
131CREATE OR REPLACE FUNCTION public.compensar_lote_entrada(lote cadlentd) RETURNS VOID AS
132$BODY$
133DECLARE
134 total_item NUMERIC;
135 total_operacoes NUMERIC;
136BEGIN
137
138 SELECT qtd_produto * COALESCE(qtd_fator, 1) INTO total_item FROM cadicomp ic
139 WHERE (ic.cod_rede, ic.cod_filial, ic.cod_fornec, ic.num_nota, ic.num_seqnota, ic.num_sequencial) = (lote.cod_rede, lote.cod_filial, lote.cod_fornec, lote.num_nota, lote.num_seqnota, lote.num_seqcadicomp);
140 SELECT SUM(qtd_operacao) INTO total_operacoes FROM operacao_entrada
141 WHERE (cod_rede, cod_filial, cod_fornec_icomp, num_nota_icomp, num_seqnota_icomp, num_sequencial_icomp) = (lote.cod_rede, lote.cod_filial, lote.cod_fornec, lote.num_nota, lote.num_seqnota, lote.num_seqcadicomp)
142 AND cod_operacao_estorno IS NULL
143 AND flg_estorno IS FALSE;
144
145 IF total_item > COALESCE(total_operacoes, 0) THEN
146 PERFORM efetivar_entrada_estoque(lote.cod_rede, lote.cod_filial, lote.cod_fornec, lote.num_nota, lote.num_seqnota, lote.num_seqcadicomp, lote.cod_reduzido, '[SEM_LOTE]', 1, total_item - COALESCE(total_operacoes, 0), 1);
147 END IF;
148
149END
150$BODY$ LANGUAGE plpgsql;
151
152--Controle de devolucoes
153CREATE OR REPLACE FUNCTION public.efetivar_devolucao_estoque(rede INTEGER, filial INTEGER, nota INTEGER, sequencial INTEGER, produto INTEGER, lote varchar, local_armazenagem INTEGER, quantidade NUMERIC(16,4))
154 RETURNS void AS
155$BODY$
156DECLARE
157 error_detail TEXT;
158BEGIN
159
160 IF quantidade < 0 THEN
161 RAISE invalid_parameter_value USING MESSAGE = format('Operacao de devolucao nao pode registrar uma quantidade menor que zero: %s', quantidade);
162 END IF;
163
164 INSERT INTO public.operacao_entrada(qtd_operacao, cod_rede, cod_filial, cod_reduzido, num_nota_ivend, num_sequencial_ivend, num_lote, cod_local_armazenagem)
165 VALUES (quantidade, rede, filial, produto, nota, sequencial, lote, local_armazenagem);
166
167 RAISE DEBUG 'Efetivando devolucao. Op: %; Prod.: %; Filial: %-%; Qtde.: %',
168 CURRVAL('operacao_entrada_seq'), produto, rede, filial, quantidade;
169
170EXCEPTION
171 WHEN unique_violation THEN
172 GET STACKED DIAGNOSTICS error_detail = PG_EXCEPTION_DETAIL;
173 RAISE unique_violation USING MESSAGE = 'Operacao de devolucao ja efetivada anteriormente',
174 DETAIL = error_detail,
175 HINT = 'Considere estornar o movimento';
176END;
177$BODY$
178 LANGUAGE plpgsql VOLATILE;
179
180CREATE OR REPLACE FUNCTION public.efetivar_movimento_devolucao(item cadivend)
181 RETURNS VOID AS
182$BODY$
183DECLARE
184 lote cadlvend%rowtype;
185BEGIN
186 --Realiza a movimentacao via lotes
187 FOR lote IN
188 SELECT * FROM cadlvend lv where
189 (lv.cod_rede, lv.cod_filial, lv.num_nota, lv.num_seqcadivend, lv.cod_reduzido) = (item.cod_rede, item.cod_filial, item.num_nota, item.num_sequencial, item.cod_reduzido) LOOP
190 if EXISTS(
191 SELECT
192 op.*
193 FROM
194 operacao_entrada op
195 WHERE
196 (op.cod_rede, op.cod_filial, op.num_nota_ivend, op.num_sequencial_ivend, op.cod_reduzido, op.num_lote)
197 = (lote.cod_rede, lote.cod_filial, lote.num_nota, lote.num_seqcadivend, lote.cod_reduzido, lote.num_lote)
198 AND op.cod_operacao_estorno IS NULL
199 AND op.flg_estorno IS FALSE
200 ) THEN
201 RAISE DEBUG 'Operacao encontrada para o Prod.: % Lote: %. Ignorando...', lote.cod_reduzido, lote.num_lote;
202 CONTINUE;
203 END IF;
204
205 RAISE DEBUG 'Aplicando alteracao de estoque para o Prod.: % Lote: % Qtde: %', lote.cod_reduzido, lote.num_lote, lote.qtd_lote;
206 PERFORM efetivar_devolucao_estoque(lote.cod_rede, lote.cod_filial, lote.num_nota, lote.num_seqcadivend, lote.cod_reduzido, lote.num_lote, 1, lote.qtd_lote);
207 END LOOP;
208
209 --Realiza a movimentacao atraves do proprio item se nao houverem lotes
210 IF NOT FOUND THEN
211
212 RAISE DEBUG 'Lotes não encontrados, aplicando movimentacao por item';
213
214 if EXISTS(
215 SELECT
216 op.*
217 FROM
218 operacao_entrada op
219 WHERE
220 (op.cod_rede, op.cod_filial, op.num_nota_ivend, op.num_sequencial_ivend, op.cod_reduzido)
221 = (item.cod_rede, item.cod_filial, item.num_nota, item.num_sequencial, item.cod_reduzido)
222 AND op.cod_operacao_estorno IS NULL
223 AND op.flg_estorno IS FALSE
224 AND op.num_lote = '[SEM_LOTE]'
225 ) THEN
226 RAISE DEBUG 'Operacao encontrada para o Prod.: % Lote: ''[SEM_LOTE]''. Ignorando...', item.cod_reduzido;
227 RETURN;
228 END IF;
229
230 RAISE DEBUG 'Aplicando alteracao de estoque para o Prod.: % Lote: ''[SEM_LOTE]'' Qtde: %', item.cod_reduzido, item.qtd_produto;
231 PERFORM efetivar_devolucao_estoque(item.cod_rede, item.cod_filial, item.num_nota, item.num_sequencial, item.cod_reduzido, '[SEM_LOTE]', 1, item.qtd_produto);
232 END IF;
233
234 --Aplica a diferenca que sobrou entre o(s) lote(s) e item para assegurar que estao com a quantidade igual
235 PERFORM compensar_item_devolucao(item);
236
237END;
238$BODY$
239 LANGUAGE plpgsql VOLATILE;
240
241CREATE OR REPLACE FUNCTION public.efetivar_movimento_devolucao_item()
242 RETURNS trigger AS
243$BODY$
244BEGIN
245
246 PERFORM efetivar_movimento_devolucao(NEW);
247 RETURN NULL;
248
249END;
250$BODY$
251 LANGUAGE plpgsql VOLATILE;
252
253CREATE OR REPLACE FUNCTION public.efetivar_estorno_devolucao_estoque_item()
254 RETURNS trigger AS
255$BODY$
256DECLARE
257 movimento cadivend;
258 operacao operacao_entrada;
259BEGIN
260
261 IF TG_OP = 'DELETE' THEN
262 movimento := OLD;
263 ELSE
264 movimento := NEW;
265 END IF;
266
267 FOR operacao IN
268 UPDATE operacao_entrada SET cod_operacao_estorno = NEXTVAL('operacao_entrada_seq') WHERE
269 cod_rede = movimento.cod_rede AND
270 cod_filial = movimento.cod_filial AND
271 cod_reduzido = movimento.cod_reduzido AND
272 num_nota_ivend = movimento.num_nota AND
273 num_sequencial_ivend = movimento.num_sequencial AND
274 cod_operacao_estorno IS NULL AND
275 flg_estorno IS FALSE RETURNING *
276 LOOP
277
278 PERFORM estornar_operacao_entrada(operacao);
279
280 RAISE DEBUG 'Efetivando estorno de devolucao. Op: %; Prod.: %; Filial: %-%; Qtde.: %; Estorno Gerado: %',
281 operacao.cod_operacao, operacao.cod_reduzido, operacao.cod_rede, operacao.cod_filial, operacao.qtd_operacao, CURRVAL('operacao_entrada_seq');
282
283 END LOOP;
284
285 RETURN NULL;
286END;
287$BODY$
288 LANGUAGE plpgsql VOLATILE;
289
290DROP TRIGGER IF EXISTS efetivar_movimento_devolucao_update_tg ON cadivend;
291
292CREATE CONSTRAINT TRIGGER efetivar_movimento_devolucao_update_tg
293 AFTER UPDATE ON public.cadivend INITIALLY DEFERRED FOR EACH ROW
294 WHEN
295 (((NEW.flg_estoque = 'S' AND NEW.flg_estoque IS DISTINCT FROM OLD.flg_estoque AND COALESCE(NEW.flg_excluido, 'N') = 'N')
296 OR (COALESCE(NEW.flg_excluido, 'N') = 'N' AND OLD.flg_excluido = 'S')
297 OR (NEW.flg_estoque = 'S' AND NEW.qtd_produto IS DISTINCT FROM OLD.qtd_produto AND COALESCE(NEW.flg_excluido, 'N') = 'N'))
298 AND is_cadivend_devolucao(NEW.cod_rede, NEW.cod_filial, NEW.num_nota))
299EXECUTE PROCEDURE public.efetivar_movimento_devolucao_item();
300
301DROP TRIGGER IF EXISTS efetivar_movimento_devolucao_insert_tg ON cadivend;
302
303CREATE CONSTRAINT TRIGGER efetivar_movimento_devolucao_insert_tg
304 AFTER INSERT ON public.cadivend INITIALLY DEFERRED FOR EACH ROW
305 WHEN
306 (NEW.flg_estoque = 'S' AND COALESCE(NEW.flg_excluido, 'N') = 'N' AND is_cadivend_devolucao(NEW.cod_rede, NEW.cod_filial, NEW.num_nota))
307EXECUTE PROCEDURE public.efetivar_movimento_devolucao_item();
308
309DROP TRIGGER IF EXISTS efetivar_estorno_devolucao_estoque_update_tg ON cadivend;
310
311CREATE TRIGGER efetivar_estorno_devolucao_estoque_update_tg
312 AFTER UPDATE ON public.cadivend FOR EACH ROW
313 WHEN (
314 ((NEW.flg_estoque IS DISTINCT FROM OLD.flg_estoque AND OLD.flg_estoque = 'S')
315 OR (NEW.qtd_produto IS DISTINCT FROM OLD.qtd_produto AND OLD.flg_estoque = 'S')
316 OR (NEW.flg_excluido IS DISTINCT FROM OLD.flg_excluido AND NEW.flg_excluido = 'S')) AND is_cadivend_devolucao(NEW.cod_rede, NEW.cod_filial, NEW.num_nota))
317EXECUTE PROCEDURE public.efetivar_estorno_devolucao_estoque_item();
318
319DROP TRIGGER IF EXISTS efetivar_estorno_devolucao_estoque_delete_tg ON cadivend;
320
321CREATE TRIGGER efetivar_estorno_devolucao_estoque_delete_tg
322 AFTER DELETE ON public.cadivend FOR EACH ROW
323 WHEN (is_cadivend_devolucao(OLD.cod_rede, OLD.cod_filial, OLD.num_nota))
324EXECUTE PROCEDURE public.efetivar_estorno_devolucao_estoque_item();
325
326---------------------- cadcvend --------------------------
327CREATE OR REPLACE FUNCTION public.efetivar_movimento_devolucao_cabecalho()
328 RETURNS trigger AS
329$BODY$
330DECLARE
331 item cadivend%rowtype;
332BEGIN
333
334 FOR item IN
335 SELECT * FROM cadivend iv WHERE
336 (iv.cod_rede, iv.cod_filial, iv.num_nota) = (NEW.cod_rede, NEW.cod_filial, NEW.num_nota)
337 AND iv.flg_estoque = 'S' AND COALESCE(iv.flg_excluido, 'N') = 'N' LOOP
338 PERFORM efetivar_movimento_devolucao(item);
339 END LOOP;
340 RETURN NULL;
341
342END;
343$BODY$
344 LANGUAGE plpgsql VOLATILE;
345
346DROP TRIGGER IF EXISTS efetivar_devolucao_estoque_update_tg ON cadcvend;
347
348CREATE CONSTRAINT TRIGGER efetivar_devolucao_estoque_update_tg
349 AFTER UPDATE ON public.cadcvend INITIALLY DEFERRED FOR EACH ROW
350 WHEN (
351 ((COALESCE(NEW.flg_excluido, 'N') = 'N' AND OLD.flg_excluido = 'S')
352 OR NEW.flg_sitcaixa = '2' AND NEW.flg_sitcaixa IS DISTINCT FROM OLD.flg_sitcaixa)
353 AND NEW.tip_venda = 'D')
354EXECUTE PROCEDURE public.efetivar_movimento_devolucao_cabecalho();
355
356---------ESTORNO CABECALHO
357CREATE OR REPLACE FUNCTION public.efetivar_estorno_devolucao_estoque_cabecalho()
358 RETURNS trigger AS
359$BODY$
360DECLARE
361 movimento cadcvend;
362 operacao operacao_entrada;
363BEGIN
364
365 IF TG_OP = 'DELETE' THEN
366 movimento := OLD;
367 ELSE
368 movimento := NEW;
369 END IF;
370
371 FOR operacao IN
372 UPDATE operacao_entrada SET cod_operacao_estorno = NEXTVAL('operacao_entrada_seq') WHERE
373 cod_rede = movimento.cod_rede AND
374 cod_filial = movimento.cod_filial AND
375 num_nota_ivend = movimento.num_nota AND
376 cod_operacao_estorno IS NULL AND
377 flg_estorno IS FALSE RETURNING *
378 LOOP
379
380 PERFORM estornar_operacao_entrada(operacao);
381
382 RAISE DEBUG 'Efetivando estorno de devolucao. Op: %; Prod.: %; Filial: %-%; Qtde.: %; Estorno Gerado: %',
383 operacao.cod_operacao, operacao.cod_reduzido, operacao.cod_rede, operacao.cod_filial, operacao.qtd_operacao, CURRVAL('operacao_entrada_seq');
384
385 END LOOP;
386
387 RETURN NEW;
388END;
389$BODY$
390 LANGUAGE plpgsql VOLATILE;
391
392DROP TRIGGER IF EXISTS efetivar_estorno_devolucao_estoque_update_tg ON cadcvend;
393
394CREATE TRIGGER efetivar_estorno_devolucao_estoque_update_tg
395 AFTER UPDATE ON public.cadcvend FOR EACH ROW
396 WHEN (NEW.flg_excluido = 'S' AND NEW.flg_excluido IS DISTINCT FROM OLD.flg_excluido AND NEW.tip_venda = 'D')
397EXECUTE PROCEDURE public.efetivar_estorno_devolucao_estoque_cabecalho();
398
399DROP TRIGGER IF EXISTS efetivar_estorno_devolucao_estoque_delete_tg ON cadcvend;
400
401CREATE TRIGGER efetivar_estorno_devolucao_estoque_delete_tg
402 AFTER DELETE ON public.cadcvend FOR EACH ROW
403 WHEN (OLD.tip_venda = 'D')
404EXECUTE PROCEDURE public.efetivar_estorno_devolucao_estoque_cabecalho();
405
406---------------------- cadlvend --------------------------
407CREATE OR REPLACE FUNCTION public.efetivar_movimento_devolucao_item_lote()
408 RETURNS trigger AS
409$BODY$
410DECLARE
411 operacao operacao_entrada;
412BEGIN
413
414 --Se a operacao for de insercao e existir lotes do tipo [SEM_LOTE] entao o sistema deve estornar todas as movimentacoes para que o usuario informe os lotes corretos
415 IF (TG_OP = 'INSERT') THEN
416 FOR operacao IN
417 UPDATE operacao_entrada SET cod_operacao_estorno = NEXTVAL('operacao_entrada_seq') WHERE
418 cod_rede = NEW.cod_rede AND
419 cod_filial = NEW.cod_filial AND
420 num_nota_ivend = NEW.num_nota AND
421 num_lote = '[SEM_LOTE]' AND
422 cod_operacao_estorno IS NULL AND
423 flg_estorno IS FALSE RETURNING *
424 LOOP
425
426 PERFORM estornar_operacao_entrada(operacao);
427
428 RAISE DEBUG 'Efetivando estorno de devolucao. Op: %; Prod.: %; Filial: %-%; Qtde.: %; Estorno Gerado: %',
429 operacao.cod_operacao, operacao.cod_reduzido, operacao.cod_rede, operacao.cod_filial, operacao.qtd_operacao, CURRVAL('operacao_entrada_seq');
430
431 END LOOP;
432 END IF;
433
434 --Efetiva o lote atual
435 PERFORM efetivar_devolucao_estoque(it.cod_rede, it.cod_filial, it.num_nota, it.num_seqcadivend, it.cod_reduzido, it.num_lote, it.cod_local_armazenagem, it.qtd_lote) FROM
436 (SELECT
437 NEW.cod_rede, NEW.cod_filial, NEW.num_nota, NEW.num_seqcadivend, NEW.cod_reduzido, NEW.num_lote, 1 AS cod_local_armazenagem, NEW.qtd_lote
438
439 EXCEPT
440
441 SELECT
442 cod_rede, cod_filial, num_nota_ivend, num_sequencial_ivend, cod_reduzido, num_lote, cod_local_armazenagem, qtd_operacao
443 FROM
444 operacao_entrada
445 WHERE
446 (cod_rede, cod_filial, num_nota_ivend, num_sequencial_ivend) = (NEW.cod_rede, NEW.cod_filial, NEW.num_nota, NEW.num_seqcadivend)
447 AND cod_operacao_estorno IS NULL
448 AND flg_estorno IS FALSE
449 ORDER BY num_seqcadivend) AS it;
450
451 --Aplica a diferenca que sobrou entre o(s) lote(s) e item para assegurar que estao com a quantidade igual
452 PERFORM compensar_lote_devolucao(NEW);
453
454 RETURN NULL;
455
456END;
457$BODY$
458 LANGUAGE plpgsql VOLATILE;
459
460CREATE OR REPLACE FUNCTION public.efetivar_estorno_devolucao_estoque_item_lote()
461 RETURNS trigger AS
462$BODY$
463DECLARE
464 lote cadlvend;
465 operacao operacao_entrada;
466BEGIN
467
468 IF TG_OP = 'DELETE' THEN
469 lote := OLD;
470 ELSE
471 lote := NEW;
472 END IF;
473
474 FOR operacao IN
475 UPDATE operacao_entrada SET cod_operacao_estorno = NEXTVAL('operacao_entrada_seq') WHERE
476 cod_rede = lote.cod_rede AND
477 cod_filial = lote.cod_filial AND
478 cod_reduzido = lote.cod_reduzido AND
479 num_nota_ivend = lote.num_nota AND
480 num_sequencial_ivend = lote.num_seqcadivend AND
481 (num_lote = lote.num_lote OR num_lote = '[SEM_LOTE]') AND
482 cod_operacao_estorno IS NULL AND
483 flg_estorno IS FALSE RETURNING *
484 LOOP
485
486 PERFORM estornar_operacao_entrada(operacao);
487
488 RAISE DEBUG 'Efetivando estorno de devolucao. Op: %; Prod.: %; Filial: %-%; Qtde.: %; Estorno Gerado: %',
489 operacao.cod_operacao, operacao.cod_reduzido, operacao.cod_rede, operacao.cod_filial, operacao.qtd_operacao, CURRVAL('operacao_entrada_seq');
490
491 END LOOP;
492
493 IF TG_OP = 'DELETE' THEN
494 PERFORM compensar_lote_devolucao(lote);
495 END IF;
496
497 RETURN NULL;
498END;
499$BODY$ LANGUAGE plpgsql;
500
501DROP TRIGGER IF EXISTS efetivar_movimento_devolucao_update_item_lote_tg ON cadlvend;
502
503CREATE CONSTRAINT TRIGGER efetivar_movimento_devolucao_update_item_lote_tg
504 AFTER UPDATE ON public.cadlvend INITIALLY DEFERRED FOR EACH ROW
505 WHEN (NEW.qtd_lote IS DISTINCT FROM OLD.qtd_lote AND is_cadivend_devolucao(NEW.cod_rede, NEW.cod_filial, NEW.num_nota))
506EXECUTE PROCEDURE public.efetivar_movimento_devolucao_item_lote();
507
508DROP TRIGGER IF EXISTS efetivar_movimento_devolucao_insert_item_lote_tg ON cadlvend;
509
510CREATE CONSTRAINT TRIGGER efetivar_movimento_devolucao_insert_item_lote_tg
511 AFTER INSERT ON public.cadlvend INITIALLY DEFERRED FOR EACH ROW
512 WHEN (is_cadivend_devolucao(NEW.cod_rede, NEW.cod_filial, NEW.num_nota))
513EXECUTE PROCEDURE public.efetivar_movimento_devolucao_item_lote();
514
515DROP TRIGGER IF EXISTS efetivar_estorno_devolucao_update_item_lote_tg ON cadlvend;
516
517CREATE TRIGGER efetivar_estorno_devolucao_update_item_lote_tg
518 AFTER UPDATE ON public.cadlvend FOR EACH ROW
519 WHEN (NEW.qtd_lote IS DISTINCT FROM OLD.qtd_lote AND is_cadivend_devolucao(NEW.cod_rede, NEW.cod_filial, NEW.num_nota))
520EXECUTE PROCEDURE public.efetivar_estorno_devolucao_estoque_item_lote();
521
522DROP TRIGGER IF EXISTS efetivar_estorno_devolucao_estoque_delete_item_lote_tg ON cadlvend;
523
524CREATE TRIGGER efetivar_estorno_devolucao_estoque_delete_item_lote_tg
525 AFTER DELETE ON public.cadlvend FOR EACH ROW
526 WHEN (is_cadivend_devolucao(OLD.cod_rede, OLD.cod_filial, OLD.num_nota))
527EXECUTE PROCEDURE public.efetivar_estorno_devolucao_estoque_item_lote();
528
529--Controle de compras
530CREATE OR REPLACE FUNCTION public.efetivar_entrada_estoque(rede INTEGER, filial INTEGER, fornecedor INTEGER, nota INTEGER, sequencial_nota INTEGER,
531 sequencial INTEGER, produto INTEGER, lote varchar, local_armazenagem INTEGER, quantidade NUMERIC(16,4), fator INTEGER)
532 RETURNS void AS
533$BODY$
534DECLARE
535 error_detail TEXT;
536BEGIN
537
538 IF quantidade < 0 THEN
539 RAISE invalid_parameter_value USING MESSAGE = format('Operacao de entrada nao pode registrar uma quantidade menor que zero: %s', quantidade);
540 END IF;
541
542 INSERT INTO public.operacao_entrada(qtd_operacao, qtd_fator, cod_rede, cod_filial, cod_reduzido, cod_fornec_icomp, num_nota_icomp,
543 num_seqnota_icomp, num_sequencial_icomp, num_lote, cod_local_armazenagem)
544 VALUES (quantidade * fator, fator, rede, filial, produto, fornecedor, nota, sequencial_nota, sequencial, lote, local_armazenagem);
545
546 RAISE DEBUG 'Efetivando entrada. Op: %; Prod.: %; Filial: %-%; Qtde.: %',
547 CURRVAL('operacao_entrada_seq'), produto, rede, filial, quantidade;
548
549EXCEPTION
550 WHEN unique_violation THEN
551 GET STACKED DIAGNOSTICS error_detail = PG_EXCEPTION_DETAIL;
552 RAISE unique_violation USING MESSAGE = 'Operacao de entrada ja efetivada anteriormente',
553 DETAIL = error_detail,
554 HINT = 'Considere estornar o movimento';
555END;
556$BODY$
557 LANGUAGE plpgsql VOLATILE;
558
559CREATE OR REPLACE FUNCTION public.efetivar_movimento_entrada(item cadicomp) RETURNS VOID AS
560$BODY$
561DECLARE
562 lote cadlentd%rowtype;
563BEGIN
564
565 --Realiza a movimentacao via lotes
566 FOR lote IN
567 SELECT ld.* FROM cadlentd ld where
568 (ld.cod_rede, ld.cod_filial, ld.cod_fornec, ld.num_nota, ld.num_seqnota, ld.num_seqcadicomp)
569 = (item.cod_rede, item.cod_filial, item.cod_fornec, item.num_nota, item.num_seqnota, item.num_sequencial) LOOP
570
571 if EXISTS(
572 SELECT
573 op.*
574 FROM
575 operacao_entrada op
576 WHERE
577 (op.cod_rede, op.cod_filial, op.cod_fornec_icomp, op.num_nota_icomp, op.num_seqnota_icomp, op.num_sequencial_icomp, op.num_lote)
578 = (lote.cod_rede, lote.cod_filial, lote.cod_fornec, lote.num_nota, lote.num_seqnota, lote.num_seqcadicomp, lote.num_lote)
579 AND op.cod_operacao_estorno IS NULL
580 AND op.flg_estorno IS FALSE
581 ) THEN
582 RAISE DEBUG 'Operacao encontrada para o Prod.: % Lote: %. Ignorando...', lote.cod_reduzido, lote.num_lote;
583 CONTINUE;
584 END IF;
585
586 RAISE DEBUG 'Aplicando alteracao de estoque para o Prod.: % Lote: % Qtde: % Fator: %', lote.cod_reduzido, lote.num_lote, lote.qtd_entrada, lote.qtd_fator;
587 PERFORM efetivar_entrada_estoque(
588 lote.cod_rede, lote.cod_filial, lote.cod_fornec, lote.num_nota, lote.num_seqnota, lote.num_seqcadicomp, lote.cod_reduzido, lote.num_lote, 1, lote.qtd_entrada, coalesce(lote.qtd_fator, 1));
589
590 END LOOP;
591
592 --Realiza a movimentacao atraves do proprio item se nao houverem lotes
593 IF NOT FOUND THEN
594
595 RAISE DEBUG 'Lotes não encontrados, aplicando movimentacao por item';
596
597 if EXISTS(
598 SELECT
599 *
600 FROM
601 operacao_entrada op
602 WHERE
603 (op.cod_rede, op.cod_filial, op.cod_fornec_icomp, op.num_nota_icomp, op.num_seqnota_icomp, op.num_sequencial_icomp)
604 = (item.cod_rede, item.cod_filial, item.cod_fornec, item.num_nota, item.num_seqnota, item.num_sequencial)
605 AND op.cod_operacao_estorno IS NULL
606 AND op.flg_estorno IS FALSE
607 AND op.num_lote = '[SEM_LOTE]'
608 ) THEN
609 RAISE DEBUG 'Operacao encontrada para o Prod.: % Lote: ''[SEM_LOTE]''. Ignorando...', item.cod_reduzido;
610 RETURN;
611 END IF;
612
613 RAISE DEBUG 'Aplicando alteracao de estoque para o Prod.: % Lote: ''[SEM_LOTE]'' Qtde: % Fator: %', item.cod_reduzido, item.qtd_produto, coalesce(item.qtd_fator, 1);
614 PERFORM efetivar_entrada_estoque(
615 item.cod_rede, item.cod_filial, item.cod_fornec, item.num_nota, item.num_seqnota, item.num_sequencial, item.cod_reduzido, '[SEM_LOTE]', 1, item.qtd_produto, coalesce(item.qtd_fator, 1));
616
617 END IF;
618
619 --Aplica a diferenca que sobrou entre o(s) lote(s) e item para assegurar que estao com a quantidade igual
620 PERFORM compensar_item_entrada(item);
621
622END
623$BODY$ LANGUAGE plpgsql;
624
625CREATE OR REPLACE FUNCTION public.efetivar_movimento_entrada_item()
626 RETURNS trigger AS
627$BODY$
628
629BEGIN
630 PERFORM efetivar_movimento_entrada(NEW);
631 RETURN NULL;
632
633END;
634$BODY$
635 LANGUAGE plpgsql VOLATILE;
636
637CREATE OR REPLACE FUNCTION public.efetivar_estorno_entrada_estoque_item()
638 RETURNS trigger AS
639$BODY$
640DECLARE
641 movimento cadicomp;
642 operacao operacao_entrada;
643BEGIN
644
645 IF TG_OP = 'DELETE' THEN
646 movimento := OLD;
647 ELSE
648 movimento := NEW;
649 END IF;
650
651 FOR operacao IN
652 UPDATE operacao_entrada SET cod_operacao_estorno = NEXTVAL('operacao_entrada_seq') WHERE
653 cod_rede = movimento.cod_rede AND
654 cod_filial = movimento.cod_filial AND
655 cod_fornec_icomp = movimento.cod_fornec AND
656 cod_reduzido = movimento.cod_reduzido AND
657 num_nota_icomp = movimento.num_nota AND
658 num_seqnota_icomp = movimento.num_seqnota AND
659 num_sequencial_icomp = movimento.num_sequencial AND
660 cod_operacao_estorno IS NULL AND
661 flg_estorno IS FALSE RETURNING *
662 LOOP
663
664 PERFORM estornar_operacao_entrada(operacao);
665
666 RAISE DEBUG 'Efetivando estorno de entrada. Op: %; Prod.: %; Filial: %-%; Qtde.: %; Estorno Gerado: %',
667 operacao.cod_operacao, operacao.cod_reduzido, operacao.cod_rede, operacao.cod_filial, operacao.qtd_operacao, CURRVAL('operacao_entrada_seq');
668
669 END LOOP;
670
671 RETURN NULL;
672END;
673$BODY$
674 LANGUAGE plpgsql VOLATILE;
675
676DROP TRIGGER IF EXISTS efetivar_movimento_entrada_update_tg ON cadicomp;
677
678CREATE CONSTRAINT TRIGGER efetivar_movimento_entrada_update_tg
679 AFTER UPDATE ON public.cadicomp INITIALLY DEFERRED FOR EACH ROW
680 WHEN
681 (NEW.qtd_produto IS NOT NULL AND NEW.qtd_produto IS DISTINCT FROM OLD.qtd_produto AND is_cadccomp_conferido(NEW.cod_rede, NEW.cod_filial, NEW.cod_fornec, NEW.num_nota, NEW.num_seqnota))
682EXECUTE PROCEDURE public.efetivar_movimento_entrada_item();
683
684DROP TRIGGER IF EXISTS efetivar_movimento_entrada_insert_tg ON cadicomp;
685
686CREATE CONSTRAINT TRIGGER efetivar_movimento_entrada_insert_tg
687 AFTER INSERT ON public.cadicomp INITIALLY DEFERRED FOR EACH ROW
688 WHEN
689 (NEW.qtd_produto IS NOT NULL AND is_cadccomp_conferido(NEW.cod_rede, NEW.cod_filial, NEW.cod_fornec, NEW.num_nota, NEW.num_seqnota))
690EXECUTE PROCEDURE public.efetivar_movimento_entrada_item();
691
692DROP TRIGGER IF EXISTS efetivar_estorno_entrada_estoque_update_tg ON cadicomp;
693
694CREATE TRIGGER efetivar_estorno_entrada_estoque_update_tg
695 AFTER UPDATE ON public.cadicomp FOR EACH ROW
696 WHEN (NEW.qtd_produto IS DISTINCT FROM OLD.qtd_produto AND is_cadccomp_conferido(NEW.cod_rede, NEW.cod_filial, NEW.cod_fornec, NEW.num_nota, NEW.num_seqnota))
697EXECUTE PROCEDURE public.efetivar_estorno_entrada_estoque_item();
698
699DROP TRIGGER IF EXISTS efetivar_estorno_entrada_estoque_delete_tg ON cadicomp;
700
701CREATE TRIGGER efetivar_estorno_entrada_estoque_delete_tg
702 AFTER DELETE ON public.cadicomp FOR EACH ROW
703 WHEN (is_cadccomp_conferido(OLD.cod_rede, OLD.cod_filial, OLD.cod_fornec, OLD.num_nota, OLD.num_seqnota))
704EXECUTE PROCEDURE public.efetivar_estorno_entrada_estoque_item();
705
706---------------------- cadccomp --------------------------
707CREATE OR REPLACE FUNCTION public.efetivar_movimento_entrada_cabecalho()
708 RETURNS trigger AS
709$BODY$
710DECLARE
711 item cadicomp%rowtype;
712BEGIN
713
714 FOR item IN
715 SELECT * FROM cadicomp ic WHERE
716 (ic.cod_rede, ic.cod_filial, ic.cod_fornec, ic.num_nota, ic.num_seqnota) = (NEW.cod_rede, NEW.cod_filial, NEW.cod_fornec, NEW.num_nota, NEW.num_seqnota) LOOP
717 PERFORM efetivar_movimento_entrada(item);
718 END LOOP;
719
720 RETURN NULL;
721
722END;
723$BODY$
724 LANGUAGE plpgsql VOLATILE;
725
726DROP TRIGGER IF EXISTS efetivar_entrada_estoque_update_tg ON cadccomp;
727
728CREATE CONSTRAINT TRIGGER efetivar_entrada_estoque_update_tg
729 AFTER UPDATE ON public.cadccomp INITIALLY DEFERRED FOR EACH ROW
730 WHEN (COALESCE(NEW.flg_estoque, 'S') = 'S' AND NEW.flg_estoque IS DISTINCT FROM OLD.flg_estoque)
731EXECUTE PROCEDURE public.efetivar_movimento_entrada_cabecalho();
732
733---------ESTORNO CABECALHO
734CREATE OR REPLACE FUNCTION public.efetivar_estorno_entrada_estoque_cabecalho()
735 RETURNS trigger AS
736$BODY$
737DECLARE
738 movimento cadccomp;
739 operacao operacao_entrada;
740BEGIN
741
742 IF TG_OP = 'DELETE' THEN
743 movimento := OLD;
744 ELSE
745 movimento := NEW;
746 END IF;
747
748 FOR operacao IN
749 UPDATE operacao_entrada SET cod_operacao_estorno = NEXTVAL('operacao_entrada_seq') WHERE
750 cod_rede = movimento.cod_rede AND
751 cod_filial = movimento.cod_filial AND
752 cod_fornec_icomp = movimento.cod_fornec AND
753 num_nota_icomp = movimento.num_nota AND
754 num_seqnota_icomp = movimento.num_seqnota AND
755 cod_operacao_estorno IS NULL AND
756 flg_estorno IS FALSE RETURNING *
757 LOOP
758
759 PERFORM estornar_operacao_entrada(operacao);
760
761 RAISE DEBUG 'Efetivando estorno de entrada. Op: %; Prod.: %; Filial: %-%; Qtde.: %; Estorno Gerado: %',
762 operacao.cod_operacao, operacao.cod_reduzido, operacao.cod_rede, operacao.cod_filial, operacao.qtd_operacao, CURRVAL('operacao_entrada_seq');
763
764 END LOOP;
765
766 RETURN NEW;
767END;
768$BODY$
769 LANGUAGE plpgsql VOLATILE;
770
771DROP TRIGGER IF EXISTS efetivar_estorno_entrada_estoque_update_tg ON cadccomp;
772
773CREATE TRIGGER efetivar_estorno_entrada_estoque_update_tg
774 AFTER UPDATE ON public.cadccomp FOR EACH ROW
775 WHEN (NEW.flg_estoque = 'N' AND NEW.flg_estoque IS DISTINCT FROM OLD.flg_estoque)
776EXECUTE PROCEDURE public.efetivar_estorno_entrada_estoque_cabecalho();
777
778DROP TRIGGER IF EXISTS efetivar_estorno_entrada_estoque_delete_tg ON cadccomp;
779
780CREATE TRIGGER efetivar_estorno_entrada_estoque_delete_tg
781 AFTER DELETE ON public.cadccomp FOR EACH ROW
782 WHEN (COALESCE(OLD.flg_estoque, 'S') = 'S')
783EXECUTE PROCEDURE public.efetivar_estorno_entrada_estoque_cabecalho();
784
785---------------------- cadlentd --------------------------
786CREATE OR REPLACE FUNCTION public.efetivar_movimento_entrada_item_lote()
787 RETURNS trigger AS
788$BODY$
789DECLARE
790 operacao operacao_entrada;
791 total_item NUMERIC;
792 total_operacoes numeric;
793BEGIN
794
795 --Se a operacao for de insercao e existir lotes do tipo [SEM_LOTE] entao o sistema deve estornar todas as movimentacoes para que o usuario informe os lotes corretos
796 IF (TG_OP = 'INSERT') THEN
797 FOR operacao IN
798 UPDATE operacao_entrada SET cod_operacao_estorno = NEXTVAL('operacao_entrada_seq') WHERE
799 cod_rede = NEW.cod_rede AND
800 cod_filial = NEW.cod_filial AND
801 cod_reduzido = NEW.cod_reduzido AND
802 num_nota_icomp = NEW.num_nota AND
803 num_seqnota_icomp = NEW.num_seqnota AND
804 num_sequencial_icomp = NEW.num_seqcadicomp AND
805 num_lote = '[SEM_LOTE]' AND
806 cod_operacao_estorno IS NULL AND
807 flg_estorno IS FALSE RETURNING *
808 LOOP
809
810 PERFORM estornar_operacao_entrada(operacao);
811
812 RAISE DEBUG 'Efetivando estorno de entrada. Op: %; Prod.: %; Filial: %-%; Qtde.: %; Estorno Gerado: %',
813 operacao.cod_operacao, operacao.cod_reduzido, operacao.cod_rede, operacao.cod_filial, operacao.qtd_operacao, CURRVAL('operacao_entrada_seq');
814
815 END LOOP;
816 END IF;
817
818 --Efetiva o lote atual
819 PERFORM efetivar_entrada_estoque(it.cod_rede, it.cod_filial, it.cod_fornec, it.num_nota, it.num_seqnota, it.num_seqcadicomp, it.cod_reduzido, it.num_lote,
820 1, NEW.qtd_entrada, coalesce(NEW.qtd_fator, 1)) FROM
821 (
822 SELECT NEW.cod_rede, NEW.cod_filial, NEW.cod_fornec, NEW.num_nota, NEW.num_seqnota, NEW.num_seqcadicomp, NEW.cod_reduzido, NEW.num_lote
823
824 EXCEPT
825
826 SELECT
827 cod_rede, cod_filial, cod_fornec_icomp, num_nota_icomp, num_seqnota_icomp, num_sequencial_icomp, cod_reduzido, num_lote
828 FROM
829 operacao_entrada
830 WHERE
831 (cod_rede, cod_filial, cod_fornec_icomp, num_nota_icomp, num_seqnota_icomp, num_sequencial_icomp)
832 = (NEW.cod_rede, NEW.cod_filial, NEW.cod_fornec, NEW.num_nota, NEW.num_seqnota, NEW.num_seqcadicomp)
833 AND cod_operacao_estorno IS NULL
834 AND flg_estorno IS FALSE
835 ORDER BY num_seqcadicomp) AS it;
836
837 --Aplica a diferenca que sobrou entre o(s) lote(s) e item para assegurar que estao com a quantidade igual
838 PERFORM compensar_lote_entrada(NEW);
839
840 RETURN NULL;
841
842END;
843$BODY$
844 LANGUAGE plpgsql VOLATILE;
845
846CREATE OR REPLACE FUNCTION public.efetivar_estorno_entrada_estoque_item_lote()
847 RETURNS trigger AS
848$BODY$
849DECLARE
850 lote cadlentd;
851 operacao operacao_entrada;
852BEGIN
853
854 IF TG_OP = 'DELETE' THEN
855 lote := OLD;
856 ELSE
857 lote := NEW;
858 END IF;
859
860 FOR operacao IN
861 UPDATE operacao_entrada SET cod_operacao_estorno = NEXTVAL('operacao_entrada_seq') WHERE
862 cod_rede = lote.cod_rede AND
863 cod_filial = lote.cod_filial AND
864 cod_reduzido = lote.cod_reduzido AND
865 num_nota_icomp = lote.num_nota AND
866 num_seqnota_icomp = lote.num_seqnota AND
867 num_sequencial_icomp = lote.num_seqcadicomp AND
868 (num_lote = lote.num_lote OR num_lote = '[SEM_LOTE]') AND
869 cod_operacao_estorno IS NULL AND
870 flg_estorno IS FALSE RETURNING *
871 LOOP
872
873 PERFORM estornar_operacao_entrada(operacao);
874
875 RAISE DEBUG 'Efetivando estorno de entrada. Op: %; Prod.: %; Filial: %-%; Qtde.: %; Estorno Gerado: %',
876 operacao.cod_operacao, operacao.cod_reduzido, operacao.cod_rede, operacao.cod_filial, operacao.qtd_operacao, CURRVAL('operacao_entrada_seq');
877
878 END LOOP;
879
880 IF TG_OP = 'DELETE' THEN
881 --Aplica a diferenca que sobrou entre o(s) lote(s) e item para assegurar que estao com a quantidade igual
882 PERFORM compensar_lote_entrada(lote);
883 END IF;
884
885 RETURN NULL;
886END;
887$BODY$
888 LANGUAGE plpgsql VOLATILE;
889
890DROP TRIGGER IF EXISTS efetivar_movimento_entrada_update_item_lote_tg ON cadlentd;
891
892CREATE CONSTRAINT TRIGGER efetivar_movimento_entrada_update_item_lote_tg
893 AFTER UPDATE ON public.cadlentd INITIALLY DEFERRED FOR EACH ROW
894 WHEN (NEW.qtd_entrada IS NOT NULL AND (NEW.qtd_entrada IS DISTINCT FROM OLD.qtd_entrada)
895 OR (NEW.qtd_fator IS DISTINCT FROM OLD.qtd_fator) AND is_cadccomp_conferido(NEW.cod_rede, NEW.cod_filial, NEW.cod_fornec, NEW.num_nota, NEW.num_seqnota))
896EXECUTE PROCEDURE public.efetivar_movimento_entrada_item_lote();
897
898DROP TRIGGER IF EXISTS efetivar_movimento_entrada_insert_item_lote_tg ON cadlentd;
899
900CREATE CONSTRAINT TRIGGER efetivar_movimento_entrada_insert_item_lote_tg
901 AFTER INSERT ON public.cadlentd INITIALLY DEFERRED FOR EACH ROW
902 WHEN (NEW.qtd_entrada IS NOT NULL AND is_cadccomp_conferido(NEW.cod_rede, NEW.cod_filial, NEW.cod_fornec, NEW.num_nota, NEW.num_seqnota))
903EXECUTE PROCEDURE public.efetivar_movimento_entrada_item_lote();
904
905DROP TRIGGER IF EXISTS efetivar_estorno_entrada_update_item_lote_tg ON cadlentd;
906
907CREATE TRIGGER efetivar_estorno_entrada_update_item_lote_tg
908 AFTER UPDATE ON public.cadlentd FOR EACH ROW
909 WHEN ((NEW.qtd_entrada IS DISTINCT FROM OLD.qtd_entrada)
910 OR (NEW.qtd_fator IS DISTINCT FROM OLD.qtd_fator) AND is_cadccomp_conferido(NEW.cod_rede, NEW.cod_filial, NEW.cod_fornec, NEW.num_nota, NEW.num_seqnota))
911EXECUTE PROCEDURE public.efetivar_estorno_entrada_estoque_item_lote();
912
913DROP TRIGGER IF EXISTS efetivar_estorno_entrada_estoque_delete_item_lote_tg ON cadlentd;
914
915CREATE TRIGGER efetivar_estorno_entrada_estoque_delete_item_lote_tg
916 AFTER DELETE ON public.cadlentd FOR EACH ROW
917 WHEN (is_cadccomp_conferido(OLD.cod_rede, OLD.cod_filial, OLD.cod_fornec, OLD.num_nota, OLD.num_seqnota))
918EXECUTE PROCEDURE public.efetivar_estorno_entrada_estoque_item_lote();
919
920--Controle de saidas
921CREATE OR REPLACE FUNCTION public.efetivar_saida_estoque(rede INTEGER, filial INTEGER, nota INTEGER, sequencial INTEGER, produto INTEGER, lote varchar, local_armazenagem INTEGER, quantidade NUMERIC(16,4))
922 RETURNS void AS
923$BODY$
924DECLARE
925 error_detail TEXT;
926BEGIN
927
928 IF quantidade > 0 THEN
929 RAISE invalid_parameter_value USING MESSAGE = format('Operacao de saida nao pode registrar uma quantidade maior que zero: %s', quantidade);
930 END IF;
931
932 INSERT INTO public.operacao_saida(qtd_operacao, cod_rede, cod_filial, cod_reduzido, num_nota, num_sequencial, num_lote, cod_local_armazenagem)
933 VALUES (quantidade, rede, filial, produto, nota, sequencial, lote, local_armazenagem);
934
935 RAISE DEBUG 'Efetivando saida. Op: %; Prod.: %; Filial: %-%; Qtde.: %',
936 CURRVAL('operacao_saida_seq'), produto, rede, filial, quantidade;
937
938EXCEPTION
939 WHEN unique_violation THEN
940 GET STACKED DIAGNOSTICS error_detail = PG_EXCEPTION_DETAIL;
941 RAISE unique_violation USING MESSAGE = 'Operacao de saida ja efetivada anteriormente',
942 DETAIL = error_detail,
943 HINT = 'Considere estornar o movimento';
944END;
945$BODY$
946 LANGUAGE plpgsql VOLATILE;
947
948
949--alter event trigger pg_internal_proxy disable
950CREATE OR REPLACE FUNCTION public.efetivar_movimento_saida(item cadivend)
951 RETURNS VOID AS
952$BODY$
953DECLARE
954 lote cadlvend%rowtype;
955BEGIN
956
957 --Realiza a movimentacao via lotes
958 FOR lote IN
959 SELECT * FROM cadlvend lv where
960 (lv.cod_rede, lv.cod_filial, lv.num_nota, lv.num_seqcadivend, lv.cod_reduzido)
961 = (item.cod_rede, item.cod_filial, item.num_nota, item.num_sequencial, item.cod_reduzido) LOOP
962
963 if EXISTS(
964 SELECT
965 op.*
966 FROM
967 operacao_saida op
968 WHERE
969 (op.cod_rede, op.cod_filial, op.num_nota, op.num_sequencial, op.cod_reduzido, op.num_lote)
970 = (lote.cod_rede, lote.cod_filial, lote.num_nota, lote.num_seqcadivend, lote.cod_reduzido, lote.num_lote)
971 AND op.cod_operacao_estorno IS NULL
972 AND op.flg_estorno IS FALSE
973 ) THEN
974 RAISE DEBUG 'Operacao encontrada para o Prod.: % Lote: %. Ignorando...', lote.cod_reduzido, lote.num_lote;
975 CONTINUE;
976 END IF;
977
978 RAISE DEBUG 'Aplicando alteracao de estoque para o Prod.: % Lote: % Qtde: %', lote.cod_reduzido, lote.num_lote, lote.qtd_lote;
979 PERFORM efetivar_saida_estoque(lote.cod_rede, lote.cod_filial, lote.num_nota, lote.num_seqcadivend, lote.cod_reduzido, lote.num_lote, 1, lote.qtd_lote * -1);
980 END LOOP;
981
982 --Realiza a movimentacao atraves do proprio item se nao houverem lotes
983 IF NOT FOUND THEN
984
985 RAISE DEBUG 'Lotes não encontrados, aplicando movimentacao por item';
986
987 if EXISTS(
988 SELECT
989 op.*
990 FROM
991 operacao_saida op
992 WHERE
993 (op.cod_rede, op.cod_filial, op.num_nota, op.num_sequencial, op.cod_reduzido)
994 = (item.cod_rede, item.cod_filial, item.num_nota, item.num_sequencial, item.cod_reduzido)
995 AND op.cod_operacao_estorno IS NULL
996 AND op.flg_estorno IS FALSE
997 AND op.num_lote = '[SEM_LOTE]'
998 ) THEN
999 RAISE DEBUG 'Operacao encontrada para o Prod.: % Lote: ''[SEM_LOTE]''. Ignorando...', item.cod_reduzido;
1000 RETURN;
1001 END IF;
1002
1003 RAISE DEBUG 'Aplicando alteracao de estoque para o Prod.: % Lote: ''[SEM_LOTE]'' Qtde: %', item.cod_reduzido, item.qtd_produto;
1004 PERFORM efetivar_saida_estoque(item.cod_rede, item.cod_filial, item.num_nota, item.num_sequencial, item.cod_reduzido, '[SEM_LOTE]', 1, item.qtd_produto * -1);
1005
1006 END IF;
1007
1008 --Aplica a diferenca que sobrou entre o(s) lote(s) e item para assegurar que estao com a quantidade igual
1009 PERFORM compensar_item_saida(item);
1010
1011END;
1012$BODY$
1013 LANGUAGE plpgsql VOLATILE;
1014
1015CREATE OR REPLACE FUNCTION public.efetivar_movimento_saida_item()
1016 RETURNS trigger AS
1017$BODY$
1018BEGIN
1019 PERFORM efetivar_movimento_saida(NEW);
1020 RETURN NULL;
1021END;
1022$BODY$
1023 LANGUAGE plpgsql VOLATILE;
1024
1025CREATE OR REPLACE FUNCTION public.efetivar_estorno_saida_estoque_item()
1026 RETURNS trigger AS
1027$BODY$
1028DECLARE
1029 movimento cadivend;
1030 operacao operacao_saida;
1031BEGIN
1032
1033 IF TG_OP = 'DELETE' THEN
1034 movimento := OLD;
1035 ELSE
1036 movimento := NEW;
1037 END IF;
1038
1039 FOR operacao IN
1040 UPDATE operacao_saida SET cod_operacao_estorno = NEXTVAL('operacao_saida_seq') WHERE
1041 cod_rede = movimento.cod_rede AND
1042 cod_filial = movimento.cod_filial AND
1043 cod_reduzido = movimento.cod_reduzido AND
1044 num_nota = movimento.num_nota AND
1045 num_sequencial = movimento.num_sequencial AND
1046 cod_operacao_estorno IS NULL AND
1047 flg_estorno IS FALSE RETURNING *
1048 LOOP
1049
1050 PERFORM estornar_operacao_saida(operacao);
1051
1052 RAISE DEBUG 'Efetivando estorno de saida. Op: %; Prod.: %; Filial: %-%; Qtde.: %; Estorno Gerado: %',
1053 operacao.cod_operacao, operacao.cod_reduzido, operacao.cod_rede, operacao.cod_filial, operacao.qtd_operacao, CURRVAL('operacao_saida_seq');
1054
1055 END LOOP;
1056
1057 RETURN NULL;
1058END;
1059$BODY$
1060 LANGUAGE plpgsql VOLATILE;
1061
1062DROP TRIGGER IF EXISTS efetivar_movimento_saida_update_tg ON cadivend;
1063
1064CREATE CONSTRAINT TRIGGER efetivar_movimento_saida_update_tg
1065 AFTER UPDATE ON public.cadivend INITIALLY DEFERRED FOR EACH ROW
1066 WHEN
1067 (((NEW.flg_estoque = 'S' AND NEW.flg_estoque IS DISTINCT FROM OLD.flg_estoque AND COALESCE(NEW.flg_excluido, 'N') = 'N')
1068 OR (COALESCE(NEW.flg_excluido, 'N') = 'N' AND OLD.flg_excluido = 'S')
1069 OR (NEW.flg_estoque = 'S' AND NEW.qtd_produto IS DISTINCT FROM OLD.qtd_produto AND COALESCE(NEW.flg_excluido, 'N') = 'N'))
1070 AND is_cadivend_saida(NEW.cod_rede, NEW.cod_filial, NEW.num_nota))
1071EXECUTE PROCEDURE public.efetivar_movimento_saida_item();
1072
1073DROP TRIGGER IF EXISTS efetivar_movimento_saida_insert_tg ON cadivend;
1074
1075CREATE CONSTRAINT TRIGGER efetivar_movimento_saida_insert_tg
1076 AFTER INSERT ON public.cadivend INITIALLY DEFERRED FOR EACH ROW
1077 WHEN
1078 (NEW.flg_estoque = 'S' AND COALESCE(NEW.flg_excluido, 'N') = 'N' AND is_cadivend_saida(NEW.cod_rede, NEW.cod_filial, NEW.num_nota))
1079EXECUTE PROCEDURE public.efetivar_movimento_saida_item();
1080
1081DROP TRIGGER IF EXISTS efetivar_estorno_saida_estoque_update_tg ON cadivend;
1082
1083CREATE TRIGGER efetivar_estorno_saida_estoque_update_tg
1084 AFTER UPDATE ON public.cadivend FOR EACH ROW
1085 WHEN (
1086 ((NEW.flg_estoque IS DISTINCT FROM OLD.flg_estoque AND OLD.flg_estoque = 'S')
1087 OR (NEW.qtd_produto IS DISTINCT FROM OLD.qtd_produto AND OLD.flg_estoque = 'S')
1088 OR (NEW.flg_excluido IS DISTINCT FROM OLD.flg_excluido AND NEW.flg_excluido = 'S')) AND is_cadivend_saida(NEW.cod_rede, NEW.cod_filial, NEW.num_nota))
1089EXECUTE PROCEDURE public.efetivar_estorno_saida_estoque_item();
1090
1091DROP TRIGGER IF EXISTS efetivar_estorno_saida_estoque_delete_tg ON cadivend;
1092
1093CREATE TRIGGER efetivar_estorno_saida_estoque_delete_tg
1094 AFTER DELETE ON public.cadivend FOR EACH ROW
1095 WHEN (is_cadivend_saida(OLD.cod_rede, OLD.cod_filial, OLD.num_nota))
1096EXECUTE PROCEDURE public.efetivar_estorno_saida_estoque_item();
1097
1098---------------------- cadcvend --------------------------
1099CREATE OR REPLACE FUNCTION public.efetivar_movimento_saida_cabecalho()
1100 RETURNS trigger AS
1101$BODY$
1102DECLARE
1103 item cadivend%rowtype;
1104BEGIN
1105
1106 FOR item IN
1107 SELECT * FROM cadivend iv WHERE
1108 (iv.cod_rede, iv.cod_filial, iv.num_nota) = (NEW.cod_rede, NEW.cod_filial, NEW.num_nota)
1109 AND iv.flg_estoque = 'S' AND COALESCE(iv.flg_excluido, 'N') = 'N' LOOP
1110 PERFORM efetivar_movimento_saida(item);
1111 END LOOP;
1112 RETURN NULL;
1113
1114END;
1115$BODY$
1116 LANGUAGE plpgsql VOLATILE;
1117
1118DROP TRIGGER IF EXISTS efetivar_saida_estoque_update_tg ON cadcvend;
1119
1120CREATE CONSTRAINT TRIGGER efetivar_saida_estoque_update_tg
1121 AFTER UPDATE ON public.cadcvend INITIALLY DEFERRED FOR EACH ROW
1122 WHEN (
1123 ((COALESCE(NEW.flg_excluido, 'N') = 'N' AND OLD.flg_excluido = 'S')
1124 OR NEW.flg_sitcaixa = '2' AND NEW.flg_sitcaixa IS DISTINCT FROM OLD.flg_sitcaixa)
1125 AND NEW.tip_venda IN ('V', 'O'))
1126EXECUTE PROCEDURE public.efetivar_movimento_saida_cabecalho();
1127
1128---------ESTORNO CABECALHO
1129CREATE OR REPLACE FUNCTION public.efetivar_estorno_saida_estoque_cabecalho()
1130 RETURNS trigger AS
1131$BODY$
1132DECLARE
1133 movimento cadcvend;
1134 operacao operacao_saida;
1135BEGIN
1136
1137 IF TG_OP = 'DELETE' THEN
1138 movimento := OLD;
1139 ELSE
1140 movimento := NEW;
1141 END IF;
1142
1143 FOR operacao IN
1144 UPDATE operacao_saida SET cod_operacao_estorno = NEXTVAL('operacao_saida_seq') WHERE
1145 cod_rede = movimento.cod_rede AND
1146 cod_filial = movimento.cod_filial AND
1147 num_nota = movimento.num_nota AND
1148 cod_operacao_estorno IS NULL AND
1149 flg_estorno IS FALSE RETURNING *
1150 LOOP
1151
1152 PERFORM estornar_operacao_saida(operacao);
1153
1154 RAISE DEBUG 'Efetivando estorno de saida. Op: %; Prod.: %; Filial: %-%; Qtde.: %; Estorno Gerado: %',
1155 operacao.cod_operacao, operacao.cod_reduzido, operacao.cod_rede, operacao.cod_filial, operacao.qtd_operacao, CURRVAL('operacao_saida_seq');
1156
1157 END LOOP;
1158
1159 RETURN NEW;
1160END;
1161$BODY$
1162 LANGUAGE plpgsql VOLATILE;
1163
1164DROP TRIGGER IF EXISTS efetivar_estorno_saida_estoque_update_tg ON cadcvend;
1165
1166CREATE TRIGGER efetivar_estorno_saida_estoque_update_tg
1167 AFTER UPDATE ON public.cadcvend FOR EACH ROW
1168 WHEN (NEW.flg_excluido = 'S' AND NEW.flg_excluido IS DISTINCT FROM OLD.flg_excluido AND NEW.tip_venda IN ('V', 'O'))
1169EXECUTE PROCEDURE public.efetivar_estorno_saida_estoque_cabecalho();
1170
1171DROP TRIGGER IF EXISTS efetivar_estorno_saida_estoque_delete_tg ON cadcvend;
1172
1173CREATE TRIGGER efetivar_estorno_saida_estoque_delete_tg
1174 AFTER DELETE ON public.cadcvend FOR EACH ROW
1175 WHEN (OLD.tip_venda IN ('V', 'O'))
1176EXECUTE PROCEDURE public.efetivar_estorno_saida_estoque_cabecalho();
1177
1178---------------------- cadlvend --------------------------
1179CREATE OR REPLACE FUNCTION public.efetivar_movimento_saida_item_lote()
1180 RETURNS trigger AS
1181$BODY$
1182DECLARE
1183 operacao operacao_saida;
1184BEGIN
1185
1186 --Se a operacao for de insercao e existir lotes do tipo [SEM_LOTE] entao o sistema deve estornar todas as movimentacoes para que o usuario informe os lotes corretos
1187 IF (TG_OP = 'INSERT') THEN
1188 FOR operacao IN
1189 UPDATE operacao_saida SET cod_operacao_estorno = NEXTVAL('operacao_saida_seq') WHERE
1190 cod_rede = NEW.cod_rede AND
1191 cod_filial = NEW.cod_filial AND
1192 cod_reduzido = NEW.cod_reduzido AND
1193 num_nota = NEW.num_nota AND
1194 num_lote = '[SEM_LOTE]' AND
1195 num_sequencial = NEW.num_seqcadivend AND
1196 cod_operacao_estorno IS NULL AND
1197 flg_estorno IS FALSE RETURNING *
1198 LOOP
1199
1200 PERFORM estornar_operacao_saida(operacao);
1201
1202 RAISE DEBUG 'Efetivando estorno de saida. Op: %; Prod.: %; Filial: %-%; Qtde.: %; Estorno Gerado: %',
1203 operacao.cod_operacao, operacao.cod_reduzido, operacao.cod_rede, operacao.cod_filial, operacao.qtd_operacao, CURRVAL('operacao_saida_seq');
1204
1205 END LOOP;
1206 END IF;
1207
1208 --Efetiva o lote atual
1209 PERFORM efetivar_saida_estoque(it.cod_rede, it.cod_filial, it.num_nota, it.num_seqcadivend, it.cod_reduzido, it.num_lote, it.cod_local_armazenagem, it.qtd_lote) FROM
1210 (SELECT
1211 NEW.cod_rede, NEW.cod_filial, NEW.num_nota, NEW.num_seqcadivend, NEW.cod_reduzido, NEW.num_lote, 1 AS cod_local_armazenagem, (NEW.qtd_lote * -1) AS qtd_lote
1212
1213 EXCEPT
1214
1215 SELECT
1216 cod_rede, cod_filial, num_nota, num_sequencial, cod_reduzido, num_lote, cod_local_armazenagem, qtd_operacao
1217 FROM
1218 operacao_saida
1219 WHERE
1220 (cod_rede, cod_filial, num_nota, num_sequencial) = (NEW.cod_rede, NEW.cod_filial, NEW.num_nota, NEW.num_seqcadivend)
1221 AND cod_operacao_estorno IS NULL
1222 AND flg_estorno IS FALSE
1223 ORDER BY num_seqcadivend) AS it;
1224
1225 --Aplica a diferenca que sobrou entre o(s) lote(s) e item para assegurar que estao com a quantidade igual
1226 PERFORM compensar_lote_saida(NEW);
1227
1228 RETURN NULL;
1229
1230END;
1231$BODY$
1232 LANGUAGE plpgsql VOLATILE;
1233
1234CREATE OR REPLACE FUNCTION public.efetivar_estorno_saida_estoque_item_lote()
1235 RETURNS trigger AS
1236$BODY$
1237DECLARE
1238 lote cadlvend;
1239 operacao operacao_saida;
1240 total_item NUMERIC;
1241 total_operacoes NUMERIC;
1242BEGIN
1243
1244 IF TG_OP = 'DELETE' THEN
1245 lote := OLD;
1246 ELSE
1247 lote := NEW;
1248 END IF;
1249
1250 FOR operacao IN
1251 UPDATE operacao_saida SET cod_operacao_estorno = NEXTVAL('operacao_saida_seq') WHERE
1252 cod_rede = lote.cod_rede AND
1253 cod_filial = lote.cod_filial AND
1254 cod_reduzido = lote.cod_reduzido AND
1255 num_nota = lote.num_nota AND
1256 num_sequencial = lote.num_seqcadivend AND
1257 (num_lote = lote.num_lote OR num_lote = '[SEM_LOTE]') AND
1258 cod_operacao_estorno IS NULL AND
1259 flg_estorno IS FALSE RETURNING *
1260 LOOP
1261
1262 PERFORM estornar_operacao_saida(operacao);
1263
1264 RAISE DEBUG 'Efetivando estorno de saida. Op: %; Prod.: %; Filial: %-%; Qtde.: %; Estorno Gerado: %',
1265 operacao.cod_operacao, operacao.cod_reduzido, operacao.cod_rede, operacao.cod_filial, operacao.qtd_operacao, CURRVAL('operacao_saida_seq');
1266
1267 END LOOP;
1268
1269 IF TG_OP = 'DELETE' THEN
1270 --Aplica a diferenca que sobrou entre o(s) lote(s) e item para assegurar que estao com a quantidade igual
1271 PERFORM compensar_lote_saida(lote);
1272 END IF;
1273
1274 RETURN NULL;
1275END;
1276$BODY$
1277 LANGUAGE plpgsql VOLATILE;
1278
1279DROP TRIGGER IF EXISTS efetivar_movimento_saida_update_item_lote_tg ON cadlvend;
1280
1281CREATE CONSTRAINT TRIGGER efetivar_movimento_saida_update_item_lote_tg
1282 AFTER UPDATE ON public.cadlvend INITIALLY DEFERRED FOR EACH ROW
1283 WHEN (NEW.qtd_lote IS DISTINCT FROM OLD.qtd_lote AND is_lote_saida(NEW.cod_rede, NEW.cod_filial, NEW.num_nota, NEW.num_seqcadivend))
1284EXECUTE PROCEDURE public.efetivar_movimento_saida_item_lote();
1285
1286DROP TRIGGER IF EXISTS efetivar_movimento_saida_insert_item_lote_tg ON cadlvend;
1287
1288CREATE CONSTRAINT TRIGGER efetivar_movimento_saida_insert_item_lote_tg
1289 AFTER INSERT ON public.cadlvend INITIALLY DEFERRED FOR EACH ROW
1290 WHEN (is_lote_saida(NEW.cod_rede, NEW.cod_filial, NEW.num_nota, NEW.num_seqcadivend))
1291EXECUTE PROCEDURE public.efetivar_movimento_saida_item_lote();
1292
1293DROP TRIGGER IF EXISTS efetivar_estorno_saida_update_item_lote_tg ON cadlvend;
1294
1295CREATE TRIGGER efetivar_estorno_saida_update_item_lote_tg
1296 AFTER UPDATE ON public.cadlvend FOR EACH ROW
1297 WHEN (NEW.qtd_lote IS DISTINCT FROM OLD.qtd_lote AND is_lote_saida(NEW.cod_rede, NEW.cod_filial, NEW.num_nota, NEW.num_seqcadivend))
1298EXECUTE PROCEDURE public.efetivar_estorno_saida_estoque_item_lote();
1299
1300DROP TRIGGER IF EXISTS efetivar_estorno_saida_estoque_delete_item_lote_tg ON cadlvend;
1301
1302CREATE TRIGGER efetivar_estorno_saida_estoque_delete_item_lote_tg
1303 AFTER DELETE ON public.cadlvend FOR EACH ROW
1304 WHEN (is_lote_saida(OLD.cod_rede, OLD.cod_filial, OLD.num_nota, OLD.num_seqcadivend))
1305EXECUTE PROCEDURE public.efetivar_estorno_saida_estoque_item_lote();
1306
1307--Validando as constraints
1308DO $$
1309 DECLARE
1310 con RECORD;
1311 BEGIN
1312
1313 FOR con IN SELECT conrelid::regclass AS tablename, conname FROM pg_constraint WHERE NOT convalidated LOOP
1314 EXECUTE format('ALTER TABLE %I VALIDATE CONSTRAINT %I', con.tablename, con.conname);
1315 RAISE DEBUG 'Validating constraint: %.%', con.tablename, con.conname;
1316 END LOOP;
1317
1318 END $$;
1319
1320--Funcoes de manipulacao de estoque
1321CREATE OR REPLACE FUNCTION manipular_estoque(operacao anyelement) RETURNS NUMERIC AS $$
1322 WITH op AS (
1323 INSERT INTO alteracoes_estoque(cod_rede, cod_filial, cod_reduzido, qtd_operacao) VALUES (operacao.cod_rede, operacao.cod_filial, operacao.cod_reduzido, operacao.qtd_operacao) RETURNING *
1324 )
1325 INSERT INTO public.estoque (cod_rede, cod_filial, cod_reduzido, qtd_estoque) SELECT cod_rede, cod_filial, cod_reduzido, qtd_operacao FROM op
1326 ON CONFLICT ON CONSTRAINT estoque_pkey DO UPDATE SET qtd_estoque = (estoque.qtd_estoque + EXCLUDED.qtd_estoque) RETURNING qtd_estoque;
1327$$ LANGUAGE SQL;
1328
1329CREATE OR REPLACE FUNCTION manipular_estoque_lote(operacao anyelement) RETURNS NUMERIC AS $$
1330INSERT INTO public.estoque_lote (cod_rede, cod_filial, cod_reduzido, num_lote, qtd_estoque) VALUES (operacao.cod_rede, operacao.cod_filial, operacao.cod_reduzido, operacao.num_lote, operacao.qtd_operacao)
1331ON CONFLICT ON CONSTRAINT estoque_lote_pkey DO UPDATE SET qtd_estoque = (estoque_lote.qtd_estoque + EXCLUDED.qtd_estoque) RETURNING qtd_estoque;
1332$$ LANGUAGE SQL;
1333
1334--Gateways
1335CREATE OR REPLACE FUNCTION public.executar_gateway_operacao_entrada()
1336 RETURNS trigger AS
1337$BODY$
1338BEGIN
1339 NEW.num_dia := date_part('day', NEW.dat_operacao);
1340 NEW.num_mes := date_part('month', NEW.dat_operacao);
1341 NEW.num_ano := date_part('year', NEW.dat_operacao);
1342 NEW.qtd_estoque_efetivado := manipular_estoque(NEW);
1343 NEW.qtd_estoque_lote_efetivado := manipular_estoque_lote(NEW);
1344 RETURN NEW;
1345END;
1346$BODY$
1347 LANGUAGE plpgsql VOLATILE;
1348
1349DO $$
1350 BEGIN
1351 CREATE TRIGGER gateway_operacao_entrada_tg
1352 BEFORE INSERT ON public.operacao_entrada FOR EACH ROW
1353 EXECUTE PROCEDURE public.executar_gateway_operacao_entrada();
1354 EXCEPTION
1355 WHEN duplicate_object THEN
1356 RAISE NOTICE 'Trigger existente detectada. Ignorando criacao...';
1357 END$$;
1358
1359
1360CREATE OR REPLACE FUNCTION public.executar_gateway_operacao_saida()
1361 RETURNS trigger AS
1362$BODY$
1363BEGIN
1364 NEW.num_dia := date_part('day', NEW.dat_operacao);
1365 NEW.num_mes := date_part('month', NEW.dat_operacao);
1366 NEW.num_ano := date_part('year', NEW.dat_operacao);
1367 NEW.qtd_estoque_efetivado := manipular_estoque(NEW);
1368 NEW.qtd_estoque_lote_efetivado := manipular_estoque_lote(NEW);
1369 RETURN NEW;
1370END;
1371$BODY$
1372 LANGUAGE plpgsql VOLATILE;
1373
1374DO $$
1375BEGIN
1376 CREATE TRIGGER gateway_operacao_saida_tg
1377 BEFORE INSERT ON public.operacao_saida FOR EACH ROW
1378 EXECUTE PROCEDURE public.executar_gateway_operacao_saida();
1379EXCEPTION
1380 WHEN duplicate_object THEN
1381 RAISE NOTICE 'Trigger existente detectada. Ignorando criacao...';
1382END$$;
1383
1384DROP FUNCTION IF EXISTS alteracoes_estoque_notify() CASCADE;
1385
1386CREATE OR REPLACE FUNCTION alteracoes_estoque_notify() RETURNS TRIGGER AS $$
1387begin
1388 NOTIFY alteracao_estoque;
1389 RETURN NEW;
1390end
1391$$ language plpgsql;
1392
1393DROP TRIGGER IF EXISTS alteracoes_estoque_notify_tg ON alteracoes_estoque;
1394CREATE TRIGGER alteracoes_estoque_notify_tg AFTER INSERT ON alteracoes_estoque FOR EACH STATEMENT EXECUTE PROCEDURE alteracoes_estoque_notify();
1395
1396--PROTECAO CADESTOQ
1397DROP FUNCTION IF EXISTS public.cadestoq_protecao_novo_estoque() CASCADE;
1398
1399CREATE OR REPLACE FUNCTION public.cadestoq_protecao_novo_estoque() RETURNS trigger AS
1400$BODY$
1401BEGIN
1402
1403 RAISE DEBUG 'Alteracao de estoque. txid: % -> %', txid_current(), fc_get_env('sgfpod1.bypass_cadestoq_protection');
1404 IF NEW.cod_filial IS NOT DISTINCT FROM (SELECT coalesce(cod_filiallogin, cod_filialreplica) FROM cadredes)
1405 AND fc_get_env('sgfpod1.bypass_cadestoq_protection') IS DISTINCT FROM CAST(txid_current() AS TEXT) THEN
1406 RAISE DEBUG 'Tentativa de alteracao de estoque bloqueada, o valor anterior será mantido. Novo: % Antigo: %', NEW.qtd_estoque, OLD.qtd_estoque;
1407 NEW.qtd_estoque := OLD.qtd_estoque;
1408 ELSE
1409 RAISE DEBUG 'Deixou atualizar estoque, de % para %. Conf: %', OLD.qtd_estoque, NEW.qtd_estoque, fc_get_env('sgfpod1.bypass_cadestoq_protection');
1410 END IF;
1411
1412 RETURN NEW;
1413END;
1414$BODY$
1415 LANGUAGE plpgsql VOLATILE;
1416
1417DROP TRIGGER IF EXISTS cadestoq_protecao_novo_estoque_tg ON public.cadestoq;
1418
1419CREATE TRIGGER cadestoq_protecao_novo_estoque_tg
1420 BEFORE UPDATE OF qtd_estoque
1421 ON public.cadestoq
1422 FOR EACH ROW
1423 EXECUTE PROCEDURE public.cadestoq_protecao_novo_estoque();
1424
1425--Views
1426DROP VIEW IF EXISTS public.extrato_estoque_vw;
1427
1428CREATE OR REPLACE VIEW extrato_estoque_vw AS
1429 SELECT
1430 cod_rede, cod_filial, cod_reduzido, num_lote, dat_operacao, qtd_operacao, qtd_estoque_efetivado, qtd_estoque_lote_efetivado
1431 FROM
1432 operacao_entrada
1433 WHERE
1434 cod_operacao_estorno IS NULL
1435 AND NOT flg_estorno
1436 UNION ALL
1437 SELECT
1438 cod_rede, cod_filial, cod_reduzido, num_lote, dat_operacao, qtd_operacao, qtd_estoque_efetivado, qtd_estoque_lote_efetivado
1439 FROM
1440 operacao_saida
1441 WHERE
1442 cod_operacao_estorno IS NULL
1443 AND NOT flg_estorno
1444 ORDER BY
1445 dat_operacao;
1446
1447DROP VIEW IF EXISTS public.diferenca_estoque_persistido_vs_calculado_vw;
1448
1449CREATE OR REPLACE VIEW diferenca_estoque_persistido_vs_calculado_vw AS
1450 WITH operacoes AS (
1451 SELECT cod_rede, cod_filial, cod_reduzido, qtd_operacao FROM operacao_entrada
1452 UNION ALL
1453 SELECT cod_rede, cod_filial, cod_reduzido, qtd_operacao FROM operacao_saida
1454 ), estoque_calculado AS (
1455 SELECT cod_rede, cod_filial, cod_reduzido, SUM(qtd_operacao) AS qtd_estoque_calculado FROM operacoes GROUP BY cod_rede, cod_filial, cod_reduzido
1456 )
1457 SELECT
1458 e.cod_rede,
1459 e.cod_filial,
1460 e.cod_reduzido,
1461 e.qtd_estoque AS qtd_estoque_persistido,
1462 c.qtd_estoque_calculado,
1463 e.qtd_estoque - c.qtd_estoque_calculado AS diferenca
1464 FROM
1465 estoque e
1466 JOIN estoque_calculado c ON (e.cod_rede, e.cod_filial, e.cod_reduzido) = (c.cod_rede, c.cod_filial, c.cod_reduzido) WHERE e.qtd_estoque <> c.qtd_estoque_calculado
1467 ORDER BY diferenca;
1468
1469DROP VIEW IF EXISTS public.diferenca_estoque_lote_persistido_vs_calculado_vw;
1470
1471CREATE OR REPLACE VIEW diferenca_estoque_lote_persistido_vs_calculado_vw AS
1472 WITH operacoes AS (
1473 SELECT cod_rede, cod_filial, cod_reduzido, num_lote, qtd_operacao FROM operacao_entrada
1474 UNION ALL
1475 SELECT cod_rede, cod_filial, cod_reduzido, num_lote, qtd_operacao FROM operacao_saida
1476 ), estoque_calculado AS (
1477 SELECT cod_rede, cod_filial, cod_reduzido, num_lote, SUM(qtd_operacao) AS qtd_estoque_calculado FROM operacoes GROUP BY cod_rede, cod_filial, cod_reduzido, num_lote
1478 )
1479 SELECT
1480 e.cod_rede,
1481 e.cod_filial,
1482 e.cod_reduzido,
1483 e.num_lote,
1484 e.qtd_estoque AS qtd_estoque_persistido,
1485 c.qtd_estoque_calculado,
1486 e.qtd_estoque - c.qtd_estoque_calculado AS diferenca
1487 FROM
1488 estoque_lote e
1489 JOIN estoque_calculado c ON (e.cod_rede, e.cod_filial, e.cod_reduzido, e.num_lote) = (c.cod_rede, c.cod_filial, c.cod_reduzido, c.num_lote) WHERE e.qtd_estoque <> c.qtd_estoque_calculado
1490 ORDER BY diferenca;
1491
1492DROP VIEW IF exists diferenca_estoque_antigo_e_novo_vw CASCADE;
1493
1494CREATE OR REPLACE view diferenca_estoque_antigo_e_novo_vw AS
1495 SELECT e1.cod_rede,
1496 e1.cod_filial,
1497 e1.cod_reduzido,
1498 e1.qtd_estoque AS qtd_estoque_antigo,
1499 e2.qtd_estoque as qtd_novo_estoque,
1500 e1.qtd_estoque - e2.qtd_estoque AS diferenca
1501 FROM cadestoq e1
1502 JOIN estoque e2 ON e1.cod_rede = e2.cod_rede AND e1.cod_filial = e2.cod_filial AND e1.cod_reduzido = e2.cod_reduzido
1503 JOIN cadprodu pr ON e1.cod_rede = pr.cod_rede AND e1.cod_reduzido = pr.cod_reduzido
1504 WHERE e1.qtd_estoque <> e2.qtd_estoque AND pr.flg_estoque = 'S'
1505 ORDER BY (e1.qtd_estoque - e2.qtd_estoque);
1506
1507--Function para verificacao de inconsistencias
1508DROP FUNCTION IF EXISTS verificar_inconsistencias_estoque();
1509CREATE OR REPLACE FUNCTION public.verificar_inconsistencias_estoque()
1510 RETURNS boolean AS
1511$BODY$
1512DECLARE
1513 item record;
1514 encontrou_divergencias boolean := FALSE;
1515BEGIN
1516
1517 RAISE DEBUG 'Iniciando validação de estoque do produto';
1518
1519 RAISE DEBUG 'Validando Saldo Inicial...';
1520
1521 FOR
1522 item IN
1523 SELECT
1524 sl.qtd_saldo, op.qtd_operacao
1525 FROM
1526 cadsldpr sl
1527 JOIN (
1528 SELECT cod_rede, cod_filial, cod_reduzido, SUM(qtd_operacao) AS qtd_operacao FROM (
1529 SELECT cod_rede, cod_filial, cod_reduzido, qtd_operacao FROM operacao_entrada ope WHERE flg_saldo_inicial
1530 UNION ALL
1531 SELECT cod_rede, cod_filial, cod_reduzido, qtd_operacao FROM operacao_saida ops WHERE flg_saldo_inicial
1532 ) AS operacoes
1533 GROUP BY cod_rede, cod_filial, cod_reduzido
1534 ) op ON (op.cod_rede = sl.cod_rede AND op.cod_filial = sl.cod_filial AND op.cod_reduzido = sl.cod_reduzido)
1535 JOIN cadredes r ON (r.cod_rede = sl.cod_rede AND COALESCE(r.cod_filiallogin, r.cod_filialreplica) = sl.cod_filial)
1536 WHERE
1537 op.qtd_operacao IS DISTINCT FROM sl.qtd_saldo
1538 LOOP
1539
1540 encontrou_divergencias := TRUE;
1541 RAISE WARNING 'Saldo Inicial incorreto: (cadsldpr: %; operacoes: %)', item.qtd_saldo, item.qtd_operacao;
1542
1543 END LOOP;
1544
1545 RAISE DEBUG 'Validando Compras...';
1546
1547 FOR
1548 item IN
1549 SELECT
1550 ic.cod_rede, ic.cod_filial, ic.cod_fornec, ic.num_nota, ic.num_seqnota, ic.num_sequencial, (ic.qtd_produto * COALESCE(qtd_fator, 1)) as qtd_entrada, operacao.qtd_operacao, lote.qtd_lote
1551 FROM
1552 cadccomp cc
1553 JOIN cadicomp ic ON (cc.cod_rede, cc.cod_filial, cc.cod_fornec, cc.num_nota, cc.num_seqnota) =
1554 (ic.cod_rede, ic.cod_filial, ic.cod_fornec, ic.num_nota, ic.num_seqnota)
1555 JOIN cadredes r ON (r.cod_rede = cc.cod_rede AND COALESCE(r.cod_filiallogin, r.cod_filialreplica) = cc.cod_filial)
1556 LEFT JOIN LATERAL (
1557 SELECT
1558 sum(qtd_operacao) AS qtd_operacao
1559 FROM
1560 operacao_entrada ope
1561 WHERE (ic.cod_rede, ic.cod_filial, ic.cod_fornec, ic.num_nota, ic.num_seqnota, ic.num_sequencial) =
1562 (ope.cod_rede, ope.cod_filial, ope.cod_fornec_icomp, ope.num_nota_icomp, ope.num_seqnota_icomp, ope.num_sequencial_icomp)) AS operacao ON TRUE
1563 LEFT JOIN LATERAL (
1564 SELECT
1565 sum(qtd_entrada * coalesce(qtd_fator, 1)) AS qtd_lote
1566 FROM
1567 cadlentd ld
1568 WHERE (ic.cod_rede, ic.cod_filial, ic.cod_fornec, ic.num_nota, ic.num_seqnota, ic.num_sequencial, ic.cod_reduzido) =
1569 (ld.cod_rede, ld.cod_filial, ld.cod_fornec, ld.num_nota, ld.num_seqnota, ld.num_seqcadicomp, ld.cod_reduzido)
1570 ) AS lote ON TRUE
1571 WHERE
1572 COALESCE(cc.flg_estoque, 'S') = 'S'
1573 AND (
1574 (lote.qtd_lote IS NOT NULL AND operacao.qtd_operacao IS DISTINCT FROM lote.qtd_lote)
1575 OR operacao.qtd_operacao IS DISTINCT FROM (ic.qtd_produto * COALESCE(qtd_fator, 1))
1576 )
1577
1578 LOOP
1579
1580 encontrou_divergencias := TRUE;
1581 RAISE WARNING 'Item de compra com valor divergente no novo estoque:'
1582 ' (cod_rede = % AND cod_filial = % AND cod_fornec = % AND num_nota = % AND num_seqnota = % AND num_sequencial = %). Icomp: % Oper.: % Lote: % ',
1583 item.cod_rede, item.cod_filial, item.cod_fornec, item.num_nota, item.num_seqnota, item.num_sequencial, item.qtd_entrada, item.qtd_operacao, item.qtd_lote;
1584
1585 END LOOP;
1586
1587 RAISE DEBUG 'Validando Devolucoes...';
1588
1589 FOR
1590 item IN
1591 SELECT
1592 iv.cod_rede, iv.cod_filial, iv.num_nota, iv.num_sequencial
1593 FROM cadcvend cv
1594 INNER JOIN cadivend iv ON (cv.cod_rede, cv.cod_filial, cv.num_nota) = (iv.cod_rede, iv.cod_filial, iv.num_nota)
1595 JOIN cadredes r ON (r.cod_rede = cv.cod_rede AND COALESCE(r.cod_filiallogin, r.cod_filialreplica) = cv.cod_filial)
1596 LEFT JOIN operacao_entrada ope ON (iv.cod_rede, iv.cod_filial, iv.num_nota, iv.num_sequencial) =
1597 (ope.cod_rede, ope.cod_filial, ope.num_nota_ivend, ope.num_sequencial_ivend)
1598 WHERE
1599 iv.flg_estoque = 'S'
1600 AND COALESCE(cv.flg_excluido, 'N') <> 'S'
1601 AND COALESCE(iv.flg_excluido, 'N') <> 'S'
1602 AND cv.tip_venda = 'D'
1603 AND ope.num_nota_ivend IS NULL
1604
1605 LOOP
1606
1607 encontrou_divergencias := TRUE;
1608 RAISE WARNING 'Item de devolucao sem operacao de entrada correspondente: (cod_rede = % AND cod_filial = % AND num_nota = % AND num_sequencial = %)',
1609 item.cod_rede, item.cod_filial, item.num_nota, item.num_sequencial;
1610
1611 END LOOP;
1612
1613 RAISE DEBUG 'Validando Saidas...';
1614
1615 FOR
1616 item IN
1617 SELECT
1618 iv.cod_rede, iv.cod_filial, iv.num_nota, iv.num_sequencial, iv.qtd_produto, abs(ops.qtd_operacao) as qtd_operacao, lote.qtd_lote
1619 FROM cadcvend cv
1620 INNER JOIN cadivend iv ON (cv.cod_rede, cv.cod_filial, cv.num_nota) = (iv.cod_rede, iv.cod_filial, iv.num_nota)
1621 JOIN cadredes r ON (r.cod_rede = cv.cod_rede AND COALESCE(r.cod_filiallogin, r.cod_filialreplica) = cv.cod_filial)
1622 LEFT JOIN LATERAL (
1623 SELECT
1624 sum(qtd_operacao) as qtd_operacao
1625 FROM
1626 operacao_saida ops
1627 WHERE
1628 (iv.cod_rede, iv.cod_filial, iv.num_nota, iv.num_sequencial) = (ops.cod_rede, ops.cod_filial, ops.num_nota, ops.num_sequencial)
1629 ) AS ops ON TRUE
1630 LEFT JOIN LATERAL (
1631 SELECT
1632 sum(qtd_lote) AS qtd_lote
1633 FROM
1634 cadlvend lv
1635 WHERE (iv.cod_rede, iv.cod_filial, iv.num_nota, iv.num_sequencial, iv.cod_reduzido)
1636 = (lv.cod_rede, lv.cod_filial, lv.num_nota, lv.num_seqcadivend, lv.cod_reduzido)
1637 ) AS lote ON TRUE
1638 WHERE
1639 iv.flg_estoque = 'S'
1640 AND COALESCE(cv.flg_excluido, 'N') <> 'S'
1641 AND COALESCE(iv.flg_excluido, 'N') <> 'S'
1642 AND (cv.tip_venda IN ('O') OR (cv.tip_venda = 'V' AND cv.flg_sitcaixa IS NOT NULL))
1643 AND ((lote.qtd_lote IS NOT NULL AND iv.qtd_produto IS DISTINCT FROM lote.qtd_lote)
1644 OR iv.qtd_produto IS DISTINCT FROM abs(ops.qtd_operacao)
1645 )
1646
1647 LOOP
1648
1649 encontrou_divergencias := TRUE;
1650 RAISE WARNING 'Item de venda/outras saidas com valor divergente no novo estoque: (cod_rede = % AND cod_filial = % AND num_nota = % AND num_sequencial = %). Cadivend: % Op.: % Lote: %',
1651 item.cod_rede, item.cod_filial, item.num_nota, item.num_sequencial, item.qtd_produto, item.qtd_operacao, item.qtd_lote;
1652
1653 END LOOP;
1654
1655 RAISE DEBUG 'Finalizando validacao. %.', (CASE encontrou_divergencias WHEN TRUE THEN 'Divergencias encontradas' ELSE 'Nenhuma divergencia encontrada' END);
1656
1657 RETURN encontrou_divergencias;
1658
1659END $BODY$
1660 LANGUAGE plpgsql IMMUTABLE;
1661
1662--Triggers temporarias para preenchimento automatico das novas tabelas
1663CREATE OR REPLACE FUNCTION public.insere_lote_atraves_da_cadloted()
1664 RETURNS trigger AS
1665$BODY$
1666BEGIN
1667 INSERT INTO lote (cod_rede, cod_reduzido, num_lote, dat_fabricacao, dat_vencimento)
1668 VALUES (NEW.cod_rede, NEW.cod_reduzido, NEW.num_lote, NEW.dat_fabric, NEW.dat_valid) ON CONFLICT DO NOTHING;
1669 RETURN NEW;
1670END;
1671$BODY$
1672 LANGUAGE plpgsql VOLATILE;
1673
1674DO $$
1675BEGIN
1676 CREATE TRIGGER insere_lote_atraves_da_cadloted_tg
1677 AFTER INSERT ON public.cadloted FOR EACH ROW
1678 EXECUTE PROCEDURE public.insere_lote_atraves_da_cadloted();
1679EXCEPTION
1680 WHEN duplicate_object THEN
1681 RAISE NOTICE 'Trigger existente detectada. Ignorando criacao...';
1682END$$;
1683
1684COMMENT ON FUNCTION public.insere_lote_atraves_da_cadloted() IS '[TEMP] Controle de estoque 2.0';
1685COMMENT ON TRIGGER insere_lote_atraves_da_cadloted_tg ON cadloted IS '[TEMP] Controle de estoque 2.0';
1686
1687CREATE OR REPLACE FUNCTION public.insere_lote_padrao_cadprodu()
1688 RETURNS trigger AS
1689$BODY$
1690BEGIN
1691 INSERT INTO lote (cod_rede, cod_reduzido, num_lote) VALUES (NEW.cod_rede, NEW.cod_reduzido, '[SEM_LOTE]') ON CONFLICT DO NOTHING;
1692 RETURN NEW;
1693END;
1694$BODY$
1695 LANGUAGE plpgsql VOLATILE;
1696
1697DO $$
1698BEGIN
1699 CREATE TRIGGER insere_lote_padrao_cadprodu_tg
1700 AFTER INSERT ON public.cadprodu FOR EACH ROW
1701 EXECUTE PROCEDURE public.insere_lote_padrao_cadprodu();
1702EXCEPTION
1703 WHEN duplicate_object THEN
1704 RAISE NOTICE 'Trigger existente detectada. Ignorando criacao...';
1705END$$;
1706
1707COMMENT ON FUNCTION public.insere_lote_padrao_cadprodu() IS '[TEMP] Controle de estoque 2.0';
1708COMMENT ON TRIGGER insere_lote_padrao_cadprodu_tg ON cadprodu IS '[TEMP] Controle de estoque 2.0';
1709
1710CREATE OR REPLACE FUNCTION public.insere_local_armazenagem_padrao_cadfilia()
1711 RETURNS trigger AS
1712$BODY$
1713BEGIN
1714 INSERT INTO local_armazenagem (cod_rede, cod_filial, cod_local_armazenagem, nom_local_armazenagem) VALUES (NEW.cod_rede, NEW.cod_filial, 1, 'Local Padrao') ON CONFLICT DO NOTHING;
1715 RETURN NEW;
1716END;
1717$BODY$
1718 LANGUAGE plpgsql VOLATILE;
1719
1720DO $$
1721 BEGIN
1722 CREATE TRIGGER insere_local_armazenagem_padrao_cadfilia_tg
1723 AFTER INSERT ON public.cadfilia FOR EACH ROW
1724 EXECUTE PROCEDURE public.insere_local_armazenagem_padrao_cadfilia();
1725 EXCEPTION
1726 WHEN duplicate_object THEN
1727 RAISE NOTICE 'Trigger existente detectada. Ignorando criacao...';
1728 END$$;
1729
1730COMMENT ON FUNCTION public.insere_local_armazenagem_padrao_cadfilia() IS '[TEMP] Controle de estoque 2.0';
1731COMMENT ON TRIGGER insere_local_armazenagem_padrao_cadfilia_tg ON cadfilia IS '[TEMP] Controle de estoque 2.0';
1732
1733--View para análise da implantação
1734DROP VIEW IF EXISTS public.acerto_implantacao_estoque_vw;
1735
1736CREATE OR REPLACE VIEW acerto_implantacao_estoque_vw AS
1737 SELECT cod_rede, cod_filial, cod_reduzido, qtd_operacao AS acerto_entrada, 0 AS acerto_saida FROM operacao_entrada WHERE num_lote = '[ACERTO_IMPLANTACAO]'
1738 UNION ALL
1739 SELECT cod_rede, cod_filial, cod_reduzido, 0, qtd_operacao FROM operacao_saida WHERE num_lote = '[ACERTO_IMPLANTACAO]' order by 1, 2, 3;
1740
1741DO $PFC$
1742BEGIN
1743
1744 PERFORM * FROM pg_class WHERE relname = 'estoque' AND relkind = 'r';
1745
1746 IF NOT FOUND THEN
1747 RAISE INFO 'Estoque nao instalado, ignorando...';
1748 RETURN;
1749 END IF;
1750
1751 RAISE INFO 'Novo estoque encontrado, prosseguindo com a atualizacao';
1752
1753 DROP TRIGGER IF EXISTS efetivar_estorno_entrada_estoque_update_tg ON cadicomp;
1754
1755 CREATE TRIGGER efetivar_estorno_entrada_estoque_update_tg
1756 AFTER UPDATE ON public.cadicomp FOR EACH ROW
1757 WHEN ((NEW.qtd_produto IS DISTINCT FROM OLD.qtd_produto OR NEW.qtd_fator IS DISTINCT FROM OLD.qtd_fator) AND is_cadccomp_conferido(NEW.cod_rede, NEW.cod_filial, NEW.cod_fornec, NEW.num_nota, NEW.num_seqnota))
1758 EXECUTE PROCEDURE public.efetivar_estorno_entrada_estoque_item();
1759
1760 DROP TRIGGER IF EXISTS efetivar_movimento_entrada_update_tg ON cadicomp;
1761
1762 CREATE CONSTRAINT TRIGGER efetivar_movimento_entrada_update_tg
1763 AFTER UPDATE ON public.cadicomp INITIALLY DEFERRED FOR EACH ROW
1764 WHEN
1765 (NEW.qtd_produto IS NOT NULL AND (NEW.qtd_produto IS DISTINCT FROM OLD.qtd_produto OR NEW.qtd_fator IS DISTINCT FROM OLD.qtd_fator) AND is_cadccomp_conferido(NEW.cod_rede, NEW.cod_filial, NEW.cod_fornec, NEW.num_nota, NEW.num_seqnota))
1766 EXECUTE PROCEDURE public.efetivar_movimento_entrada_item();
1767
1768END$PFC$;