aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/404.php45
-rw-r--r--include/about.php107
-rw-r--r--include/assignments-edit.php59
-rw-r--r--include/assignments-new.php45
-rw-r--r--include/assignments-overview.php170
-rw-r--r--include/assignments-view.php0
-rw-r--r--include/assignments.php98
-rw-r--r--include/clients-edit.php42
-rw-r--r--include/clients-new.php38
-rw-r--r--include/clients-overview.php118
-rw-r--r--include/clients-view.php62
-rw-r--r--include/clients.php98
-rw-r--r--include/contacts-edit.php65
-rw-r--r--include/contacts-new.php47
-rw-r--r--include/contacts-overview.php168
-rw-r--r--include/contacts.php98
-rw-r--r--include/home.php274
-rw-r--r--include/offers-edit.php59
-rw-r--r--include/offers-new.php39
-rw-r--r--include/offers-overview.php169
-rw-r--r--include/offers-view.php130
-rw-r--r--include/offers.php157
22 files changed, 2088 insertions, 0 deletions
diff --git a/include/404.php b/include/404.php
new file mode 100644
index 0000000..335ebf7
--- /dev/null
+++ b/include/404.php
@@ -0,0 +1,45 @@
+<?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('./index.php');
+require('./header.php');
+?>
+
+<div id="wrapper">
+
+ <?php require('nav.php'); ?>
+
+ <!-- Page Content -->
+ <div id="page-wrapper">
+ <div class="row">
+ <div class="col-lg-12">
+ <h1>404</h1>
+ <p class="lead">The page you requested could not be found.</p>
+ </div>
+ <!-- /.col-lg-12 -->
+ </div>
+ <!-- /.row -->
+ </div>
+ <!-- /#page-wrapper -->
+
+</div>
+<!-- /#wrapper -->
+<?php
+require('./footer.php');
+?> \ No newline at end of file
diff --git a/include/about.php b/include/about.php
new file mode 100644
index 0000000..a428ce6
--- /dev/null
+++ b/include/about.php
@@ -0,0 +1,107 @@
+<?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('./index.php');
+require('./header.php');
+?>
+
+<div id="wrapper">
+
+ <?php require('nav.php'); ?>
+
+ <!-- Page Content -->
+ <div id="page-wrapper">
+ <div class="row">
+ <div class="col-lg-12">
+ <h1 class="page-header">About</h1>
+ </div>
+ <!-- /.col-lg-12 -->
+ </div>
+
+ <div class="row">
+ <div class="col-md-8">
+ <div class="panel panel-default">
+ <div class="panel-heading">About</div>
+ <div class="panel-body">
+ <p class="lead">This control panel was made using BusinessAdmin. It is open source software under the GPL 3.0 license.</p>
+ <p>A full version of the license is available <a href="<?=constants::url_external?>LICENSE">here</a>. An excerpt is shown below:</p>
+ <pre>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/.
+
+You can contact me, Camil Staps, here:
+
+Camil Staps
+www.camilstaps.nl
+info@camilstaps.nl</pre>
+ </div>
+ </div>
+ </div>
+ <!-- /.col-lg-12 -->
+
+ <div class="col-md-4">
+ <div class="panel panel-default" id="panel-contact">
+ <div class="panel-heading">Contact</div>
+ <div class="panel-body">
+ <img class="gravatar pull-right" src="https://www.gravatar.com/avatar/<?=md5('info@camilstaps.nl')?>?d=mm"/>
+ <p>For things related to BusinessAdmin, please use GitHub: <a href="https://github.com/camilstaps/BusinessAdmin">camilstaps/BusinessAdmin</a></p>
+ <p>The BusinessAdmin system was developed by <a href="http://camilstaps.nl/">Camil Staps</a>. See my website for contact details.</p>
+ </div>
+ </div>
+ </div>
+
+ <div class="col-md-4">
+ <div class="panel panel-default" id="panel-contact">
+ <div class="panel-heading">Thanks</div>
+ <div class="panel-body">
+ <p>BusinessAdmin was created using:</p>
+ <ul>
+ <li><a href="http://startbootstrap.com/template-overviews/sb-admin-2/">SB Admin 2</a></li>
+ <li><a href="http://getbootstrap.com">Bootstrap 3.2.0</a></li>
+ <li><a href="http://jquery.org/">jQuery 1.11.0</a></li>
+ <li><a href="http://fontawesome.io/">Font Awesome 4.3.0</a></li>
+ <li><a href="http://font.ubuntu.com/">Ubuntu fonts</a></li>
+ <li>And various jQuery plugins</li>
+ </ul>
+ <p>Many thanks go to the creators and developers of these software packages.</p>
+ </div>
+ </div>
+ </div>
+ </div>
+ <!-- /.row -->
+ </div>
+ <!-- /#page-wrapper -->
+
+</div>
+<!-- /#wrapper -->
+<?php
+require('./footer.php');
+?> \ No newline at end of file
diff --git a/include/assignments-edit.php b/include/assignments-edit.php
new file mode 100644
index 0000000..0e0801a
--- /dev/null
+++ b/include/assignments-edit.php
@@ -0,0 +1,59 @@
+<?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('./conf.php');
+
+$response = new response();
+
+try {
+ $assignment = new assignment($_pdo, $_REQUEST['pk']);
+
+ $name = explode('-', $_REQUEST['name']);
+ $what_to_edit = $name[count($name) - 1];
+ switch ($what_to_edit) {
+ case 'title':
+ $response->success = $assignment->setTitle($_REQUEST['value']);
+ break;
+ case 'hours':
+ $response->success = $assignment->setHours($_REQUEST['value']);
+ break;
+ case 'price_per_hour':
+ $response->success = $assignment->setPricePerHour($_REQUEST['value']);
+ break;
+ case 'vat':
+ $response->success = $assignment->setVAT($_REQUEST['value']);
+ break;
+ default:
+ $response->http_response_code(404);
+ $response->success = false;
+ }
+ if (!$response->success && $response->http_response_code() == 200) {
+ $response->http_response_code(500);
+ $response->message = "The assignment could not be edited due to an error.";
+ }
+} catch (PDOException $e) {
+ $response->http_response_code(500);
+ $response->success = false;
+ $response->message = "The assignment could not be edited due to a PDO error ({$e->getMessage()}).";
+} catch (Exception $e) {
+ $response->http_response_code(404);
+ $response->success = false;
+ $response->message = "The assignment could not be edited due to an exception.";
+}
+echo $response->message; \ No newline at end of file
diff --git a/include/assignments-new.php b/include/assignments-new.php
new file mode 100644
index 0000000..2de3b1f
--- /dev/null
+++ b/include/assignments-new.php
@@ -0,0 +1,45 @@
+<?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('./conf.php');
+
+$response = new response();
+
+try {
+ $offer = new offer($_pdo, $_REQUEST['offerId']);
+
+ $assignment = $offer->createAssignment(
+ $_REQUEST['title'],
+ $_REQUEST['description'],
+ $_REQUEST['hours'],
+ $_REQUEST['price_per_hour'],
+ $_REQUEST['vat']
+ );
+ $response->success = true;
+ $response->message = "Assignment {$assignment->getTitle()} has been succesfully created. <a class='alert-link' href='javascript:location.reload(true);'>Refresh the page</a>.";
+} catch (PDOException $e) {
+ $response->http_response_code(500);
+ $response->success = false;
+ $response->message = "The assignment could not be created due to a PDO error ({$e->getMessage()}).";
+} catch (Exception $e) {
+ $response->http_response_code(404);
+ $response->success = false;
+ $response->message = "The assignment could not be created due to an error.";
+}
+echo $response->getJson(); \ No newline at end of file
diff --git a/include/assignments-overview.php b/include/assignments-overview.php
new file mode 100644
index 0000000..af201f9
--- /dev/null
+++ b/include/assignments-overview.php
@@ -0,0 +1,170 @@
+<?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/>.
+ */
+?>
+
+<div class="col-lg-12">
+ <div class="panel panel-default">
+ <div class="panel-heading">Overview</div>
+ <div class="panel-body table-responsive">
+ <table class="table table-bordered table-striped">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>Offer</th>
+ <th>Briefing</th>
+ <th>Time</th>
+ <th>Price</th>
+ <th>Tools</th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php
+ $assignments = BusinessAdmin::getAssignments($_pdo);
+ foreach ($assignments as $assignment) {
+ echo "<tr>
+ <td class='col-min-width'>{$assignment->getId()}</td>
+ <td class='col-min-width'>#{$assignment->getOffer()->getId()} to {$assignment->getOffer()->getContact()->getName()} ({$assignment->getOffer()->getContact()->getClient()->getName()})</td>
+ <td class='col-max-width'>
+ <b><a href='#' class='editable' id='editable-assignment-{$assignment->getId()}-title' data-type='text' data-pk='{$assignment->getId()}' data-url='".constants::url_external."assignments/edit'>{$assignment->getTitle()}</a></b><br/>
+ <p>{$assignment->getDescription()}</p>
+ </td>
+ <td class='col-min-width'><a href='#' class='editable' id='editable-assignment-{$assignment->getId()}-hours' data-type='text' data-pk='{$assignment->getId()}' data-url='".constants::url_external."assignments/edit'>{$assignment->getHours()}</a>h</td>
+ <td class='col-min-width'>
+ ".constants::invoice_valuta."<a href='#' class='editable' id='editable-assignment-{$assignment->getId()}-price_per_hour' data-type='text' data-pk='{$assignment->getId()}' data-url='".constants::url_external."assignments/edit'>{$assignment->getPricePerHour()}</a> / hr<br/>
+ <a href='#' class='editable' id='editable-assignment-{$assignment->getId()}-vat' data-type='text' data-pk='{$assignment->getId()}' data-url='".constants::url_external."assignments/edit'>{$assignment->getVAT()}</a>% VAT
+ </td>
+ <td class='col-min-width'>
+ <a title='View' href='?id={$assignment->getId()}' class='btn btn-primary btn-circle fa fa-arrow-right'></a>
+ <a title='Delete' href='?delete={$assignment->getId()}' class='btn btn-danger btn-circle fa fa-times'></a>
+ </td>
+ </tr>";
+ }
+ if (count($assignments) == 0) {
+ echo "<tr><td colspan='6'>There are no assignments in the database. Why not start with creating one, below?</td></tr>";
+ }
+ ?>
+ </tbody>
+ </table>
+ </div>
+ </div>
+</div>
+<div class="col-lg-12">
+ <div class="panel panel-default">
+ <div class="panel-heading">Create new</div>
+ <div class="panel-body">
+ <form role="form" id="newAssignment" action='<?=constants::url_external?>assignments/new' method="post" class="bootstrapValidator ajaxify"
+ data-ajaxify-options='{"success":"newAssignmentSuccess","error":"newAssignmentError","beforeSubmit":"newAssignmentBeforeSubmit","clearForm":true}'>
+ <div class="ajaxify-response alert alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><span class="ajaxify-response-text"></span></div>
+ <div class="col-lg-6">
+ <div class="form-group">
+ <label>Offer:</label>
+ <select name="offerId" class="form-control">
+ <?php
+ foreach (BusinessAdmin::getOffers($_pdo) as $offer) {
+ echo "<option value='{$offer->getId()}'>#{$offer->getId()} to {$offer->getContact()->getName()} ({$offer->getContact()->getClient()->getName()})</option>";
+ }
+ ?>
+ </select>
+ </div>
+ <div class="form-group">
+ <label>Title:</label>
+ <input
+ type="text" name="title" class="form-control" placeholder="Title"
+ data-bv-notempty="true" data-bv-notempty-message="You have to provide a title"/>
+ </div>
+ <div class="form-group">
+ <label>Description:</label>
+ <textarea
+ name="description" class="form-control" placeholder="Description" rows="4"
+ data-bv-notempty="true" data-bv-notempty-message="You have to provide a description"
+ data-bv-stringlength="true" data-bv-stringlength-message="The description should contain between 30 and 1000 characters" data-bv-stringlength-min="30" data-bv-stringlength-max="1000"></textarea>
+ </div>
+ </div>
+ <div class="col-lg-6">
+ <div class="form-group">
+ <label>Estimated time (h):</label>
+ <input
+ type="text" name="hours" class="form-control" placeholder="Time in hours"
+ data-bv-notempty="true" data-bv-notempty-message="You have to give an estimation"
+ data-bv-integer="true" data-bv-integer-message="Please enter an integer" />
+ </div>
+ <div class="form-group">
+ <label>Price per hour (<?=constants::invoice_valuta?>):</label>
+ <input
+ type="text" name="price_per_hour" class="form-control" placeholder="Price per hour"
+ data-bv-notempty="true" data-bv-notempty-message="You have to give a rate"
+ data-bv-numeric="true" data-bv-numeric-message="Please enter a number (with a '.' as decimal separator)" />
+ </div>
+ <div class="form-group">
+ <label>VAT (%):</label>
+ <input
+ type="text" name="vat" class="form-control" placeholder="VAT"
+ data-bv-notempty="true" data-bv-notempty-message="You have to provide a VAT percentage"
+ data-bv-numeric="true" data-bv-numeric-message="Please enter a number (with a '.' as decimal separator)" />
+ </div>
+ </div>
+ <div class="col-lg-6">
+ <button type="submit" class="btn btn-default">Go</button>
+ </div>
+ </form>
+ <script type="text/javascript">
+ // Callback for before the form is submitted
+ function newAssignmentBeforeSubmit() {
+ $('#newAssignment input').prop('disabled', true);
+ $('#newAssignment .ajaxify-response').hide().removeClass('alert-success alert-danger').find('.ajaxify-response-text').html('');
+ }
+
+ // Callback for when the form is successfully submitted
+ function newAssignmentSuccess(data) {
+ if (data.success == true) {
+ $('#newAssignment .ajaxify-response')
+ .addClass('alert-success')
+ .show()
+ .find('.ajaxify-response-text')
+ .html(data.message);
+
+ $('#newAssignment input, #newAssignment button').prop('disabled', false);
+ $('#newAssignment').data('bootstrapValidator').resetForm();
+ } else {
+ $('#newAssignment .ajaxify-response')
+ .addClass('alert-danger')
+ .show()
+ .find('.ajaxify-response-text')
+ .html(data.message);
+
+ $('#newAssignment input, #newAssignment button').prop('disabled', false);
+ $('#newAssignment').data('bootstrapValidator').resetForm();
+ }
+ }
+
+ // Callback for when form submission encountered an error
+ function newAssignmentError() {
+ $('#newAssignment .ajaxify-response')
+ .addClass('alert-danger')
+ .show()
+ .find('.ajaxify-response-text')
+ .html('An unknown error occurred. Please contact support.');
+
+ $('#newAssignment input, #newAssignment button').prop('disabled', false);
+ $('#newAssignment').data('bootstrapValidator').resetForm();
+ }
+ </script>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/include/assignments-view.php b/include/assignments-view.php
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/include/assignments-view.php
diff --git a/include/assignments.php b/include/assignments.php
new file mode 100644
index 0000000..5ba21c6
--- /dev/null
+++ b/include/assignments.php
@@ -0,0 +1,98 @@
+<?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('./index.php');
+require('./header.php');
+?>
+
+<div id="wrapper">
+
+ <?php require('./nav.php'); ?>
+
+ <div id="page-wrapper">
+ <div class="row">
+ <?php
+ //------------------------------------------------------------------------------
+ // Check for GET variables
+ //
+ // ?id=<id> View information of the assignment with id <id>
+ // ?delete=<id> Delete the assignment with id <id>
+ //------------------------------------------------------------------------------
+
+ // The header of the page
+ $header = 'Assignments';
+ // Whether or not to show an individual assignment in the end (false if not, or the id if yes)
+ $show_individual = false;
+
+ // View assignment
+ if (isset($_GET['id'])) {
+ $id = (int) $_GET['id'];
+ try {
+ $assignment = new assignment($_pdo, $id);
+ $header = "<a href='".constants::url_external."assignments'>Assignments</a> / {$assignment->getTitle()}";
+ $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 assignment 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 assignment 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>";
+
+ // Delete assignment
+ if (isset($_GET['delete'])) {
+ echo "<div class='col-lg-12'>";
+ $id = (int) $_GET['delete'];
+ try {
+ $assignment = new assignment($_pdo, $id);
+ if ($assignment->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 assignment with title <i>{$assignment->getTitle()}</i> 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 assignment with title <i>{$assignment->getTitle()}</i> 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 assignment 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 assignment with id {$id} could not be found.</div>";
+ }
+
+ echo "</div>";
+ }
+
+ if ($show_individual !== false) {
+ $_id = $show_individual;
+ require('assignments-view.php');
+ } else {
+ require('assignments-overview.php');
+ }
+ ?>
+ </div>
+ <!-- /.row -->
+ </div>
+ <!-- /#page-wrapper -->
+
+</div>
+<!-- /#wrapper -->
+
+<?php
+require('./footer.php');
+?> \ No newline at end of file
diff --git a/include/clients-edit.php b/include/clients-edit.php
new file mode 100644
index 0000000..c0b83c8
--- /dev/null
+++ b/include/clients-edit.php
@@ -0,0 +1,42 @@
+<?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('./conf.php');
+
+$response = new response();
+
+try {
+ $client = new client($_pdo, $_REQUEST['pk']);
+ if ($client->setName($_REQUEST['value'])) {
+ $response->success = true;
+ } else {
+ $response->http_response_code(500);
+ $response->success = false;
+ $response->message = "The client could not be edited due to an error.";
+ }
+} catch (PDOException $e) {
+ $response->http_response_code(500);
+ $response->success = false;
+ $response->message = "The client could not be edited due to a PDO error ({$e->getMessage()}).";
+} catch (Exception $e) {
+ $response->http_response_code(404);
+ $response->success = false;
+ $response->message = "The client could not be edited due to an exception.";
+}
+echo $response->message; \ No newline at end of file
diff --git a/include/clients-new.php b/include/clients-new.php
new file mode 100644
index 0000000..9466638
--- /dev/null
+++ b/include/clients-new.php
@@ -0,0 +1,38 @@
+<?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('./conf.php');
+
+$response = new response();
+
+try {
+ $client = BusinessAdmin::createClient($_pdo, $_REQUEST['name']);
+
+ if ($client === false) {
+ $response->success = false;
+ $response->message = "The client could not be created due to an error.";
+ } else {
+ $response->success = true;
+ $response->message = "Client <i>'{$client->getName()}'</i> has been created. <a class='alert-link' href='javascript:location.reload(true);'>Refresh the page</a>.";
+ }
+} catch (PDOException $e) {
+ $response->success = false;
+ $response->message = "The client could not be created due to a PDO error ({$e->getMessage()}).";
+}
+echo $response->getJson(); \ No newline at end of file
diff --git a/include/clients-overview.php b/include/clients-overview.php
new file mode 100644
index 0000000..523aeef
--- /dev/null
+++ b/include/clients-overview.php
@@ -0,0 +1,118 @@
+<?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/>.
+ */
+?>
+
+<div class="col-lg-6 col-md-6">
+ <div class="panel panel-default">
+ <div class="panel-heading">Overview</div>
+ <div class="panel-body table-responsive">
+ <table class="table table-bordered table-striped">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>Name</th>
+ <th>Tools</th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php
+ $clients = BusinessAdmin::getClients($_pdo);
+ foreach ($clients as $client) {
+ echo "<tr>
+ <td class='col-min-width'>{$client->getId()}</td>
+ <td class='col-max-width'>
+ <a href='#' class='editable' id='editable-client-{$client->getId()}-name' data-type='text' data-pk='{$client->getId()}' data-url='".constants::url_external."clients/edit' data-title='Enter new name'>
+ {$client->getName()}
+ </a>
+ </td>
+ <td class='col-min-width'>
+ <a title='View' href='?id={$client->getId()}' class='btn btn-primary btn-circle fa fa-arrow-right'></a>
+ <a title='Delete' href='?delete={$client->getId()}' class='btn btn-danger btn-circle fa fa-times'></a>
+ </td>
+ </tr>";
+ }
+ if (count($clients) == 0) {
+ echo "<tr><td colspan='3'>There are no clients in the database. Why not start with creating one, on the right?</td></tr>";
+ }
+ ?>
+ </tbody>
+ </table>
+ </div>
+ </div>
+</div>
+<div class="col-lg-6 col-md-6">
+ <div class="panel panel-default">
+ <div class="panel-heading">Create new</div>
+ <div class="panel-body">
+ <form role="form" id="newClient" action='<?=constants::url_external?>clients/new' method="post" class="bootstrapValidator ajaxify"
+ data-ajaxify-options='{"success":"newClientSuccess","error":"newClientError","beforeSubmit":"newClientBeforeSubmit","clearForm":true}'>
+ <div class="ajaxify-response alert alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><span class="ajaxify-response-text"></span></div>
+ <div class="form-group">
+ <label>Name:</label>
+ <input
+ type="text" name="name" class="form-control" placeholder="Title"
+ data-bv-notempty="true" data-bv-notempty-message="You have to provide a name"/>
+ </div>
+ <button type="submit" class="btn btn-default">Go</button>
+ </form>
+ <script type="text/javascript">
+ // Callback for before the form is submitted
+ function newClientBeforeSubmit() {
+ $('#newClient input').prop('disabled', true);
+ $('#newClient .ajaxify-response').hide().removeClass('alert-success alert-danger').find('.ajaxify-response-text').html('');
+ }
+
+ // Callback for when the form is successfully submitted
+ function newClientSuccess(data) {
+ if (data.success == true) {
+ $('#newClient .ajaxify-response')
+ .addClass('alert-success')
+ .show()
+ .find('.ajaxify-response-text')
+ .html(data.message);
+
+ $('#newClient input, #newClient button').prop('disabled', false);
+ $('#newClient').data('bootstrapValidator').resetForm();
+ } else {
+ $('#newClient .ajaxify-response')
+ .addClass('alert-danger')
+ .show()
+ .find('.ajaxify-response-text')
+ .html(data.message);
+
+ $('#newClient input, #newClient button').prop('disabled', false);
+ $('#newClient').data('bootstrapValidator').resetForm();
+ }
+ }
+
+ // Callback for when form submission encountered an error
+ function newClientError() {
+ $('#newClient .ajaxify-response')
+ .addClass('alert-danger')
+ .show()
+ .find('.ajaxify-response-text')
+ .html('An unknown error occurred. Please contact support.');
+
+ $('#newClient input, #newClient button').prop('disabled', false);
+ $('#newClient').data('bootstrapValidator').resetForm();
+ }
+ </script>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/include/clients-view.php b/include/clients-view.php
new file mode 100644
index 0000000..066ad3e
--- /dev/null
+++ b/include/clients-view.php
@@ -0,0 +1,62 @@
+<?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/>.
+ */
+
+$_client = new client($_pdo, $_id);
+?>
+<div class="col-lg-12">
+ <div class="panel panel-default">
+ <div class="panel-heading">Contacts</div>
+ <div class="panel-body table-responsive">
+ <table class="table table-bordered table-striped">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>Name</th>
+ <th>Address</th>
+ <th>Tools</th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php
+ $contacts = $_client->getContacts();
+ foreach ($contacts as $contact) {
+ echo "<tr>
+ <td class='col-min-width'>{$contact->getId()}</td>
+ <td class='col-min-width'><a href='#' class='editable' id='editable-contact-{$contact->getId()}-name' data-type='text' data-pk='{$contact->getId()}' data-url='".constants::url_external."contacts/edit'>{$contact->getName()}</a></td>
+ <td class='col-max-width'>
+ <a href='#' class='editable' id='editable-contact-{$contact->getId()}-address' data-type='text' data-pk='{$contact->getId()}' data-url='".constants::url_external."contacts/edit'>{$contact->getAddress()}</a><br/>
+ <a href='#' class='editable' id='editable-contact-{$contact->getId()}-postal_code' data-type='text' data-pk='{$contact->getId()}' data-url='".constants::url_external."contacts/edit'>{$contact->getPostalCode()}</a>
+ <a href='#' class='editable' id='editable-contact-{$contact->getId()}-city' data-type='text' data-pk='{$contact->getId()}' data-url='".constants::url_external."contacts/edit'>{$contact->getCity()}</a><br/>
+ <a href='#' class='editable' id='editable-contact-{$contact->getId()}-country' data-type='text' data-pk='{$contact->getId()}' data-url='".constants::url_external."contacts/edit'>{$contact->getCountry()}</a>
+ </td>
+ <td class='col-min-width'>
+ <a title='View' href='?id={$contact->getId()}' class='btn btn-primary btn-circle fa fa-arrow-right'></a>
+ <a title='Delete' href='?delete={$contact->getId()}' class='btn btn-danger btn-circle fa fa-times'></a>
+ </td>
+ </tr>";
+ }
+ if (count($contacts) == 0) {
+ echo "<tr><td colspan='4'>There are no contacts in the database. Why not <a href='".constants::url_external."contacts'>create one</a>?</td></tr>";
+ }
+ ?>
+ </tbody>
+ </table>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/include/clients.php b/include/clients.php
new file mode 100644
index 0000000..7248e0c
--- /dev/null
+++ b/include/clients.php
@@ -0,0 +1,98 @@
+<?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('./index.php');
+require('./header.php');
+?>
+
+<div id="wrapper">
+
+ <?php require('./nav.php'); ?>
+
+ <div id="page-wrapper">
+ <div class="row">
+ <?php
+ //------------------------------------------------------------------------------
+ // Check for GET variables
+ //
+ // ?id=<id> View information of the client with id <id>
+ // ?delete=<id> Delete the client with id <id>
+ //------------------------------------------------------------------------------
+
+ // The header of the page
+ $header = 'Clients';
+ // Whether or not to show an individual client in the end (false if not, or the id if yes)
+ $show_individual = false;
+
+ // View client
+ if (isset($_GET['id'])) {
+ $id = (int) $_GET['id'];
+ try {
+ $client = new client($_pdo, $id);
+ $header = "<a href='".constants::url_external."clients'>Clients</a> / {$client->getName()}";
+ $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 client 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 client 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>";
+
+ // Delete client
+ if (isset($_GET['delete'])) {
+ echo "<div class='col-lg-12'>";
+ $id = (int) $_GET['delete'];
+ try {
+ $client = new client($_pdo, $id);
+ if ($client->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 client with name <i>{$client->getName()}</i> 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 client with name <i>{$client->getName()}</i> 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 client 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 client with id {$id} could not be found.</div>";
+ }
+
+ echo "</div>";
+ }
+
+ if ($show_individual !== false) {
+ $_id = $show_individual;
+ require('clients-view.php');
+ } else {
+ require('clients-overview.php');
+ }
+ ?>
+ </div>
+ <!-- /.row -->
+ </div>
+ <!-- /#page-wrapper -->
+
+</div>
+<!-- /#wrapper -->
+
+<?php
+require('./footer.php');
+?> \ No newline at end of file
diff --git a/include/contacts-edit.php b/include/contacts-edit.php
new file mode 100644
index 0000000..9e7c606
--- /dev/null
+++ b/include/contacts-edit.php
@@ -0,0 +1,65 @@
+<?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('./conf.php');
+
+$response = new response();
+
+try {
+ $contact = new contact($_pdo, $_REQUEST['pk']);
+
+ $name = explode('-', $_REQUEST['name']);
+ $what_to_edit = $name[count($name) - 1];
+ switch ($what_to_edit) {
+ case 'name':
+ $response->success = $contact->setName($_REQUEST['value']);
+ break;
+ case 'email':
+ $response->success = $contact->setEmail($_REQUEST['value']);
+ break;
+ case 'address':
+ $response->success = $contact->setAddress($_REQUEST['value']);
+ break;
+ case 'postal_code':
+ $response->success = $contact->setPostalCode($_REQUEST['value']);
+ break;
+ case 'city':
+ $response->success = $contact->setCity($_REQUEST['value']);
+ break;
+ case 'country':
+ $response->success = $contact->setCountry($_REQUEST['value']);
+ break;
+ default:
+ $response->http_response_code(404);
+ $response->success = false;
+ }
+ if (!$response->success) {
+ $response->http_response_code(500);
+ $response->message = "The contact could not be edited due to an error.";
+ }
+} catch (PDOException $e) {
+ $response->http_response_code(500);
+ $response->success = false;
+ $response->message = "The contact could not be edited due to a PDO error ({$e->getMessage()}).";
+} catch (Exception $e) {
+ $response->http_response_code(404);
+ $response->success = false;
+ $response->message = "The contact could not be edited due to an exception.";
+}
+echo $response->message; \ No newline at end of file
diff --git a/include/contacts-new.php b/include/contacts-new.php
new file mode 100644
index 0000000..c04fa72
--- /dev/null
+++ b/include/contacts-new.php
@@ -0,0 +1,47 @@
+<?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('./conf.php');
+
+$response = new response();
+
+try {
+ $client = new client($_pdo, $_REQUEST['clientId']);
+
+ $contact = $client->createContact(
+ $_REQUEST['name'],
+ $_REQUEST['email'],
+ $_REQUEST['address'],
+ $_REQUEST['address_2'],
+ $_REQUEST['postal_code'],
+ $_REQUEST['city'],
+ $_REQUEST['country']
+ );
+ $response->success = true;
+ $response->message = "Contact {$contact->getName()} has been succesfully created. <a class='alert-link' href='javascript:location.reload(true);'>Refresh the page</a>.";
+} catch (PDOException $e) {
+ $response->http_response_code(500);
+ $response->success = false;
+ $response->message = "The contact could not be created due to a PDO error ({$e->getMessage()}).";
+} catch (Exception $e) {
+ $response->http_response_code(404);
+ $response->success = false;
+ $response->message = "The contact could not be created due to an error.";
+}
+echo $response->getJson(); \ No newline at end of file
diff --git a/include/contacts-overview.php b/include/contacts-overview.php
new file mode 100644
index 0000000..bad63ed
--- /dev/null
+++ b/include/contacts-overview.php
@@ -0,0 +1,168 @@
+<?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/>.
+ */
+?>
+
+<div class="col-lg-7 col-md-7">
+ <div class="panel panel-default">
+ <div class="panel-heading">Overview</div>
+ <div class="panel-body table-responsive">
+ <table class="table table-bordered table-striped">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>Name</th>
+ <th>Address</th>
+ <th>Tools</th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php
+ $contacts = BusinessAdmin::getContacts($_pdo);
+ foreach ($contacts as $contact) {
+ echo "<tr>
+ <td class='col-min-width'>{$contact->getId()}</td>
+ <td class='col-min-width'>
+ <a href='#' class='editable' id='editable-contact-{$contact->getId()}-name' data-type='text' data-pk='{$contact->getId()}' data-url='".constants::url_external."contacts/edit'>{$contact->getName()}</a><br/>
+ ({$contact->getClient()->getName()})
+ </td>
+ <td class='col-max-width'>
+ <a href='#' class='editable' id='editable-contact-{$contact->getId()}-email' data-type='text' data-pk='{$contact->getId()}' data-url='".constants::url_external."contacts/edit'>{$contact->getEmail()}</a><br/>
+ <br/>
+ <a href='#' class='editable' id='editable-contact-{$contact->getId()}-address' data-type='text' data-pk='{$contact->getId()}' data-url='".constants::url_external."contacts/edit'>{$contact->getAddress()}</a><br/>
+ " . ($contact->getAddress_2() != '' ? "<a href='#' class='editable' id='editable-contact-{$contact->getId()}-address_2' data-type='text' data-pk='{$contact->getId()}' data-url='".constants::url_external."contacts/edit'>{$contact->getAddress_2()}</a><br/>" : "") . "
+ <a href='#' class='editable' id='editable-contact-{$contact->getId()}-postal_code' data-type='text' data-pk='{$contact->getId()}' data-url='".constants::url_external."contacts/edit'>{$contact->getPostalCode()}</a>
+ <a href='#' class='editable' id='editable-contact-{$contact->getId()}-city' data-type='text' data-pk='{$contact->getId()}' data-url='".constants::url_external."contacts/edit'>{$contact->getCity()}</a><br/>
+ <a href='#' class='editable' id='editable-contact-{$contact->getId()}-country' data-type='text' data-pk='{$contact->getId()}' data-url='".constants::url_external."contacts/edit'>{$contact->getCountry()}</a>
+ </td>
+ <td class='col-min-width'>
+ <a title='View' href='?id={$contact->getId()}' class='btn btn-primary btn-circle fa fa-arrow-right'></a>
+ <a title='Delete' href='?delete={$contact->getId()}' class='btn btn-danger btn-circle fa fa-times'></a>
+ </td>
+ </tr>";
+ }
+ if (count($contacts) == 0) {
+ echo "<tr><td colspan='5'>There are no contacts in the database. Why not start with creating one, on the right?</td></tr>";
+ }
+ ?>
+ </tbody>
+ </table>
+ </div>
+ </div>
+</div>
+<div class="col-lg-5 col-md-5">
+ <div class="panel panel-default">
+ <div class="panel-heading">Create new</div>
+ <div class="panel-body">
+ <form role="form" id="newContact" action='<?=constants::url_external?>contacts/new' method="post" class="bootstrapValidator ajaxify"
+ data-ajaxify-options='{"success":"newContactSuccess","error":"newContactError","beforeSubmit":"newContactBeforeSubmit","clearForm":true}'>
+ <div class="ajaxify-response alert alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><span class="ajaxify-response-text"></span></div>
+ <div class="form-group">
+ <label>Client:</label>
+ <select name="clientId" class="form-control">
+ <?php
+ foreach (BusinessAdmin::getClients($_pdo) as $client) {
+ echo "<option value='{$client->getId()}'>{$client->getName()}</option>";
+ }
+ ?>
+ </select>
+ </div>
+ <div class="form-group">
+ <label>Name:</label>
+ <input
+ type="text" name="name" class="form-control" placeholder="Name"
+ data-bv-notempty="true" data-bv-notempty-message="You have to provide a name"/>
+ </div>
+ <div class="form-group">
+ <label>Email:</label>
+ <input
+ type="email" name="email" class="form-control" placeholder="Email"
+ data-bv-notempty="true" data-bv-notempty-message="You have to provide a valid email address"/>
+ </div>
+ <div class="form-group">
+ <label>Address:</label>
+ <input
+ type="text" name="address" class="form-control" placeholder="Address"
+ data-bv-notempty="true" data-bv-notempty-message="You have to provide an address"/>
+ </div>
+ <div class="form-group">
+ <input
+ type="text" name="address_2" class="form-control" placeholder="Second address line (optional)" />
+ </div>
+ <div class="form-group">
+ <input
+ type="text" name="postal_code" class="form-control" placeholder="Postal code"
+ data-bv-notempty="true" data-bv-notempty-message="You have to provide a postal code"/>
+ </div>
+ <div class="form-group">
+ <input
+ type="text" name="city" class="form-control" placeholder="City"
+ data-bv-notempty="true" data-bv-notempty-message="You have to provide a city"/>
+ </div>
+ <div class="form-group">
+ <input
+ type="text" name="country" class="form-control" placeholder="Country"
+ data-bv-notempty="true" data-bv-notempty-message="You have to provide a country"/>
+ </div>
+ <button type="submit" class="btn btn-default">Go</button>
+ </form>
+ <script type="text/javascript">
+ // Callback for before the form is submitted
+ function newContactBeforeSubmit() {
+ $('#newContact input').prop('disabled', true);
+ $('#newContact .ajaxify-response').hide().removeClass('alert-success alert-danger').find('.ajaxify-response-text').html('');
+ }
+
+ // Callback for when the form is successfully submitted
+ function newContactSuccess(data) {
+ if (data.success == true) {
+ $('#newContact .ajaxify-response')
+ .addClass('alert-success')
+ .show()
+ .find('.ajaxify-response-text')
+ .html(data.message);
+
+ $('#newContact input, #newContact button').prop('disabled', false);
+ $('#newContact').data('bootstrapValidator').resetForm();
+ } else {
+ $('#newContact .ajaxify-response')
+ .addClass('alert-danger')
+ .show()
+ .find('.ajaxify-response-text')
+ .html(data.message);
+
+ $('#newContact input, #newContact button').prop('disabled', false);
+ $('#newContact').data('bootstrapValidator').resetForm();
+ }
+ }
+
+ // Callback for when form submission encountered an error
+ function newContactError() {
+ $('#newContact .ajaxify-response')
+ .addClass('alert-danger')
+ .show()
+ .find('.ajaxify-response-text')
+ .html('An unknown error occurred. Please contact support.');
+
+ $('#newContact input, #newContact button').prop('disabled', false);
+ $('#newContact').data('bootstrapValidator').resetForm();
+ }
+ </script>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/include/contacts.php b/include/contacts.php
new file mode 100644
index 0000000..787bd9a
--- /dev/null
+++ b/include/contacts.php
@@ -0,0 +1,98 @@
+<?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('./index.php');
+require('./header.php');
+?>
+
+<div id="wrapper">
+
+ <?php require('./nav.php'); ?>
+
+ <div id="page-wrapper">
+ <div class="row">
+ <?php
+ //------------------------------------------------------------------------------
+ // Check for GET variables
+ //
+ // ?id=<id> View information of the contact with id <id>
+ // ?delete=<id> Delete the contact with id <id>
+ //------------------------------------------------------------------------------
+
+ // The header of the page
+ $header = 'Contacts';
+ // Whether or not to show an individual contact in the end (false if not, or the id if yes)
+ $show_individual = false;
+
+ // View contact
+ if (isset($_GET['id'])) {
+ $id = (int) $_GET['id'];
+ try {
+ $contact = new contact($_pdo, $id);
+ $header = "<a href='".constants::url_external."contacts'>Contacts</a> / {$contact->getName()}";
+ $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 contact 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 contact 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>";
+
+ // Delete contact
+ if (isset($_GET['delete'])) {
+ echo "<div class='col-lg-12'>";
+ $id = (int) $_GET['delete'];
+ try {
+ $contact = new contact($_pdo, $id);
+ if ($contact->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 contact with name <i>{$contact->getName()}</i> 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 contact with name <i>{$contact->getName()}</i> 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 contact 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 contact with id {$id} could not be found.</div>";
+ }
+
+ echo "</div>";
+ }
+
+ if ($show_individual !== false) {
+ $_id = $show_individual;
+ require('contacts-view.php');
+ } else {
+ require('contacts-overview.php');
+ }
+ ?>
+ </div>
+ <!-- /.row -->
+ </div>
+ <!-- /#page-wrapper -->
+
+</div>
+<!-- /#wrapper -->
+
+<?php
+require('./footer.php');
+?> \ No newline at end of file
diff --git a/include/home.php b/include/home.php
new file mode 100644
index 0000000..0be5f7e
--- /dev/null
+++ b/include/home.php
@@ -0,0 +1,274 @@
+<?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('index.php');
+require('header.php');
+?>
+
+<div id="wrapper">
+
+ <?php require('nav.php'); ?>
+
+ <div id="page-wrapper">
+ <div class="row">
+ <div class="col-lg-12">
+ <h1 class="page-header">Welcome</h1>
+ </div>
+ <!-- /.col-lg-12 -->
+ </div>
+ <!-- /.row -->
+ <div class="row">
+ <div class="col-lg-4 col-md-4 col-sm-6">
+ <?php
+ $count = count(BusinessAdmin::getOfferIds($_pdo, array("`accepted` = 0")));
+ ?>
+ <div class="panel panel-<?=($count==0 ? 'primary' : 'yellow')?>">
+ <div class="panel-heading">
+ <div class="row">
+ <div class="col-xs-3">
+ <i class="fa fa-briefcase fa-5x"></i>
+ </div>
+ <div class="col-xs-9 text-right">
+ <div class="huge"><?=$count?></div>
+ <!--<div>Unaccepted offers</div>-->
+ </div>
+ </div>
+ </div>
+ <a href="<?=constants::url_external?>offers">
+ <div class="panel-footer">
+ <span class="pull-left">Unaccepted offers</span>
+ <span class="pull-right"><i class="fa fa-arrow-circle-right"></i></span>
+ <div class="clearfix"></div>
+ </div>
+ </a>
+ </div>
+ </div>
+ <div class="col-lg-4 col-md-4 col-sm-6">
+ <?php
+ $count = count(BusinessAdmin::getOfferIds($_pdo, array("`accepted`=1", "`start_date` <= CURDATE()", "`end_date` >= CURDATE()", "`invoice_date` IS NULL OR `invoice_date` = '1970-01-01'")));
+ ?>
+ <div class="panel panel-<?=($count==0 ? 'primary' : ($count < 3) ? 'green' : ($count < 5 ? 'yellow' : 'red'))?>">
+ <div class="panel-heading">
+ <div class="row">
+ <div class="col-xs-3">
+ <i class="fa fa-tasks fa-5x"></i>
+ </div>
+ <div class="col-xs-9 text-right">
+ <div class="huge"><?=$count?></div>
+ <!--<div>Active offers</div>-->
+ </div>
+ </div>
+ </div>
+ <a href="#panel-active-offers">
+ <div class="panel-footer">
+ <span class="pull-left">Active offers</span>
+ <span class="pull-right"><i class="fa fa-arrow-circle-right"></i></span>
+ <div class="clearfix"></div>
+ </div>
+ </a>
+ </div>
+ </div>
+ <div class="col-lg-4 col-md-4 col-sm-6">
+ <?php
+ $count = count(BusinessAdmin::getOfferIds($_pdo, array("`invoice_date` > '1970-01-01'", "`payment_received` <= '1970-01-01' OR `payment_received` IS NULL")));
+ ?>
+ <div class="panel panel-<?=($count==0 ? 'primary' : 'yellow')?>">
+ <div class="panel-heading">
+ <div class="row">
+ <div class="col-xs-3">
+ <i class="fa fa-circle-o-notch fa-5x"></i>
+ </div>
+ <div class="col-xs-9 text-right">
+ <div class="huge"><?=$count?></div>
+ <!--<div>Open invoices</div>-->
+ </div>
+ </div>
+ </div>
+ <a href="#panel-open-invoices">
+ <div class="panel-footer">
+ <span class="pull-left">Open invoices</span>
+ <span class="pull-right"><i class="fa fa-arrow-circle-right"></i></span>
+ <div class="clearfix"></div>
+ </div>
+ </a>
+ </div>
+ </div>
+ </div>
+ <!-- /.row -->
+ <div class="row">
+ <div class="col-lg-6 col-md-8">
+ <div class="panel panel-default" id="panel-active-offers">
+ <div class="panel-heading">
+ <i class="fa fa-tasks fa-fw"></i> Currently active offers
+ </div>
+ <!-- /.panel-heading -->
+ <div class="panel-body">
+ <?php
+ $offers = BusinessAdmin::getOffers($_pdo, array("`accepted`=1", "`start_date` <= CURDATE()", "`end_date` >= CURDATE()", "`invoice_date` IS NULL OR `invoice_date` = '1970-01-01'"));
+ $list = array();
+ foreach ($offers as $offer) {
+ $start = BusinessAdmin::formatDate($offer->getStartDate(), false);
+ $end = BusinessAdmin::formatDate($offer->getEndDate(), false);
+ $since = mktime(0,0,0,date("n"),date("j"),date("Y")) - $offer->getStartDate();
+ $total = $offer->getEndDate() - $offer->getStartDate();
+ $percentage = ($total == 0) ? 100 : round($since / $total * 100);
+
+ // We want to sort on percentage (DESC) and secondly end date (ASC) so start date (DESC)
+ $list[str_pad($percentage, 3, '0', STR_PAD_LEFT) . $offer->getStartDate()] = array(
+ 'start' => $start,
+ 'end' => $end,
+ 'id' => $offer->getId(),
+ 'contactClientName' => $offer->getContact()->getClient()->getName(),
+ 'percentage' => $percentage
+ );
+ }
+ krsort($list, SORT_STRING);
+ foreach ($list as $item) {
+ echo "<p>#{$item['id']} to {$item['contactClientName']} ({$item['start']} - {$item['end']})<span class='pull-right text-muted'>{$item['percentage']}% complete</span></p>
+ <div class='progress progress-striped active'>
+ <div class='progress-bar progress-bar-".($item['percentage'] < 60 ? 'info' : ($item['percentage'] < 80 ? 'warning' : 'danger'))."' style='width:{$item['percentage']}%;' aria-valuemax='100' aria-valuemin='0' aria-valuenow='{$item['percentage']}' role='progressbar'></div>
+ </div>";
+ }
+ if (count($list) == 0) {
+ echo "There are no currently active offers.";
+ }
+ ?>
+ </div>
+ <!-- /.panel-body -->
+ </div>
+ <!-- /.panel -->
+ </div>
+ <div class="col-lg-6 col-md-4">
+ <div class="panel panel-default" id="panel-open-invoices">
+ <div class="panel-heading">
+ <i class="fa fa-circle-o-notch fa-fw"></i> Currently open invoices
+ </div>
+ <div class="panel-body table-responsive">
+ <table class="table table-bordered table-striped">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>Contact</th>
+ <th>Invoice sent</th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php
+ $offers = BusinessAdmin::getOffers($_pdo, array("`invoice_date` > '1970-01-01'", "`payment_received` <= '1970-01-01' OR `payment_received` IS NULL"));
+ if (count($offers) == 0) {
+ echo "<tr><td colspan='3'>There are no currently open invoices.</td></tr>";
+ } else {
+ foreach ($offers as $offer) {
+ echo "<tr>";
+ echo "<td>{$offer->getId()}</td>";
+ echo "<td>{$offer->getContact()->getClient()->getName()}</td>";
+ echo "<td>".BusinessAdmin::formatDate($offer->getInvoiceDate(), false)."</td>";
+ echo "</tr>";
+ }
+ }
+ ?>
+ </tbody>
+ </table>
+ </div>
+ <!-- /.panel-body -->
+ </div>
+ <!-- /.panel -->
+ </div>
+ </div>
+ <!-- /.row -->
+ <div class="row">
+ <div class="col-lg-12">
+ <div class="panel panel-default" id="panel-timeline">
+ <div class="panel-heading">
+ <i class="fa fa-clock-o fa-fw"></i> Timeline
+ </div>
+ <!-- /.panel-heading -->
+ <div class="panel-body">
+ <ul class="timeline">
+ <?php
+ $offers = BusinessAdmin::getOffers($_pdo);
+ $list = array();
+ $sort_list = array();
+ foreach ($offers as $offer) {
+ $temp = array(
+ 'id' => $offer->getId(),
+ 'contact' => $offer->getContact()->getName(),
+ 'assignments' => '',
+ 'assignments_header' => ''
+ );
+ foreach ($offer->getAssignments() as $assignment) {
+ $temp['assignments'] .= "<b>{$assignment->getTitle()}</b><br/><span class='smaller'>(".constants::invoice_valuta."{$assignment->calculate(assignment::SUBTOTAL)} excl. VAT, ".constants::invoice_valuta."{$assignment->calculate(assignment::TOTAL)} incl. VAT)</span><br/><p>{$assignment->getDescription()}</p>";
+ $temp['assignments_header'] .= "<b>{$assignment->getTitle()}</b><br/><span class='smaller'>(".constants::invoice_valuta."{$assignment->calculate(assignment::SUBTOTAL)} excl. VAT, ".constants::invoice_valuta."{$assignment->calculate(assignment::TOTAL)} incl. VAT)</span><br/>";
+ }
+ $list[] = array_merge($temp, array('type' => 'start', 'time' => $offer->getStartDate(), 'description' => 'Offer started'));
+ $sort_list[] = $offer->getStartDate() . $offer->getId() . 0;
+ $list[] = array_merge($temp, array('type' => 'end', 'time' => $offer->getEndDate(), 'description' => 'Offer ended'));
+ $sort_list[] = $offer->getEndDate() . $offer->getId() . 1;
+ if ($offer->getInvoiceDate() > 0) {
+ $list[] = array_merge($temp, array('type' => 'invoice', 'time' => $offer->getInvoiceDate(), 'description' => 'Invoice sent'));
+ $sort_list[] = $offer->getInvoiceDate() . $offer->getId() . 2;
+ if ($offer->getPaymentReceived() > 0) {
+ $list[] = array_merge($temp, array('type' => 'payment_received', 'time' => $offer->getPaymentReceived(), 'description' => 'Payment received'));
+ $sort_list[] = $offer->getPaymentReceived() . $offer->getId() . 3;
+ }
+ }
+ }
+ array_multisort($sort_list, SORT_DESC, $list);
+ foreach ($list as $item) {
+ if ($item['time'] > time()) {
+ continue;
+ }
+ echo "<li" . ($item['type'] != 'start' ? ' class="timeline-inverted"' : '') . ">";
+ switch ($item['type']) {
+ case 'start': echo "<div class='timeline-badge info' title='{$item['description']}'><i class='fa fa-circle-o-notch'></i></div>"; break;
+ case 'end': echo "<div class='timeline-badge primary' title='{$item['description']}'><i class='fa fa-circle-o'></i></div>"; break;
+ case 'invoice': echo "<div class='timeline-badge warning' title='{$item['description']}'><i class='fa fa-check-circle-o'></i></div>"; break;
+ case 'payment_received': echo "<div class='timeline-badge success' title='{$item['description']}'><i class='fa fa-eur'></i></div>"; break;
+ }
+ echo "<div class='timeline-panel'>";
+ echo "<div class='timeline-heading'><h4 class='timeline-title'>#{$item['id']} to {$item['contact']}: {$item['description']}</h4><p><small class='text-muted'><i class='fa fa-clock-o fa-fw'></i> ".BusinessAdmin::formatDate($item['time'],false,true,true)."</small></p></div>";
+ switch ($item['type']) {
+ case 'start': echo "<div class='timeline-body'>{$item['assignments']}</div>"; break;
+ default: echo "<div class='timeline-body'>{$item['assignments_header']}</div>";
+ }
+ echo "</div>";
+ echo "</li>";
+ }
+ if (count($list) == 0) {
+ echo '<li class="timeline-inverted">
+ <div class="timeline-badge info"><i class="fa fa-check-circle-o"></i></div>
+ <div class="timeline-panel">
+ <div class="timeline-heading"><h4 class="timeline-title">Welcome to BusinessAdmin!</div>
+ <div class="timeline-body">When you start adding projects, a timeline will appear here.</div>
+ </div>
+ </li>';
+ }
+ ?>
+ </ul>
+ </div>
+ <!-- /.panel-body -->
+ </div>
+ <!-- /.panel -->
+ </div>
+ </div>
+ </div>
+ <!-- /#page-wrapper -->
+
+</div>
+<!-- /#wrapper --> \ No newline at end of file
diff --git a/include/offers-edit.php b/include/offers-edit.php
new file mode 100644
index 0000000..b2a7156
--- /dev/null
+++ b/include/offers-edit.php
@@ -0,0 +1,59 @@
+<?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('./conf.php');
+
+$response = new response();
+
+try {
+ $offer = new offer($_pdo, $_REQUEST['pk']);
+
+ $name = explode('-', $_REQUEST['name']);
+ $what_to_edit = $name[count($name) - 1];
+ switch ($what_to_edit) {
+ case 'start_date':
+ $response->success = $offer->setStartDate(strtotime($_REQUEST['value']));
+ break;
+ case 'end_date':
+ $response->success = $offer->setEndDate(strtotime($_REQUEST['value']));
+ break;
+ case 'invoice_date':
+ $response->success = $offer->setInvoiceDate(strtotime($_REQUEST['value']));
+ break;
+ case 'payment_received':
+ $response->success = $offer->setPaymentReceived(strtotime($_REQUEST['value']));
+ break;
+ default:
+ $response->http_response_code(404);
+ $response->success = false;
+ }
+ if (!$response->success && $response->http_response_code() == 200) {
+ $response->http_response_code(500);
+ $response->message = "The offer could not be edited due to an error.";
+ }
+} catch (PDOException $e) {
+ $response->http_response_code(500);
+ $response->success = false;
+ $response->message = "The offer could not be edited due to a PDO error ({$e->getMessage()}).";
+} catch (Exception $e) {
+ $response->http_response_code(404);
+ $response->success = false;
+ $response->message = "The offer could not be edited due to an exception.";
+}
+echo $response->message; \ No newline at end of file
diff --git a/include/offers-new.php b/include/offers-new.php
new file mode 100644
index 0000000..46bec3b
--- /dev/null
+++ b/include/offers-new.php
@@ -0,0 +1,39 @@
+<?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('./conf.php');
+
+$response = new response();
+
+try {
+ $contact = new contact($_pdo, $_REQUEST['contactId']);
+
+ $offer = $contact->createOffer();
+ $response->success = true;
+ $response->message = "Offer #{$offer->getId()} has been succesfully created. <a class='alert-link' href='javascript:location.reload(true);'>Refresh the page</a>.";
+} catch (PDOException $e) {
+ $response->http_response_code(500);
+ $response->success = false;
+ $response->message = "The offer could not be created due to a PDO error ({$e->getMessage()}).";
+} catch (Exception $e) {
+ $response->http_response_code(404);
+ $response->success = false;
+ $response->message = "The offer could not be created due to an error.";
+}
+echo $response->getJson(); \ No newline at end of file
diff --git a/include/offers-overview.php b/include/offers-overview.php
new file mode 100644
index 0000000..de8863c
--- /dev/null
+++ b/include/offers-overview.php
@@ -0,0 +1,169 @@
+<?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/>.
+ */
+?>
+
+<div class="col-lg-12">
+ <div class="panel panel-default">
+ <div class="panel-heading">Overview</div>
+ <div class="panel-body table-responsive">
+ <table class="table table-bordered table-striped">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>Contact</th>
+ <th>Assignments</th>
+ <th>Dates</th>
+ <th>Invoice</th>
+ <th>Tools</th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php
+ $offers = BusinessAdmin::getOffers($_pdo);
+ foreach ($offers as $offer) {
+ $invoiceFile = $offer->getInvoiceFile();
+
+ echo "<tr>
+ <td class='col-min-width'>{$offer->getId()}</td>
+ <td class='col-min-width'><span title='{$offer->getContact()->getClient()->getName()}'>{$offer->getContact()->getName()}</span></td>
+ <td class='col-max-width'>";
+ foreach ($offer->getAssignments() as $assignment) {
+ echo "<b>{$assignment->getTitle()}</b><br/><span class='smaller'>(".constants::invoice_valuta."{$assignment->calculate(assignment::SUBTOTAL)} excl. VAT, ".constants::invoice_valuta."{$assignment->calculate(assignment::TOTAL)} incl. VAT)</span><br/><p>{$assignment->getDescription()}</p>";
+ }
+ echo "</td>
+ <td class='col-min-width'>
+ <table>
+ <tr>
+ <th style='padding-right:1em;'>From:</th>
+ <td><a href='#' class='editable' id='editable-offer-{$offer->getId()}-start_date' data-type='text' data-pk='{$offer->getId()}' data-url='".constants::url_external."offers/edit'>".BusinessAdmin::formatDate($offer->getStartDate(),false,true)."</a></td>
+ </tr>
+ <tr>
+ <th style='padding-right:1em;'>To:</th>
+ <td><a href='#' class='editable' id='editable-offer-{$offer->getId()}-end_date' data-type='text' data-pk='{$offer->getId()}' data-url='".constants::url_external."offers/edit'>".BusinessAdmin::formatDate($offer->getEndDate(),false,true)."</a></td>
+ </tr>
+ <tr>
+ <th style='padding-right:1em;'>Invoice:</th>
+ <td><a href='#' class='editable' id='editable-offer-{$offer->getId()}-invoice_date' data-type='text' data-pk='{$offer->getId()}' data-url='".constants::url_external."offers/edit'>".BusinessAdmin::formatDate($offer->getInvoiceDate(),false,true)."</a></td>
+ </tr>
+ <tr>
+ <th style='padding-right:1em;'>Payment received:</th>
+ <td><a href='#' class='editable' id='editable-offer-{$offer->getId()}-payment_received' data-type='text' data-pk='{$offer->getId()}' data-url='".constants::url_external."offers/edit'>".BusinessAdmin::formatDate($offer->getPaymentReceived(),false,true)."</a></td>
+ </tr>
+ </table>
+ </td>
+ <td class='col-min-width'>"
+ . (($invoiceFile instanceof file)
+ ? "<a title='View' href='{$invoiceFile->getFilenameURI()}' target='_blank' class='btn btn-default btn-circle fa fa-eye'></a>
+ <a title='Regenerate' href='?generate_invoice={$offer->getId()}' class='btn btn-default btn-circle fa fa-refresh'></a>
+ <a title='Trash' href='?trash_invoice={$offer->getId()}' class='btn btn-default btn-circle fa fa-trash'></a>"
+ : "<a title='Create invoice' href='?generate_invoice={$offer->getId()}' class='btn btn-default btn-circle fa fa-calculator'></a>")
+ . "<br/>
+ <table>
+ <tr>
+ <th style='padding-right:1em;'>Subtotal:</th>
+ <td>".constants::invoice_valuta."{$offer->calculate(offer::SUBTOTAL)}</td>
+ </tr>
+ <tr>
+ <th style='padding-right:1em;'>VAT:</th>
+ <td>".constants::invoice_valuta."{$offer->calculate(offer::VAT)}</td>
+ <tr>
+ </tr>
+ <th style='padding-right:1em;'>Total:</th>
+ <td>".constants::invoice_valuta."{$offer->calculate(offer::TOTAL)}</td>
+ </tr>
+ </table>
+ </td>
+ <td class='col-min-width'>
+ <a title='" . ($offer->isAccepted() ? "Accepted" : "Not accepted") . "' href='?toggle_accept={$offer->getId()}' class='btn " . ($offer->isAccepted() ? "btn-success" : "btn-default") . " btn-circle fa fa-check'></a><a title='View' href='?id={$offer->getId()}' class='btn btn-primary btn-circle fa fa-arrow-right'></a><a title='Delete' href='?delete={$offer->getId()}' class='btn btn-danger btn-circle fa fa-times'></a>
+ </td>
+ </tr>";
+ }
+ if (count($offers) == 0) {
+ echo "<tr><td colspan='6'>There are no offers in the database. Why not start with creating one, below?</td></tr>";
+ }
+ ?>
+ </tbody>
+ </table>
+ </div>
+ </div>
+</div>
+<div class="col-lg-6 col-md-6">
+ <div class="panel panel-default">
+ <div class="panel-heading">Create new</div>
+ <div class="panel-body">
+ <form role="form" id="newOffer" action='<?=constants::url_external?>offers/new' method="post" class="bootstrapValidator ajaxify"
+ data-ajaxify-options='{"success":"newOfferSuccess","error":"newOfferError","beforeSubmit":"newOfferBeforeSubmit","clearForm":true}'>
+ <div class="ajaxify-response alert alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><span class="ajaxify-response-text"></span></div>
+ <div class="form-group">
+ <label>Contact:</label>
+ <select name="contactId" class="form-control">
+ <?php
+ foreach (BusinessAdmin::getContacts($_pdo) as $contact) {
+ echo "<option value='{$contact->getId()}'>{$contact->getName()} ({$contact->getClient()->getName()})</option>";
+ }
+ ?>
+ </select>
+ </div>
+ <button type="submit" class="btn btn-default">Go</button>
+ </form>
+ <script type="text/javascript">
+ // Callback for before the form is submitted
+ function newOfferBeforeSubmit() {
+ $('#newOffer input').prop('disabled', true);
+ $('#newOffer .ajaxify-response').hide().removeClass('alert-success alert-danger').find('.ajaxify-response-text').html('');
+ }
+
+ // Callback for when the form is successfully submitted
+ function newOfferSuccess(data) {
+ if (data.success == true) {
+ $('#newOffer .ajaxify-response')
+ .addClass('alert-success')
+ .show()
+ .find('.ajaxify-response-text')
+ .html(data.message);
+
+ $('#newOffer input, #newOffer button').prop('disabled', false);
+ $('#newOffer').data('bootstrapValidator').resetForm();
+ } else {
+ $('#newOffer .ajaxify-response')
+ .addClass('alert-danger')
+ .show()
+ .find('.ajaxify-response-text')
+ .html(data.message);
+
+ $('#newOffer input, #newOffer button').prop('disabled', false);
+ $('#newOffer').data('bootstrapValidator').resetForm();
+ }
+ }
+
+ // Callback for when form submission encountered an error
+ function newOfferError() {
+ $('#newOffer .ajaxify-response')
+ .addClass('alert-danger')
+ .show()
+ .find('.ajaxify-response-text')
+ .html('An unknown error occurred. Please contact support.');
+
+ $('#newOffer input, #newOffer button').prop('disabled', false);
+ $('#newOffer').data('bootstrapValidator').resetForm();
+ }
+ </script>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/include/offers-view.php b/include/offers-view.php
new file mode 100644
index 0000000..b7fb092
--- /dev/null
+++ b/include/offers-view.php
@@ -0,0 +1,130 @@
+<?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/>.
+ */
+
+$_offer = new offer($_pdo, $_id);
+$_offer->generateInvoice();
+?>
+<div class="col-lg-6">
+ <div class="panel panel-default" id="panel-timeline">
+ <div class="panel-heading">
+ <i class="fa fa-clock-o fa-fw"></i> Timeline
+ </div>
+ <!-- /.panel-heading -->
+ <div class="panel-body">
+ <ul class="timeline">
+ <?php
+ $list = array();
+ $sort_list = array();
+
+ $temp = array(
+ 'id' => $_offer->getId(),
+ 'contact' => $_offer->getContact()->getName(),
+ 'assignments' => '',
+ 'assignments_header' => ''
+ );
+ foreach ($_offer->getAssignments() as $assignment) {
+ $temp['assignments'] .= "<b>{$assignment->getTitle()}</b><br/><span class='smaller'>(".constants::invoice_valuta."{$assignment->calculate(assignment::SUBTOTAL)} excl. VAT, ".constants::invoice_valuta."{$assignment->calculate(assignment::TOTAL)} incl. VAT)</span><br/><p>{$assignment->getDescription()}</p>";
+ $temp['assignments_header'] .= "<b>{$assignment->getTitle()}</b><br/><span class='smaller'>(".constants::invoice_valuta."{$assignment->calculate(assignment::SUBTOTAL)} excl. VAT, ".constants::invoice_valuta."{$assignment->calculate(assignment::TOTAL)} incl. VAT)</span><br/>";
+ }
+ $list[] = array_merge($temp, array('type' => 'start', 'time' => $_offer->getStartDate(), 'description' => 'Offer started'));
+ $sort_list[] = $_offer->getStartDate() . $_offer->getId() . 0;
+ $list[] = array_merge($temp, array('type' => 'end', 'time' => $_offer->getEndDate(), 'description' => 'Offer ended'));
+ $sort_list[] = $_offer->getEndDate() . $_offer->getId() . 1;
+ if ($_offer->getInvoiceDate() > 0) {
+ $list[] = array_merge($temp, array('type' => 'invoice', 'time' => $_offer->getInvoiceDate(), 'description' => 'Invoice sent'));
+ $sort_list[] = $_offer->getInvoiceDate() . $_offer->getId() . 2;
+ if ($_offer->getPaymentReceived() > 0) {
+ $list[] = array_merge($temp, array('type' => 'payment_received', 'time' => $_offer->getPaymentReceived(), 'description' => 'Payment received'));
+ $sort_list[] = $_offer->getPaymentReceived() . $_offer->getId() . 3;
+ }
+ }
+
+ array_multisort($sort_list, SORT_DESC, $list);
+ $i = 0;
+ foreach ($list as $item) {
+ if ($item['time'] > time()) {
+ continue;
+ }
+ echo "<li" . ($i++ % 2 == 0 ? ' class="timeline-inverted"' : '') . ">";
+ switch ($item['type']) {
+ case 'start': echo "<div class='timeline-badge info' title='{$item['description']}'><i class='fa fa-circle-o-notch'></i></div>"; break;
+ case 'end': echo "<div class='timeline-badge primary' title='{$item['description']}'><i class='fa fa-circle-o'></i></div>"; break;
+ case 'invoice': echo "<div class='timeline-badge warning' title='{$item['description']}'><i class='fa fa-check-circle-o'></i></div>"; break;
+ case 'payment_received': echo "<div class='timeline-badge success' title='{$item['description']}'><i class='fa fa-eur'></i></div>"; break;
+ }
+ echo "<div class='timeline-panel'>";
+ echo "<div class='timeline-heading'><h4 class='timeline-title'>#{$item['id']} to {$item['contact']}: {$item['description']}</h4><p><small class='text-muted'><i class='fa fa-clock-o fa-fw'></i> ".BusinessAdmin::formatDate($item['time'],false,true,true)."</small></p></div>";
+ switch ($item['type']) {
+ case 'start': echo "<div class='timeline-body'>{$item['assignments']}</div>"; break;
+ default: echo "<div class='timeline-body'>{$item['assignments_header']}</div>";
+ }
+ echo "</div>";
+ echo "</li>";
+ }
+ ?>
+ </ul>
+ </div>
+ <!-- /.panel-body -->
+ </div>
+ <!-- /.panel -->
+</div>
+<div class="col-lg-6">
+ <div class="panel panel-default">
+ <div class="panel-heading">Assignments</div>
+ <div class="panel-body table-responsive">
+ <table class="table table-bordered table-striped">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>Briefing</th>
+ <th>Time</th>
+ <th>Price</th>
+ <th>Tools</th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php
+ $assignments = BusinessAdmin::getAssignments($_pdo);
+ foreach ($assignments as $assignment) {
+ echo "<tr>
+ <td class='col-min-width'>{$assignment->getId()}</td>
+ <td class='col-max-width'>
+ <b><a href='#' class='editable' id='editable-assignment-{$assignment->getId()}-title' data-type='text' data-pk='{$assignment->getId()}' data-url='".constants::url_external."assignments/edit'>{$assignment->getTitle()}</a></b><br/>
+ <p>{$assignment->getDescription()}</p>
+ </td>
+ <td class='col-min-width'><a href='#' class='editable' id='editable-assignment-{$assignment->getId()}-hours' data-type='text' data-pk='{$assignment->getId()}' data-url='".constants::url_external."assignments/edit'>{$assignment->getHours()}</a>h</td>
+ <td class='col-min-width'>
+ ".constants::invoice_valuta."<a href='#' class='editable' id='editable-assignment-{$assignment->getId()}-price_per_hour' data-type='text' data-pk='{$assignment->getId()}' data-url='".constants::url_external."assignments/edit'>{$assignment->getPricePerHour()}</a> / hr<br/>
+ <a href='#' class='editable' id='editable-assignment-{$assignment->getId()}-vat' data-type='text' data-pk='{$assignment->getId()}' data-url='".constants::url_external."assignments/edit'>{$assignment->getVAT()}</a>% VAT
+ </td>
+ <td class='col-min-width'>
+ <a title='View' href='?id={$assignment->getId()}' class='btn btn-primary btn-circle fa fa-arrow-right'></a>
+ <a title='Delete' href='?delete={$assignment->getId()}' class='btn btn-danger btn-circle fa fa-times'></a>
+ </td>
+ </tr>";
+ }
+ if (count($assignments) == 0) {
+ echo "<tr><td colspan='6'>There are no assignments in the database. Why not start with creating one, below?</td></tr>";
+ }
+ ?>
+ </tbody>
+ </table>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/include/offers.php b/include/offers.php
new file mode 100644
index 0000000..872773d
--- /dev/null
+++ b/include/offers.php
@@ -0,0 +1,157 @@
+<?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('./index.php');
+require('./header.php');
+?>
+
+<div id="wrapper">
+
+ <?php require('./nav.php'); ?>
+
+ <div id="page-wrapper">
+ <div class="row">
+ <?php
+ //------------------------------------------------------------------------------
+ // Check for GET variables
+ //
+ // ?id=<id> View information of the offer with id <id>
+ // ?toggle_accept=<id> Toggle the accepted status of the offer with id <id>
+ // ?generate_invoice=<id> Generate an invoice for the offer with id <id>
+ // ?trash_invoice=<id> Trash the invoice file
+ // ?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->getId()}";
+ $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);
+ if ($offer->toggleAccepted()) {
+ 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 offer #{$offer->getId()} has been set to <i>".($offer->isAccepted() ? "accepted" : "unaccepted")."</i>.</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 status of the offer #{$offer->getId()} could not be changed.</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>";
+ } 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>";
+ }
+
+ 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->getId()} is generated: <a class='alert-link' href='{$file->getFilenameURI()}' target='_blank'>{$file->getFilename()}</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->getId()} 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>";
+ }
+ 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->getId()} 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>";
+ }
+ } 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->getId()} 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>";
+ }
+ 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->getId()} 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->getId()} 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>";
+ } 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>";
+ }
+
+ echo "</div>";
+ }
+
+ if ($show_individual !== false) {
+ $_id = $show_individual;
+ require('offers-view.php');
+ } else {
+ require('offers-overview.php');
+ }
+ ?>
+ </div>
+ <!-- /.row -->
+ </div>
+ <!-- /#page-wrapper -->
+
+</div>
+<!-- /#wrapper -->
+
+<?php
+require('./footer.php');
+?> \ No newline at end of file