From 4700139a86d1ef44eabe43edb5a4abff9c645811 Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Thu, 12 Mar 2015 23:03:51 -0400 Subject: Start to develop the budget module --- app/Controller/Budget.php | 111 ++++++++++++++++++++++++++++++++++ app/Model/Acl.php | 1 + app/Model/Base.php | 1 + app/Model/Budget.php | 101 +++++++++++++++++++++++++++++++ app/Schema/Mysql.php | 15 ++++- app/Schema/Postgres.php | 14 ++++- app/Schema/Sqlite.php | 14 ++++- app/ServiceProvider/ClassProvider.php | 1 + app/Template/budget/create.php | 51 ++++++++++++++++ app/Template/budget/index.php | 9 +++ app/Template/budget/remove.php | 13 ++++ app/Template/project/sidebar.php | 5 +- 12 files changed, 332 insertions(+), 4 deletions(-) create mode 100644 app/Controller/Budget.php create mode 100644 app/Model/Budget.php create mode 100644 app/Template/budget/create.php create mode 100644 app/Template/budget/index.php create mode 100644 app/Template/budget/remove.php (limited to 'app') diff --git a/app/Controller/Budget.php b/app/Controller/Budget.php new file mode 100644 index 00000000..01090550 --- /dev/null +++ b/app/Controller/Budget.php @@ -0,0 +1,111 @@ +getProject(); + + $this->response->html($this->projectLayout('budget/index', array( + 'total' => $this->budget->getTotal($project['id']), + 'project' => $project, + 'title' => t('Budget') + ))); + } + + /** + * Create budget lines + * + * @access public + */ + public function create(array $values = array(), array $errors = array()) + { + $project = $this->getProject(); + + if (empty($values)) { + $values['date'] = date('Y-m-d'); + } + + $this->response->html($this->projectLayout('budget/create', array( + 'lines' => $this->budget->getAll($project['id']), + 'values' => $values + array('project_id' => $project['id']), + 'errors' => $errors, + 'project' => $project, + 'title' => t('Budget') + ))); + } + + /** + * Validate and save a new budget + * + * @access public + */ + public function save() + { + $project = $this->getProject(); + + $values = $this->request->getValues(); + list($valid, $errors) = $this->budget->validateCreation($values); + + if ($valid) { + + if ($this->budget->create($values['project_id'], $values['amount'], $values['comment'], $values['date'])) { + $this->session->flash(t('The budget line have been created successfully.')); + $this->response->redirect($this->helper->url('budget', 'create', array('project_id' => $project['id']))); + } + else { + $this->session->flashError(t('Unable to create the budget line.')); + } + } + + $this->create($values, $errors); + } + + /** + * Confirmation dialog before removing a budget + * + * @access public + */ + public function confirm() + { + $project = $this->getProject(); + + $this->response->html($this->projectLayout('budget/remove', array( + 'project' => $project, + 'budget_id' => $this->request->getIntegerParam('budget_id'), + 'title' => t('Remove a budget line'), + ))); + } + + /** + * Remove a budget + * + * @access public + */ + public function remove() + { + $this->checkCSRFParam(); + $project = $this->getProject(); + + if ($this->budget->remove($this->request->getIntegerParam('budget_id'))) { + $this->session->flash(t('Budget line removed successfully.')); + } else { + $this->session->flashError(t('Unable to remove this budget line.')); + } + + $this->response->redirect($this->helper->url('budget', 'create', array('project_id' => $project['id']))); + } +} diff --git a/app/Model/Acl.php b/app/Model/Acl.php index 56938f9d..b52a7864 100644 --- a/app/Model/Acl.php +++ b/app/Model/Acl.php @@ -56,6 +56,7 @@ class Acl extends Base 'export' => array('tasks', 'subtasks', 'summary'), 'project' => array('edit', 'update', 'share', 'integration', 'users', 'alloweverybody', 'allow', 'setowner', 'revoke', 'duplicate', 'disable', 'enable'), 'swimlane' => '*', + 'budget' => '*', ); /** diff --git a/app/Model/Base.php b/app/Model/Base.php index f836231c..8a90e286 100644 --- a/app/Model/Base.php +++ b/app/Model/Base.php @@ -16,6 +16,7 @@ use Pimple\Container; * @property \Model\Action $action * @property \Model\Authentication $authentication * @property \Model\Board $board + * @property \Model\Budget $budget * @property \Model\Category $category * @property \Model\Comment $comment * @property \Model\CommentHistory $commentHistory diff --git a/app/Model/Budget.php b/app/Model/Budget.php new file mode 100644 index 00000000..03a90f7f --- /dev/null +++ b/app/Model/Budget.php @@ -0,0 +1,101 @@ +db->table(self::TABLE)->eq('project_id', $project_id)->desc('date')->findAll(); + } + + /** + * Get the current total of the budget + * + * @access public + * @param integer $project_id + * @return float + */ + public function getTotal($project_id) + { + $result = $this->db->table(self::TABLE)->columns('SUM(amount) as total')->eq('project_id', $project_id)->findOne(); + return isset($result['total']) ? (float) $result['total'] : 0; + } + + /** + * Add a new budget line in the database + * + * @access public + * @param integer $project_id + * @param float $amount + * @param string $comment + * @param string $date + * @return boolean|integer + */ + public function create($project_id, $amount, $comment, $date = '') + { + $values = array( + 'project_id' => $project_id, + 'amount' => $amount, + 'comment' => $comment, + 'date' => $date ?: date('Y-m-d'), + ); + + return $this->persist(self::TABLE, $values); + } + + /** + * Remove a specific budget line + * + * @access public + * @param integer $budget_id + * @return boolean + */ + public function remove($budget_id) + { + return $this->db->table(self::TABLE)->eq('id', $budget_id)->remove(); + } + + /** + * Validate creation + * + * @access public + * @param array $values Form values + * @return array $valid, $errors [0] = Success or not, [1] = List of errors + */ + public function validateCreation(array $values) + { + $v = new Validator($values, array( + new Validators\Required('project_id', t('Field required')), + new Validators\Required('amount', t('Field required')), + )); + + return array( + $v->execute(), + $v->getErrors() + ); + } +} \ No newline at end of file diff --git a/app/Schema/Mysql.php b/app/Schema/Mysql.php index 44ca7fd4..03868748 100644 --- a/app/Schema/Mysql.php +++ b/app/Schema/Mysql.php @@ -6,7 +6,20 @@ use PDO; use Core\Security; use Model\Link; -const VERSION = 51; +const VERSION = 52; + +function version_52($pdo) +{ + $pdo->exec('CREATE TABLE budget_lines ( + `id` INT NOT NULL AUTO_INCREMENT, + `project_id` INT NOT NULL, + `amount` FLOAT NOT NULL, + `date` VARCHAR(10) NOT NULL, + `comment` TEXT, + FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, + PRIMARY KEY(id) + ) ENGINE=InnoDB CHARSET=utf8'); +} function version_51($pdo) { diff --git a/app/Schema/Postgres.php b/app/Schema/Postgres.php index fe01b1e9..124aec76 100644 --- a/app/Schema/Postgres.php +++ b/app/Schema/Postgres.php @@ -6,7 +6,19 @@ use PDO; use Core\Security; use Model\Link; -const VERSION = 32; +const VERSION = 33; + +function version_33($pdo) +{ + $pdo->exec('CREATE TABLE budget_lines ( + "id" SERIAL PRIMARY KEY, + "project_id" INTEGER NOT NULL, + "amount" REAL NOT NULL, + "date" VARCHAR(10) NOT NULL, + "comment" TEXT, + FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE + )'); +} function version_32($pdo) { diff --git a/app/Schema/Sqlite.php b/app/Schema/Sqlite.php index eaa5c734..818ed78d 100644 --- a/app/Schema/Sqlite.php +++ b/app/Schema/Sqlite.php @@ -6,7 +6,19 @@ use Core\Security; use PDO; use Model\Link; -const VERSION = 50; +const VERSION = 51; + +function version_51($pdo) +{ + $pdo->exec('CREATE TABLE budget_lines ( + "id" INTEGER PRIMARY KEY, + "project_id" INTEGER NOT NULL, + "amount" REAL NOT NULL, + "date" TEXT NOT NULL, + "comment" TEXT, + FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE + )'); +} function version_50($pdo) { diff --git a/app/ServiceProvider/ClassProvider.php b/app/ServiceProvider/ClassProvider.php index a94bb745..6f597a5c 100644 --- a/app/ServiceProvider/ClassProvider.php +++ b/app/ServiceProvider/ClassProvider.php @@ -17,6 +17,7 @@ class ClassProvider implements ServiceProviderInterface 'Action', 'Authentication', 'Board', + 'Budget', 'Category', 'Color', 'Comment', diff --git a/app/Template/budget/create.php b/app/Template/budget/create.php new file mode 100644 index 00000000..0ff395c9 --- /dev/null +++ b/app/Template/budget/create.php @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + +
e($line['date']) ?>e($line['comment']) ?> + a(t('Remove'), 'budget', 'confirm', array('project_id' => $project['id'], 'budget_id' => $line['id'])) ?> +
+ +

+ + +
+ + formCsrf() ?> + + formHidden('id', $values) ?> + formHidden('project_id', $values) ?> + + formLabel(t('Amount'), 'amount') ?> + formText('amount', $values, $errors, array('required'), 'form-numeric') ?> + + formLabel(t('Date'), 'date') ?> + formText('date', $values, $errors, array('required'), 'form-date') ?> + + formLabel(t('Comment'), 'comment') ?> + formText('comment', $values, $errors) ?> + +
+ +
+
\ No newline at end of file diff --git a/app/Template/budget/index.php b/app/Template/budget/index.php new file mode 100644 index 00000000..8bdf1a57 --- /dev/null +++ b/app/Template/budget/index.php @@ -0,0 +1,9 @@ + + +

diff --git a/app/Template/budget/remove.php b/app/Template/budget/remove.php new file mode 100644 index 00000000..97f9c3dc --- /dev/null +++ b/app/Template/budget/remove.php @@ -0,0 +1,13 @@ + + +
+

+ +
+ a(t('Yes'), 'budget', 'remove', array('project_id' => $project['id'], 'budget_id' => $budget_id), true, 'btn btn-red') ?> + + a(t('cancel'), 'budget', 'create', array('project_id' => $project['id'])) ?> +
+
\ No newline at end of file diff --git a/app/Template/project/sidebar.php b/app/Template/project/sidebar.php index f4809fde..4afc8ba9 100644 --- a/app/Template/project/sidebar.php +++ b/app/Template/project/sidebar.php @@ -33,7 +33,10 @@ a(t('Automatic actions'), 'action', 'index', array('project_id' => $project['id'])) ?>
  • - a(t('Duplicate'), 'project', 'duplicate', array('project_id' => $project['id']), true) ?> + a(t('Duplicate'), 'project', 'duplicate', array('project_id' => $project['id'])) ?> +
  • +
  • + a(t('Budget'), 'budget', 'index', array('project_id' => $project['id'])) ?>
  • -- cgit v1.2.3