const path = require("path"); require("dotenv").config({ path: path.resolve( process.cwd(), `.env.${process.env.NODE_ENV || "development"}` ), }); const GraphQLClient = require("graphql-request").GraphQLClient; const soap = require("soap"); const queries = require("../graphql-client/queries"); const CdkBase = require("../web-sockets/web-socket"); const CdkWsdl = require("./cdk-wsdl").default; const logger = require("../utils/logger"); const { CDK_CREDENTIALS, CheckCdkResponseForError } = require("./cdk-wsdl"); exports.default = async function (socket, jobid) { socket.logEvents = []; socket.recordid = jobid; try { CdkBase.createLogEvent( socket, "DEBUG", `Received Job export request for id ${jobid}` ); //The following values will be stored on the socket to allow callbacks. //let clVFV, clADPV, clADPC; const JobData = await QueryJobData(socket, jobid); const DealerId = JobData.bodyshop.cdk_dealerid; CdkBase.createLogEvent( socket, "TRACE", `Dealer ID detected: ${JSON.stringify(DealerId)}` ); //{1} Begin Calculate DMS Vehicle Id socket.clVFV = await CalculateDmsVid(socket, JobData); if (socket.clVFV.newId === "Y") { //{1.2} This is a new Vehicle ID CdkBase.createLogEvent( socket, "DEBUG", `{1.2} clVFV DMSVid does *not* exist.` ); CdkBase.createLogEvent( socket, "TRACE", `{1.2} clVFV: ${JSON.stringify(socket.clVFV, null, 2)}` ); //Check if DMSCustId is Empty - which it should always be? //{6.6} Should check to see if a customer exists so that we can marry it to the new vehicle. CdkBase.createLogEvent( socket, "DEBUG", `{6.6} Trying to find customer ID in DMS.` ); //Array const strIDS = await FindCustomerIdFromDms(socket, JobData); if (strIDS && strIDS.length > 0) { CdkBase.createLogEvent( socket, "DEBUG", `{8.2} ${strIDS.length} Customer ID(s) found.` ); CdkBase.createLogEvent( socket, "TRACE", `{8.2} strIDS: ${JSON.stringify(strIDS, null, 2)}` ); if (strIDS.length > 1) { //We have multiple IDs //TODO: Do we need to let the person select it? CdkBase.createLogEvent( socket, "WARNING", `{F} Mutliple customer ids have been found (${strIDS.length})` ); CdkBase.createLogEvent( socket, "DEBUG", `Asking for user intervention to select customer.` ); socket.emit("cdk-select-customer", strIDS); return; } } else { CdkBase.createLogEvent( socket, "DEBUG", `{8.5} Customer ID(s) *not* found.` ); //Create a customer number, then use that to insert the customer record. const newCustomerNumber = await GenerateCustomerNumberFromDms( socket, JobData ); CdkBase.createLogEvent( socket, "DEBUG", `{10.1} New Customer number generated. newCustomerNumber: ${newCustomerNumber}` ); //Use the new customer number to insert the customer record. socket.clADPC = await CreateCustomerInDms( socket, JobData, newCustomerNumber ); CdkBase.createLogEvent( socket, "DEBUG", `{11.1} New Customer inserted.` ); CdkBase.createLogEvent( socket, "TRACE", `{11.1} clADPC: ${JSON.stringify(socket.clADPC, null, 2)}` ); } } else { CdkBase.createLogEvent(socket, "DEBUG", `{1.1} clVFV DMSVid does exist.`); CdkBase.createLogEvent( socket, "TRACE", `{1.1} clVFV: ${JSON.stringify(socket.clVFV, null, 2)}` ); //{2} Begin Find Vehicle in DMS socket.clADPV = await FindVehicleInDms(socket, JobData, socket.clVFV); //TODO: Verify that this should always return a result. If an ID was found previously, it should be correct? //{2.2} Check if the vehicle was found in the DMS. if (socket.clADPV.AppErrorNo === "0") { //Vehicle was found. CdkBase.createLogEvent( socket, "DEBUG", `{1.4} Vehicle was found in the DMS.` ); CdkBase.createLogEvent( socket, "TRACE", `{1.4} clADPV: ${JSON.stringify(socket.clADPV, null, 2)}` ); } else { //Vehicle was not found. CdkBase.createLogEvent( socket, "DEBUG", `{6.4} Vehicle does not exist in DMS. Will have to create one.` ); CdkBase.createLogEvent( socket, "TRACE", `{6.4} clVFV: ${JSON.stringify(socket.clVFV, null, 2)}` ); } } } catch (error) { CdkBase.createLogEvent( socket, "ERROR", `Error encountered in CdkJobExport. ${error}` ); } finally { //Ensure we always insert logEvents //GQL to insert logevents. CdkBase.createLogEvent( socket, "DEBUG", `Capturing log events to database.` ); } }; async function QueryJobData(socket, jobid) { CdkBase.createLogEvent(socket, "DEBUG", `Querying job data for id ${jobid}`); const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {}); const result = await client .setHeaders({ Authorization: `Bearer ${socket.handshake.auth.token}` }) .request(queries.QUERY_JOBS_FOR_CDK_EXPORT, { id: jobid }); CdkBase.createLogEvent( socket, "TRACE", `Job data query result ${JSON.stringify(result, null, 2)}` ); return result.jobs_by_pk; } async function CreateCustomerInDms(socket, JobData, newCustomerNumber) { CdkBase.createLogEvent(socket, "DEBUG", `{11} Begin Create Customer in DMS`); try { const soapClientCustomerInsertUpdate = await soap.createClientAsync( CdkWsdl.CustomerInsertUpdate ); const soapResponseCustomerInsertUpdate = await soapClientCustomerInsertUpdate.insertAsync( { arg0: CDK_CREDENTIALS, arg1: { dealerId: JobData.bodyshop.cdk_dealerid }, //TODO: Verify why this does not follow the other standards. arg2: { userId: null }, arg3: { //Copied the required fields from the other integration. //TODO: Verify whether we need to bring more information in. id: { value: newCustomerNumber }, address: { city: JobData.ownr_city, country: null, postalcode: JobData.ownr_zip, stateOrProvince: JobData.ownr_st, }, contactInfo: { mainTelephoneNumber: { main: true, value: JobData.ownr_ph1 }, }, demographics: null, name1: { companyname: null, firstName: JobData.ownr_fn, fullname: null, lastName: JobData.ownr_ln, middleName: null, nameType: "Person", suffix: null, title: null, }, }, }, {} ); CheckCdkResponseForError(socket, soapResponseCustomerInsertUpdate); const [ result, //rawResponse, soapheader, rawRequest ] = soapResponseCustomerInsertUpdate; CdkBase.createLogEvent( socket, "TRACE", `soapClientCustomerInsertUpdate.insertAsync Result ${JSON.stringify( result, null, 2 )}` ); const customer = result && result.return; return customer; } catch (error) { CdkBase.createLogEvent( socket, "ERROR", `Error in CreateCustomerInDms - ${JSON.stringify(error, null, 2)}` ); throw new Error(error); } } async function GenerateCustomerNumberFromDms(socket, JobData) { CdkBase.createLogEvent( socket, "DEBUG", `{10} Begin Generate Customer Number from DMS` ); try { const soapClientCustomerInsertUpdate = await soap.createClientAsync( CdkWsdl.CustomerInsertUpdate ); const soapResponseCustomerInsertUpdate = await soapClientCustomerInsertUpdate.getCustomerNumberAsync( { arg0: CDK_CREDENTIALS, arg1: { dealerId: JobData.bodyshop.cdk_dealerid }, //TODO: Verify why this does not follow the other standards. arg2: { userId: null }, }, {} ); CheckCdkResponseForError(socket, soapResponseCustomerInsertUpdate); const [ result, //rawResponse, soapheader, rawRequest ] = soapResponseCustomerInsertUpdate; CdkBase.createLogEvent( socket, "TRACE", `soapClientCustomerInsertUpdate.getCustomerNumberAsync Result ${JSON.stringify( result, null, 2 )}` ); const customerNumber = result && result.return && result.return.customerNumber; return customerNumber; } catch (error) { CdkBase.createLogEvent( socket, "ERROR", `Error in GenerateCustomerNumberFromDms - ${JSON.stringify( error, null, 2 )}` ); throw new Error(error); } } async function FindCustomerIdFromDms(socket, JobData) { const ownerName = `${JobData.ownr_ln},${JobData.ownr_fn}`; CdkBase.createLogEvent( socket, "DEBUG", `{8} Begin Read Customer from DMS using OWNER NAME: ${ownerName}` ); try { const soapClientCustomerSearch = await soap.createClientAsync( CdkWsdl.CustomerSearch ); const soapResponseCustomerSearch = await soapClientCustomerSearch.executeSearchAsync( { arg0: CDK_CREDENTIALS, arg1: { dealerId: JobData.bodyshop.cdk_dealerid }, //TODO: Verify why this does not follow the other standards. arg2: { verb: "EXACT", key: ownerName, }, }, {} ); CheckCdkResponseForError(socket, soapResponseCustomerSearch); const [ result, // rawResponse, soapheader, rawRequest ] = soapResponseCustomerSearch; CdkBase.createLogEvent( socket, "TRACE", `soapClientCustomerSearch.executeSearchBulkAsync Result ${JSON.stringify( result, null, 2 )}` ); const CustomersFromDms = result && result.return; return CustomersFromDms; } catch (error) { CdkBase.createLogEvent( socket, "ERROR", `Error in FindCustomerIdFromDms - ${JSON.stringify(error, null, 2)}` ); throw new Error(error); } } async function FindVehicleInDms(socket, JobData, clVFV) { CdkBase.createLogEvent( socket, "DEBUG", `{2}/{6} Begin Find Vehicle In DMS using clVFV: ${clVFV}` ); try { const soapClientVehicleInsertUpdate = await soap.createClientAsync( CdkWsdl.VehicleInsertUpdate ); const soapResponseVehicleInsertUpdate = await soapClientVehicleInsertUpdate.readBulkAsync( { arg0: CDK_CREDENTIALS, arg1: { id: JobData.bodyshop.cdk_dealerid }, arg2: { fileType: "VEHICLES", vehiclesVehicleId: clVFV.vehiclesVehId, }, }, {} ); CheckCdkResponseForError(socket, soapResponseVehicleInsertUpdate); const [ result, //rawResponse, soapheader, rawRequest ] = soapResponseVehicleInsertUpdate; CdkBase.createLogEvent( socket, "TRACE", `soapClientVehicleInsertUpdate.readBulkAsync Result ${JSON.stringify( result, null, 2 )}` ); const VehicleFromDMS = result && result.return && result.return[0]; return VehicleFromDMS; } catch (error) { CdkBase.createLogEvent( socket, "ERROR", `Error in FindVehicleInDms - ${JSON.stringify(error, null, 2)}` ); throw new Error(error); } } async function CalculateDmsVid(socket, JobData) { CdkBase.createLogEvent( socket, "TRACE", `{1} Begin Calculate DMS Vehicle ID using VIN: ${JobData.v_vin}` ); try { const soapClientVehicleInsertUpdate = await soap.createClientAsync( CdkWsdl.VehicleInsertUpdate ); const soapResponseVehicleInsertUpdate = await soapClientVehicleInsertUpdate.getVehIdsAsync( { arg0: CDK_CREDENTIALS, arg1: { id: JobData.bodyshop.cdk_dealerid }, arg2: { VIN: JobData.v_vin }, }, {} ); CheckCdkResponseForError(socket, soapResponseVehicleInsertUpdate); const [ result, //rawResponse, soapheader, rawRequest ] = soapResponseVehicleInsertUpdate; CdkBase.createLogEvent( socket, "TRACE", `soapClientVehicleInsertUpdate.searchIDsByVINAsync Result ${JSON.stringify( result, null, 2 )}` ); const DmsVehicle = result && result.return && result.return[0]; return DmsVehicle; } catch (error) { CdkBase.createLogEvent( socket, "ERROR", `Error in CalculateDmsVid - ${JSON.stringify(error, null, 2)}` ); throw new Error(error); } }