aboutsummaryrefslogtreecommitdiff
path: root/docs/files
diff options
context:
space:
mode:
authorCamil Staps2015-02-07 21:06:17 +0100
committerCamil Staps2015-02-07 21:06:17 +0100
commit29955216d69ca08b69afe1ace71151839049c045 (patch)
tree48a085e24cf1e65677bbace195017f118292ecc2 /docs/files
parentAdded some documentation; added Makefile for generating docs with phpdoc (diff)
Added documentation
Diffstat (limited to 'docs/files')
-rw-r--r--docs/files/BusinessAdmin.class.html280
-rw-r--r--docs/files/BusinessAdmin.class.php.txt282
-rw-r--r--docs/files/assignment.class.html280
-rw-r--r--docs/files/assignment.class.php.txt316
-rw-r--r--docs/files/client.class.html280
-rw-r--r--docs/files/client.class.php.txt195
-rw-r--r--docs/files/constants.class.html280
-rw-r--r--docs/files/constants.class.php.txt71
-rw-r--r--docs/files/contact.class.html280
-rw-r--r--docs/files/contact.class.php.txt378
-rw-r--r--docs/files/correspondence.class.html261
-rw-r--r--docs/files/correspondence.class.php.txt269
-rw-r--r--docs/files/file.class.html280
-rw-r--r--docs/files/file.class.php.txt148
-rw-r--r--docs/files/offer.class.html280
-rw-r--r--docs/files/offer.class.php.txt627
-rw-r--r--docs/files/response.class.html280
-rw-r--r--docs/files/response.class.php.txt112
18 files changed, 4899 insertions, 0 deletions
diff --git a/docs/files/BusinessAdmin.class.html b/docs/files/BusinessAdmin.class.html
new file mode 100644
index 0000000..e4ca958
--- /dev/null
+++ b/docs/files/BusinessAdmin.class.html
@@ -0,0 +1,280 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
+ <meta charset="utf-8"/>
+ <title>API Documentation</title>
+ <meta name="author" content=""/>
+ <meta name="description" content=""/>
+
+ <link href="../css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
+ <link href="../css/font-awesome.min.css" rel="stylesheet">
+ <link href="../css/prism.css" rel="stylesheet" media="all"/>
+ <link href="../css/template.css" rel="stylesheet" media="all"/>
+
+ <!--[if lt IE 9]>
+ <script src="../js/html5.js"></script>
+ <![endif]-->
+ <script src="../js/jquery-1.11.0.min.js"></script>
+ <script src="../js/ui/1.10.4/jquery-ui.min.js"></script>
+ <script src="../js/bootstrap.min.js"></script>
+ <script src="../js/jquery.smooth-scroll.js"></script>
+ <script src="../js/prism.min.js"></script>
+ <!-- TODO: Add http://jscrollpane.kelvinluck.com/ to style the scrollbars for browsers not using webkit-->
+ <script type="text/javascript">
+ function loadExternalCodeSnippets() {
+ Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function (pre) {
+ var src = pre.getAttribute('data-src');
+ var extension = (src.match(/\.(\w+)$/) || [, ''])[1];
+ var language = 'php';
+
+ var code = document.createElement('code');
+ code.className = 'language-' + language;
+
+ pre.textContent = '';
+
+ code.textContent = 'Loading…';
+
+ pre.appendChild(code);
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.open('GET', src, true);
+
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+
+ if (xhr.status < 400 && xhr.responseText) {
+ code.textContent = xhr.responseText;
+
+ Prism.highlightElement(code);
+ }
+ else if (xhr.status >= 400) {
+ code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;
+ }
+ else {
+ code.textContent = '✖ Error: File does not exist or is empty';
+ }
+ }
+ };
+
+ xhr.send(null);
+ });
+ }
+
+ $(document).ready(function(){
+ loadExternalCodeSnippets();
+ });
+ $('#source-view').on('shown', function () {
+ loadExternalCodeSnippets();
+ })
+ </script>
+
+ <link rel="shortcut icon" href="../images/favicon.ico"/>
+ <link rel="apple-touch-icon" href="../images/apple-touch-icon.png"/>
+ <link rel="apple-touch-icon" sizes="72x72" href="../images/apple-touch-icon-72x72.png"/>
+ <link rel="apple-touch-icon" sizes="114x114" href="../images/apple-touch-icon-114x114.png"/>
+</head>
+<body>
+
+<div class="navbar navbar-fixed-top">
+ <div class="navbar-inner">
+ <div class="container">
+ <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+ <i class="icon-ellipsis-vertical"></i>
+ </a>
+ <a class="brand" href="../index.html">API Documentation</a>
+
+ <div class="nav-collapse">
+ <ul class="nav pull-right">
+ <li class="dropdown" id="charts-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Charts <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../graphs/class.html">
+ <i class="icon-list-alt"></i>&#160;Class hierarchy diagram
+ </a>
+ </li>
+ </ul>
+ </li>
+ <li class="dropdown" id="reports-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Reports <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../reports/errors.html">
+ <i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">50</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/markers.html">
+ <i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">1</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/deprecated.html">
+ <i class="icon-list-alt"></i>&#160;Deprecated <span class="label label-info pull-right">0</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <!--<div class="go_to_top">-->
+ <!--<a href="#___" style="color: inherit">Back to top&#160;&#160;<i class="icon-upload icon-white"></i></a>-->
+ <!--</div>-->
+</div>
+
+<div id="___" class="container-fluid">
+ <section class="row-fluid">
+ <div class="span2 sidebar">
+ <div class="accordion" style="margin-bottom: 0">
+ <div class="accordion-group">
+ <div class="accordion-heading">
+ <a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-2048145480"></a>
+ <a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
+ </div>
+ <div id="namespace-2048145480" class="accordion-body collapse in">
+ <div class="accordion-inner">
+
+
+ <ul>
+ <li class="class"><a href="../classes/assignment.html">assignment</a></li>
+ <li class="class"><a href="../classes/BusinessAdmin.html">BusinessAdmin</a></li>
+ <li class="class"><a href="../classes/client.html">client</a></li>
+ <li class="class"><a href="../classes/constants.html">constants</a></li>
+ <li class="class"><a href="../classes/contact.html">contact</a></li>
+ <li class="class"><a href="../classes/correspondence.html">correspondence</a></li>
+ <li class="class"><a href="../classes/file.html">file</a></li>
+ <li class="class"><a href="../classes/offer.html">offer</a></li>
+ <li class="class"><a href="../classes/response.html">response</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ </div>
+ </section>
+ <section class="row-fluid">
+ <div class="span10 offset2">
+ <div class="row-fluid">
+ <div class="span8 content file">
+ <nav>
+ </nav>
+
+ <a href="#source-view" role="button" class="pull-right btn" data-toggle="modal"><i class="icon-code"></i></a>
+ <h1><small></small>BusinessAdmin.class.php</h1>
+ <p><em>This file provides the BusinessAdmin class</em></p>
+
+
+
+
+ <h2>Classes</h2>
+ <table class="table table-hover">
+ <tr>
+ <td><a href="../classes/BusinessAdmin.html">BusinessAdmin</a></td>
+ <td><em>Provides basic functions like adding elements to the database</em></td>
+ </tr>
+ </table>
+ </div>
+
+ <aside class="span4 detailsbar">
+ <dl>
+ <dt>Package</dt>
+ <dd><div class="namespace-wrapper">\Default</div></dd>
+
+
+ </dl>
+ <h2>Tags</h2>
+ <table class="table table-condensed">
+ <tr>
+ <th>
+ author
+ </th>
+ <td>
+ <p>Camil Staps</p>
+<p>BusinessAdmin: administrative software for small companies
+Copyright (C) 2015 Camil Staps (ViviSoft)</p>
+<p>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.</p>
+<p>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.</p>
+<p>You should have received a copy of the GNU General Public License
+along with this program. If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.</p>
+ </td>
+ </tr>
+ </table>
+
+ </aside>
+ </div>
+
+
+
+ </div>
+ </section>
+
+ <div id="source-view" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="source-view-label" aria-hidden="true">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+ <h3 id="source-view-label"></h3>
+ </div>
+ <div class="modal-body">
+ <pre data-src="../files/BusinessAdmin.class.php.txt" class="language-php line-numbers"></pre>
+ </div>
+ </div>
+
+ <footer class="row-fluid">
+ <section class="span10 offset2">
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <section class="row-fluid footer-sections">
+ <section class="span4">
+ <h1><i class="icon-code"></i></h1>
+ <div>
+ <ul>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-bar-chart"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../graphs/class.html">Class Hierarchy Diagram</a></li>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-pushpin"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../reports/errors.html">Errors</a></li>
+ <li><a href="../reports/markers.html">Markers</a></li>
+ </ul>
+ </div>
+ </section>
+ </section>
+ </section>
+ </section>
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <hr />
+ Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
+ on February 7th, 2015 at 21:04.
+ </section>
+ </section>
+ </section>
+ </footer>
+</div>
+
+</body>
+</html>
diff --git a/docs/files/BusinessAdmin.class.php.txt b/docs/files/BusinessAdmin.class.php.txt
new file mode 100644
index 0000000..7efedd2
--- /dev/null
+++ b/docs/files/BusinessAdmin.class.php.txt
@@ -0,0 +1,282 @@
+<?php
+/**
+ * This file provides the BusinessAdmin class
+ *
+ * @author Camil Staps
+ *
+ * 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/>.
+ */
+
+/**
+ * Provides basic functions like adding elements to the database
+ */
+class BusinessAdmin {
+ //------------------------------------------------------------------------------
+ // Getters and setters
+ //------------------------------------------------------------------------------
+
+ /**
+ * Get all client ids
+ *
+ * @see BusinessAdmin::getClients() This funtion returns instances of the client class instead of just the ids
+ *
+ * @param PDO $pdo The PDO class for database connection
+ *
+ * @throws PDOException Is something went wrong with the database
+ *
+ * @return int[] The ids
+ */
+ public static function getClientIds($pdo) {
+ $ids = array();
+ $clients = $pdo->query("SELECT `id` FROM `".constants::db_prefix."client`")->fetchAll(PDO::FETCH_ASSOC);
+ foreach ($clients as $client) {
+ $ids[] = $client['id'];
+ }
+ return $ids;
+ }
+
+ /**
+ * Get all clients
+ *
+ * @see BusinessAdmin::getClientIds() This function returns just the ids of the clients, and not instances of the client class
+ *
+ * @param PDO $pdo The PDO class for database connection
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return client[] An array indexed by id of instances of the client class
+ */
+ public static function getClients($pdo) {
+ $ids = self::getClientIds($pdo);
+ $clients = array();
+ foreach ($ids as $id) {
+ $clients[$id] = new client($pdo, $id);
+ }
+ return $clients;
+ }
+
+ /**
+ * Get all contact ids
+ *
+ * @see BusinessAdmin::getContacts() This funtion returns instances of the contact class instead of just the ids
+ *
+ * @param PDO $pdo The PDO class for database connection
+ *
+ * @throws PDOException Is something went wrong with the database
+ *
+ * @return int[] The ids
+ */
+ public static function getContactIds($pdo) {
+ $ids = array();
+ $contacts = $pdo->query("SELECT `id` FROM `".constants::db_prefix."contact`")->fetchAll(PDO::FETCH_ASSOC);
+ foreach ($contacts as $contact) {
+ $ids[] = $contact['id'];
+ }
+ return $ids;
+ }
+
+ /**
+ * Get all contacts
+ *
+ * @see BusinessAdmin::getContactIds() This function returns just the ids of the contacts, and not instances of the contact class
+ *
+ * @param PDO $pdo The PDO class for database connection
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return contact[] An array indexed by id of instances of the contact class
+ */
+ public static function getContacts($pdo) {
+ $ids = self::getContactIds($pdo);
+ $contacts = array();
+ foreach ($ids as $id) {
+ $contacts[$id] = new contact($pdo, $id);
+ }
+ return $contacts;
+ }
+
+ /**
+ * Get all offer ids
+ *
+ * @see BusinessAdmin::getOffers() This funtion returns instances of the offer class instead of just the ids
+ *
+ * @param PDO $pdo The PDO class for database connection
+ * @param string[] $where An array of WHERE clauses that will be AND-ed
+ *
+ * @throws PDOException Is something went wrong with the database
+ *
+ * @return int[] The ids
+ */
+ public static function getOfferIds($pdo, $where = array()) {
+ $ids = array();
+ $offers = $pdo->query("SELECT `id` FROM `".constants::db_prefix."offer`" . ((count($where) > 0) ? (" WHERE (" . implode(') AND (', $where) . ")") : ""))->fetchAll(PDO::FETCH_ASSOC);
+ foreach ($offers as $offer) {
+ $ids[] = $offer['id'];
+ }
+ return $ids;
+ }
+
+ /**
+ * Get all offers
+ *
+ * @see BusinessAdmin::getOfferIds() This function returns just the ids of the offers, and not instances of the offer class
+ *
+ * @param PDO $pdo The PDO class for database connection
+ * @param string[] $where An array of WHERE clauses that will be AND-ed
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return offer[] An array indexed by id of instances of the offer class
+ */
+ public static function getOffers($pdo, $where = array()) {
+ $ids = self::getOfferIds($pdo, $where);
+ $offers = array();
+ foreach ($ids as $id) {
+ $offers[$id] = new offer($pdo, $id);
+ }
+ return $offers;
+ }
+
+ /**
+ * Get all assignment ids
+ *
+ * @see BusinessAdmin::getAssignments() This funtion returns instances of the assignment class instead of just the ids
+ *
+ * @param PDO $pdo The PDO class for database connection
+ *
+ * @throws PDOException Is something went wrong with the database
+ *
+ * @return int[] The ids
+ */
+ public static function getAssignmentIds($pdo) {
+ $ids = array();
+ $assignments = $pdo->query("SELECT `id` FROM `".constants::db_prefix."assignment`")->fetchAll(PDO::FETCH_ASSOC);
+ foreach ($assignments as $assignment) {
+ $ids[] = $assignment['id'];
+ }
+ return $ids;
+ }
+
+ /**
+ * Get all assignments
+ *
+ * @see BusinessAdmin::getAssignmentIds() This function returns just the ids of the assignments, and not instances of the assignment class
+ *
+ * @param PDO $pdo The PDO class for database connection
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return assignment[] An array indexed by id of instances of the assignment class
+ */
+ public static function getAssignments($pdo) {
+ $ids = self::getAssignmentIds($pdo);
+ $assignments = array();
+ foreach ($ids as $id) {
+ $assignments[$id] = new assignment($pdo, $id);
+ }
+ return $assignments;
+ }
+
+ //------------------------------------------------------------------------------
+ // Other functions
+ //------------------------------------------------------------------------------
+
+ /**
+ * Create a new client
+ *
+ * @param PDO $pdo The database connection
+ * @param string $name The name for the new client
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return client|bool A new instance of the client object, or false on failure
+ */
+ public static function createClient($pdo, $name) {
+ $stmt = $pdo->prepare("INSERT INTO `".constants::db_prefix."client` (`name`) VALUES (?)");
+ $stmt->execute(array($name));
+ if ($stmt->rowCount() == 1) {
+ return new client($pdo, $pdo->lastInsertId());
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Create a new file
+ *
+ * @param PDO $pdo The database connection
+ * @param string $filename The desired filename
+ *
+ * @throws PDOException If something went wrong with the database
+ * @throws Exception If the file could not be created (due to permissions, file existed already, etc.), or the database record couldn't be added
+ *
+ * @return file A new instance of the file object
+ */
+ public static function createFile($pdo, $filename) {
+ // Check for file existence
+ if (file_exists(constants::files_folder . $filename)) {
+ throw new Exception("$filename already exists.");
+ }
+
+ // Try to create the file
+ if (file_put_contents(constants::files_folder . $filename, '') === false) {
+ throw new Exception("$filename could not be created. Check the permissions.");
+ }
+
+ $stmt = $pdo->prepare("INSERT INTO `".constants::db_prefix."file` (`filename`) VALUES (?)");
+ $stmt->execute(array($filename));
+ if ($stmt->rowCount() == 1) {
+ return new file($pdo, $pdo->lastInsertId());
+ } else {
+ unlink(constants::files_folder . $filename);
+ throw new Exception("$filename could not be added to the database");
+ }
+ }
+
+ /**
+ * Format a date nicely
+ *
+ * @todo implement $relatively = true
+ *
+ * @param int $timestamp The UNIX timestamp to format
+ * @param bool $with_time If false, only the date is returned; if false, also the time
+ * @param bool $full_date If true, a year will be outputted even if the date is in the current year
+ * @param bool $relatively Whether or not to show the date relatively (e.g. '1 day ago') (NOT IMPLEMENTED YET)
+ *
+ * @return string The formatted date
+ */
+ public static function formatDate($timestamp, $with_time = true, $full_date = false, $relatively = false) {
+ $output = '';
+ if (date('Y', $timestamp) == 1970) {
+ return 'never';
+ }
+ if (date('d/m/Y') == date('d/m/Y', $timestamp)) {
+ return 'today';
+ }
+ if (date('Y') != date('Y', $timestamp) || $full_date) {
+ $output .= date('Y-', $timestamp);
+ }
+ if (date('d/m/Y') != date('d/m/Y', $timestamp) || $full_date) {
+ $output .= date('m-d', $timestamp);
+ }
+ if ($with_time) {
+ $output .= date(' H:i', $timestamp);
+ }
+
+ return $output;
+ }
+}
diff --git a/docs/files/assignment.class.html b/docs/files/assignment.class.html
new file mode 100644
index 0000000..b7eb5c4
--- /dev/null
+++ b/docs/files/assignment.class.html
@@ -0,0 +1,280 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
+ <meta charset="utf-8"/>
+ <title>API Documentation</title>
+ <meta name="author" content=""/>
+ <meta name="description" content=""/>
+
+ <link href="../css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
+ <link href="../css/font-awesome.min.css" rel="stylesheet">
+ <link href="../css/prism.css" rel="stylesheet" media="all"/>
+ <link href="../css/template.css" rel="stylesheet" media="all"/>
+
+ <!--[if lt IE 9]>
+ <script src="../js/html5.js"></script>
+ <![endif]-->
+ <script src="../js/jquery-1.11.0.min.js"></script>
+ <script src="../js/ui/1.10.4/jquery-ui.min.js"></script>
+ <script src="../js/bootstrap.min.js"></script>
+ <script src="../js/jquery.smooth-scroll.js"></script>
+ <script src="../js/prism.min.js"></script>
+ <!-- TODO: Add http://jscrollpane.kelvinluck.com/ to style the scrollbars for browsers not using webkit-->
+ <script type="text/javascript">
+ function loadExternalCodeSnippets() {
+ Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function (pre) {
+ var src = pre.getAttribute('data-src');
+ var extension = (src.match(/\.(\w+)$/) || [, ''])[1];
+ var language = 'php';
+
+ var code = document.createElement('code');
+ code.className = 'language-' + language;
+
+ pre.textContent = '';
+
+ code.textContent = 'Loading…';
+
+ pre.appendChild(code);
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.open('GET', src, true);
+
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+
+ if (xhr.status < 400 && xhr.responseText) {
+ code.textContent = xhr.responseText;
+
+ Prism.highlightElement(code);
+ }
+ else if (xhr.status >= 400) {
+ code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;
+ }
+ else {
+ code.textContent = '✖ Error: File does not exist or is empty';
+ }
+ }
+ };
+
+ xhr.send(null);
+ });
+ }
+
+ $(document).ready(function(){
+ loadExternalCodeSnippets();
+ });
+ $('#source-view').on('shown', function () {
+ loadExternalCodeSnippets();
+ })
+ </script>
+
+ <link rel="shortcut icon" href="../images/favicon.ico"/>
+ <link rel="apple-touch-icon" href="../images/apple-touch-icon.png"/>
+ <link rel="apple-touch-icon" sizes="72x72" href="../images/apple-touch-icon-72x72.png"/>
+ <link rel="apple-touch-icon" sizes="114x114" href="../images/apple-touch-icon-114x114.png"/>
+</head>
+<body>
+
+<div class="navbar navbar-fixed-top">
+ <div class="navbar-inner">
+ <div class="container">
+ <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+ <i class="icon-ellipsis-vertical"></i>
+ </a>
+ <a class="brand" href="../index.html">API Documentation</a>
+
+ <div class="nav-collapse">
+ <ul class="nav pull-right">
+ <li class="dropdown" id="charts-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Charts <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../graphs/class.html">
+ <i class="icon-list-alt"></i>&#160;Class hierarchy diagram
+ </a>
+ </li>
+ </ul>
+ </li>
+ <li class="dropdown" id="reports-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Reports <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../reports/errors.html">
+ <i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">50</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/markers.html">
+ <i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">1</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/deprecated.html">
+ <i class="icon-list-alt"></i>&#160;Deprecated <span class="label label-info pull-right">0</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <!--<div class="go_to_top">-->
+ <!--<a href="#___" style="color: inherit">Back to top&#160;&#160;<i class="icon-upload icon-white"></i></a>-->
+ <!--</div>-->
+</div>
+
+<div id="___" class="container-fluid">
+ <section class="row-fluid">
+ <div class="span2 sidebar">
+ <div class="accordion" style="margin-bottom: 0">
+ <div class="accordion-group">
+ <div class="accordion-heading">
+ <a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-1389342729"></a>
+ <a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
+ </div>
+ <div id="namespace-1389342729" class="accordion-body collapse in">
+ <div class="accordion-inner">
+
+
+ <ul>
+ <li class="class"><a href="../classes/assignment.html">assignment</a></li>
+ <li class="class"><a href="../classes/BusinessAdmin.html">BusinessAdmin</a></li>
+ <li class="class"><a href="../classes/client.html">client</a></li>
+ <li class="class"><a href="../classes/constants.html">constants</a></li>
+ <li class="class"><a href="../classes/contact.html">contact</a></li>
+ <li class="class"><a href="../classes/correspondence.html">correspondence</a></li>
+ <li class="class"><a href="../classes/file.html">file</a></li>
+ <li class="class"><a href="../classes/offer.html">offer</a></li>
+ <li class="class"><a href="../classes/response.html">response</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ </div>
+ </section>
+ <section class="row-fluid">
+ <div class="span10 offset2">
+ <div class="row-fluid">
+ <div class="span8 content file">
+ <nav>
+ </nav>
+
+ <a href="#source-view" role="button" class="pull-right btn" data-toggle="modal"><i class="icon-code"></i></a>
+ <h1><small></small>assignment.class.php</h1>
+ <p><em>Provides the assignment class, an interface to the assignment table in the database</em></p>
+
+
+
+
+ <h2>Classes</h2>
+ <table class="table table-hover">
+ <tr>
+ <td><a href="../classes/assignment.html">assignment</a></td>
+ <td><em>An interface to the assignment table in the database</em></td>
+ </tr>
+ </table>
+ </div>
+
+ <aside class="span4 detailsbar">
+ <dl>
+ <dt>Package</dt>
+ <dd><div class="namespace-wrapper">\Default</div></dd>
+
+
+ </dl>
+ <h2>Tags</h2>
+ <table class="table table-condensed">
+ <tr>
+ <th>
+ author
+ </th>
+ <td>
+ <p>Camil Staps</p>
+<p>BusinessAdmin: administrative software for small companies
+Copyright (C) 2015 Camil Staps (ViviSoft)</p>
+<p>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.</p>
+<p>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.</p>
+<p>You should have received a copy of the GNU General Public License
+along with this program. If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.</p>
+ </td>
+ </tr>
+ </table>
+
+ </aside>
+ </div>
+
+
+
+ </div>
+ </section>
+
+ <div id="source-view" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="source-view-label" aria-hidden="true">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+ <h3 id="source-view-label"></h3>
+ </div>
+ <div class="modal-body">
+ <pre data-src="../files/assignment.class.php.txt" class="language-php line-numbers"></pre>
+ </div>
+ </div>
+
+ <footer class="row-fluid">
+ <section class="span10 offset2">
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <section class="row-fluid footer-sections">
+ <section class="span4">
+ <h1><i class="icon-code"></i></h1>
+ <div>
+ <ul>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-bar-chart"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../graphs/class.html">Class Hierarchy Diagram</a></li>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-pushpin"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../reports/errors.html">Errors</a></li>
+ <li><a href="../reports/markers.html">Markers</a></li>
+ </ul>
+ </div>
+ </section>
+ </section>
+ </section>
+ </section>
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <hr />
+ Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
+ on February 7th, 2015 at 21:04.
+ </section>
+ </section>
+ </section>
+ </footer>
+</div>
+
+</body>
+</html>
diff --git a/docs/files/assignment.class.php.txt b/docs/files/assignment.class.php.txt
new file mode 100644
index 0000000..cafba65
--- /dev/null
+++ b/docs/files/assignment.class.php.txt
@@ -0,0 +1,316 @@
+<?php
+/**
+ * Provides the assignment class, an interface to the assignment table in the database
+ *
+ * @author Camil Staps
+ *
+ * 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/>.
+ */
+
+/**
+ * An interface to the assignment table in the database
+ */
+class assignment {
+ /**
+ * @var pdo $pdo The PDO class for database communication
+ * @var int $id The id of the assignment
+ * @var int $offerId The id of the offer this assignment is linked to
+ * @var string $title The title of the assignment
+ * @var string $description The description of the assignment
+ * @var int $hours The amount of hours of the assignment
+ * @var float $price_per_hour The price per hour for this assignment, in your valuta
+ * @var float $vat The percentage of VAT to calculate on this assignment
+ */
+ protected $pdo, $offerId, $id, $title, $description, $hours, $price_per_hour, $vat;
+
+ const SUBTOTAL = 1;
+ const VAT = 2;
+ const TOTAL = 3;
+
+ /**
+ * Create a new instance
+ *
+ * @param PDO $pdo The PDO class, to access the database
+ * @param int $id The id of the assignment to fetch
+ *
+ * @throws PDOException If something went wrong with the database
+ * @throws Exception If the assignment could not be found
+ */
+ public function __construct($pdo, $id) {
+ $this->pdo = $pdo;
+
+ $stmt = $this->pdo->prepare("SELECT * FROM `".constants::db_prefix."assignment` WHERE `id`=?");
+ $stmt->execute(array($id));
+ if ($stmt->rowCount() == 0) {
+ throw new Exception("The assignment with id '$id' could not be found.");
+ }
+ $assignment = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ $this->id = $assignment['id'];
+ $this->offerId = $assignment['offerId'];
+ $this->title = $assignment['title'];
+ $this->description = $assignment['description'];
+ $this->hours = $assignment['hours'];
+ $this->price_per_hour = $assignment['price_per_hour'];
+ $this->vat = $assignment['VAT_percentage'];
+ }
+
+ //------------------------------------------------------------------------------
+ // Getters and setters
+ //------------------------------------------------------------------------------
+
+ /**
+ * Get the ID of the assignment
+ *
+ * @return int The ID
+ */
+ public function getId() {
+ return $this->id;
+ }
+
+ /**
+ * Get the ID of the offer that this assignment is linked to
+ *
+ * @return int The ID
+ */
+ public function getOfferId() {
+ return $this->offerId;
+ }
+
+ /**
+ * Get the offer that this assignment is linked to
+ *
+ * @return offer The offer
+ */
+ public function getOffer() {
+ return new offer($this->pdo, $this->offerId);
+ }
+
+ /**
+ * Get the title of the assignment
+ *
+ * @return string The title
+ */
+ public function getTitle() {
+ return $this->title;
+ }
+
+ /**
+ * Set the title of the assignment
+ *
+ * @param string $title The new title for the assignment
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setTitle($title) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."assignment` SET `title`=? WHERE `id`=?");
+ $stmt->execute(array($title, $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->title = $title;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the description of the assignment
+ *
+ * @param bool $parseMarkdown Whether or not to parse markdown
+ *
+ * @return string The description
+ */
+ public function getDescription($parseMarkdown = true) {
+ if ($parseMarkdown) {
+ $pd = new Parsedown;
+ return $pd->text($this->description);
+ } else {
+ return $this->description;
+ }
+ }
+
+ /**
+ * Set the description of the assignment
+ *
+ * @param string $description The new description for the assignment
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setDescription($description) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."assignment` SET `description`=? WHERE `id`=?");
+ $stmt->execute(array($description, $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->description = $description;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the amount of hours of the assignment
+ *
+ * @return int The amount of hours
+ */
+ public function getHours() {
+ return $this->hours;
+ }
+
+ /**
+ * Set the amount of hours of the assignment
+ *
+ * @param int $hours The new amount hours for the assignment
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setHours($hours) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."assignment` SET `hours`=? WHERE `id`=?");
+ $stmt->execute(array($hours, $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->hours = $hours;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the price per hour of the assignment
+ *
+ * @return float The price per hour
+ */
+ public function getPricePerHour() {
+ return $this->price_per_hour;
+ }
+
+ /**
+ * Set the price per hour of the assignment
+ *
+ * @param float $price_per_hour The new price per hour for the assignment
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setPricePerHour($price_per_hour) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."assignment` SET `price_per_hour`=? WHERE `id`=?");
+ $stmt->execute(array($price_per_hour, $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->price_per_hour = $price_per_hour;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the VAT percentage of the assignment
+ *
+ * @return float The VAT percentage
+ */
+ public function getVAT() {
+ return $this->vat;
+ }
+
+ /**
+ * Set the VAT percentage of the assignment
+ *
+ * @param float $vat The new VAT percentage for the assignment
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setVAT($vat) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."assignment` SET `VAT_percentage`=? WHERE `id`=?");
+ $stmt->execute(array($vat, $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->vat = $vat;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ // Other functions
+ //------------------------------------------------------------------------------
+
+ /**
+ * Calculate useful numbers about the assignment
+ *
+ * Subtotal: price_per_hour \* hours
+ *
+ * VAT: subtotal \* VAT_percentage
+ *
+ * Total: subtotal + VAT
+ *
+ * @param int $what Any of assignment::SUBTOTAL, assignment::VAT, assignment::TOTAL
+ * @param int $round How many decimals to round on
+ * @param bool $format Whether to format the number nicely (for output) or not (for calculations)
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return float|bool The calculated value rounded on $round decimals, or false when the input is incorrect
+ */
+ public function calculate($what = self::TOTAL, $round = 2, $format = true) {
+ $return = 0;
+ switch ($what) {
+ case self::SUBTOTAL:
+ $return = $this->getPricePerHour() * $this->getHours();
+ break;
+ case self::VAT:
+ $return = $this->calculate(self::SUBTOTAL, $round + 1, false) * $this->getVAT() / 100;
+ break;
+ case self::TOTAL:
+ $return = $this->calculate(self::SUBTOTAL, $round + 1, false) + $this->calculate(self::VAT, $round + 1, false);
+ break;
+ default:
+ return false;
+ }
+ if ($format) {
+ return number_format($return, $round);
+ } else {
+ return round($return, $round);
+ }
+ }
+
+ /**
+ * Remove this assignment from the database
+ *
+ * If this doesn't succeed (i.e. false is returned), that means the assignment was removed manually or by another instance of this class
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on success, false on failure
+ */
+ public function delete() {
+ $stmt = $this->pdo->prepare("DELETE FROM `".constants::db_prefix."assignment` WHERE `id`=?");
+ $stmt->execute(array($this->id));
+ if ($stmt->rowCount() != 1) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+}
diff --git a/docs/files/client.class.html b/docs/files/client.class.html
new file mode 100644
index 0000000..9a1ca8c
--- /dev/null
+++ b/docs/files/client.class.html
@@ -0,0 +1,280 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
+ <meta charset="utf-8"/>
+ <title>API Documentation</title>
+ <meta name="author" content=""/>
+ <meta name="description" content=""/>
+
+ <link href="../css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
+ <link href="../css/font-awesome.min.css" rel="stylesheet">
+ <link href="../css/prism.css" rel="stylesheet" media="all"/>
+ <link href="../css/template.css" rel="stylesheet" media="all"/>
+
+ <!--[if lt IE 9]>
+ <script src="../js/html5.js"></script>
+ <![endif]-->
+ <script src="../js/jquery-1.11.0.min.js"></script>
+ <script src="../js/ui/1.10.4/jquery-ui.min.js"></script>
+ <script src="../js/bootstrap.min.js"></script>
+ <script src="../js/jquery.smooth-scroll.js"></script>
+ <script src="../js/prism.min.js"></script>
+ <!-- TODO: Add http://jscrollpane.kelvinluck.com/ to style the scrollbars for browsers not using webkit-->
+ <script type="text/javascript">
+ function loadExternalCodeSnippets() {
+ Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function (pre) {
+ var src = pre.getAttribute('data-src');
+ var extension = (src.match(/\.(\w+)$/) || [, ''])[1];
+ var language = 'php';
+
+ var code = document.createElement('code');
+ code.className = 'language-' + language;
+
+ pre.textContent = '';
+
+ code.textContent = 'Loading…';
+
+ pre.appendChild(code);
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.open('GET', src, true);
+
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+
+ if (xhr.status < 400 && xhr.responseText) {
+ code.textContent = xhr.responseText;
+
+ Prism.highlightElement(code);
+ }
+ else if (xhr.status >= 400) {
+ code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;
+ }
+ else {
+ code.textContent = '✖ Error: File does not exist or is empty';
+ }
+ }
+ };
+
+ xhr.send(null);
+ });
+ }
+
+ $(document).ready(function(){
+ loadExternalCodeSnippets();
+ });
+ $('#source-view').on('shown', function () {
+ loadExternalCodeSnippets();
+ })
+ </script>
+
+ <link rel="shortcut icon" href="../images/favicon.ico"/>
+ <link rel="apple-touch-icon" href="../images/apple-touch-icon.png"/>
+ <link rel="apple-touch-icon" sizes="72x72" href="../images/apple-touch-icon-72x72.png"/>
+ <link rel="apple-touch-icon" sizes="114x114" href="../images/apple-touch-icon-114x114.png"/>
+</head>
+<body>
+
+<div class="navbar navbar-fixed-top">
+ <div class="navbar-inner">
+ <div class="container">
+ <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+ <i class="icon-ellipsis-vertical"></i>
+ </a>
+ <a class="brand" href="../index.html">API Documentation</a>
+
+ <div class="nav-collapse">
+ <ul class="nav pull-right">
+ <li class="dropdown" id="charts-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Charts <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../graphs/class.html">
+ <i class="icon-list-alt"></i>&#160;Class hierarchy diagram
+ </a>
+ </li>
+ </ul>
+ </li>
+ <li class="dropdown" id="reports-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Reports <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../reports/errors.html">
+ <i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">50</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/markers.html">
+ <i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">1</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/deprecated.html">
+ <i class="icon-list-alt"></i>&#160;Deprecated <span class="label label-info pull-right">0</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <!--<div class="go_to_top">-->
+ <!--<a href="#___" style="color: inherit">Back to top&#160;&#160;<i class="icon-upload icon-white"></i></a>-->
+ <!--</div>-->
+</div>
+
+<div id="___" class="container-fluid">
+ <section class="row-fluid">
+ <div class="span2 sidebar">
+ <div class="accordion" style="margin-bottom: 0">
+ <div class="accordion-group">
+ <div class="accordion-heading">
+ <a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-970143172"></a>
+ <a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
+ </div>
+ <div id="namespace-970143172" class="accordion-body collapse in">
+ <div class="accordion-inner">
+
+
+ <ul>
+ <li class="class"><a href="../classes/assignment.html">assignment</a></li>
+ <li class="class"><a href="../classes/BusinessAdmin.html">BusinessAdmin</a></li>
+ <li class="class"><a href="../classes/client.html">client</a></li>
+ <li class="class"><a href="../classes/constants.html">constants</a></li>
+ <li class="class"><a href="../classes/contact.html">contact</a></li>
+ <li class="class"><a href="../classes/correspondence.html">correspondence</a></li>
+ <li class="class"><a href="../classes/file.html">file</a></li>
+ <li class="class"><a href="../classes/offer.html">offer</a></li>
+ <li class="class"><a href="../classes/response.html">response</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ </div>
+ </section>
+ <section class="row-fluid">
+ <div class="span10 offset2">
+ <div class="row-fluid">
+ <div class="span8 content file">
+ <nav>
+ </nav>
+
+ <a href="#source-view" role="button" class="pull-right btn" data-toggle="modal"><i class="icon-code"></i></a>
+ <h1><small></small>client.class.php</h1>
+ <p><em>Provides the client class, an interface to the client table in the database</em></p>
+
+
+
+
+ <h2>Classes</h2>
+ <table class="table table-hover">
+ <tr>
+ <td><a href="../classes/client.html">client</a></td>
+ <td><em>An interface to the client table in the database</em></td>
+ </tr>
+ </table>
+ </div>
+
+ <aside class="span4 detailsbar">
+ <dl>
+ <dt>Package</dt>
+ <dd><div class="namespace-wrapper">\Default</div></dd>
+
+
+ </dl>
+ <h2>Tags</h2>
+ <table class="table table-condensed">
+ <tr>
+ <th>
+ author
+ </th>
+ <td>
+ <p>Camil Staps</p>
+<p>BusinessAdmin: administrative software for small companies
+Copyright (C) 2015 Camil Staps (ViviSoft)</p>
+<p>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.</p>
+<p>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.</p>
+<p>You should have received a copy of the GNU General Public License
+along with this program. If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.</p>
+ </td>
+ </tr>
+ </table>
+
+ </aside>
+ </div>
+
+
+
+ </div>
+ </section>
+
+ <div id="source-view" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="source-view-label" aria-hidden="true">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+ <h3 id="source-view-label"></h3>
+ </div>
+ <div class="modal-body">
+ <pre data-src="../files/client.class.php.txt" class="language-php line-numbers"></pre>
+ </div>
+ </div>
+
+ <footer class="row-fluid">
+ <section class="span10 offset2">
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <section class="row-fluid footer-sections">
+ <section class="span4">
+ <h1><i class="icon-code"></i></h1>
+ <div>
+ <ul>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-bar-chart"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../graphs/class.html">Class Hierarchy Diagram</a></li>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-pushpin"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../reports/errors.html">Errors</a></li>
+ <li><a href="../reports/markers.html">Markers</a></li>
+ </ul>
+ </div>
+ </section>
+ </section>
+ </section>
+ </section>
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <hr />
+ Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
+ on February 7th, 2015 at 21:04.
+ </section>
+ </section>
+ </section>
+ </footer>
+</div>
+
+</body>
+</html>
diff --git a/docs/files/client.class.php.txt b/docs/files/client.class.php.txt
new file mode 100644
index 0000000..bde99ff
--- /dev/null
+++ b/docs/files/client.class.php.txt
@@ -0,0 +1,195 @@
+<?php
+/**
+ * Provides the client class, an interface to the client table in the database
+ *
+ * @author Camil Staps
+ *
+ * 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/>.
+ */
+
+/**
+ * An interface to the client table in the database
+ */
+class client {
+ /**
+ * @var pdo $pdo The PDO class for database communication
+ * @var int $id The id of the client
+ * @var string $name The name of the client
+ */
+ protected $pdo, $id, $name;
+
+ /**
+ * Create a new instance
+ *
+ * @param PDO $pdo The PDO class, to access the database
+ * @param int $id The id of the client to fetch
+ *
+ * @throws PDOException If something went wrong with the database
+ * @throws Exception If the client could not be found
+ */
+ public function __construct($pdo, $id) {
+ $this->pdo = $pdo;
+
+ $stmt = $this->pdo->prepare("SELECT * FROM `".constants::db_prefix."client` WHERE `id`=?");
+ $stmt->execute(array($id));
+ if ($stmt->rowCount() == 0) {
+ throw new Exception("The client with id '$id' could not be found.");
+ }
+ $client = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ $this->id = $client['id'];
+ $this->name = $client['name'];
+ }
+
+ //------------------------------------------------------------------------------
+ // Getters and setters
+ //------------------------------------------------------------------------------
+
+ /**
+ * Get the ID of the client
+ *
+ * @return int The ID
+ */
+ public function getId() {
+ return $this->id;
+ }
+
+ /**
+ * Get the name of the client
+ *
+ * @return string The name
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * Set the name of the client
+ *
+ * @param string $name The new name for the client
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setName($name) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."client` SET `name`=? WHERE `id`=?");
+ $stmt->execute(array($name, $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->name = $name;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get all contact ids for this client
+ *
+ * @see client::getContacts() This funtion returns instances of the contact class instead of just the ids
+ *
+ * @throws PDOException Is something went wrong with the database
+ *
+ * @return int[] The ids
+ */
+ public function getContactIds() {
+ $ids = array();
+ $contacts = $this->pdo->query("SELECT `id` FROM `".constants::db_prefix."contact` WHERE `clientId`={$this->id}")->fetchAll(PDO::FETCH_ASSOC);
+ foreach ($contacts as $contact) {
+ $ids[] = $contact['id'];
+ }
+ return $ids;
+ }
+
+ /**
+ * Get all contacts for this client
+ *
+ * @see client::getContactIds() This function returns just the ids of the contacts, and not instances of the contact class
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return contact[] An array indexed by id of instances of the contact class
+ */
+ public function getContacts() {
+ $ids = $this->getContactIds();
+ $contacts = array();
+ foreach ($ids as $id) {
+ $contacts[$id] = new contact($this->pdo, $id);
+ }
+ return $contacts;
+ }
+
+ //------------------------------------------------------------------------------
+ // Other functions
+ //------------------------------------------------------------------------------
+
+ /**
+ * Remove this client from the database
+ *
+ * If this doesn't succeed (i.e. false is returned), that means the client was removed manually or by another instance of this class
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on success, false on failure
+ */
+ public function delete() {
+ $stmt = $this->pdo->prepare("DELETE FROM `".constants::db_prefix."client` WHERE `id`=?");
+ $stmt->execute(array($this->id));
+ if ($stmt->rowCount() != 1) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Make a new contact for this client
+ *
+ * @param string $name The name for this contact
+ * @param string $email The email for this contact
+ * @param string $address The first address line of this contact (normally street and house number)
+ * @param string $address_2 The second address line of this contact
+ * @param string $postal_code The postal code for this contact
+ * @param string $city The city for this contact
+ * @param string $state The state for this contact
+ * @param string $country The country for this contact
+ *
+ * @throws PDOException If something went wrong with the database
+ * @throws Exception If there was a problem with the input
+ *
+ * @return contact A new instance of the contact class containing the new contact
+ */
+ public function createContact($name, $email, $address, $address_2, $postal_code, $city, $country) {
+ $stmt = $this->pdo->prepare("INSERT INTO `".constants::db_prefix."contact` (`clientId`,`name`,`email`,`address`,`address_2`,`postal_code`,`city`,`country`) VALUES (?,?,?,?,?,?,?,?)");
+ $stmt->execute(array(
+ $this->id,
+ $name,
+ $email,
+ $address,
+ $address_2,
+ $postal_code,
+ $city,
+ $country
+ ));
+ if ($stmt->rowCount() == 1) {
+ return new contact($this->pdo, $this->pdo->lastInsertId());
+ } else {
+ $error = $stmt->errorInfo();
+ throw new Exception($error[2]);
+ }
+ }
+}
diff --git a/docs/files/constants.class.html b/docs/files/constants.class.html
new file mode 100644
index 0000000..d0a03fd
--- /dev/null
+++ b/docs/files/constants.class.html
@@ -0,0 +1,280 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
+ <meta charset="utf-8"/>
+ <title>API Documentation</title>
+ <meta name="author" content=""/>
+ <meta name="description" content=""/>
+
+ <link href="../css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
+ <link href="../css/font-awesome.min.css" rel="stylesheet">
+ <link href="../css/prism.css" rel="stylesheet" media="all"/>
+ <link href="../css/template.css" rel="stylesheet" media="all"/>
+
+ <!--[if lt IE 9]>
+ <script src="../js/html5.js"></script>
+ <![endif]-->
+ <script src="../js/jquery-1.11.0.min.js"></script>
+ <script src="../js/ui/1.10.4/jquery-ui.min.js"></script>
+ <script src="../js/bootstrap.min.js"></script>
+ <script src="../js/jquery.smooth-scroll.js"></script>
+ <script src="../js/prism.min.js"></script>
+ <!-- TODO: Add http://jscrollpane.kelvinluck.com/ to style the scrollbars for browsers not using webkit-->
+ <script type="text/javascript">
+ function loadExternalCodeSnippets() {
+ Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function (pre) {
+ var src = pre.getAttribute('data-src');
+ var extension = (src.match(/\.(\w+)$/) || [, ''])[1];
+ var language = 'php';
+
+ var code = document.createElement('code');
+ code.className = 'language-' + language;
+
+ pre.textContent = '';
+
+ code.textContent = 'Loading…';
+
+ pre.appendChild(code);
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.open('GET', src, true);
+
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+
+ if (xhr.status < 400 && xhr.responseText) {
+ code.textContent = xhr.responseText;
+
+ Prism.highlightElement(code);
+ }
+ else if (xhr.status >= 400) {
+ code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;
+ }
+ else {
+ code.textContent = '✖ Error: File does not exist or is empty';
+ }
+ }
+ };
+
+ xhr.send(null);
+ });
+ }
+
+ $(document).ready(function(){
+ loadExternalCodeSnippets();
+ });
+ $('#source-view').on('shown', function () {
+ loadExternalCodeSnippets();
+ })
+ </script>
+
+ <link rel="shortcut icon" href="../images/favicon.ico"/>
+ <link rel="apple-touch-icon" href="../images/apple-touch-icon.png"/>
+ <link rel="apple-touch-icon" sizes="72x72" href="../images/apple-touch-icon-72x72.png"/>
+ <link rel="apple-touch-icon" sizes="114x114" href="../images/apple-touch-icon-114x114.png"/>
+</head>
+<body>
+
+<div class="navbar navbar-fixed-top">
+ <div class="navbar-inner">
+ <div class="container">
+ <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+ <i class="icon-ellipsis-vertical"></i>
+ </a>
+ <a class="brand" href="../index.html">API Documentation</a>
+
+ <div class="nav-collapse">
+ <ul class="nav pull-right">
+ <li class="dropdown" id="charts-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Charts <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../graphs/class.html">
+ <i class="icon-list-alt"></i>&#160;Class hierarchy diagram
+ </a>
+ </li>
+ </ul>
+ </li>
+ <li class="dropdown" id="reports-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Reports <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../reports/errors.html">
+ <i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">50</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/markers.html">
+ <i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">1</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/deprecated.html">
+ <i class="icon-list-alt"></i>&#160;Deprecated <span class="label label-info pull-right">0</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <!--<div class="go_to_top">-->
+ <!--<a href="#___" style="color: inherit">Back to top&#160;&#160;<i class="icon-upload icon-white"></i></a>-->
+ <!--</div>-->
+</div>
+
+<div id="___" class="container-fluid">
+ <section class="row-fluid">
+ <div class="span2 sidebar">
+ <div class="accordion" style="margin-bottom: 0">
+ <div class="accordion-group">
+ <div class="accordion-heading">
+ <a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-32393827"></a>
+ <a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
+ </div>
+ <div id="namespace-32393827" class="accordion-body collapse in">
+ <div class="accordion-inner">
+
+
+ <ul>
+ <li class="class"><a href="../classes/assignment.html">assignment</a></li>
+ <li class="class"><a href="../classes/BusinessAdmin.html">BusinessAdmin</a></li>
+ <li class="class"><a href="../classes/client.html">client</a></li>
+ <li class="class"><a href="../classes/constants.html">constants</a></li>
+ <li class="class"><a href="../classes/contact.html">contact</a></li>
+ <li class="class"><a href="../classes/correspondence.html">correspondence</a></li>
+ <li class="class"><a href="../classes/file.html">file</a></li>
+ <li class="class"><a href="../classes/offer.html">offer</a></li>
+ <li class="class"><a href="../classes/response.html">response</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ </div>
+ </section>
+ <section class="row-fluid">
+ <div class="span10 offset2">
+ <div class="row-fluid">
+ <div class="span8 content file">
+ <nav>
+ </nav>
+
+ <a href="#source-view" role="button" class="pull-right btn" data-toggle="modal"><i class="icon-code"></i></a>
+ <h1><small></small>constants.class.php</h1>
+ <p><em>Some constants that can be used on other locations</em></p>
+
+
+
+
+ <h2>Classes</h2>
+ <table class="table table-hover">
+ <tr>
+ <td><a href="../classes/constants.html">constants</a></td>
+ <td><em>A class for some constants</em></td>
+ </tr>
+ </table>
+ </div>
+
+ <aside class="span4 detailsbar">
+ <dl>
+ <dt>Package</dt>
+ <dd><div class="namespace-wrapper">\Default</div></dd>
+
+
+ </dl>
+ <h2>Tags</h2>
+ <table class="table table-condensed">
+ <tr>
+ <th>
+ author
+ </th>
+ <td>
+ <p>Camil Staps</p>
+<p>BusinessAdmin: administrative software for small companies
+Copyright (C) 2015 Camil Staps (ViviSoft)</p>
+<p>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.</p>
+<p>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.</p>
+<p>You should have received a copy of the GNU General Public License
+along with this program. If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.</p>
+ </td>
+ </tr>
+ </table>
+
+ </aside>
+ </div>
+
+
+
+ </div>
+ </section>
+
+ <div id="source-view" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="source-view-label" aria-hidden="true">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+ <h3 id="source-view-label"></h3>
+ </div>
+ <div class="modal-body">
+ <pre data-src="../files/constants.class.php.txt" class="language-php line-numbers"></pre>
+ </div>
+ </div>
+
+ <footer class="row-fluid">
+ <section class="span10 offset2">
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <section class="row-fluid footer-sections">
+ <section class="span4">
+ <h1><i class="icon-code"></i></h1>
+ <div>
+ <ul>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-bar-chart"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../graphs/class.html">Class Hierarchy Diagram</a></li>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-pushpin"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../reports/errors.html">Errors</a></li>
+ <li><a href="../reports/markers.html">Markers</a></li>
+ </ul>
+ </div>
+ </section>
+ </section>
+ </section>
+ </section>
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <hr />
+ Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
+ on February 7th, 2015 at 21:04.
+ </section>
+ </section>
+ </section>
+ </footer>
+</div>
+
+</body>
+</html>
diff --git a/docs/files/constants.class.php.txt b/docs/files/constants.class.php.txt
new file mode 100644
index 0000000..83ae246
--- /dev/null
+++ b/docs/files/constants.class.php.txt
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Some constants that can be used on other locations
+ *
+ * @author Camil Staps
+ *
+ * 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/>.
+ */
+
+/**
+ * A class for some constants
+ */
+class constants {
+ /** @const db_prefix A prefix to add to the tables in the database (leave empty for none) */
+ const db_prefix = '';
+
+ /** @const files_folder The folder to store all files (appendices, invoices, etc.) in; with a trailing slash */
+ const files_folder = '/var/www/localhost/BusinessAdmin/files/';
+ /** @const files_folder_external The external URI to this folder; with a trailing slash */
+ const files_folder_external = 'http://localhost/BusinessAdmin/files/';
+ /** @const files_folder_trash The folder inside files_folder to use a trash, without any trailing slashes */
+ const files_folder_trash = 'trash';
+
+ /** @const url_external The external URI to this folder; with a trailing slash */
+ const url_external = 'http://localhost/BusinessAdmin/';
+ /** @const url_internal The URI without the domain name; with a slash at the beginning but not at the end */
+ const url_internal = '/BusinessAdmin';
+
+ /** @const my_name Name of this control panel */
+ const my_name = 'BusinessAdmin';
+
+ /**
+ * @const invoice_name Your name or the name of your business
+ * @const invoice_address_1 First address line
+ * @const invoice_address_2 Second address line
+ * @const invoice_address_3 Third address line
+ * @const invoice_tax_nr Your tax number
+ * @const invoice_iban Your IBAN number
+ * @const invoice_bic The BIC code of your bank
+ * @const invoice_tel_nr Your telephone number
+ * @const invoice_email Your email address
+ * @const invoice_valuta The valuta symbol (will be placed in front of amounts). You can use a symbol like $ or a code like USD
+ */
+ const invoice_name = 'BusinessAdmin';
+ const invoice_address_1 = 'My Street 1';
+ const invoice_address_2 = '12345 My City';
+ const invoice_address_3 = 'My Country';
+ const invoice_tax_nr = 'XX123456789A00';
+ const invoice_iban = 'XX00 ABCD 1234 5678 90';
+ const invoice_bic = 'XXXX XXXX';
+ const invoice_tel_nr = '+31 6 1234 5678';
+ const invoice_email = 'my-email@domain.tld';
+ const invoice_valuta = '$'; // chr(128) for euro
+
+ /** @const version Version of BusinessAdmin. Don't change this yourself! */
+ const version = '0.1';
+}
diff --git a/docs/files/contact.class.html b/docs/files/contact.class.html
new file mode 100644
index 0000000..d4ef593
--- /dev/null
+++ b/docs/files/contact.class.html
@@ -0,0 +1,280 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
+ <meta charset="utf-8"/>
+ <title>API Documentation</title>
+ <meta name="author" content=""/>
+ <meta name="description" content=""/>
+
+ <link href="../css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
+ <link href="../css/font-awesome.min.css" rel="stylesheet">
+ <link href="../css/prism.css" rel="stylesheet" media="all"/>
+ <link href="../css/template.css" rel="stylesheet" media="all"/>
+
+ <!--[if lt IE 9]>
+ <script src="../js/html5.js"></script>
+ <![endif]-->
+ <script src="../js/jquery-1.11.0.min.js"></script>
+ <script src="../js/ui/1.10.4/jquery-ui.min.js"></script>
+ <script src="../js/bootstrap.min.js"></script>
+ <script src="../js/jquery.smooth-scroll.js"></script>
+ <script src="../js/prism.min.js"></script>
+ <!-- TODO: Add http://jscrollpane.kelvinluck.com/ to style the scrollbars for browsers not using webkit-->
+ <script type="text/javascript">
+ function loadExternalCodeSnippets() {
+ Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function (pre) {
+ var src = pre.getAttribute('data-src');
+ var extension = (src.match(/\.(\w+)$/) || [, ''])[1];
+ var language = 'php';
+
+ var code = document.createElement('code');
+ code.className = 'language-' + language;
+
+ pre.textContent = '';
+
+ code.textContent = 'Loading…';
+
+ pre.appendChild(code);
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.open('GET', src, true);
+
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+
+ if (xhr.status < 400 && xhr.responseText) {
+ code.textContent = xhr.responseText;
+
+ Prism.highlightElement(code);
+ }
+ else if (xhr.status >= 400) {
+ code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;
+ }
+ else {
+ code.textContent = '✖ Error: File does not exist or is empty';
+ }
+ }
+ };
+
+ xhr.send(null);
+ });
+ }
+
+ $(document).ready(function(){
+ loadExternalCodeSnippets();
+ });
+ $('#source-view').on('shown', function () {
+ loadExternalCodeSnippets();
+ })
+ </script>
+
+ <link rel="shortcut icon" href="../images/favicon.ico"/>
+ <link rel="apple-touch-icon" href="../images/apple-touch-icon.png"/>
+ <link rel="apple-touch-icon" sizes="72x72" href="../images/apple-touch-icon-72x72.png"/>
+ <link rel="apple-touch-icon" sizes="114x114" href="../images/apple-touch-icon-114x114.png"/>
+</head>
+<body>
+
+<div class="navbar navbar-fixed-top">
+ <div class="navbar-inner">
+ <div class="container">
+ <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+ <i class="icon-ellipsis-vertical"></i>
+ </a>
+ <a class="brand" href="../index.html">API Documentation</a>
+
+ <div class="nav-collapse">
+ <ul class="nav pull-right">
+ <li class="dropdown" id="charts-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Charts <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../graphs/class.html">
+ <i class="icon-list-alt"></i>&#160;Class hierarchy diagram
+ </a>
+ </li>
+ </ul>
+ </li>
+ <li class="dropdown" id="reports-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Reports <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../reports/errors.html">
+ <i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">50</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/markers.html">
+ <i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">1</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/deprecated.html">
+ <i class="icon-list-alt"></i>&#160;Deprecated <span class="label label-info pull-right">0</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <!--<div class="go_to_top">-->
+ <!--<a href="#___" style="color: inherit">Back to top&#160;&#160;<i class="icon-upload icon-white"></i></a>-->
+ <!--</div>-->
+</div>
+
+<div id="___" class="container-fluid">
+ <section class="row-fluid">
+ <div class="span2 sidebar">
+ <div class="accordion" style="margin-bottom: 0">
+ <div class="accordion-group">
+ <div class="accordion-heading">
+ <a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-1186592253"></a>
+ <a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
+ </div>
+ <div id="namespace-1186592253" class="accordion-body collapse in">
+ <div class="accordion-inner">
+
+
+ <ul>
+ <li class="class"><a href="../classes/assignment.html">assignment</a></li>
+ <li class="class"><a href="../classes/BusinessAdmin.html">BusinessAdmin</a></li>
+ <li class="class"><a href="../classes/client.html">client</a></li>
+ <li class="class"><a href="../classes/constants.html">constants</a></li>
+ <li class="class"><a href="../classes/contact.html">contact</a></li>
+ <li class="class"><a href="../classes/correspondence.html">correspondence</a></li>
+ <li class="class"><a href="../classes/file.html">file</a></li>
+ <li class="class"><a href="../classes/offer.html">offer</a></li>
+ <li class="class"><a href="../classes/response.html">response</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ </div>
+ </section>
+ <section class="row-fluid">
+ <div class="span10 offset2">
+ <div class="row-fluid">
+ <div class="span8 content file">
+ <nav>
+ </nav>
+
+ <a href="#source-view" role="button" class="pull-right btn" data-toggle="modal"><i class="icon-code"></i></a>
+ <h1><small></small>contact.class.php</h1>
+ <p><em>Provides the contact class, an interface to the contact table in the database</em></p>
+
+
+
+
+ <h2>Classes</h2>
+ <table class="table table-hover">
+ <tr>
+ <td><a href="../classes/contact.html">contact</a></td>
+ <td><em>An interface to the contact table in the database</em></td>
+ </tr>
+ </table>
+ </div>
+
+ <aside class="span4 detailsbar">
+ <dl>
+ <dt>Package</dt>
+ <dd><div class="namespace-wrapper">\Default</div></dd>
+
+
+ </dl>
+ <h2>Tags</h2>
+ <table class="table table-condensed">
+ <tr>
+ <th>
+ author
+ </th>
+ <td>
+ <p>Camil Staps</p>
+<p>BusinessAdmin: administrative software for small companies
+Copyright (C) 2015 Camil Staps (ViviSoft)</p>
+<p>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.</p>
+<p>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.</p>
+<p>You should have received a copy of the GNU General Public License
+along with this program. If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.</p>
+ </td>
+ </tr>
+ </table>
+
+ </aside>
+ </div>
+
+
+
+ </div>
+ </section>
+
+ <div id="source-view" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="source-view-label" aria-hidden="true">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+ <h3 id="source-view-label"></h3>
+ </div>
+ <div class="modal-body">
+ <pre data-src="../files/contact.class.php.txt" class="language-php line-numbers"></pre>
+ </div>
+ </div>
+
+ <footer class="row-fluid">
+ <section class="span10 offset2">
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <section class="row-fluid footer-sections">
+ <section class="span4">
+ <h1><i class="icon-code"></i></h1>
+ <div>
+ <ul>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-bar-chart"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../graphs/class.html">Class Hierarchy Diagram</a></li>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-pushpin"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../reports/errors.html">Errors</a></li>
+ <li><a href="../reports/markers.html">Markers</a></li>
+ </ul>
+ </div>
+ </section>
+ </section>
+ </section>
+ </section>
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <hr />
+ Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
+ on February 7th, 2015 at 21:04.
+ </section>
+ </section>
+ </section>
+ </footer>
+</div>
+
+</body>
+</html>
diff --git a/docs/files/contact.class.php.txt b/docs/files/contact.class.php.txt
new file mode 100644
index 0000000..90f965b
--- /dev/null
+++ b/docs/files/contact.class.php.txt
@@ -0,0 +1,378 @@
+<?php
+/**
+ * Provides the contact class, an interface to the contact table in the database
+ *
+ * @author Camil Staps
+ *
+ * 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/>.
+ */
+
+/**
+ * An interface to the contact table in the database
+ */
+class contact {
+ /**
+ * @var PDO $pdo The PDO class for database communication
+ * @var int $id The id of the contact
+ * @var int $clientId The id of the client the contact is linked to
+ * @var string $name The name of the contact
+ * @var string $email The email address of the contact
+ * @var string $address The first address line (normally street and house number) of the contact
+ * @var string $address_2 The second address line (can be null)
+ * @var string $postal_code The postal code of the contact
+ * @var string $city The city of the contact
+ * @var string $country The country of the contact
+ * @var string $language The language of the contact
+ */
+ protected $pdo, $id, $clientId, $name, $email, $address, $postal_code, $city, $country, $language;
+
+ /**
+ * Create a new instance
+ *
+ * @param PDO $pdo The PDO class, to access the database
+ * @param int $id The id of the contact to fetch
+ *
+ * @throws PDOException If something went wrong with the database
+ * @throws Exception If the contact could not be found
+ */
+ public function __construct($pdo, $id) {
+ $this->pdo = $pdo;
+
+ $stmt = $this->pdo->prepare("SELECT * FROM `".constants::db_prefix."contact` WHERE `id`=?");
+ $stmt->execute(array($id));
+ if ($stmt->rowCount() == 0) {
+ throw new Exception("The contact with id '$id' could not be found.");
+ }
+ $contact = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ $this->id = $contact['id'];
+ $this->clientId = $contact['clientId'];
+ $this->name = $contact['name'];
+ $this->email = $contact['email'];
+ $this->address = $contact['address'];
+ $this->address_2 = $contact['address_2'];
+ $this->postal_code = $contact['postal_code'];
+ $this->city = $contact['city'];
+ $this->country = $contact['country'];
+ $this->language = $contact['language'];
+ }
+
+ //------------------------------------------------------------------------------
+ // Getters and setters
+ //------------------------------------------------------------------------------
+
+ /**
+ * Get the ID of the contact
+ *
+ * @return int The ID
+ */
+ public function getId() {
+ return $this->id;
+ }
+
+ /**
+ * Get the ID of the client that this contact is linked to
+ *
+ * @return int The ID
+ */
+ public function getClientId() {
+ return $this->clientId;
+ }
+
+ /**
+ * Get the client that this contact is linked to
+ *
+ * @return client The client
+ */
+ public function getClient() {
+ return new client($this->pdo, $this->clientId);
+ }
+
+ /**
+ * Get the name of the contact
+ *
+ * @return string The name
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * Set the name of the contact
+ *
+ * @param string $name The new name for the contact
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setName($name) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."contact` SET `name`=? WHERE `id`=?");
+ $stmt->execute(array($name, $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->name = $name;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the email of the contact
+ *
+ * @return string The email
+ */
+ public function getEmail() {
+ return $this->email;
+ }
+
+ /**
+ * Set the email of the contact
+ *
+ * @param string $email The new email for the contact
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setEmail($email) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."contact` SET `email`=? WHERE `id`=?");
+ $stmt->execute(array($email, $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->email = $email;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the first address line of the contact
+ *
+ * @return string The address
+ */
+ public function getAddress() {
+ return $this->address;
+ }
+
+ /**
+ * Set the first address line of the contact
+ *
+ * @param string $address The new address for the contact
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setAddress($address) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."contact` SET `address`=? WHERE `id`=?");
+ $stmt->execute(array($address, $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->address = $address;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the second address line of the contact
+ *
+ * @return string The address
+ */
+ public function getAddress_2() {
+ return $this->address_2;
+ }
+
+ /**
+ * Set the second address line of the contact
+ *
+ * @param string $address_2 The new address for the contact
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setAddress_2($address_2) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."contact` SET `address_2`=? WHERE `id`=?");
+ $stmt->execute(array($address_2, $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->address_2 = $address_2;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the postal_code of the contact
+ *
+ * @return string The postal_code
+ */
+ public function getPostalCode() {
+ return $this->postal_code;
+ }
+
+ /**
+ * Set the postal code of the contact
+ *
+ * @param $postal_code string The new postal code for the contact
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setPostalCode($postal_code) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."contact` SET `postal_code`=? WHERE `id`=?");
+ $stmt->execute(array($postal_code, $this->id));
+ if ($stmt->rowCount() == 1) {
+ return true;
+ $this->postal_code = $postal_code;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the city of the contact
+ *
+ * @return string The city
+ */
+ public function getCity() {
+ return $this->city;
+ }
+
+ /**
+ * Set the city of the contact
+ *
+ * @param string $city The new city for the contact
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setCity($city) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."contact` SET `city`=? WHERE `id`=?");
+ $stmt->execute(array($city, $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->city = $city;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the country of the contact
+ *
+ * @return string The country
+ */
+ public function getCountry() {
+ return $this->country;
+ }
+
+ /**
+ * Set the country of the contact
+ *
+ * @param string $country The new country for the contact
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setCountry($country) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."contact` SET `country`=? WHERE `id`=?");
+ $stmt->execute(array($country, $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->country = $country;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the language of the contact
+ *
+ * @return string The language
+ */
+ public function getLanguage() {
+ return $this->language;
+ }
+
+ /**
+ * Set the language of the contact
+ *
+ * @param string $language The new language for the contact
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setLanguage($language) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."contact` SET `language`=? WHERE `id`=?");
+ $stmt->execute(array($language, $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->language = $language;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ // Other functions
+ //------------------------------------------------------------------------------
+
+ /**
+ * Remove this contact from the database
+ *
+ * If this doesn't succeed (i.e. false is returned), that means the contact was removed manually or by another instance of this class
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on success, false on failure
+ */
+ public function delete() {
+ $stmt = $this->pdo->prepare("DELETE FROM `".constants::db_prefix."contact` WHERE `id`=?");
+ $stmt->execute(array($this->id));
+ if ($stmt->rowCount() != 1) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Make a new offer for this contact
+ *
+ * @throws PDOException If something went wrong with the database
+ * @throws Exception If there was a problem with the input
+ *
+ * @return offer A new instance of the offer class containing the new offer
+ */
+ public function createOffer() {
+ $stmt = $this->pdo->prepare("INSERT INTO `".constants::db_prefix."offer` (`contactId`) VALUES (?)");
+ $stmt->execute(array($this->id));
+ if ($stmt->rowCount() == 1) {
+ return new offer($this->pdo, $this->pdo->lastInsertId());
+ } else {
+ $error = $stmt->errorInfo();
+ throw new Exception($error[2]);
+ }
+ }
+}
diff --git a/docs/files/correspondence.class.html b/docs/files/correspondence.class.html
new file mode 100644
index 0000000..f98c4fd
--- /dev/null
+++ b/docs/files/correspondence.class.html
@@ -0,0 +1,261 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
+ <meta charset="utf-8"/>
+ <title>API Documentation</title>
+ <meta name="author" content=""/>
+ <meta name="description" content=""/>
+
+ <link href="../css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
+ <link href="../css/font-awesome.min.css" rel="stylesheet">
+ <link href="../css/prism.css" rel="stylesheet" media="all"/>
+ <link href="../css/template.css" rel="stylesheet" media="all"/>
+
+ <!--[if lt IE 9]>
+ <script src="../js/html5.js"></script>
+ <![endif]-->
+ <script src="../js/jquery-1.11.0.min.js"></script>
+ <script src="../js/ui/1.10.4/jquery-ui.min.js"></script>
+ <script src="../js/bootstrap.min.js"></script>
+ <script src="../js/jquery.smooth-scroll.js"></script>
+ <script src="../js/prism.min.js"></script>
+ <!-- TODO: Add http://jscrollpane.kelvinluck.com/ to style the scrollbars for browsers not using webkit-->
+ <script type="text/javascript">
+ function loadExternalCodeSnippets() {
+ Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function (pre) {
+ var src = pre.getAttribute('data-src');
+ var extension = (src.match(/\.(\w+)$/) || [, ''])[1];
+ var language = 'php';
+
+ var code = document.createElement('code');
+ code.className = 'language-' + language;
+
+ pre.textContent = '';
+
+ code.textContent = 'Loading…';
+
+ pre.appendChild(code);
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.open('GET', src, true);
+
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+
+ if (xhr.status < 400 && xhr.responseText) {
+ code.textContent = xhr.responseText;
+
+ Prism.highlightElement(code);
+ }
+ else if (xhr.status >= 400) {
+ code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;
+ }
+ else {
+ code.textContent = '✖ Error: File does not exist or is empty';
+ }
+ }
+ };
+
+ xhr.send(null);
+ });
+ }
+
+ $(document).ready(function(){
+ loadExternalCodeSnippets();
+ });
+ $('#source-view').on('shown', function () {
+ loadExternalCodeSnippets();
+ })
+ </script>
+
+ <link rel="shortcut icon" href="../images/favicon.ico"/>
+ <link rel="apple-touch-icon" href="../images/apple-touch-icon.png"/>
+ <link rel="apple-touch-icon" sizes="72x72" href="../images/apple-touch-icon-72x72.png"/>
+ <link rel="apple-touch-icon" sizes="114x114" href="../images/apple-touch-icon-114x114.png"/>
+</head>
+<body>
+
+<div class="navbar navbar-fixed-top">
+ <div class="navbar-inner">
+ <div class="container">
+ <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+ <i class="icon-ellipsis-vertical"></i>
+ </a>
+ <a class="brand" href="../index.html">API Documentation</a>
+
+ <div class="nav-collapse">
+ <ul class="nav pull-right">
+ <li class="dropdown" id="charts-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Charts <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../graphs/class.html">
+ <i class="icon-list-alt"></i>&#160;Class hierarchy diagram
+ </a>
+ </li>
+ </ul>
+ </li>
+ <li class="dropdown" id="reports-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Reports <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../reports/errors.html">
+ <i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">50</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/markers.html">
+ <i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">1</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/deprecated.html">
+ <i class="icon-list-alt"></i>&#160;Deprecated <span class="label label-info pull-right">0</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <!--<div class="go_to_top">-->
+ <!--<a href="#___" style="color: inherit">Back to top&#160;&#160;<i class="icon-upload icon-white"></i></a>-->
+ <!--</div>-->
+</div>
+
+<div id="___" class="container-fluid">
+ <section class="row-fluid">
+ <div class="span2 sidebar">
+ <div class="accordion" style="margin-bottom: 0">
+ <div class="accordion-group">
+ <div class="accordion-heading">
+ <a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-1775654533"></a>
+ <a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
+ </div>
+ <div id="namespace-1775654533" class="accordion-body collapse in">
+ <div class="accordion-inner">
+
+
+ <ul>
+ <li class="class"><a href="../classes/assignment.html">assignment</a></li>
+ <li class="class"><a href="../classes/BusinessAdmin.html">BusinessAdmin</a></li>
+ <li class="class"><a href="../classes/client.html">client</a></li>
+ <li class="class"><a href="../classes/constants.html">constants</a></li>
+ <li class="class"><a href="../classes/contact.html">contact</a></li>
+ <li class="class"><a href="../classes/correspondence.html">correspondence</a></li>
+ <li class="class"><a href="../classes/file.html">file</a></li>
+ <li class="class"><a href="../classes/offer.html">offer</a></li>
+ <li class="class"><a href="../classes/response.html">response</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ </div>
+ </section>
+ <section class="row-fluid">
+ <div class="span10 offset2">
+ <div class="row-fluid">
+ <div class="span8 content file">
+ <nav>
+ </nav>
+
+ <a href="#source-view" role="button" class="pull-right btn" data-toggle="modal"><i class="icon-code"></i></a>
+ <h1><small></small>correspondence.class.php</h1>
+ <p><em></em></p>
+
+
+
+
+ <h2>Classes</h2>
+ <table class="table table-hover">
+ <tr>
+ <td><a href="../classes/correspondence.html">correspondence</a></td>
+ <td><em>An extension of FPDF to generate personalized correspondence PDFs</em></td>
+ </tr>
+ </table>
+ </div>
+
+ <aside class="span4 detailsbar">
+ <dl>
+ <dt>Package</dt>
+ <dd><div class="namespace-wrapper">\Default</div></dd>
+
+
+ </dl>
+ <h2>Tags</h2>
+ <table class="table table-condensed">
+ <tr><td colspan="2"><em>None found</em></td></tr>
+ </table>
+
+ </aside>
+ </div>
+
+
+
+ </div>
+ </section>
+
+ <div id="source-view" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="source-view-label" aria-hidden="true">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+ <h3 id="source-view-label"></h3>
+ </div>
+ <div class="modal-body">
+ <pre data-src="../files/correspondence.class.php.txt" class="language-php line-numbers"></pre>
+ </div>
+ </div>
+
+ <footer class="row-fluid">
+ <section class="span10 offset2">
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <section class="row-fluid footer-sections">
+ <section class="span4">
+ <h1><i class="icon-code"></i></h1>
+ <div>
+ <ul>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-bar-chart"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../graphs/class.html">Class Hierarchy Diagram</a></li>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-pushpin"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../reports/errors.html">Errors</a></li>
+ <li><a href="../reports/markers.html">Markers</a></li>
+ </ul>
+ </div>
+ </section>
+ </section>
+ </section>
+ </section>
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <hr />
+ Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
+ on February 7th, 2015 at 21:04.
+ </section>
+ </section>
+ </section>
+ </footer>
+</div>
+
+</body>
+</html>
diff --git a/docs/files/correspondence.class.php.txt b/docs/files/correspondence.class.php.txt
new file mode 100644
index 0000000..f6b66bb
--- /dev/null
+++ b/docs/files/correspondence.class.php.txt
@@ -0,0 +1,269 @@
+<?php
+/**
+ * This file provides the correspondence class
+ *
+ * @author Camil Staps
+ *
+ * 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('fpdf.php');
+
+/**
+ * An extension of FPDF to generate personalized correspondence PDFs
+ */
+class correspondence extends FPDF {
+ /**
+ * @var $contact Holds the contact this correspondence will be sent to
+ * @var $language Holds the language this correspondence should be sent in
+ */
+ var $contact, $language;
+
+ /**
+ * If you'd want, you could change these constants to encode an RGB colour for headings in your PDFs
+ */
+ const HEAD_RED = 0;
+ const HEAD_GREEN = 0;
+ const HEAD_BLUE = 0;
+
+ /**
+ * Array holding the translations
+ *
+ * @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'),
+ );
+
+ /**
+ * Translate a string
+ *
+ * @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
+ */
+ public function _($key) {
+ if (!array_key_exists($key, self::$translations))
+ return $key;
+ return self::$translations[$key][$this->language];
+ }
+
+ /**
+ * Create a new PDF
+ *
+ * @param string $orientation See the FPDF class specs
+ * @param string $unit See the FPDF class specs
+ * @param string $size See the FPDF class specs
+ */
+ function __construct($orientation='P',$unit='mm',$size='A4') {
+ $this->FPDF($orientation,$unit,$size);
+
+ $this->SetMargins(30,20,20);
+ $this->SetAuthor(constants::invoice_name);
+ $this->SetCreator('BusinessAdmin Correspondence Generator');
+ $this->SetDisplayMode('fullpage','continuous');
+ }
+
+ /**
+ * Set the language of the correspondence (used to translate stuff)
+ *
+ * @param string $lang The language, two letter code ('en', 'nl', ...)
+ */
+ function SetLangauge($lang) {
+ $supported = array('nl', 'en');
+ if (!in_array($lang, $supported)) {
+ throw new Exception("Language not supported");
+ } else {
+ $this->language = $lang;
+ }
+ }
+
+ /**
+ * Set the contact to whom this correspondence will be sent (used for the address)
+ *
+ * @param contact $contact The contact
+ */
+ function SetContact($contact) {
+ $this->contact = $contact;
+
+ $this->language = $contact->getLanguage();
+ }
+
+ /**
+ * Makes a header with your details and the address of the contact
+ */
+ function CorrespondenceHeader() {
+ if (file_exists(constants::files_folder . 'logo-correspondence.png')) {
+ $this->Image(constants::files_folder . 'logo-correspondence.png',30,20,50);
+ }
+
+ $this->SetFont('Helvetica','',7);
+ $this->Cell(110,20);
+ $this->Cell(12,1,' ','T');
+ $this->Cell(2,1);
+ $this->Cell(35,1,' ','T');
+ $this->Ln();
+
+ $this->Cell(110,3.5);
+ $this->SetFont('','B');
+ $this->Cell(12,3.5,$this->_('adres'),'',0,'R');
+ $this->Cell(2,3.5);
+ $this->SetFont('','');
+ $this->Cell(35,3.5, constants::invoice_name);
+ $this->Ln();
+
+ $this->Cell(124,3.5);
+ $this->Cell(35,3.5, constants::invoice_address_1);
+ $this->Ln();
+ $this->Cell(124,3.5);
+ $this->Cell(35,3.5, constants::invoice_address_2);
+ $this->Ln();
+ $this->Cell(124,3.5);
+ $this->Cell(35,3.5, constants::invoice_address_3);
+ $this->Ln();
+ $this->Cell(160,1.5);
+ $this->Ln();
+ $this->Cell(110,3.5);
+ $this->SetFont('','B');
+ $this->Cell(12,3.5,$this->_('btwnr'),'',0,'R');
+ $this->Cell(2,3.5);
+ $this->SetFont('','');
+ $this->Cell(35,3.5, constants::invoice_tax_nr);
+ $this->Ln();
+ $this->Cell(160,1.5);
+ $this->Ln();
+ $this->Cell(110,3.5);
+ $this->SetFont('','B');
+ $this->Cell(12,3.5, $this->_('iban'),'',0,'R');
+ $this->Cell(2,3.5);
+ $this->SetFont('','');
+ $this->Cell(35,3.5, constants::invoice_iban);
+ $this->Ln();
+ $this->Cell(160,1.5);
+ $this->Ln();
+ $this->Cell(110,3.5);
+ $this->SetFont('','B');
+ $this->Cell(12,3.5, $this->_('tel-nr'),'',0,'R');
+ $this->Cell(2,3.5);
+ $this->SetFont('','',7);
+ $this->Cell(35,3.5, constants::invoice_tel_nr);
+ $this->Ln();
+ $this->Cell(110,3.5);
+ $this->SetFont('','B');
+ $this->Cell(12,3.5, $this->_('email'),'',0,'R');
+ $this->Cell(2,3.5);
+ $this->SetFont('','');
+ $this->Cell(35,3.5, constants::invoice_email);
+ $this->Ln();
+ $this->Cell(110,1);
+ $this->Cell(12,1,' ','B');
+ $this->Cell(2,1);
+ $this->Cell(35,1,' ','B');
+ $this->Ln();
+ $this->Cell(160,15);
+ $this->Ln();
+
+ $this->SetFont('','',11);
+ $this->SetXY(30,56.5);
+ $this->Cell(90,5.5,utf8_decode($this->contact->getName()));
+ $this->Ln();
+ $this->SetXY(30,61.5);
+ $this->Cell(90,5.5,utf8_decode($this->contact->getAddress()));
+ $this->Ln();
+ $this->SetXY(30,66.5);
+ $this->Cell(90,5.5,utf8_decode($this->contact->getPostalCode().' '.$this->contact->getCity()));
+ $this->Ln();
+ $this->SetXY(30,71.5);
+ $this->Cell(90,5.5,utf8_decode($this->contact->getCountry()));
+ $this->Ln();
+ }
+
+ /**
+ * Put PDF information
+ */
+ function _putinfo()
+ {
+ $this->_out('/Producer '.$this->_textstring('BusinessAdmin Correspondence Generator'));
+ if(!empty($this->title))
+ $this->_out('/Title '.$this->_textstring($this->title));
+ if(!empty($this->subject))
+ $this->_out('/Subject '.$this->_textstring($this->subject));
+ if(!empty($this->author))
+ $this->_out('/Author '.$this->_textstring($this->author));
+ if(!empty($this->keywords))
+ $this->_out('/Keywords '.$this->_textstring($this->keywords));
+ if(!empty($this->creator))
+ $this->_out('/Creator '.$this->_textstring($this->creator));
+ $this->_out('/CreationDate '.$this->_textstring('D:'.@date('YmdHis')));
+ }
+}
diff --git a/docs/files/file.class.html b/docs/files/file.class.html
new file mode 100644
index 0000000..80fda27
--- /dev/null
+++ b/docs/files/file.class.html
@@ -0,0 +1,280 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
+ <meta charset="utf-8"/>
+ <title>API Documentation</title>
+ <meta name="author" content=""/>
+ <meta name="description" content=""/>
+
+ <link href="../css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
+ <link href="../css/font-awesome.min.css" rel="stylesheet">
+ <link href="../css/prism.css" rel="stylesheet" media="all"/>
+ <link href="../css/template.css" rel="stylesheet" media="all"/>
+
+ <!--[if lt IE 9]>
+ <script src="../js/html5.js"></script>
+ <![endif]-->
+ <script src="../js/jquery-1.11.0.min.js"></script>
+ <script src="../js/ui/1.10.4/jquery-ui.min.js"></script>
+ <script src="../js/bootstrap.min.js"></script>
+ <script src="../js/jquery.smooth-scroll.js"></script>
+ <script src="../js/prism.min.js"></script>
+ <!-- TODO: Add http://jscrollpane.kelvinluck.com/ to style the scrollbars for browsers not using webkit-->
+ <script type="text/javascript">
+ function loadExternalCodeSnippets() {
+ Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function (pre) {
+ var src = pre.getAttribute('data-src');
+ var extension = (src.match(/\.(\w+)$/) || [, ''])[1];
+ var language = 'php';
+
+ var code = document.createElement('code');
+ code.className = 'language-' + language;
+
+ pre.textContent = '';
+
+ code.textContent = 'Loading…';
+
+ pre.appendChild(code);
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.open('GET', src, true);
+
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+
+ if (xhr.status < 400 && xhr.responseText) {
+ code.textContent = xhr.responseText;
+
+ Prism.highlightElement(code);
+ }
+ else if (xhr.status >= 400) {
+ code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;
+ }
+ else {
+ code.textContent = '✖ Error: File does not exist or is empty';
+ }
+ }
+ };
+
+ xhr.send(null);
+ });
+ }
+
+ $(document).ready(function(){
+ loadExternalCodeSnippets();
+ });
+ $('#source-view').on('shown', function () {
+ loadExternalCodeSnippets();
+ })
+ </script>
+
+ <link rel="shortcut icon" href="../images/favicon.ico"/>
+ <link rel="apple-touch-icon" href="../images/apple-touch-icon.png"/>
+ <link rel="apple-touch-icon" sizes="72x72" href="../images/apple-touch-icon-72x72.png"/>
+ <link rel="apple-touch-icon" sizes="114x114" href="../images/apple-touch-icon-114x114.png"/>
+</head>
+<body>
+
+<div class="navbar navbar-fixed-top">
+ <div class="navbar-inner">
+ <div class="container">
+ <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+ <i class="icon-ellipsis-vertical"></i>
+ </a>
+ <a class="brand" href="../index.html">API Documentation</a>
+
+ <div class="nav-collapse">
+ <ul class="nav pull-right">
+ <li class="dropdown" id="charts-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Charts <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../graphs/class.html">
+ <i class="icon-list-alt"></i>&#160;Class hierarchy diagram
+ </a>
+ </li>
+ </ul>
+ </li>
+ <li class="dropdown" id="reports-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Reports <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../reports/errors.html">
+ <i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">50</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/markers.html">
+ <i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">1</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/deprecated.html">
+ <i class="icon-list-alt"></i>&#160;Deprecated <span class="label label-info pull-right">0</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <!--<div class="go_to_top">-->
+ <!--<a href="#___" style="color: inherit">Back to top&#160;&#160;<i class="icon-upload icon-white"></i></a>-->
+ <!--</div>-->
+</div>
+
+<div id="___" class="container-fluid">
+ <section class="row-fluid">
+ <div class="span2 sidebar">
+ <div class="accordion" style="margin-bottom: 0">
+ <div class="accordion-group">
+ <div class="accordion-heading">
+ <a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-1100704132"></a>
+ <a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
+ </div>
+ <div id="namespace-1100704132" class="accordion-body collapse in">
+ <div class="accordion-inner">
+
+
+ <ul>
+ <li class="class"><a href="../classes/assignment.html">assignment</a></li>
+ <li class="class"><a href="../classes/BusinessAdmin.html">BusinessAdmin</a></li>
+ <li class="class"><a href="../classes/client.html">client</a></li>
+ <li class="class"><a href="../classes/constants.html">constants</a></li>
+ <li class="class"><a href="../classes/contact.html">contact</a></li>
+ <li class="class"><a href="../classes/correspondence.html">correspondence</a></li>
+ <li class="class"><a href="../classes/file.html">file</a></li>
+ <li class="class"><a href="../classes/offer.html">offer</a></li>
+ <li class="class"><a href="../classes/response.html">response</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ </div>
+ </section>
+ <section class="row-fluid">
+ <div class="span10 offset2">
+ <div class="row-fluid">
+ <div class="span8 content file">
+ <nav>
+ </nav>
+
+ <a href="#source-view" role="button" class="pull-right btn" data-toggle="modal"><i class="icon-code"></i></a>
+ <h1><small></small>file.class.php</h1>
+ <p><em>Provides the file class, an interface to the file table in the database</em></p>
+
+
+
+
+ <h2>Classes</h2>
+ <table class="table table-hover">
+ <tr>
+ <td><a href="../classes/file.html">file</a></td>
+ <td><em>An interface to the file table in the database</em></td>
+ </tr>
+ </table>
+ </div>
+
+ <aside class="span4 detailsbar">
+ <dl>
+ <dt>Package</dt>
+ <dd><div class="namespace-wrapper">\Default</div></dd>
+
+
+ </dl>
+ <h2>Tags</h2>
+ <table class="table table-condensed">
+ <tr>
+ <th>
+ author
+ </th>
+ <td>
+ <p>Camil Staps</p>
+<p>BusinessAdmin: administrative software for small companies
+Copyright (C) 2015 Camil Staps (ViviSoft)</p>
+<p>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.</p>
+<p>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.</p>
+<p>You should have received a copy of the GNU General Public License
+along with this program. If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.</p>
+ </td>
+ </tr>
+ </table>
+
+ </aside>
+ </div>
+
+
+
+ </div>
+ </section>
+
+ <div id="source-view" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="source-view-label" aria-hidden="true">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+ <h3 id="source-view-label"></h3>
+ </div>
+ <div class="modal-body">
+ <pre data-src="../files/file.class.php.txt" class="language-php line-numbers"></pre>
+ </div>
+ </div>
+
+ <footer class="row-fluid">
+ <section class="span10 offset2">
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <section class="row-fluid footer-sections">
+ <section class="span4">
+ <h1><i class="icon-code"></i></h1>
+ <div>
+ <ul>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-bar-chart"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../graphs/class.html">Class Hierarchy Diagram</a></li>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-pushpin"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../reports/errors.html">Errors</a></li>
+ <li><a href="../reports/markers.html">Markers</a></li>
+ </ul>
+ </div>
+ </section>
+ </section>
+ </section>
+ </section>
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <hr />
+ Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
+ on February 7th, 2015 at 21:04.
+ </section>
+ </section>
+ </section>
+ </footer>
+</div>
+
+</body>
+</html>
diff --git a/docs/files/file.class.php.txt b/docs/files/file.class.php.txt
new file mode 100644
index 0000000..27d64dd
--- /dev/null
+++ b/docs/files/file.class.php.txt
@@ -0,0 +1,148 @@
+<?php
+/**
+ * Provides the file class, an interface to the file table in the database
+ *
+ * @author Camil Staps
+ *
+ * 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/>.
+ */
+
+/**
+ * An interface to the file table in the database
+ */
+class file {
+ /**
+ * @var PDO $pdo The PDO class for database communication
+ * @var int $id The id of the file
+ * @var string $filename The relative path to the file
+ */
+ protected $pdo, $id, $filename;
+
+ /**
+ * Create a new instance
+ *
+ * @param PDO $pdo The PDO class, to access the database
+ * @param int $id The id of the file to fetch
+ *
+ * @throws PDOException If something went wrong with the database
+ * @throws Exception If the file could not be found
+ */
+ public function __construct($pdo, $id) {
+ $this->pdo = $pdo;
+
+ $stmt = $this->pdo->prepare("SELECT * FROM `".constants::db_prefix."file` WHERE `id`=?");
+ $stmt->execute(array($id));
+ if ($stmt->rowCount() == 0) {
+ throw new Exception("The file with id '$id' could not be found.");
+ }
+ $file = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ $this->id = $file['id'];
+ $this->filename = $file['filename'];
+ }
+
+ //------------------------------------------------------------------------------
+ // Getters and setters
+ //------------------------------------------------------------------------------
+
+ /**
+ * Get the ID of the file
+ *
+ * @return int The ID
+ */
+ public function getId() {
+ return $this->id;
+ }
+
+ /**
+ * Get the relative filename of the file
+ *
+ * @see file::getFilenamePath To get the full internal path to the file
+ * @see file::getFilenameURI To get the full external path to the file
+ *
+ * @return string The filename
+ */
+ public function getFilename() {
+ return $this->filename;
+ }
+
+ /**
+ * Get the full internal path to the file
+ *
+ * @see file::getFilename To get the relative filename
+ * @see file::getFilenameURI To get the full external path to the file
+ *
+ * @return string The path
+ */
+ public function getFilenamePath() {
+ return constants::files_folder . $this->filename;
+ }
+
+ /**
+ * Get the full external path to the file
+ *
+ * @see file::getFilename To get the relative filename
+ * @see file::getFilenamePath To get the full internal path to the file
+ *
+ * @return string The URI
+ */
+ public function getFilenameURI() {
+ return constants::files_folder_external . $this->filename;
+ }
+
+ //------------------------------------------------------------------------------
+ // Other functions
+ //------------------------------------------------------------------------------
+
+ /**
+ * Move this file to the trash and delete all records for it
+ *
+ * Physically, this moves the file to a trash folder
+ * Then, the file will be removed from the file table in the database
+ * Any appendices linking to this file with fileId will have fileId NULL
+ * Any offers linking to this file with invoice_fileId will have invoice_fileId NULL
+ *
+ * @throws PDOException If there's something wrong with the database
+ *
+ * @return bool True on success, false on failure
+ */
+ public function delete() {
+ // Try to move the file to trash
+ $newname = pathinfo($this->filename, PATHINFO_FILENAME) . '--' . date('Y-m-d.H.i.s.') . pathinfo($this->filename, PATHINFO_EXTENSION);
+ $newdir = pathinfo($this->getFilenamePath(), PATHINFO_DIRNAME) . '/' . constants::files_folder_trash . '/';
+ if (!file_exists($newdir)) {
+ if (!mkdir($newdir)) {
+ return false;
+ }
+ }
+ if (!(@rename($this->getFilenamePath(), $newdir . $newname))) {
+ return false;
+ }
+
+ // Remove offers linked by invoice_fileId
+ $this->pdo->query("UPDATE `".constants::db_prefix."offer` SET `invoice_fileId`=NULL WHERE `invoice_fileId`={$this->id}");
+
+ // Remove the record of the file
+ $stmt = $this->pdo->prepare("DELETE FROM `".constants::db_prefix."file` WHERE `id`=?");
+ $stmt->execute(array($this->id));
+ if ($stmt->rowCount() == 1) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/docs/files/offer.class.html b/docs/files/offer.class.html
new file mode 100644
index 0000000..20dc299
--- /dev/null
+++ b/docs/files/offer.class.html
@@ -0,0 +1,280 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
+ <meta charset="utf-8"/>
+ <title>API Documentation</title>
+ <meta name="author" content=""/>
+ <meta name="description" content=""/>
+
+ <link href="../css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
+ <link href="../css/font-awesome.min.css" rel="stylesheet">
+ <link href="../css/prism.css" rel="stylesheet" media="all"/>
+ <link href="../css/template.css" rel="stylesheet" media="all"/>
+
+ <!--[if lt IE 9]>
+ <script src="../js/html5.js"></script>
+ <![endif]-->
+ <script src="../js/jquery-1.11.0.min.js"></script>
+ <script src="../js/ui/1.10.4/jquery-ui.min.js"></script>
+ <script src="../js/bootstrap.min.js"></script>
+ <script src="../js/jquery.smooth-scroll.js"></script>
+ <script src="../js/prism.min.js"></script>
+ <!-- TODO: Add http://jscrollpane.kelvinluck.com/ to style the scrollbars for browsers not using webkit-->
+ <script type="text/javascript">
+ function loadExternalCodeSnippets() {
+ Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function (pre) {
+ var src = pre.getAttribute('data-src');
+ var extension = (src.match(/\.(\w+)$/) || [, ''])[1];
+ var language = 'php';
+
+ var code = document.createElement('code');
+ code.className = 'language-' + language;
+
+ pre.textContent = '';
+
+ code.textContent = 'Loading…';
+
+ pre.appendChild(code);
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.open('GET', src, true);
+
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+
+ if (xhr.status < 400 && xhr.responseText) {
+ code.textContent = xhr.responseText;
+
+ Prism.highlightElement(code);
+ }
+ else if (xhr.status >= 400) {
+ code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;
+ }
+ else {
+ code.textContent = '✖ Error: File does not exist or is empty';
+ }
+ }
+ };
+
+ xhr.send(null);
+ });
+ }
+
+ $(document).ready(function(){
+ loadExternalCodeSnippets();
+ });
+ $('#source-view').on('shown', function () {
+ loadExternalCodeSnippets();
+ })
+ </script>
+
+ <link rel="shortcut icon" href="../images/favicon.ico"/>
+ <link rel="apple-touch-icon" href="../images/apple-touch-icon.png"/>
+ <link rel="apple-touch-icon" sizes="72x72" href="../images/apple-touch-icon-72x72.png"/>
+ <link rel="apple-touch-icon" sizes="114x114" href="../images/apple-touch-icon-114x114.png"/>
+</head>
+<body>
+
+<div class="navbar navbar-fixed-top">
+ <div class="navbar-inner">
+ <div class="container">
+ <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+ <i class="icon-ellipsis-vertical"></i>
+ </a>
+ <a class="brand" href="../index.html">API Documentation</a>
+
+ <div class="nav-collapse">
+ <ul class="nav pull-right">
+ <li class="dropdown" id="charts-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Charts <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../graphs/class.html">
+ <i class="icon-list-alt"></i>&#160;Class hierarchy diagram
+ </a>
+ </li>
+ </ul>
+ </li>
+ <li class="dropdown" id="reports-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Reports <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../reports/errors.html">
+ <i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">50</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/markers.html">
+ <i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">1</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/deprecated.html">
+ <i class="icon-list-alt"></i>&#160;Deprecated <span class="label label-info pull-right">0</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <!--<div class="go_to_top">-->
+ <!--<a href="#___" style="color: inherit">Back to top&#160;&#160;<i class="icon-upload icon-white"></i></a>-->
+ <!--</div>-->
+</div>
+
+<div id="___" class="container-fluid">
+ <section class="row-fluid">
+ <div class="span2 sidebar">
+ <div class="accordion" style="margin-bottom: 0">
+ <div class="accordion-group">
+ <div class="accordion-heading">
+ <a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-563987229"></a>
+ <a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
+ </div>
+ <div id="namespace-563987229" class="accordion-body collapse in">
+ <div class="accordion-inner">
+
+
+ <ul>
+ <li class="class"><a href="../classes/assignment.html">assignment</a></li>
+ <li class="class"><a href="../classes/BusinessAdmin.html">BusinessAdmin</a></li>
+ <li class="class"><a href="../classes/client.html">client</a></li>
+ <li class="class"><a href="../classes/constants.html">constants</a></li>
+ <li class="class"><a href="../classes/contact.html">contact</a></li>
+ <li class="class"><a href="../classes/correspondence.html">correspondence</a></li>
+ <li class="class"><a href="../classes/file.html">file</a></li>
+ <li class="class"><a href="../classes/offer.html">offer</a></li>
+ <li class="class"><a href="../classes/response.html">response</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ </div>
+ </section>
+ <section class="row-fluid">
+ <div class="span10 offset2">
+ <div class="row-fluid">
+ <div class="span8 content file">
+ <nav>
+ </nav>
+
+ <a href="#source-view" role="button" class="pull-right btn" data-toggle="modal"><i class="icon-code"></i></a>
+ <h1><small></small>offer.class.php</h1>
+ <p><em>Provides the offer class, an interface to the offer table in the database</em></p>
+
+
+
+
+ <h2>Classes</h2>
+ <table class="table table-hover">
+ <tr>
+ <td><a href="../classes/offer.html">offer</a></td>
+ <td><em>An interface to the offer table in the database</em></td>
+ </tr>
+ </table>
+ </div>
+
+ <aside class="span4 detailsbar">
+ <dl>
+ <dt>Package</dt>
+ <dd><div class="namespace-wrapper">\Default</div></dd>
+
+
+ </dl>
+ <h2>Tags</h2>
+ <table class="table table-condensed">
+ <tr>
+ <th>
+ author
+ </th>
+ <td>
+ <p>Camil Staps</p>
+<p>BusinessAdmin: administrative software for small companies
+Copyright (C) 2015 Camil Staps (ViviSoft)</p>
+<p>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.</p>
+<p>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.</p>
+<p>You should have received a copy of the GNU General Public License
+along with this program. If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.</p>
+ </td>
+ </tr>
+ </table>
+
+ </aside>
+ </div>
+
+
+
+ </div>
+ </section>
+
+ <div id="source-view" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="source-view-label" aria-hidden="true">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+ <h3 id="source-view-label"></h3>
+ </div>
+ <div class="modal-body">
+ <pre data-src="../files/offer.class.php.txt" class="language-php line-numbers"></pre>
+ </div>
+ </div>
+
+ <footer class="row-fluid">
+ <section class="span10 offset2">
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <section class="row-fluid footer-sections">
+ <section class="span4">
+ <h1><i class="icon-code"></i></h1>
+ <div>
+ <ul>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-bar-chart"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../graphs/class.html">Class Hierarchy Diagram</a></li>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-pushpin"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../reports/errors.html">Errors</a></li>
+ <li><a href="../reports/markers.html">Markers</a></li>
+ </ul>
+ </div>
+ </section>
+ </section>
+ </section>
+ </section>
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <hr />
+ Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
+ on February 7th, 2015 at 21:04.
+ </section>
+ </section>
+ </section>
+ </footer>
+</div>
+
+</body>
+</html>
diff --git a/docs/files/offer.class.php.txt b/docs/files/offer.class.php.txt
new file mode 100644
index 0000000..d07215b
--- /dev/null
+++ b/docs/files/offer.class.php.txt
@@ -0,0 +1,627 @@
+<?php
+/**
+ * Provides the offer class, an interface to the offer table in the database
+ *
+ * @author Camil Staps
+ *
+ * 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/>.
+ */
+
+/**
+ * An interface to the offer table in the database
+ */
+class offer {
+ /**
+ * @var pdo $pdo The PDO class for database communication
+ * @var int $id The id of the offer
+ * @var int $contactId The id of the contact this offer is linked to
+ * @var int $start_date A UNIX timestamp of the start date
+ * @var int $end_date A UNIX timestamp of the end date
+ * @var int $invoice_date A UNIX timestamp of the invoice date
+ * @var bool $accepted Whether the offer is accepted or not
+ * @var null|int $invoice_fileId If an invoice has been generated, an the id of the file
+ * @var null|int $payment_received A UNIX timestamp of the date the payment has been received
+ */
+ protected $pdo, $id, $contactId, $start_date, $end_date, $invoice_date, $accepted, $invoice_fileId, $payment_received;
+
+ const SUBTOTAL = 1;
+ const VAT = 2;
+ const TOTAL = 3;
+
+ /**
+ * Create a new instance
+ *
+ * Blah
+ *
+ * @param PDO $pdo The PDO class, to access the database
+ * @param int $id The id of the offer to fetch
+ *
+ * @throws PDOException If something went wrong with the database
+ * @throws Exception If the offer could not be found
+ */
+ public function __construct($pdo, $id) {
+ $this->pdo = $pdo;
+
+ $stmt = $this->pdo->prepare("SELECT * FROM `".constants::db_prefix."offer` WHERE `id`=?");
+ $stmt->execute(array($id));
+ if ($stmt->rowCount() == 0) {
+ throw new Exception("The offer with id '$id' could not be found.");
+ }
+ $offer = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ $this->id = $offer['id'];
+ $this->contactId = $offer['contactId'];
+ $this->start_date = strtotime($offer['start_date']);
+ $this->end_date = strtotime($offer['end_date']);
+ $this->invoice_date = strtotime($offer['invoice_date']);
+ $this->accepted = (bool) $offer['accepted'];
+ $this->invoice_fileId = $offer['invoice_fileId'];
+ $this->payment_received = ($offer['payment_received'] == null) ? null : strtotime($offer['payment_received']);
+ }
+
+ //------------------------------------------------------------------------------
+ // Getters and setters
+ //------------------------------------------------------------------------------
+
+ /**
+ * Get the ID of the offer
+ *
+ * @return int The ID
+ */
+ public function getId() {
+ return $this->id;
+ }
+
+ /**
+ * Get the ID of the contact that this offer is linked to
+ *
+ * @see offer::getContact() This function returns the contact as an instance of the object class
+ *
+ * @return int The ID
+ */
+ public function getContactId() {
+ return $this->contactId;
+ }
+
+ /**
+ * Get the contact that this offer is linked to
+ *
+ * @see offer::getContactId() This function returns just the id
+ *
+ * @return contact The contact
+ */
+ public function getContact() {
+ return new contact($this->pdo, $this->contactId);
+ }
+
+ /**
+ * Get all assignment ids for this offer
+ *
+ * @see offer::getAssignments() This funtion returns instances of the assignment class instead of just the ids
+ *
+ * @throws PDOException Is something went wrong with the database
+ *
+ * @return int[] The ids
+ */
+ public function getAssignmentIds() {
+ $ids = array();
+ $assignments = $this->pdo->query("SELECT `id` FROM `".constants::db_prefix."assignment` WHERE `offerId`={$this->id}")->fetchAll(PDO::FETCH_ASSOC);
+ foreach ($assignments as $assignment) {
+ $ids[] = $assignment['id'];
+ }
+ return $ids;
+ }
+
+ /**
+ * Get all assignments for this offer
+ *
+ * @see offer::getAssignmentIds() This function returns just the ids of the assignments, and not instances of the assignment class
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return assignment[] An array indexed by id of instances of the assignment class
+ */
+ public function getAssignments() {
+ $ids = $this->getAssignmentIds();
+ $assignments = array();
+ foreach ($ids as $id) {
+ $assignments[$id] = new assignment($this->pdo, $id);
+ }
+ return $assignments;
+ }
+
+ /**
+ * Get the start date of the assignment
+ *
+ * @return int The start date as a UNIX timestamp
+ */
+ public function getStartDate() {
+ return $this->start_date;
+ }
+
+ /**
+ * Set the start date of the assignment
+ *
+ * @param int $start_date The new start date for the assignment as a UNIX timestamp
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setStartDate($start_date) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."offer` SET `start_date`=? WHERE `id`=?");
+ $stmt->execute(array(date('Y-m-d', $start_date), $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->start_date = $start_date;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the end date of the assignment
+ *
+ * @return int The end date as a UNIX timestamp
+ */
+ public function getEndDate() {
+ return $this->end_date;
+ }
+
+ /**
+ * Set the end date of the assignment
+ *
+ * @param int $end_date The new end date for the assignment as a UNIX timestamp
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setEndDate($end_date) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."offer` SET `end_date`=? WHERE `id`=?");
+ $stmt->execute(array(date('Y-m-d', $end_date), $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->end_date = $end_date;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the invoice date of the assignment
+ *
+ * @return int The invoice date as a UNIX timestamp
+ */
+ public function getInvoiceDate() {
+ return $this->invoice_date;
+ }
+
+ /**
+ * Set the invoice date of the assignment
+ *
+ * @param int $invoice_date The new invoice date for the assignment as a UNIX timestamp
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setInvoiceDate($invoice_date) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."offer` SET `invoice_date`=? WHERE `id`=?");
+ $stmt->execute(array(date('Y-m-d', $invoice_date), $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->invoice_date = $invoice_date;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the date the payment was received
+ *
+ * @return int|null The date as a UNIX timestamp, or null if it wasn't received yet
+ */
+ public function getPaymentReceived() {
+ return $this->payment_received;
+ }
+
+ /**
+ * Set the payment received date of the assignment
+ *
+ * @param int $payment_received The new date the payment has been received as a UNIX timestamp
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setPaymentReceived($payment_received) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."offer` SET `payment_received`=? WHERE `id`=?");
+ $stmt->execute(array(date('Y-m-d', $payment_received), $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->payment_received = $payment_received;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Check if the offer is accepted or not
+ *
+ * @return bool True if the offer is accepted, false if not
+ */
+ public function isAccepted() {
+ return $this->accepted;
+ }
+
+ /**
+ * Toggle the `accepted' status of the offer
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on success, false on failure
+ */
+ public function toggleAccepted() {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."offer` SET `accepted`=? WHERE `id`=?");
+ $new_value = !$this->accepted;
+ $stmt->execute(array($new_value, $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->accepted = $new_value;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the ID of the file that the invoice of this offer is linked to
+ *
+ * @see offer::getInvoiceFile() This function returns the file as an instance of the file class
+ *
+ * @return int The ID
+ */
+ public function getInvoiceFileId() {
+ return $this->invoice_fileId;
+ }
+
+ /**
+ * Get the file that the invoice this offer is linked to
+ *
+ * @see offer::getInvoiceId() This function returns just the id
+ *
+ * @return file|null The file, or null if it doesn't exist
+ */
+ public function getInvoiceFile() {
+ if ($this->invoice_fileId != null) {
+ return new file($this->pdo, $this->invoice_fileId);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Set the invoice file id of the assignment
+ *
+ * @param int $invoice_fileId The new invoice file id for the assignment
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on succes, false on failure
+ */
+ public function setInvoiceFileId($invoice_fileId) {
+ $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."offer` SET `invoice_fileId`=? WHERE `id`=?");
+ $stmt->execute(array($invoice_fileId, $this->id));
+ if ($stmt->rowCount() == 1) {
+ $this->invoice_fileId = $invoice_fileId;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ // Other functions
+ //------------------------------------------------------------------------------
+
+ /**
+ * Calculate a handy number about the invoice
+ *
+ * Subtotal: the sum of the prices of the assignments excl. VAT
+ *
+ * VAT: the sum of all the VAT from all the assignments
+ *
+ * Total: the sum of subtotal and total
+ *
+ * @param int $what Any of offer::SUBTOTAL, offer::VAT and offer::TOTAL
+ * @param int $round How many decimals to round the result on
+ * @param bool $format Whether to format the number nicely (for output) or not (for calculations)
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return float|bool The calculated value rounded to $round decimals, or false on incorrect input
+ */
+ public function calculate($what = self::TOTAL, $round = 2, $format = true) {
+ $return = 0;
+ switch ($what) {
+ case self::SUBTOTAL:
+ $assignments = $this->getAssignments();
+ foreach ($assignments as $assignment) {
+ $return += $assignment->calculate(assignment::SUBTOTAL, $round + 1, false);
+ }
+ break;
+ case self::VAT:
+ $assignments = $this->getAssignments();
+ foreach ($assignments as $assignment) {
+ $return += $assignment->calculate(assignment::VAT, $round + 1, false);
+ }
+ break;
+ case self::TOTAL:
+ $return = $this->calculate(self::SUBTOTAL, $round + 1, false) + $this->calculate(self::VAT, $round + 1, false);
+ break;
+ default:
+ return false;
+ }
+ if ($format) {
+ return number_format($return, 2);
+ } else {
+ return round($return, 2);
+ }
+ }
+
+ /**
+ * Remove this offer from the database
+ *
+ * If this doesn't succeed (i.e. false is returned), that means the offer was removed manually or by another instance of this class
+ *
+ * @throws PDOException If something went wrong with the database
+ *
+ * @return bool True on success, false on failure
+ */
+ public function delete() {
+ $stmt = $this->pdo->prepare("DELETE FROM `".constants::db_prefix."offer` WHERE `id`=?");
+ $stmt->execute(array($this->id));
+ if ($stmt->rowCount() != 1) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Make a new assignment linked to this order
+ *
+ * @param string $title The title for this assignment
+ * @param string $description The description for this assignment
+ * @param int $hours The amount of hours to work on this assignment
+ * @param float $price_per_hour The price per hour on this assignment
+ * @param float $vat The VAT percentage (so, 21 for 21%, not 0.21!)
+ *
+ * @throws PDOException If something went wrong with the database
+ * @throws Exception If there was a problem with the input
+ *
+ * @return assignment A new instance of the assignment class containing the new assignment
+ */
+ public function createAssignment($title, $description, $hours, $price_per_hour, $vat) {
+ $stmt = $this->pdo->prepare("INSERT INTO `".constants::db_prefix."assignment` (`offerId`,`title`,`description`,`hours`,`price_per_hour`,`VAT_percentage`) VALUES (?,?,?,?,?,?)");
+ $stmt->execute(array(
+ $this->id,
+ $title,
+ $description,
+ $hours,
+ $price_per_hour,
+ $vat
+ ));
+ if ($stmt->rowCount() == 1) {
+ return new assignment($this->pdo, $this->pdo->lastInsertId());
+ } else {
+ $error = $stmt->errorInfo();
+ throw new Exception($error[2]);
+ }
+ }
+
+ /**
+ * Generate a PDF invoice
+ *
+ * @throws PDOException If something went wrong with the database
+ * @throws Exception If the file could not be written or an other error occured
+ *
+ * @return file An instance of the file class with information on the invoice file generated
+ */
+ public function generateInvoice() {
+ // Check if we already have a file
+ $file = $this->getInvoiceFile();
+ if (!($file instanceof file)) {
+ // If not, create a new file
+ $i = 1;
+ do {
+ $invoice_nr = date('Y',$this->invoice_date) . str_pad($i++, 2, '0', STR_PAD_LEFT);
+ $filename = 'invoice-' . $invoice_nr . '.pdf';
+ } while (file_exists(constants::files_folder . $filename));
+ $file = BusinessAdmin::createFile($this->pdo, $filename);
+
+ $this->setInvoiceFileId($file->getId());
+ } else {
+ $invoice_nr = str_replace(array('invoice-','.pdf'), array('',''), $file->getFilename());
+ }
+
+ $assignments = $this->getAssignments();
+ $list = array();
+ foreach ($assignments as $assignment)
+ $list[] = array(
+ $assignment->getTitle(),
+ $assignment->getPricePerHour() * $assignment->getHours(),
+ $assignment->getVAT() . "%",
+ $assignment->getPricePerHour() * $assignment->getHours() * (1 + $assignment->getVAT() / 100)
+ );
+
+ $pdf = new correspondence();
+ $pdf->SetContact($this->getContact());
+ $pdf->SetTitle($pdf->_('invoice') . ' ' . $invoice_nr);
+ $pdf->AddPage();
+ $pdf->correspondenceHeader();
+
+ $pdf->SetY(100);
+ $pdf->SetFont('','B',14);
+ $pdf->SetTextColor(correspondence::HEAD_RED, correspondence::HEAD_GREEN, correspondence::HEAD_BLUE);
+ $pdf->Cell(60,6, $pdf->_('invoice'),'B');
+ $pdf->SetTextColor(0);
+ $pdf->Ln();
+
+ $width = array(90,25,20,25);
+ $subtotal = 0;
+ $btw = array();
+ $total = 0;
+
+ // Header
+
+ $pdf->SetFont('','',9);
+ $pdf->Cell(60,4);
+ $pdf->Ln();
+ $pdf->SetFont('','B');
+ $pdf->Cell(30,4.5,$pdf->_('invoice-date'));
+ $pdf->SetFont('','');
+ $pdf->Cell(50,4.5,date("d-m-Y", $this->invoice_date));
+ $pdf->Ln();
+ $pdf->SetFont('','B');
+ $pdf->Cell(30,4.5,$pdf->_('invoice-nr'));
+ $pdf->SetFont('','');
+ $pdf->Cell(50,4.5,$invoice_nr);
+ $pdf->Ln();
+ $pdf->SetFont('','B');
+ $pdf->Cell(30,4.5,$pdf->_('due-date'));
+ $pdf->SetFont('','');
+ $pdf->Cell(50,4.5,date("d-m-Y",$this->invoice_date+3600*24*30));
+ $pdf->Ln();
+ $pdf->Cell(60,4.5,'','B');
+ $pdf->Ln();
+
+ $pdf->SetY(140);
+
+ // Table
+
+ $pdf->SetFont('','B',11);
+ $pdf->SetTextColor(correspondence::HEAD_RED, correspondence::HEAD_GREEN, correspondence::HEAD_BLUE);
+ $pdf->Cell($width[0],7,$pdf->_('description'),'B');
+ $pdf->Cell($width[1],7,$pdf->_('price-excl'),'B',0,'R');
+ $pdf->Cell($width[2],7,$pdf->_('vat'),'B',0,'R');
+ $pdf->Cell($width[3],7,$pdf->_('price-incl'),'B',0,'R');
+ $pdf->SetTextColor(0);
+ $pdf->Ln();
+
+ $pdf->SetFont('','');
+ foreach ($list as $row) {
+ $x = $pdf->getX();
+ $y = $pdf->getY();
+ $pdf->MultiCell($width[0],6,$row[0],0,'L');
+ $newy = $pdf->getY();
+ $pdf->SetXY($x + $width[0], $y);
+ $pdf->Cell($width[1],6,constants::invoice_valuta.number_format($row[1],2),'',0,'R');
+ $pdf->Cell($width[2],6,round($row[2],0) . '%','',0,'R');
+ $pdf->Cell($width[3],6,constants::invoice_valuta.number_format($row[3],2),'',0,'R');
+ $pdf->Ln();
+ $pdf->SetY($newy);
+ $subtotal += $row[1];
+ if (!isset($btw[$row[2]])) $btw[$row[2]] = 0;
+ $btw[$row[2]] += $row[3] - $row[1];
+ }
+ $total = $subtotal;
+ foreach ($btw as $m) {
+ $total += $m;
+ }
+
+ $pdf->Cell(array_sum($width),5,'','T');
+ $pdf->Ln();
+ $pdf->Cell(array_sum($width),5);
+ $pdf->Ln();
+
+ $pdf->Cell($width[0],7);
+ $pdf->SetFont('','B');
+ $pdf->Cell($width[1] + $width[2],7,$pdf->_('amount'));
+ $pdf->SetFont('','');
+ $pdf->Cell($width[3],7,constants::invoice_valuta . $this->calculate(self::SUBTOTAL),'',0,'R');
+ $pdf->Ln();
+
+ foreach ($btw as $p => $m) {
+ $pdf->Cell($width[0],7);
+ $pdf->Cell($width[1] + $width[2],7,$pdf->_('vat') . ' '.round($p,0).'%');
+ $pdf->Cell($width[3],7,constants::invoice_valuta . number_format($m,2),'',0,'R');
+ $pdf->Ln();
+ }
+
+ $pdf->Cell(array_sum($width),5);
+ $pdf->Ln();
+
+ $pdf->Cell($width[0],7);
+ $pdf->SetFont('','B');
+ $pdf->Cell($width[1] + $width[2],7,$pdf->_('total'));
+ $pdf->SetFont('','');
+ $pdf->Cell($width[3],7,constants::invoice_valuta . $this->calculate(self::TOTAL),'T',0,'R');
+ $pdf->Ln();
+
+ // Footer
+
+ $pdf->Ln();
+ if ($pdf->GetY() < 230) {
+ $pdf->SetY(230);
+ }
+ $oldY = $pdf->GetY();
+ $pdf->Cell(45,20,'',1);
+ $pdf->Cell(12.5,20);
+ $pdf->Cell(45,20,'',1);
+ $pdf->Cell(12.5,20);
+ $pdf->Cell(45,20,'',1);
+
+ $pdf->SetFont('','B',10);
+ $pdf->SetTextColor(correspondence::HEAD_RED, correspondence::HEAD_GREEN, correspondence::HEAD_BLUE);
+ $pdf->SetY($oldY + 3);
+ $pdf->Cell(5,5);
+ $pdf->Cell(40,5,$pdf->_('iban'));
+ $pdf->Cell(17.5,5);
+ $pdf->Cell(40,5,$pdf->_('invoice-nr'));
+ $pdf->Cell(17.5,5);
+ $pdf->Cell(40,5,$pdf->_('amount-due'));
+ $pdf->SetTextColor(0);
+
+ $pdf->SetFont('','',8);
+ $pdf->Ln();
+ $pdf->Ln();
+ $oldY = $pdf->GetY();
+
+ $pdf->Cell(5,5);
+ $pdf->Cell(40,5, constants::invoice_iban);
+ $pdf->Cell(17.5,5);
+ $pdf->Cell(40,5,$invoice_nr);
+ $pdf->Cell(17.5,5);
+ $pdf->Cell(40,5,constants::invoice_valuta . $this->calculate(self::TOTAL));
+
+ $pdf->SetY($oldY + 14);
+
+ $pdf->SetFontSize(7);
+ $pdf->Cell(160,5,$pdf->_('request'),0,0,'C');
+ $pdf->Ln();
+ $pdf->Cell(160,5,str_replace('%%', constants::invoice_bic, $pdf->_('biccode')),0,0,'C');
+
+ if (file_exists($file->getFilenamePath())) {
+ unlink($file->getFilenamePath());
+ }
+ $pdf->Output($file->getFilenamePath(),'F');
+ chmod($file->getFilenamePath(),0644);
+
+ return $file;
+ }
+}
diff --git a/docs/files/response.class.html b/docs/files/response.class.html
new file mode 100644
index 0000000..990a487
--- /dev/null
+++ b/docs/files/response.class.html
@@ -0,0 +1,280 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
+ <meta charset="utf-8"/>
+ <title>API Documentation</title>
+ <meta name="author" content=""/>
+ <meta name="description" content=""/>
+
+ <link href="../css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
+ <link href="../css/font-awesome.min.css" rel="stylesheet">
+ <link href="../css/prism.css" rel="stylesheet" media="all"/>
+ <link href="../css/template.css" rel="stylesheet" media="all"/>
+
+ <!--[if lt IE 9]>
+ <script src="../js/html5.js"></script>
+ <![endif]-->
+ <script src="../js/jquery-1.11.0.min.js"></script>
+ <script src="../js/ui/1.10.4/jquery-ui.min.js"></script>
+ <script src="../js/bootstrap.min.js"></script>
+ <script src="../js/jquery.smooth-scroll.js"></script>
+ <script src="../js/prism.min.js"></script>
+ <!-- TODO: Add http://jscrollpane.kelvinluck.com/ to style the scrollbars for browsers not using webkit-->
+ <script type="text/javascript">
+ function loadExternalCodeSnippets() {
+ Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function (pre) {
+ var src = pre.getAttribute('data-src');
+ var extension = (src.match(/\.(\w+)$/) || [, ''])[1];
+ var language = 'php';
+
+ var code = document.createElement('code');
+ code.className = 'language-' + language;
+
+ pre.textContent = '';
+
+ code.textContent = 'Loading…';
+
+ pre.appendChild(code);
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.open('GET', src, true);
+
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+
+ if (xhr.status < 400 && xhr.responseText) {
+ code.textContent = xhr.responseText;
+
+ Prism.highlightElement(code);
+ }
+ else if (xhr.status >= 400) {
+ code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;
+ }
+ else {
+ code.textContent = '✖ Error: File does not exist or is empty';
+ }
+ }
+ };
+
+ xhr.send(null);
+ });
+ }
+
+ $(document).ready(function(){
+ loadExternalCodeSnippets();
+ });
+ $('#source-view').on('shown', function () {
+ loadExternalCodeSnippets();
+ })
+ </script>
+
+ <link rel="shortcut icon" href="../images/favicon.ico"/>
+ <link rel="apple-touch-icon" href="../images/apple-touch-icon.png"/>
+ <link rel="apple-touch-icon" sizes="72x72" href="../images/apple-touch-icon-72x72.png"/>
+ <link rel="apple-touch-icon" sizes="114x114" href="../images/apple-touch-icon-114x114.png"/>
+</head>
+<body>
+
+<div class="navbar navbar-fixed-top">
+ <div class="navbar-inner">
+ <div class="container">
+ <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+ <i class="icon-ellipsis-vertical"></i>
+ </a>
+ <a class="brand" href="../index.html">API Documentation</a>
+
+ <div class="nav-collapse">
+ <ul class="nav pull-right">
+ <li class="dropdown" id="charts-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Charts <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../graphs/class.html">
+ <i class="icon-list-alt"></i>&#160;Class hierarchy diagram
+ </a>
+ </li>
+ </ul>
+ </li>
+ <li class="dropdown" id="reports-menu">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ Reports <b class="caret"></b>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <a href="../reports/errors.html">
+ <i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">50</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/markers.html">
+ <i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">1</span>
+ </a>
+ </li>
+ <li>
+ <a href="../reports/deprecated.html">
+ <i class="icon-list-alt"></i>&#160;Deprecated <span class="label label-info pull-right">0</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <!--<div class="go_to_top">-->
+ <!--<a href="#___" style="color: inherit">Back to top&#160;&#160;<i class="icon-upload icon-white"></i></a>-->
+ <!--</div>-->
+</div>
+
+<div id="___" class="container-fluid">
+ <section class="row-fluid">
+ <div class="span2 sidebar">
+ <div class="accordion" style="margin-bottom: 0">
+ <div class="accordion-group">
+ <div class="accordion-heading">
+ <a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-1973630602"></a>
+ <a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
+ </div>
+ <div id="namespace-1973630602" class="accordion-body collapse in">
+ <div class="accordion-inner">
+
+
+ <ul>
+ <li class="class"><a href="../classes/assignment.html">assignment</a></li>
+ <li class="class"><a href="../classes/BusinessAdmin.html">BusinessAdmin</a></li>
+ <li class="class"><a href="../classes/client.html">client</a></li>
+ <li class="class"><a href="../classes/constants.html">constants</a></li>
+ <li class="class"><a href="../classes/contact.html">contact</a></li>
+ <li class="class"><a href="../classes/correspondence.html">correspondence</a></li>
+ <li class="class"><a href="../classes/file.html">file</a></li>
+ <li class="class"><a href="../classes/offer.html">offer</a></li>
+ <li class="class"><a href="../classes/response.html">response</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ </div>
+ </section>
+ <section class="row-fluid">
+ <div class="span10 offset2">
+ <div class="row-fluid">
+ <div class="span8 content file">
+ <nav>
+ </nav>
+
+ <a href="#source-view" role="button" class="pull-right btn" data-toggle="modal"><i class="icon-code"></i></a>
+ <h1><small></small>response.class.php</h1>
+ <p><em>Provides the response class</em></p>
+
+
+
+
+ <h2>Classes</h2>
+ <table class="table table-hover">
+ <tr>
+ <td><a href="../classes/response.html">response</a></td>
+ <td><em>Provides a standard to base all responses to be called with AJAX on</em></td>
+ </tr>
+ </table>
+ </div>
+
+ <aside class="span4 detailsbar">
+ <dl>
+ <dt>Package</dt>
+ <dd><div class="namespace-wrapper">\Default</div></dd>
+
+
+ </dl>
+ <h2>Tags</h2>
+ <table class="table table-condensed">
+ <tr>
+ <th>
+ author
+ </th>
+ <td>
+ <p>Camil Staps</p>
+<p>BusinessAdmin: administrative software for small companies
+Copyright (C) 2015 Camil Staps (ViviSoft)</p>
+<p>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.</p>
+<p>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.</p>
+<p>You should have received a copy of the GNU General Public License
+along with this program. If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.</p>
+ </td>
+ </tr>
+ </table>
+
+ </aside>
+ </div>
+
+
+
+ </div>
+ </section>
+
+ <div id="source-view" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="source-view-label" aria-hidden="true">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+ <h3 id="source-view-label"></h3>
+ </div>
+ <div class="modal-body">
+ <pre data-src="../files/response.class.php.txt" class="language-php line-numbers"></pre>
+ </div>
+ </div>
+
+ <footer class="row-fluid">
+ <section class="span10 offset2">
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <section class="row-fluid footer-sections">
+ <section class="span4">
+ <h1><i class="icon-code"></i></h1>
+ <div>
+ <ul>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-bar-chart"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../graphs/class.html">Class Hierarchy Diagram</a></li>
+ </ul>
+ </div>
+ </section>
+ <section class="span4">
+ <h1><i class="icon-pushpin"></i></h1>
+ <div>
+ <ul>
+ <li><a href="../reports/errors.html">Errors</a></li>
+ <li><a href="../reports/markers.html">Markers</a></li>
+ </ul>
+ </div>
+ </section>
+ </section>
+ </section>
+ </section>
+ <section class="row-fluid">
+ <section class="span10 offset1">
+ <hr />
+ Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
+ on February 7th, 2015 at 21:04.
+ </section>
+ </section>
+ </section>
+ </footer>
+</div>
+
+</body>
+</html>
diff --git a/docs/files/response.class.php.txt b/docs/files/response.class.php.txt
new file mode 100644
index 0000000..8d64006
--- /dev/null
+++ b/docs/files/response.class.php.txt
@@ -0,0 +1,112 @@
+<?php
+/**
+ * Provides the response class
+ *
+ * @author Camil Staps
+ *
+ * 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/>.
+ */
+
+/**
+ * Provides a standard to base all responses to be called with AJAX on
+ */
+class response {
+ /** The variable to keep the response in until output */
+ private $response;
+ /** The variable to keep the HTTP response code in until output */
+ private $http_response_code;
+
+ /**
+ * Create a new instance
+ */
+ public function __construct() {
+ $this->response = array();
+ $this->http_response_code = 200;
+ }
+
+ /**
+ * Set a variable of the response
+ *
+ * @param string $name The name of the variable to set
+ * @param string $value The (new) value for the variable
+ */
+ public function __set($name, $value) {
+ $this->response[$name] = $value;
+ }
+
+ /**
+ * Get a variable of the response
+ *
+ * @param string $name The name of the variable to get
+ *
+ * @return mixed The value of the variable
+ */
+ public function __get($name) {
+ return $this->response[$name];
+ }
+
+ /**
+ * Check if a variable of the response is set
+ *
+ * @param string $name The name of the variable to check
+ *
+ * @return bool True if the variable exists, false otherwise
+ */
+ public function __isset($name) {
+ return isset($this->response[$name]);
+ }
+
+ /**
+ * Unset a variable of the response
+ *
+ * @param string $name The variable to unset
+ */
+ public function __unset($name) {
+ unset($this->response[$name]);
+ }
+
+ /**
+ * Get or set the HTTP response code
+ *
+ * If a parameter is provided, it is used as the new HTTP response code, and a bool is returned for success or failure. Otherwise, the current one is returned.
+ *
+ * @param int $code The new code
+ *
+ * @return int|bool True on successful change, false on unsuccesful change, int when the current code is returned
+ */
+ public function http_response_code($code = null) {
+ if ($code === null) {
+ return $this->http_response_code;
+ } else {
+ if (http_response_code($code)) {
+ $this->http_response_code = $code;
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Output the response in json
+ *
+ * @return string The response in json format
+ */
+ public function getJson() {
+ return json_encode($this->response);
+ }
+}