#\controllers\register.py
import config, re, json, datetime
from bottle import template, route, request, redirect
from models import customerdb, bicycledb, registerdb
config.kargs['sortIndex'] = 0
@route('/register')
def displayRegister():
config.kargs['registers'] = json.dumps(registerdb.select())
return template('register', data=config.kargs)
@route('/registerForm')
def getRegisterForm():
config.kargs['bicycles'] = json.dumps(bicycledb.select())
config.kargs['customers'] = json.dumps(customerdb.select())
return template('registerform', data=config.kargs)
@route('/register', method="POST")
def insertToRegister():
brand = json.loads(request.forms.get("fbikelist"))
customer = json.loads(request.forms.get("fcustomerlist"))
bicycledb.amountMinus(brand[0])
registerdb.insert(brand[0], customer[1], brand[1], (datetime.date.today()).strftime('%Y-%m-%d'), '1990-07-30')
redirect('/register')
@route('/register/returndate/<id>/<bikeid>')
def editReturnDate(id, bikeid):
registerdb.setReturnDate((datetime.date.today()).strftime('%Y-%m-%d'), id)
bicycledb.amountPlus(bikeid)
redirect('/register')
@route('/register/delete/<id>')
def deleteRegister(id):
registerdb.delete(id)
redirect('/register')
@route("/register/<key>/<index>")
def sortCustomer(key, index):
config.kargs['registers'] = json.dumps(registerdb.sort(key))
config.kargs['sortIndex'] = index
return template('register', data=config.kargs)
@route("/search/register/<query>")
def searchCustomer(query):
config.kargs['registers'] = json.dumps(registerdb.search(query))
return template('register', data=config.kargs)
#\models\registerdb.py
import sqlite3
def insert(*register):
conn = sqlite3.connect('sqlite.db')
cursor = conn.cursor()
sql ='''CREATE TABLE IF NOT EXISTS REGISTER(
ID INT,
CUSTOMER TEXT,
BRAND TEXT,
RENTDATE DATE,
RETURNDATE DATE
)
'''
cursor.execute(sql)
cursor.execute("INSERT INTO REGISTER VALUES (?, ?, ?, ?, ?)", register)
conn.commit()
conn.close()
def select():
conn = sqlite3.connect('sqlite.db')
cursor = conn.cursor()
sql ='''CREATE TABLE IF NOT EXISTS REGISTER(
ID INT,
CUSTOMER TEXT,
BRAND TEXT,
RENTDATE DATE,
RETURNDATE DATE
)
'''
cursor.execute(sql)
cursor.execute("SELECT ROWID, * from REGISTER")
registers = cursor.fetchall()
conn.commit()
conn.close()
return registers
def setReturnDate(*args):
conn = sqlite3.connect('sqlite.db')
cursor = conn.cursor()
sql = "UPDATE REGISTER SET RETURNDATE=? WHERE ROWID=?"
cursor.execute(sql, args)
conn.commit()
conn.close()
def delete(id):
conn = sqlite3.connect('sqlite.db')
cursor = conn.cursor()
cursor.execute("DELETE FROM REGISTER WHERE ROWID=?", (id,))
conn.commit()
conn.close()
def sort(key):
conn = sqlite3.connect('sqlite.db')
cursor = conn.cursor()
cursor.execute("SELECT ROWID, * from REGISTER ORDER BY " + key)
registers = cursor.fetchall()
conn.commit()
conn.close()
return registers
def search(query):
conn = sqlite3.connect('sqlite.db')
cursor = conn.cursor()
sql = "SELECT ROWID, * from REGISTER WHERE CUSTOMER LIKE '%"+query+"%'"
sql += " OR BRAND LIKE '%"+query+"%'"
sql += " OR RENTDATE LIKE '%"+query+"%'"
sql += " OR RETURNDATE LIKE '%"+query+"%'"
cursor.execute(sql)
registers = cursor.fetchall()
conn.commit()
conn.close()
return registers
<!--\views\register.tpl-->
%include("./partials/header.tpl")
<div class="main" id="main">
<div class="content" id="content">
<div class="top-widget">
<span>REGISTERS</span><input onclick="location.href='/registerForm'" type="button" value="Add Register" />
</div>
<div class="bottom-widget">
<span>
<select id="regiskey">
<option value="Customer" >Customer</option>
<option value="Brand" >Bicycle</option>
<option value="RentDate" >Rental Date</option>
<option value="ReturnDate" >Return Date</option>
</select>
<input onclick="bicycle.sortRegister()" type="button" value="Sort" />
</span>
<span class="search">
<input id="query" type="text" /><input onclick="bicycle.searchRegister()" type="button" value="Search" />
</span>
</div>
<div id="table"></div>
<script>
$( document ).ready(function() {
bicycle.showRegister({{!data['registers']}}, {{!data['sortIndex']}});
});
</script>
</div><!--content-->
</div><!--main-->
%include("./partials/footer")
//\public\js\main.js
class Bicycle{
setActiveMenu(){
const pathName = window.location.pathname;
$("#menu a").each(function(){
if($(this).attr("href") === pathName)
$(this).parent().addClass( "active" );
});
}
bicycleForm(formId){
var brand = document.forms[formId]['fbrand'].value;
var country = document.forms[formId]['fcountry'].value;
var year = document.forms[formId]['fyear'].value;
var amount = document.forms[formId]['famount'].value;
var price = document.forms[formId]['fprice'].value;
if((brand == "") || (country == "") || (year == "") || (amount == "") || (price == "")){
return false;
}else{
var numberRGEX = /^(?:[1-9]\d*|0)?(?:\.\d+)?$/;
var intRGEX = /^[0-9]+$/;
var numberResult = numberRGEX.test(price);
var intResult = (intRGEX.test(year) && intRGEX.test(amount));
if(!numberResult){
alert('Please enter a number for price.');
return false;
}
if(!intResult){
alert('Please enter a whole number for year and amount.');
return false;
}
}
}
showBicycle(bicycles,sortIndex){
var html = '';
if(bicycles.length > 0){
html += "<table>";
html += "<tr>";
for(var k in {id:0, brand:0, country:0, year:0, amount:0, price:0}){
html += "<th>" + k.toUpperCase() + "</th>";
}
html += "<th>OPTION</th>";
html += "</tr>";
for(var i=0; i<bicycles.length; i++){
html += "<tr>";
html += "<td>" + (i+1) + "</td>";
for(var j in bicycles[i]){
if(j > 0)
html += "<td>" + bicycles[i][j] + "</td>";
}
html += `<td class="option"><a href="/bikeform/edit/${bicycles[i][0]}" class="edit">Edit</a>|<a href="/bikeform/delete/${bicycles[i][0]}" class="delete" >Delete</a></td>`;
html += "</tr>";
}
html += "</table>";
}
document.getElementById("table").innerHTML = html;
document.getElementById("bikekey").selectedIndex = sortIndex;
}
sortBicycle(){
var element = document.getElementById("bikekey");
var sortIndex = element.selectedIndex;
var key = element.options[sortIndex].value;
window.location.href = "/bicycle/" + key + "/" + sortIndex;
}
searchBicycle(){
var query = $("#query").val();
location.href= "/search/bicycle/" + query;
}
customerForm(formId){
var name = document.forms[formId]['fname'].value;
var phone = document.forms[formId]['fphone'].value;
if((name == "") || (phone == "")){
alert("Please fill this form with your name and phone number!");
return false;
}else{
var phoneRegex = /^(\+\d{1,2}\s?)?1?\-?\.?\s?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/;
var numberResult = phoneRegex.test(phone);
if(!numberResult){
alert("Please fill this form with the right phone number.");
return false;
}
}
}
showCustomer(customers, sortIndex){
var html = '';
if(customers.length > 0){
html += "<table>";
html += "<tr>";
for(var k in {id:0, name:0, phone:0}){
html += "<th>" + k.toUpperCase() + "</th>";
}
html += "<th>OPTION</th>";
html += "</tr>";
for(var i=0; i<customers.length; i++){
html += "<tr>";
html += "<td>" + (i+1) + "</td>";
for(var j in customers[i]){
if(j > 0)
html += "<td>" + customers[i][j] + "</td>";
}
html += `<td class="option"><a href="/custform/edit/${customers[i][0]}" class="edit">Edit</a>|<a href="/customer/delete/${customers[i][0]}" class="delete" >Delete</a></td>`;
html += "</tr>";
}
html += "</table>";
}
document.getElementById("table").innerHTML = html;
document.getElementById("custkey").selectedIndex = sortIndex;
}
sortCustomer(){
var element = document.getElementById("custkey");
var sortIndex = element.selectedIndex;
var key = element.options[sortIndex].value;
window.location.href = "/customer/" + key + "/" + sortIndex;
}
searchCustomer(){
var query = $("#query").val();
location.href= "/search/customer/" + query;
}
registerForm(bicycles, customers){
for(var i=0; i<bicycles.length; i++){
var brand = bicycles[i][1];
var amount = bicycles[i][4];
if(amount > 0)
$('#bikelist').append(`<option value='[${bicycles[i][0]}, "${brand}"]'>${brand}</option>`);
}
for(var i=0; i<customers.length; i++){
var name = customers[i][1];
$('#customerlist').append(`<option value='[${customers[i][0]}, "${name}"]'>${name}</option>`);
}
}
showRegister(registers, sortIndex){
var html = '';
if(registers.length > 0){
html += "<table>";
html += "<tr>";
for(var k in {id:1, customer:1, bicycle:1, 'Rental Date':1, 'Return Date':1}){
html += "<th>" + k.toUpperCase() + "</th>";
}
html += "<th>OPTION</th>";
html += "</tr>";
for(var i=0; i<registers.length; i++){
html += "<tr>";
html += "<td>" + (i+1) + "</td>";
for(var j in registers[i]){
if(j > 1){
if(j == 5){
if(registers[i][j] == "1990-07-30")
html += `<td class='return-date'><a href='/register/returndate/${registers[i][0]}/${registers[i][1]}'><img src='/static/images/return.png' /></a></td>`;
else
html += "<td class='return-date'>" + registers[i][j] + "</td>";
}else{
html += "<td>" + registers[i][j] + "</td>";
}
}
}
html += `<td class="option"><a href="/register/delete/${registers[i][0]}" class="delete" >Delete</a></td>`;
html += "</tr>";
}
html += "</table>";
}
document.getElementById("table").innerHTML = html;
document.getElementById("regiskey").selectedIndex = sortIndex;
}
sortRegister(){
var element = document.getElementById("regiskey");
var sortIndex = element.selectedIndex;
var key = element.options[sortIndex].value;
window.location.href = "/register/" + key + "/" + sortIndex;
}
searchRegister(){
var query = $("#query").val();
location.href= "/search/register/" + query;
}
}//end of class
var bicycle = new Bicycle();
GitHub: https://github.com/Sokhavuth/Rental-Bicycle-App
Heroku: https://khmerweb-rba.herokuapp.com/













