Start to develop the budget module
This commit is contained in:
111
app/Controller/Budget.php
Normal file
111
app/Controller/Budget.php
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Controller;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Budget
|
||||||
|
*
|
||||||
|
* @package controller
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class Budget extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Budget index page
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$project = $this->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'])));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -56,6 +56,7 @@ class Acl extends Base
|
|||||||
'export' => array('tasks', 'subtasks', 'summary'),
|
'export' => array('tasks', 'subtasks', 'summary'),
|
||||||
'project' => array('edit', 'update', 'share', 'integration', 'users', 'alloweverybody', 'allow', 'setowner', 'revoke', 'duplicate', 'disable', 'enable'),
|
'project' => array('edit', 'update', 'share', 'integration', 'users', 'alloweverybody', 'allow', 'setowner', 'revoke', 'duplicate', 'disable', 'enable'),
|
||||||
'swimlane' => '*',
|
'swimlane' => '*',
|
||||||
|
'budget' => '*',
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use Pimple\Container;
|
|||||||
* @property \Model\Action $action
|
* @property \Model\Action $action
|
||||||
* @property \Model\Authentication $authentication
|
* @property \Model\Authentication $authentication
|
||||||
* @property \Model\Board $board
|
* @property \Model\Board $board
|
||||||
|
* @property \Model\Budget $budget
|
||||||
* @property \Model\Category $category
|
* @property \Model\Category $category
|
||||||
* @property \Model\Comment $comment
|
* @property \Model\Comment $comment
|
||||||
* @property \Model\CommentHistory $commentHistory
|
* @property \Model\CommentHistory $commentHistory
|
||||||
|
|||||||
101
app/Model/Budget.php
Normal file
101
app/Model/Budget.php
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Model;
|
||||||
|
|
||||||
|
use SimpleValidator\Validator;
|
||||||
|
use SimpleValidator\Validators;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Budget
|
||||||
|
*
|
||||||
|
* @package model
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class Budget extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* SQL table name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const TABLE = 'budget_lines';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all budget lines for a project
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $project_id
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getAll($project_id)
|
||||||
|
{
|
||||||
|
return $this->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()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,20 @@ use PDO;
|
|||||||
use Core\Security;
|
use Core\Security;
|
||||||
use Model\Link;
|
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)
|
function version_51($pdo)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,19 @@ use PDO;
|
|||||||
use Core\Security;
|
use Core\Security;
|
||||||
use Model\Link;
|
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)
|
function version_32($pdo)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,19 @@ use Core\Security;
|
|||||||
use PDO;
|
use PDO;
|
||||||
use Model\Link;
|
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)
|
function version_50($pdo)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ class ClassProvider implements ServiceProviderInterface
|
|||||||
'Action',
|
'Action',
|
||||||
'Authentication',
|
'Authentication',
|
||||||
'Board',
|
'Board',
|
||||||
|
'Budget',
|
||||||
'Category',
|
'Category',
|
||||||
'Color',
|
'Color',
|
||||||
'Comment',
|
'Comment',
|
||||||
|
|||||||
51
app/Template/budget/create.php
Normal file
51
app/Template/budget/create.php
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<div class="page-header">
|
||||||
|
<h2><?= t('Budget') ?></h2>
|
||||||
|
<ul>
|
||||||
|
<li><?= $this->a(t('Budget lines'), 'budget', 'create', array('project_id' => $project['id'])) ?></li>
|
||||||
|
<li><?= $this->a(t('Burn rate'), 'budget', 'index', array('project_id' => $project['id'])) ?></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if (! empty($lines)): ?>
|
||||||
|
<table class="table-fixed table-stripped">
|
||||||
|
<tr>
|
||||||
|
<th class="column-20"><?= t('Budget line') ?></th>
|
||||||
|
<th class="column-20"><?= t('Date') ?></th>
|
||||||
|
<th><?= t('Comment') ?></th>
|
||||||
|
<th><?= t('Action') ?></th>
|
||||||
|
</tr>
|
||||||
|
<?php foreach ($lines as $line): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?= n($line['amount']) ?></td>
|
||||||
|
<td><?= $this->e($line['date']) ?></td>
|
||||||
|
<td><?= $this->e($line['comment']) ?></td>
|
||||||
|
<td>
|
||||||
|
<?= $this->a(t('Remove'), 'budget', 'confirm', array('project_id' => $project['id'], 'budget_id' => $line['id'])) ?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h3><?= t('New budget line') ?></h3>
|
||||||
|
<?php endif ?>
|
||||||
|
|
||||||
|
<form method="post" action="<?= $this->u('budget', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
|
||||||
|
|
||||||
|
<?= $this->formCsrf() ?>
|
||||||
|
|
||||||
|
<?= $this->formHidden('id', $values) ?>
|
||||||
|
<?= $this->formHidden('project_id', $values) ?>
|
||||||
|
|
||||||
|
<?= $this->formLabel(t('Amount'), 'amount') ?>
|
||||||
|
<?= $this->formText('amount', $values, $errors, array('required'), 'form-numeric') ?>
|
||||||
|
|
||||||
|
<?= $this->formLabel(t('Date'), 'date') ?>
|
||||||
|
<?= $this->formText('date', $values, $errors, array('required'), 'form-date') ?>
|
||||||
|
|
||||||
|
<?= $this->formLabel(t('Comment'), 'comment') ?>
|
||||||
|
<?= $this->formText('comment', $values, $errors) ?>
|
||||||
|
|
||||||
|
<div class="form-actions">
|
||||||
|
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
9
app/Template/budget/index.php
Normal file
9
app/Template/budget/index.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<div class="page-header">
|
||||||
|
<h2><?= t('Budget') ?></h2>
|
||||||
|
<ul>
|
||||||
|
<li><?= $this->a(t('Budget lines'), 'budget', 'create', array('project_id' => $project['id'])) ?></li>
|
||||||
|
<li><?= $this->a(t('Burn rate'), 'budget', 'index', array('project_id' => $project['id'])) ?></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p><?= t('Current budget: ') ?><strong><?= n($total) ?></strong></p>
|
||||||
13
app/Template/budget/remove.php
Normal file
13
app/Template/budget/remove.php
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<div class="page-header">
|
||||||
|
<h2><?= t('Remove budget line') ?></h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="confirm">
|
||||||
|
<p class="alert alert-info"><?= t('Do you really want to remove this budget line?') ?></p>
|
||||||
|
|
||||||
|
<div class="form-actions">
|
||||||
|
<?= $this->a(t('Yes'), 'budget', 'remove', array('project_id' => $project['id'], 'budget_id' => $budget_id), true, 'btn btn-red') ?>
|
||||||
|
<?= t('or') ?>
|
||||||
|
<?= $this->a(t('cancel'), 'budget', 'create', array('project_id' => $project['id'])) ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -33,7 +33,10 @@
|
|||||||
<?= $this->a(t('Automatic actions'), 'action', 'index', array('project_id' => $project['id'])) ?>
|
<?= $this->a(t('Automatic actions'), 'action', 'index', array('project_id' => $project['id'])) ?>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<?= $this->a(t('Duplicate'), 'project', 'duplicate', array('project_id' => $project['id']), true) ?>
|
<?= $this->a(t('Duplicate'), 'project', 'duplicate', array('project_id' => $project['id'])) ?>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<?= $this->a(t('Budget'), 'budget', 'index', array('project_id' => $project['id'])) ?>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<?php if ($project['is_active']): ?>
|
<?php if ($project['is_active']): ?>
|
||||||
|
|||||||
Reference in New Issue
Block a user