IO-723 Audit notes

This commit is contained in:
Patrick Fic
2021-03-08 14:38:50 -08:00
parent 5b281094b4
commit 30e0f106d7
17 changed files with 30233 additions and 894 deletions

23364
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -158,6 +158,7 @@ export function ContractConvertToRo({
text: t("contracts.labels.noteconvertedfrom", { text: t("contracts.labels.noteconvertedfrom", {
agreementnumber: contract.agreementnumber, agreementnumber: contract.agreementnumber,
}), }),
audit: true,
created_by: currentUser.email, created_by: currentUser.email,
}, },
], ],

View File

@@ -122,6 +122,7 @@ export function JobsAvailableContainer({ bodyshop, currentUser }) {
notes: { notes: {
data: { data: {
created_by: currentUser.email, created_by: currentUser.email,
audit: true,
text: t("jobs.labels.importnote", { text: t("jobs.labels.importnote", {
date: moment().format("MM/DD/yyy"), date: moment().format("MM/DD/yyy"),
time: moment().format("hh:mm a"), time: moment().format("hh:mm a"),
@@ -279,6 +280,7 @@ export function JobsAvailableContainer({ bodyshop, currentUser }) {
{ {
jobid: selectedJob, jobid: selectedJob,
created_by: currentUser.email, created_by: currentUser.email,
audit: true,
text: t("jobs.labels.supplementnote", { text: t("jobs.labels.supplementnote", {
date: moment().format("MM/DD/yyy"), date: moment().format("MM/DD/yyy"),
time: moment().format("hh:mm a"), time: moment().format("hh:mm a"),

View File

@@ -1,4 +1,5 @@
import { import {
AuditOutlined,
DeleteFilled, DeleteFilled,
EditFilled, EditFilled,
EyeInvisibleFilled, EyeInvisibleFilled,
@@ -40,6 +41,7 @@ export function JobNotesComponent({
<WarningFilled style={{ margin: 4, color: "red" }} /> <WarningFilled style={{ margin: 4, color: "red" }} />
) : null} ) : null}
{record.private ? <EyeInvisibleFilled style={{ margin: 4 }} /> : null} {record.private ? <EyeInvisibleFilled style={{ margin: 4 }} /> : null}
{record.audit ? <AuditOutlined style={{ margin: 4 }} /> : null}
</span> </span>
), ),
}, },
@@ -76,11 +78,13 @@ export function JobNotesComponent({
<span> <span>
<Button <Button
loading={deleteLoading} loading={deleteLoading}
disabled={record.audit}
onClick={() => handleNoteDelete(record.id)} onClick={() => handleNoteDelete(record.id)}
> >
<DeleteFilled /> <DeleteFilled />
</Button> </Button>
<Button <Button
disabled={record.audit}
onClick={() => { onClick={() => {
setNoteUpsertContext({ setNoteUpsertContext({
actions: { refetch: refetch }, actions: { refetch: refetch },

View File

@@ -23,6 +23,7 @@ export const QUERY_NOTES_BY_JOB_PK = gql`
private private
text text
updated_at updated_at
audit
} }
} }
} }

View File

@@ -0,0 +1,5 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."notes" DROP COLUMN "audit";
type: run_sql

View File

@@ -0,0 +1,6 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."notes" ADD COLUMN "audit" boolean NOT NULL DEFAULT
false;
type: run_sql

View File

@@ -0,0 +1,33 @@
- args:
role: user
table:
name: notes
schema: public
type: drop_insert_permission
- args:
permission:
check:
job:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
columns:
- id
- created_at
- updated_at
- jobid
- text
- created_by
- critical
- private
set: {}
role: user
table:
name: notes
schema: public
type: create_insert_permission

View File

@@ -0,0 +1,34 @@
- args:
role: user
table:
name: notes
schema: public
type: drop_insert_permission
- args:
permission:
check:
job:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
columns:
- audit
- created_at
- created_by
- critical
- id
- jobid
- private
- text
- updated_at
set: {}
role: user
table:
name: notes
schema: public
type: create_insert_permission

View File

@@ -0,0 +1,34 @@
- args:
role: user
table:
name: notes
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: false
columns:
- critical
- private
- created_by
- text
- created_at
- updated_at
- id
- jobid
computed_fields: []
filter:
job:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
role: user
table:
name: notes
schema: public
type: create_select_permission

View File

@@ -0,0 +1,35 @@
- args:
role: user
table:
name: notes
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: false
columns:
- audit
- created_at
- created_by
- critical
- id
- jobid
- private
- text
- updated_at
computed_fields: []
filter:
job:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
role: user
table:
name: notes
schema: public
type: create_select_permission

View File

@@ -0,0 +1,33 @@
- args:
role: user
table:
name: notes
schema: public
type: drop_update_permission
- args:
permission:
columns:
- critical
- private
- created_by
- text
- created_at
- updated_at
- id
- jobid
filter:
job:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
set: {}
role: user
table:
name: notes
schema: public
type: create_update_permission

View File

@@ -0,0 +1,34 @@
- args:
role: user
table:
name: notes
schema: public
type: drop_update_permission
- args:
permission:
columns:
- audit
- created_at
- created_by
- critical
- id
- jobid
- private
- text
- updated_at
filter:
job:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
set: {}
role: user
table:
name: notes
schema: public
type: create_update_permission

View File

@@ -3129,26 +3129,28 @@ tables:
- active: - active:
_eq: true _eq: true
columns: columns:
- id - audit
- created_at - created_at
- updated_at
- jobid
- text
- created_by - created_by
- critical - critical
- id
- jobid
- private - private
- text
- updated_at
select_permissions: select_permissions:
- role: user - role: user
permission: permission:
columns: columns:
- critical - audit
- private
- created_by
- text
- created_at - created_at
- updated_at - created_by
- critical
- id - id
- jobid - jobid
- private
- text
- updated_at
filter: filter:
job: job:
bodyshop: bodyshop:
@@ -3163,14 +3165,15 @@ tables:
- role: user - role: user
permission: permission:
columns: columns:
- critical - audit
- private
- created_by
- text
- created_at - created_at
- updated_at - created_by
- critical
- id - id
- jobid - jobid
- private
- text
- updated_at
filter: filter:
job: job:
bodyshop: bodyshop:

7138
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -28,7 +28,6 @@
"firebase-admin": "^9.5.0", "firebase-admin": "^9.5.0",
"graphql": "^15.5.0", "graphql": "^15.5.0",
"graphql-request": "^3.4.0", "graphql-request": "^3.4.0",
"handlebars": "^4.7.7",
"inline-css": "^3.0.0", "inline-css": "^3.0.0",
"intuit-oauth": "^3.0.2", "intuit-oauth": "^3.0.2",
"lodash": "^4.17.21", "lodash": "^4.17.21",

View File

@@ -1,213 +1,212 @@
const path = require("path"); // const path = require("path");
const moment = require("moment"); // const moment = require("moment");
require("dotenv").config({ // require("dotenv").config({
path: path.resolve( // path: path.resolve(
process.cwd(), // process.cwd(),
`.env.${process.env.NODE_ENV || "development"}` // `.env.${process.env.NODE_ENV || "development"}`
), // ),
}); // });
var _ = require("lodash"); // var _ = require("lodash");
const Handlebars = require("handlebars"); // const Handlebars = require("handlebars");
const phone = require("phone"); // const phone = require("phone");
var Dinero = require("dinero.js"); // var Dinero = require("dinero.js");
Dinero.defaultCurrency = "CAD"; // Dinero.defaultCurrency = "CAD";
Dinero.globalLocale = "en-CA"; // Dinero.globalLocale = "en-CA";
//Usage: {{moment appointments_by_pk.start format="dddd, DD MMMM YYYY"}} // //Usage: {{moment appointments_by_pk.start format="dddd, DD MMMM YYYY"}}
Handlebars.registerHelper("round", function (context, block) { // Handlebars.registerHelper("round", function (context, block) {
if (context && context.hash) { // if (context && context.hash) {
block = _.cloneDeep(context); // block = _.cloneDeep(context);
context = undefined; // context = undefined;
} // }
try { // try {
return context.toFixed(2); // return context.toFixed(2);
} catch { // } catch {
return context; // return context;
} // }
}); // });
Handlebars.registerHelper("dinerof", function (context, block) { // Handlebars.registerHelper("dinerof", function (context, block) {
if (context && context.hash) { // if (context && context.hash) {
block = _.cloneDeep(context); // block = _.cloneDeep(context);
context = undefined; // context = undefined;
} // }
var amount = Dinero(context); // var amount = Dinero(context);
if (context) { // if (context) {
return amount.toFormat(); // return amount.toFormat();
} // }
return ""; // return "";
}); // });
Handlebars.registerHelper("phonef", function (context, block) { // Handlebars.registerHelper("phonef", function (context, block) {
if (context && context.hash) { // if (context && context.hash) {
block = _.cloneDeep(context); // block = _.cloneDeep(context);
context = undefined; // context = undefined;
} // }
var ph = phone(context)[0]; // var ph = phone(context)[0];
if (context) { // if (context) {
return ph; // return ph;
} // }
return ""; // return "";
}); // });
Handlebars.registerHelper("partType", function (context, block) { // Handlebars.registerHelper("partType", function (context, block) {
if (!context) return ""; // if (!context) return "";
switch (context.toUpperCase()) { // switch (context.toUpperCase()) {
case "PAA": // case "PAA":
return "Aftermarket"; // return "Aftermarket";
case "PAE": // case "PAE":
return "Existing"; // return "Existing";
case "PAN": // case "PAN":
return "OEM"; // return "OEM";
case "PAO": // case "PAO":
return "Other"; // return "Other";
case "PAS": // case "PAS":
return "Sublet"; // return "Sublet";
case "PASL": // case "PASL":
return "Sublet"; // return "Sublet";
case "PAL": // case "PAL":
return "LKQ"; // return "LKQ";
case "PAM": // case "PAM":
return "Remanufactured"; // return "Remanufactured";
case "PAC": // case "PAC":
return "Chrome"; // return "Chrome";
case "PAP": // case "PAP":
return "OEM Partial"; // return "OEM Partial";
case "PAR": // case "PAR":
return "Record"; // return "Record";
default: // default:
return context; // return context;
} // }
}); // });
Handlebars.registerHelper("lbrType", function (context, block) { // Handlebars.registerHelper("lbrType", function (context, block) {
if (!context) return ""; // if (!context) return "";
switch (context.toUpperCase()) { // switch (context.toUpperCase()) {
case "LAA": // case "LAA":
return "Aluminum"; // return "Aluminum";
case "LAB": // case "LAB":
return "Body"; // return "Body";
case "LAD": // case "LAD":
return "Diagnostic"; // return "Diagnostic";
case "LAF": // case "LAF":
return "Frame"; // return "Frame";
case "LAG": // case "LAG":
return "Glass"; // return "Glass";
case "LAM": // case "LAM":
return "Mechanical"; // return "Mechanical";
case "LAR": // case "LAR":
return "Refinish"; // return "Refinish";
case "LAS": // case "LAS":
return "Structural"; // return "Structural";
case "LAU": // case "LAU":
return "Detail"; // return "Detail";
default: // default:
return context; // return context;
} // }
}); // });
Handlebars.registerHelper("objectKeys", function (obj, block) { // Handlebars.registerHelper("objectKeys", function (obj, block) {
var accum = ""; // var accum = "";
obj && // obj &&
Object.keys(obj).map((key) => { // Object.keys(obj).map((key) => {
accum += block.fn({ key, value: obj[key] }); // accum += block.fn({ key, value: obj[key] });
}); // });
return accum; // return accum;
}); // });
Handlebars.registerHelper("dinero", function (context, block) { // Handlebars.registerHelper("dinero", function (context, block) {
if (context && context.hash) { // if (context && context.hash) {
block = _.cloneDeep(context); // block = _.cloneDeep(context);
context = undefined; // context = undefined;
} // }
var amount = Dinero({ // var amount = Dinero({
amount: Math.round((context || 0) * 100), // amount: Math.round((context || 0) * 100),
currency: "CAD", // currency: "CAD",
}); // });
return amount.toFormat(); // return amount.toFormat();
}); // });
Handlebars.registerHelper("moment", function (context, block) { // Handlebars.registerHelper("moment", function (context, block) {
if (context && context.hash) { // if (context && context.hash) {
block = _.cloneDeep(context); // block = _.cloneDeep(context);
context = undefined; // context = undefined;
} // }
if (!!!context) return ""; // if (!!!context) return "";
var date = moment(context); // var date = moment(context);
if (block.hash.timezone) { // if (block.hash.timezone) {
date.tz(block.hash.timezone); // date.tz(block.hash.timezone);
} // }
var hasFormat = false; // var hasFormat = false;
// Reset the language back to default before doing anything else // // Reset the language back to default before doing anything else
date.locale("en"); // date.locale("en");
for (var i in block.hash) { // for (var i in block.hash) {
if (i === "format") { // if (i === "format") {
hasFormat = true; // hasFormat = true;
} else if (date[i]) { // } else if (date[i]) {
date = date[i](block.hash[i]); // date = date[i](block.hash[i]);
} else { // } else {
console.log('moment.js does not support "' + i + '"'); // console.log('moment.js does not support "' + i + '"');
} // }
} // }
if (hasFormat) { // if (hasFormat) {
date = date.format(block.hash.format); // date = date.format(block.hash.format);
} // }
return date; // return date;
}); // });
Handlebars.registerHelper("duration", function (context, block) { // Handlebars.registerHelper("duration", function (context, block) {
if (context && context.hash) { // if (context && context.hash) {
block = _.cloneDeep(context); // block = _.cloneDeep(context);
context = 0; // context = 0;
} // }
var duration = moment.duration(context); // var duration = moment.duration(context);
var hasFormat = false; // var hasFormat = false;
// Reset the language back to default before doing anything else // // Reset the language back to default before doing anything else
duration = duration.lang("en"); // duration = duration.lang("en");
for (var i in block.hash) { // for (var i in block.hash) {
if (i === "format") { // if (i === "format") {
hasFormat = true; // hasFormat = true;
} else if (duration[i]) { // } else if (duration[i]) {
duration = duration[i](block.hash[i]); // duration = duration[i](block.hash[i]);
} else { // } else {
console.log('moment.js duration does not support "' + i + '"'); // console.log('moment.js duration does not support "' + i + '"');
} // }
} // }
if (hasFormat) { // if (hasFormat) {
duration = duration.format(block.hash.format); // duration = duration.format(block.hash.format);
} // }
return duration; // return duration;
}); // });
exports.render = (req, res) => { exports.render = (req, res) => {
//Perform request validation // //Perform request validation
let view; // let view;
console.log("[HJS Render] New Render Request."); // console.log("[HJS Render] New Render Request.");
// //console.log("[HJS Render] Context", req.body.context);
//console.log("[HJS Render] Context", req.body.context); // if (req.body.context.bodyshop.template_header) {
if (req.body.context.bodyshop.template_header) { // console.log("[HJS Render] Including Header");
console.log("[HJS Render] Including Header"); // //view = req.body.view;
//view = req.body.view; // view = `${req.body.context.bodyshop.template_header}${req.body.view}`;
view = `${req.body.context.bodyshop.template_header}${req.body.view}`; // } else {
} else { // console.log("[HJS Render] No header to include.");
console.log("[HJS Render] No header to include."); // view = req.body.view;
view = req.body.view; // }
} // var template = Handlebars.compile(view);
var template = Handlebars.compile(view); // res.send(template(req.body.context));
res.send(template(req.body.context));
}; };