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", {
agreementnumber: contract.agreementnumber,
}),
audit: true,
created_by: currentUser.email,
},
],

View File

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

View File

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

View File

@@ -23,6 +23,7 @@ export const QUERY_NOTES_BY_JOB_PK = gql`
private
text
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:
_eq: true
columns:
- id
- audit
- created_at
- updated_at
- jobid
- text
- created_by
- critical
- id
- jobid
- private
- text
- updated_at
select_permissions:
- role: user
permission:
columns:
- critical
- private
- created_by
- text
- audit
- created_at
- updated_at
- created_by
- critical
- id
- jobid
- private
- text
- updated_at
filter:
job:
bodyshop:
@@ -3163,14 +3165,15 @@ tables:
- role: user
permission:
columns:
- critical
- private
- created_by
- text
- audit
- created_at
- updated_at
- created_by
- critical
- id
- jobid
- private
- text
- updated_at
filter:
job:
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",
"graphql": "^15.5.0",
"graphql-request": "^3.4.0",
"handlebars": "^4.7.7",
"inline-css": "^3.0.0",
"intuit-oauth": "^3.0.2",
"lodash": "^4.17.21",

View File

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