Fix #7123 - getting abra ready to test
[Pman.Xtuple] / Fifo / ProcessValues.php
1 <?php
2
3 /**
4  * fill in any fifo basic entries that have not been processed..
5  * -- does not fill in values.. - just qty's
6  *
7  */
8 require_once 'ProcessBase.php';
9  
10 class Pman_Xtuple_Fifo_ProcessValues extends  Pman_Xtuple_Fifo_ProcessBase
11
12 {
13     static $cli_desc = "Fill in Fifo dollar values. - use /BIG to only do the large ones..";
14    
15     
16     static $cli_opts = array(
17         'send-to' => array(
18             'desc' => 'Send the error report to this email address',
19             'default' => '',
20             'short' => 't',
21             'min' => 0,
22             'max' => 1,
23         )
24     );
25    
26     static $permitError = false;
27     
28     var $loc_only = false;//187; //false;
29     
30     var $efforts = 10;
31     function getAuth()
32     {
33         $ff = HTML_FlexyFramework::get();
34         if (!$ff->cli) {
35             die("run form cli only");
36         }
37          
38     }
39     
40     function get($v = '',$opts)
41     {
42         
43         $this->opts = $opts;
44         // set up the failure code..
45         PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
46         
47         // we have to have a pointer to work out where we left off..
48         // this process can go by invdetail_id ASC..
49         
50         // clear up trailing voided coheads..
51         
52        echo "Finding bad calcs\n";
53         //DB_DataObject::debugLevel(1);
54         $id = DB_DataObject::Factory('invfifo');
55         $id->query("SELECT
56                         distinct(invhist_itemsite_id) as invhist_itemsite_id, invdetail_location_id
57                    FROM
58                         invdetailview
59                    WHERE
60                         ( 
61                                 invfifo_cost_before > invfifo_cost_after
62                             OR
63                                 invfifo_cost_before < 0
64                             OR
65                                 (
66                                     invfifo_cost_before = 0
67                                     and
68                                     invfifo_qty_before > 0
69                                 )
70                             OR
71                                 (
72                                     -- landed unit cost is zero or negative -- when it's not void..
73                                     
74                                    invfifo_landedunitcost <= 0.0
75                                   
76                                 )
77                         )
78                         AND
79                             invfifo_void = 0
80                     GROUP BY invhist_itemsite_id, invdetail_location_id
81             ");
82         
83         $is = array();
84         $bads = array();
85         
86         while ($id->fetch()) {
87             $id->invhist_itemsite_id *=1;
88             if(empty($id->invhist_itemsite_id)){
89                 continue;
90             }
91             $is[] = $id->invhist_itemsite_id ;
92             
93             $bads[] = array(
94                 'itemsite_id' => $id->invhist_itemsite_id,
95                 'location_id' => $id->invdetail_location_id,
96             );
97         }
98         
99         if (count($is)) {
100              echo "Deleting postions on bad calcs\n";
101             $id = DB_DataObject::Factory('invfifo');
102             $id->query("delete from invfifopos where invfifopos_itemsite_id IN (". implode(',', $is) .')');
103         
104         
105         }
106
107         echo "Filling stock level on bad calcs ". count($is) . "\n";
108         
109         
110         foreach ($bads as $bad){
111 //            SELECT invfifo_fill_all(128, 2319)
112             $id = DB_DataObject::Factory('invfifo');
113             $id->query("SELECT invfifo_fill_all({$bad['location_id']}, {$bad['itemsite_id']})");
114             
115         }
116         
117         if ($v == 'BAD') {
118             //DB_DAtaObject::debugLevel(1);
119             $this->efforts =10;
120             echo "running process\n";
121             $this->runStandard($is);
122         
123             die("DONE");
124         }
125         
126         
127        if ($v == 'BIG') {
128             //DB_DAtaObject::debugLevel(1);
129             $id = DB_DataObject::Factory('invfifo');
130             
131             $id->query("SELECT invfifopos_itemsite_id FROM invfifopos WHERE invfifopos_lastadjustment != 0.0 ORDER BY invfifopos_lastadjustment ASC");
132             $is = array();
133             while ($id->fetch()) {
134                 $is[] = $id->invfifopos_itemsite_id;
135             }
136             $id->free();
137             $this->efforts =10;
138             echo "running process\n";
139             $this->runStandard($is);
140         
141             die("DONE");
142        }
143        
144          
145       
146         if ($v == 'RESET') {
147             $id = DB_DataObject::Factory('invfifo');
148             $id->query("delete from invfifopos");
149             $v = '';
150             
151             
152             
153         }
154        
155        
156        
157         
158         if (!empty($v)) {
159             $this->runSingle($v);
160             die("DONE");
161         }
162         
163         $id = DB_DataObject::Factory('invdetail');
164         $id->autoJoin();
165        
166         $id->selectAdd();
167         $id->selectAdd('distinct(join_invhist.invhist_itemsite_id) as itemsite_id');
168         $id->orderBy('join_invhist.invhist_itemsite_id ASC');
169         if (!empty($this->loc_only)) {
170             $id->invdetail_location_id = $this->loc_only;
171         }
172         $id->whereAdd("
173             join_invhist.invhist_itemsite_id IS NOT NULL
174         ");
175         $is = $id->fetchAll('itemsite_id');
176         $id->free();
177         
178         //$this->runTest($is);
179         
180         $this->runStandard($is);
181         
182         die("DONE");
183     }
184     
185     function runStandard($is) {
186         $tot = count($is);
187         
188         $start = time();
189         $id = DB_DataObject::Factory('invdetail');
190         $ftot = $id->count();
191         
192         
193         
194         
195         $fdone = 0;
196         foreach($is as $n=>$itemsite) {
197             
198             // before we do fifo calcs make sure the qty's are correct.
199             
200             $id = DB_DataObject::Factory('invdetail');
201             $id->query(" SELECT invfifo_fill_all_itemsite({$itemsite})  ");
202             
203             
204             
205             
206             $id = DB_DataObject::Factory('invdetail');
207             $id->autoJoin();
208             $id->whereAdd("join_invhist.invhist_itemsite_id = $itemsite");
209             $fdone += $id->count(); // 0.09 seconds.
210             $past = array();
211             for($i = 0; $i< $this->efforts ;$i++) {
212                 $id = DB_DataObject::Factory('invdetail');
213                 
214                 
215                 $id->query("SELECT invfifo_update_from_invdetail_all($itemsite) as result");
216                 $id->fetch();
217                 $res= $id->result;
218                 $id->free();
219                 if (round($res,2) == 0.00 ) {
220                     break;
221                 }
222                 echo ".... $res\n";
223                 $match =0;
224                 for ($pp= 0; $pp < min(10, count($past)) ;$pp++) {
225                     if ($past[$pp]  == $res) {
226                         $match++;
227                         continue;
228                     }
229                     break;
230                 }
231                 if ($match == 10) {
232                     break;
233                 }
234                 array_unshift($past, $res);
235                 
236                 
237                 
238             }
239             //if (!($n % 10)) {
240                 $dur = (time() - $start) / 60;
241                 
242                 $complete = ((($dur/ $fdone) * $ftot) - $dur) / 60;
243                 
244                 $mu = memory_get_usage();
245                 echo "$itemsite - $n/$tot  $fdone/$ftot  " .
246                     "- Memory - $mu | So far : ". number_format($dur,2)."m | est. complet = ". number_format($complete,2)."hours ($res)\n";
247             //}
248             //sleep(1);
249         }
250         
251         $this->sendErr();
252         
253         die("DONE");
254          
255    
256     }
257     
258     function runSingle($itemsite )
259     {
260         //DB_DataObject::debugLevel(1);
261         for($i = 0; $i< 50;$i++) {
262             
263             $itemsite = (int)$itemsite;
264             $start = time();
265             $id = DB_DataObject::Factory('invdetail');
266             echo "SELECT invfifo_update_from_invdetail_all($itemsite) as result\n";
267             $id->query("SELECT invfifo_update_from_invdetail_all($itemsite) as result");
268             $id->fetch();
269             echo "GOT $id->result\n";
270             if (round($id->result,2) == 0.00 ) {
271                 break;
272             }
273         }
274         
275         $this->sendErr();
276         
277         exit;
278         
279    
280     }
281     
282     function sendErr()
283     {
284         if(empty($this->errMsg)){
285             return;
286         }
287         
288         require_once 'Pman/Core/Mailer.php';
289
290         $r = new Pman_Core_Mailer(array(
291             'template'=> 'ProcessValues',
292             'page' => $this,
293             'contents' => array(
294                 'person' => $this->opts['send-to'],
295                 'message' => $this->errMsg
296             )
297         ));
298
299         $sent = $r->send();
300     }
301     
302     
303     // 226619 -- slow..
304     function runTest($is)
305     {
306         //DB_DataObject::debugLevel(1);
307         $tot = count($is);
308         
309         
310         $start = time();
311         $id = DB_DataObject::Factory('invdetail');
312         $ftot = $id->count();
313         
314         // biggies...
315         //1559 
316
317         
318         $fdone = 0;
319         foreach($is as $n=>$itemsite) {
320             
321            // $itemsite = 1559;
322             
323             $id = DB_DataObject::Factory('invdetail');
324             $id->autoJoin();
325             $id->whereAdd("join_invhist.invhist_itemsite_id = $itemsite AND invfifo_void = 0");
326             $id->orderBy('
327                 invhist_transdate ASC,
328                 invdetail_id ASC
329             ');
330             
331             $fdone += $id->count();// 0.001 seconds.
332             $id->selectAdd();
333             $id->selectAdd('invdetail_id');
334             $ids = $id->fetchAll('invdetail_id'); // 0.01
335             
336             
337             
338             foreach($ids as $nn=>$i) {
339                 $st= microtime(true);
340                 $id = DB_DataObject::Factory('invdetail');
341                 $id->query("SELECT invfifo_update_from_invdetail($i)");
342                 $id->free();
343                 if (!($nn % 10)) {
344                     echo "$nn/". count($ids) . "\n";
345                 }
346
347                 $totals[$i] = microtime(true) - $st;
348                //if ($nn > 500) break;
349             }
350             asort($totals);
351             print_r($totals);
352             exit;
353             
354         }
355     
356         
357         die("DONE");
358          
359    
360     }
361     
362 }