Files
Facilitor/APPL/MLD/mld_opdr_actions.asp
Jos Groot Lipman 29ea85186e Merge 2024.1 RC4 patches
svn path=/Website/trunk/; revision=63809
2024-03-05 11:07:47 +00:00

454 lines
21 KiB
Plaintext

<%@language = "javascript" %>
<%
/* $Revision$
$Id$
File: mld_opdr_actions.asp
Description: Actiescherm voor opdrachten
Parameters: opdr_key (REQUIRED)
Context: Accessed from remote
Note:
Het idee is dat je hier hmac-beschermd met een opdrachtkey binnenkomt en
details van die opdracht toont.
Je bent dan niet als een echte user ingelogd.
We weten dat dit scherm voor de uitvoerders van de opdracht bedoeld is dus
kunnen op grond daarvan zelf hardcoded beslissen wat zinvol te tonen is.
Afhankelijk van de status van de opdracht worden opties voor acties geboden:
- accepteren of afwijzen
- bijwerken (opmerking, plandatum, geplande einddatum, einddatum, notitie?)
- afmelden
- afronden.
Dit kan ook mobiel benaderd worden dus ruime mate van responsive is er fijn.
Deze pagina is alleen praktischer en toegespitster, je kunt er als die
user niet meer of minder mee dan anders.
Note: Denk aan lcl-textcontextswitcher?
Status: opzet, in detail echt afmaken
*/
var LOCKED_USER_OK = { "xmlnode": "opdracht", "key": getQParamInt("opdr_key") };
%>
<!-- #include file="../Shared/common.inc" -->
<!-- #include file="../Shared/iface.inc" -->
<!-- #include file="../Shared/status.inc" -->
<!-- #include file="mld.inc" -->
<!-- #include file="mld_flexkenmerk.inc" -->
<!-- #include file="../PRS/prs.inc" -->
<!-- #include file="../Shared/notes.inc" -->
<%
// todo protectQS.verify(); // tamper check
FCLTHeader.Requires({ plugins:["jQuery"],
js: ["./mld.js", "jQuery-ui.js", "notes.js"]
});
var opdr_key = getQParamInt("opdr_key");
// Mag deze user_key genoeg op deze opdracht?
var this_opdr = mld.func_enabled_opdracht(opdr_key); // wat mag ik zoal op deze opdracht
var hasBOread = this_opdr.canReadBOF || this_opdr.canReadORD;
var hasBO2read = this_opdr.canReadBO2;
user.auth_required_or_abort(this_opdr.canReadAny);
var outputmode = getQParamInt("outputmode", 0); // 0 = screen, 1 = print, 2 = excel etc
// Nu mag ik het allemaal dus
// Toon gezellig wat opdrachtdetails readonly.
// Toon daarbij afhankelijk van de diverse this_opdr.canXXXX de mogelijke acties en opties.
// submit liefst naar de normale save (of mooier nog: submit via de API-POST ?)
%>
<html>
<head>
<%
FCLTHeader.Generate();
%>
<style>
.actionbody {padding: 10px;}
.action-wrapper {
display: flex;
justify-content: space-evenly;
align-items: center;
row-gap: var(--fclt-gap-xl);
flex-wrap: wrap;
}
.action {
color: #333;
font-size: 1.3em;
padding: 1em;
border: var(--fclt-border);
border-radius: var(--fclt-border-radius-lg);
}
.expired {color: #CC0000; font-weight: bold;}
.ordacp > i {color: #51AF1B!important;}
.ordrej > i {color: #AF1B1B!important;}
.ordupd > i {color: #999!important;}
:is(.ordafm, .ordafr) > i {color: #E37B00!important;}
geenhekjeaanbeginregel, #opdrNotesLightHistorie { background-color: var(--notesbackgroundcolor); }
geenhekjeaanbeginregel, #opdrNotesLightHistorieList { background-color: rgba(255, 255, 255, 0.6); }
</style>
<script type="text/javascript">
$(() => {
init_note(-1);
$(".card > [data-toggle=collapse]").on("click", function () {
let $target = $($(this).data("target"));
$(this).attr("aria-expanded", ($(this).attr("aria-expanded") == "false" ? "true" : "false"));
$target.toggle().promise().done(() => {
FcltMgr.resized();
$target[0].scrollIntoView({ block: "nearest", behavior: "smooth" });
});
});
});
async function this_note_submit(formid) {
if ($("#tot_kosten").val()) {
if (!await save_and_then()) {
return false;
}
}
note_submit(formid);
}
function note_submit_callback(json)
{
if (window.noteediting && FcltMgr.stopEdit(window)) {
window.noteediting = false;
}
FcltMgr.reload();
}
async function save_and_then(save_callback)
{
if (!await validateForm("u2", { checkOnly: ["tot_kosten"] })) {
return false;
}
return $.post($("form[name=u2]")[0].action, $("[name=u2]").serialize(), save_callback, "json");
}
function opdr_accept()
{
save_and_then(function () {
FcltMgr.confirm(L("lcl_mld_opdr_accept").format(""),
function() { // Accepteren scherm
var data = { opdr_key: <%=opdr_key%> };
protectRequest.dataToken(data);
$.post("opdr_accept_save.asp", data, FcltCallbackRefresh, "json");
});
});
}
function opdr_cancel()
{
save_and_then(function () {
var url = "../mld/opdr_cancel_confirm.asp?opdr_key=<%=opdr_key%>&dorefresh=1";
FcltMgr.openModalDetail(url, L("lcl_mld_opdr_cancel"),
{ callback: opdrCloseCallback
});
});
}
function opdr_close()
{
save_and_then(function () {
var url = "../mld/opdr_close_confirm.asp?opdr_key=<%=opdr_key%>";
FcltMgr.openModalDetail(url, L("lcl_mld_opdr_close"),
{ callback: opdrCloseCallback
});
});
}
function finish_callback()
{
var opdr_kosten = parseFloat(String($("#tot_kosten").val()).replace(',', '.'));
var data = { opdr_key: <%=opdr_key%>,
opdr_kosten: (isNaN(opdr_kosten) ? "" : opdr_kosten)
};
protectRequest.dataToken(data);
$.post( "opdr_finish.asp"
, data
, FcltCallbackRefresh
, "json"
);
}
async function opdr_finish() {
if (!await validateForm("u2", { checkOnly: ["tot_kosten"] })) {
return false;
}
$.post( "mld_edit_opdr_save.asp?opdr_key=<%=opdr_key%>&finish=1",
$("[name=u2]").serialize(),
finish_callback,
"json");
}
</script>
</head>
<%
var mld_opdr = this_opdr.mld_opdr;
var mld_info = mld.mld_melding_info(mld_opdr.mld_key)
var prs_info = new prs.prs_perslid(mld_info.melder_key);
%>
<body class="actionbody notesmode">
<% SUBFRAME_START({ containerClass: "container", rowClass: "justify-content-center" });%>
<form name="u2" id="opdrform" method="post" action="mld_edit_opdr_save.asp?opdr_key=<%=opdr_key%>"></form>
<form name="noteform" id="noteform" method="post" action="opdr_edit_note_save.asp?opdr_key=<%=opdr_key%>"></form>
<% BLOCK_START(null, null, { wide: true });%>
<div class="logo"><img alt="" src="<%=custpath + "/" + S("fac_logo_file")%>"></div>
<h2><%=L("lcl_opdr_action_tekst4") + ","/* Beste uitvoerder, */%></h2>
<p><%=L("lcl_opdr_action_tekst1").format((mld_opdr.srtdiscprefix||"") + mld_opdr.mld_key + "/" + mld_opdr.volgnr)/* "U heeft opdracht {0} van ons ontvangen. Hieronder ziet u de details." */%></p>
<p>
<u><%=L("lcl_opdr_action_tekst5")/* Omschrijving */%></u>
<br>
<%=safe.html(mld_opdr.opdr_omschr)%>
</p>
<p>
<%=L("lcl_opdr_action_tekst6").format(safe.html(prs_info.naam || L("lcl_opdr_action_tekst8")))/* "Oorspronkelijk gemeld door: {0}" */%>
<br>
<%=L("lcl_opdr_action_tekst7").format(safe.html(prs_info.prs_perslid_telefoonnr))/* "Telefoonnummer: {0}" */%>
</p>
<p>
<%=L("lcl_opdr_action_status").format(mld.getextendedopdrstatustext(mld_opdr.extended_opdr_status, opdr_key))%>
</p>
<% /* TR's zonder table? */
ROFIELDTR("fld", L("lcl_orderdate_uitv"), toDateTimeString(mld_opdr.mld_opdr_datumbegin));
ROFIELDTR("fld"+(mld_opdr.mld_opdr_plandatum < new Date() ? " expired":""), L("lcl_opdr_plandate"), toDateTimeString(mld_opdr.mld_opdr_plandatum), {suppressEmpty: true});
ROFIELDTR("fld"+(mld_opdr.mld_opdr_plandatum2 < new Date() ? " expired":""), L("lcl_opdr_plandate2"), toDateTimeString(mld_opdr.mld_opdr_plandatum2), {suppressEmpty: true});
ROFIELDTR("fld"+(mld_opdr.mld_opdr_einddatum && mld_opdr.mld_opdr_einddatum < new Date() ? " expired":""), L("lcl_opdr_enddate_uitv"), toDateTimeString(mld_opdr.mld_opdr_einddatum), { suppressEmpty: true });
if (this_opdr.canFinish && mld_opdr.opdrkosten_verplicht) { // Afgemeld, je moet kosten opgeven, dit veld staat er alleen omdat het verplicht is als je wilt verwerken
%> <input type="hidden" name="opdr_key" value="<%=opdr_key%>" form="opdrform"><%
RWFIELDTR("tot_kosten", "fldshort totkosten", L("lcl_opdr_kosten"), safe.curreditable(mld_opdr.t_cost), { required: mld_opdr.opdrkosten_verplicht, datatype: "currency", formid: "opdrform" });
} else {
ROFIELDTR("fld", L("lcl_opdr_kosten"), mld_opdr.t_cost, {suppressEmpty: true, datatype: "currency"});
}
BLOCK_END();
BLOCK_START("opdrNotesLightHistorie", L("lcl_opdr_frame_notes"), { wide: true, nopadding: true, icon: "fa-clipboard-list-check", collapsible: ".notes-wrapper", expanded: true });
// afgehandeld: 1=afgewezen, 6=Technisch Voltooid/Afgemeld, 7=Verwerkt en 9= Kosten Voltooid
var afgehandeld = (mld_opdr.opdr_status == 1 || mld_opdr.opdr_status == 6 || mld_opdr.opdr_status == 7 || mld_opdr.opdr_status == 9);
var opdr_note_flag = 0;
var params = { tabel: "mld_opdr",
formid: "noteform",
xmlnode: "opdracht",
mod_tabel: "mld_opdr",
note_tabel: "mld_opdr_note",
note_submit_func: "this_note_submit",
showNote: this_opdr.canShowOpdrNote,
writeNote: this_opdr.canEditOpdrNote,
afgehandeld: afgehandeld,
note_flag: opdr_note_flag,
this_opdr: this_opdr, // meegeven wat je al weet
mld_info: mld_info
};
var any_att_sql = "SELECT COUNT(*) attachment_count"
+ " FROM fac_bijlagen fb"
+ " , mld_opdr_note n"
+ " WHERE fb.fac_bijlagen_refkey = n.mld_opdr_note_key"
+ " AND fb.fac_bijlagen_module = 'ORDN'"
+ (this_opdr.myRole === 4 ? " AND BITAND(n.mld_opdr_note_flag, 4) = 4" : "")
+ " AND n.mld_opdr_key = " + opdr_key;
var any_att_oRs = Oracle.Execute(any_att_sql);
var has_any_attachments = any_att_oRs("attachment_count").Value > 0;
any_att_oRs.Close();
notes.note_field(opdr_key, -1, "OPDR", params);
var selector_sql = "(SELECT fac_note_group_naam"
+ " FROM fac_note_group fng"
+ " WHERE n.fac_note_group_key = fng.fac_note_group_key"
+ " AND fac_note_group_vervaldatum IS NULL) fac_note_group_naam";
var sql_n = "SELECT n.mld_opdr_note_aanmaak"
+ " , n.mld_opdr_note_key pkey"
+ " , n.mld_opdr_note_parent_key"
+ " , pf.prs_perslid_key"
+ " , pf.prs_perslid_naam_friendly"
+ " , n.mld_opdr_note_omschrijving"
+ " , n.mld_opdr_note_flag"
+ " , NULL fac_srtnotificatie_code"
+ " , n.fac_tracking_key note_fac_tracking_key" // verwijzing naar de tracking waar de notitie bij hoort
+ ", " + selector_sql
+ " FROM mld_opdr_note n"
+ " , prs_v_perslid_fullnames_all pf"
+ " WHERE n.prs_perslid_key = pf.prs_perslid_key (+)"
+ " AND n.mld_opdr_key = " + opdr_key
+ (this_opdr.myRole === 4 ? " AND BITAND(n.mld_opdr_note_flag, 4) = 4" : "");
var sql = "SELECT * FROM ("+ sql_n + ")"
+ " ORDER BY 1 DESC, 2 DESC";
var oRs = Oracle.Execute(sql);
var lasttime = null;
var lastuser = null;
var firstrec = true;
Response.Write("<div class='notes-wrapper collapse show'>");
while(!oRs.Eof)
{
var thisuser = oRs("prs_perslid_naam_friendly").Value;
var prs_key = oRs("prs_perslid_key").Value;
var note_parent_key = oRs("mld_opdr_note_parent_key").value || -1;
var thistime = new Date(oRs("mld_opdr_note_aanmaak").Value);
var timestr = toTimeString(thistime);
var srtnoti = oRs("fac_srtnotificatie_code").Value;
var note_oms = oRs("mld_opdr_note_omschrijving").Value;
var fac_note_group_naam = oRs("fac_note_group_naam").Value;
var fullname_html = notes.fnPerslidNaamFull(oRs);
var last_note_key = oRs("pkey").Value;
var note_zichtbaarUITV = oRs("mld_opdr_note_flag").Value & 4;
var note_unanswered = oRs("mld_opdr_note_flag").Value & 32;
var ismailnote = oRs("mld_opdr_note_flag").Value & 64;
var note_flag = oRs("mld_opdr_note_flag").Value || 0;
var note_fac_tracking_key = oRs("note_fac_tracking_key").Value;
var eigenNotitie = prs_key == user_key;
if (srtnoti) {
var note_uid = "track-" + last_note_key; /* Eigenlijk tracking */
} else {
var note_uid = "note-2" + last_note_key; /* Hardcoded 2, want dit staat altijd in de mld_opdr_note tabel */
}
var note_wrapper_class = "note-wrapper" + (note_unanswered ? " note-marked" : "");
var note_container_class = "note-container note-module-ord";
var note_author_icon = "";
if (mld_info.melder_key == prs_key) {
note_author_icon = "fa-user-circle";
}
oRs.MoveNext();
var newestIsNote = false;
if (firstrec) {
firstrec = false;
newestIsNote = !srtnoti;
}
if (eigenNotitie)
note_wrapper_class += " note-type-self";
// Bij user of dag switch altijd kopje. Ik zou graag systeemmeldingen niet als user-switch zien,
// dus die bij het voorgaande kopje laten horen door die te skippen bij lastuser
var dedatum = toDateString(thistime, false, true);
if (lasttime == null || (S("note_sort_ascending")? thistime.midnight() > lasttime.midnight() : thistime.midnight() < lasttime.midnight()))
Response.Write("<div class='note-date-wrapper'><div class='note-date'>{0}</div></div>".format(toDateString(thistime, false, true)));
var sameevent = (srtnoti && lastuser == thisuser && lasttime && Math.abs(thistime.getTime() - lasttime.getTime()) < 60000);
lasttime = thistime;
if (thisuser != null)
lastuser = thisuser; // de laatste echte user
var safehtml = "";
note_container_class += (srtnoti ? " note-type-tracking" : "");
if (!note_oms && srtnoti) // tracking zonder dat tekst is overruled
note_oms = status.getsrtnotificatietext(srtnoti); // default tracking tekst
if (note_oms) // Notitie of tracking met opgeslagen tekst
{
safehtml = safe.notehtml(note_oms, "ORD", last_note_key);
if (!note_zichtbaarUITV && !srtnoti)
note_container_class += " note-uitv-hidden";
note_container_class += (ismailnote ? " note-type-email" : "");
var note_header_left = "";
if (!sameevent)
{
if (note_author_icon)
note_header_left += "<span class='note-author-icon'>{0}</span>".format(I(safe.html(note_author_icon)));
note_header_left += "<span class='note-author'>{0}</span>".format(fullname_html);
note_header_left += "<span class='note-timestamp' title='{0}'>{1}</span>".format(dedatum, timestr == "00:00" ? "" : (fullname_html != "" ? " - " : "") + timestr);
}
note_header_left = "<span class='note-header-left-wrapper'>{0}</span>".format(note_header_left);
var note_header_right = "";
if (fac_note_group_naam)
note_header_right += "<span class='note-group'>" + safe.html(fac_note_group_naam) + "</span>";
if (!note_zichtbaarUITV && !srtnoti)
note_header_right += "<span class='note-icon-hidden-uitv' title='{0}'>".format(L("lcl_mld_verborgen_UITV")) + I("fa-lock") + "</span>";
note_header_right = "<span class='note-header-right-wrapper'>{0}</span>".format(note_header_right);
var note_header = "<div class='note-header'>{0}{1}</div>".format(note_header_left, note_header_right);
var autocollapse = S("note_autocollapse") && note_oms.match(new RegExp(S("note_autocollapse"))) && note_oms.split("\n").length > 2;
var collapse_class = "";
if (!newestIsNote)
{
if (autocollapse) /* ingeklapt tot 2 regels */
collapse_class += " note-autocollapse";
else if (safehtml.length > S("rs_maxchar") * 5) /* ingeklapt tot 5 regels */
collapse_class += " note-collapsed";
}
var toggler = "";
if (autocollapse || safehtml.length > S("rs_maxchar") * 5)
toggler += "<div class='note-toggler'>{0}</div>".format(newestIsNote ? L("lcl_rs_truncate") : L("lcl_rs_truncated"));
var reply_to_this_note = notes.inlineReplyNote(note_parent_key, "O");
var note_attachments = "";
if (has_any_attachments && !srtnoti) {
note_attachments = BB_ATTACHMENTS_HTML("ORDN", last_note_key, "note", "show", { safeQS: "&opdr_key=" + opdr_key });
}
var note_text = "<div class='note-body'>{0}<div class='note-text{1}'>{2}</div>{3}{4}</div>"
.format(reply_to_this_note, collapse_class, safehtml, toggler, note_attachments);
/* Nu hebben we alles om de notitie of tracking te printen; */
Response.Write("<div id='{0}' class='{1}' data-tracking='{2}'>".format(note_uid, note_wrapper_class, note_fac_tracking_key||"")
+ " <div class='{0}' data-flag='{1}'>{2}{3}</div>".format(note_container_class, note_flag, note_header, note_text)
+ "</div>");
}
// else obscuur dat we geen tekst hebben?
// De MoveNext hebben we al eerder gehad
}
Response.Write("</div>"); /* .notes-wrapper */
oRs.Close();
BLOCK_END();
BLOCK_START("actInfo3", L("lcl_opdr_action_watnu"), { wide: true, icon: "fa-hand-point-up" });
%> </table>
<div class="action-wrapper">
<% if (this_opdr.canAccept) { /* Uitgegeven: expliciet accepteren of afwijzen */ %>
<span class="action nowrap default-clickable-icon tappable ordacp" onclick="javascript:opdr_accept()"><%=I("fa-unlock fa-2xl")%><span class="action-text"><%=L("lcl_opdr_action_ordacp")%></span></span>
<% }
if (this_opdr.canCancel) { %>
<span class="action nowrap default-clickable-icon tappable ordrej" onclick="javascript:opdr_cancel()"><%=I("fa-times fa-2xl")%><span class="action-text"><%=L("lcl_opdr_action_ordrej")%></span></span>
<% }
if (this_opdr.canClose) { /* Geaccepteerd */ %>
<span class="action nowrap default-clickable-icon tappable ordafm" onclick="javascript:opdr_close()"><%=I("fa-flag-checkered fa-2xl")%><span class="action-text"><%=L("lcl_opdr_action_ordafm")%></span></span>
<% }
if (this_opdr.canFinish) { /* Afgemeld */ %>
<span class="action nowrap default-clickable-icon tappable ordafr" onclick="javascript:opdr_finish()"><%=I("fa-flag-checkered fa-2xl")%><span class="action-text"><%=L("lcl_opdr_action_ordafr")%></span></span>
<% } %>
</div>
<input type="hidden" name="orderdate" id="orderdate" value="<%=mld_opdr.mld_opdr_datumbegin.getTime()%>" form="opdrform">
<% IFACE.FORM_END({ formid: "opdrform" }); %>
<br>
<%=L("lcl_opdr_action_foottekst1").format(safe.html(mld_opdr.contactpers_naam))%>
<br>
<%=L("lcl_opdr_action_foottekst2")%>
<% BLOCK_END();
SUBFRAME_END();%>
</body>
<!-- You are <%=safe.html(user.naam())%> -->
</html>
<% ASPPAGE_END(); %>