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'); $csv = $fc->convert('text/csv'); $this->debugLog('running import CSV'); $this->importCsv($csv); } 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) { ini_set("auto_detect_line_endings", true); $this->debugLog('reading file'); $fh = fopen($content, 'r'); if (!$fh) { $this->jerr("invalid content file"); } // new format header $reqs = array( 'ORDER ID', 'CREATION DATE', 'BILLING NAME', 'CUSTOMER EMAIL', 'SHIPPING NAME', 'SHIPPING ADDRESS', 'SHIPPING CITY', 'SHIPPING STATE', 'SHIPPING POSTCODE', 'SHIPPING COUNTRY', 'SHIPPING TELEPHONE', 'SHIPPING METHOD', 'DELIVERY NOTE', 'SIGNATURE REQUIRED?', 'TOTAL WEIGHT', 'CUSTOMER BALANCE', 'SHIPPING', 'GRAND TOTAL', 'GIFT CARD', 'TAX AMOUNT', 'SKU', 'PRODUCT NAME', 'QTY', 'UNIT PRICE', 'SUBTOTAL', 'DISCOUNT', 'DISCOUNTED TOTAL', 'PAYMENT METHOD', 'GIFT WRAP ID', 'COUPON CODE', 'CUSTOMER GROUP' ); $cols = false; $rows = array(); // 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_lines_in_file= count(file($content)) ; $no_split = $no_lines_in_file > 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 && $no_lines_in_file > 2500) { $this->jerr("file is too large to upload - please send to admin to import ($no_lines_in_file)"); } $ln = ''; $lnum= 0; $od = false; while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) { $lnum++; if (!strlen(implode('', $n))) { continue; } if (!$cols) { $cols = array(); foreach($n as $k) { $cols[] = strtoupper(trim($k)); } if (empty($cols)) { continue; } foreach($reqs as $req) { if (!in_array($req,$cols)) { $cols = false; break; } } continue; } foreach ($cols as $k => $c){ $c = strtoupper($c); if (empty($c) || !strlen(trim($c))) { continue; } if($c == 'ORDER ID'){ if($ln != $n[$k]){ $ln = $n[$k]; $row = 1; } $r[$c] = substr($n[$k], -4) * 10000 + $row; continue; } if($c == 'CREATION DATE'){ $r[$c] = date('Y-m-d',strtotime(str_replace('/', '-', $n[$k]))); continue; } if (!isset($n[$k])) { $this->jerr("Error on line $lnum - missing data in column $c"); } $r[$c] = $n[$k]; } if ($od === false) { $od = $r['CREATION DATE']; } if ($od != $r['CREATION DATE']) { $this->jerr("the file contains orders for multiple days first was $od, found {$r['CREATION DATE']} - either download again, or remove the extra lines"); } if (empty($r['QTY']) || (floor($r['QTY']) != $r['QTY'])) { $this->jerr("Error on line $lnum - {$r['QTY']} is not a valid quantity"); } $row++; $index = $no_split ? 1 : floor($r['ORDER ID'] / 1000000); if($r['PAYMENT METHOD'] == 'creditcard' || $r['PAYMENT METHOD'] == 'free' || $r['PAYMENT METHOD'] == 'secureframe'){ $rows['MGCREDITCARD'][$index][] = $r; continue; } if($r['PAYMENT METHOD'] == 'paypal_express'){ $rows['MGPAYPAL'][$index][] = $r; continue; } if($r['PAYMENT METHOD'] == 'paypal_standard'){ $rows['MGPAYPAL'][$index][] = $r; continue; } if($r['PAYMENT METHOD'] == 'directdeposit_au'){ $rows['MGDEPOSIT'][$index][] = $r; continue; } $this->jerr("invalid payment type: {$r['PAYMENT METHOD']} on line $lnum"); } fclose($fh); if (empty($cols)) { $this->jerr("could not find a row with " . implode(' / ', $req)); } $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]['CREATION 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'); $total = 0.0; $delivery = 0.0; $billitems = array(); $invoice_total = 0.0; $toShipment = array(); $gift = 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['SKU']); if (!$i) { $this->errmsg[] = $r['SKU'] . ' not found'; continue; } // delete the old line numbers.. AGHH !!! = this has been destroying data!!! (it did not have coitem_cohead_id before..) $coitem = DB_DataObject::factory('coitem'); $coitem->coitem_cohead_id = $co->pid(); if($coitem->get('coitem_linenumber', $r['ORDER ID'])){ // 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"); } $coitem_custprice = round(($r['UNIT PRICE']) * (10 / 11) ,3); // take out the tax // grand total = unit price + discount + shipping -customer balance - gift card $discount_rate = round((abs( $r['DISCOUNT']) / ($r['GRAND TOTAL'] - $r['SHIPPING'] - $r['DISCOUNT'] + $r['CUSTOMER BALANCE'] + $r['GIFT CARD']) ), 3); // discount rate $coitem_price = round(($coitem_custprice * (1 - $discount_rate)), 3); $coitem->setFrom(array( 'coitem_cohead_id' => $co->pid(), 'coitem_linenumber' => $r['ORDER ID'], 'coitem_itemsite_id' => $itemsite->pid(), 'coitem_qtyord' => $r['QTY'], '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['CREATION DATE'] )); foreach($coitem->defaults() as $k=>$v) { if (empty($coitem->$k)) { $coitem->$k = $v; } } $coitem->insert(); if(!$coitem->coitem_id){ $this->errmsg[] = $r['SKU'] . ' error occur on insert'; continue; } $toShipment[$coitem->pid()] = $coitem; if(substr($r['ORDER ID'],-4,4) == 1){ $total += ($r['GRAND TOTAL'] + $r['CUSTOMER BALANCE'] + $r['GIFT CARD']) ; // with tax // if ( $r['PAYMENT METHOD'] == 'free' ) { // $r['SHIPPING'] = 0.0; // } $delivery += round(($r['SHIPPING'] * (10 / 11)), 3); // without tax $gift += round((($r['CUSTOMER BALANCE'] + $r['GIFT CARD']) * (10 / 11)), 3); // without tax } $x = array( 'cobill_coitem_id' => $coitem->pid(), 'cobill_qty' => $coitem->coitem_qtyord ); $billitems[] = (object)$x; $invoice_total += round($coitem->coitem_qtyord * $coitem->coitem_price, 3); } 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'); $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,3) ; $x = array( 'cobill_coitem_id' => $coitem->pid(), '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( 'cobill_coitem_id' => $coitem->pid(), 'cobill_qty' => $coitem->coitem_qtyord ); $billitems[] = (object)$x; $invoice_total = $invoice_total + round(($coitem->coitem_qtyord * $coitem->coitem_price), 3); $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(); if($gift > 0){ // 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 cmhead 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(); 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 }