pgsql/investigations/ar-cash.sql
[Pman.Xtuple] / pgsql / x-fifo-invfifo-update-from-return-inventory.sql
1 --- updates the invfifo values for shipped and unitcost
2
3 -- purchase order return from shipping.. (note we just pop it of the stack as usual,
4 --even though it affects landed cost, as our landed cost
5 -- is affected by this.
6
7 --  note, we actually need this where single items are returned from shipments..
8  
9
10 CREATE OR REPLACE FUNCTION invfifo_update_from_return_inventory(integer)
11     RETURNS  boolean
12 AS $BODY$
13 DECLARE    
14 i_invdetail_id  ALIAS FOR $1;
15 BEGIN
16     RAISE EXCEPTION 'replaced with option version';
17 END
18 $BODY$
19   LANGUAGE plpgsql VOLATILE
20   COST 100; 
21
22 ----------------------------
23
24 CREATE OR REPLACE FUNCTION invfifo_update_from_return_inventory(integer, boolean)
25     RETURNS  NUMERIC
26 AS $BODY$
27 DECLARE        
28            
29     i_invdetail_id  ALIAS FOR $1;
30     i_update_after ALIAS FOR $2;
31    
32     r_invdetail RECORD;
33     r_invdetail_out RECORD;
34     r_invadj RECORD;
35    
36     v_unitcost  NUMERIC;
37     v_landedcost NUMERIC;
38     v_est_unitcost NUMERIC;
39     v_new_after NUMERIC;
40     v_invfifo_cost_before NUMERIC;
41     v_invfifo_cost_after NUMERIC;
42     v_diff NUMERIC;
43     v_last_id INTEGER;
44     v_vend_id INTEGER;
45     v_pohead_number TEXT;
46   
47 BEGIN
48      
49  
50     SELECT
51             *
52         INTO
53             r_invdetail
54         FROM
55             invdetailview  
56         WHERE
57             invdetail_id    = i_invdetail_id;
58     
59     
60     IF NOT FOUND THEN
61         RAISE EXCEPTION ' invfifo_update_from_return_inventory -- need to add invfifo gen code';
62     END IF;
63     
64      IF (r_invdetail.invhist_transtype != 'RP') THEN
65         RAISE EXCEPTION 'invfifo_update_from_return_inventory called on non-inventory return';
66     END IF;
67     
68     
69     
70       
71     -- fetch the actual purchase price
72     -- it should be the reverse of this.
73     
74     SELECT invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_before) INTO
75         v_invfifo_cost_before;
76     
77     SELECT invfifo_cost_at_qty(r_invdetail.invhist_itemsite_id, r_invdetail.invdetail_location_id, r_invdetail.invfifo_qty_after) INTO
78         v_invfifo_cost_after;
79     
80     
81     --RAISE NOTICE 'cost before is %,  cost after is %',v_invfifo_cost_before, v_invfifo_cost_after;
82     
83     IF v_invfifo_cost_before < 0 THEN
84     
85           SELECT invfifo_cost_before_out(r_invdetail.invfifo_qty_before, r_invdetail.invdetail_location_id ,r_invdetail.invhist_itemsite_id) INTO
86                 v_invfifo_cost_before;
87         
88             v_invfifo_cost_after = v_invfifo_cost_before +
89                     ABS(r_invdetail.invdetail_qty) * r_invdetail.invhist_unitcost;
90           
91     
92          
93     END IF;
94  
95     IF v_invfifo_cost_after <= 0.0 THEN
96         -- we are selling more than we have..
97         -- we should find out what was the last purchase price and use that as the unitcost..
98         v_invfifo_cost_after = v_invfifo_cost_before +
99                     ABS(r_invdetail.invdetail_qty) * r_invdetail.invhist_unitcost;
100     
101     END IF;
102  
103      
104     --RAISE NOTICE 'cost before is %,  cost after is %',v_invfifo_cost_before, v_invfifo_cost_after;
105     v_unitcost = ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty);
106     v_landedcost = ABS((v_invfifo_cost_after - v_invfifo_cost_before) /  r_invdetail.invdetail_qty);
107             
108     IF (
109         r_invdetail.invfifo_unitcost = v_unitcost
110         AND
111         r_invdetail.invfifo_landedunitcost = v_landedcost
112         AND
113         r_invdetail.invfifo_cost_after = v_invfifo_cost_after
114         AND
115         r_invdetail.invfifo_cost_before = v_invfifo_cost_before
116         --- we might need these???
117         --AND
118         --r_invdetail.invfifo_cust_id = v_cust_id
119         --AND
120         --r_invdetail.invfifo_cohead_id = v_cohead_id
121     ) THEN
122         RETURN 0;
123     END IF;
124     
125     
126  
127  
128     UPDATE invfifo
129         SET 
130             invfifo_unitcost = v_unitcost,
131             invfifo_landedunitcost = v_landedcost,
132             invfifo_cost_after = v_invfifo_cost_after,
133             invfifo_cost_before = v_invfifo_cost_before,
134             invfifo_recalc_queued = false
135         WHERE
136             invfifo_invdetail_id = r_invdetail.invdetail_id;
137     
138     v_diff = ROUND(v_invfifo_cost_after - r_invdetail.invfifo_cost_after,2);
139     
140     IF (v_diff = 0.0) THEN
141         RETURN 0;
142     END IF;
143     
144     IF NOT i_update_after THEN
145         RETURN v_diff;
146     END IF;
147     
148     -- update the values after this one..
149      -- FLAG The sales after this date as dirty.?? just in case?
150      
151     UPDATE invfifo
152         SET 
153             invfifo_cost_after = invfifo_cost_after + v_diff,
154             invfifo_cost_before = invfifo_cost_before + v_diff
155             --,
156      --       invfifo_recalc_queued = 1
157       
158         FROM
159             invdetail, invhist           
160            -- unit costs and landed does not change on after..
161         WHERE
162             invfifo_invdetail_id = invdetail_id
163             AND
164             invhist_id = invdetail_invhist_id
165             AND            
166             invdetail_location_id =  r_invdetail.invdetail_location_id 
167             AND
168             invhist_itemsite_id = r_invdetail.invhist_itemsite_id 
169             AND
170             invfifo_qty_after >  r_invdetail.invfifo_qty_after
171             AND
172             invdetail_qty < 0
173             AND
174             invfifo_void = 0;
175      
176      
177     return v_diff;
178  
179 END;
180 $BODY$
181   LANGUAGE plpgsql VOLATILE
182   COST 100;
183   
184 ALTER FUNCTION  invfifo_update_from_return_inventory(integer,boolean)
185   OWNER TO admin;
186