diff --git a/hasura/metadata/tables.yaml b/hasura/metadata/tables.yaml index 387e129ff..74a00b23b 100644 --- a/hasura/metadata/tables.yaml +++ b/hasura/metadata/tables.yaml @@ -944,6 +944,7 @@ - autohouseid - bill_allow_post_to_closed - bill_tax_rates + - carfax_exclude - cdk_configuration - cdk_dealerid - chatterid diff --git a/hasura/migrations/1758833517953_alter_table_public_bodyshops_add_column_carfax_exclude/down.sql b/hasura/migrations/1758833517953_alter_table_public_bodyshops_add_column_carfax_exclude/down.sql new file mode 100644 index 000000000..1667505c0 --- /dev/null +++ b/hasura/migrations/1758833517953_alter_table_public_bodyshops_add_column_carfax_exclude/down.sql @@ -0,0 +1,4 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- alter table "public"."bodyshops" add column "carfax_exclude" boolean +-- not null default 'false'; diff --git a/hasura/migrations/1758833517953_alter_table_public_bodyshops_add_column_carfax_exclude/up.sql b/hasura/migrations/1758833517953_alter_table_public_bodyshops_add_column_carfax_exclude/up.sql new file mode 100644 index 000000000..64df7a469 --- /dev/null +++ b/hasura/migrations/1758833517953_alter_table_public_bodyshops_add_column_carfax_exclude/up.sql @@ -0,0 +1,2 @@ +alter table "public"."bodyshops" add column "carfax_exclude" boolean + not null default 'false'; diff --git a/server/data/carfax.js b/server/data/carfax.js index b0792813d..34a145dda 100644 --- a/server/data/carfax.js +++ b/server/data/carfax.js @@ -99,7 +99,7 @@ exports.default = async (req, res) => { await processShopData(shopsToProcess, start, end, skipUpload, ignoreDateFilter, allXMLResults, allErrors); await sendServerEmail({ - subject: `CARFAX Report ${moment().format("MM-DD-YY")}`, + subject: `Project Mexico Report ${moment().format("MM-DD-YY")}`, text: `Errors:\n${JSON.stringify(allErrors, null, 2)}\n\nUploaded:\n${JSON.stringify( allXMLResults.map((x) => ({ imexshopid: x.imexshopid, @@ -164,35 +164,36 @@ async function processShopData(shopsToProcess, start, end, skipUpload, ignoreDat if (skipUpload) { fs.writeFileSync(`./logs/${jsonObj.filename}`, jsonObj.json); + uploadToS3(jsonObj); } else { await uploadViaSFTP(jsonObj); - } - await sendMexicoBillingEmail({ - subject: `${shopid.toUpperCase()}_Mexico${InstanceManager({ - imex: "IO", - rome: "RO" - })}_${moment().format("MMDDYYYY")} ROs ${jsonObj.count} Error ${errorCode(jsonObj)}`, - text: `Errors:\n${JSON.stringify( - erroredJobs.map((ej) => ({ - ro_number: ej.job?.ro_number, - jobid: ej.job?.id, - error: ej.error - })), - null, - 2 - )}\n\nUploaded:\n${JSON.stringify( - { - bodyshopid: bodyshop.id, - imexshopid: shopid, - count: jsonObj.count, - filename: jsonObj.filename, - result: jsonObj.result - }, - null, - 2 - )}` - }); + await sendMexicoBillingEmail({ + subject: `${shopid.replace(/_/g, "").toUpperCase()}_Mexico${InstanceManager({ + imex: "IO", + rome: "RO" + })}_${moment().format("MMDDYYYY")} ROs ${jsonObj.count} Error ${errorCode(jsonObj)}`, + text: `Errors:\n${JSON.stringify( + erroredJobs.map((ej) => ({ + ro_number: ej.job?.ro_number, + jobid: ej.job?.id, + error: ej.error + })), + null, + 2 + )}\n\nUploaded:\n${JSON.stringify( + { + bodyshopid: bodyshop.id, + imexshopid: shopid, + count: jsonObj.count, + filename: jsonObj.filename, + result: jsonObj.result + }, + null, + 2 + )}` + }); + } allXMLResults.push({ bodyshopid: bodyshop.id, @@ -292,17 +293,22 @@ const CreateRepairOrderTag = (job, errorCallback) => { v_make: job.v_make_desc || "", v_model: job.v_model_desc || "", - date_estimated: - (job.date_estimated && moment(job.date_estimated).tz(job.bodyshop.timezone).format(AHDateFormat)) || - (job.created_at && moment(job.created_at).tz(job.bodyshop.timezone).format(AHDateFormat)) || - "", - data_opened: - (job.date_open && moment(job.date_open).tz(job.bodyshop.timezone).format(AHDateFormat)) || - (job.created_at && moment(job.created_at).tz(job.bodyshop.timezone).format(AHDateFormat)) || - "", - date_invoiced: - (job.date_invoiced && moment(job.date_invoiced).tz(job.bodyshop.timezone).format(AHDateFormat)) || "", - loss_date: (job.loss_date && moment(job.loss_date).format(AHDateFormat)) || "", + date_estimated: [job.date_estimated, job.created_at].find((date) => date) + ? moment([job.date_open, job.created_at].find((date) => date)) + .tz(job.bodyshop.timezone) + .format(AHDateFormat) + : "", + data_opened: [job.date_open, job.created_at].find((date) => date) + ? moment([job.date_open, job.created_at].find((date) => date)) + .tz(job.bodyshop.timezone) + .format(AHDateFormat) + : "", + date_invoiced: [job.date_invoiced, job.actual_delivery, job.actual_completion].find((date) => date) + ? moment([job.date_invoiced, job.actual_delivery, job.actual_completion].find((date) => date)) + .tz(job.bodyshop.timezone) + .format(AHDateFormat) + : "", + loss_date: job.loss_date ? moment(job.loss_date).format(AHDateFormat) : "", ins_co_nm: job.ins_co_nm || "", loss_desc: job.loss_desc || "", @@ -329,7 +335,9 @@ const GenerateDetailLines = (line) => { line_desc: line.line_desc ? line.line_desc.replace(NON_ASCII_REGEX, "") : null, oem_partno: line.oem_partno ? line.oem_partno.replace(NON_ASCII_REGEX, "") : null, alt_partno: line.alt_partno ? line.alt_partno.replace(NON_ASCII_REGEX, "") : null, + op_code_desc: line.op_code_desc ? line.op_code_desc.replace(NON_ASCII_REGEX, "") : null, lbr_ty: generateLaborType(line.mod_lbr_ty), + lbr_hrs: line.mod_lb_hrs || 0, part_qty: line.part_qty || 0, part_type: generatePartType(line.part_type), act_price: line.act_price || 0 diff --git a/server/graphql-client/queries.js b/server/graphql-client/queries.js index 26bbd70fd..27f30304e 100644 --- a/server/graphql-client/queries.js +++ b/server/graphql-client/queries.js @@ -879,39 +879,43 @@ exports.CHATTER_QUERY = `query CHATTER_EXPORT($start: timestamptz, $bodyshopid: }`; exports.CARFAX_QUERY = `query CARFAX_EXPORT($start: timestamptz, $bodyshopid: uuid!, $end: timestamptz) { - bodyshops_by_pk(id: $bodyshopid){ + bodyshops_by_pk(id: $bodyshopid) { id shopname imexshopid timezone } - jobs(where: {_and: [{converted: {_eq: true}}, {v_vin: {_is_null: false}}, {date_invoiced: {_gt: $start}}, {date_invoiced: {_lte: $end}}, {shopid: {_eq: $bodyshopid}}]}) { - id + jobs(where: {_and: [{_or: [{date_invoiced: {_gt: $start, _lte: $end}}, {actual_delivery: {_gt: $start, _lte: $end}, date_invoiced: {_is_null: true}}, {actual_completion: {_gt: $start, _lte: $end}, actual_delivery: {_is_null: true}, date_invoiced: {_is_null: true}}]}, {_not: {_and: [{date_invoiced: {_is_null: true}}, {actual_delivery: {_is_null: true}}, {actual_completion: {_is_null: true}}]}}, {shopid: {_eq: $bodyshopid}}]}) { + actual_completion + actual_delivery + area_of_damage created_at - ro_number - v_model_yr - v_model_desc - v_make_desc - v_vin date_estimated - date_open date_invoiced - loss_date + date_open + id ins_co_nm + job_totals + joblines(where: {removed: {_eq: false}}) { + act_price + alt_partno + line_desc + mod_lb_hrs + mod_lbr_ty + oem_partno + op_code_desc + part_type + part_qty + } + loss_date loss_desc + ro_number theft_ind tlos_ind - job_totals - area_of_damage - joblines(where: {removed: {_eq: false}}) { - line_desc - oem_partno - alt_partno - mod_lbr_ty - part_qty - part_type - act_price - } + v_make_desc + v_model_desc + v_model_yr + v_vin } }`; @@ -1854,7 +1858,7 @@ exports.GET_CHATTER_SHOPS = `query GET_CHATTER_SHOPS { }`; exports.GET_CARFAX_SHOPS = `query GET_CARFAX_SHOPS { - bodyshops(where: {external_shop_id: {_is_null: true}}){ + bodyshops(where: {external_shop_id: {_is_null: true}, carfax_exclude: {_neq: "true"}}){ id shopname imexshopid