Skip to content

Commit

Permalink
Merge pull request #211 from mrf345/development
Browse files Browse the repository at this point in the history
Add ticket status and allow updating tickets through the management view.
  • Loading branch information
mrf345 authored Aug 31, 2020
2 parents 2b0e08f + c881b31 commit e493e1a
Show file tree
Hide file tree
Showing 13 changed files with 318 additions and 93 deletions.
3 changes: 3 additions & 0 deletions app/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@
DATABASE_FILE = 'data.sqlite'

PREFIXES = [p for p in list(map(lambda i: chr(i).upper(), range(97, 123)))]

TICKET_STATUSES = ['Waiting', 'Processed', 'Unattended']
TICKET_WAITING, TICKET_PROCESSED, TICKET_UNATTENDED = TICKET_STATUSES
32 changes: 28 additions & 4 deletions app/database.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from flask_login import UserMixin, current_user
from flask_sqlalchemy import BaseQuery
from sqlalchemy.sql import and_, or_
from werkzeug.security import generate_password_hash, check_password_hash
from datetime import datetime
from random import randint

from app.middleware import db
from app.constants import USER_ROLES, DEFAULT_PASSWORD, PREFIXES
from app.constants import (USER_ROLES, DEFAULT_PASSWORD, PREFIXES, TICKET_WAITING,
TICKET_PROCESSED, TICKET_UNATTENDED)

mtasks = db.Table(
'mtasks',
Expand Down Expand Up @@ -167,8 +169,28 @@ def migrate_tickets(self, from_office, to_office):

db.session.commit()


class SerialQuery(BaseQuery):
@property
def processed(self):
return self.filter_by(p=True)

@property
def unattended(self):
return self.filter_by(p=True, status=TICKET_UNATTENDED)

@property
def waiting(self):
return self.filter_by(p=False)


class Serial(db.Model, TicketsMixin, Mixin):
__tablename__ = "serials"
query_class = SerialQuery
STATUS_WAITING = TICKET_WAITING
STATUS_PROCESSED = TICKET_PROCESSED
STATUS_UNATTENDED = TICKET_UNATTENDED

id = db.Column(db.Integer, primary_key=True)
number = db.Column(db.Integer)
timestamp = db.Column(db.DateTime(), index=True, default=datetime.utcnow)
Expand All @@ -181,19 +203,20 @@ class Serial(db.Model, TicketsMixin, Mixin):
# Fix: adding pulled by feature to tickets
pulledBy = db.Column(db.Integer)
on_hold = db.Column(db.Boolean, default=False)
status = db.Column(db.String(10), default=TICKET_PROCESSED)
office_id = db.Column(db.Integer, db.ForeignKey('offices.id'))
task_id = db.Column(db.Integer, db.ForeignKey('tasks.id'))

def __init__(self, number=100, office_id=1, task_id=1,
name=None, n=False, p=False, pulledBy=0):
def __init__(self, number=100, office_id=1, task_id=1, name=None,
n=False, p=False, pulledBy=0, status=TICKET_WAITING):
self.number = number
self.office_id = office_id
self.task_id = task_id
self.name = name
self.n = n
# fixing mass use tickets multi operators conflict
self.p = p
self.pulledBy = pulledBy
self.status = status

@property
def task(self):
Expand Down Expand Up @@ -324,6 +347,7 @@ def pull(self, office_id):
self.pdt = datetime.utcnow()
self.pulledBy = getattr(current_user, 'id', None)
self.office_id = office_id
self.status = TICKET_PROCESSED

db.session.add(self)
db.session.commit()
Expand Down
11 changes: 11 additions & 0 deletions app/forms/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from app.forms.base import LocalizedForm
from app.database import Office
from app.constants import TICKET_STATUSES


class OfficeForm(LocalizedForm):
Expand Down Expand Up @@ -56,3 +57,13 @@ def __init__(self, defLang='en', *args, **kwargs):
prefix_choices.append((office.id, f'{office.prefix} {office.name}'))

self.tl.choices = prefix_choices


class ProcessedTicketForm(LocalizedForm):
printed = BooleanField('Printied ticket :',
validators=[InputRequired('')])
value = StringField('Registered ticket value :')
status = SelectField('Select ticket current status :',
coerce=str,
choices=[(s, s) for s in TICKET_STATUSES],
validators=[InputRequired('You must chose a ticket status')])
3 changes: 2 additions & 1 deletion app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ def inject_vars():
defLang=session.get('lang'), getattr=getattr, settings=Settings.get(), Serial=Serial,
checkId=lambda id, records: id in [i.id for i in records], offices=Office.query.all(),
moment_wrapper=moment_wrapper, current_path=quote(request.path, safe=''),
windows=os.name == 'nt', unix=os.name != 'nt')
windows=os.name == 'nt', unix=os.name != 'nt', next=next, it=iter,
setattr=lambda *args, **kwargs: setattr(*args, **kwargs) or '')

return app
48 changes: 43 additions & 5 deletions app/views/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
from app.middleware import db
from app.utils import ids, remove_string_noise
from app.helpers import (reject_operator, reject_no_offices, is_operator, is_office_operator,
is_common_task_operator, reject_setting, get_or_reject)
from app.forms.manage import OfficeForm, TaskForm, SearchForm
is_common_task_operator, reject_setting, get_or_reject, decode_links)
from app.forms.manage import OfficeForm, TaskForm, SearchForm, ProcessedTicketForm
from app.constants import TICKET_WAITING


manage_app = Blueprint('manage_app', __name__)
Expand Down Expand Up @@ -45,6 +46,7 @@ def all_offices():
last_ticket_office = last_ticket_pulled and data.Office.query\
.filter_by(id=last_ticket_pulled.office_id)\
.first()
tickets_form = ProcessedTicketForm()

return render_template('all_offices.html',
officesp=pagination.items,
Expand All @@ -59,7 +61,8 @@ def all_offices():
navbar='#snb1',
hash='#da2',
last_ticket_pulled=last_ticket_pulled,
last_ticket_office=last_ticket_office)
last_ticket_office=last_ticket_office,
tickets_form=tickets_form)


@manage_app.route('/offices/<int:o_id>', methods=['GET', 'POST'])
Expand All @@ -73,6 +76,7 @@ def offices(office):
return redirect(url_for('core.root'))

form = OfficeForm(current_prefix=office.prefix)
tickets_form = ProcessedTicketForm()
page = request.args.get('page', 1, type=int)
tickets = data.Serial.all_office_tickets(office.id)
last_ticket_pulled = tickets.filter_by(p=True).first()
Expand Down Expand Up @@ -112,7 +116,8 @@ def offices(office):
navbar='#snb1',
dropdown='#dropdown-lvl' + str(office.id),
hash='#t1' + str(office.id),
last_ticket_pulled=last_ticket_pulled)
last_ticket_pulled=last_ticket_pulled,
tickets_form=tickets_form)


@manage_app.route('/office_a', methods=['GET', 'POST'])
Expand Down Expand Up @@ -243,6 +248,7 @@ def task(task, ofc_id):

task = data.Task.get(task.id) # NOTE: session's lost
form = TaskForm(common=task.common)
tickets_form = ProcessedTicketForm()
page = request.args.get('page', 1, type=int)
tickets = data.Serial.all_task_tickets(ofc_id, task.id)
last_ticket_pulled = tickets.filter_by(p=True).first()
Expand Down Expand Up @@ -308,7 +314,8 @@ def task(task, ofc_id):
hash='#tt%i%i' % (ofc_id, task.id),
last_ticket_pulled=last_ticket_pulled,
edit_task=len(task.offices) == 1 or not is_operator(),
office=data.Office.get(ofc_id))
office=data.Office.get(ofc_id),
tickets_form=tickets_form)


@manage_app.route('/task_d/<int:t_id>', defaults={'ofc_id': None})
Expand Down Expand Up @@ -435,3 +442,34 @@ def task_a(office):
dropdown='#dropdown-lvl' + str(office.id),
hash='#t3' + str(office.id),
page_title='Add new task')


@manage_app.route('/serial_u/<int:ticket_id>/<redirect_to>', methods=['POST'], defaults={'o_id': None})
@manage_app.route('/serial_u/<int:ticket_id>/<redirect_to>/<int:o_id>', methods=['POST'])
@login_required
@decode_links
def serial_u(ticket_id, redirect_to, o_id=None):
''' to update ticket details '''
if is_operator() and not is_office_operator(o_id):
flash('Error: operators are not allowed to access the page ', 'danger')
return redirect(url_for('core.root'))

form = ProcessedTicketForm()
ticket = data.Serial.get(ticket_id)

if not ticket:
flash('Error: wrong entry, something went wrong', 'danger')
return redirect(redirect_to)

if form.validate_on_submit():
ticket.name = form.value.data or ''
ticket.n = not form.printed.data
ticket.status = form.status.data

if ticket.status == TICKET_WAITING:
ticket.p = False

db.session.commit()

flash('Notice: Ticket details updated successfully', 'info')
return redirect(redirect_to)
61 changes: 60 additions & 1 deletion gt_cached.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
{
"": {},
"": {
"ar": "",
"en": "",
"es": "",
"fr": "",
"it": ""
},
" Opps, a critical error has occurred, we will be ": {
"ar": "\u062d\u062f\u062b \u062e\u0637\u0623 \u0641\u0627\u062f\u062d \u0641\u064a \u062a\u0634\u063a\u064a\u0644 \u0627\u0644\u0646\u0638\u0627\u0645 , \u0633\u0646\u0643\u0648\u0646 \u0634\u0627\u0643\u0631\u064a\u0646 \u0644\u0643 \u0625\u0646 ",
"en": " Opps, a critical error has occurred, we will be ",
Expand Down Expand Up @@ -451,6 +457,13 @@
"fr": "Choisissez la taille de la police du titre:",
"it": "Scegli la dimensione del carattere del titolo:"
},
"Close": {
"ar": "\u0642\u0631\u064a\u0628",
"en": "Close",
"es": "Cerca",
"fr": "Fermer",
"it": "Vicino"
},
"Colored background": {
"ar": "\u062e\u0644\u0641\u064a\u0629 \u0645\u0644\u0648\u0646\u0629",
"en": "Colored background",
Expand Down Expand Up @@ -1642,6 +1655,16 @@
"fr": "Avis: D\u00e9sol\u00e9, aucun r\u00e9sultat correspondant n'a \u00e9t\u00e9 trouv\u00e9",
"it": "Avviso: scusa, non sono stati trovati risultati corrispondenti"
},
"Notice: Ticket details updated successfully": {
"ar": "\u0625\u0634\u0639\u0627\u0631: \u062a\u0641\u0627\u0635\u064a\u0644 \u062a\u0630\u0643\u0631\u0629 \u062a\u062c\u062f\u064a\u062f \u0628\u0646\u062c\u0627\u062d",
"en": "Notice: Ticket details updated successfully",
"es": "Aviso: Detalles del billete actualizado correctamente",
"fr": "Avis: les d\u00e9tails de billets mis \u00e0 jour avec succ\u00e8s",
"it": "Avviso: i dettagli dei biglietti aggiornati correttamente"
},
"Notice: Ticket details updated were updated.": {
"en": "Notice: Ticket details updated were updated."
},
"Notice: Ticket has been pulled ..": {
"ar": "\u0645\u0644\u0627\u062d\u0638\u0629: \u062a\u0645 \u0633\u062d\u0628 \u0627\u0644\u062a\u0630\u0643\u0631\u0629 ..",
"en": "Notice: Ticket has been pulled ..",
Expand Down Expand Up @@ -1765,6 +1788,7 @@
},
"Notice: office has been updated. ": {
"ar": "\u0625\u0634\u0639\u0627\u0631: \u062a\u0645 \u062a\u062d\u062f\u064a\u062b \u0627\u0644\u0645\u0643\u062a\u0628.",
"en": "Notice: office has been updated.",
"es": "Aviso: la oficina ha sido actualizada.",
"fr": "Avis: le bureau a \u00e9t\u00e9 mis \u00e0 jour.",
"it": "Avviso: l'ufficio \u00e8 stato aggiornato."
Expand Down Expand Up @@ -2088,6 +2112,13 @@
"fr": "Imprim\u00e9: le num\u00e9ro de ticket client unique imprim\u00e9 typique",
"it": "Stampato: il tipico numero di biglietto del cliente unico stampato"
},
"Printied ticket :": {
"ar": "\u062a\u0630\u0643\u0631\u0629 \u0627\u0644\u0645\u0637\u0628\u0648\u0639\u0629:",
"en": "Printed ticket :",
"es": "billete impreso:",
"fr": "billet imprim\u00e9:",
"it": "biglietto stampato:"
},
"Processed": {
"ar": "\u0645\u0639\u0627\u0644\u062c\u0629",
"en": "Processed",
Expand Down Expand Up @@ -2193,6 +2224,13 @@
"fr": "Enregistr\u00e9: permet au client d'enregistrer son nom et qui sera utilis\u00e9 pour se r\u00e9f\u00e9rer par, au lieu d'un ticket imprim\u00e9 typique",
"it": "Registrato: consente al cliente di registrare il suo nome e che sar\u00e0 utilizzato per fare riferimento, invece di un tipico biglietto stampato"
},
"Registered ticket value :": {
"ar": "\u0642\u064a\u0645\u0629 \u062a\u0630\u0643\u0631\u0629 \u0627\u0644\u0645\u0633\u062c\u0644\u0629:",
"en": "Registered ticket value :",
"es": "valor del boleto registrada:",
"fr": "valeur du billet enregistr\u00e9:",
"it": "valore del biglietto Registrato:"
},
"Remeber me : ": {
"ar": "\u062a\u0630\u0643\u0631\u0646\u0649 :",
"en": "Remember me :",
Expand Down Expand Up @@ -2579,6 +2617,13 @@
"fr": "S\u00e9lectionnez les bureaux auxquels ajouter la t\u00e2che commune:",
"it": "Seleziona gli uffici per aggiungere l'attivit\u00e0 comune a:"
},
"Select ticket current status :": {
"ar": "\u062d\u062f\u062f \u062a\u0630\u0643\u0631\u0629 \u0627\u0644\u0648\u0636\u0639 \u0627\u0644\u062d\u0627\u0644\u064a:",
"en": "Select ticket current status :",
"es": "Elija un billete estado actual:",
"fr": "S\u00e9lectionnez billet d'\u00e9tat actuel:",
"it": "Acquista biglietti stato attuale:"
},
"Select ticket prefix : ": {
"ar": "\u062d\u062f\u062f \u0628\u0627\u062f\u0626\u0629 \u0627\u0644\u062a\u0630\u0643\u0631\u0629:",
"en": "Select ticket prefix :",
Expand Down Expand Up @@ -3091,6 +3136,13 @@
"fr": "Type d'annonce et de notification r\u00e9p\u00e9tant:",
"it": "Tipo di annuncio e notifica che si ripetono:"
},
"Unattended": {
"ar": "\u063a\u064a\u0631 \u0627\u0644\u0645\u0631\u0627\u0642\u0628",
"en": "Unattended",
"es": "Desesperado",
"fr": "Unattended",
"it": "incustodito"
},
"Unused files": {
"ar": "\u0627\u0644\u0645\u0644\u0641\u0627\u062a \u063a\u064a\u0631 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645\u0629",
"en": "Unused files",
Expand Down Expand Up @@ -3133,6 +3185,13 @@
"fr": "Mise \u00e0 jour",
"it": "Attivit\u00e0 di aggiornamento"
},
"Update ticket": {
"ar": "\u062a\u062d\u062f\u064a\u062b \u062a\u0630\u0643\u0631\u0629",
"en": "Update ticket",
"es": "billete de actualizaci\u00f3n",
"fr": "billet de mise \u00e0 jour",
"it": "biglietto di Aggiornamento"
},
"Update user": {
"ar": "\u062a\u062d\u062f\u064a\u062b \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645",
"en": "Update user",
Expand Down
28 changes: 28 additions & 0 deletions migrations/versions/ec3035d61f8b_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""Add status column to tickets.
Revision ID: ec3035d61f8b
Revises: 0397e48c5db8
Create Date: 2020-08-30 21:04:30.936267
"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'ec3035d61f8b'
down_revision = '0397e48c5db8'
branch_labels = None
depends_on = None


def upgrade():
try:
op.add_column('serials', sa.Column('status', sa.String(length=10), nullable=True))
except Exception:
pass


def downgrade():
with op.batch_alter_table('serials') as batch:
batch.drop_column('status')
Loading

0 comments on commit e493e1a

Please sign in to comment.