diff options
-rw-r--r-- | classes/Correspondence.php | 179 | ||||
-rw-r--r-- | classes/Offer.php | 22 | ||||
-rw-r--r-- | footer.php | 16 | ||||
-rw-r--r-- | include/ajax-email-offer.php | 86 | ||||
-rw-r--r-- | include/offers-view.php | 20 | ||||
-rw-r--r-- | include/offers.php | 115 | ||||
-rw-r--r-- | index.php | 1 | ||||
-rw-r--r-- | js/businessadmin.js | 50 |
8 files changed, 344 insertions, 145 deletions
diff --git a/classes/Correspondence.php b/classes/Correspondence.php index 09873c3..80c4c87 100644 --- a/classes/Correspondence.php +++ b/classes/Correspondence.php @@ -51,62 +51,65 @@ class Correspondence extends FPDF { * * @see _() A function to translate */ - protected static $translations = array( - 'adres' => array( - 'en' => 'Address', - 'nl' => 'Adres'), - 'amount' => array( - 'en' => 'Amount', - 'nl' => 'Subtotaal'), - 'amount-due' => array( - 'en' => 'Total amount due', - 'nl' => 'Te voldoen'), - 'biccode' => array( - 'en' => 'The BIC code of our bank is %%.', - 'nl' => 'De BIC-code van de bank is %%.'), - 'btwnr' => array( - 'en' => 'VAT nr', - 'nl' => 'BTW nr'), - 'description' => array( - 'en' => 'Description', - 'nl' => 'Omschrijving'), - 'due-date' => array( - 'en' => 'Due date', - 'nl' => 'Vervaldatum'), - 'email' => array( - 'en' => 'Email', - 'nl' => 'Email'), - 'iban' => array( - 'en' => 'IBAN', - 'nl' => 'IBAN'), - 'invoice' => array( - 'en' => 'Invoice', - 'nl' => 'Factuur'), - 'invoice-date' => array( - 'en' => 'Invoice date', - 'nl' => 'Factuurdatum'), - 'invoice-nr' => array( - 'en' => 'Invoice number', - 'nl' => 'Factuurnummer'), - 'price-excl' => array( - 'en' => 'Price excl.', - 'nl' => 'Prijs excl.'), - 'price-incl' => array( - 'en' => 'Price incl.', - 'nl' => 'Prijs incl.'), - 'request' => array( - 'en' => 'You are kindly requested to transfer the total amount before the due date to the provided IBAN nr.', - 'nl' => 'U wordt vriendelijk verzocht het te voldoen bedrag voor de vervaldatum van de factuur over te maken naar opgegeven IBAN-nummer.'), - 'tel-nr' => array( - 'en' => 'Tel.', - 'nl' => 'Tel.'), - 'total' => array( - 'en' => 'Total', - 'nl' => 'Totaal'), - 'vat' => array( - 'en' => 'VAT', - 'nl' => 'BTW'), - ); + protected static $translations = [ + 'adres' => [ + 'en' => 'Address', + 'nl' => 'Adres'], + 'amount' => [ + 'en' => 'Amount', + 'nl' => 'Subtotaal'], + 'amount-due' => [ + 'en' => 'Total amount due', + 'nl' => 'Te voldoen'], + 'biccode' => [ + 'en' => 'The BIC code of our bank is %%.', + 'nl' => 'De BIC-code van de bank is %%.'], + 'btwnr' => [ + 'en' => 'VAT nr', + 'nl' => 'BTW nr'], + 'description' => [ + 'en' => 'Description', + 'nl' => 'Omschrijving'], + 'due-date' => [ + 'en' => 'Due date', + 'nl' => 'Vervaldatum'], + 'email' => [ + 'en' => 'Email', + 'nl' => 'Email'], + 'iban' => [ + 'en' => 'IBAN', + 'nl' => 'IBAN'], + 'invoice' => [ + 'en' => 'Invoice', + 'nl' => 'Factuur'], + 'invoice-date' => [ + 'en' => 'Invoice date', + 'nl' => 'Factuurdatum'], + 'invoice-nr' => [ + 'en' => 'Invoice number', + 'nl' => 'Factuurnummer'], + 'price-excl' => [ + 'en' => 'Price excl.', + 'nl' => 'Prijs excl.'], + 'price-incl' => [ + 'en' => 'Price incl.', + 'nl' => 'Prijs incl.'], + 'request' => [ + 'en' => 'You are kindly requested to transfer the total amount before the due date to the provided IBAN nr.', + 'nl' => 'U wordt vriendelijk verzocht het te voldoen bedrag voor de vervaldatum van de factuur over te maken naar opgegeven IBAN-nummer.'], + 'tel-nr' => [ + 'en' => 'Tel.', + 'nl' => 'Tel.'], + 'total' => [ + 'en' => 'Total', + 'nl' => 'Totaal'], + 'vat' => [ + 'en' => 'VAT', + 'nl' => 'BTW'], + 'mail-offer' => [ + 'en' => "Dear {{getContact-name}},\r\n\r\nPlease find attached your invoice. You can either pay by bank transfer, as indicated on the invoice, or using Paypal or a credit card on {{getPaymentUrl}}.\r\n\r\nThank you in advance,\r\n\r\n{{{invoice_name}}}", + 'nl' => "Beste {{getContact-name}},\r\n\r\nBijgevoegd vindt u uw factuur. U kunt per bankoverschrijving betalen, zoals aangegeven op de factuur, of met Paypal of een credit card op {{getPaymentUrl}}.\r\n\r\nAlvast hartelijk dank,\r\n\r\n{{{invoice_name}}}"], + ]; /** @var $page_height The height of a page in millimeters */ protected static $page_height = 297; // A4 @@ -119,7 +122,6 @@ class Correspondence extends FPDF { * @see $translations The array holding the translations * * @param string $key The string to translate - * @param string $lang The language to translate to (two-letter code) * * @return string The translated string */ @@ -130,6 +132,69 @@ class Correspondence extends FPDF { } /** + * Translate a string, statically + * + * @param string $key The string to translate + * @param string $lang The language to translate to (two-letter code) + * + * @return string The translated string + */ + public static function __($key, $lang) { + if (!array_key_exists($key, self::$translations)) + return $key; + if (!array_key_exists($lang, self::$translations[$key])) + return $key; + return self::$translations[$key][$lang]; + } + + /** + * Translate a string, statically, and resolve (@see resolve) it + * + * @param string $key The string to translate + * @param string $lang The language to translate to (two-letter code) + * @param mixed $obj The object to resolve + * + * @return string The resolved translated string + */ + public static function __r($key, $lang, $obj) { + return self::resolve(self::__($key, $lang), $obj); + } + + /** + * Resolve a string + * + * Resolves {{keyA-keyB-keyC}} to e.g. $obj->keyA()->keyB->keyC(), where + * first the function (e.g. keyA()) is tried, and then the property (e.g. + * keyB). + * + * Resolves {{{const}}} to Constants::const. + * + * @param string $string The string to resolve + * @param mixed $obj The object to use + * + * @return string The generated string + */ + public static function resolve($string, $obj) { + $string = preg_replace_callback('/\{\{\{(\w+)\}\}\}/', function ($matches) { + $key = $matches[1]; + return constant("Constants::$key"); + }, $string); + $string = preg_replace_callback('/\{\{([\w-]+)\}\}/', function ($matches) use ($obj) { + $keys = explode('-', $matches[1]); + $temp = $obj; + foreach ($keys as $key) { + if (method_exists($temp, $key)) { + $temp = call_user_func([$temp, $key]); + } else { + $temp = $temp->$key; + } + } + return $temp; + }, $string); + return $string; + } + + /** * Create a new PDF * * @param string $orientation See the FPDF class specs diff --git a/classes/Offer.php b/classes/Offer.php index 7b0d2fc..2a48604 100644 --- a/classes/Offer.php +++ b/classes/Offer.php @@ -87,6 +87,15 @@ class Offer extends Model{ } /** + * Get the URL on which the offer can be paid + * + * @return string The URL + */ + public function getPaymentUrl() { + return Constants::url_external . "pay?id={$this->id}&key={$this->payment_key}"; + } + + /** * Get the contact that this offer is linked to * * @return contact The contact @@ -301,6 +310,11 @@ class Offer extends Model{ public function mailer() { $mailer = new Mailer($this->pdo); $mailer->setOffer($this); + + $mailer->addAttachment($this->getInvoiceFile()->getFilenamePath()); + $mailer->Subject = 'Your invoice'; + $mailer->Body = Correspondence::__r('mail-offer', $this->getContact()->language, $this); + return $mailer; } @@ -310,13 +324,7 @@ class Offer extends Model{ * @return bool The result of Mailer::send */ public function send() { - $mailer = $this->mailer(); - - $mailer->addAttachment($this->getInvoiceFile()->getFilenamePath()); - $mailer->Subject = 'Your invoice'; - $mailer->Body = 'Here is your invoice.'; - - return $mailer->send(); + return $this->mailer()->send(); } /** @@ -1,2 +1,18 @@ + <div class="modal fade" tabindex="-1" role="dialog" id="modal-email"> + <div class="modal-dialog modal-lg" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> + <h4 class="modal-title">Email</h4> + </div> + <div class="modal-body"> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> + <button type="button" class="btn btn-primary btn-send" onclick='sendMail()'><i class="fa fa-fw fa-envelope"></i> Send</button> + </div> + </div> + </div> + </div> </body> </html> diff --git a/include/ajax-email-offer.php b/include/ajax-email-offer.php new file mode 100644 index 0000000..3960d37 --- /dev/null +++ b/include/ajax-email-offer.php @@ -0,0 +1,86 @@ +<?php +/** + * BusinessAdmin: administrative software for small companies + * Copyright (C) 2015 Camil Staps (ViviSoft) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +require_once('./login-ajax.php'); + +$_offer = new Offer($_pdo, $_REQUEST['id']); +$_mailer = $_offer->mailer(); + +function format_email($address) { + if ($address[1] != '') { + return "{$address[1]} <{$address[0]}>"; + } else { + return $address[0]; + } +} + +if ($_SERVER['REQUEST_METHOD'] === 'GET') { +?> + <form action='#' class='form-horizontal' method='post'> + <input type='hidden' name='id' value='<?=$_offer->id?>'/> + <div class='form-group'> + <label class='col-sm-2 control-label'>From</label> + <div class='col-sm-10'><input class='form-control input-sm' type='text' readonly='readonly' name='from' value='<?=$_mailer->FromName?> <<?=$_mailer->From?>>'/></div> + </div> + <?php foreach ($_mailer->getReplyToAddresses() as $addr) { ?> + <div class='form-group'> + <label class='col-sm-2 control-label'>Reply-To</label> + <div class='col-sm-10'><input class='form-control input-sm' type='text' readonly='readonly' name='replyto[]' value='<?=format_email($addr)?>'/></div> + </div> + <?php } foreach ($_mailer->getBccAddresses() as $addr) { ?> + <div class='form-group'> + <label class='col-sm-2 control-label'>BCC</label> + <div class='col-sm-10'><input class='form-control input-sm' type='text' readonly='readonly' name='bcc[]' value='<?=format_email($addr)?>'/></div> + </div> + <?php } foreach ($_mailer->getCcAddresses() as $addr) { ?> + <div class='form-group'> + <label class='col-sm-2 control-label'>CC</label> + <div class='col-sm-10'><input class='form-control input-sm' type='text' readonly='readonly' name='cc[]' value='<?=format_email($addr)?>'/></div> + </div> + <?php } foreach ($_mailer->getToAddresses() as $addr) { ?> + <div class='form-group'> + <label class='col-sm-2 control-label'>To</label> + <div class='col-sm-10'><input class='form-control input-sm' type='text' readonly='readonly' name='to[]' value='<?=format_email($addr)?>'/></div> + </div> + <?php } ?> + <div class='form-group'> + <label class='col-sm-2 control-label'>Subject</label> + <div class='col-sm-10'><input class='form-control input-sm' type='text' name='subject' value='<?=$_mailer->Subject?>'/></div> + </div> + <div class='form-group'> + <label class='col-sm-2 control-label'>Body</label> + <div class='col-sm-10'><textarea class='form-control input-sm' rows='10' name='body'><?=$_mailer->Body?></textarea></div> + </div> + </form> +<?php +} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') { + $_mailer->Subject = $_POST['subject']; + $_mailer->Body = $_POST['body']; + try { + if ($_mailer->send()) { + echo 'OK'; + } else { + http_response_code(500); + echo 'Sending the email failed:<br/>' . $_mailer->ErrorInfo; + } + } catch (Exception $e) { + http_response_code(500); + echo "Sending the email failed with an exception ({$e->getCode()}): {$e->getMessage()}<br/>" . $e->getTraceAsString(); + } +} diff --git a/include/offers-view.php b/include/offers-view.php index d96e9ed..ec579b6 100644 --- a/include/offers-view.php +++ b/include/offers-view.php @@ -107,26 +107,6 @@ $_offer = new Offer($_pdo, $_id); </div> </div> </div> -<div class="clearfix"></div> -<div class="col-md-6"> - <div class="panel panel-default"> - <div class="panel-heading">Tools</div> - <div class="panel-body"> - <?php - $accepted = $_offer->accepted ? - ['Accepted', 'btn-success'] : - ['Not accepted', 'btn-default']; - $eligible = $_offer->getPaymentEligibility() ? - ['Eligible for online payment', 'btn-success'] : - ['Not eligible for online payment', 'btn-default']; - ?> - <a title='<?=$accepted[0]?>' href='?id=<?=$_offer->id?>&toggle_accept=<?=$_offer->id?>' class='btn <?=$accepted[1]?>'><i class='fa fa-fw fa-check'></i> <?=$accepted[0]?></a> - <a title='<?=$eligible[0]?>' href='?id=<?=$_offer->id?>&toggle_payment_eligibility=<?=$_offer->id?>' class='btn <?=$eligible[1]?>'><i class='fa fa-fw fa-credit-card'></i> <?=$eligible[0]?></a> - <a title='Send invoice' href='?id=<?=$_offer->id?>&send_invoice=<?=$_offer->id?>' class='btn btn-info'><i class='fa fa-fw fa-envelope'></i> Send invoice to contact</a> - <a title='Delete' href='?delete=<?=$_offer->id?>' class='btn btn-danger'><i class='fa fa-fw fa-times'></i> Delete</a> - </div> - </div> -</div> <div class="col-md-6"> <div class="panel panel-default" id="panel-timeline"> <div class="panel-heading"> diff --git a/include/offers.php b/include/offers.php index dbe5df0..e06a4eb 100644 --- a/include/offers.php +++ b/include/offers.php @@ -41,49 +41,22 @@ require('./header.php'); // ?delete=<id> Delete the offer with id <id> //------------------------------------------------------------------------------ - // The header of the page - $header = 'Offers'; - // Whether or not to show an individual offer in the end (false if not, or the id if yes) - $show_individual = false; - - // View offer - if (isset($_GET['id'])) { - $id = (int) $_GET['id']; - try { - $offer = new Offer($_pdo, $id); - $header = "<a href='".Constants::url_external."offers'>Offers</a> / #{$offer->id}"; - $show_individual = $id; - } catch (PDOException $e) { - $alert = "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer with id $id</i> could not be found.</div>"; - } catch (Exception $e) { - $alert = "<div class='alert alert-warning alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer with id $id</i> could not be found.</div>"; - } - } - - // Show the header - echo "<div class='col-lg-12'><h1 class='page-header'>$header</h1></div>"; - if (isset($alert)) echo "<div class='col-lg-12'>$alert</div>"; - // Accept offer if (isset($_GET['toggle_accept'])) { - echo "<div class='col-lg-12'>"; $id = (int) $_GET['toggle_accept']; try { $offer = new Offer($_pdo, $id); $offer->accepted = !$offer->accepted; - echo "<div class='alert alert-success alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The status of offer #{$offer->id} has been set to <i>".($offer->accepted ? "accepted" : "unaccepted")."</i>.</div>"; + $alert = "<div class='alert alert-success alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The status of offer #{$offer->id} has been set to <i>".($offer->accepted ? "accepted" : "unaccepted")."</i>.</div>"; } catch (PDOException $e) { - echo "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The status of the offer could not be changed due to a PDO error.</div>"; + $alert = "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The status of the offer could not be changed due to a PDO error.</div>"; } catch (Exception $e) { - echo "<div class='alert alert-warning alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer with id {$id} could not be found.</div>"; + $alert = "<div class='alert alert-warning alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer with id {$id} could not be found.</div>"; } - - echo "</div>"; } // Toggle offer payment eligibility if (isset($_GET['toggle_payment_eligibility'])) { - echo "<div class='col-lg-12'>"; $id = (int) $_GET['toggle_payment_eligibility']; try { $offer = new Offer($_pdo, $id); @@ -92,91 +65,117 @@ require('./header.php'); } else { $offer->payment_key = Offer::getRandomPaymentKey(); } - echo "<div class='alert alert-success alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer #{$offer->id} is now <i>".($offer->getPaymentEligibility() ? "eligible" : "ineligible")."</i> for online payment.</div>"; + $alert = "<div class='alert alert-success alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer #{$offer->id} is now <i>".($offer->getPaymentEligibility() ? "eligible" : "ineligible")."</i> for online payment.</div>"; } catch (PDOException $e) { - echo "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The online payment eligibility could not be changed due to a PDO error.</div>"; + $alert = "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The online payment eligibility could not be changed due to a PDO error.</div>"; } catch (Exception $e) { - echo "<div class='alert alert-warning alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer with id {$id} could not be found.</div>"; + $alert = "<div class='alert alert-warning alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer with id {$id} could not be found.</div>"; } - - echo "</div>"; } // Generate invoice if (isset($_GET['generate_invoice'])) { - echo "<div class='col-lg-12'>"; $id = (int) $_GET['generate_invoice']; try { $offer = new Offer($_pdo, $id); $file = $offer->generateInvoice(); - echo "<div class='alert alert-success alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice for offer #{$offer->id} is generated: <a class='alert-link' href='{$file->getFilenameURI()}' target='_blank'>{$file->filename}</a></div>"; + $alert = "<div class='alert alert-success alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice for offer #{$offer->id} is generated: <a class='alert-link' href='{$file->getFilenameURI()}' target='_blank'>{$file->filename}</a></div>"; } catch (PDOException $e) { - echo "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice for offer #{$offer->id} could not be generated due to a PDO error.</div>"; + $alert = "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice for offer #{$offer->id} could not be generated due to a PDO error.</div>"; } catch (Exception $e) { - echo "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice for offer #{$id} could not be generated.</div>"; + $alert = "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice for offer #{$id} could not be generated.</div>"; } - echo "</div>"; } // Trash invoice if (isset($_GET['trash_invoice'])) { - echo "<div class='col-lg-12'>"; $id = (int) $_GET['trash_invoice']; try { $offer = new Offer($_pdo, $id); $file = $offer->getInvoiceFile(); if ($file instanceof file && $file->delete()) { - echo "<div class='alert alert-success alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice for offer #{$offer->id} is trashed.</div>"; + $alert = "<div class='alert alert-success alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice for offer #{$offer->id} is trashed.</div>"; } else { - echo "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice for offer #{$id} could not be trashed.</div>"; + $alert = "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice for offer #{$id} could not be trashed.</div>"; } } catch (PDOException $e) { - echo "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice for offer #{$offer->id} could not be trashed due to a PDO error.</div>"; + $alert = "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice for offer #{$offer->id} could not be trashed due to a PDO error.</div>"; } catch (Exception $e) { - echo "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice for offer #{$id} could not be trashed.</div>"; + $alert = "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice for offer #{$id} could not be trashed.</div>"; } - echo "</div>"; } // Send invoice if (isset($_GET['send_invoice'])) { - echo "<div class='col-lg-12'>"; $id = (int) $_GET['send_invoice']; try { $offer = new Offer($_pdo, $id); if ($offer->send()) { - echo "<div class='alert alert-success alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice for offer {$id} has been sent to {$offer->getContact()->email}.</div>"; + $alert = "<div class='alert alert-success alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice for offer {$id} has been sent to {$offer->getContact()->email}.</div>"; } else { - echo "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice could not be sent due to an unknown error.</div>"; + $alert = "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice could not be sent due to an unknown error.</div>"; } } catch (PDOException $e) { - echo "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice could not be sent due to a PDO error.</div>"; + $alert = "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The invoice could not be sent due to a PDO error.</div>"; } catch (Exception $e) { - echo "<div class='alert alert-warning alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer with id {$id} could not be found.</div>"; + $alert = "<div class='alert alert-warning alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer with id {$id} could not be found.</div>"; } - echo "</div>"; } // Delete offer if (isset($_GET['delete'])) { - echo "<div class='col-lg-12'>"; $id = (int) $_GET['delete']; try { $offer = new Offer($_pdo, $id); if ($offer->delete()) { - echo "<div class='alert alert-success alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer #{$offer->id} has been removed.</div>"; + $alert = "<div class='alert alert-success alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer #{$offer->id} has been removed.</div>"; } else { - echo "<div class='alert alert-warning alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer #{$offer->id} could not be removed. Perhaps it's already removed?</div>"; + $alert = "<div class='alert alert-warning alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer #{$offer->id} could not be removed. Perhaps it's already removed?</div>"; } } catch (PDOException $e) { - echo "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer could not be removed due to a PDO error.</div>"; + $alert = "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer could not be removed due to a PDO error.</div>"; } catch (Exception $e) { - echo "<div class='alert alert-warning alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer with id {$id} could not be found.</div>"; + $alert = "<div class='alert alert-warning alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer with id {$id} could not be found.</div>"; } + } + + //------------------------------------------------------------------------------ + // The header of the page + //------------------------------------------------------------------------------ + $header = 'Offers'; + // Whether or not to show an individual offer in the end (false if not, or the id if yes) + $show_individual = false; - echo "</div>"; + // View offer + if (isset($_GET['id'])) { + $id = (int) $_GET['id']; + try { + $offer = new Offer($_pdo, $id); + $header = "<a href='".Constants::url_external."offers'>Offers</a> / #{$offer->id}"; + $show_individual = $id; + $accepted = $offer->accepted ? + ['Accepted', 'btn-success'] : + ['Not accepted', 'btn-default']; + $eligible = $offer->getPaymentEligibility() ? + ['Eligible for online payment', 'btn-success'] : + ['Not eligible for online payment', 'btn-default']; + $header .= "<span class='pull-right'> + <a title='{$accepted[0]}' href='?id={$offer->id}&toggle_accept={$offer->id}' class='btn {$accepted[1]}'><i class='fa fa-fw fa-check'></i> {$accepted[0]}</a> + <a title='{$eligible[0]}' href='?id={$offer->id}&toggle_payment_eligibility={$offer->id}' class='btn {$eligible[1]}'><i class='fa fa-fw fa-credit-card'></i> {$eligible[0]}</a> + <a title='Send invoice' href='#' onclick='offerEmail({$offer->id})' class='btn btn-info'><i class='fa fa-fw fa-envelope'></i> Send invoice to contact</a> + <a title='Delete' href='?delete={$offer->id}' class='btn btn-danger'><i class='fa fa-fw fa-times'></i> Delete</a> + </span>"; + } catch (PDOException $e) { + $alert = "<div class='alert alert-danger alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer with id $id</i> could not be found.</div>"; + } catch (Exception $e) { + $alert = "<div class='alert alert-warning alert-dismissable'><button type='button' class='close fa fa-times' data-dismiss='alert' aria-hidden='true'></button>The offer with id $id</i> could not be found.</div>"; + } } + // Show the header + echo "<div class='col-lg-12'><h1 class='page-header'>$header</h1></div>"; + if (isset($alert)) echo "<div class='col-lg-12'>$alert</div>"; + if ($show_individual !== false) { $_id = $show_individual; require('offers-view.php'); @@ -56,6 +56,7 @@ $pages = array( '/settings' => './include/settings.php', '/users/new' => './include/users-new.php', '/ajax/collapse' => './include/ajax-collapse.php', + '/ajax/email/offer' => './include/ajax-email-offer.php', '/pay' => './include/pay.php', '/file/get' => './include/file-get.php' ); diff --git a/js/businessadmin.js b/js/businessadmin.js index e5da52e..1d00fa9 100644 --- a/js/businessadmin.js +++ b/js/businessadmin.js @@ -108,9 +108,6 @@ $(document).ready(function(){ method: 'GET', crossDomain: true, cache: false, - xhrFields: { - withCredentials: true - }, data: { setting: collapsed } @@ -119,3 +116,50 @@ $(document).ready(function(){ return true; }); }); + +// Email modal +function sendMail() { + var modal = $('#modal-email'); + var modalBody = modal.find('.modal-body'); + var sendIcon = modal.find('.modal-footer .btn-send .fa'); + var values = modalBody.find('form').serialize(); + modalBody.find(':input').prop('disabled', true); + sendIcon.removeClass('fa-envelope').addClass('fa-spin fa-refresh'); + $.ajax({ + url: const_url_external + 'ajax/email/offer', + method: 'POST', + data: values, + success: function(data) { + modal.modal('hide'); + modalBody.html(''); + }, + error: function(jqxhr, stat, err) { + modalBody.find('.alert').remove(); + modalBody.html('<div class="alert alert-danger" role="alert">' + stat + ': ' + err + '</div>' + modalBody.html()); + }, + complete: function() { + modalBody.find(':input').prop('disabled', false); + sendIcon.addClass('fa-envelope').removeClass('fa-spin fa-refresh'); + } + }); +} + +function offerEmail(offerId) { + var modal = $('#modal-email'); + var modalBody = modal.find('.modal-body'); + modal.modal('show'); + modalBody.html('<i class="fa fa-fw fa-refresh fa-spin"></i>'); + $.ajax({ + url: const_url_external + 'ajax/email/offer', + method: 'GET', + data: { + id: offerId + }, + success: function(data) { + modalBody.html(data); + }, + error: function(jqxhr, stat, err) { + modalBody.html('<div class="alert alert-danger" role="alert">' + stat + ': ' + err + '</div>'); + } + }); +} |