Fix #7123 - getting abra ready to test
[Pman.Xtuple] / pgsql / x-fifo-invfifo-update-from-invdetail.sql
1 -- relay method, that calls various updates based on the type of line.
2
3
4 --- updates the invfifo values for shipped and unitcost
5
6
7 -- test: SELECT invfifo_update_from_invdetail(11598); SELECT * from invdetailview where invdetail_id = 11598;
8
9
10
11 CREATE OR REPLACE FUNCTION invfifo_update_from_invdetail(integer)
12     RETURNS  boolean
13 AS $BODY$
14 DECLARE    
15 i_invdetail_id  ALIAS FOR $1;
16 BEGIN
17     RAISE EXCEPTION 'replaced with option version';
18 END
19 $BODY$
20   LANGUAGE plpgsql VOLATILE
21   COST 100;
22   
23 ALTER FUNCTION  invfifo_update_from_invdetail(integer)
24   OWNER TO admin;
25  
26 -----------
27    
28 CREATE OR REPLACE FUNCTION invfifo_update_from_invdetail(i_invdetail_id integer, i_update_after boolean)
29     RETURNS  NUMERIC
30
31 AS $BODY$
32 DECLARE        
33             
34     v_qty_before NUMERIC;
35     v_ret NUMERIC;
36     r_invdetail RECORD;
37     r_invdetail_rev RECORD;
38
39     v_ts_start timestamp with time zone;
40
41 BEGIN
42     -- RAISE NOTICE ' invfifo_update_from_invdetail  %',i_invdetail_id;
43
44     
45     v_ts_start = clock_timestamp();
46     
47     SELECT
48             *
49         INTO
50             r_invdetail
51         FROM
52             invdetailview  
53         WHERE
54             invdetail_id    = i_invdetail_id;
55     
56     -- no value to calc..
57     if (r_invdetail.invfifo_void > 0) THEN
58         -- RAISE NOTICE ' calling void on %,%',i_invdetail_id, r_invdetail.invfifo_void;
59         SELECT
60             invfifo_update_from_void(i_invdetail_id, r_invdetail.invfifo_void, i_update_after)
61             INTO v_ret;
62             
63         SELECT
64             *
65         INTO
66             r_invdetail_rev
67         FROM
68             invdetailview  
69         WHERE
70             invdetail_id    = r_invdetail.invfifo_void;
71             
72         IF r_invdetail_rev.invfifo_void < 1 THEN
73             RAISE NOTICE 'voiding reversal %', r_invdetail.invfifo_void;
74             SELECT
75                 invfifo_update_from_void(r_invdetail.invfifo_void,i_invdetail_id, i_update_after)
76                 INTO v_ret;
77             
78         
79         END IF;
80     
81     -- no value to cal    
82             
83         RETURN v_ret;
84     END IF;
85     
86     -- should we fix broken voids here?
87     -- if before/after same and not void... -then fill needs calling..
88     
89     -- validate the quantity - as if this is wrong it causes all sorts of problems.
90      
91     
92     SELECT
93             COALESCE(invfifo_qty_after, 0)
94         INTO
95             v_qty_before
96         FROM
97             invdetailview
98         WHERE
99             invdetail_location_id = r_invdetail.invdetail_location_id
100             AND
101             (
102                 (
103                     invhist_transdate < r_invdetail.invhist_transdate
104                 )
105                 OR
106                 (   invhist_transdate = r_invdetail.invhist_transdate
107                     AND
108                     invdetail_id < i_invdetail_id
109                 )
110             )
111             
112             AND
113                 invhist_itemsite_id = r_invdetail.invhist_itemsite_id
114             AND
115                 -- if r_invhist.invdetail_qty
116                 (
117                     (r_invdetail.invdetail_qty > 0 AND  invdetail_qty > 0)
118                     OR
119                     (r_invdetail.invdetail_qty < 0 AND  invdetail_qty < 0)
120                 )
121             ORDER BY
122                 invhist_transdate DESC,
123                 invdetail_id DESC
124             LIMIT 1;
125              
126     IF v_qty_before != r_invdetail.invfifo_qty_before THEN
127         PERFORM invfifo_fill(i_invdetail_id, true);
128     END IF;
129      
130     --RAISE NOTICE '% invfifo_update_from_invdetail (% : %/%) %s',
131     --        clock_timestamp(), i_invdetail_id ,
132     --        r_invdetail.invhist_transtype, r_invdetail.invhist_ordtype, r_invdetail.invdetail_qty;
133     --
134     IF (r_invdetail.invdetail_qty > 0) THEN      
135            -- calculate the cost before.. (incremental cost)
136             
137            IF (r_invdetail.invhist_transtype = 'RP') THEN
138                SELECT  invfifo_update_from_pohead(i_invdetail_id, i_update_after)
139                     INTO v_ret;
140               -- RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
141                --     clock_timestamp() - v_ts_start, i_invdetail_id ;
142                RETURN v_ret;
143                
144            END IF;
145            
146           
147            -- if it's a transfer
148                -- then unit price is dependant on FIFO sale that the tx relates to.
149                
150            IF (r_invdetail.invhist_transtype = 'RL') THEN
151                SELECT invfifo_update_from_transfer_in(i_invdetail_id, i_update_after)
152                     INTO v_ret;
153               -- RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
154               --      clock_timestamp() - v_ts_start, i_invdetail_id ;
155                
156                RETURN v_ret;
157            END IF;
158        
159                
160            -- what if it's a debit memo???
161            
162            -- if's it's a credit memo.
163            IF (r_invdetail.invhist_transtype = 'RS' AND r_invdetail.invhist_ordtype = 'CM' ) THEN
164                 SELECT invfifo_update_from_credit_memo(i_invdetail_id, i_update_after)
165                     INTO v_ret;
166                 --RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
167                --     clock_timestamp() - v_ts_start, i_invdetail_id ;
168                
169                 RETURN v_ret;
170            END IF;
171            
172            IF (r_invdetail.invhist_transtype = 'RS' AND r_invdetail.invhist_ordtype = 'SO' ) THEN
173             -- This is a voided transaction..
174             
175                 -- if void is not +ve then we need to know what it returned from..
176                 if (r_invdetail.invfifo_void > 0) THEN
177                 
178                     SELECT invfifo_update_from_void(i_invdetail_id, r_invdetail.invfifo_void, i_update_after)
179                         INTO v_ret;
180                 
181                 ELSE
182                     UPDATE cohead set  cohead_fifo_has_error = true where cohead_number = split_part(r_invdetail.invhist_ordnumber, '-', 1);
183                 
184                     --UPDATE invfifo SET invfifo_void = 0 WHERE
185                     --    invfifo_invdetail_id IN
186                     --        (
187                     --            SELECT
188                     --                    invdetail_id
189                     --                FROM
190                     --                    invdetailview
191                     --                WHERE
192                     --                    invhist_itemsite_id = r_invdetail.invhist_itemsite_id
193                     --                AND
194                     --                   invhist_ordnumber like split_part(r_invdetail.invhist_ordnumber, '-', 1) || '-%'
195                     --                AND
196                     --                    invhist_ordtype = 'SO'
197                     --                    
198                     --        );
199                     --    
200                     --    
201                     --PERFORM invfifo_cohead_void_flag(cohead_id ,r_invdetail.invhist_itemsite_id) FROM
202                     --    (SELECT cohead_id FROM cohead where cohead_number = split_part(r_invdetail.invhist_ordnumber, '-', 1) ) x;
203                     --    
204                     -- SELECT
205                     --        *
206                     --    INTO
207                     --        r_invdetail
208                     --    FROM
209                     --        invdetailview  
210                     --    WHERE
211                     --        invdetail_id    = i_invdetail_id;
212                     --
213                     --
214                 END IF;
215                -- RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
216                --     clock_timestamp() - v_ts_start, i_invdetail_id ;
217                
218                 RETURN v_ret;
219            END IF;
220            
221            
222            IF (r_invdetail.invhist_transtype = 'SH' AND r_invdetail.invhist_ordtype = 'IN' ) THEN
223                 -- CAN BE RETurn from shipping.
224                SELECT  invfifo_update_from_return_invoice(i_invdetail_id, i_update_after)
225                     INTO v_ret;
226                -- RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
227                 --    clock_timestamp() - v_ts_start, i_invdetail_id ;
228                
229                RETURN v_ret;
230            END IF;
231            
232            
233            
234            
235         -- if it's an adjustment...
236                -- then the invhist is really the only tx record of this..
237            
238            IF (r_invdetail.invhist_transtype = 'AD') THEN
239                SELECT  invfifo_update_from_adjustment_in(i_invdetail_id, i_update_after)
240                     INTO v_ret;
241                 --RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
242                 --    clock_timestamp() - v_ts_start, i_invdetail_id ;
243                
244                RETURN v_ret;
245            END IF;
246            
247    
248            RAISE EXCEPTION 'Unknown transtype (IN) %, % %', r_invdetail.invhist_transtype,  r_invdetail.invhist_ordtype , i_invdetail_id;
249            RETURN false;
250        END IF;
251         
252        -- outgoing. 
253         
254         -- are these all based on FIFO values???
255         -- but some 
256         
257         
258         -- if's it's a shipment - record customer id...
259         IF (r_invdetail.invhist_transtype = 'SH' AND r_invdetail.invhist_ordtype='SO') THEN
260             SELECT invfifo_update_from_shipment(i_invdetail_id, i_update_after)
261                  INTO v_ret;
262             --RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
263              --       clock_timestamp() - v_ts_start, i_invdetail_id ;
264                
265             RETURN v_ret;
266         END IF;
267        
268         IF (r_invdetail.invhist_transtype = 'SH' AND r_invdetail.invhist_ordtype='IN') THEN
269            SELECT invfifo_update_from_invoice(i_invdetail_id, i_update_after)
270                 INTO v_ret;
271             --RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
272             --        clock_timestamp() - v_ts_start, i_invdetail_id ;
273                
274             RETURN v_ret;
275         END IF;
276        
277         IF (r_invdetail.invhist_transtype = 'RL') THEN
278             -- this is handled by the transfer in
279             
280             SELECT
281                     invfifo_update_from_transfer_in(invdetail_id,i_update_after)
282                 INTO
283                     v_ret
284                 FROM
285                     invdetailview
286                 WHERE
287                     invhist_id = r_invdetail.invhist_id
288                 AND
289                     invdetail_id != i_invdetail_id;
290         
291           -- PERFORM invfifo_update_from_transfer_out(i_invdetail_id);
292            RETURN 0;
293         END IF;
294         -- return PO inventory..  -- SAME as a void transaction
295         IF (r_invdetail.invhist_transtype = 'RP') THEN
296            
297             
298             if (r_invdetail.invfifo_void < 1) THEN
299                 -- RAISE NOTICE 'performing void flag on ordnumber % , itemsite %', r_invdetail.invhist_ordnumber,  r_invdetail.invhist_itemsite_id;
300                 PERFORM invfifo_pohead_void_flag_order(pohead_id) FROM   pohead where pohead_number =  split_part(r_invdetail.invhist_ordnumber, '-', 1);
301                 
302             END IF;
303             
304             --RAISE EXCEPTION 'need to add rp back';
305            
306             SELECT invfifo_update_from_return_inventory(i_invdetail_id,  i_update_after)
307                 INTO v_ret;
308              --RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
309              --       clock_timestamp() - v_ts_start, i_invdetail_id ;
310                
311             RETURN v_ret;
312         END IF;
313         
314         IF (r_invdetail.invhist_transtype = 'AD') THEN
315             SELECT invfifo_update_from_adjustment_out(i_invdetail_id, i_update_after)
316                  INTO v_ret;
317             --RAISE NOTICE 'TIME: % invfifo_update_from_invdetail (%)',
318              --       clock_timestamp() - v_ts_start, i_invdetail_id ;
319                
320             RETURN v_ret;
321         END IF;
322         -- return from shipping? alwasy
323         IF (r_invdetail.invhist_transtype = 'RS') THEN
324             -- can be
325              
326             -- ignore returned shipment with invalid values?!?!
327             -- these should be voided and not happend.
328             RETURN 0;
329             
330             
331         END IF;
332      
333         RAISE EXCEPTION 'Unknonw transtype (OUT) % , invdetail_id = %',r_invdetail.invhist_transtype, i_invdetail_id ;
334         RETURN 0;
335         
336       
337 END;
338 $BODY$
339   LANGUAGE plpgsql VOLATILE
340   COST 100;
341   
342 ALTER FUNCTION  invfifo_update_from_invdetail(integer,boolean)
343   OWNER TO admin;
344     
345     
346
347 --SELECT invfifo_update_from_invdetail(invdetail_id,true) FROM invdetail order by invdetail_id DESC limit 10;
348
349     
350     
351