IO-2933 Add in email for succesful postback from Short URL.
This commit is contained in:
@@ -14,10 +14,12 @@ import { selectBodyshop } from "../../redux/user/user.selectors";
|
|||||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||||
import CurrencyFormItemComponent from "../form-items-formatted/currency-form-item.component";
|
import CurrencyFormItemComponent from "../form-items-formatted/currency-form-item.component";
|
||||||
import JobSearchSelectComponent from "../job-search-select/job-search-select.component";
|
import JobSearchSelectComponent from "../job-search-select/job-search-select.component";
|
||||||
|
import { getCurrentUser } from "../../firebase/firebase.utils";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
cardPaymentModal: selectCardPayment,
|
cardPaymentModal: selectCardPayment,
|
||||||
bodyshop: selectBodyshop
|
bodyshop: selectBodyshop,
|
||||||
|
currentUser: getCurrentUser
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
@@ -25,7 +27,13 @@ const mapDispatchToProps = (dispatch) => ({
|
|||||||
toggleModalVisible: () => dispatch(toggleModalVisible("cardPayment"))
|
toggleModalVisible: () => dispatch(toggleModalVisible("cardPayment"))
|
||||||
});
|
});
|
||||||
|
|
||||||
const CardPaymentModalComponent = ({ bodyshop, cardPaymentModal, toggleModalVisible, insertAuditTrail }) => {
|
const CardPaymentModalComponent = ({
|
||||||
|
bodyshop,
|
||||||
|
currentUser,
|
||||||
|
cardPaymentModal,
|
||||||
|
toggleModalVisible,
|
||||||
|
insertAuditTrail
|
||||||
|
}) => {
|
||||||
const { context, actions } = cardPaymentModal;
|
const { context, actions } = cardPaymentModal;
|
||||||
|
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
@@ -142,7 +150,7 @@ const CardPaymentModalComponent = ({ bodyshop, cardPaymentModal, toggleModalVisi
|
|||||||
return acc + (val?.amount || 0);
|
return acc + (val?.amount || 0);
|
||||||
}, 0),
|
}, 0),
|
||||||
account: payments && data && data.jobs.length > 0 ? data.jobs.map((j) => j.ro_number).join(", ") : null,
|
account: payments && data && data.jobs.length > 0 ? data.jobs.map((j) => j.ro_number).join(", ") : null,
|
||||||
comment: btoa(JSON.stringify(payments)),
|
comment: btoa(JSON.stringify({ payments, userEmail: currentUser.email })),
|
||||||
paymentSplitMeta: form.getFieldsValue()
|
paymentSplitMeta: form.getFieldsValue()
|
||||||
});
|
});
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
|
|||||||
@@ -8,11 +8,12 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { openChatByPhone, setMessage } from "../../redux/messaging/messaging.actions";
|
import { openChatByPhone, setMessage } from "../../redux/messaging/messaging.actions";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
|
||||||
import CurrencyFormItemComponent from "../form-items-formatted/currency-form-item.component";
|
import CurrencyFormItemComponent from "../form-items-formatted/currency-form-item.component";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop
|
bodyshop: selectBodyshop,
|
||||||
|
currentUser: selectCurrentUser
|
||||||
});
|
});
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
openChatByPhone: (phone) => dispatch(openChatByPhone(phone)),
|
openChatByPhone: (phone) => dispatch(openChatByPhone(phone)),
|
||||||
@@ -20,7 +21,7 @@ const mapDispatchToProps = (dispatch) => ({
|
|||||||
});
|
});
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(PaymentsGenerateLink);
|
export default connect(mapStateToProps, mapDispatchToProps)(PaymentsGenerateLink);
|
||||||
|
|
||||||
export function PaymentsGenerateLink({ bodyshop, callback, job, openChatByPhone, setMessage }) {
|
export function PaymentsGenerateLink({ bodyshop, currentUser, callback, job, openChatByPhone, setMessage }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
@@ -41,7 +42,7 @@ export function PaymentsGenerateLink({ bodyshop, callback, job, openChatByPhone,
|
|||||||
bodyshop,
|
bodyshop,
|
||||||
amount: amount,
|
amount: amount,
|
||||||
account: job.ro_number,
|
account: job.ro_number,
|
||||||
invoice: job.id
|
comment: btoa(JSON.stringify({ payments: [{ jobid: job.id, amount }], userEmail: currentUser.email }))
|
||||||
});
|
});
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
setPaymentLink(response.data.shorUrl);
|
setPaymentLink(response.data.shorUrl);
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ const sendServerEmail = async ({ subject, text }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendTaskEmail = async ({ to, subject, text, attachments }) => {
|
const sendTaskEmail = async ({ to, subject, type = "text", html, text, attachments }) => {
|
||||||
try {
|
try {
|
||||||
transporter.sendMail(
|
transporter.sendMail(
|
||||||
{
|
{
|
||||||
@@ -107,7 +107,7 @@ const sendTaskEmail = async ({ to, subject, text, attachments }) => {
|
|||||||
}),
|
}),
|
||||||
to: to,
|
to: to,
|
||||||
subject: subject,
|
subject: subject,
|
||||||
text: text,
|
...(type === "text" ? { text } : { html }),
|
||||||
attachments: attachments || null
|
attachments: attachments || null
|
||||||
},
|
},
|
||||||
(err, info) => {
|
(err, info) => {
|
||||||
|
|||||||
@@ -94,7 +94,8 @@ const formatPriority = (priority) => {
|
|||||||
* @param taskId
|
* @param taskId
|
||||||
* @returns {{header, body: string, subHeader: string}}
|
* @returns {{header, body: string, subHeader: string}}
|
||||||
*/
|
*/
|
||||||
const generateTemplateArgs = (title, priority, description, dueDate, bodyshop, job, taskId) => {
|
|
||||||
|
function getEndpoints() {
|
||||||
const endPoints = InstanceManager({
|
const endPoints = InstanceManager({
|
||||||
imex: process.env?.NODE_ENV === "test" ? "https://test.imex.online" : "https://imex.online",
|
imex: process.env?.NODE_ENV === "test" ? "https://test.imex.online" : "https://imex.online",
|
||||||
rome:
|
rome:
|
||||||
@@ -106,6 +107,10 @@ const generateTemplateArgs = (title, priority, description, dueDate, bodyshop, j
|
|||||||
? "https//test.romeonline.io"
|
? "https//test.romeonline.io"
|
||||||
: "https://romeonline.io"
|
: "https://romeonline.io"
|
||||||
});
|
});
|
||||||
|
return endPoints;
|
||||||
|
}
|
||||||
|
const generateTemplateArgs = (title, priority, description, dueDate, bodyshop, job, taskId) => {
|
||||||
|
const endPoints = getEndpoints();
|
||||||
return {
|
return {
|
||||||
header: title,
|
header: title,
|
||||||
subHeader: `Body Shop: ${bodyshop.shopname} | Priority: ${formatPriority(priority)} ${formatDate(dueDate)}`,
|
subHeader: `Body Shop: ${bodyshop.shopname} | Priority: ${formatPriority(priority)} ${formatDate(dueDate)}`,
|
||||||
@@ -333,5 +338,6 @@ const tasksRemindEmail = async (req, res) => {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
taskAssignedEmail,
|
taskAssignedEmail,
|
||||||
tasksRemindEmail
|
tasksRemindEmail,
|
||||||
|
getEndpoints
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2502,6 +2502,13 @@ exports.GET_JOBS_BY_PKS = `query GET_JOBS_BY_PKS($ids: [uuid!]!) {
|
|||||||
jobs(where: {id: {_in: $ids}}) {
|
jobs(where: {id: {_in: $ids}}) {
|
||||||
id
|
id
|
||||||
shopid
|
shopid
|
||||||
|
ro_number
|
||||||
|
ownr_co_nm
|
||||||
|
ownr_fn
|
||||||
|
ownr_ln
|
||||||
|
v_make_desc
|
||||||
|
v_model_yr
|
||||||
|
v_model_desc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ const axios = require("axios");
|
|||||||
const moment = require("moment");
|
const moment = require("moment");
|
||||||
const logger = require("../utils/logger");
|
const logger = require("../utils/logger");
|
||||||
const InstanceManager = require("../utils/instanceMgr").default;
|
const InstanceManager = require("../utils/instanceMgr").default;
|
||||||
|
const { sendTaskEmail } = require("../email/sendemail");
|
||||||
|
const generateEmailTemplate = require("../email/generateTemplate");
|
||||||
|
const { getEndpoints } = require("../email/tasksEmails");
|
||||||
require("dotenv").config({
|
require("dotenv").config({
|
||||||
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
|
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
|
||||||
});
|
});
|
||||||
@@ -166,7 +168,16 @@ exports.postback = async (req, res) => {
|
|||||||
if (comment) {
|
if (comment) {
|
||||||
//Shifted the order to have this first to retain backwards compatibility for the old style of short link.
|
//Shifted the order to have this first to retain backwards compatibility for the old style of short link.
|
||||||
//This has been triggered by IO and may have multiple jobs.
|
//This has been triggered by IO and may have multiple jobs.
|
||||||
const partialPayments = JSON.parse(comment);
|
const parsedComment = JSON.parse(comment);
|
||||||
|
|
||||||
|
//Adding in the user email to the short pay email.
|
||||||
|
//Need to check this to ensure backwards compatibility for clients that don't update.
|
||||||
|
let partialPayments;
|
||||||
|
if (!Array.isArray(parsedComment)) {
|
||||||
|
partialPayments = parsedComment.payments;
|
||||||
|
} else {
|
||||||
|
partialPayments = parsedComment;
|
||||||
|
}
|
||||||
const jobs = await gqlClient.request(queries.GET_JOBS_BY_PKS, {
|
const jobs = await gqlClient.request(queries.GET_JOBS_BY_PKS, {
|
||||||
ids: partialPayments.map((p) => p.jobid)
|
ids: partialPayments.map((p) => p.jobid)
|
||||||
});
|
});
|
||||||
@@ -197,6 +208,25 @@ exports.postback = async (req, res) => {
|
|||||||
paymentResult
|
paymentResult
|
||||||
});
|
});
|
||||||
res.sendStatus(200);
|
res.sendStatus(200);
|
||||||
|
if (values.origin === "OneLink" && parsedComment.userEmail) {
|
||||||
|
//Send an email, it was a text to pay link.
|
||||||
|
const endPoints = getEndpoints();
|
||||||
|
sendTaskEmail({
|
||||||
|
to: parsedComment.userEmail,
|
||||||
|
subject: `New Payment(s) Received - RO ${jobs.jobs.map((j) => j.ro_number).join(", ")}`,
|
||||||
|
type: "html",
|
||||||
|
html: generateEmailTemplate({
|
||||||
|
header: "New Payment(s) Received",
|
||||||
|
subHeader: "",
|
||||||
|
body: jobs.jobs
|
||||||
|
.map(
|
||||||
|
(job) =>
|
||||||
|
`Reference: <a href="${endPoints}/manage/jobs/${job.id}">${job.ro_number || "N/A"}</a> | ${job.ownr_co_nm ? job.ownr_co_nm : `${job.ownr_fn || ""} ${job.ownr_ln || ""}`.trim()} | ${`${job.v_model_yr || ""} ${job.v_make_desc || ""} ${job.v_model_desc || ""}`.trim()} | $${partialPayments.find((p) => p.jobid === job.id).amount}`
|
||||||
|
)
|
||||||
|
.join("<br/>")
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
} else if (values.invoice) {
|
} else if (values.invoice) {
|
||||||
//This is a link email that's been sent out.
|
//This is a link email that's been sent out.
|
||||||
const job = await gqlClient.request(queries.GET_JOB_BY_PK, {
|
const job = await gqlClient.request(queries.GET_JOB_BY_PK, {
|
||||||
|
|||||||
Reference in New Issue
Block a user