aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--classes/Correspondence.php179
-rw-r--r--classes/Offer.php22
-rw-r--r--footer.php16
-rw-r--r--include/ajax-email-offer.php86
-rw-r--r--include/offers-view.php20
-rw-r--r--include/offers.php115
-rw-r--r--index.php1
-rw-r--r--js/businessadmin.js50
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();
}
/**
diff --git a/footer.php b/footer.php
index 308b1d0..75df9cf 100644
--- a/footer.php
+++ b/footer.php
@@ -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">&times;</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');
diff --git a/index.php b/index.php
index 6c049af..4467853 100644
--- a/index.php
+++ b/index.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>');
+ }
+ });
+}