Fix #7123 - getting abra ready to test
[Pman.Xtuple] / Import / MagentoOld.php
1 <?php
2
3 require_once 'Pman/Roo.php';
4
5 class Pman_Xtuple_Import_MagentoOld extends Pman_Roo
6 {
7     
8     function getAuth()
9     {
10         if (HTML_FlexyFramework::get()->cli) {
11             $this->authUser = DB_DataObject::Factory('Person');
12             $this->authUser->get('email','brian@bloomandgrowdirect.com');
13             return true;
14         }
15         return parent::getAuth();
16     }
17     
18     var $timer = false;
19     
20     function get()
21     { 
22         ini_set('memory_limit', '1024M'); 
23         $this->sessionState(0); // turn off session..
24        //$this->transObj = DB_DataObject::Factory('coitem');
25         
26 //        $this->transObj->query('BEGIN');
27         
28         PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
29         
30         $this->timer = microtime(true);
31         
32         require_once 'File/Convert.php';
33         
34         $this->debugLog('reading /tmp/magento.csv');
35         $fc = new File_Convert('/tmp/magento.csv', 'text/csv');
36         $content = $fc->convert('text/csv');
37         $this->debugLog('running import CSV');
38         $this->importCsv($content, '');
39         
40     }
41     
42     
43     function debugLog($str)
44     {
45         if (!HTML_FlexyFramework::get()->cli) {
46             return;
47         }
48         static $start = false;
49         if (!$start) {
50             
51             $start = microtime(true);
52         }
53         $timed = microtime(true) - $start;
54         
55     
56         echo number_format($timed/60 ,2, '.',','). 'm MEM:' . number_format(memory_get_usage() /1000000,0, '.',','). 'M : '. $str . "\n";
57
58     }
59     
60     
61     function post( )
62     {
63         ini_set('memory_limit', '512M'); 
64         set_time_limit(0);
65         $this->timer = microtime(true);
66         
67         $this->sessionState(0); // turn off session..
68         //$this->transObj = DB_DataObject::Factory('coitem');
69       
70 //        $this->transObj->query('BEGIN');
71                 
72         PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
73         
74         $img = DB_DataObject::Factory('images');
75         $img->setFrom(array(
76             'onid' => 0,
77             'ontable' => 'ipshead'
78         ));
79         $img->onUpload(false);
80         
81         require_once 'File/Convert.php';
82         $fc = new File_Convert($img->getStoreName(), $img->mimetype );
83         $csv = $fc->convert('text/csv');
84         $this->importCsv($csv);
85     }
86     
87     function importCsv($content, $header = '')
88     {
89         ini_set("auto_detect_line_endings", true);
90         
91         // defaut the header
92         $col = array(
93           'order number', 'order date', 'customer name', 'email', 'billing name', 'address',
94           'city', 'state', 'postalcode', 'country', 'phone', 'ship type', 'unknown1', 'ship note',
95           'signature required', 'weight', 'subtotal', 'freight', 'total', 'tax', 'item name', 'item description',
96           'quantity', 'item total', 'discount', 'payment type', 'unknown2', 'unknown3', 'discount description'
97         );
98         // header from file
99         if(!empty($header)){
100             $col = array();
101             $fh = fopen($header, 'r');
102             if (!$fh) {
103                 $this->jerr("invalid header file");
104             }
105             while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
106                 foreach ($n as $h){
107                     $col[] = strtoupper(trim($h));
108                 } 
109             }
110         }
111         $this->debugLog('reading file');
112         
113         $fh = fopen($content, 'r');
114         if (!$fh) {
115             $this->jerr("invalid content file");
116         
117             
118         }
119         // load customers..
120         
121         $c = DB_DataObject::factory('custinfo');
122         $c->whereAdd("
123             cust_number = 'MGCREDITCARD'
124             OR
125             cust_number= 'MGPAYPAL'
126             OR
127             cust_number = 'MGDEPOSIT'
128         ");
129         
130         $customers = $c->fetchAll('cust_id', 'cust_number');
131         
132         if(count(array_values($customers)) != 3){
133             $this->jerr("error occur on getting MGCREDITCARD, MGPAYPAL and MGDEPOSIT customers". print_R($customers,true));
134         }
135         
136         foreach($customers as $id=>$n) {
137             $rows[$n] = array();
138         }
139         $this->errmsg = array();
140         
141         $no_split = count(file($content)) > 500 ? false : true; // small file just group by customers.. big file group by the first two char of the order number!
142         
143         if (!HTML_FlexyFramework::get()->cli && !$no_split) {
144             $roo->jerr("file is too large to upload - please send to admin to import");
145         }
146         
147         $ln = '';
148         $on = '';
149         $od = false;
150         while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
151             if (!strlen(implode('', $n))) {
152                 continue;
153             }
154             
155             foreach ($col as $k => $c){
156                 $c = strtoupper($c);
157                 if($c == 'ORDER NUMBER'){
158                     if($ln != $n[$k]){
159                         $ln = $n[$k];
160                         $row = 1;
161                     }
162                     $r[$c] = substr($n[$k], -4) * 10000 + $row;
163                     continue;
164                 }
165                 if($c == 'ORDER DATE'){
166                    $r[$c] = date('Y-m-d',strtotime(str_replace('/', '-', $n[$k]))); 
167                    continue;
168                 }
169                 
170                 $r[$c] = $n[$k];
171             }
172             if ($od === false) {
173                 $od = $r['ORDER DATE'];
174             } 
175             if ($od != $r['ORDER DATE']) {
176                 $this->jerr("the file contains orders for multiple days first was $od, found {$r['ORDER DATE']}
177                             - either download again, or remove the extra lines");
178             }
179             
180             $row++;
181             $index = $no_split ? 1 : floor($r['ORDER NUMBER'] / 1000000);
182             
183             if($r['PAYMENT TYPE'] == 'creditcard' || $r['PAYMENT TYPE'] == 'free'){
184                 $rows['MGCREDITCARD'][$index][] = $r;
185                 continue;
186                 
187             }
188             
189             if($r['PAYMENT TYPE'] == 'paypal_express'){
190                 $rows['MGPAYPAL'][$index][] = $r;
191                 continue;
192             }
193             if($r['PAYMENT TYPE'] == 'directdeposit_au'){
194                 $rows['MGDEPOSIT'][$index][] = $r;
195                 continue;
196             }
197             $this->jerr("invalid payment type: "  .$r['PAYMENT TYPE'] );
198             
199         }
200         
201         fclose($fh);
202         
203         $total   = 0.0;
204         $billed = 0.0;
205         
206         foreach($customers as $cid => $cname) {
207             
208             
209             if (empty($rows[$cname])) {
210                 continue;
211             }
212             foreach ($rows[$cname] as $k => $v){
213                 $this->transObj = DB_DataObject::Factory('cohead');
214                 $this->transObj->query('BEGIN');
215                 $this->transObj->lockTables();
216                 list( $ltotal, $lbilled)  = $this->createOrder($cid, $cname, $v, ($no_split) ? '' : ($k));
217                 
218                 if (!empty($this->errmsg)) {
219                     $this->jerr(implode("\n", $this->errmsg));
220                 }
221                 
222                 $this->transObj->query('COMMIT');
223                 $this->transObj = false;
224                 
225                 $GLOBALS['_DB_DATAOBJECT']['RESULTS']   = array();
226                 $GLOBALS['_DB_DATAOBJECT']['RESULTFIELDS'] = array();
227                 
228                 
229                 $total += $ltotal;
230                 $billed += $lbilled;
231             }
232             
233         }
234         
235          
236         $msg = empty($this->ok_message) ? 'data imported successfully' : $this->ok_message;
237
238         $this->addEvent('MAGENTO', false, $msg);
239         
240         $this->jok($msg . ' TOTAL: '. number_format($total,2) . ' BILLED: ' .number_format($billed, 2) . ' Time:' . (microtime(true) - $this->timer) . ' seconds' );
241        
242     }
243     
244     function createOrder($cust_id, $cust_name, $rows, $suffix = '')
245     {
246         
247         $this->debugLog("creating order $cust_name - $suffix");
248         $customer = DB_DataObject::Factory('custinfo');
249         $customer->get($cust_id);
250         $location_id = DB_DataObject::Factory('location')->defaultByItemsite()->itemsite_location_id;
251         
252         if(empty($rows)){
253             $this->warning[] = "No products sold for " . $cust_name;
254             return;
255         }
256         
257         $order_date = $rows[0]['ORDER DATE'];
258         
259         $prefix = array(
260             'MGCREDITCARD' => 'MGC',
261             'MGPAYPAL' => 'MGP',
262             'MGDEPOSIT' => 'MGD',
263             
264         );
265         
266         if(!empty($suffix)){
267             static $oldvoid = array();
268             $nox = $prefix[$cust_name] . str_replace('-', '', $order_date);
269             if (!in_array($nox, $oldvoid)) {
270                 $this->debugLog('void the non-x sales order');
271                 
272                 $co = DB_DataObject::factory('cohead');
273                 if($co->get('cohead_number',$nox)){
274                     $this->voidInvAndShipments($co);
275                     $co->void();
276                 }
277                 
278                 $oldvoid[] = $nox;
279             }
280             $suffix = 'x'.$suffix;
281         }
282         
283         $cohead_number = $prefix[$cust_name] . str_replace('-', '', $order_date) . $suffix;
284         
285         $co = DB_DataObject::factory('cohead');
286         
287         if($co->get('cohead_number',$cohead_number)){
288             
289             $this->voidInvAndShipments($co);
290         
291         } else {
292             
293             $this->debugLog('creating new head');
294             // create cntct if not exists
295             $cntct = array(
296                 'cntct_first_name' => $customer->cust_name,
297                 'cust_id'  =>        $cust_id,
298                 'cntct_active'     => 1,
299                 'cntct_name'       => $customer->cust_name
300             );
301             // simple address for customer..
302             $addr = array(
303                 'addr_active' => 1,
304                 'addr_line1'  => 'Address for ' . $customer->cust_name . ' account'
305             );
306             $cn = $this->checkcntctAndaddr($cntct, $addr);
307
308             if(!$cn->cntct_id){
309                 $this->jerr('error occur on getting the contact of ' . $customer->cust_name);
310             }
311             $sr = $this->authUser->salesrep();
312
313             $co = DB_DataObject::factory('cohead');
314
315             $co->setFrom(array(
316                 'cohead_cust_id'           => $cust_id,
317                 'cohead_number'            => $cohead_number,
318                 'cohead_cust_id_cust_name' => $cust_name,
319                 'cohead_orderdate'         => $order_date,
320                 'cohead_targetdate'        => $order_date,
321                 'cohead_location_src'      => $location_id,
322                 'cohead_terms_id'          => $customer->cust_terms_id,
323                 'cohead_salesrep_id'       => empty($sr->salesrep_id) ? $customer->cust_salesrep_id : $sr->salesrep_id,
324                 'cohead_billto_cntct_id'   => $cn->pid(),
325                 'cohead_shipto_cntct_id'   => $cn->pid(),
326                 'cohead_curr_id'           => $customer->cust_curr_id,
327                 'cohead_taxzone_id'        => $customer->cust_taxzone_id
328                 
329             ));
330
331             foreach($co->defaults() as $k=>$v) {
332                 if (!isset($co->$k)) {
333                     $co->$k = $v;
334                 }
335             }
336
337             $co->insert();
338             $oldco = clone($co);
339             $co->updateAddress();
340             $co->fixMisc();
341             $co->update($oldco);
342             
343         }
344         
345         $this->debugLog('adding lines');
346         $freight = 0.0;
347         $total = 0.0;
348         $total_discount = 0.0;
349         $itemtotal = 0.0;
350         $delivery = 0.0;
351         $billitems = array();
352         $invoice_total = 0.0;
353         $toShipment = array();
354         
355         $totaldiscounted_inctax = 0.0;
356         $rounding = 0.0;
357         $aftertax_line_total = 0.0;
358         
359         $this->debugLog("number of items " . count($rows));
360         foreach ($rows  as $r){
361             
362             // do we have the itme??
363             $i = DB_DataObject::factory('item')->lookupSKU($r['ITEM NAME']);
364             if (!$i) {
365                 $this->errmsg[] = $r['ITEM NAME'] . ' not found';
366                 continue;
367             }
368             
369             // delete the old line numbers..
370             $coitem = DB_DataObject::factory('coitem');
371             if($coitem->get('coitem_linenumber', $r['ORDER NUMBER'])){ // coitem not exist
372                $coitem->delete();    
373             }
374             
375             $coitem = DB_DataObject::factory('coitem');
376             // create the coitem
377             
378             $itemsite = $i->itemsite();
379             if (!$itemsite) {
380                 $this->jerr("product {$i->item_number} has not been created correctly - missing itemsite");
381             }
382             
383             $itemtotal += $r['ITEM TOTAL'];
384             
385             $coitem_custprice = round(($r['ITEM TOTAL'] / $r['QUANTITY']) * (10 / 11) ,3);
386             $base_coitem_custprice  = $coitem_custprice;
387             
388             
389             $aftertax_line_total += round($coitem_custprice * $r['QUANTITY'] * 1.1,2 );
390              
391             // $r['DISCOUNT'] is negative number
392             //if(($r['SUBTOTAL'] - $r['DISCOUNT'] == 0.0) || $r['PAYMENT TYPE'] == 'free' ) {
393             if(($coitem_custprice == 0.0) || ($r['SUBTOTAL'] - $r['DISCOUNT'] == 0.0) || $r['PAYMENT TYPE'] == 'free' ) {
394                 $coitem_price  = 0.0;
395                 
396             } else {
397                 
398                 $coitem_price = $coitem_custprice *    ($r['SUBTOTAL'] / ($r['SUBTOTAL'] - $r['DISCOUNT']));
399                 $coitem_price = round($coitem_price ,3);
400                 
401             }
402             // for rounding tests...
403             
404            
405             $totaldiscounted_inctax +=  ( $r['ITEM TOTAL'] - round($coitem_price * $r['QUANTITY'] * 1.1,2 ));
406              
407             $coitem->setFrom(array(
408                 'coitem_cohead_id'    => $co->pid(),
409                 'coitem_linenumber'   => $r['ORDER NUMBER'],
410                 'coitem_itemsite_id'  => $itemsite->pid(),
411                 'coitem_qtyord'       => $r['QUANTITY'],
412                 'coitem_price'        => $coitem_price,
413                 'coitem_custprice'    => $coitem_custprice, 
414                 'coitem_qtyshipped'   => 0,
415                 'coitem_location_src' => $co->cohead_location_src,
416                 'coitem_shipto_id'    => $co->cohead_shipto_id, // $shipto, 
417                 'coitem_scheddate'    => $r['ORDER DATE']
418             ));
419             foreach($coitem->defaults() as $k=>$v) {
420                 if (empty($coitem->$k)) {
421                     $coitem->$k = $v;
422                 }
423             }
424             $coitem->insert();
425             
426             if(!$coitem->coitem_id){
427                 $this->errmsg[] = $r['ITEM NAME'] . ' error occur on insert';
428                 continue;
429             }
430            
431             
432             $toShipment[$coitem->pid()] = $coitem;
433             
434             if(substr($r['ORDER NUMBER'],-4,4) == 1){ 
435                 $total    +=  $r['TOTAL'] ;
436                 $total_discount += $r['DISCOUNT'] ;
437                 
438                 if ( $r['PAYMENT TYPE'] == 'free' ) {
439                     $r['FREIGHT']  = 0.0;
440                 }
441                 $freight  +=  ($r['FREIGHT'] * 1.0);
442                 $delivery +=  ($r['FREIGHT'] * 10 / 11);
443             }
444             
445             $x = array();
446             $x['cobill_coitem_id'] = $coitem->pid();
447             $x['cobill_qty'] = $coitem->coitem_qtyord;
448             
449             $billitems[] = (object)$x;
450             
451             $invoice_total +=  round($coitem->coitem_qtyord * $coitem->coitem_price,2);
452             
453              
454             
455         }
456         
457         if (!empty($this->errmsg)) {
458             return false;
459         }
460         
461         // last row - create shipment...
462         
463         if(count($toShipment)){
464             $d = array(
465                 'curr'    => $co->cohead_curr_id
466             );
467             $this->orderShipments($toShipment,$d);
468             
469         }
470         
471         $this->debugLog('sorting out discounts');
472         
473         $coitem = DB_DataObject::factory('coitem');
474         $coitem->get('coitem_cohead_id', $co->pid());
475         if($coitem->find(true)){
476             $coitem->updatePretaxDiscount($this); 
477         }
478         
479         if ($delivery > 0) {
480             $this->debugLog('sorting out delivery');
481             // make the rounding here..
482             $delivery = $freight * (10/11);
483             
484             $i = dB_DataObject::Factory('item');
485             if (!$i->get('item_number', 'Z-DELIVERY CHARGE')) { 
486                 $this->jerr("delivery charge not found");
487             }
488             $itemsite = $i->itemsite();
489             
490             // add z-Delivery Charge coz it's taxable
491             $coitem = DB_DataObject::factory('coitem');
492             $coitem->coitem_cohead_id = $co->pid();
493             $coitem->coitem_itemsite_id = $itemsite->pid();
494             $coitem->coitem_linenumber = 9999998;
495             if (!$coitem->find(true)) {
496             
497                     $coitem->setFrom(array(
498                         'coitem_cohead_id'    => $co->pid(),
499                         'coitem_linenumber'   => 9999998, // need a line number..
500                         'coitem_itemsite_id'  => $coitem->coitem_itemsite_id,
501                         'coitem_qtyord'       => 1,
502                         'coitem_price'        => round($delivery,3),
503                         'coitem_custprice'    => round($delivery,3),
504                         'coitem_qtyshipped'   => 0,
505                         'coitem_location_src' => $co->cohead_location_src,
506                         'coitem_shipto_id'    => $co->cohead_shipto_id, // $shipto, 
507                         'coitem_scheddate'    => $order_date
508                     ));
509                 
510                 foreach($coitem->defaults() as $k=>$v) {
511                     if (empty($coitem->$k)) {
512                         $coitem->$k = $v;
513                     }
514                 }
515                 $coitem->insert();
516             } else {
517                 $co_old = clone($coitem);
518                 $coitem->setFrom(array(
519                     'coitem_price'        => round($delivery,3),
520                     'coitem_custprice'    => round($delivery,3),
521                     'coitem_location_src' => $co->cohead_location_src,
522                     'coitem_shipto_id'    => $co->cohead_shipto_id, // $shipto, 
523                     'coitem_scheddate'    => $order_date
524                 ));
525                 $coitem->update($co_old);
526                 
527                 
528             }
529             // add freigth total to invoice..
530             $invoice_total +=  round($delivery,2) ;
531             
532              
533             $x = array();
534             $x['cobill_coitem_id'] = $coitem->pid();
535             $x['cobill_qty'] = $coitem->coitem_qtyord;
536             
537             $billitems[] = (object)$x;
538             
539             
540         }
541        
542         
543         $i = DB_DataObject::Factory('item');
544         if (!$i->get('item_number', 'Z-LIST-DISCOUNT')) { 
545             $this->jerr("Z-LIST-DISCOUNT not found");
546         }
547         $itemsite = $i->itemsite();
548         
549         $coitem = DB_DataObject::factory('coitem');
550         $coitem->coitem_cohead_id = $co->pid();
551         $coitem->coitem_itemsite_id = $itemsite->pid();
552         if($coitem->find(true)){
553             $x = array();
554             $x['cobill_coitem_id'] = $coitem->pid();
555             $x['cobill_qty'] = $coitem->coitem_qtyord;
556             
557             $billitems[] = (object)$x;
558             $invoice_total = $invoice_total + ($coitem->coitem_qtyord * $coitem->coitem_price);
559             
560             $co_old = clone ($co);
561             $co->setFrom(array(
562                 'cohead_misc' => $coitem->coitem_qtyord * $coitem->coitem_price * -1,
563                 'cohead_misc_descript' => 'DISCOUNT'
564             ));
565             $co->update($co_old);
566         }
567         
568         
569         $cobapply_list = array();
570         // check gift voucher
571         
572         $gift = $itemtotal + $freight - $total + $total_discount;
573         
574         if(false && $gift > 5){ // check credit memo
575             
576             $cmhead = DB_DataObject::factory('cmhead');
577             $cmhead->setFrom(array(
578                 'cmhead_number'          => $cmhead->nextNumber(),
579                 'cmhead_cust_id'         => $co->cohead_cust_id,
580                 'cmhead_billto_cntct_id' => $co->cohead_billto_cntct_id,
581                 'cmhead_taxzone_id'      => $co->cohead_taxzone_id,
582                 'cmhead_curr_id'         => $co->cohead_curr_id,
583                 'cmhead_salesrep_id'     => $co->cohead_salesrep_id,
584                 'cmhead_docdate'         => $co->cohead_targetdate,
585                 'cmhead_location_id'     => $co->cohead_location_src
586             ));
587             
588             foreach($cmhead->defaults() as $k=>$v) {
589                 if (empty($cmhead->$k)) {
590                     $cmhead->$k = $v;
591                 }
592             }
593             
594             $cmhead->insert();
595             
596             if(!$cmhead->pid()){
597                 $this->jerr('error occur on insert a credit memo');
598             }
599             
600             $i = dB_DataObject::Factory('item');
601             if (!$i->get('item_number', 'Z-DISCOUNT-VOUCHER')) { 
602                 $this->jerr("Z-DISCOUNT-VOUCHER not found");
603             }
604             $itemsite = $i->itemsite();
605             
606             $cmitem = DB_DataObject::factory('cmitem');
607             $cmitem->setFrom(array(
608                 'cmitem_cmhead_id' => $cmhead->pid(),
609                 'cmitem_linenumber' => 999997,
610                 'cmitem_itemsite_id' => $itemsite->pid(),
611                 'cmitem_qtycredit' => 1,
612                 'cmitem_qtyreturned' => 1,
613                 'cmitem_unitprice' => $gift,
614                 'cmitem_taxtype_id' => $cmitem->sqlValue("gettaxtypeid('Taxable'::text)"),
615                 'cmitem_comments' => $i->item_descrip1,
616             ));
617             
618             foreach($cmitem->defaults() as $k=>$v) {
619                 if (empty($cmitem->$k)) {
620                     $cmitem->$k = $v;
621                 }
622             }
623             $cmitem->insert();
624             
625             if(!$cmitem->pid()){
626                 $this->jerr('error occur on insert Z-DISCOUNT-VOUCHER to credit memo');
627             }
628             
629             $cmhead->post($this);
630             
631             $aropen = DB_DataObject::factory('aropen');
632             $aropen->aropen_cust_id = $customer->pid();
633             $aropen->aropen_doctype = 'C';
634             $aropen->aropen_docnumber = $cmhead->cmhead_number;
635             $cobapply_list = $aropen->fetchAll('aropen_id');
636             if(count($cobapply_list) != 1){
637                 $this->jerr('error occur on getting aropen');
638             }
639              
640         }
641         
642         $this->debugLog('creating bill');
643         
644         // create the invoice for each magento order
645         $cobmisc = DB_DataObject::factory('cobmisc');
646         
647         $cobmisc->setFrom(array(
648             'cobmisc_cohead_id' => $co->pid(),
649             'cobmisc_invcdate'  => $order_date,
650             'cobmisc_shipdate'  => $order_date
651         ));
652         
653         $cobmisc->cobmisc_taxtype_id = $cobmisc->sqlValue("gettaxtypeid('Taxable'::text)");
654         $cobmisc->fixMisc();
655         
656         $t = $cobmisc->factory('cobmisc');
657         $t->query("SELECT createBillingHeader({$co->pid()}) AS cobmisc_id");
658         $t->fetch();
659         
660         $cobmisc->cobmisc_id = $t->cobmisc_id;
661         $cobmisc->updateItems($billitems);
662         
663         // apply the credit memo..
664         if (!empty($cobapply_list)) {
665            $cobmisc->updateCobApply($this,$cobapply_list);
666         }
667         
668         // post the bill.
669         
670         $t = $cobmisc->factory('cobmisc');
671         $t->get($cobmisc->cobmisc_id);
672         $t->post($this);
673         
674         // fetch again so it should have invoice..
675         $t = $cobmisc->factory('cobmisc');
676         $t->get($cobmisc->cobmisc_id);
677         
678         $invoice = $t->invchead();
679         
680         $aropen = $invoice->aropen();
681         
682         
683         /*
684         if (round($total,2) != round($aropen->aropen_amount,2)) {
685             $this->jerr("TOTAL $total != {$aropen->aropen_amount}" .
686                     print_r(array(
687                         'itemtotal' => $itemtotal,
688                         'aftertax_line_total' => $aftertax_line_total,
689                         
690                         'total_discount' => $total_discount,
691                         'freight' => $freight,
692                         
693                         
694                         'totaldiscounted_inctax' => $totaldiscounted_inctax,
695                         'totaldiscounted_b4tax' => $totaldiscounted_inctax * (10/11),
696                         'freight_b4tax' => $freight * (10/11),
697                         
698                 ),true));
699         }
700         */
701         //print_R($aropen);$this->jerr("fixme");
702         
703         return array( $total, $aropen->aropen_amount);
704         
705     }
706     
707     function checkcntctAndaddr($cntct,$addrs)
708     {
709         $cn = DB_DataObject::factory('cntct');
710
711         if(!$cn->get('cntct_first_name', $cntct['cntct_first_name'])){ // contact not exists
712             $cn->setFrom($cntct);
713             $cn->cntct_crmacct_id = $cn->sqlValue("(SELECT crmacct_id FROM crmacct WHERE crmacct_cust_id = {$cntct['cust_id']})");
714             $cn->genNumber();
715             $cn->insert();
716         }
717
718         if(!$cn->cntct_addr_id){ // addr not exists
719             $addr = DB_DataObject::Factory('addr');
720             $addr->setFrom($addrs);
721             $addr->genNumber();
722             $addr->insert();
723
724             $oldcn = clone($cn);
725             $cn->cntct_addr_id = $addr->pid();
726             $cn->update($oldcn);
727
728         }
729         
730         return $cn;
731     }
732     
733     function checkshiptoinfo($customer, $cntct)
734     {
735         $sh = DB_DataObject::Factory('shiptoinfo');
736         $sh->shipto_cntct_id = $cntct->pid();
737         $sh->shipto_addr_id = $cntct->cntct_addr_id;
738         if ($sh->find(true)) {
739             return $sh->pid();
740         }
741         
742         $sh->setFrom(array(
743             'shipto_cust_id' => $cust_id,
744             'shipto_name' => $cntct->cntct_name,
745             'shipto_salesrep_id'=> $customer->cust_salesrep_id,
746             'shipto_active' => true,
747             'shipto_adefault' => false,
748             'shipto_shipchrg_id' => $customer->cust_shipchrg_id,
749             'shipto_taxzone_id' => $customer->cust_taxzone_id,
750             'shipto_shipform_id' => $customer->cust_shipform_id,
751             'shipto_commission' => 0,
752             'shipto_shipzone_id' => $customer->cust_taxzone_id
753
754         ));
755         $sh->genNum();
756         $sh->insert();
757         
758         return $sh->pid();
759         
760     }
761     
762     function orderShipments($toShipments,$d)
763     {
764         $this->debugLog('creating shipments');
765         
766         $ids = array_keys($toShipments);
767         $c = array_pop($toShipments);
768         
769         $cc = DB_DataObject::factory('coitem');
770         $cc->coitem_cohead_id = $c->coitem_cohead_id;
771         $cc->find();
772         
773         $x = array();
774         $shipitems = array();
775         while ($cc->fetch()){ // this query will take about 6 secs...
776             
777             $itemsite = $cc->itemsite();
778             // skip non-stock items..
779             if (!$itemsite->itemsite_stocked) {
780                 continue;
781             }
782             
783             $x['shipitem_orderitem_id'] = $cc->pid();
784             $x['shipitem_qty'] = 0;
785             if(in_array($cc->pid(), $ids)){
786                 $x['shipitem_qty'] = $cc->coitem_qtyord;
787             }
788             $shipitems[] = (object)$x;
789         }
790         
791         $sh = DB_DataObject::factory('shiphead');
792         
793         
794         
795         $sh->setFrom(array(
796             'shiphead_shipdate'        => $c->coitem_scheddate,
797             'shiphead_order_id'        => $c->coitem_cohead_id,
798             'shiphead_sfstatus'        => 'N',
799             'shiphead_location_id'     => $c->coitem_location_src,
800             'shiphead_shipto_id'       => $c->coitem_shipto_id,
801             //'shiphead_number'          => $cohead->cohead_number . substr($c->coitem_linenumber, 0, 4),
802             'shiphead_order_type'      => 'SO',
803             'shiphead_freight'         => 0, //$d['freight'],
804             'shiphead_freight_curr_id' => $d['curr'],
805             'shiphead_notes'           => '' // $r['SHIP NOTE']
806         ));
807         $sh->beforeInsert(array('shiphead_number' => 'Automatic'),$this);
808         //$this->jerr("about to create shipment: " . $sh->shiphead_number);
809         
810         $sh->insert();
811         
812         $sh->updateItems($shipitems, $this); 
813         
814         $sh->confirm($this); 
815     }
816     
817     function voidInvAndShipments($co)
818     {
819         $this->debugLog('deelting old invoices / shipments');
820         $invoices  = $co->cobmiscs();
821
822         foreach($invoices as $i) {
823             $i->void($this, true);
824         }
825
826         // do it twice..
827         $invoices  = $co->cobmiscs();
828         foreach($invoices as $i) {
829             $i->void($this,true);
830         }
831         // delete the shipments...
832         $shipheads = $co->shipheads();
833
834         foreach($shipheads  as $s) {
835
836             if (!empty($s->shiphead_shipped) && !empty($s->shiphead_shipdate)) {
837                 $res = $s->unconfirm($this,true);
838
839                 if ($res !== true) {
840                     $this->jerr("ship unconfirm failed:" . $res);
841                 }
842             }
843
844             if (!empty($s->shiphead_shipdate)) { // 395.43042492867 secs...
845                 $res = $s->void($this,true);    // void shipitem will take 0.1 sec for each... a little bit long time...
846
847                 if ($res !== true) {
848                     $this->jerr("ship voiding failed" . $res)  ;
849                 }
850             }
851         }
852     }
853     //B_45 not found
854     //B_12 not found
855     //B_1 not found
856     //B_11 not found
857     
858     // 210203 not found
859     // 212103 not found
860     // Gift Wrapping not found
861     // Gift Wrapping not found
862     // 212204 not found
863     // Gift Wrapping not found
864     
865     
866 }