Design improvements
This commit is contained in:
parent
17871b984c
commit
51f3aa1491
17
TODO
17
TODO
@ -3,9 +3,10 @@
|
||||
|
||||
inc/Invoices.class.php :
|
||||
========================
|
||||
* Better way to store users in ? => reprendre cette partie
|
||||
* Modify store() method to handle storage
|
||||
* Modify load() method to handle JOIN
|
||||
* Modify load() method to handle complex queries (such as WHERE date < DATE_1 AND date > DATE_2)
|
||||
* Buyer as user object ?
|
||||
* Cache
|
||||
|
||||
Manage paybacks :
|
||||
=================
|
||||
@ -13,16 +14,14 @@ Manage paybacks :
|
||||
|
||||
TODO :
|
||||
======
|
||||
* Colgroups + CSS hover
|
||||
* Add / Edit a bill
|
||||
* Bug in connection form
|
||||
* JSON output
|
||||
|
||||
Tests :
|
||||
=======
|
||||
* Remember me ?
|
||||
|
||||
Tests passed (quick tests) :
|
||||
============================
|
||||
To test :
|
||||
=========
|
||||
* Connection form
|
||||
* Remember me ?
|
||||
* Edit notice
|
||||
* Add / Edit user
|
||||
* Change password
|
||||
|
@ -1,36 +1,45 @@
|
||||
<?php
|
||||
// TODO : Users in
|
||||
// TODO : date format
|
||||
|
||||
require_once('data/config.php');
|
||||
require_once('Storage.class.php');
|
||||
|
||||
class Invoice extends Storage {
|
||||
protected $id = 0, $date, $users_in, $buyer, $amount, $what;
|
||||
protected $id = 0, $date, $users_in, $guests, $buyer, $amount, $what;
|
||||
// users_in is an array of user ids
|
||||
// date is a DateTime object
|
||||
// buyer is a User object
|
||||
// guests is an array with same keys as users_in
|
||||
protected $TABLE_NAME = "Invoices";
|
||||
protected $fields = array(
|
||||
'id'=>'key',
|
||||
'date'=>'date',
|
||||
'users_in'=>'string',
|
||||
'users_in'=>'string', // TODO
|
||||
'buyer'=>'int',
|
||||
'amount'=>'float',
|
||||
'what'=>'text'
|
||||
);
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
// Getters
|
||||
// =======
|
||||
public function getId() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getDate() {
|
||||
return $this->date;
|
||||
public function getDate($format = "d-m-Y H:i") {
|
||||
return $this->date->format($format);
|
||||
}
|
||||
|
||||
public function getUsersIn() {
|
||||
return $this->users_in;
|
||||
}
|
||||
|
||||
public function getGuests() {
|
||||
return $this->guests;
|
||||
}
|
||||
|
||||
public function getBuyer() {
|
||||
return $this->buyer;
|
||||
}
|
||||
@ -49,17 +58,20 @@
|
||||
$this->id = (int) $id;
|
||||
}
|
||||
|
||||
public function setDate($date_day, $date_month, $date_year) {
|
||||
if((int) $date_day < 10) $date_day = "0".(int) $date_day;
|
||||
if((int) $date_month < 10) $date_month = "0".(int) $date_month;
|
||||
public function setDate($minute, $hour, $day, $month, $year) {
|
||||
if((int) $minute < 10) $minute = '0'.$minute;
|
||||
|
||||
$this->date = $date_year.$date_month.$date_day;
|
||||
$this->date = DateTime::createFromFormat('Y-n-j G:i', $year.'-'.(int) $month.'-'.(int) $day.' '.(int) $hour.':'.$minute);
|
||||
}
|
||||
|
||||
public function setUsersIn($users_in) {
|
||||
$this->users_in = $users_in;
|
||||
}
|
||||
|
||||
public function setGuests($guests) {
|
||||
$this->guests = $guests;
|
||||
}
|
||||
|
||||
public function setBuyer($buyer) {
|
||||
$this->buyer = (int) $buyer;
|
||||
}
|
||||
|
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
require_once('data/config.php');
|
||||
require_once('Storage.class.php');
|
||||
|
||||
class Payback extends Storage {
|
||||
protected $id = 0, $invoice_id, $amount, $from, $to;
|
||||
protected $TABLE_NAME = "Paybacks";
|
||||
protected $fields = array(
|
||||
'id'=>'key',
|
||||
'invoice_id'=>'int',
|
||||
'amount'=>'float',
|
||||
'from'=>'int',
|
||||
'to'=>'int'
|
||||
);
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
// Getters
|
||||
// =======
|
||||
|
||||
public function getId() {
|
||||
return (int) $this->id;
|
||||
}
|
||||
|
||||
public function getInvoice() {
|
||||
return (int) $this->invoice_id;
|
||||
}
|
||||
|
||||
public function getAmount() {
|
||||
return (float) $this->amount;
|
||||
}
|
||||
|
||||
public function getFrom() {
|
||||
return (int) $this->from;
|
||||
}
|
||||
|
||||
public function getTo() {
|
||||
return (int) $this->to;
|
||||
}
|
||||
|
||||
// Setters
|
||||
// =======
|
||||
|
||||
public function setId($id) {
|
||||
$this->id = (int) $id;
|
||||
}
|
||||
|
||||
public function setInvoice($invoice_id) {
|
||||
$this->invoice_id = (int) $invoice_id;
|
||||
}
|
||||
|
||||
public function setAmount($amount) {
|
||||
$this->amount = (float) $amount;
|
||||
}
|
||||
|
||||
public function setFrom($from) {
|
||||
$this->from = (int) $from;
|
||||
}
|
||||
|
||||
public function setTo($to) {
|
||||
$this->to = (int) $to;
|
||||
}
|
||||
|
||||
// Restores object from array
|
||||
// ==========================
|
||||
|
||||
public function sessionRestore($data, $serialized = false) {
|
||||
if($serialized)
|
||||
$data = unserialize($data);
|
||||
|
||||
$this->setId($data['id']);
|
||||
$this->setInvoice($data['invoice_id']);
|
||||
$this->setAmount($data['amount']);
|
||||
$this->setFrom($data['from']);
|
||||
$this->setTo($data['to']);
|
||||
}
|
||||
|
||||
// Maps htmlspecialchars on the class before display
|
||||
// =================================================
|
||||
|
||||
public function secureDisplay() {
|
||||
$this->id = (int) $this->id;
|
||||
$this->invoice_id = (int) $this->invoice_id;
|
||||
$this->amount = (float) $this->amount;
|
||||
$this->from = (int) $this->from;
|
||||
$this->to = (int) $this->to;
|
||||
}
|
||||
}
|
@ -64,11 +64,18 @@ class Storage {
|
||||
public function typeToSQL($type) {
|
||||
$return = false;
|
||||
switch($type) {
|
||||
case 'key':
|
||||
case 'int':
|
||||
$return = 'INT(11)';
|
||||
break;
|
||||
|
||||
case 'key':
|
||||
$return = 'INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY';
|
||||
break;
|
||||
|
||||
case 'float':
|
||||
$return = 'FLOAT';
|
||||
break;
|
||||
|
||||
case 'string':
|
||||
$return = 'VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci';
|
||||
break;
|
||||
@ -117,6 +124,9 @@ class Storage {
|
||||
|
||||
if(!empty($fields) && is_array($fields)) {
|
||||
foreach($fields as $field=>$value) {
|
||||
if($fields[$field] == 'date')
|
||||
$value = $value->format('Y-m-d H:i:s');
|
||||
|
||||
$query->bindParam(':'.$field, $value);
|
||||
}
|
||||
}
|
||||
@ -191,6 +201,9 @@ class Storage {
|
||||
|
||||
foreach($this->fields as $field=>$type) {
|
||||
if(isset($this->$field)) {
|
||||
if($fields[$field] == 'date')
|
||||
$value = $value->format('Y-m-d H:i:s');
|
||||
|
||||
$query->bindParam(':'.$field, $this->$field);
|
||||
}
|
||||
}
|
||||
@ -218,6 +231,9 @@ class Storage {
|
||||
|
||||
foreach($this->fields as $field=>$type) {
|
||||
if(!empty($this->$field)) {
|
||||
if($fields[$field] == 'date')
|
||||
$value = $value->format('Y-m-d H:i:s');
|
||||
|
||||
$query->bindParam(':'.$field, $this->$field);
|
||||
}
|
||||
}
|
||||
|
@ -37,3 +37,17 @@
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
function ampm2int($date) {
|
||||
if($date == 'am')
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
function int2ampm($hour) {
|
||||
if($hour == 0)
|
||||
return 6;
|
||||
else
|
||||
return 18;
|
||||
}
|
||||
|
57
index.php
57
index.php
@ -278,11 +278,12 @@
|
||||
case 'edit_invoice':
|
||||
if(!empty($_GET['id'])) {
|
||||
$invoice = new Invoice();
|
||||
$invoice->load(array('id'=>(int) $_GET['id']), true);
|
||||
$invoice = $invoice->load(array('id'=>(int) $_GET['id']), true);
|
||||
|
||||
$date_day = '';
|
||||
$date_month = '';
|
||||
$date_year = '';
|
||||
$date_hour = $invoice->getDate('a');
|
||||
$date_day = $invoice->getDate('d');
|
||||
$date_month = $invoice->getDate('m');
|
||||
$date_year = $invoice->getDate('Y');
|
||||
$amount = $invoice->getAmount();
|
||||
$what = $invoice->getWhat();
|
||||
$users_in = explode(',', $invoice->getUsersIn());
|
||||
@ -296,30 +297,35 @@
|
||||
if(!empty($_POST['date_year'])) $date_year = $_POST['date_year'];
|
||||
if(!empty($_POST['users_in'])) $users_in = $_POST['users_in'];
|
||||
|
||||
if(!empty($_POST['what']) && !empty($_POST['amount']) && (float) $_POST['amount'] != 0 && !empty($_POST['date_day']) && !empty($_POST['date_month']) && !empty($_POST['date_year']) && !empty($_POST['users_in'])) {
|
||||
if(!empty($_POST['what']) && !empty($_POST['amount']) && (float) $_POST['amount'] != 0 && !empty($_POST['date_hour']) && !empty($_POST['date_day']) && !empty($_POST['date_month']) && !empty($_POST['date_year']) && !empty($_POST['users_in'])) {
|
||||
if(check_token(600, 'new_invoice')) {
|
||||
$invoice = new Invoice();
|
||||
|
||||
if(!empty($_POST['id']))
|
||||
$invoice->setId($_POST['id']);
|
||||
|
||||
$invoice->setWhat($_POST['what']);
|
||||
$invoice->setAmount($_POST['amount']);
|
||||
$invoice->setBuyer($current_user->getId());
|
||||
$invoice->setDate($date_day, $date_month, $date_year);
|
||||
|
||||
$users_in = '';
|
||||
$guests = array();
|
||||
foreach($_POST['users_in'] as $user) {
|
||||
$users_in .= ($users_in != '') ? ', ' : '';
|
||||
$users_in .= $user.'('.(!empty($_POST['guest_user_'.$user]) ? (int) $_POST['guest_user_'.$user] : '0').')';
|
||||
$guests[$user] = (int) $_POST['guest_user_'.$user];
|
||||
if($_POST['amount'] <= 0) {
|
||||
$tpl->assign('error', 'Negative amount.');
|
||||
}
|
||||
$invoice->setUsersIn($users_in);
|
||||
else {
|
||||
$invoice = new Invoice();
|
||||
|
||||
$invoice->save();
|
||||
header('location: index.php');
|
||||
exit();
|
||||
if(!empty($_POST['id']))
|
||||
$invoice->setId($_POST['id']);
|
||||
|
||||
$invoice->setWhat($_POST['what']);
|
||||
$invoice->setAmount($_POST['amount']);
|
||||
$invoice->setBuyer($current_user);
|
||||
$invoice->setDate(0, int2ampm($_POST['date_hour']), $_POST['date_day'], $_POST['date_month'], $_POST['date_year']);
|
||||
|
||||
$users_in = array();
|
||||
$guests = array();
|
||||
foreach($_POST['users_in'] as $user) {
|
||||
$users_in[] = (int) $user;
|
||||
$guests[] = (int) $_POST['guest_user_'.$user];
|
||||
}
|
||||
$invoice->setUsersIn($users_in);
|
||||
$invoice->setGuests($guests);
|
||||
|
||||
$invoice->save();
|
||||
header('location: index.php');
|
||||
exit();
|
||||
}
|
||||
}
|
||||
else {
|
||||
$tpl->assign('error', 'Token error. Please resubmit the form.');
|
||||
@ -333,6 +339,7 @@
|
||||
$tpl->assign('months', range(1, 12));
|
||||
$tpl->assign('years', range(date('Y') - 1, date('Y') + 1));
|
||||
|
||||
$tpl->assign('hour_post', (!empty($date_hour) ? (int) ampm2int($date_hour) : (int) ampm2int(date('a'))));
|
||||
$tpl->assign('day_post', (!empty($date_day) ? (int) $date_day : (int) date('d')));
|
||||
$tpl->assign('month_post', (!empty($date_month) ? (int) $date_month : (int) date('m')));
|
||||
$tpl->assign('year_post', (!empty($date_year) ? (int) $date_year : (int) date('Y')));
|
||||
|
@ -12,10 +12,16 @@ table {
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
max-width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table td, table th {
|
||||
padding: 0.5em;
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
table th {
|
||||
background-color: #DDD;
|
||||
}
|
||||
|
||||
h2 {
|
||||
@ -88,9 +94,13 @@ input[type=submit] {
|
||||
text-align: center
|
||||
}
|
||||
|
||||
#edit_password_form, #edit_user_form, #invoice_form {
|
||||
width: 50%;
|
||||
margin-left: 15%;
|
||||
#edit_password_form, #edit_user_form, #invoice_form, #notice_form {
|
||||
width: 67%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
#edit_password_form p, #edit_user_form p, #notice_form p {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#edit_user_admin_rights {
|
||||
@ -98,13 +108,25 @@ input[type=submit] {
|
||||
}
|
||||
|
||||
#textarea_notice {
|
||||
width: 50%;
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
textarea#what {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
#list_expenses tr:hover {
|
||||
background-color: #00bd00;
|
||||
}
|
||||
|
||||
#balance_table tr:not(:first-child):hover * {
|
||||
background-color: #00bd00;
|
||||
}
|
||||
|
||||
.highlight_td {
|
||||
background-color: #00bd00;
|
||||
}
|
||||
|
||||
#install {
|
||||
margin: 0;
|
||||
}
|
||||
|
@ -6,8 +6,8 @@
|
||||
|
||||
{if condition="$view == 'list_users'"}
|
||||
<h2>List of users</h2>
|
||||
<p>You can also <a href="?do=add_user">add a user</a>.</p>
|
||||
<table>
|
||||
<p class="center">You can also <a href="?do=add_user">add a user</a>.</p>
|
||||
<table id="edit_users">
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Login</th>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<script type="text/javascript" src="js/main.js"></script>
|
||||
<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
|
||||
<script type="text/javascript" src="js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<div id="quick_summary">
|
||||
<h2>Balance</h2>
|
||||
<p class="center">Read <em>line</em> owes <em>case</em> {$currency} to <em>column</em>. You can click on links to confirm the payback.
|
||||
<table>
|
||||
<table id="balance_table">
|
||||
<tr>
|
||||
<th>Owes\To</th>
|
||||
{loop="users"}
|
||||
@ -27,7 +27,7 @@
|
||||
<div id="detailed_summary">
|
||||
<h2>Detailed list of bills for last month</h2>
|
||||
|
||||
<table>
|
||||
<table id="list_expenses">
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Paid by</th>
|
||||
@ -40,7 +40,7 @@
|
||||
{loop="invoices"}
|
||||
<tr>
|
||||
<td>{$value->getDate()}</td>
|
||||
<td>{$value->getBuyer()}</td>
|
||||
<td>{$value->getBuyer()->getDisplayName()}</td>
|
||||
<td>{$value->getUsersIn()}</td>
|
||||
<td>{$value->getAmount()}</td>
|
||||
<td>{$value->getWhat()}</td>
|
||||
|
@ -38,3 +38,23 @@ function toggle_password(id) {
|
||||
else
|
||||
document.getElementById(id).type = 'password';
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$('#balance_table td').hover(function() {
|
||||
$(this).closest('tr').find('td,th').addClass('highlight_td');
|
||||
var col = $(this).index()+1;
|
||||
$(this).closest('table').find('tr :nth-child('+col+')').addClass('highlight_td');
|
||||
}, function() {
|
||||
$(this).closest('tr').find('td,th').removeClass('highlight_td');
|
||||
var col = $(this).index()+1;
|
||||
$(this).closest('table').find('tr :nth-child('+col+')').removeClass('highlight_td');
|
||||
});
|
||||
|
||||
$('#balance_table tr:first-child th:not(:first-child)').hover(function() {
|
||||
var col = $(this).index()+1;
|
||||
$(this).closest('table').find('tr :nth-child('+col+')').addClass('highlight_td');
|
||||
}, function() {
|
||||
var col = $(this).index()+1;
|
||||
$(this).closest('table').find('tr :nth-child('+col+')').removeClass('highlight_td');
|
||||
});
|
||||
});
|
||||
|
@ -7,39 +7,46 @@
|
||||
<h2>Add a bill</h2>
|
||||
|
||||
<form method="post" action="index.php?do=new_invoice" id="invoice_form">
|
||||
<p>
|
||||
<label for="what">What ? </label>
|
||||
</p>
|
||||
<textarea name="what" id="what" rows="10">{$what_post}</textarea>
|
||||
<p>
|
||||
<label for="amount">Amount : </label>
|
||||
<input type="text" name="amount" id="amount" {if condition="$amount_post != 0"} value="{$amount_post}" {/if} size="5"/> {$currency}
|
||||
</p>
|
||||
<p>
|
||||
<label for="date_day">Date : </label>
|
||||
<select name="date_day" id="date_day">
|
||||
{loop="days"}
|
||||
<option value="{$value}" {if condition="$value == $day_post"}selected{/if}>{$value}</option>
|
||||
{/loop}
|
||||
</select> /
|
||||
<select name="date_month" id="date_month" onchange="set_days_month_year();">
|
||||
{loop="months"}
|
||||
<option value="{$value}" {if condition="$value == $month_post"}selected{/if}>{$value}</option>
|
||||
{/loop}
|
||||
</select> /
|
||||
<select name="date_year" id="date_year" onchange="set_days_month_year();">
|
||||
{loop="years"}
|
||||
<option value="{$value}" {if condition="$value == $year_post"}selected{/if}>{$value}</option>
|
||||
{/loop}
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
Users in ?
|
||||
<fieldset>
|
||||
<legend>Expense</legend>
|
||||
<p>
|
||||
<label for="what">What ? </label>
|
||||
</p>
|
||||
<textarea name="what" id="what" rows="10">{$what_post}</textarea>
|
||||
<p>
|
||||
<label for="amount">Amount : </label>
|
||||
<input type="text" name="amount" id="amount" {if condition="$amount_post != 0"} value="{$amount_post}" {/if} size="5"/> {$currency}
|
||||
</p>
|
||||
<p>
|
||||
<label for="date_day">Date : </label>
|
||||
<select name="date_day" id="date_day">
|
||||
{loop="days"}
|
||||
<option value="{$value}" {if condition="$value == $day_post"}selected{/if}>{$value}</option>
|
||||
{/loop}
|
||||
</select> /
|
||||
<select name="date_month" id="date_month" onchange="set_days_month_year();">
|
||||
{loop="months"}
|
||||
<option value="{$value}" {if condition="$value == $month_post"}selected{/if}>{$value}</option>
|
||||
{/loop}
|
||||
</select> /
|
||||
<select name="date_year" id="date_year" onchange="set_days_month_year();">
|
||||
{loop="years"}
|
||||
<option value="{$value}" {if condition="$value == $year_post"}selected{/if}>{$value}</option>
|
||||
{/loop}
|
||||
</select>
|
||||
<select name="date_hour" id="date_hour">
|
||||
<option value="0" {if condition="$hour_post == 0"}selected{/if}>AM</option>
|
||||
<option value="1" {if condition="$hour_post == 1"}selected{/if}>PM</option>
|
||||
</select>
|
||||
</p>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Users in ?</legend>
|
||||
{loop="users"}
|
||||
<br/><input type="checkbox" name="users_in[]" value="{$value->getId()}" id="users_in_{$value->getId()}" {if condition="$current_user->getId() == $value->getId() || in_array($value->getId(), $users_in)"} checked {/if}/> <label for="users_in_{$value->getId()}">{$value->getDisplayName()}</label> and <input type="text" name="guest_user_{$value->getId()}" id="guest_user_{$value->getId()}" size="1" {if condition="in_array($value->getId(), $users_in)"} value="{$guests[$value->getId()]}" {else} value="0" {/if} onkeyup="guest_user_label({$value->getId()});"/><label for="guest_user_{$value->getId()}" id="guest_user_{$value->getId()}_label"> guest</label>.
|
||||
{/loop}
|
||||
</p>
|
||||
<p>
|
||||
</fieldset>
|
||||
<p class="center">
|
||||
<input type="submit" value="Add"/>
|
||||
{if condition="$id != 0"}<input type="hidden" name="id" value="{$id}"/>{/if}
|
||||
<input type="hidden" name="token" value="{$token}"/>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<textarea name="notice" rows="15" id="textarea_notice">{$notice}</textarea>
|
||||
</p>
|
||||
<p><em>Note :</em> You can use HTML formatting in this form.</p>
|
||||
<p>
|
||||
<p class="center">
|
||||
<input type="submit" value="Submit"/>
|
||||
<input type="hidden" name="token" value="{$token}"/>
|
||||
</p>
|
||||
|
Loading…
Reference in New Issue
Block a user