From b6baa8ecd899e1b1e5a2bc3c6808ad423e16f2c4 Mon Sep 17 00:00:00 2001 From: Karl Cordes Date: Thu, 12 Feb 2009 15:02:05 +1100 Subject: [PATCH] Fixed up the vault and email handling. Added Customer Categories --- .../customer_categories_controller.php | 52 ++++ controllers/customers_controller.php | 8 + controllers/emails_controller.php | 1 + controllers/enquiries_controller.php | 1 + controllers/users_controller.php | 6 +- models/customer.php | 3 + models/customer_category.php | 12 + vendors/shells/vault.php | 240 ++++++++---------- views/customer_categories/add.ctp | 17 ++ views/customer_categories/edit.ctp | 19 ++ views/customer_categories/index.ctp | 50 ++++ views/customer_categories/view.ctp | 73 ++++++ views/customers/add.ctp | 4 + views/customers/edit.ctp | 4 + views/customers/index.ctp | 24 ++ views/customers/view.ctp | 5 + views/elements/email_attachments.ctp | 57 +++++ views/emails/frame.ctp | 8 + views/emails/print.ctp | 52 ++++ views/emails/show.ctp | 35 --- views/enquiries/view.ctp | 6 +- views/layouts/minimal.ctp | 2 +- webroot/css/email.css | 86 +++++++ webroot/css/quotenik.css | 32 ++- webroot/img/text-x-generic.png | Bin 0 -> 523 bytes 25 files changed, 618 insertions(+), 179 deletions(-) create mode 100644 controllers/customer_categories_controller.php create mode 100644 models/customer_category.php create mode 100644 views/customer_categories/add.ctp create mode 100644 views/customer_categories/edit.ctp create mode 100644 views/customer_categories/index.ctp create mode 100644 views/customer_categories/view.ctp create mode 100644 views/elements/email_attachments.ctp create mode 100644 views/emails/print.ctp create mode 100644 webroot/css/email.css create mode 100644 webroot/img/text-x-generic.png diff --git a/controllers/customer_categories_controller.php b/controllers/customer_categories_controller.php new file mode 100644 index 00000000..2e5521c6 --- /dev/null +++ b/controllers/customer_categories_controller.php @@ -0,0 +1,52 @@ +CustomerCategory->recursive = 0; + $this->set('customerCategories', $this->paginate()); + } + + function view($id = null) { + if (!$id) { + $this->Session->setFlash(__('Invalid CustomerCategory.', true)); + $this->redirect(array('action'=>'index')); + } + $this->set('customerCategory', $this->CustomerCategory->read(null, $id)); + } + + function add() { + if (!empty($this->data)) { + $this->CustomerCategory->create(); + if ($this->CustomerCategory->save($this->data)) { + $this->Session->setFlash(__('The CustomerCategory has been saved', true)); + $this->redirect(array('action'=>'index')); + } else { + $this->Session->setFlash(__('The CustomerCategory could not be saved. Please, try again.', true)); + } + } + } + + function edit($id = null) { + if (!$id && empty($this->data)) { + $this->Session->setFlash(__('Invalid CustomerCategory', true)); + $this->redirect(array('action'=>'index')); + } + if (!empty($this->data)) { + if ($this->CustomerCategory->save($this->data)) { + $this->Session->setFlash(__('The CustomerCategory has been saved', true)); + $this->redirect(array('action'=>'index')); + } else { + $this->Session->setFlash(__('The CustomerCategory could not be saved. Please, try again.', true)); + } + } + if (empty($this->data)) { + $this->data = $this->CustomerCategory->read(null, $id); + } + } + + +} +?> diff --git a/controllers/customers_controller.php b/controllers/customers_controller.php index 8fbf7246..c513bdb3 100755 --- a/controllers/customers_controller.php +++ b/controllers/customers_controller.php @@ -14,6 +14,12 @@ class CustomersController extends AppController { function index() { $this->Customer->recursive = 0; $this->set('customers', $this->paginate()); + $this->set('customer_categories', $this->Customer->CustomerCategory->find('all')); + /* Show only customers from a particular category name */ + if(isset($this->params['named']['showonly'])) { + $this->set('customers', $this->paginate('Customer', array('Customer.customer_category_id' => $this->params['named']['showonly']))); + } + } function view($id = null) { @@ -38,6 +44,7 @@ class CustomersController extends AppController { $this->Session->setFlash(__('The Customer could not be saved. Please try again.', true)); } } + $this->set('customer_categories', $this->Customer->CustomerCategory->find('list')); $this->set('states', $this->Customer->Address->State->find('list')); $this->set('countries', $this->Customer->Address->Country->find('list')); @@ -60,6 +67,7 @@ class CustomersController extends AppController { } if (empty($this->data)) { $this->data = $this->Customer->read(null, $id); + $this->set('customer_categories', $this->Customer->CustomerCategory->find('list')); } } diff --git a/controllers/emails_controller.php b/controllers/emails_controller.php index 6747c929..146db243 100644 --- a/controllers/emails_controller.php +++ b/controllers/emails_controller.php @@ -33,6 +33,7 @@ class EmailsController extends AppController { function frame($id = null) { $this->set('id', $id); + $this->set('attachments', $this->Email->EmailAttachment->findAllByEmailId($id)); } function show($id = null) { diff --git a/controllers/enquiries_controller.php b/controllers/enquiries_controller.php index 3e982edf..3ddbd307 100755 --- a/controllers/enquiries_controller.php +++ b/controllers/enquiries_controller.php @@ -261,6 +261,7 @@ class EnquiriesController extends AppController { $enquiry = $this->Enquiry->read(null, $id); $this->Email->to = $enquiry['Contact']['email']; + $this->Email->cc = array($enquiry['User']['email']); $this->Email->bcc = array('carpis@cmctechnologies.com.au'); $this->Email->subject = $enquiry['Enquiry']['title'].' - Your Enquiry has been Entered in our System - CMC Technologies'; diff --git a/controllers/users_controller.php b/controllers/users_controller.php index 85fe9b79..4b2adeac 100755 --- a/controllers/users_controller.php +++ b/controllers/users_controller.php @@ -5,7 +5,11 @@ class UsersController extends AppController { var $helpers = array('Html', 'Form'); var $components = array('Acl','Auth'); var $paginate = array( - 'limit' => 250); + 'Users' => array('order' => array('User.name' => 'asc'), + 'limit' => 20 + ), + 'Enquiry' => array('order' => array('Enquiry.id' => 'desc'), 'limit' => 250) + ); function beforeFilter() { $this->Auth->allow('add'); diff --git a/models/customer.php b/models/customer.php index e7e86bf5..69486a5b 100755 --- a/models/customer.php +++ b/models/customer.php @@ -65,6 +65,9 @@ class Customer extends AppModel { 'counterQuery' => '' ) ); + + var $belongsTo = array('CustomerCategory'=>array('className' => 'CustomerCategory', + 'foreignKey' => 'customer_category_id')); } ?> diff --git a/models/customer_category.php b/models/customer_category.php new file mode 100644 index 00000000..63b3ba7c --- /dev/null +++ b/models/customer_category.php @@ -0,0 +1,12 @@ +array('className'=>'Customer', + 'foreignKey'=>'customer_category_id')); + + + +} + diff --git a/vendors/shells/vault.php b/vendors/shells/vault.php index 558f630c..4a87b053 100644 --- a/vendors/shells/vault.php +++ b/vendors/shells/vault.php @@ -9,19 +9,17 @@ class VaultShell extends Shell { var $uses = array('Enquiry', 'Email', 'EmailAttachment'); - function main() { - + /****************************************************** + * Config Variables + * *****************************************************/ $testing = 1; //Whether to actually move the emails. 1=test, 0=production /* Setup Connection to the IMAP server */ $username = 'vault'; $password = 'xjdYOsmJWc37'; /* The password for the account to be checked */ - $email_dir = '/var/www/quotenik1.2/app/emails/working'; - $attachment_dir = '/var/www/quotenik1.2/app/emails/working/attachments'; $temp_filename = 'temp.eml'; - $mbox = imap_open("{saturn:143/novalidate-cert}INBOX", $username, $password) or die("can't connect: " . imap_last_error()); $MC = imap_check($mbox); $number_of_messages = $MC->Nmsgs; @@ -29,19 +27,9 @@ class VaultShell extends Shell { /* Loop through the messages and sort them into ones to be processed or discarded */ for ($i=1; $i <= $number_of_messages; $i++) { $this_header = imap_headerinfo($mbox, $i); - preg_match("/CMC\d+([NVQWSO]|ACT|NT)E\d+-\d+/", $this_header->subject, $output); - if(isset($output[0])) { - - $fetched_enquirynumber = $output[0]; - $enquiry = $this->Enquiry->findByTitle($fetched_enquirynumber); - - if($enquiry['Enquiry']['id'] == NULL) { //It passes the Regex - but we don't find an Enquiry for it in the MER. - if($testing == 0) { //testing mode. - imap_mail_move($mbox, $i, 'INBOX/Discarded'); //Discard it. - } - } - - else { //Process it and store the message and its attachments. + $enquiry = $this->checkIfValidEnquiry($mbox, $i, $this_header, $testing); + if($enquiry != FALSE) { + //Process it and store the message and its attachments. $message = $this->getMessage($mbox, $i, $this_header); $this->Email->create(); @@ -51,43 +39,78 @@ class VaultShell extends Shell { $this->data['Email']['from'] = $message['from']; $this->data['Email']['date'] = $message['date']; $this->data['Email']['subject'] = $message['subject']; - $this->data['Email']['body'] = $message['body']; - + $this->data['Email']['body'] = ""; + $this->data['Email']['plainbody'] = ""; + $structure = imap_fetchstructure($mbox, $i); + if (empty($structure->parts)) { /* A single part message. No attachments and is plain text */ + $this->data['Email']['body'] = imap_body($mbox, $i); + } + else { + $attachments = $this->fetchBodyAttachments($mbox, $i, $temp_filename, $email_dir); + foreach ($attachments as $attachment) { + if($attachment['type'] == 'text/html') { //Assuming All HTML attachments are the body of the email + + $filecontents = file_get_contents($email_dir.'/'.$attachment['name']); + $size = filesize($email_dir.'/'.$attachment['name']); + $this->data['Email']['body'] .= $filecontents; + + + } + if($attachment['type'] == 'text/plain') { //Found plain text + $filecontents = file_get_contents($email_dir.'/'.$attachment['name']); + $size = filesize($email_dir.'/'.$attachment['name']); + $this->data['Email']['plainbody'] .= $filecontents; + + + } + } + + } + //Sanitize::clean($this->data); if($this->Email->save($this->data)) { $email_id = $this->Email->id; - - $attachment_files = $this->fetchAttachments($mbox, $i, $temp_filename, $email_dir, $attachment_dir); - foreach ($attachment_files as $attachment) { - $this->EmailAttachment->create(); - $this->data['EmailAttachment']['email_id'] = $email_id; - $this->data['EmailAttachment']['name'] = $attachment; - $this->data['EmailAttachment']['type'] = mime_content_type("$attachment_dir/$attachment"); //Depreciated but works better than the new one - $this->data['EmailAttachment']['size'] = filesize("$attachment_dir/$attachment"); - $this->data['EmailAttachment']['data'] = fread(fopen("$attachment_dir/$attachment", "r"), $this->data['EmailAttachment']['size']); - if ($this->EmailAttachment->save($this->data)) { - echo "Saved file successfully to database\n"; + if(isset($attachments)) { + foreach ($attachments as $attachment) { + if( ($attachment['type'] != 'text/html') && ($attachment['type'] != 'multipart/mixed') && + ($attachment['type'] != 'multipart/alternative') ) { + $this->EmailAttachment->create(); + $this->data['EmailAttachment']['email_id'] = $email_id; + $this->data['EmailAttachment']['name'] = $attachment['name']; + $this->data['EmailAttachment']['type'] = $attachment['type']; + $this->data['EmailAttachment']['size'] = filesize($email_dir.'/'.$attachment['name']); + $this->data['EmailAttachment']['data'] = file_get_contents($email_dir.'/'.$attachment['name']); + if ($this->EmailAttachment->save($this->data)) { + echo "Saved file successfully to database\n"; + } + else { + echo "Something went wrong saving the file to the DB\n"; + } + } + } } - else { - echo "Something went wrong saving the file to the DB\n"; + echo "Email stored in the DB under enquiry ".$enquiry['Enquiry']['title']." Will be moved to the stored folder\n"; + + if($testing == 0) { //Testing Mode. Don't actually move these emails unless we're in production. + imap_mail_move($mbox, $i, 'INBOX/Stored'); //Move it to the stored folder. + } + + + + if(isset($attachments)) { + $this->clearEmailAttachmentDirs($email_dir, $temp_filename, $attachments); } - } - echo "Email stored in the DB under enquiry ".$enquiry['Enquiry']['title']." Will be moved to the stored folder\n"; - if($testing == 0) { //Testing Mode. Don't actually move these emails unless we're in production. - imap_mail_move($mbox, $i, 'INBOX/Stored'); //Move it to the stored folder. - } - $this->clearEmailAttachmentDirs($email_dir, $temp_filename, $attachment_dir, $attachment_files); + } else { echo 'Unable to save the Email\n'; } - } - } - else { + + } else { /* Can't find a valid-looking CMC Enquiry Number. Move the message to the discarded folder * I may change this to simply delete the emails. This will do for now, but it's doubling up on the storage for useless files. * */ @@ -101,62 +124,52 @@ class VaultShell extends Shell { } } } - - } - - - + + } /* Finished working with the IMAP server. Make the changes and close the connection */ imap_expunge($mbox); imap_close($mbox); - } - - - - - -/* Fetches and Writes attachements to a directory under $email_dir. - * Uses uudeview to do the decoding - * */ -function fetchAttachments($mailbox, $msg_number, $filename, $email_dir, $attachment_dir) { +} + + + +/* +* Fetches the body and attachments from a MIME encoded email. Uses ripmime to do the decoding + * + */ - /* Make the temporary directory to store this email and the attachments */ - if (!file_exists($email_dir)){ - mkdir($email_dir); - } - if (!file_exists($attachment_dir)) { - mkdir($attachment_dir); - } - +function fetchBodyAttachments($mailbox, $msg_number, $filename, $email_dir) { + $email_file = $email_dir.'/'.$filename; imap_savebody($mailbox, $email_file, $msg_number); - $command = "uudeview -i $email_file -p $attachment_dir"; + $command = "ripmime -i $email_file -d $email_dir -v --verbose-contenttype --paranoid --prefix $msg_number"; $output = array(); exec($command, $output); /* Check the $output array and find the filenames of the attachments */ - $filenames = array(); - - for($i=0; $i< count($output); $i++) { - $matches = preg_match("/\bsuccessfully\b/", $output[$i]); - if($matches > 0) { - $result = explode("/", $output[$i]); - $filenames[] = $result[8]; // - } + $attachments = array(); + + for($i=0, $j=0; $i< count($output); $i++, $j++) { + $words = explode(' ', $output[$i]); + $type = explode('=', $words[1]); + $name = explode('=', $words[2]); + $attachments[$j]['type'] = $type[1]; + $attachments[$j]['name'] = $name[1]; + } - -return $filenames; +return $attachments; } + /* clearEmailyAttachmentDirs($email_dir, $filename, $attachment_dir, $attachments) * - * Deletes $email_dir/$filename.eml and the attachments specified in $attachment_dir + * Deletes $email_dir/$filename.eml and the attachments specified by $attachments * */ -function clearEmailAttachmentDirs($email_dir, $filename, $attachment_dir, $attachments) { +function clearEmailAttachmentDirs($email_dir, $filename, $attachments) { unlink("$email_dir/$filename"); foreach ($attachments as $attachment) { - unlink("$attachment_dir/$attachment"); + unlink($email_dir.'/'.$attachment['name']); } } @@ -172,9 +185,6 @@ function getMessage($mbox, $msgnumber, $headers) { $message['to'] = $recipients['to']; $message['from'] = $recipients['from']; $message['cc'] = $recipients['cc']; - - - $message['body'] = $this->getBody($mbox, $msgnumber); return $message; } @@ -213,8 +223,6 @@ function getRecipients($headers) { } } - - return $recipients; } @@ -230,59 +238,27 @@ function getBody($mbox, $msgnumber) { return $body; } - -function getParts($parts, $mbox, $msgnumber) { - for ($i = 0, $j = count($parts); $i < $j; $i++) { - $part = $parts[$i]; - $bodystruct = imap_bodystruct($mbox, $msgnumber, $i+1); - if ($part->subtype == 'HTML') { /* Find the HTML component of the body */ - $body = imap_fetchbody($mbox, $msgnumber, $i+1); - - if($bodystruct->subtype != 'HTML') { - continue; +function checkIfValidEnquiry($mbox, $msgnumber, $this_header, $testing) { + + preg_match("/CMC\d+([NVQWSO]|ACT|NT)E\d+-\d+/", $this_header->subject, $output); + if(isset($output[0])) { //Found a valid-looking Enquiry Number + $fetched_enquirynumber = $output[0]; + $enquiry = $this->Enquiry->findByTitle($fetched_enquirynumber); + if($enquiry['Enquiry']['id'] == NULL) { //It passes the Regex - but we don't find an Enquiry for it in the MER. + if($testing == 0) { //testing mode == 1, production == 0. + imap_mail_move($mbox, $i, 'INBOX/Discarded'); //Discard it. } - if($bodystruct->subtype == 'HTML') { - break; //Found HTML (preferred) So end the loop. - } - - } - elseif($part->subtype == 'PLAIN') { - $body = imap_fetchbody($mbox, $msgnumber, $i+1); - break; - } - elseif(isset($part->parts)) { - $body = getParts($part->parts, $mbox, $msgnumber); /* Handle these goddamn Outlook messages */ - - } + } + else { + return $enquiry; // Valid Enquiry if we've found the enquiry in the Master Enquiry Register + } + } + else { + return FALSE; } - return $body; } -/* -function getParts($parts, $mbox, $msgnumber) { - for ($i = 0, $j = count($parts); $i < $j; $i++) { - $part = $parts[$i]; - - - if ($part->subtype == 'HTML') { /* Find the HTML component of the body - $body = imap_fetchbody($mbox, $msgnumber, $i+1); - break; //Found HTML (preferred) So end the loop. - } - elseif($part->subtype == 'PLAIN') { - $body = imap_fetchbody($mbox, $msgnumber, $i+1); - - } - elseif(isset($part->parts)) { - $body = $this->getParts($part->parts, $mbox, $msgnumber); /* Handle these goddamn Outlook messages - - } - } - return $body; - -} -*/ - } diff --git a/views/customer_categories/add.ctp b/views/customer_categories/add.ctp new file mode 100644 index 00000000..a3988686 --- /dev/null +++ b/views/customer_categories/add.ctp @@ -0,0 +1,17 @@ +
+create('CustomerCategory');?> +
+ + input('name'); + ?> +
+end('Submit');?> +
+
+ +
diff --git a/views/customer_categories/edit.ctp b/views/customer_categories/edit.ctp new file mode 100644 index 00000000..07169984 --- /dev/null +++ b/views/customer_categories/edit.ctp @@ -0,0 +1,19 @@ +
+create('CustomerCategory');?> +
+ + input('id'); + echo $form->input('name'); + ?> +
+end('Submit');?> +
+
+ +
diff --git a/views/customer_categories/index.ctp b/views/customer_categories/index.ctp new file mode 100644 index 00000000..dbe95642 --- /dev/null +++ b/views/customer_categories/index.ctp @@ -0,0 +1,50 @@ +
+

+

+counter(array( +'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true) +)); +?>

+ + + + + + + + > + + + + + +
sort('id');?>sort('name');?>
+ + + + + link(__('View', true), array('action'=>'view', $customerCategory['CustomerCategory']['id'])); ?> + link(__('Edit', true), array('action'=>'edit', $customerCategory['CustomerCategory']['id'])); ?> + +
+
+
+ prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));?> + | numbers();?> + next(__('next', true).' >>', array(), null, array('class'=>'disabled'));?> +
+
+ +
diff --git a/views/customer_categories/view.ctp b/views/customer_categories/view.ctp new file mode 100644 index 00000000..ba850ac8 --- /dev/null +++ b/views/customer_categories/view.ctp @@ -0,0 +1,73 @@ +
+

+
+ > + > + +   + + > + > + +   + +
+
+
+ +
+ diff --git a/views/customers/add.ctp b/views/customers/add.ctp index b7064348..55600527 100755 --- a/views/customers/add.ctp +++ b/views/customers/add.ctp @@ -18,6 +18,10 @@ echo $this->element('payment_terms_box'); echo $form->input('discount_pricing_policies', array('label'=>'Discount and Pricing Policies')); + echo '
'; + echo $form->label('Customer.customer_category_id', 'Customer Category'); + echo $form->select('customer_category_id', $customer_categories, 0, array('label'=>'Customer Category'), false); + echo '
'; echo $form->input('notes', array('label' => 'Notes about this Customer')); echo '

'; diff --git a/views/customers/edit.ctp b/views/customers/edit.ctp index c0a16c85..d3c1cb43 100755 --- a/views/customers/edit.ctp +++ b/views/customers/edit.ctp @@ -9,6 +9,10 @@ echo $this->element('payment_terms_box'); echo $form->input('discount_pricing_policies', array('label'=>'Discount and Pricing Policies')); echo $form->input('notes'); + echo '
'; + echo $form->label('Customer.customer_category_id', 'Customer Category'); + echo $form->select('customer_category_id', $customer_categories, 0, array('label'=>'Customer Category'), false); + echo '
'; ?> end('Submit');?> diff --git a/views/customers/index.ctp b/views/customers/index.ctp index 1a50f992..256b0822 100755 --- a/views/customers/index.ctp +++ b/views/customers/index.ctp @@ -1,5 +1,12 @@

+ +link($category['CustomerCategory']['name'], array('action'=>"index/showonly:".$category['CustomerCategory']['id'])).' '; +} +?>
+

counter(array( @@ -12,6 +19,7 @@ echo $paginator->counter(array( sort('Company Name', 'name');?> sort('ABN', 'abn');?> sort('Payment Terms', 'payment_terms'); ?> + sort('Category', 'customer_category_id'); ?> sort('Date Added', 'created');?> @@ -22,6 +30,18 @@ foreach ($customers as $customer): if ($i++ % 2 == 0) { $class = ' class="altrow"'; } + if($customer['Customer']['customer_category_id'] == 1) { + $class = ' class="customer-suspect"'; + } + if($customer['Customer']['customer_category_id'] == 2) { + $class = ' class="customer-prospect"'; + } + if($customer['Customer']['customer_category_id'] == 3) { + $class = ' class="customer-customer"'; + } + + + ?> > @@ -34,6 +54,10 @@ foreach ($customers as $customer): + + + + toUnix($customer['Customer']['created'])); ?> diff --git a/views/customers/view.ctp b/views/customers/view.ctp index 4be8a79b..232ac94c 100755 --- a/views/customers/view.ctp +++ b/views/customers/view.ctp @@ -31,6 +31,11 @@   + > + > + +   +

diff --git a/views/elements/email_attachments.ctp b/views/elements/email_attachments.ctp new file mode 100644 index 00000000..181d7d56 --- /dev/null +++ b/views/elements/email_attachments.ctp @@ -0,0 +1,57 @@ + + diff --git a/views/emails/frame.ctp b/views/emails/frame.ctp index b5338073..28cb3c31 100644 --- a/views/emails/frame.ctp +++ b/views/emails/frame.ctp @@ -1,3 +1,11 @@ + + +
+

Email

+
+
+element('email_attachments', $attachments); ?> +
diff --git a/views/emails/print.ctp b/views/emails/print.ctp new file mode 100644 index 00000000..77e24a12 --- /dev/null +++ b/views/emails/print.ctp @@ -0,0 +1,52 @@ + + + +
+ +Enquiry Number:
+Date:
+Subject:
+To:
+From:
+CC:
+ +
+ + + +
+ + +
diff --git a/views/emails/show.ctp b/views/emails/show.ctp index 3a3ff52e..530f149f 100644 --- a/views/emails/show.ctp +++ b/views/emails/show.ctp @@ -41,40 +41,5 @@ - diff --git a/views/enquiries/view.ctp b/views/enquiries/view.ctp index 36cf375b..99940b01 100755 --- a/views/enquiries/view.ctp +++ b/views/enquiries/view.ctp @@ -97,14 +97,16 @@
  • link(__('Edit Enquiry', true), array('action'=>'edit', $enquiry['Enquiry']['id'])); ?>
  • +
    + +
    -
    -
    +