cli) { $this->authUser = DB_DataObject::Factory('Person'); $this->authUser->get('email','brian@bloomandgrowdirect.com'); return true; } return parent::getAuth(); } var $timer = false; function get() { ini_set('memory_limit', '1024M'); $this->sessionState(0); // turn off session.. //$this->transObj = DB_DataObject::Factory('coitem'); // $this->transObj->query('BEGIN'); PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError')); $this->timer = microtime(true); require_once 'File/Convert.php'; $this->debugLog('reading /tmp/magento.csv'); $fc = new File_Convert('/tmp/magento.csv', 'text/csv'); $content = $fc->convert('text/csv'); $this->debugLog('running import CSV'); $this->importCsv($content, ''); } function debugLog($str) { if (!HTML_FlexyFramework::get()->cli) { return; } static $start = false; if (!$start) { $start = microtime(true); } $timed = microtime(true) - $start; echo number_format($timed/60 ,2, '.',','). 'm MEM:' . number_format(memory_get_usage() /1000000,0, '.',','). 'M : '. $str . "\n"; } function post( ) { ini_set('memory_limit', '512M'); set_time_limit(0); $this->timer = microtime(true); $this->sessionState(0); // turn off session.. //$this->transObj = DB_DataObject::Factory('coitem'); // $this->transObj->query('BEGIN'); PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError')); $img = DB_DataObject::Factory('images'); $img->setFrom(array( 'onid' => 0, 'ontable' => 'ipshead' )); $img->onUpload(false); require_once 'File/Convert.php'; $fc = new File_Convert($img->getStoreName(), $img->mimetype ); $csv = $fc->convert('text/csv'); $this->importCsv($csv); } function importCsv($content, $header = '') { ini_set("auto_detect_line_endings", true); // defaut the header $col = array( 'order number', 'order date', 'customer name', 'email', 'billing name', 'address', 'city', 'state', 'postalcode', 'country', 'phone', 'ship type', 'unknown1', 'ship note', 'signature required', 'weight', 'subtotal', 'freight', 'total', 'tax', 'item name', 'item description', 'quantity', 'item total', 'discount', 'payment type', 'unknown2', 'unknown3', 'discount description' ); // header from file if(!empty($header)){ $col = array(); $fh = fopen($header, 'r'); if (!$fh) { $this->jerr("invalid header file"); } while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) { foreach ($n as $h){ $col[] = strtoupper(trim($h)); } } } $this->debugLog('reading file'); $fh = fopen($content, 'r'); if (!$fh) { $this->jerr("invalid content file"); } // load customers.. $c = DB_DataObject::factory('custinfo'); $c->whereAdd(" cust_number = 'MGCREDITCARD' OR cust_number= 'MGPAYPAL' OR cust_number = 'MGDEPOSIT' "); $customers = $c->fetchAll('cust_id', 'cust_number'); if(count(array_values($customers)) != 3){ $this->jerr("error occur on getting MGCREDITCARD, MGPAYPAL and MGDEPOSIT customers". print_R($customers,true)); } foreach($customers as $id=>$n) { $rows[$n] = array(); } $this->errmsg = array(); $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! if (!HTML_FlexyFramework::get()->cli && !$no_split) { $roo->jerr("file is too large to upload - please send to admin to import"); } $ln = ''; $on = ''; $od = false; while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) { if (!strlen(implode('', $n))) { continue; } foreach ($col as $k => $c){ $c = strtoupper($c); if($c == 'ORDER NUMBER'){ if($ln != $n[$k]){ $ln = $n[$k]; $row = 1; } $r[$c] = substr($n[$k], -4) * 10000 + $row; continue; } if($c == 'ORDER DATE'){ $r[$c] = date('Y-m-d',strtotime(str_replace('/', '-', $n[$k]))); continue; } $r[$c] = $n[$k]; } if ($od === false) { $od = $r['ORDER DATE']; } if ($od != $r['ORDER DATE']) { $this->jerr("the file contains orders for multiple days first was $od, found {$r['ORDER DATE']} - either download again, or remove the extra lines"); } $row++; $index = $no_split ? 1 : floor($r['ORDER NUMBER'] / 1000000); if($r['PAYMENT TYPE'] == 'creditcard' || $r['PAYMENT TYPE'] == 'free'){ $rows['MGCREDITCARD'][$index][] = $r; continue; } if($r['PAYMENT TYPE'] == 'paypal_express'){ $rows['MGPAYPAL'][$index][] = $r; continue; } if($r['PAYMENT TYPE'] == 'directdeposit_au'){ $rows['MGDEPOSIT'][$index][] = $r; continue; } $this->jerr("invalid payment type: " .$r['PAYMENT TYPE'] ); } fclose($fh); $total = 0.0; $billed = 0.0; foreach($customers as $cid => $cname) { if (empty($rows[$cname])) { continue; } foreach ($rows[$cname] as $k => $v){ $this->transObj = DB_DataObject::Factory('cohead'); $this->transObj->query('BEGIN'); $this->transObj->lockTables(); list( $ltotal, $lbilled) = $this->createOrder($cid, $cname, $v, ($no_split) ? '' : ($k)); if (!empty($this->errmsg)) { $this->jerr(implode("\n", $this->errmsg)); } $this->transObj->query('COMMIT'); $this->transObj = false; $GLOBALS['_DB_DATAOBJECT']['RESULTS'] = array(); $GLOBALS['_DB_DATAOBJECT']['RESULTFIELDS'] = array(); $total += $ltotal; $billed += $lbilled; } } $msg = empty($this->ok_message) ? 'data imported successfully' : $this->ok_message; $this->addEvent('MAGENTO', false, $msg); $this->jok($msg . ' TOTAL: '. number_format($total,2) . ' BILLED: ' .number_format($billed, 2) . ' Time:' . (microtime(true) - $this->timer) . ' seconds' ); } function createOrder($cust_id, $cust_name, $rows, $suffix = '') { $this->debugLog("creating order $cust_name - $suffix"); $customer = DB_DataObject::Factory('custinfo'); $customer->get($cust_id); $location_id = DB_DataObject::Factory('location')->defaultByItemsite()->itemsite_location_id; if(empty($rows)){ $this->warning[] = "No products sold for " . $cust_name; return; } $order_date = $rows[0]['ORDER DATE']; $prefix = array( 'MGCREDITCARD' => 'MGC', 'MGPAYPAL' => 'MGP', 'MGDEPOSIT' => 'MGD', ); if(!empty($suffix)){ static $oldvoid = array(); $nox = $prefix[$cust_name] . str_replace('-', '', $order_date); if (!in_array($nox, $oldvoid)) { $this->debugLog('void the non-x sales order'); $co = DB_DataObject::factory('cohead'); if($co->get('cohead_number',$nox)){ $this->voidInvAndShipments($co); $co->void(); } $oldvoid[] = $nox; } $suffix = 'x'.$suffix; } $cohead_number = $prefix[$cust_name] . str_replace('-', '', $order_date) . $suffix; $co = DB_DataObject::factory('cohead'); if($co->get('cohead_number',$cohead_number)){ $this->voidInvAndShipments($co); } else { $this->debugLog('creating new head'); // create cntct if not exists $cntct = array( 'cntct_first_name' => $customer->cust_name, 'cust_id' => $cust_id, 'cntct_active' => 1, 'cntct_name' => $customer->cust_name ); // simple address for customer.. $addr = array( 'addr_active' => 1, 'addr_line1' => 'Address for ' . $customer->cust_name . ' account' ); $cn = $this->checkcntctAndaddr($cntct, $addr); if(!$cn->cntct_id){ $this->jerr('error occur on getting the contact of ' . $customer->cust_name); } $sr = $this->authUser->salesrep(); $co = DB_DataObject::factory('cohead'); $co->setFrom(array( 'cohead_cust_id' => $cust_id, 'cohead_number' => $cohead_number, 'cohead_cust_id_cust_name' => $cust_name, 'cohead_orderdate' => $order_date, 'cohead_targetdate' => $order_date, 'cohead_location_src' => $location_id, 'cohead_terms_id' => $customer->cust_terms_id, 'cohead_salesrep_id' => empty($sr->salesrep_id) ? $customer->cust_salesrep_id : $sr->salesrep_id, 'cohead_billto_cntct_id' => $cn->pid(), 'cohead_shipto_cntct_id' => $cn->pid(), 'cohead_curr_id' => $customer->cust_curr_id, 'cohead_taxzone_id' => $customer->cust_taxzone_id )); foreach($co->defaults() as $k=>$v) { if (!isset($co->$k)) { $co->$k = $v; } } $co->insert(); $oldco = clone($co); $co->updateAddress(); $co->fixMisc(); $co->update($oldco); } $this->debugLog('adding lines'); $freight = 0.0; $total = 0.0; $total_discount = 0.0; $itemtotal = 0.0; $delivery = 0.0; $billitems = array(); $invoice_total = 0.0; $toShipment = array(); $totaldiscounted_inctax = 0.0; $rounding = 0.0; $aftertax_line_total = 0.0; $this->debugLog("number of items " . count($rows)); foreach ($rows as $r){ // do we have the itme?? $i = DB_DataObject::factory('item')->lookupSKU($r['ITEM NAME']); if (!$i) { $this->errmsg[] = $r['ITEM NAME'] . ' not found'; continue; } // delete the old line numbers.. $coitem = DB_DataObject::factory('coitem'); if($coitem->get('coitem_linenumber', $r['ORDER NUMBER'])){ // coitem not exist $coitem->delete(); } $coitem = DB_DataObject::factory('coitem'); // create the coitem $itemsite = $i->itemsite(); if (!$itemsite) { $this->jerr("product {$i->item_number} has not been created correctly - missing itemsite"); } $itemtotal += $r['ITEM TOTAL']; $coitem_custprice = round(($r['ITEM TOTAL'] / $r['QUANTITY']) * (10 / 11) ,3); $base_coitem_custprice = $coitem_custprice; $aftertax_line_total += round($coitem_custprice * $r['QUANTITY'] * 1.1,2 ); // $r['DISCOUNT'] is negative number //if(($r['SUBTOTAL'] - $r['DISCOUNT'] == 0.0) || $r['PAYMENT TYPE'] == 'free' ) { if(($coitem_custprice == 0.0) || ($r['SUBTOTAL'] - $r['DISCOUNT'] == 0.0) || $r['PAYMENT TYPE'] == 'free' ) { $coitem_price = 0.0; } else { $coitem_price = $coitem_custprice * ($r['SUBTOTAL'] / ($r['SUBTOTAL'] - $r['DISCOUNT'])); $coitem_price = round($coitem_price ,3); } // for rounding tests... $totaldiscounted_inctax += ( $r['ITEM TOTAL'] - round($coitem_price * $r['QUANTITY'] * 1.1,2 )); $coitem->setFrom(array( 'coitem_cohead_id' => $co->pid(), 'coitem_linenumber' => $r['ORDER NUMBER'], 'coitem_itemsite_id' => $itemsite->pid(), 'coitem_qtyord' => $r['QUANTITY'], 'coitem_price' => $coitem_price, 'coitem_custprice' => $coitem_custprice, 'coitem_qtyshipped' => 0, 'coitem_location_src' => $co->cohead_location_src, 'coitem_shipto_id' => $co->cohead_shipto_id, // $shipto, 'coitem_scheddate' => $r['ORDER DATE'] )); foreach($coitem->defaults() as $k=>$v) { if (empty($coitem->$k)) { $coitem->$k = $v; } } $coitem->insert(); if(!$coitem->coitem_id){ $this->errmsg[] = $r['ITEM NAME'] . ' error occur on insert'; continue; } $toShipment[$coitem->pid()] = $coitem; if(substr($r['ORDER NUMBER'],-4,4) == 1){ $total += $r['TOTAL'] ; $total_discount += $r['DISCOUNT'] ; if ( $r['PAYMENT TYPE'] == 'free' ) { $r['FREIGHT'] = 0.0; } $freight += ($r['FREIGHT'] * 1.0); $delivery += ($r['FREIGHT'] * 10 / 11); } $x = array(); $x['cobill_coitem_id'] = $coitem->pid(); $x['cobill_qty'] = $coitem->coitem_qtyord; $billitems[] = (object)$x; $invoice_total += round($coitem->coitem_qtyord * $coitem->coitem_price,2); } if (!empty($this->errmsg)) { return false; } // last row - create shipment... if(count($toShipment)){ $d = array( 'curr' => $co->cohead_curr_id ); $this->orderShipments($toShipment,$d); } $this->debugLog('sorting out discounts'); $coitem = DB_DataObject::factory('coitem'); $coitem->get('coitem_cohead_id', $co->pid()); if($coitem->find(true)){ $coitem->updatePretaxDiscount($this); } if ($delivery > 0) { $this->debugLog('sorting out delivery'); // make the rounding here.. $delivery = $freight * (10/11); $i = dB_DataObject::Factory('item'); if (!$i->get('item_number', 'Z-DELIVERY CHARGE')) { $this->jerr("delivery charge not found"); } $itemsite = $i->itemsite(); // add z-Delivery Charge coz it's taxable $coitem = DB_DataObject::factory('coitem'); $coitem->coitem_cohead_id = $co->pid(); $coitem->coitem_itemsite_id = $itemsite->pid(); $coitem->coitem_linenumber = 9999998; if (!$coitem->find(true)) { $coitem->setFrom(array( 'coitem_cohead_id' => $co->pid(), 'coitem_linenumber' => 9999998, // need a line number.. 'coitem_itemsite_id' => $coitem->coitem_itemsite_id, 'coitem_qtyord' => 1, 'coitem_price' => round($delivery,3), 'coitem_custprice' => round($delivery,3), 'coitem_qtyshipped' => 0, 'coitem_location_src' => $co->cohead_location_src, 'coitem_shipto_id' => $co->cohead_shipto_id, // $shipto, 'coitem_scheddate' => $order_date )); foreach($coitem->defaults() as $k=>$v) { if (empty($coitem->$k)) { $coitem->$k = $v; } } $coitem->insert(); } else { $co_old = clone($coitem); $coitem->setFrom(array( 'coitem_price' => round($delivery,3), 'coitem_custprice' => round($delivery,3), 'coitem_location_src' => $co->cohead_location_src, 'coitem_shipto_id' => $co->cohead_shipto_id, // $shipto, 'coitem_scheddate' => $order_date )); $coitem->update($co_old); } // add freigth total to invoice.. $invoice_total += round($delivery,2) ; $x = array(); $x['cobill_coitem_id'] = $coitem->pid(); $x['cobill_qty'] = $coitem->coitem_qtyord; $billitems[] = (object)$x; } $i = DB_DataObject::Factory('item'); if (!$i->get('item_number', 'Z-LIST-DISCOUNT')) { $this->jerr("Z-LIST-DISCOUNT not found"); } $itemsite = $i->itemsite(); $coitem = DB_DataObject::factory('coitem'); $coitem->coitem_cohead_id = $co->pid(); $coitem->coitem_itemsite_id = $itemsite->pid(); if($coitem->find(true)){ $x = array(); $x['cobill_coitem_id'] = $coitem->pid(); $x['cobill_qty'] = $coitem->coitem_qtyord; $billitems[] = (object)$x; $invoice_total = $invoice_total + ($coitem->coitem_qtyord * $coitem->coitem_price); $co_old = clone ($co); $co->setFrom(array( 'cohead_misc' => $coitem->coitem_qtyord * $coitem->coitem_price * -1, 'cohead_misc_descript' => 'DISCOUNT' )); $co->update($co_old); } $cobapply_list = array(); // check gift voucher $gift = $itemtotal + $freight - $total + $total_discount; if(false && $gift > 5){ // check credit memo $cmhead = DB_DataObject::factory('cmhead'); $cmhead->setFrom(array( 'cmhead_number' => $cmhead->nextNumber(), 'cmhead_cust_id' => $co->cohead_cust_id, 'cmhead_billto_cntct_id' => $co->cohead_billto_cntct_id, 'cmhead_taxzone_id' => $co->cohead_taxzone_id, 'cmhead_curr_id' => $co->cohead_curr_id, 'cmhead_salesrep_id' => $co->cohead_salesrep_id, 'cmhead_docdate' => $co->cohead_targetdate, 'cmhead_location_id' => $co->cohead_location_src )); foreach($cmhead->defaults() as $k=>$v) { if (empty($cmhead->$k)) { $cmhead->$k = $v; } } $cmhead->insert(); if(!$cmhead->pid()){ $this->jerr('error occur on insert a credit memo'); } $i = dB_DataObject::Factory('item'); if (!$i->get('item_number', 'Z-DISCOUNT-VOUCHER')) { $this->jerr("Z-DISCOUNT-VOUCHER not found"); } $itemsite = $i->itemsite(); $cmitem = DB_DataObject::factory('cmitem'); $cmitem->setFrom(array( 'cmitem_cmhead_id' => $cmhead->pid(), 'cmitem_linenumber' => 999997, 'cmitem_itemsite_id' => $itemsite->pid(), 'cmitem_qtycredit' => 1, 'cmitem_qtyreturned' => 1, 'cmitem_unitprice' => $gift, 'cmitem_taxtype_id' => $cmitem->sqlValue("gettaxtypeid('Taxable'::text)"), 'cmitem_comments' => $i->item_descrip1, )); foreach($cmitem->defaults() as $k=>$v) { if (empty($cmitem->$k)) { $cmitem->$k = $v; } } $cmitem->insert(); if(!$cmitem->pid()){ $this->jerr('error occur on insert Z-DISCOUNT-VOUCHER to credit memo'); } $cmhead->post($this); $aropen = DB_DataObject::factory('aropen'); $aropen->aropen_cust_id = $customer->pid(); $aropen->aropen_doctype = 'C'; $aropen->aropen_docnumber = $cmhead->cmhead_number; $cobapply_list = $aropen->fetchAll('aropen_id'); if(count($cobapply_list) != 1){ $this->jerr('error occur on getting aropen'); } } $this->debugLog('creating bill'); // create the invoice for each magento order $cobmisc = DB_DataObject::factory('cobmisc'); $cobmisc->setFrom(array( 'cobmisc_cohead_id' => $co->pid(), 'cobmisc_invcdate' => $order_date, 'cobmisc_shipdate' => $order_date )); $cobmisc->cobmisc_taxtype_id = $cobmisc->sqlValue("gettaxtypeid('Taxable'::text)"); $cobmisc->fixMisc(); $t = $cobmisc->factory('cobmisc'); $t->query("SELECT createBillingHeader({$co->pid()}) AS cobmisc_id"); $t->fetch(); $cobmisc->cobmisc_id = $t->cobmisc_id; $cobmisc->updateItems($billitems); // apply the credit memo.. if (!empty($cobapply_list)) { $cobmisc->updateCobApply($this,$cobapply_list); } // post the bill. $t = $cobmisc->factory('cobmisc'); $t->get($cobmisc->cobmisc_id); $t->post($this); // fetch again so it should have invoice.. $t = $cobmisc->factory('cobmisc'); $t->get($cobmisc->cobmisc_id); $invoice = $t->invchead(); $aropen = $invoice->aropen(); /* if (round($total,2) != round($aropen->aropen_amount,2)) { $this->jerr("TOTAL $total != {$aropen->aropen_amount}" . print_r(array( 'itemtotal' => $itemtotal, 'aftertax_line_total' => $aftertax_line_total, 'total_discount' => $total_discount, 'freight' => $freight, 'totaldiscounted_inctax' => $totaldiscounted_inctax, 'totaldiscounted_b4tax' => $totaldiscounted_inctax * (10/11), 'freight_b4tax' => $freight * (10/11), ),true)); } */ //print_R($aropen);$this->jerr("fixme"); return array( $total, $aropen->aropen_amount); } function checkcntctAndaddr($cntct,$addrs) { $cn = DB_DataObject::factory('cntct'); if(!$cn->get('cntct_first_name', $cntct['cntct_first_name'])){ // contact not exists $cn->setFrom($cntct); $cn->cntct_crmacct_id = $cn->sqlValue("(SELECT crmacct_id FROM crmacct WHERE crmacct_cust_id = {$cntct['cust_id']})"); $cn->genNumber(); $cn->insert(); } if(!$cn->cntct_addr_id){ // addr not exists $addr = DB_DataObject::Factory('addr'); $addr->setFrom($addrs); $addr->genNumber(); $addr->insert(); $oldcn = clone($cn); $cn->cntct_addr_id = $addr->pid(); $cn->update($oldcn); } return $cn; } function checkshiptoinfo($customer, $cntct) { $sh = DB_DataObject::Factory('shiptoinfo'); $sh->shipto_cntct_id = $cntct->pid(); $sh->shipto_addr_id = $cntct->cntct_addr_id; if ($sh->find(true)) { return $sh->pid(); } $sh->setFrom(array( 'shipto_cust_id' => $cust_id, 'shipto_name' => $cntct->cntct_name, 'shipto_salesrep_id'=> $customer->cust_salesrep_id, 'shipto_active' => true, 'shipto_adefault' => false, 'shipto_shipchrg_id' => $customer->cust_shipchrg_id, 'shipto_taxzone_id' => $customer->cust_taxzone_id, 'shipto_shipform_id' => $customer->cust_shipform_id, 'shipto_commission' => 0, 'shipto_shipzone_id' => $customer->cust_taxzone_id )); $sh->genNum(); $sh->insert(); return $sh->pid(); } function orderShipments($toShipments,$d) { $this->debugLog('creating shipments'); $ids = array_keys($toShipments); $c = array_pop($toShipments); $cc = DB_DataObject::factory('coitem'); $cc->coitem_cohead_id = $c->coitem_cohead_id; $cc->find(); $x = array(); $shipitems = array(); while ($cc->fetch()){ // this query will take about 6 secs... $itemsite = $cc->itemsite(); // skip non-stock items.. if (!$itemsite->itemsite_stocked) { continue; } $x['shipitem_orderitem_id'] = $cc->pid(); $x['shipitem_qty'] = 0; if(in_array($cc->pid(), $ids)){ $x['shipitem_qty'] = $cc->coitem_qtyord; } $shipitems[] = (object)$x; } $sh = DB_DataObject::factory('shiphead'); $sh->setFrom(array( 'shiphead_shipdate' => $c->coitem_scheddate, 'shiphead_order_id' => $c->coitem_cohead_id, 'shiphead_sfstatus' => 'N', 'shiphead_location_id' => $c->coitem_location_src, 'shiphead_shipto_id' => $c->coitem_shipto_id, //'shiphead_number' => $cohead->cohead_number . substr($c->coitem_linenumber, 0, 4), 'shiphead_order_type' => 'SO', 'shiphead_freight' => 0, //$d['freight'], 'shiphead_freight_curr_id' => $d['curr'], 'shiphead_notes' => '' // $r['SHIP NOTE'] )); $sh->beforeInsert(array('shiphead_number' => 'Automatic'),$this); //$this->jerr("about to create shipment: " . $sh->shiphead_number); $sh->insert(); $sh->updateItems($shipitems, $this); $sh->confirm($this); } function voidInvAndShipments($co) { $this->debugLog('deelting old invoices / shipments'); $invoices = $co->cobmiscs(); foreach($invoices as $i) { $i->void($this, true); } // do it twice.. $invoices = $co->cobmiscs(); foreach($invoices as $i) { $i->void($this,true); } // delete the shipments... $shipheads = $co->shipheads(); foreach($shipheads as $s) { if (!empty($s->shiphead_shipped) && !empty($s->shiphead_shipdate)) { $res = $s->unconfirm($this,true); if ($res !== true) { $this->jerr("ship unconfirm failed:" . $res); } } if (!empty($s->shiphead_shipdate)) { // 395.43042492867 secs... $res = $s->void($this,true); // void shipitem will take 0.1 sec for each... a little bit long time... if ($res !== true) { $this->jerr("ship voiding failed" . $res) ; } } } } //B_45 not found //B_12 not found //B_1 not found //B_11 not found // 210203 not found // 212103 not found // Gift Wrapping not found // Gift Wrapping not found // 212204 not found // Gift Wrapping not found }