Bladeren bron

added tender allocation per record

jacob-kruger-work 1 maand geleden
bovenliggende
commit
76f2e7652d

+ 23 - 1
flask_app/app/main/forms.py

@@ -61,7 +61,7 @@ class RoleDepartmentForm(FlaskForm):
 
 
 class RoleForm(FlaskForm):
-    hid_role_id = HiddenField(id="hid_qualification_id", default="0")
+    hid_role_id = HiddenField(id="hid_role_id", default="0")
     sel_department = SelectField(id="sel_departmen", label="Department", choices=[(0, "IT and Technology"), (1, "Sales and Marketing")], default=0)
     txt_role_name = StringField(id="txt_role_name", label="Role Name", validators=[InputRequired(), Length(min=3, max=128)])
     txt_description = TextAreaField(id="txt_description", label="Description", validators=[Length(min=0, max=255)], render_kw={"wrap": "hard", "rows": "5", "cols": "50"})
@@ -71,6 +71,7 @@ class RoleDepartmentRemovalForm(FlaskForm):
     hid_remove_department_id = HiddenField(id="hid_remove_department_id", default="0")
 # end of RoleDepartmentRemovalForm class
 
+
 class RoleRemovalForm(FlaskForm):
     hid_remove_role_id = HiddenField(id="hid_remove_role_id", default="0")
 # end of RoleRemovalForm class
@@ -120,3 +121,24 @@ class UserForm(FlaskForm):
 class UserRemovalForm(FlaskForm):
     hid_remove_user_id = HiddenField(id="hid_remove_user_id", default="0")
 # end of UserRemovalForm class
+
+
+class TenderForm(FlaskForm):
+    hid_tender_id = HiddenField(id="hid_tender_id", default="0")
+    txt_reference_number = StringField(id="txt_reference_number", label="Reference Number", validators=[InputRequired(), Length(min=1, max=64)])
+    txt_description = TextAreaField(id="txt_description", label="Description", validators=[Length(min=0, max=512)], render_kw={"wrap": "hard", "rows": "5", "cols": "50"})
+# end of TenderForm class
+
+
+class TenderRemovalForm(FlaskForm):
+    hid_remove_tender_id = HiddenField(id="hid_remove_tender_id", default="0")
+# end of TenderRemovalForm class
+
+
+class TenderAllocationForm(FlaskForm):
+    sel_tender = SelectField(id="sel_tender", label="Tender to be Allocated", choices=[(0, "---none---")], default=0)
+# end of TenderAllocationForm class
+
+class TenderCVRemovalForm(FlaskForm):
+    hid_tender_cv_id = HiddenField(id="hid_tender_cv_id", default="0")
+# end of TenderCVRemovalForm class

+ 136 - 7
flask_app/app/main/routes.py

@@ -10,7 +10,7 @@ from sqlalchemy import and_, or_, not_, func
 import json, requests, re, os
 from .forms import RecordForm, QualificationTypeForm, QualificationForm, QualificationTypeRemovalForm, QualificationRemovalForm, RecordQualificationForm, RecordQualificationRemovalForm
 from .forms import RoleDepartmentForm, RoleForm, RoleDepartmentRemovalForm, RoleRemovalForm, \
-    UploadForm, UploadRemovalForm, FilterForm
+    UploadForm, UploadRemovalForm, FilterForm, TenderForm, TenderRemovalForm, TenderAllocationForm, TenderCVRemovalForm
 from .forms import UserForm, UserRemovalForm
 import re
 import datetime as datetime_class
@@ -145,6 +145,7 @@ def index():
     # end of surrounding try-except
 # end of index view function for route /
 
+
 @bp.route("/icons", methods=["GET"])
 def icons():
     """icons preview - purely testing"""
@@ -177,6 +178,8 @@ def capture_record(i_record:int = 0):
                 qualification_form.sel_qualification.choices = l_choices
             # end of checking if qualifications were retrieved
         # end of checking if there are qualification types
+        tender_form = TenderAllocationForm()
+        tender_removal_form = TenderCVRemovalForm()
         if form.validate_on_submit() and request.form.get("btn_save", "")=="Save":
             s_action = "updated"
             o_record = None
@@ -258,9 +261,36 @@ def capture_record(i_record:int = 0):
                 db.session.commit()
                 flash("Qualification removed")
             # end of making sure retrieved record
-        # end of checking for form submission
+        elif tender_removal_form.validate_on_submit() and request.form.get("hid_tender_cv_id", None) is not None:
+            i_tender_cv_id = int(tender_removal_form.hid_tender_cv_id.data)
+            db.session.execute(delete(tbl_tender_cvs).where(tbl_tender_cvs.id==i_tender_cv_id))
+            db.session.commit()
+            flash("Tender allocation removed", "success")
+        # end of checking for form submission initially
+        # populate possible tender allocation choices
+        sq_tenders = select(tbl_tender_cvs.i_tender_id.distinct()).filter(tbl_tender_cvs.i_record_id==i_record)
+        l_other_tenders = list(map(dict_row, db.session.query(tbl_tenders.id, tbl_tenders.v_reference_number, tbl_tenders.v_description).filter(tbl_tenders.id.not_in(sq_tenders)).all()))
+        if len(l_other_tenders)>0:
+            l_tender_choices = []
+            for ix, d_tender in enumerate(l_other_tenders):
+                l_tender_choices.append((d_tender["id"], " - ".join((d_tender["v_reference_number"], str(d_tender["v_description"])[:20]))))
+            # end of looping through other tenders
+            tender_form.sel_tender.choices = tender_form.sel_tender.choices + l_tender_choices
+        # end of checking if need to populate tender choices for possible allocation
+        # second form submission check after cv allocation might have been updated - because am populating tender choices here b4 validation
+        if tender_form.validate_on_submit() and request.form.get("btn_allocate", "")=="Allocate":
+            i_tender_id = int(tender_form.sel_tender.data)
+            if i_tender_id>0:
+                db.session.add(tbl_tender_cvs(i_tender_id=i_tender_id, i_record_id=i_record))
+                db.session.commit()
+                flash("Tender allocated", "success")
+                # update tender allocation choices
+                tender_form.sel_tender.choices = list(filter((lambda x : x[0]!=i_tender_id), tender_form.sel_tender.choices))
+            # end of making sure actual tender record was selected
+        # end of second form submission check
         form.hid_record_id.data = i_record
         remove_qualification_form.hid_remove_qualification_id.data = 0
+        tender_form.sel_tender.data = 0
         # populate record info if existing record
         if i_record>0:
             o_record = db.session.get(tbl_records, i_record)
@@ -288,9 +318,13 @@ def capture_record(i_record:int = 0):
         l_languages = db.session.query(tbl_languages.v_language_abbreviation, tbl_languages.v_language_name, tbl_languages.si_level).filter(tbl_languages.i_record_id==i_record).order_by(tbl_languages.si_ranking).all()
         l_languages = list(map(dict_row, l_languages))
         l_record_qualifications = list(map(dict_row, db.session.query(tbl_record_qualifications.id, tbl_qualification_types.v_qualification_type, tbl_qualifications.v_qualification_name, tbl_record_qualifications.d_acquired).join(tbl_qualifications, tbl_record_qualifications.i_qualification_id==tbl_qualifications.id, isouter=False).join(tbl_qualification_types, tbl_qualifications.i_qualification_type==tbl_qualification_types.id, isouter=False).filter(tbl_record_qualifications.i_record_id==i_record).order_by(tbl_record_qualifications.d_acquired, tbl_qualifications.v_qualification_name).all()))
+        l_prior_tenders = list(map(dict_row, db.session.query(tbl_tender_cvs.id, tbl_tenders.v_reference_number, tbl_tenders.v_description, tbl_tender_cvs.dt_when).join(tbl_tenders, tbl_tenders.id==tbl_tender_cvs.i_tender_id, isouter=False).filter(tbl_tender_cvs.i_record_id==i_record).order_by(tbl_tender_cvs.dt_when.desc()).limit(3)))
+        for ix, t in enumerate(l_prior_tenders):
+            l_prior_tenders[ix]["dt_when"] = l_prior_tenders[ix]["dt_when"].strftime("%Y-%m-%d %H:%M")
+        # end of updating values in prior tenders
         s_base = "base_bs.html" if Config.BOOTSTRAP else "base.html"
         s_url = url_for("main.capture_record")#, _external=True)
-        return render_template("capture_record.html", js=True, base=s_base, url=s_url, form=form, record_id=i_record, languages=l_languages, all_languages=l_all_languages, qualification_types=l_qualification_types, qualification_form=qualification_form, record_qualifications=l_record_qualifications, departments=l_departments, roles=l_roles, department_id=i_department_id, role_id=i_role_id, remove_qualification_form=remove_qualification_form)
+        return render_template("capture_record.html", js=True, base=s_base, url=s_url, form=form, record_id=i_record, languages=l_languages, all_languages=l_all_languages, qualification_types=l_qualification_types, qualification_form=qualification_form, record_qualifications=l_record_qualifications, departments=l_departments, roles=l_roles, department_id=i_department_id, role_id=i_role_id, remove_qualification_form=remove_qualification_form, prior_tenders=l_prior_tenders, tender_form=tender_form, remove_tender_form=tender_removal_form)
     except Exception as exc:
         return render_template_string(end_user_debugging("capture_record"))
     # end of surrounding try-except
@@ -560,7 +594,7 @@ def roles():
     except Exception as exc:
         return render_template_string(end_user_debugging("roles"))
     # end of surrounding try-except
-# end of roles view function for route /positions
+# end of roles view function for route /roles
 
 
 @bp.route("/roles_list/<int:i_department_id>/", methods=["GET"])
@@ -686,6 +720,7 @@ def record_details(i_record_id):
             # end of looping through qualifications
             d_out["uploads"] = list(map(dict_row, db.session.query(tbl_uploads.id, tbl_uploads.si_upload_type, tbl_uploads.v_filename, tbl_uploads.v_description, tbl_qualifications.v_qualification_name).join(tbl_qualifications, tbl_qualifications.id==tbl_uploads.i_matching_id, isouter=True).filter(tbl_uploads.i_record_id==i_record_id).all()))
             for ix, d in enumerate(d_out["uploads"]): d["si_upload_type"] = {0: "Original CV", 1: "Alteram CV", 2: "Certificate/Diploma/Degree", 3: "I.D. Document or Passport"}[d["si_upload_type"]]
+            d_out["tenders"] = list(map(dict_row, db.session.query(tbl_tender_cvs.id, tbl_tenders.v_reference_number).join(tbl_tenders, tbl_tenders.id==tbl_tender_cvs.i_tender_id, isouter=False).filter(tbl_tender_cvs.i_record_id==i_record_id).order_by(tbl_tender_cvs.dt_when).limit(3)))
         # end of initial query length check
         return make_response(jsonify(d_out), 200)
     except Exception as exc:
@@ -789,6 +824,100 @@ def css_sample():
 # end of css_sample view function for route /css_sample
 
 
-s_todo = """
-    double-check both try-except across the board, along with then logging exceptions
-"""
+@bp.route("/tenders/", methods=["GET", "POST"])
+@login_required
+@check_admin
+def tenders():
+    """manage tenders available for assignment to records"""
+    try:
+        tender_form = TenderForm()
+        remove_tender_form = TenderRemovalForm()
+        if tender_form.validate_on_submit() and request.form.get("btn_save_tender", "")=="Save":
+            i_tender_id, s_reference_number, s_description = (int(tender_form.hid_tender_id.data), str(tender_form.txt_reference_number.data), str(tender_form.txt_description.data))
+            if i_tender_id > 0:
+                o_tender = db.session.get(tbl_tenders, i_tender_id)
+                if o_tender is not None:
+                    if db.session.query(tbl_tenders).filter(tbl_tenders.id!=i_tender_id, tbl_tenders.v_reference_number==s_reference_number).count()>0:
+                        flash("There is already another tender with the same reference number on record", "error")
+                    else:
+                        o_tender.v_reference_number = s_reference_number
+                        o_tender.v_description = s_description
+                        db.session.add(o_tender)
+                        db.session.commit()
+                        flash("Tender updated", "success")
+                    # end of making sure no other duplicates with same reference number
+                else:
+                    flash("No tender record could be retrieved", "error")
+                # end of checking if record existed
+            else:
+                if db.session.query(tbl_tenders.id).filter(tbl_tenders.v_reference_number==s_reference_number).count()<1:
+                    db.session.add(tbl_tenders(v_reference_number=s_reference_number, v_description=s_description))
+                    db.session.commit()
+                    flash("Tender inserted", "success")
+                else:
+                    flash("Atender with the same reference number has already been recorded", "error")
+                # end of making sure new tender is not a duplicate
+            # end of checking if new or existing tender record
+        elif remove_tender_form.validate_on_submit():
+            i_tender_id = int(remove_tender_form.hid_remove_tender_id.data)
+            o_tender = db.session.get(tbl_tenders, i_tender_id)
+            if o_tender is not None:
+                db.session.delete(o_tender)
+                db.session.commit()
+                db.session.execute(delete(tbl_tender_cvs).where(tbl_tender_cvs.i_tender_id==i_tender_id))
+                db.session.commit()
+                flash("Tender removed", "success")
+            # end of checking if record existed
+        # end of checking for form submission
+        tender_form.hid_tender_id.data, tender_form.txt_reference_number.data, tender_form.txt_description.data = (0, "", "")
+        remove_tender_form.hid_remove_tender_id.data = "0"
+        i_page = request.form.get("hid_page", 1, type=int)
+        q_tenders = db.session.query(tbl_tenders.id, tbl_tenders.v_reference_number, tbl_tenders.v_description).order_by(tbl_tenders.v_reference_number)
+        pagination = q_tenders.paginate(page=i_page, per_page=20)
+        l_tenders = list(map(dict_row, pagination.items))
+        s_base = "base_bs.html" if Config.BOOTSTRAP else "base.html"
+        s_url = url_for("main.tenders")#, _external=True)
+        return render_template("tenders.html", js=True, base=s_base, url=s_url, tenders=l_tenders, form=tender_form, remove_form=remove_tender_form, paging=pagination)
+    except Exception as exc:
+        return render_template_string(end_user_debugging("tenders"))
+    # end of surrounding try-except
+# end of tenders view function for route /tenders
+
+
+@bp.route("/tenders_list/", methods=["GET"])
+@login_required
+def tenders_list():
+    """return list of tender entries"""
+    try:
+        l_out = []
+        try:
+            q_tenders = db.session.query(tbl_tenders.id, tbl_tenders.v_reference_number, tbl_tenders.v_description)
+            if q_tenders.count()>0:
+                q_tenders = q_tenders.order_by(tbl_tenders.v_reference_number)
+                l_out = list(map(dict_row, q_tenders.all()))
+            # end of checking result count of query
+        except Exception as exc:
+            print(extract_exc("list roles?"))
+        # end of try-except
+        return make_response(jsonify(l_out), 200)
+    except Exception as exc:
+        return render_template_string(end_user_debugging("tenders_list"))
+    # end of surrounding try-except
+# end of tenders_list view function for route /tenders_list/
+
+
+@bp.route("/tender_details/<int:i_tender_id>/", methods=["GET"])
+@login_required
+def tender_details(i_tender_id):
+    """retrieve tender details"""
+    try:
+        d_out = {}
+        o_tender = db.session.get(tbl_tenders, i_tender_id)
+        if o_tender is not None:
+            d_out = dict_instance(o_tender)
+        # end of checking if record retrieved
+        return make_response(jsonify(d_out), 200)
+    except Exception as exc:
+        return render_template_string(end_user_debugging("tender_details"))
+    # end of surrounding try-except
+# end of tender_details view function for route /tender_details/<int:i_tender_id>/

+ 21 - 0
flask_app/app/models/cv_data.py

@@ -128,3 +128,24 @@ class tbl_roles(Base):
 
     i_department = relationship('tbl_role_departments')
 # end of tbl_roles ORM model class
+
+
+class tbl_tender_cvs(Base):
+    __tablename__ = 'tbl_tender_cvs'
+    __table_args__ = {'schema': 'cv_data'}
+
+    id = db.Column(db.Integer, primary_key=True, server_default=text("nextval('cv_data.tbl_tender_cvs_id_seq'::regclass)"))
+    i_record_id = db.Column(db.Integer, nullable=False, server_default=text("0"))
+    i_tender_id = db.Column(db.Integer, nullable=False, server_default=text("0"))
+    dt_when = db.Column(db.DateTime, nullable=False, server_default=text("CURRENT_TIMESTAMP"))
+# end of tbl_tender_cvs ORM model class
+
+
+class tbl_tenders(Base):
+    __tablename__ = 'tbl_tenders'
+    __table_args__ = {'schema': 'cv_data'}
+
+    id = db.Column(db.Integer, primary_key=True, server_default=text("nextval('cv_data.tbl_tenders_id_seq'::regclass)"))
+    v_reference_number = db.Column(db.String(64), nullable=False, server_default=text("''::character varying"))
+    v_description = db.Column(db.String(512), nullable=False, server_default=text("''::character varying"))
+# end of tbl_tenders ORM model class

+ 1 - 0
flask_app/app/templates/base.html

@@ -71,6 +71,7 @@ if (String(s_msg).length>0) {
 <li><a href="{{ url_for("main.qualifications") }}">Qualifications</a></li>
 <li><a href="{{ url_for("main.roles") }}">Positions | Roles</a></li>
 <li><a href="{{ url_for("main.users") }}">Access User Profiles</a></li>
+<li><a href="{{ url_for("main.tenders") }}">Tenders</a></li>
 {% endif %}{# end of checking for bl_admin #}
 {% if current_user.bl_capture or current_user.bl_admin %}
 <li><a href="{{ url_for("main.capture_record") }}">Capture record</a></li>

+ 32 - 1
flask_app/app/templates/capture_record.html

@@ -8,6 +8,7 @@
 <form action="{{ url_for("main.capture_record", i_record=record_id) }}" method="post" id="frm_capture">
 {{ form.csrf_token }}
 {{ form.hid_record_id }}
+<h3>Basic Details</h3>
 <div class="table-container">
 <table class="data-table">
 <tr>
@@ -81,6 +82,7 @@
 <input type="submit" name="btn_save" value="Save">
 </form>
 {% if record_id>0 %}
+<h3>Qualifications</h3>
 <div><a href="#" id="a_add_qualification">Add qualification</a></div>
 {% if record_qualifications %}
 <ul>
@@ -89,7 +91,22 @@
 {% endfor %}
 </ul>
 {% endif %}{# end of checking for existing qualification records #}
-{% endif %}{# end of checking if existing record to then  render qualifications #}
+<h3>Tender Applications</h3>
+<div>
+<form action="{{ url_for("main.capture_record", i_record=record_id) }}" method="post" id="frm_tender">
+{{ tender_form.csrf_token }}
+{{ tender_form.sel_tender.label }}&nbsp;{{ tender_form.sel_tender }}<br>
+<input type="submit" name="btn_allocate" value="Allocate">
+</form>
+</div>
+{% if prior_tenders %}
+<ul>
+{% for tender in prior_tenders %}
+<li><span style="font-weight: bold;">Reference Number:</span>&nbsp;{{ tender.v_reference_number }}&nbsp;{{ tender.dt_when }}&nbsp;<a href="#{{ tender.id }}" class="a_remove_tender">{{ icons.delete_svg(s_label="Remove tender allocation") }}</a><br><blockquote>{{ tender.v_description }}</blockquote></li>
+{% endfor %}{# end of looping through prior_tenders #}
+</ul>
+{% endif %}
+{% endif %}{# end of checking if existing record to then  render qualifications and possibly prior tender associations #}
 </div><!-- end of div.content -->
 {% from "macros/dialog.html" import dlg_prep with context %}
 {{ dlg_prep(["dlg_language", "dlg_qualification"]) }}
@@ -268,6 +285,16 @@ $(".a_remove_qualification").click( function(event) {
     }// end of confirmation check
 });// end of .a_remove_qualification click event
 
+$(".a_remove_tender").click( function(event) {
+    event.preventDefault();
+    var s_id = String($(this).attr("href")).replace("#", "");
+    var bl_confirm = confirm("Are you sure you wish to remove tender allocation from this C.V.?");
+    if (bl_confirm) {
+        $("#hid_tender_cv_id").val(s_id);
+        document.getElementById("frm_remove_tender").submit();
+    }// end of confirmation check
+});// end of .a_remove_tender click event
+
 } catch(e) {
     var s_err = String(e.name) + "\nmessage:" + String(e.message);
     s_err = (typeof(e.lineNumber)!="undefined") ? s_err + "\nline:" + String(e.lineNumber) : s_err;
@@ -280,4 +307,8 @@ $(".a_remove_qualification").click( function(event) {
 {{ remove_qualification_form.csrf_token }}
 {{remove_qualification_form.hid_remove_qualification_id }}
 </form>
+<form action="{{ url_for("main.capture_record", i_record=record_id) }}" method="post" id="frm_remove_tender">
+{{ remove_tender_form.csrf_token }}
+{{ remove_tender_form.hid_tender_cv_id }}
+</form>
 {% endblock %}

+ 22 - 2
flask_app/app/templates/index.html

@@ -156,6 +156,10 @@ font-size: smaller;
 <h4>Uploads</h4>
 <ul id="ul_uploads"></ul>
 </div>
+<span id="spn_tenders">
+<h4>Prior Tenders</h4>
+<ul id="ul_tenders"></ul>
+</span>
 </div><!-- end of dlg_details -->
 <script type="text/javascript">
 $(document).ready( function() {
@@ -258,7 +262,7 @@ try {
                 s_html = s_html + "<li><span class=\"label\">Employment Position/Role:</label>&nbsp;" + String(o_data.record["v_role_name"]) + "</li>\n";
                 $("#ul_details").append(s_html);
             }// end of typeof check against basic details
-            // qualifications
+            // languagess
             s_html = "";
             if (typeof(o_data.languages)=="object") {
             if (o_data.languages.length>0) {
@@ -271,10 +275,26 @@ try {
                 $("#ul_languages").append(s_html);
             } else {
                 $("#spn_languages").hide();
-            }// end of .length check against qualifications
+            }// end of .length check against languages
             } else {
                 $("#spn_languages").hide();
             }// end of typeof check against language data
+            // tenders
+            s_html = "";
+            if (typeof(o_data.tenders)=="object") {
+            if (o_data.tenders.length>0) {
+                $.each(o_data.tenders, function(ix, t) {
+                    s_html = s_html + "<li><span class=\"label\">Reference no.:</span>&nbsp;" + String(t.v_reference_number) + "</li>\n";
+                    s_html = s_html + "</ul>\n";
+                });// end of looping through tenders
+                $("#ul_tenders").append(s_html);
+            } else {
+                $("#spn_tenders").hide();
+            }// end of .length check against languages
+            } else {
+                $("#spn_tenders").hide();
+            }// end of typeof check against prior tender data
+            // qualifications
             if (typeof(o_data.qualifications)=="object") {
             if (o_data.qualifications.length>0) {
                 $.each(o_data.qualifications, function(ix, q) {

+ 171 - 0
flask_app/app/templates/tenders.html

@@ -0,0 +1,171 @@
+{% extends base %}
+{% block head_extra %}
+<style>
+.label {
+font-weight: bold;
+}
+div.paging {
+color: dark-blue;
+font-size: smaller;
+}
+</style>
+{% endblock %}
+
+{% block content %}
+{% import "macros/action_icons_static.html" as icons %}
+<span class="title"><h2>{% block title %}Tenders{% endblock %}</h2></span>
+<div class="content-container content">
+<div><a href="#" id="a_add_tender" aria-label="Add tender">{{ icons.add_svg }}</a></div>
+{% if tenders %}
+<h3>Tenders</h3>
+<div class="table-container">
+<table class="data-table" id="tbl_tenders">
+<thead>
+<tr>
+<th>Reference Number</th><th>Description</th><th style="font-size: smaller;">[actions]</th>
+</tr>
+</thead>
+{% for tender in tenders %}
+<tr>
+<td>{{ tender.v_reference_number }}</td><td>{{ tender.v_description }}</td>
+<td>
+<a href="#{{ tender.id }}" class="a_edit_tender">{{ icons.edit_svg() }}</a>
+<a href="#{{ tender.id }}" class="a_remove_tender">{{ icons.delete_svg() }}</a>
+</td>
+</tr>
+{% endfor %}{# end of looping through tenders #}
+</table><!-- end of tbl_tenders -->
+</div><!-- end of div.table-container -->
+<div class="paging">
+<div>Paging...</div>
+
+{#
+{% if paging.has_prev %}
+<!-- prev_num --><span><a class="a_page_number" href="#{{ paging.prev_num }}"{{ "<<" }}</a></span>
+{% endif %}
+#}
+
+{% for number in paging.iter_pages() %}
+{% if paging.page != number %}
+<!-- page_num --><span><a class="a_page_number" href="#{{ number }}">{{ number }}</a></span>&nbsp;&nbsp;
+{% else %}
+<!-- current_num --><span class="current-page-number">{{ number }}</span>&nbsp;&nbsp;
+{% endif %}
+{% endfor %}
+
+{#
+{% if paging.has_next %}
+<span>
+<!-- next_num --><a class="a_page_number" href="#{{ paging.next_num }}">{{ ">>" }}</a></span>
+{% endif %}
+#}
+
+</div><!-- end of div.paging -->
+{% endif %}{# end of checking if tenders existed #}
+</div><!-- end of div.content -->
+{% from "macros/dialog.html" import dlg_prep with context %}
+{{ dlg_prep(["dlg_tender"]) }}
+{# dlg divs below #}
+<div id="dlg_tender" aria-labeledby="spn_tender">
+<span id="spn_tender">Tender details</span><br>
+<form action="{{ url_for("main.tenders") }}" method="post" id="frm_tender">
+{{ form.csrf_token }}
+{{ form.hid_tender_id }}
+<ul>
+<li>{{ form.txt_reference_number.label }}&nbsp;{{ form.txt_reference_number }}</li>
+<li>{{ form.txt_description.label }}<br>
+{{ form.txt_description }}</li>
+</ul>
+<input type="submit" name="btn_save_tender" value="Save">
+</form>
+</div><!-- end of dlg_tender -->
+<script type="text/javascript">
+$(document).ready( function() {
+
+try {
+
+var s_dlg_tender = $("#dlg_tender").html();
+
+$("#a_add_tender").click( function(event) {
+    event.preventDefault();
+    $("#dlg_tender").html(s_dlg_tender);
+    $("#dlg_tender").redraw();
+    $("#dlg_tender").dialog("open");
+    $("#txt_reference_number").focus();
+});// end of #a_add_tender click event
+
+$("#tbl_tenders").on("click", ".a_edit_tender", function(event) {
+try {
+    event.preventDefault();
+    $("#dlg_tender").html(s_dlg_tender);
+    $("#dlg_tender").redraw();
+    var s_id = String($(this).attr("href")).replace("#", "");
+    var s_url = "{{ url_for("main.tender_details", i_tender_id=99999) }}".replace("99999", s_id);
+    $.get(s_url, function(o_data) {
+        if (typeof(o_data)=="object") {
+            var s_reference_number = String(o_data.v_reference_number);
+            var s_description = String(o_data.v_description)
+            $("#hid_tender_id").val(s_id);
+            $("#txt_reference_number").val(s_reference_number);
+            $("#txt_description").val(s_description);
+            $("#dlg_tender").redraw();
+            $("#dlg_tender").dialog("open");
+            $("#txt_reference_number").focus();
+        } else {
+            do_alert(String(o_data));
+        }// end of typeof check against o_data
+    });// end of .get
+} catch(e) {
+    var s_err = String(e.name) + "\nmessage:" + String(e.message);
+    s_err = (typeof(e.lineNumber)!="undefined") ? s_err + "\nline:" + String(e.lineNumber) : s_err;
+    alert("Error! " + s_err);
+}//end of catch
+});// end of .a_edit_tender click event inside tbl_tenders
+
+$("#tbl_tenders").on("click", ".a_remove_tender", function(event) {
+try {
+    event.preventDefault();
+    var bl_confirm = confirm("Are you sure?");
+    if (bl_confirm) {
+        var s_id = String($(this).attr("href")).replace("#", "");
+        $("#hid_remove_tender_id").val(s_id);
+        document.getElementById("frm_remove_tender").submit();
+    }// end of confirmation check
+} catch(e) {
+    var s_err = String(e.name) + "\nmessage:" + String(e.message);
+    s_err = (typeof(e.lineNumber)!="undefined") ? s_err + "\nline:" + String(e.lineNumber) : s_err;
+    alert("Error! " + s_err);
+}//end of catch
+});// end of .a_edit_tender click event inside tbl_tenders
+
+function jump_page(i_page) {
+    i_page = (isNaN(i_page)) ? 1 : Number(i_page);
+    $("#hid_page").val(i_page);
+    document.getElementById("frm_paging").submit();
+}// end of jump_page function
+
+$(".a_page_number").click( function(event) {
+    event.preventDefault();
+    var s_page = String($(this).attr("href")).replace("#", "");
+    i_page = (isNaN(s_page)) ? 1 : Number(s_page);
+    jump_page(i_page);
+});// end of .a_page_number function
+
+window.setTimeout( function() {
+    var s_nada = ""; //alert("hello world");
+}, 300);
+var s = "nada"; // do_alert("hello world");
+
+} catch(e) {
+    var s_err = String(e.name) + "\nmessage:" + String(e.message);
+    s_err = (typeof(e.lineNumber)!="undefined") ? s_err + "\nline:" + String(e.lineNumber) : s_err;
+    alert("Error! " + s_err);
+}//end of catch
+
+});// end of secondary document ready
+</script>
+<form action="{{ url_for("main.tenders") }}" method="post" id="frm_remove_tender">
+{{ remove_form.csrf_token }}
+{{ remove_form.hid_remove_tender_id }}
+</form>
+{% endblock %}