public function get_id_email_handler() { global $FANNIE_OP_DB; $mem = new MeminfoModel(FannieDB::get($FANNIE_OP_DB)); $mem->card_no($this->id); $mem->email_1($this->email); $mem->save(); header('Location: PIMemberPage.php?id=' . $this->id); return false; }
function addTempMembers($dbc = "") { //global $dbConn2; global $tempMemberRange; /* End of range to fill with NEW MEMBER records. * 0 means "do no fill" */ global $tempMemberRangeMax; /* Placeholder custdata.LastName that will be: * - ignored when it occurrs in the range of synced records * - assigned to new placeholder records if filling is being done. */ global $tempMemberLastName; /* custdata.memType for placeholder records. * Must be real. */ global $tempMemberMemberType; /* memContact.pref for placeholder records. * Must be real. */ global $tempMemberContactPref; $retval = null; $errors = ''; if ($dbc == "") { $errors = "addTempMembers() no database connection supplied."; return $errors; } /* Much of what follows is lifted from $MEM/NewMemberTool.php */ $name = $tempMemberLastName; /* Validate in memtypes.memtype */ $mtype = $tempMemberMemberType; $memtypes = new MemtypeModel($dbc); $memtypes->memtype($mtype); $mtypes = $memtypes->find(); if (count($mtypes) == 0) { $errors = "Member type {$mtype} is not known."; return $errors; } /* Validate in memContactPrefs.pref_id */ $pref = $tempMemberContactPref; $memprefs = new MemContactPrefsModel($dbc); $memprefs->pref_id($pref); $mprefs = $memprefs->find(); if (count($mprefs) == 0) { $errors = "Contact preference {$pref} is not known."; return $errors; } $mt = $dbc->tableDefinition('memtype'); $dQuery = "SELECT custdataType,discount,staff,ssi from memtype " . "WHERE memtype=?"; $defaultsQ = $dbc->prepare_statement($dQuery); if ($dbc->tableExists('memdefaults') && (!isset($mt['custdataType']) || !isset($mt['discount']) || !isset($mt['staff']) || !isset($mt['ssi']))) { $dQuery = "SELECT cd_type as custdataType,discount,staff,SSI as ssi " . "FROM memdefaults WHERE memtype=?"; $defaultsQ = $dbc->prepare_statement($dQuery); } $defaultsR = $dbc->exec_statement($defaultsQ, array($mtype)); $defaults = $dbc->fetch_row($defaultsR); $start = $tempMemberRange + 1; $end = $tempMemberRangeMax; $custdata = new CustdataModel($dbc); /* Pre-populate most custdata fields. */ $custdata->personNum(1); $custdata->LastName($name); $custdata->FirstName(''); $custdata->CashBack(999.99); $custdata->Balance(0); $custdata->memCoupons(0); $custdata->Discount($defaults['discount']); $custdata->Type($defaults['custdataType']); $custdata->staff($defaults['staff']); $custdata->SSI($defaults['ssi']); $custdata->memType($mtype); $meminfo = new MeminfoModel($dbc); /* Pre-populate most meminfo fields. */ $meminfo->last_name(''); $meminfo->first_name(''); $meminfo->othlast_name(''); $meminfo->othfirst_name(''); $meminfo->street(''); $meminfo->city(''); $meminfo->state(''); $meminfo->zip(''); $meminfo->phone(''); $meminfo->email_1(''); $meminfo->email_2(''); $chkP = $dbc->prepare_statement('SELECT CardNo FROM custdata WHERE CardNo=?'); $mdP = $dbc->prepare_statement("INSERT INTO memDates VALUES (?,NULL,NULL)"); $mcP = $dbc->prepare_statement("INSERT INTO memContact (card_no,pref) VALUES (?,?)"); $membersAdded = 0; for ($i = $start; $i <= $end; $i++) { // skip if record already exists $chkR = $dbc->exec_statement($chkP, array($i)); if ($dbc->num_rows($chkR) > 0) { continue; } $custdata->CardNo($i); $custdata->blueLine($i . ' ' . $name); $custdata->save(); $meminfo->card_no($i); $meminfo->save(); /* memDates */ $dbc->exec_statement($mdP, array($i)); /* memContact */ $dbc->exec_statement($mcP, array($i, $pref)); $membersAdded++; } $retval = $errors ? $errors : $membersAdded; return $retval; // addTempMembers() }
// save next personNum $count++; } // remove names that were blank on the form for ($i = $count; $i < 5; $i++) { $cust->personNum($i); $cust->delete(); } $meminfo = new MeminfoModel($dbc); $meminfo->card_no($memNum); $meminfo->street($MI_FIELDS['street']); $meminfo->city($MI_FIELDS['city']); $meminfo->state($MI_FIELDS['state']); $meminfo->phone($MI_FIELDS['phone']); $meminfo->email_2($MI_FIELDS['email_2']); $meminfo->email_1($MI_FIELDS['email_1']); $meminfo->ads_OK($MI_FIELDS['ads_OK']); $meminfo->save(); $memdate = new MemDatesModel($dbc); $memdate->card_no($memNum); $memdate->start_date($_POST['startDate']); $memdate->end_date($_POST['endDate']); $memdate->save(); // FIRE ALL UPDATE include 'custUpdates.php'; updateCustomerAllLanes($memNum); /* general note handling */ $notetext = $_POST['notetext']; $notetext = preg_replace("/\n/", "<br />", $notetext); $notetext = preg_replace("/\\'/", "''", $notetext); $checkQ = $sql->prepare("select * from memberNotes where note=? and cardno=?");
/** Update older tables. */ private static function postCustdata($dbc, $id, $json) { $config = \FannieConfig::factory(); $ret = array('errors' => 0, 'error-msg' => ''); /** save dates if provided **/ if (isset($json['startDate']) || isset($json['endDate'])) { $dates = new \MemDatesModel($dbc); $dates->start_date($json['startDate']); $dates->end_date($json['endDate']); $dates->card_no($id); if (!$dates->save()) { $ret['errors']++; $ret['error-msg'] .= 'ErrDates '; } } /** save UPC if provided **/ if (isset($json['idCardUPC'])) { $cards = new \MemberCardsModel($dbc); $cards->card_no($id); if ($json['idCardUPC'] != '') { $cards->upc(\BarcodeLib::padUPC($json['idCardUPC'])); } else { $cards->upc(''); } if (!$cards->save()) { $ret['errors']++; } } /** save contact method if provided **/ if (isset($json['contactMethod'])) { $contact = new \MemContactModel($dbc); $contact->card_no($id); if (isset($json['contactAllowed']) && !$json['contactAllowed']) { $contact->pref(0); } elseif ($json['contactMethod'] == 'email') { $contact->pref(2); } elseif ($json['contactMethod'] == 'both') { $contact->pref(3); } else { $contact->pref(1); } if (!$contact->save()) { $ret['errors']++; $ret['error-msg'] .= 'ErrUPC '; } } /** Custdata and meminfo are messier. Start with account-level settings. */ $custdata = new \CustdataModel($dbc); $custdata->CardNo($id); $custdata_changed = false; $meminfo = new \MeminfoModel($dbc); $meminfo->card_no($id); if (isset($json['addressFirstLine'])) { $street = $json['addressFirstLine']; if (isset($json['addressSecondLine'])) { $street .= "\n" . $json['addressSecondLine']; } $meminfo->street($street); } if (isset($json['city'])) { $meminfo->city($json['city']); } if (isset($json['state'])) { $meminfo->state($json['state']); } if (isset($json['zip'])) { $meminfo->zip($json['zip']); } if (isset($json['contactAllowed'])) { $meminfo->ads_OK($json['contactAllowed']); } if (isset($json['activeStatus']) && $json['activeStatus'] != '') { $custdata->Type($json['activeStatus']); $custdata_changed = true; } elseif (isset($json['memberStatus'])) { $custdata->Type($json['memberStatus']); $custdata_changed = true; } if (isset($json['customerTypeID'])) { $custdata->memType($json['customerTypeID']); $custdata_changed = true; } if (isset($json['chargeLimit'])) { $custdata->ChargeLimit($json['chargeLimit']); $custdata->MemDiscountLimit($json['chargeLimit']); $custdata_changed = true; } if (isset($json['chargeBalance'])) { $custdata->Balance($json['chargeBalance']); $custdata_changed = true; } /** Now loop through per-person settings. Assign the primary account holder's email address and phone number to the global meminfo, but save the other settings using a different per-person custdata instance */ if (isset($json['customers']) && is_array($json['customers']) && count($json['customers']) > 0) { $personNum = 2; foreach ($json['customers'] as $c_json) { if (!isset($c_json['accountHolder'])) { $ret['errors']++; $ret['error-msg'] .= 'ErrAcctHolder '; continue; } $loopCD = new \CustdataModel($dbc); $loopCD->CardNo($id); $loopCD_changed = false; if ($c_json['accountHolder']) { $loopCD->personNum(1); if (isset($c_json['phone'])) { $meminfo->phone($c_json['phone']); } if (isset($c_json['altPhone'])) { $meminfo->email_2($c_json['altPhone']); } if (isset($c_json['email'])) { $meminfo->email_1($c_json['email']); } } elseif (isset($c_json['firstName']) && isset($c_json['lastName']) && $c_json['firstName'] == '' && $c_json['lastName'] == '') { // blank name fields on non-account holder mean // the customer was removed from the account continue; } else { $loopCD->personNum($personNum); $personNum++; } if (isset($c_json['firstName'])) { $loopCD->FirstName($c_json['firstName']); $loopCD_changed = true; } if (isset($c_json['lastName'])) { $loopCD->LastName($c_json['lastName']); $loopCD_changed = true; } if (isset($c_json['chargeAllowed'])) { $loopCD->ChargeOk($c_json['chargeAllowed']); $loopCD_changed = true; } if (isset($c_json['checksAllowed'])) { $loopCD->WriteChecks($c_json['checksAllowed']); $loopCD_changed = true; } if (isset($c_json['staff'])) { $loopCD->staff($c_json['staff']); $loopCD_changed = true; } if (isset($c_json['discount'])) { $loopCD->Discount($c_json['discount']); $loopCD_changed = true; } if (isset($c_json['lowIncomeBenefits'])) { $loopCD->SSI($c_json['lowIncomeBenefits']); $loopCD_changed = true; } if ($loopCD_changed && !$loopCD->save()) { $ret['errors']++; $ret['error-msg'] .= 'ErrPerson '; } } $cleanP = $dbc->prepare('DELETE FROM custdata WHERE CardNo=? AND personNum>=?'); $cleanR = $dbc->execute($cleanP, array($id, $personNum)); } if (!$meminfo->save()) { $ret['errors']++; $ret['error-msg'] .= 'ErrMeminfo '; } /** Finally, apply account-level settings to all custdata records for the account. */ if ($custdata_changed) { $allCD = new \CustdataModel($dbc); $allCD->CardNo($id); foreach ($allCD->find() as $c) { $custdata->personNum($c->personNum()); if (!$custdata->save()) { $ret['errors']++; $ret['error-msg'] .= 'ErrGlobal '; } } } self::setBlueLines($id); // in classic mode sync changes back to the new table if present if ($config->get('CUST_SCHEMA') != 1 && $dbc->tableExists('CustomerAccounts')) { self::postAccount($dbc, $id, $json); } $ret['account'] = self::get($id); return $ret; }
public function post_id_fn_city_ph1_ln_state_ph2_addr1_zip_email_addr2_handler() { global $FANNIE_OP_DB; $dbc = FannieDB::get($FANNIE_OP_DB); $cust = new CustdataModel($dbc); $cust->CardNo($this->id); $cust->personNum(1); $cust->FirstName($this->fn); $cust->LastName($this->ln); $cust->save(); $mem = new MeminfoModel($dbc); $mem->card_no($this->id); $mem->city($this->city); $mem->state($this->state); $mem->zip($this->zip); $mem->phone($this->ph1); $mem->email_1($this->email); $mem->email_2($this->ph2); $street = $this->addr1; if (!empty($this->addr2)) { $street .= "\n" . $this->addr2; } $mem->street($street); $mem->save(); header('Location: GumMainPage.php?id=' . $this->id); return false; }
public function run() { global $FANNIE_OP_DB, $FANNIE_PLUGIN_SETTINGS, $argv; $dbc = FannieDB::get($FANNIE_OP_DB); $custdata = new CustdataModel($dbc); $meminfo = new MeminfoModel($dbc); $APIKEY = 'a92f83d3e5f7fe52d4579e7902c6491d-us8'; $LISTID = '54100d18af'; $APIKEY = $FANNIE_PLUGIN_SETTINGS['MailChimpApiKey']; $LISTID = $FANNIE_PLUGIN_SETTINGS['MailChimpListID']; if (empty($APIKEY) || empty($LISTID)) { $this->cronMsg('Missing API key or List ID', FannieLogger::NOTICE); return false; } if (!class_exists('Mailchimp')) { $this->cronMsg('MailChimp library is not installed', FannieLogger::NOTICE); return false; } $mc = new MailChimpEx($APIKEY); if ($FANNIE_PLUGIN_SETTINGS['MailChimpMergeVarField'] != 1) { $vars = $mc->lists->mergeVars(array($LISTID)); $field_id = false; if ($vars['data']) { $current = array_pop($vars['data']); foreach ($current['merge_vars'] as $index => $info) { if ($info['tag'] == 'CARDNO') { $field_id = $info['id']; break; } } if ($field_id !== false) { echo 'Found member# field' . "\n"; } else { echo 'Adding member# field' . "\n"; $new = $mc->lists->mergeVarAdd($LISTID, 'CARDNO', 'Owner Number', array('field_type' => 'number', 'public' => false)); $field_id = $new['id']; } } if ($field_id === false) { $this->cronMsg('Error: could not locate / create owner number field!', FannieLogger::NOTICE); return false; } } // end create owner number field if needed $statuses = array('subscribed', 'unsubscribed', 'cleaned'); $cleans = array(); $memlist = ''; /** Examine all list members */ foreach ($statuses as $status) { $this->cronMsg('==== Checking ' . $status . ' emails ====', FannieLogger::INFO); $full_list = $mc->lists->export($LISTID, $status); $headers = array_shift($full_list); $columns = array(); foreach ($headers as $index => $name) { $columns[strtoupper($name)] = $index; } $line_count = 1; foreach ($full_list as $record) { /** Print progress meter in verbose mode */ if (isset($argv[2]) && ($argv[2] == '-v' || $argv[2] == '--verbose')) { printf("Processing %d/%d\r", $line_count, count($full_list)); } $line_count++; $card_no = $record[$columns['OWNER NUMBER']]; $email = $record[$columns['EMAIL ADDRESS']]; $fn = $record[$columns['FIRST NAME']]; $ln = $record[$columns['LAST NAME']]; $changed = isset($columns['LAST_CHANGED']) && isset($record[$columns['LAST_CHANGED']]) ? $record[$columns['LAST_CHANGED']] : 0; /** MailChimp has a POS member number tag **/ if (!empty($card_no)) { switch ($status) { /** If subscribed list member has been tagged with a POS member number, compare MailChimp fields to POS fields. If name disagrees, use POS value for both. If email disagrees, use MailChimp value for both. */ case 'subscribed': $memlist .= sprintf('%d,', $card_no); $custdata->reset(); $custdata->CardNo($card_no); $custdata->personNum(1); $custdata->load(); $update = array(); $meminfo->reset(); $meminfo->card_no($card_no); $meminfo->load(); if ($meminfo->email_1() != $email && strtotime($changed) > strtotime($meminfo->modified())) { $this->cronMsg(sprintf("MISMATCH: POS says %s, MailChimp says %s, Mailchimp is newer", $meminfo->email_1(), $email), FannieLogger::INFO); $meminfo->email_1($email); $meminfo->save(); } elseif ($meminfo->email_1() != $email) { $update['EMAIL'] = $meminfo->email_1(); $this->cronMsg(sprintf("MISMATCH: POS says %s, MailChimp says %s, POS is newer", $meminfo->email_1(), $email), FannieLogger::INFO); } if (strtoupper(trim($custdata->FirstName())) != strtoupper($fn)) { $this->cronMsg(sprintf("MISMATCH: POS says %s, MailChimp says %s", $custdata->FirstName(), $fn), FannieLogger::INFO); $update['FNAME'] = trim($custdata->FirstName()); } if (strtoupper(trim($custdata->LastName())) != strtoupper($ln)) { $this->cronMsg(sprintf("MISMATCH: POS says %s, MailChimp says %s", $custdata->LastName(), $ln), FannieLogger::INFO); $update['LNAME'] = trim($custdata->LastName()); } if (count($update) > 0) { $email_struct = array('euid' => $record[$columns['EUID']], 'leid' => $record[$columns['LEID']]); $this->cronMsg(sprintf("Updating name field(s) for member #%d", $card_no), FannieLogger::INFO); try { $mc->lists->updateMember($LISTID, $email_struct, $update, '', false); } catch (Exception $ex) { echo $ex; var_dump($update); } sleep(1); } break; /** Just track the number to avoid re-adding them to the list */ /** Just track the number to avoid re-adding them to the list */ case 'unsubscribed': $memlist .= sprintf('%d,', $card_no); break; /** Cleaned in MailChimp means the address isn't deliverable In this situation, remove the bad address from POS and delete the address from MailChimp. The member can be re-added when a correct email is entered into POS. */ /** Cleaned in MailChimp means the address isn't deliverable In this situation, remove the bad address from POS and delete the address from MailChimp. The member can be re-added when a correct email is entered into POS. */ case 'cleaned': $meminfo->reset(); $meminfo->card_no($card_no); $meminfo->email_1(''); $meminfo->save(); $this->cronMsg(sprintf('CLEANING Member %d, email %s', $card_no, $email), FannieLogger::INFO); $cleans[] = $record; break; } /** If list member is not tagged with a POS member number, try to locate them in POS by name and/or email address. If found, tag them in MailChimp with the POS member number. This whole situation only occurs if the initial list is imported without member numbers. */ } else { switch ($status) { // subscribed users can be updated easily case 'subscribed': $update = array(); $meminfo->reset(); $meminfo->email_1($email); $matches = $meminfo->find(); if (count($matches) == 1) { $update['CARDNO'] = $matches[0]->card_no(); } else { $custdata->reset(); $custdata->FirstName($fn); $custdata->LastName($ln); $custdata->personNum(1); $custdata->Type('PC'); $matches = $custdata->find(); if (count($matches) == 1) { $update['CARDNO'] = $matches[0]->CardNo(); } } if (isset($update['CARDNO'])) { $email_struct = array('email' => $email, 'euid' => $record[$columns['EUID']], 'leid' => $record[$columns['LEID']]); $this->cronMsg("Assigning member # to account " . $email, FannieLogger::INFO); $mc->lists->updateMember($LISTID, $email_struct, $update, '', false); sleep(1); $memlist .= sprintf('%d,', $update['CARDNO']); } break; /** Unsubscribed are currently ignored. The can't be updated as is. They could be deleted entirely via unsubscribe, resubscribed with an owner number, and then unsubscribed again. That's not currently implemented. It does check for the email address on the POS side to prevent re-adding it. */ /** Unsubscribed are currently ignored. The can't be updated as is. They could be deleted entirely via unsubscribe, resubscribed with an owner number, and then unsubscribed again. That's not currently implemented. It does check for the email address on the POS side to prevent re-adding it. */ case 'unsubscribed': $meminfo->reset(); $this->cronMsg('Checking unsubscribed ' . $email, FannieLogger::INFO); $meminfo->email_1($email); $matches = $meminfo->find(); foreach ($matches as $opted_out) { $memlist .= sprintf('%d,', $opted_out->card_no()); $this->cronMsg('Excluding member ' . $opted_out->card_no(), FannieLogger::INFO); } break; /** Cleaned are bad addresses. Delete them from POS database then from Mail Chimp. */ /** Cleaned are bad addresses. Delete them from POS database then from Mail Chimp. */ case 'cleaned': $meminfo->reset(); $meminfo->email_1($email); foreach ($meminfo->find() as $bad_address) { $bad_address->email_1(''); $bad_address->save(); $this->cronMsg(sprintf('CLEANING untagged member %d, email %s', $bad_address->card_no(), $email), FannieLogger::INFO); } $cleans[] = $record; break; } } } // foreach list member record } // foreach list status /** Removed bounced from the MailChimp list now that POS has been updated */ $removal_batch = array(); foreach ($cleans as $record) { if (empty($record[$columns['EMAIL ADDRESS']])) { continue; } $email_struct = array('email' => $record[$columns['EMAIL ADDRESS']], 'euid' => $record[$columns['EUID']], 'leid' => $record[$columns['LEID']]); $removal_batch[] = $email_struct; } if (count($removal_batch) > 0) { $this->cronMsg(sprintf('Removing %d addresses with status "cleaned"', count($removal_batch)), FannieLogger::INFO); $result = $mc->lists->batchUnsubscribe($LISTID, $removal_batch, true, false, false); } /** Finally, find new members and add them to MailChimp */ if ($memlist === '') { $memlist = '-1,'; } $memlist = substr($memlist, 0, strlen($memlist) - 1); $query = 'SELECT m.card_no, m.email_1, c.FirstName, c.LastName FROM meminfo AS m INNER JOIN custdata AS c ON c.CardNo=m.card_no AND c.personNum=1 WHERE c.Type = \'PC\' AND m.email_1 IS NOT NULL AND m.email_1 <> \'\' AND m.card_no NOT IN (' . $memlist . ')'; $result = $dbc->query($query); $add_batch = array(); while ($row = $dbc->fetch_row($result)) { if (!filter_var($row['email_1'], FILTER_VALIDATE_EMAIL)) { continue; } $new = array('email' => array('email' => $row['email_1']), 'email_type' => 'html', 'merge_vars' => array('FNAME' => $row['FirstName'], 'LNAME' => $row['LastName'], 'CARDNO' => $row['card_no'])); $add_batch[] = $new; } if (count($add_batch) > 0) { $this->cronMsg(sprintf('Adding %d new members', count($add_batch)), FannieLogger::INFO); $added = $mc->lists->batchSubscribe($LISTID, $add_batch, false, true); } return true; }
/** Update various legacy tables to match existing Customer records. @param $card_no [int] member number @return [boolean] success */ public function legacySync($card_no) { $dbc = $this->connection; $custdata = new CustdataModel($dbc); $custdata->CardNo($card_no); $meminfo = new MeminfoModel($dbc); $meminfo->card_no($card_no); $this->reset(); $this->cardNo($card_no); $this->accountHolder(1); if (count($this->find()) != 1) { // no customer records // or invalid customer records return false; } $account = new CustomerAccountsModel($dbc); $account->cardNo($card_no); if (!$account->load()) { return false; } foreach ($this->find() as $c) { $meminfo->phone($c->phone()); $meminfo->email_2($c->altPhone()); $meminfo->email_1($c->email()); $meminfo->save(); $custdata->personNum(1); $custdata->FirstName($c->firstName()); $custdata->LastName($c->lastName()); $custdata->blueLine($card_no . ' ' . $c->lastName()); $custdata->ChargeOk($c->chargeAllowed()); $custdata->WriteChecks($c->checksAllowed()); $custdata->staff($c->staff()); $custdata->SSI($c->lowIncomeBenefits()); $custdata->Discount($c->discount()); $custdata->save(); } $person = 2; $this->accountHolder(0); foreach ($this->find() as $c) { $custdata->personNum($person); $custdata->FirstName($c->firstName()); $custdata->LastName($c->lastName()); $custdata->blueLine($card_no . ' ' . $c->lastName()); $custdata->ChargeOk($c->chargeAllowed()); $custdata->WriteChecks($c->checksAllowed()); $custdata->staff($c->staff()); $custdata->SSI($c->lowIncomeBenefits()); $custdata->Discount($c->discount()); $custdata->save(); $person++; } return true; }